Wt examples: /home/koen/project/wt/public-git/wt/examples/gitmodel/GitModel.C Source File

Wt examples 3.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

/home/koen/project/wt/public-git/wt/examples/gitmodel/GitModel.C
Go to the documentation of this file.

    00001 /*
    00002  * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
    00003  *
    00004  * See the LICENSE file for terms of use.
    00005  */
    00006
    00007 #include "GitModel.h"
    00008
    00009 using namespace Wt;
    00010
    00011 GitModel::GitModel(WObject *parent)
    00012   : WAbstractItemModel(parent)
    00013 { }
    00014
    00015 void GitModel::setRepositoryPath(const std::string& gitRepositoryPath)
    00016 {
    00017   git_.setRepositoryPath(gitRepositoryPath);
    00018   loadRevision("master");
    00019 }
    00020
    00021 void GitModel::loadRevision(const std::string& revName)
    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, git_.treeSize(treeRoot)));
    00036
    00037   layoutChanged().emit();
    00038 }
    00039
    00040 WModelIndex GitModel::parent(const WModelIndex& index) const
    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 }
    00055
    00056 WModelIndex GitModel::index(int row, int column,
    00057                             const WModelIndex& parent) const
    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 }
    00075
    00076 int GitModel::getTreeId(int parentId, int childIndex) const
    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, git_.treeSize(o.id)));
    00090     int result = treeData_.size() - 1;
    00091     childPointer_[index] = result;
    00092     return result;
    00093   } else
    00094     return i->second;
    00095 }
    00096
    00097 int GitModel::columnCount(const WModelIndex& index) const
    00098 {
    00099   // currently only one column
    00100   return 1;
    00101 }
    00102
    00103 int GitModel::rowCount(const WModelIndex& index) const
    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   int treeId;
    00109
    00110   if (index.isValid()) {
    00111     // only column 0 items may contain children
    00112     if (index.column() != 0)
    00113       return 0;
    00114
    00115     Git::Object o = getObject(index);
    00116     if (o.type == Git::Tree) {
    00117       objectId = o.id;
    00118       treeId = getTreeId(index.internalId(), index.row());
    00119     } else
    00120       // not a folder: no children
    00121       return 0;
    00122   } else {
    00123     treeId = 0;
    00124     // the index corresponds to the root object
    00125     if (treeData_.empty())
    00126       // model not yet loaded !
    00127       return 0;
    00128     else
    00129       objectId = treeData_[0].treeObject();
    00130   }
    00131
    00132   return treeData_[treeId].rowCount();
    00133 }
    00134
    00135 boost::any GitModel::data(const WModelIndex& index, int role) const
    00136 {
    00137   if (!index.isValid())
    00138     return boost::any();
    00139
    00140   /* Only 3 data roles on column 0 data are supported:
    00141    * - DisplayRole: the file name
    00142    * - DecorationRole: an icon (folder or file)
    00143    * - ContentsRole: the file contents
    00144    */
    00145   if (index.column() == 0) {
    00146     Git::Object object = getObject(index);
    00147     if (role == DisplayRole) {
    00148       if (object.type == Git::Tree)
    00149         return object.name + '/';
    00150       else
    00151         return object.name;
    00152     } else if (role == DecorationRole) {
    00153       if (object.type == Git::Blob)
    00154         return static_cast<const char*>("icons/git-blob.png");
    00155       else if (object.type == Git::Tree)
    00156         return static_cast<const char*>("icons/git-tree.png");
    00157     } else if (role == ContentsRole) {
    00158       if (object.type == Git::Blob)
    00159         return git_.catFile(object.id);
    00160     } else if (role == FilePathRole) {
    00161       return boost::any();
    00162     }
    00163   }
    00164
    00165   return boost::any();
    00166 }
    00167
    00168 boost::any GitModel::headerData(int section, Orientation orientation,
    00169                                 int role) const
    00170 {
    00171   if (orientation == Horizontal && role == DisplayRole)
    00172     return static_cast<const char*>("File");
    00173   else
    00174     return boost::any();
    00175 }
    00176
    00177 Git::Object GitModel::getObject(const WModelIndex& index) const
    00178 {
    00179   int parentId = index.internalId();
    00180   const Tree& parentItem = treeData_[parentId];
    00181   return git_.treeGetObject(parentItem.treeObject(), index.row());
    00182 }