Go to the documentation of this file.00001 #ifndef TREE_COMPLETER_H
00002 #define TREE_COMPLETER_H
00003
00004 #include <QString>
00005 #include <QHash>
00006 #include <QVariant>
00007 #include <QList>
00008 #include <QStandardItem>
00009 #include <QStandardItemModel>
00010 #include <QCompleter>
00011
00012 class TreeItem
00013 {
00014 public:
00015 explicit TreeItem(QStandardItem* item): _item(item)
00016 {
00017
00018 }
00019
00020 TreeItem* appendChild(const QString& name, QStandardItem* item)
00021 {
00022 return &(_child_items_map.insert(name, TreeItem(item) ).value());
00023 }
00024
00025 TreeItem * findChild(const QString& name)
00026 {
00027 auto it = _child_items_map.find(name);
00028 if( it == _child_items_map.end())
00029 {
00030 return nullptr;
00031 }
00032 return &(it.value());
00033 }
00034
00035 QStandardItem* standardItem() { return _item; }
00036
00037 private:
00038 QHash<QString, TreeItem> _child_items_map;
00039 QStandardItem* _item;
00040 };
00041
00042 class TreeModelCompleter : public QCompleter
00043 {
00044
00045 public:
00046 TreeModelCompleter(QObject *parent = 0):
00047 QCompleter(parent),
00048 _model(new QStandardItemModel()),
00049 _root_tree_item(nullptr)
00050 {
00051 setModelSorting( QCompleter::CaseInsensitivelySortedModel );
00052 setModel(_model);
00053 _root_tree_item = TreeItem(_model->invisibleRootItem());
00054 }
00055
00056 void clear()
00057 {
00058 _model->clear();
00059 _root_tree_item = TreeItem(_model->invisibleRootItem());
00060 }
00061
00062 QStringList splitPath(const QString &path) const override {
00063 return path.split('/');
00064 }
00065
00066 QString pathFromIndex(const QModelIndex &index) const override
00067 {
00068 QStringList dataList;
00069 for (QModelIndex it = index; it.isValid(); it = it.parent())
00070 {
00071 dataList.prepend(model()->data(it, completionRole()).toString());
00072 }
00073 return dataList.join('/');
00074 }
00075
00076 void addToCompletionTree(const QString &name)
00077 {
00078 auto parts = name.split('/');
00079 if( parts.size() == 0 )
00080 {
00081 return;
00082 }
00083
00084 TreeItem* tree_parent = & _root_tree_item;
00085 QStandardItem *item_parent = tree_parent->standardItem();
00086
00087 for (const auto& part: parts)
00088 {
00089 TreeItem* matching_child = tree_parent->findChild( part );
00090 if(matching_child)
00091 {
00092 tree_parent = matching_child;
00093 item_parent = matching_child->standardItem();
00094 }
00095 else
00096 {
00097 QStandardItem* item = new QStandardItem( part );
00098 item_parent->appendRow(item);
00099 tree_parent = tree_parent->appendChild(part, item);
00100 item_parent = item;
00101 }
00102 }
00103 }
00104
00105 private:
00106
00107 QStandardItemModel* _model;
00108 TreeItem _root_tree_item;
00109 };
00110
00111
00112 #endif // TREE_COMPLETER_H