~canonical-platform-qa/autopilot-qt/overlay

« back to all changes in this revision

Viewing changes to driver/qtnode.cpp

  • Committer: CI bot
  • Author(s): Christopher Lee
  • Date: 2014-07-24 23:51:01 UTC
  • mfrom: (83.4.37 adding-new-node-types)
  • Revision ID: ps-jenkins@lists.canonical.com-20140724235101-p2b9alu7qaah6jv1
Adding new data model nodes. 
Approved by: Thomi Richards, PS Jenkins bot

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#endif
18
18
#include <QDBusArgument>
19
19
 
 
20
#include <QAbstractItemView>
 
21
#include <QAbstractProxyModel>
 
22
#include <QTableWidget>
 
23
#include <QTreeView>
 
24
#include <QTreeWidget>
 
25
#include <QListView>
 
26
 
 
27
const QByteArray AP_ID_NAME("_autopilot_id");
 
28
 
 
29
void CollectSpecialChildren(QObject* object, xpathselect::NodeVector& children, DBusNode::Ptr parent);
 
30
 
 
31
void GetDataElementChildren(QTableWidget* table, xpathselect::NodeVector& children, DBusNode::Ptr parent);
 
32
void GetDataElementChildren(QTreeView* tree_view, xpathselect::NodeVector& children, DBusNode::Ptr parent);
 
33
void GetDataElementChildren(QTreeWidget* tree_widget, xpathselect::NodeVector& children, DBusNode::Ptr parent);
 
34
void GetDataElementChildren(QListView* list_view, xpathselect::NodeVector& children, DBusNode::Ptr parent);
 
35
 
 
36
void CollectAllIndices(QModelIndex index, QAbstractItemModel *model, QModelIndexList &collection);
 
37
QVariant SafePackProperty(QVariant const& prop);
 
38
 
 
39
bool MatchProperty(QVariantMap const& packed_properties, std::string const& name, QVariant value);
 
40
 
 
41
// Produce an id suitable for xpathselects' GetId
 
42
int32_t calculate_ap_id(quint64 big_id)
 
43
{
 
44
    int32_t high = static_cast<int32_t>(big_id >> 32);
 
45
    int32_t low = static_cast<int32_t>(big_id);
 
46
    return high ^ low;
 
47
}
 
48
 
20
49
// Marshall the NodeIntrospectionData data into a D-Bus argument
21
 
QDBusArgument &operator<<(QDBusArgument &argument, const NodeIntrospectionData &node_data)
 
50
QDBusArgument &operator<<(QDBusArgument &argument, NodeIntrospectionData const& node_data)
22
51
{
23
52
    argument.beginStructure();
24
53
    argument << node_data.object_path << node_data.state;
27
56
}
28
57
 
29
58
// Retrieve the NodeIntrospectionData data from the D-Bus argument
30
 
const QDBusArgument &operator>>(const QDBusArgument &argument, NodeIntrospectionData &node_data)
 
59
const QDBusArgument &operator>>(QDBusArgument const& argument, NodeIntrospectionData& node_data)
31
60
{
32
61
    argument.beginStructure();
33
62
    argument >> node_data.object_path >> node_data.state;
35
64
    return argument;
36
65
}
37
66
 
38
 
const QByteArray AP_ID_NAME("_autopilot_id");
 
67
void GetDataElementChildren(QTableWidget *table, xpathselect::NodeVector& children, DBusNode::Ptr parent)
 
68
{
 
69
    QList<QTableWidgetItem *> tablewidgetitems = table->findItems("*", Qt::MatchWildcard|Qt::MatchRecursive);
 
70
    foreach (QTableWidgetItem *item, tablewidgetitems){
 
71
        children.push_back(
 
72
            std::make_shared<QTableWidgetItemNode>(item, parent)
 
73
            );
 
74
    }
 
75
}
 
76
 
 
77
void CollectAllIndices(QModelIndex index, QAbstractItemModel *model, QModelIndexList &collection)
 
78
{
 
79
    for(int c=0; c < model->columnCount(index); ++c) {
 
80
        for(int r=0; r < model->rowCount(index); ++r) {
 
81
            QModelIndex new_index = model->index(r, c, index);
 
82
            collection.push_back(new_index);
 
83
            if(new_index.isValid() && qHash(new_index) != qHash(index)) {
 
84
                CollectAllIndices(new_index, model, collection);
 
85
            }
 
86
        }
 
87
    }
 
88
}
 
89
 
 
90
// Pack property, but return a default blank if the packed property is invalid.
 
91
QVariant SafePackProperty(QVariant const& prop)
 
92
{
 
93
    static QVariant blank_default = PackProperty("");
 
94
 
 
95
    QVariant property_attempt = PackProperty(prop);
 
96
    if(property_attempt.isValid())
 
97
        return property_attempt;
 
98
    else
 
99
        return blank_default;
 
100
}
 
101
 
 
102
bool MatchProperty(QVariantMap const& packed_properties, std::string const& name, QVariant value)
 
103
{
 
104
    QString qname = QString::fromStdString(name);
 
105
    if (! packed_properties.contains(qname))
 
106
        return false;
 
107
 
 
108
    // Because the properties are packed, we need the value, not the type.
 
109
    QVariant object_value = qvariant_cast<QVariantList>(packed_properties[qname]).at(1);
 
110
    if (value.canConvert(object_value.type()))
 
111
    {
 
112
        value.convert(object_value.type());
 
113
        return value == object_value;
 
114
    }
 
115
    return false;
 
116
}
 
117
 
 
118
 
 
119
void GetDataElementChildren(QTreeView* tree_view, xpathselect::NodeVector& children, DBusNode::Ptr parent)
 
120
{
 
121
    QAbstractItemModel* abstract_model = tree_view->model();
 
122
    if(! abstract_model)
 
123
    {
 
124
        qDebug() << "Unable to get element children from QTreeView "
 
125
                 << "with objectName '" << tree_view->objectName() << "'. "
 
126
                 << "No model found.";
 
127
        return;
 
128
    }
 
129
 
 
130
    QModelIndexList all_indices;
 
131
    for(int c=0; c < abstract_model->columnCount(); ++c) {
 
132
        for(int r=0; r < abstract_model->rowCount(); ++r) {
 
133
            QModelIndex index = abstract_model->index(r, c);
 
134
            all_indices.push_back(index);
 
135
            CollectAllIndices(index, abstract_model, all_indices);
 
136
        }
 
137
    }
 
138
 
 
139
    foreach(QModelIndex index, all_indices)
 
140
    {
 
141
        if(index.isValid())
 
142
        {
 
143
            children.push_back(
 
144
                std::make_shared<QModelIndexNode>(
 
145
                    index,
 
146
                    tree_view,
 
147
                    parent)
 
148
                );
 
149
        }
 
150
    }
 
151
}
 
152
 
 
153
void GetDataElementChildren(QTreeWidget* tree_widget, xpathselect::NodeVector& children, DBusNode::Ptr parent)
 
154
{
 
155
    for(int i=0; i < tree_widget->topLevelItemCount(); ++i) {
 
156
        children.push_back(
 
157
            std::make_shared<QTreeWidgetItemNode>(
 
158
                tree_widget->topLevelItem(i),
 
159
                parent)
 
160
            );
 
161
    }
 
162
}
 
163
 
 
164
void GetDataElementChildren(QListView* list_view, xpathselect::NodeVector& children, DBusNode::Ptr parent)
 
165
{
 
166
    QAbstractItemModel* abstract_model = list_view->model();
 
167
 
 
168
    if(! abstract_model) {
 
169
        qDebug() << "Unable to get element children from QListView "
 
170
                 << "with objectName '" << list_view->objectName() << "'. "
 
171
                 << "No model found.";
 
172
        return;
 
173
    }
 
174
 
 
175
    QModelIndexList all_indices;
 
176
    QModelIndex root_index = list_view->rootIndex();
 
177
    if(root_index.isValid()) {
 
178
        // The root item is the parent item to the view's toplevel items
 
179
        CollectAllIndices(root_index, abstract_model, all_indices);
 
180
    }
 
181
    else {
 
182
        for(int c=0; c < abstract_model->columnCount(); ++c) {
 
183
            for(int r=0; r < abstract_model->rowCount(); ++r) {
 
184
                QModelIndex index = abstract_model->index(r, c);
 
185
                all_indices.push_back(index);
 
186
                CollectAllIndices(index, abstract_model, all_indices);
 
187
            }
 
188
        }
 
189
    }
 
190
 
 
191
    foreach(QModelIndex index, all_indices) {
 
192
        if(index.isValid())
 
193
        {
 
194
            children.push_back(
 
195
                std::make_shared<QModelIndexNode>(
 
196
                    index,
 
197
                    list_view,
 
198
                    parent)
 
199
                );
 
200
        }
 
201
    }
 
202
}
39
203
 
40
204
QObjectNode::QObjectNode(QObject *obj, DBusNode::Ptr parent)
41
205
: object_(obj)
70
234
    QString name = object_->metaObject()->className();
71
235
 
72
236
    // QML type names get mangled by Qt - they get _QML_N or _QMLTYPE_N appended.
73
 
    //
74
237
    if (name.contains('_'))
75
238
        name = name.split('_').front();
76
239
    return name.toStdString();
97
260
    return qvariant_cast<int32_t>(object_->property(AP_ID_NAME));
98
261
}
99
262
 
100
 
bool QObjectNode::MatchStringProperty(const std::string& name, const std::string& value) const
 
263
bool QObjectNode::MatchStringProperty(std::string const& name, std::string const& value) const
101
264
{
102
 
    QVariantMap properties = GetNodeProperties(object_);
103
 
 
104
 
    QString qname = QString::fromStdString(name);
105
 
    if (! properties.contains(qname))
106
 
        return false;
107
 
 
108
 
    QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1);
109
 
    QVariant check_value(QString::fromStdString(value));
110
 
    if (check_value.canConvert(object_value.type()))
111
 
    {
112
 
        check_value.convert(object_value.type());
113
 
        return check_value == object_value;
114
 
    }
115
 
 
116
 
    return false;
 
265
    return MatchProperty(GetNodeProperties(object_), name, QString::fromStdString(value));
117
266
}
118
267
 
119
 
bool QObjectNode::MatchIntegerProperty(const std::string& name, int32_t value) const
 
268
bool QObjectNode::MatchIntegerProperty(std::string const& name, int32_t value) const
120
269
{
121
270
    if (name == "id")
122
271
        return value == GetId();
123
272
 
124
 
    QVariantMap properties = GetNodeProperties(object_);
125
 
 
126
 
    QString qname = QString::fromStdString(name);
127
 
    if (! properties.contains(qname))
128
 
        return false;
129
 
 
130
 
    QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1);
131
 
    QVariant check_value(value);
132
 
    if (check_value.canConvert(object_value.type()))
133
 
    {
134
 
        check_value.convert(object_value.type());
135
 
        return check_value == object_value;
136
 
    }
137
 
 
138
 
    return false;
139
 
}
140
 
 
141
 
bool QObjectNode::MatchBooleanProperty(const std::string& name, bool value) const
142
 
{
143
 
    QVariantMap properties = GetNodeProperties(object_);
144
 
 
145
 
    QString qname = QString::fromStdString(name);
146
 
    if (! properties.contains(qname))
147
 
        return false;
148
 
 
149
 
    QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1);
150
 
    QVariant check_value(value);
151
 
 
152
 
    if (check_value.canConvert(object_value.type()))
153
 
    {
154
 
        check_value.convert(object_value.type());
155
 
        return check_value == object_value;
156
 
    }
157
 
 
158
 
    return false;
 
273
    return MatchProperty(GetNodeProperties(object_), name, value);
 
274
}
 
275
 
 
276
bool QObjectNode::MatchBooleanProperty(std::string const& name, bool value) const
 
277
{
 
278
    return MatchProperty(GetNodeProperties(object_), name, value);
 
279
}
 
280
 
 
281
template <class T>
 
282
bool AttemptGetSpecialChildren(QObject* object, xpathselect::NodeVector& children, DBusNode::Ptr parent)
 
283
{
 
284
    auto className = T::staticMetaObject.className();
 
285
    if(object->inherits(className))
 
286
    {
 
287
        T* table = qobject_cast<T *>(object);
 
288
        if(table) {
 
289
            GetDataElementChildren(table, children, parent);
 
290
        }
 
291
        else {
 
292
            qDebug() << "Casting object (with objectName: " << object->objectName() << ") "
 
293
                     << "to " << className
 
294
                     << "failed. Unable to retrieve children.";
 
295
            return false;
 
296
        }
 
297
        return true;
 
298
    }
 
299
    return false;
 
300
}
 
301
 
 
302
void CollectSpecialChildren(QObject* object, xpathselect::NodeVector& children, DBusNode::Ptr parent)
 
303
{
 
304
    // Need to make sure to make these checks in the correct order.
 
305
    // i.e. Because QTreeWidget inherits from QTreeView do it first otherwise
 
306
    // we would never reach the specific QTreeWidget code.
 
307
    AttemptGetSpecialChildren<QTableWidget>(object, children, parent)
 
308
        || AttemptGetSpecialChildren<QTreeWidget>(object, children, parent)
 
309
        || AttemptGetSpecialChildren<QTreeView>(object, children, parent)
 
310
        || AttemptGetSpecialChildren<QListView>(object, children, parent);
159
311
}
160
312
 
161
313
xpathselect::NodeVector QObjectNode::Children() const
162
314
{
163
315
    xpathselect::NodeVector children;
164
316
 
 
317
    CollectSpecialChildren(object_, children, shared_from_this());
 
318
 
165
319
#ifdef QT5_SUPPORT
166
320
    // Qt5's hierarchy for QML has changed a bit:
167
321
    // - On top there's a QQuickView which holds all the QQuick items
219
373
{
220
374
    return parent_;
221
375
}
 
376
 
 
377
// QModelIndexNode
 
378
QModelIndexNode::QModelIndexNode(QModelIndex index, QAbstractItemView* parent_view, DBusNode::Ptr parent)
 
379
    : index_(index)
 
380
    , parent_view_(parent_view)
 
381
    , parent_(parent)
 
382
{
 
383
    std::string parent_path = parent ? parent->GetPath() : "";
 
384
    full_path_ = parent_path + "/" + GetName();
 
385
}
 
386
 
 
387
NodeIntrospectionData QModelIndexNode::GetIntrospectionData() const
 
388
{
 
389
    NodeIntrospectionData data;
 
390
    data.object_path = QString::fromStdString(GetPath());
 
391
    data.state = GetProperties();
 
392
    data.state["id"] = PackProperty(GetId());
 
393
    return data;
 
394
}
 
395
 
 
396
QVariantMap QModelIndexNode::GetProperties() const
 
397
{
 
398
    QVariantMap properties;
 
399
    const QAbstractItemModel* model = index_.model();
 
400
    if(model)
 
401
    {
 
402
        // Make an attempt to store the 'text' of a node to be user friendly-ish.
 
403
        properties["text"] = SafePackProperty(model->data(index_));
 
404
 
 
405
        // Include any Role data (mung the role name with added "Role")
 
406
        const QHash<int, QByteArray> role_names = model->roleNames();
 
407
        QMap<int, QVariant> item_data = model->itemData(index_);
 
408
        foreach(int name, role_names.keys())
 
409
        {
 
410
            if(item_data.contains(name)) {
 
411
                properties[role_names[name]+"Role"] = SafePackProperty(item_data[name]);
 
412
            }
 
413
            else {
 
414
                properties[role_names[name]+"Role"] = PackProperty("");
 
415
            }
 
416
        }
 
417
    }
 
418
 
 
419
    QRect rect = parent_view_->visualRect(index_);
 
420
    QRect global_rect(
 
421
        parent_view_->viewport()->mapToGlobal(rect.topLeft()),
 
422
        rect.size());
 
423
    QRect viewport_contents = parent_view_->viewport()->contentsRect();
 
424
    properties["onScreen"] = PackProperty(viewport_contents.contains(rect));
 
425
    properties["globalRect"] = PackProperty(global_rect);
 
426
 
 
427
    return properties;
 
428
}
 
429
 
 
430
xpathselect::Node::Ptr QModelIndexNode::GetParent() const
 
431
{
 
432
    return parent_;
 
433
}
 
434
 
 
435
std::string QModelIndexNode::GetName() const
 
436
{
 
437
    return "QModelIndex";
 
438
}
 
439
 
 
440
std::string QModelIndexNode::GetPath() const
 
441
{
 
442
    return full_path_;
 
443
}
 
444
 
 
445
int32_t QModelIndexNode::GetId() const
 
446
{
 
447
    return calculate_ap_id(static_cast<quint64>(qHash(index_)));
 
448
}
 
449
 
 
450
bool QModelIndexNode::MatchStringProperty(std::string const& name, std::string const& value) const
 
451
{
 
452
    return MatchProperty(GetProperties(), name, QString::fromStdString(value));
 
453
}
 
454
 
 
455
bool QModelIndexNode::MatchIntegerProperty(std::string const& name, int32_t value) const
 
456
{
 
457
    if (name == "id")
 
458
        return value == GetId();
 
459
 
 
460
    return MatchProperty(GetProperties(), name, value);
 
461
}
 
462
 
 
463
bool QModelIndexNode::MatchBooleanProperty(std::string const& name, bool value) const
 
464
{
 
465
    return MatchProperty(GetProperties(), name, value);
 
466
}
 
467
 
 
468
xpathselect::NodeVector QModelIndexNode::Children() const
 
469
{
 
470
    // Doesn't have any children.
 
471
    xpathselect::NodeVector children;
 
472
    return children;
 
473
}
 
474
 
 
475
// QTableWidgetItemNode
 
476
QTableWidgetItemNode::QTableWidgetItemNode(QTableWidgetItem *item, DBusNode::Ptr parent)
 
477
    : item_(item)
 
478
    , parent_(parent)
 
479
{
 
480
    std::string parent_path = parent ? parent->GetPath() : "";
 
481
    full_path_ = parent_path + "/" + GetName();
 
482
}
 
483
 
 
484
NodeIntrospectionData QTableWidgetItemNode::GetIntrospectionData() const
 
485
{
 
486
    NodeIntrospectionData data;
 
487
    data.object_path = QString::fromStdString(GetPath());
 
488
    data.state = GetProperties();
 
489
    data.state["id"] = PackProperty(GetId());
 
490
    return data;
 
491
}
 
492
 
 
493
QVariantMap QTableWidgetItemNode::GetProperties() const
 
494
{
 
495
    QVariantMap properties;
 
496
 
 
497
    QTableWidget* parent = item_->tableWidget();
 
498
    QRect cellrect = parent->visualItemRect(item_);
 
499
    QRect r = QRect(parent->mapToGlobal(cellrect.topLeft()), cellrect.size());
 
500
    properties["globalRect"] = PackProperty(r);
 
501
 
 
502
    properties["text"] = SafePackProperty(PackProperty(item_->text()));
 
503
    properties["toolTip"] = SafePackProperty(PackProperty(item_->toolTip()));
 
504
    properties["icon"] = SafePackProperty(PackProperty(item_->icon()));
 
505
    properties["whatsThis"] = SafePackProperty(PackProperty(item_->whatsThis()));
 
506
    properties["row"] = SafePackProperty(PackProperty(item_->row()));
 
507
    properties["isSelected"] = SafePackProperty(PackProperty(item_->isSelected()));
 
508
    properties["column"] = SafePackProperty(PackProperty(item_->column()));
 
509
 
 
510
    return properties;
 
511
}
 
512
 
 
513
xpathselect::Node::Ptr QTableWidgetItemNode::GetParent() const
 
514
{
 
515
    return parent_;
 
516
}
 
517
 
 
518
std::string QTableWidgetItemNode::GetName() const
 
519
{
 
520
    return "QTableWidgetItem";
 
521
}
 
522
 
 
523
std::string QTableWidgetItemNode::GetPath() const
 
524
{
 
525
    return full_path_;
 
526
}
 
527
 
 
528
int32_t QTableWidgetItemNode::GetId() const
 
529
{
 
530
    return calculate_ap_id(static_cast<quint64>(reinterpret_cast<quintptr>(item_)));
 
531
}
 
532
 
 
533
bool QTableWidgetItemNode::MatchStringProperty(std::string const& name, std::string const& value) const
 
534
{
 
535
    return MatchProperty(GetProperties(), name, QString::fromStdString(value));
 
536
}
 
537
 
 
538
bool QTableWidgetItemNode::MatchIntegerProperty(std::string const& name, int32_t value) const
 
539
{
 
540
    if (name == "id")
 
541
        return value == GetId();
 
542
 
 
543
    return MatchProperty(GetProperties(), name, value);
 
544
}
 
545
 
 
546
bool QTableWidgetItemNode::MatchBooleanProperty(std::string const& name, bool value) const
 
547
{
 
548
    return MatchProperty(GetProperties(), name, value);
 
549
}
 
550
 
 
551
xpathselect::NodeVector QTableWidgetItemNode::Children() const
 
552
{
 
553
    // Doesn't have any children.
 
554
    xpathselect::NodeVector children;
 
555
    return children;
 
556
}
 
557
 
 
558
// QTreeWidgetItemNode
 
559
QTreeWidgetItemNode::QTreeWidgetItemNode(QTreeWidgetItem *item, DBusNode::Ptr parent)
 
560
    : item_(item)
 
561
    , parent_(parent)
 
562
{
 
563
    std::string parent_path = parent ? parent->GetPath() : "";
 
564
    full_path_ = parent_path + "/" + GetName();
 
565
}
 
566
 
 
567
NodeIntrospectionData QTreeWidgetItemNode::GetIntrospectionData() const
 
568
{
 
569
    NodeIntrospectionData data;
 
570
    data.object_path = QString::fromStdString(GetPath());
 
571
    data.state = GetProperties();
 
572
    data.state["id"] = PackProperty(GetId());
 
573
    return data;
 
574
}
 
575
 
 
576
QVariantMap QTreeWidgetItemNode::GetProperties() const
 
577
{
 
578
    QVariantMap properties;
 
579
    QTreeWidget* parent = item_->treeWidget();
 
580
    QRect cellrect = parent->visualItemRect(item_);
 
581
    QRect r = QRect(parent->viewport()->mapToGlobal(cellrect.topLeft()), cellrect.size());
 
582
    properties["globalRect"] = PackProperty(r);
 
583
 
 
584
    properties["text"] = SafePackProperty(item_->text(0));
 
585
    properties["columns"] = SafePackProperty(item_->columnCount());
 
586
    properties["checkState"] = SafePackProperty(item_->checkState(0));
 
587
 
 
588
    properties["isDisabled"] = SafePackProperty(item_->isDisabled());
 
589
    properties["isExpanded"] = SafePackProperty(item_->isExpanded());
 
590
    properties["isFirstColumnSpanned"] = SafePackProperty(item_->isFirstColumnSpanned());
 
591
    properties["isHidden"] = SafePackProperty(item_->isHidden());
 
592
    properties["isSelected"] = SafePackProperty(item_->isSelected());
 
593
 
 
594
    return properties;
 
595
}
 
596
 
 
597
xpathselect::Node::Ptr QTreeWidgetItemNode::GetParent() const
 
598
{
 
599
    return parent_;
 
600
}
 
601
 
 
602
std::string QTreeWidgetItemNode::GetName() const
 
603
{
 
604
    return "QTreeWidgetItem";
 
605
}
 
606
 
 
607
std::string QTreeWidgetItemNode::GetPath() const
 
608
{
 
609
    return full_path_;
 
610
}
 
611
 
 
612
int32_t QTreeWidgetItemNode::GetId() const
 
613
{
 
614
    return calculate_ap_id(static_cast<quint64>(reinterpret_cast<quintptr>(item_)));
 
615
}
 
616
 
 
617
bool QTreeWidgetItemNode::MatchStringProperty(std::string const& name, std::string const& value) const
 
618
{
 
619
    return MatchProperty(GetProperties(), name, QString::fromStdString(value));
 
620
}
 
621
 
 
622
bool QTreeWidgetItemNode::MatchIntegerProperty(std::string const& name, int32_t value) const
 
623
{
 
624
    if (name == "id")
 
625
        return value == GetId();
 
626
 
 
627
    return MatchProperty(GetProperties(), name, value);
 
628
}
 
629
 
 
630
bool QTreeWidgetItemNode::MatchBooleanProperty(std::string const& name, bool value) const
 
631
{
 
632
    return MatchProperty(GetProperties(), name, value);
 
633
}
 
634
 
 
635
xpathselect::NodeVector QTreeWidgetItemNode::Children() const
 
636
{
 
637
    xpathselect::NodeVector children;
 
638
 
 
639
    for(int i=0; i < item_->childCount(); ++i) {
 
640
        children.push_back(
 
641
            std::make_shared<QTreeWidgetItemNode>(item_->child(i),shared_from_this())
 
642
            );
 
643
    }
 
644
 
 
645
    return children;
 
646
}