| 57 | } |
| 58 | |
| 59 | void ObjectTreeModel::objectAdded(QObject *obj) |
| 60 | { |
| 61 | // see Probe::objectCreated, that promises a valid object in the main thread here |
| 62 | Q_ASSERT(thread() == QThread::currentThread()); |
| 63 | Q_ASSERT(Probe::instance()->isValidObject(obj)); |
| 64 | |
| 65 | IF_DEBUG(cout << "tree obj added: " << hex << obj << " p: " << parentObject(obj) << endl;) |
| 66 | Q_ASSERT(!obj->parent() || Probe::instance()->isValidObject(parentObject(obj))); |
| 67 | |
| 68 | if (indexForObject(obj).isValid()) { |
| 69 | IF_DEBUG(cout << "tree double obj added: " << hex << obj << endl;) |
| 70 | return; |
| 71 | } |
| 72 | |
| 73 | // this is ugly, but apparently it can happen |
| 74 | // that an object gets created without parent |
| 75 | // then later the delayed signal comes in |
| 76 | // so catch this gracefully by first adding the |
| 77 | // parent if required |
| 78 | QModelIndex index = indexForObject(parentObject(obj)); |
| 79 | if (parentObject(obj)) { |
| 80 | if (!index.isValid()) { |
| 81 | IF_DEBUG(cout << "tree: handle parent first" << endl;) |
| 82 | objectAdded(parentObject(obj)); |
| 83 | index = indexForObject(parentObject(obj)); |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | // either we get a proper parent and hence valid index or there is no parent |
| 88 | Q_ASSERT(index.isValid() || !parentObject(obj)); |
| 89 | |
| 90 | QVector<QObject *> &children = m_parentChildMap[parentObject(obj)]; |
| 91 | auto it = std::lower_bound(children.begin(), children.end(), obj); |
| 92 | const int row = std::distance(children.begin(), it); |
| 93 | |
| 94 | beginInsertRows(index, row, row); |
| 95 | |
| 96 | children.insert(it, obj); |
| 97 | m_childParentMap.insert(obj, parentObject(obj)); |
| 98 | |
| 99 | endInsertRows(); |
| 100 | } |
| 101 | |
| 102 | void ObjectTreeModel::objectRemoved(QObject *obj) |
| 103 | { |