Tulip  4.1.0
Better Visualization Through Research
 All Classes Files Functions Variables Enumerations Enumerator Properties Groups Pages
PluginModel.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 ///@cond DOXYGEN_HIDDEN
20 
21 
22 #ifndef PLUGINMODEL_H
23 #define PLUGINMODEL_H
24 
25 #include <tulip/TulipModel.h>
26 #include <tulip/PluginLister.h>
27 #include <tulip/TlpQtTools.h>
28 #include <QtCore/QMap>
29 #include <QtCore/QSet>
30 #include <QtCore/QString>
31 #include <QtGui/QPixmap>
32 #include <QtGui/QFont>
33 
34 namespace tlp {
35 
36 template<typename PLUGIN>
37 class PluginListModel : public tlp::TulipModel {
38 private:
39  QList<std::string> _list;
40 public:
41  explicit PluginListModel(QObject *parent = NULL): TulipModel(parent), _list(QList<std::string>::fromStdList(PluginLister::instance()->availablePlugins<PLUGIN>())) {
42  }
43  virtual ~PluginListModel() {
44  }
45 
46  virtual int columnCount ( const QModelIndex& = QModelIndex() ) const {
47  return 1;
48  }
49 
50  int rowCount(const QModelIndex &parent = QModelIndex()) const {
51  if(parent.isValid())
52  return 0;
53 
55  }
56 
57  QModelIndex parent(const QModelIndex &) const {
58  return QModelIndex();
59  }
60 
61  QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const {
62  if(parent.isValid())
63  return QModelIndex();
64 
65  return createIndex(row, column);
66  }
67 
68  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
69  if(index.row() < _list.size()) {
70  std::string name(_list[index.row()]);
71 
72  if(role == Qt::DisplayRole) {
73  return name.c_str();
74  }
75  else if (role == Qt::DecorationRole) {
76  const Plugin* p = PluginLister::pluginInformations(name);
77  QPixmap pix(p->icon().c_str());
78  delete p;
79  return pix;
80  }
81  }
82 
83  return QVariant();
84  }
85 };
86 
87 template<typename PLUGIN>
88 class PluginModel : public tlp::TulipModel {
89  struct TreeItem {
90  TreeItem(QString name, TreeItem* parent = NULL): name(name), parent(parent) {}
91  virtual ~TreeItem() {
92  foreach(TreeItem* c, children)
93  delete c;
94  }
95  TreeItem* addChild(QString name) {
96  TreeItem* result = new TreeItem(name,this);
97  children.push_back(result);
98  return result;
99  }
100 
101  QString name;
102  TreeItem* parent;
103  QList<TreeItem*> children;
104  };
105  TreeItem* _root;
106 
107  // FIXME: Non-optimized piece of crap, should be fixed
108  void buildTree() {
109  delete _root;
110  _root = new TreeItem("root");
111  QMap<QString,QMap<QString,QStringList > > pluginTree;
112  std::list<std::string> plugins = PluginLister::instance()->availablePlugins<PLUGIN>();
113 
114  for(std::list<std::string>::iterator it = plugins.begin(); it != plugins.end(); ++it) {
115  std::string name = *it;
116  const Plugin* plugin = PluginLister::instance()->pluginInformations(name);
117  pluginTree[plugin->category().c_str()][plugin->group().c_str()].append(name.c_str());
118  }
119 
120  foreach(QString cat, pluginTree.keys()) {
121  TreeItem* catItem = _root->addChild(cat);
122 
123  if (pluginTree[cat].keys().size() > 1) {
124  foreach(QString group, pluginTree[cat].keys()) {
125  TreeItem* groupItem = catItem;
126 
127  if (group != "")
128  groupItem = catItem->addChild(group);
129 
130  // sort in case insensitive alphabetic order
131  std::sort(pluginTree[cat][group].begin(),
132  pluginTree[cat][group].end(), QStringCaseCmp);
133 
134  foreach(QString alg, pluginTree[cat][group])
135  groupItem->addChild(alg);
136  }
137  }
138  else {
139  foreach(QString alg, pluginTree[cat][pluginTree[cat].keys()[0]])
140  catItem->addChild(alg);
141  }
142  }
143  }
144 
145  QList<int> indexHierarchy(TreeItem* item) const {
146  QList<int> result;
147  TreeItem* parent = item->parent;
148  TreeItem* child = item;
149 
150  while (child != _root) {
151  result.push_front(parent->children.indexOf(child));
152  parent = parent->parent;
153  child = child->parent;
154  }
155 
156  return result;
157  }
158 
159 public:
160  explicit PluginModel(QObject *parent = NULL): TulipModel(parent), _root(NULL) {
161  buildTree();
162  }
163  virtual ~PluginModel() {
164  delete _root;
165  }
166 
167  int rowCount(const QModelIndex &parent = QModelIndex()) const {
168  TreeItem* item = _root;
169 
170  if (parent.isValid())
171  item = (TreeItem*)parent.internalPointer();
172 
173  return item->children.size();
174  }
175 
176  int columnCount(const QModelIndex & = QModelIndex()) const {
177  return 1;
178  }
179 
180  QModelIndex parent(const QModelIndex &child) const {
181  if (!child.isValid())
182  return QModelIndex();
183 
184  TreeItem* childItem = (TreeItem*)child.internalPointer();
185 
186  if (childItem->parent == _root)
187  return QModelIndex();
188 
189  QList<int> indexes = indexHierarchy(childItem->parent);
190  int row = indexes[indexes.size()-1];
191  return createIndex(row,child.column(),childItem->parent);
192  }
193 
194  QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const {
195  TreeItem* parentItem = _root;
196 
197  if (parent.isValid()) {
198  parentItem = (TreeItem*)parent.internalPointer();
199  }
200 
201  if (row >= parentItem->children.size())
202  return QModelIndex();
203 
204  return createIndex(row,column,parentItem->children[row]);
205  }
206 
207  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
208  TreeItem* item = (TreeItem*)index.internalPointer();
209 
210  if (role == Qt::DisplayRole)
211  return item->name;
212  else if (role == Qt::FontRole && !index.parent().parent().isValid()) {
213  QFont f;
214  f.setBold(true);
215  return f;
216  }
217  else if (role == Qt::DecorationRole && tlp::PluginLister::pluginExists(item->name.toStdString())) {
218  const tlp::Plugin* p = tlp::PluginLister::pluginInformations(item->name.toStdString());
219  QIcon icon(p->icon().c_str());
220  delete p;
221  return icon;
222  }
223 
224  return QVariant();
225  }
226 
227  virtual Qt::ItemFlags flags ( const QModelIndex& index ) const {
228  Qt::ItemFlags result(QAbstractItemModel::flags(index));
229 
230  if(index.isValid()) {
231  TreeItem* item = (TreeItem*)index.internalPointer();
232 
233  if (!PluginLister::instance()->pluginExists<PLUGIN>(item->name.toStdString()))
234  result = Qt::ItemIsEnabled;
235  }
236 
237  return result;
238  }
239 };
240 }
241 
242 #endif // PLUGINMODEL_H
243 ///@endcond