Tulip  4.6.0
Better Visualization Through Research
library/tulip-gui/include/tulip/PluginModel.h
00001 /*
00002  *
00003  * This file is part of Tulip (www.tulip-software.org)
00004  *
00005  * Authors: David Auber and the Tulip development Team
00006  * from LaBRI, University of Bordeaux
00007  *
00008  * Tulip is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation, either version 3
00011  * of the License, or (at your option) any later version.
00012  *
00013  * Tulip is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  *
00018  */
00019 ///@cond DOXYGEN_HIDDEN
00020 
00021 #ifndef PLUGINMODEL_H
00022 #define PLUGINMODEL_H
00023 
00024 #include <QIcon>
00025 #include <QFont>
00026 
00027 #include <tulip/TulipModel.h>
00028 #include <tulip/TlpQtTools.h>
00029 #include <tulip/PluginLister.h>
00030 
00031 #include <string>
00032 
00033 namespace tlp {
00034 /*
00035  * @brief Build and manage a Qt Model of a list of plugins
00036  */
00037 class TLP_QT_SCOPE SimplePluginListModel : public tlp::TulipModel {
00038 private:
00039   QList<std::string> _list;
00040 
00041 public:
00042 
00043   SimplePluginListModel(const QList<std::string>& plugins,QObject *parent = NULL);
00044   virtual ~SimplePluginListModel();
00045   int columnCount ( const QModelIndex& = QModelIndex() ) const;
00046   int rowCount(const QModelIndex &parent = QModelIndex()) const;
00047   QModelIndex parent(const QModelIndex &) const;
00048   QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const;
00049   QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
00050   QList<std::string> plugins()const;
00051   std::string pluginName(const QModelIndex& index) const;
00052 };
00053 
00054 template<typename PLUGIN>
00055 class PluginModel : public tlp::TulipModel {
00056   struct TreeItem {
00057     TreeItem(QString name, QString infos = QString::null,
00058              TreeItem* parent = NULL): name(name), infos(infos), parent(parent) {}
00059     virtual ~TreeItem() {
00060       foreach(TreeItem* c, children)
00061       delete c;
00062     }
00063     TreeItem* addChild(QString name, QString infos = QString::null) {
00064       TreeItem* result = new TreeItem(name, infos, this);
00065       children.push_back(result);
00066       return result;
00067     }
00068 
00069     QString name;
00070     QString infos;
00071     TreeItem* parent;
00072     QList<TreeItem*> children;
00073   };
00074   TreeItem* _root;
00075 
00076   // FIXME: Non-optimized piece of crap, should be fixed
00077   void buildTree() {
00078     delete _root;
00079     _root = new TreeItem("root");
00080     QMap<QString,QMap<QString,QStringList > > pluginTree;
00081     std::list<std::string> plugins = PluginLister::instance()->availablePlugins<PLUGIN>();
00082 
00083     for(std::list<std::string>::iterator it = plugins.begin(); it != plugins.end(); ++it) {
00084       std::string name = *it;
00085       const Plugin& plugin = PluginLister::instance()->pluginInformation(name);
00086       pluginTree[tlp::tlpStringToQString(plugin.category())][tlp::tlpStringToQString(plugin.group())].append(tlp::tlpStringToQString(name));
00087     }
00088 
00089     foreach(QString cat, pluginTree.keys()) {
00090       TreeItem* catItem = _root->addChild(cat);
00091 
00092       foreach(QString group, pluginTree[cat].keys()) {
00093         TreeItem* groupItem = catItem;
00094 
00095         if ((group != "") && (pluginTree[cat].keys().size() > 1))
00096           groupItem = catItem->addChild(group);
00097 
00098         // sort in case insensitive alphabetic order
00099         std::sort(pluginTree[cat][group].begin(),
00100                   pluginTree[cat][group].end(), QStringCaseCmp);
00101 
00102         foreach(QString alg, pluginTree[cat][group]) {
00103           const Plugin& plugin =
00104             PluginLister::instance()->pluginInformation(tlp::QStringToTlpString(alg));
00105           std::string infos = plugin.info();
00106 
00107           // set infos only if they contain more than one word
00108           if (infos.find(' ') != std::string::npos)
00109             groupItem->addChild(alg, tlp::tlpStringToQString(infos));
00110           else
00111             groupItem->addChild(alg);
00112         }
00113       }
00114     }
00115   }
00116 
00117   QList<int> indexHierarchy(TreeItem* item) const {
00118     QList<int> result;
00119     TreeItem* parent = item->parent;
00120     TreeItem* child = item;
00121 
00122     while (child != _root) {
00123       result.push_front(parent->children.indexOf(child));
00124       parent = parent->parent;
00125       child = child->parent;
00126     }
00127 
00128     return result;
00129   }
00130 
00131 public:
00132   explicit PluginModel(QObject *parent = NULL): TulipModel(parent), _root(NULL) {
00133     buildTree();
00134   }
00135   virtual ~PluginModel() {
00136     delete _root;
00137   }
00138 
00139   int rowCount(const QModelIndex &parent = QModelIndex()) const {
00140     TreeItem* item = _root;
00141 
00142     if (parent.isValid())
00143       item = (TreeItem*)parent.internalPointer();
00144 
00145     return item->children.size();
00146   }
00147 
00148   int columnCount(const QModelIndex & = QModelIndex()) const {
00149     return 1;
00150   }
00151 
00152   QModelIndex parent(const QModelIndex &child) const {
00153     if (!child.isValid())
00154       return QModelIndex();
00155 
00156     TreeItem* childItem = (TreeItem*)child.internalPointer();
00157 
00158     if (childItem->parent == _root)
00159       return QModelIndex();
00160 
00161     QList<int> indexes = indexHierarchy(childItem->parent);
00162     int row = indexes[indexes.size()-1];
00163     return createIndex(row,child.column(),childItem->parent);
00164   }
00165 
00166   QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const {
00167     TreeItem* parentItem = _root;
00168 
00169     if (parent.isValid()) {
00170       parentItem = (TreeItem*)parent.internalPointer();
00171     }
00172 
00173     if (row >= parentItem->children.size())
00174       return QModelIndex();
00175 
00176     return createIndex(row,column,parentItem->children[row]);
00177   }
00178 
00179   QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
00180     TreeItem* item = (TreeItem*)index.internalPointer();
00181 
00182     if (role == Qt::DisplayRole)
00183       return item->name;
00184     else if (role == Qt::ToolTipRole) {
00185       if (item->infos.isNull())
00186         return item->name;
00187       else
00188         return QString("<table><tr><td>%1</td></tr><tr><td><i>%2</i></td></tr></table>").arg(item->name + ":").arg(item->infos);
00189     }
00190     else if (role == Qt::FontRole && !index.parent().parent().isValid()) {
00191       QFont f;
00192       f.setBold(true);
00193       return f;
00194     }
00195     else if (role == Qt::DecorationRole && tlp::PluginLister::pluginExists(tlp::QStringToTlpString(item->name))) {
00196       const tlp::Plugin& p = tlp::PluginLister::pluginInformation(tlp::QStringToTlpString(item->name));
00197       QIcon icon(tlp::tlpStringToQString(p.icon()));
00198       return icon;
00199     }
00200 
00201     return QVariant();
00202   }
00203 
00204   virtual Qt::ItemFlags flags ( const QModelIndex& index ) const {
00205     Qt::ItemFlags result(QAbstractItemModel::flags(index));
00206 
00207     if(index.isValid()) {
00208       TreeItem* item = (TreeItem*)index.internalPointer();
00209 
00210       if (!PluginLister::instance()->pluginExists<PLUGIN>(tlp::QStringToTlpString(item->name)))
00211         result = Qt::ItemIsEnabled;
00212     }
00213 
00214     return result;
00215   }
00216 };
00217 }
00218 
00219 #endif // PLUGINMODEL_H
00220 ///@endcond
 All Classes Files Functions Variables Enumerations Enumerator Properties