| File: | usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h |
| Warning: | line 319, column 9 Potential memory leak |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* dis_stream_dialog.cpp | |||
| 2 | * | |||
| 3 | * Wireshark - Network traffic analyzer | |||
| 4 | * By Gerald Combs <[email protected]> | |||
| 5 | * Copyright 1998 Gerald Combs | |||
| 6 | * | |||
| 7 | * SPDX-License-Identifier: GPL-2.0-or-later | |||
| 8 | */ | |||
| 9 | ||||
| 10 | #include "dis_stream_dialog.h" | |||
| 11 | ||||
| 12 | #include "dis_audio_stream.h" | |||
| 13 | ||||
| 14 | #include <QFile> | |||
| 15 | #include <QFileDialog> | |||
| 16 | #include <QHeaderView> | |||
| 17 | #include <QMenu> | |||
| 18 | #include <QMetaObject> | |||
| 19 | #include <QMessageBox> | |||
| 20 | #include <QFormLayout> | |||
| 21 | #include <QTextStream> | |||
| 22 | #include <QVBoxLayout> | |||
| 23 | ||||
| 24 | #include "epan/addr_resolv.h" | |||
| 25 | ||||
| 26 | #include "main_application.h" | |||
| 27 | ||||
| 28 | DisStreamDialog *DisStreamDialog::pinstance_ = nullptr; | |||
| 29 | std::mutex DisStreamDialog::mutex_; | |||
| 30 | ||||
| 31 | enum { | |||
| 32 | dis_col_start_time = 0, | |||
| 33 | dis_col_end_time, | |||
| 34 | dis_col_src_addr, | |||
| 35 | dis_col_src_port, | |||
| 36 | dis_col_dst_addr, | |||
| 37 | dis_col_dst_port, | |||
| 38 | dis_col_radio, | |||
| 39 | dis_col_entity, | |||
| 40 | dis_col_signal_pkts, | |||
| 41 | dis_col_tx_pkts, | |||
| 42 | dis_col_lost, | |||
| 43 | dis_col_max_delta, | |||
| 44 | dis_col_mean_jitter, | |||
| 45 | dis_col_max_jitter, | |||
| 46 | dis_col_problem, | |||
| 47 | dis_col_count | |||
| 48 | }; | |||
| 49 | ||||
| 50 | static constexpr int disstream_ptr_role = Qt::UserRole + 100; | |||
| 51 | ||||
| 52 | bool | |||
| 53 | DisStreamDialog::DisStreamTreeWidgetItem::operator<(const QTreeWidgetItem &other) const | |||
| 54 | { | |||
| 55 | int sort_col = treeWidget() ? treeWidget()->sortColumn() : 0; | |||
| 56 | QVariant lhs = data(sort_col, Qt::UserRole); | |||
| 57 | QVariant rhs = other.data(sort_col, Qt::UserRole); | |||
| 58 | ||||
| 59 | if (lhs.isValid() && rhs.isValid()) { | |||
| 60 | #if (QT_VERSION((6<<16)|(4<<8)|(2)) >= QT_VERSION_CHECK(6, 0, 0)((6<<16)|(0<<8)|(0))) | |||
| 61 | if (lhs.metaType().id() == QMetaType::Double || rhs.metaType().id() == QMetaType::Double) { | |||
| 62 | #else | |||
| 63 | if (lhs.type() == QVariant::Double || rhs.type() == QVariant::Double) { | |||
| 64 | #endif | |||
| 65 | return lhs.toDouble() < rhs.toDouble(); | |||
| 66 | } | |||
| 67 | ||||
| 68 | return lhs.toLongLong() < rhs.toLongLong(); | |||
| 69 | } | |||
| 70 | ||||
| 71 | return QTreeWidgetItem::operator<(other); | |||
| 72 | } | |||
| 73 | ||||
| 74 | DisStreamDialog * | |||
| 75 | DisStreamDialog::openDisStreamDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list) | |||
| 76 | { | |||
| 77 | std::lock_guard<std::mutex> lock(mutex_); | |||
| 78 | ||||
| 79 | if (!pinstance_) { | |||
| 80 | pinstance_ = new DisStreamDialog(parent, cf, packet_list); | |||
| 81 | } | |||
| 82 | ||||
| 83 | return pinstance_; | |||
| 84 | } | |||
| 85 | ||||
| 86 | DisStreamDialog::DisStreamDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list) : | |||
| 87 | WiresharkDialog(parent, cf), | |||
| 88 | stream_tree_(new QTreeWidget(this)), | |||
| 89 | button_box_(new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this)), | |||
| 90 | filter_button_(nullptr), | |||
| 91 | play_button_(nullptr), | |||
| 92 | stop_button_(nullptr), | |||
| 93 | analyze_button_(nullptr), | |||
| 94 | need_redraw_(false), | |||
| 95 | packet_list_(packet_list) | |||
| 96 | #ifdef QT_MULTIMEDIA_LIB1 | |||
| 97 | , audio_stream_(new DisAudioStream(this)) | |||
| 98 | #endif | |||
| 99 | { | |||
| 100 | QVBoxLayout *layout = new QVBoxLayout(this); | |||
| 101 | QFormLayout *summary_layout = new QFormLayout; | |||
| 102 | ||||
| 103 | setWindowSubtitle(tr("DIS Streams")); | |||
| 104 | ||||
| 105 | layout->addLayout(summary_layout); | |||
| 106 | ||||
| 107 | stream_tree_->setRootIsDecorated(false); | |||
| 108 | stream_tree_->setAlternatingRowColors(true); | |||
| 109 | stream_tree_->setSortingEnabled(true); | |||
| 110 | stream_tree_->setSelectionMode(QAbstractItemView::SingleSelection); | |||
| 111 | stream_tree_->setUniformRowHeights(true); | |||
| 112 | stream_tree_->setContextMenuPolicy(Qt::ActionsContextMenu); | |||
| 113 | stream_tree_->setColumnCount(dis_col_count); | |||
| 114 | stream_tree_->setHeaderLabels(QStringList() | |||
| 115 | << tr("Start") | |||
| 116 | << tr("End") | |||
| 117 | << tr("Src Address") | |||
| 118 | << tr("Src Port") | |||
| 119 | << tr("Dst Address") | |||
| 120 | << tr("Dst Port") | |||
| 121 | << tr("Radio") | |||
| 122 | << tr("Entity") | |||
| 123 | << tr("Signal") | |||
| 124 | << tr("Tx") | |||
| 125 | << tr("Lost") | |||
| 126 | << tr("Max Delta (ms)") | |||
| 127 | << tr("Mean Jitter (ms)") | |||
| 128 | << tr("Max Jitter (ms)") | |||
| 129 | << tr("Pb")); | |||
| 130 | stream_tree_->header()->setSortIndicator(dis_col_start_time, Qt::AscendingOrder); | |||
| 131 | stream_tree_->header()->setSectionResizeMode(QHeaderView::ResizeToContents); | |||
| 132 | ||||
| 133 | layout->addWidget(stream_tree_); | |||
| 134 | ||||
| 135 | filter_button_ = button_box_->addButton(tr("Prepare Filter"), QDialogButtonBox::ActionRole); | |||
| 136 | play_button_ = button_box_->addButton(tr("Play"), QDialogButtonBox::ActionRole); | |||
| 137 | stop_button_ = button_box_->addButton(tr("Stop"), QDialogButtonBox::ActionRole); | |||
| 138 | analyze_button_ = button_box_->addButton(tr("Analyze"), QDialogButtonBox::ActionRole); | |||
| 139 | layout->addWidget(button_box_); | |||
| 140 | ||||
| 141 | connect(button_box_, &QDialogButtonBox::rejected, this, &DisStreamDialog::reject); | |||
| 142 | connect(filter_button_, &QPushButton::clicked, this, &DisStreamDialog::onPrepareFilter); | |||
| 143 | connect(analyze_button_, &QPushButton::clicked, this, &DisStreamDialog::onAnalyzeStream); | |||
| 144 | #ifdef QT_MULTIMEDIA_LIB1 | |||
| 145 | connect(play_button_, &QPushButton::clicked, this, &DisStreamDialog::onPlayStream); | |||
| 146 | connect(stop_button_, &QPushButton::clicked, this, &DisStreamDialog::onStopStream); | |||
| 147 | connect(audio_stream_, &DisAudioStream::playbackStateChanged, | |||
| 148 | this, &DisStreamDialog::onPlaybackStateChanged); | |||
| 149 | #endif | |||
| 150 | connect(stream_tree_, &QTreeWidget::itemSelectionChanged, this, &DisStreamDialog::onStreamSelectionChanged); | |||
| 151 | connect(stream_tree_, &QTreeWidget::itemDoubleClicked, this, &DisStreamDialog::onStreamItemDoubleClicked); | |||
| 152 | connect(&cap_file_, &CaptureFile::captureEvent, this, &DisStreamDialog::onCaptureEvent); | |||
| 153 | ||||
| 154 | if (packet_list_) { | |||
| 155 | connect(this, SIGNAL(goToPacket(int))qFlagLocation("2" "goToPacket(int)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "155"), packet_list_, SLOT(goToPacket(int))qFlagLocation("1" "goToPacket(int)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "155")); | |||
| 156 | } | |||
| 157 | connect(this, SIGNAL(updateFilter(QString, bool))qFlagLocation("2" "updateFilter(QString, bool)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "157"), &parent, SLOT(filterPackets(QString, bool))qFlagLocation("1" "filterPackets(QString, bool)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "157")); | |||
| 158 | ||||
| 159 | memset(&tapinfo_, 0, sizeof(tapinfo_)); | |||
| 160 | tapinfo_.mode = DISSTREAM_TAP_ANALYSE; | |||
| 161 | tapinfo_.tap_reset = tapReset; | |||
| 162 | tapinfo_.tap_draw = tapDraw; | |||
| 163 | ||||
| 164 | register_tap_listener_disstream(&tapinfo_, NULL__null, NULL__null); | |||
| 165 | ||||
| 166 | if (cap_file_.isValid()) { | |||
| 167 | cap_file_.delayedRetapPackets(); | |||
| 168 | } | |||
| 169 | ||||
| 170 | loadGeometry(parent.width() * 4 / 5, parent.height() * 2 / 3); | |||
| 171 | updateWidgets(); | |||
| 172 | } | |||
| 173 | ||||
| 174 | DisStreamDialog::~DisStreamDialog() | |||
| 175 | { | |||
| 176 | std::lock_guard<std::mutex> lock(mutex_); | |||
| 177 | ||||
| 178 | #ifdef QT_MULTIMEDIA_LIB1 | |||
| 179 | audio_stream_->stopPlayback(); | |||
| 180 | #endif | |||
| 181 | ||||
| 182 | disstream_reset(&tapinfo_); | |||
| 183 | remove_tap_listener_disstream(&tapinfo_); | |||
| 184 | pinstance_ = nullptr; | |||
| 185 | } | |||
| 186 | ||||
| 187 | void | |||
| 188 | DisStreamDialog::captureFileClosing() | |||
| 189 | { | |||
| 190 | #ifdef QT_MULTIMEDIA_LIB1 | |||
| 191 | audio_stream_->stopPlayback(); | |||
| 192 | #endif | |||
| 193 | remove_tap_listener_disstream(&tapinfo_); | |||
| 194 | disstream_reset(&tapinfo_); | |||
| 195 | } | |||
| 196 | ||||
| 197 | void | |||
| 198 | DisStreamDialog::captureFileClosed() | |||
| 199 | { | |||
| 200 | #ifdef QT_MULTIMEDIA_LIB1 | |||
| 201 | audio_stream_->stopPlayback(); | |||
| 202 | #endif | |||
| 203 | stream_tree_->clear(); | |||
| 204 | } | |||
| 205 | ||||
| 206 | void | |||
| 207 | DisStreamDialog::tapReset(disstream_tapinfo_t *tapinfo _U___attribute__((unused))) | |||
| 208 | { | |||
| 209 | if (!pinstance_) { | |||
| 210 | return; | |||
| 211 | } | |||
| 212 | ||||
| 213 | pinstance_->need_redraw_ = true; | |||
| 214 | } | |||
| 215 | ||||
| 216 | void | |||
| 217 | DisStreamDialog::tapDraw(disstream_tapinfo_t *tapinfo _U___attribute__((unused))) | |||
| 218 | { | |||
| 219 | if (!pinstance_) { | |||
| ||||
| 220 | return; | |||
| 221 | } | |||
| 222 | ||||
| 223 | pinstance_->need_redraw_ = true; | |||
| 224 | QMetaObject::invokeMethod(pinstance_, [=]() { pinstance_->updateStreams(); }, Qt::QueuedConnection); | |||
| 225 | } | |||
| 226 | ||||
| 227 | disstream_info_t * | |||
| 228 | DisStreamDialog::selectedStream() const | |||
| 229 | { | |||
| 230 | QList<QTreeWidgetItem *> selected = stream_tree_->selectedItems(); | |||
| 231 | if (selected.isEmpty()) { | |||
| 232 | return nullptr; | |||
| 233 | } | |||
| 234 | ||||
| 235 | quintptr ptr = selected.first()->data(0, disstream_ptr_role).value<quintptr>(); | |||
| 236 | return reinterpret_cast<disstream_info_t *>(ptr); | |||
| 237 | } | |||
| 238 | ||||
| 239 | void | |||
| 240 | DisStreamDialog::updateStreams() | |||
| 241 | { | |||
| 242 | GList *list; | |||
| 243 | disstream_info_t *previous = selectedStream(); | |||
| 244 | QTreeWidgetItem *item_to_select = nullptr; | |||
| 245 | ||||
| 246 | if (!need_redraw_ || fileClosed()) { | |||
| 247 | updateWidgets(); | |||
| 248 | return; | |||
| 249 | } | |||
| 250 | ||||
| 251 | stream_tree_->setSortingEnabled(false); | |||
| 252 | stream_tree_->clear(); | |||
| 253 | ||||
| 254 | list = g_list_first(tapinfo_.strinfo_list); | |||
| 255 | while (list) { | |||
| 256 | disstream_info_t *stream_info = (disstream_info_t *)list->data; | |||
| 257 | DisStreamTreeWidgetItem *item; | |||
| 258 | char *src_addr; | |||
| 259 | char *dst_addr; | |||
| 260 | ||||
| 261 | item = new DisStreamTreeWidgetItem(stream_tree_); | |||
| 262 | item->setData(0, disstream_ptr_role, QVariant::fromValue((quintptr)stream_info)); | |||
| 263 | if ((previous && previous == stream_info) || (!previous && !item_to_select)) { | |||
| 264 | item_to_select = item; | |||
| 265 | } | |||
| 266 | ||||
| 267 | src_addr = address_to_display(NULL__null, &stream_info->id.src_addr); | |||
| 268 | dst_addr = address_to_display(NULL__null, &stream_info->id.dst_addr); | |||
| 269 | ||||
| 270 | item->setText(dis_col_start_time, QString::number(nstime_to_sec(&stream_info->start_rel_time), 'f', 6)); | |||
| 271 | item->setData(dis_col_start_time, Qt::UserRole, nstime_to_sec(&stream_info->start_rel_time)); | |||
| 272 | ||||
| 273 | item->setText(dis_col_end_time, QString::number(nstime_to_sec(&stream_info->stop_rel_time), 'f', 6)); | |||
| 274 | item->setData(dis_col_end_time, Qt::UserRole, nstime_to_sec(&stream_info->stop_rel_time)); | |||
| 275 | ||||
| 276 | item->setText(dis_col_src_addr, src_addr); | |||
| 277 | item->setText(dis_col_src_port, QString::number(stream_info->id.src_port)); | |||
| 278 | item->setData(dis_col_src_port, Qt::UserRole, (int)stream_info->id.src_port); | |||
| 279 | ||||
| 280 | item->setText(dis_col_dst_addr, dst_addr); | |||
| 281 | item->setText(dis_col_dst_port, QString::number(stream_info->id.dst_port)); | |||
| 282 | item->setData(dis_col_dst_port, Qt::UserRole, (int)stream_info->id.dst_port); | |||
| 283 | ||||
| 284 | item->setText(dis_col_radio, QStringLiteral("0x%1")(QString(QtPrivate::qMakeStringPrivate(u"" "0x%1"))).arg(stream_info->id.radio_id, 4, 16, QChar('0'))); | |||
| 285 | item->setData(dis_col_radio, Qt::UserRole, (int)stream_info->id.radio_id); | |||
| 286 | ||||
| 287 | item->setText(dis_col_entity, QStringLiteral("%1/%2/%3")(QString(QtPrivate::qMakeStringPrivate(u"" "%1/%2/%3"))) | |||
| 288 | .arg(stream_info->id.entity_id_site) | |||
| 289 | .arg(stream_info->id.entity_id_appl) | |||
| 290 | .arg(stream_info->id.entity_id_entity)); | |||
| 291 | ||||
| 292 | item->setText(dis_col_signal_pkts, QString::number(stream_info->signal_packet_count)); | |||
| 293 | item->setData(dis_col_signal_pkts, Qt::UserRole, (int)stream_info->signal_packet_count); | |||
| 294 | ||||
| 295 | item->setText(dis_col_tx_pkts, QString::number(stream_info->transmitter_packet_count)); | |||
| 296 | item->setData(dis_col_tx_pkts, Qt::UserRole, (int)stream_info->transmitter_packet_count); | |||
| 297 | ||||
| 298 | item->setText(dis_col_lost, QString::number(stream_info->estimated_lost_packets)); | |||
| 299 | item->setData(dis_col_lost, Qt::UserRole, (int)stream_info->estimated_lost_packets); | |||
| 300 | ||||
| 301 | item->setText(dis_col_max_delta, QString::number(stream_info->max_delta_ms, 'f', 3)); | |||
| 302 | item->setData(dis_col_max_delta, Qt::UserRole, stream_info->max_delta_ms); | |||
| 303 | ||||
| 304 | item->setText(dis_col_mean_jitter, QString::number(stream_info->mean_jitter_ms, 'f', 3)); | |||
| 305 | item->setData(dis_col_mean_jitter, Qt::UserRole, stream_info->mean_jitter_ms); | |||
| 306 | ||||
| 307 | item->setText(dis_col_max_jitter, QString::number(stream_info->max_jitter_ms, 'f', 3)); | |||
| 308 | item->setData(dis_col_max_jitter, Qt::UserRole, stream_info->max_jitter_ms); | |||
| 309 | ||||
| 310 | item->setText(dis_col_problem, stream_info->problem ? tr("X") : QString()); | |||
| 311 | item->setTextAlignment(dis_col_problem, Qt::AlignCenter); | |||
| 312 | ||||
| 313 | wmem_free(NULL__null, src_addr); | |||
| 314 | wmem_free(NULL__null, dst_addr); | |||
| 315 | ||||
| 316 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : __null); | |||
| 317 | } | |||
| 318 | ||||
| 319 | stream_tree_->setSortingEnabled(true); | |||
| 320 | stream_tree_->sortByColumn(stream_tree_->header()->sortIndicatorSection(), | |||
| 321 | stream_tree_->header()->sortIndicatorOrder()); | |||
| 322 | if (item_to_select) { | |||
| 323 | stream_tree_->setCurrentItem(item_to_select); | |||
| 324 | } | |||
| 325 | ||||
| 326 | need_redraw_ = false; | |||
| 327 | updateWidgets(); | |||
| 328 | } | |||
| 329 | ||||
| 330 | void | |||
| 331 | DisStreamDialog::updateWidgets() | |||
| 332 | { | |||
| 333 | bool has_capture = cap_file_.isValid() && !fileClosed(); | |||
| 334 | disstream_info_t *stream_info = selectedStream(); | |||
| 335 | bool has_selection = stream_info != nullptr; | |||
| 336 | bool has_audio_data = has_selection && stream_info->signal_packets && stream_info->signal_packets->len > 0; | |||
| 337 | ||||
| 338 | stream_tree_->setEnabled(has_capture); | |||
| 339 | filter_button_->setEnabled(has_capture && has_selection); | |||
| 340 | play_button_->setEnabled(has_capture && has_audio_data); | |||
| 341 | analyze_button_->setEnabled(has_capture && has_selection); | |||
| 342 | #ifdef QT_MULTIMEDIA_LIB1 | |||
| 343 | stop_button_->setEnabled(audio_stream_->isPlaying()); | |||
| 344 | #else | |||
| 345 | stop_button_->setEnabled(false); | |||
| 346 | #endif | |||
| 347 | } | |||
| 348 | ||||
| 349 | void | |||
| 350 | DisStreamDialog::onStreamSelectionChanged() | |||
| 351 | { | |||
| 352 | updateWidgets(); | |||
| 353 | } | |||
| 354 | ||||
| 355 | void | |||
| 356 | DisStreamDialog::onStreamItemDoubleClicked(QTreeWidgetItem *item, int column _U___attribute__((unused))) | |||
| 357 | { | |||
| 358 | quintptr ptr; | |||
| 359 | disstream_info_t *stream_info; | |||
| 360 | ||||
| 361 | if (!item) { | |||
| 362 | return; | |||
| 363 | } | |||
| 364 | ||||
| 365 | ptr = item->data(0, disstream_ptr_role).value<quintptr>(); | |||
| 366 | stream_info = reinterpret_cast<disstream_info_t *>(ptr); | |||
| 367 | if (stream_info && stream_info->first_packet_num > 0) { | |||
| 368 | emit goToPacket((int)stream_info->first_packet_num); | |||
| 369 | } | |||
| 370 | } | |||
| 371 | ||||
| 372 | void | |||
| 373 | DisStreamDialog::onPrepareFilter() | |||
| 374 | { | |||
| 375 | disstream_info_t *stream_info = selectedStream(); | |||
| 376 | QString filter; | |||
| 377 | ||||
| 378 | if (!stream_info) { | |||
| 379 | return; | |||
| 380 | } | |||
| 381 | ||||
| 382 | filter = QStringLiteral((QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && " "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && " "dis.entity_id_application==%5 && dis.entity_id_entity==%6" ))) | |||
| 383 | "dis && udp.srcport==%1 && udp.dstport==%2 && "(QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && " "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && " "dis.entity_id_application==%5 && dis.entity_id_entity==%6" ))) | |||
| 384 | "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && "(QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && " "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && " "dis.entity_id_application==%5 && dis.entity_id_entity==%6" ))) | |||
| 385 | "dis.entity_id_application==%5 && dis.entity_id_entity==%6")(QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && " "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && " "dis.entity_id_application==%5 && dis.entity_id_entity==%6" ))) | |||
| 386 | .arg(stream_info->id.src_port) | |||
| 387 | .arg(stream_info->id.dst_port) | |||
| 388 | .arg(stream_info->id.radio_id) | |||
| 389 | .arg(stream_info->id.entity_id_site) | |||
| 390 | .arg(stream_info->id.entity_id_appl) | |||
| 391 | .arg(stream_info->id.entity_id_entity); | |||
| 392 | ||||
| 393 | emit updateFilter(filter, true); | |||
| 394 | } | |||
| 395 | ||||
| 396 | void | |||
| 397 | DisStreamDialog::onAnalyzeStream() | |||
| 398 | { | |||
| 399 | disstream_info_t *stream_info = selectedStream(); | |||
| 400 | QWidget *parent_widget = qobject_cast<QWidget *>(parent()); | |||
| 401 | ||||
| 402 | if (!stream_info) { | |||
| 403 | return; | |||
| 404 | } | |||
| 405 | ||||
| 406 | if (!parent_widget) { | |||
| 407 | parent_widget = this; | |||
| 408 | } | |||
| 409 | ||||
| 410 | DisStreamAnalysisDialog *dialog = DisStreamAnalysisDialog::openDisStreamAnalysisDialog( | |||
| 411 | *parent_widget, cap_file_, packet_list_); | |||
| 412 | dialog->selectStream(stream_info); | |||
| 413 | dialog->show(); | |||
| 414 | dialog->raise(); | |||
| 415 | dialog->activateWindow(); | |||
| 416 | } | |||
| 417 | ||||
| 418 | #ifdef QT_MULTIMEDIA_LIB1 | |||
| 419 | void | |||
| 420 | DisStreamDialog::onPlayStream() | |||
| 421 | { | |||
| 422 | disstream_info_t *stream_info = selectedStream(); | |||
| 423 | QString error_message; | |||
| 424 | ||||
| 425 | if (!audio_stream_->playDisStream(stream_info, error_message)) { | |||
| 426 | QMessageBox::warning(this, tr("DIS Playback"), error_message); | |||
| 427 | return; | |||
| 428 | } | |||
| 429 | updateWidgets(); | |||
| 430 | } | |||
| 431 | ||||
| 432 | void | |||
| 433 | DisStreamDialog::onStopStream() | |||
| 434 | { | |||
| 435 | audio_stream_->stopPlayback(); | |||
| 436 | updateWidgets(); | |||
| 437 | } | |||
| 438 | ||||
| 439 | void | |||
| 440 | DisStreamDialog::onPlaybackStateChanged(QAudio::State state _U___attribute__((unused))) | |||
| 441 | { | |||
| 442 | updateWidgets(); | |||
| 443 | } | |||
| 444 | #endif | |||
| 445 | ||||
| 446 | void | |||
| 447 | DisStreamDialog::onCaptureEvent(CaptureEvent e) | |||
| 448 | { | |||
| 449 | if (e.captureContext() == CaptureEvent::Retap) { | |||
| 450 | need_redraw_ = true; | |||
| 451 | } | |||
| 452 | ||||
| 453 | updateStreams(); | |||
| 454 | } |
| 1 | // Copyright (C) 2022 The Qt Company Ltd. | |||
| 2 | // Copyright (C) 2019 Intel Corporation. | |||
| 3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only | |||
| 4 | ||||
| 5 | #ifndef QOBJECTDEFS_H | |||
| 6 | #define QOBJECTDEFS_H | |||
| 7 | ||||
| 8 | #if defined(__OBJC__) && !defined(__cplusplus201703L) | |||
| 9 | # warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)" | |||
| 10 | #endif | |||
| 11 | ||||
| 12 | #include <QtCore/qnamespace.h> | |||
| 13 | #include <QtCore/qobjectdefs_impl.h> | |||
| 14 | #include <QtCore/qtmetamacros.h> | |||
| 15 | ||||
| 16 | QT_BEGIN_NAMESPACE | |||
| 17 | ||||
| 18 | class QByteArray; | |||
| 19 | struct QArrayData; | |||
| 20 | ||||
| 21 | class QString; | |||
| 22 | ||||
| 23 | #ifndef QT_NO_META_MACROS | |||
| 24 | // macro for onaming members | |||
| 25 | #ifdef METHOD | |||
| 26 | #undef METHOD | |||
| 27 | #endif | |||
| 28 | #ifdef SLOT | |||
| 29 | #undef SLOT | |||
| 30 | #endif | |||
| 31 | #ifdef SIGNAL | |||
| 32 | #undef SIGNAL | |||
| 33 | #endif | |||
| 34 | #endif // QT_NO_META_MACROS | |||
| 35 | ||||
| 36 | Q_CORE_EXPORT__attribute__((visibility("default"))) const char *qFlagLocation(const char *method); | |||
| 37 | ||||
| 38 | #ifndef QT_NO_META_MACROS | |||
| 39 | # define QMETHOD_CODE0 0 // member type codes | |||
| 40 | # define QSLOT_CODE1 1 | |||
| 41 | # define QSIGNAL_CODE2 2 | |||
| 42 | # define QT_PREFIX_CODE(code, a)"code" "a" QT_STRINGIFY(code)"code" #a | |||
| 43 | # define QT_STRINGIFY_METHOD(a)"0" "a" QT_PREFIX_CODE(QMETHOD_CODE, a)"0" "a" | |||
| 44 | # define QT_STRINGIFY_SLOT(a)"1" "a" QT_PREFIX_CODE(QSLOT_CODE, a)"1" "a" | |||
| 45 | # define QT_STRINGIFY_SIGNAL(a)"2" "a" QT_PREFIX_CODE(QSIGNAL_CODE, a)"2" "a" | |||
| 46 | # ifndef QT_NO_DEBUG | |||
| 47 | # define QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "47" "\0" __FILE__"/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" QT_STRINGIFY(__LINE__)"47" | |||
| 48 | # ifndef QT_NO_KEYWORDS | |||
| 49 | # define METHOD(a)qFlagLocation("0" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "49") qFlagLocation(QT_STRINGIFY_METHOD(a)"0" "a" QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "49") | |||
| 50 | # endif | |||
| 51 | # define SLOT(a)qFlagLocation("1" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "51") qFlagLocation(QT_STRINGIFY_SLOT(a)"1" "a" QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "51") | |||
| 52 | # define SIGNAL(a)qFlagLocation("2" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "52") qFlagLocation(QT_STRINGIFY_SIGNAL(a)"2" "a" QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "52") | |||
| 53 | # else | |||
| 54 | # ifndef QT_NO_KEYWORDS | |||
| 55 | # define METHOD(a)qFlagLocation("0" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "55") QT_STRINGIFY_METHOD(a)"0" "a" | |||
| 56 | # endif | |||
| 57 | # define SLOT(a)qFlagLocation("1" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "57") QT_STRINGIFY_SLOT(a)"1" "a" | |||
| 58 | # define SIGNAL(a)qFlagLocation("2" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "58") QT_STRINGIFY_SIGNAL(a)"2" "a" | |||
| 59 | # endif | |||
| 60 | #endif // QT_NO_META_MACROS | |||
| 61 | ||||
| 62 | #define Q_ARG(type, data)QArgument<type >("type", data) QArgument<type >(#type, data) | |||
| 63 | #define Q_RETURN_ARG(type, data)QReturnArgument<type >("type", data) QReturnArgument<type >(#type, data) | |||
| 64 | ||||
| 65 | class QObject; | |||
| 66 | class QMetaMethod; | |||
| 67 | class QMetaEnum; | |||
| 68 | class QMetaProperty; | |||
| 69 | class QMetaClassInfo; | |||
| 70 | ||||
| 71 | namespace QtPrivate { | |||
| 72 | class QMetaTypeInterface; | |||
| 73 | } | |||
| 74 | ||||
| 75 | struct QMethodRawArguments | |||
| 76 | { | |||
| 77 | void **arguments; | |||
| 78 | }; | |||
| 79 | ||||
| 80 | class Q_CORE_EXPORT__attribute__((visibility("default"))) QGenericArgument | |||
| 81 | { | |||
| 82 | public: | |||
| 83 | inline QGenericArgument(const char *aName = nullptr, const void *aData = nullptr) | |||
| 84 | : _data(aData), _name(aName) {} | |||
| 85 | inline void *data() const { return const_cast<void *>(_data); } | |||
| 86 | inline const char *name() const { return _name; } | |||
| 87 | ||||
| 88 | private: | |||
| 89 | const void *_data; | |||
| 90 | const char *_name; | |||
| 91 | }; | |||
| 92 | ||||
| 93 | class Q_CORE_EXPORT__attribute__((visibility("default"))) QGenericReturnArgument: public QGenericArgument | |||
| 94 | { | |||
| 95 | public: | |||
| 96 | inline QGenericReturnArgument(const char *aName = nullptr, void *aData = nullptr) | |||
| 97 | : QGenericArgument(aName, aData) | |||
| 98 | {} | |||
| 99 | }; | |||
| 100 | ||||
| 101 | template <class T> | |||
| 102 | class QArgument: public QGenericArgument | |||
| 103 | { | |||
| 104 | public: | |||
| 105 | inline QArgument(const char *aName, const T &aData) | |||
| 106 | : QGenericArgument(aName, static_cast<const void *>(&aData)) | |||
| 107 | {} | |||
| 108 | }; | |||
| 109 | template <class T> | |||
| 110 | class QArgument<T &>: public QGenericArgument | |||
| 111 | { | |||
| 112 | public: | |||
| 113 | inline QArgument(const char *aName, T &aData) | |||
| 114 | : QGenericArgument(aName, static_cast<const void *>(&aData)) | |||
| 115 | {} | |||
| 116 | }; | |||
| 117 | ||||
| 118 | ||||
| 119 | template <typename T> | |||
| 120 | class QReturnArgument: public QGenericReturnArgument | |||
| 121 | { | |||
| 122 | public: | |||
| 123 | inline QReturnArgument(const char *aName, T &aData) | |||
| 124 | : QGenericReturnArgument(aName, static_cast<void *>(&aData)) | |||
| 125 | {} | |||
| 126 | }; | |||
| 127 | ||||
| 128 | struct Q_CORE_EXPORT__attribute__((visibility("default"))) QMetaObject | |||
| 129 | { | |||
| 130 | class Connection; | |||
| 131 | const char *className() const; | |||
| 132 | const QMetaObject *superClass() const; | |||
| 133 | ||||
| 134 | bool inherits(const QMetaObject *metaObject) const noexcept; | |||
| 135 | QObject *cast(QObject *obj) const | |||
| 136 | { return const_cast<QObject *>(cast(const_cast<const QObject *>(obj))); } | |||
| 137 | const QObject *cast(const QObject *obj) const; | |||
| 138 | ||||
| 139 | #if !defined(QT_NO_TRANSLATION) || defined(Q_CLANG_QDOC) | |||
| 140 | QString tr(const char *s, const char *c, int n = -1) const; | |||
| 141 | #endif // QT_NO_TRANSLATION | |||
| 142 | ||||
| 143 | QMetaType metaType() const; | |||
| 144 | ||||
| 145 | int methodOffset() const; | |||
| 146 | int enumeratorOffset() const; | |||
| 147 | int propertyOffset() const; | |||
| 148 | int classInfoOffset() const; | |||
| 149 | ||||
| 150 | int constructorCount() const; | |||
| 151 | int methodCount() const; | |||
| 152 | int enumeratorCount() const; | |||
| 153 | int propertyCount() const; | |||
| 154 | int classInfoCount() const; | |||
| 155 | ||||
| 156 | int indexOfConstructor(const char *constructor) const; | |||
| 157 | int indexOfMethod(const char *method) const; | |||
| 158 | int indexOfSignal(const char *signal) const; | |||
| 159 | int indexOfSlot(const char *slot) const; | |||
| 160 | int indexOfEnumerator(const char *name) const; | |||
| 161 | int indexOfProperty(const char *name) const; | |||
| 162 | int indexOfClassInfo(const char *name) const; | |||
| 163 | ||||
| 164 | QMetaMethod constructor(int index) const; | |||
| 165 | QMetaMethod method(int index) const; | |||
| 166 | QMetaEnum enumerator(int index) const; | |||
| 167 | QMetaProperty property(int index) const; | |||
| 168 | QMetaClassInfo classInfo(int index) const; | |||
| 169 | QMetaProperty userProperty() const; | |||
| 170 | ||||
| 171 | static bool checkConnectArgs(const char *signal, const char *method); | |||
| 172 | static bool checkConnectArgs(const QMetaMethod &signal, | |||
| 173 | const QMetaMethod &method); | |||
| 174 | static QByteArray normalizedSignature(const char *method); | |||
| 175 | static QByteArray normalizedType(const char *type); | |||
| 176 | ||||
| 177 | // internal index-based connect | |||
| 178 | static Connection connect(const QObject *sender, int signal_index, | |||
| 179 | const QObject *receiver, int method_index, | |||
| 180 | int type = 0, int *types = nullptr); | |||
| 181 | // internal index-based disconnect | |||
| 182 | static bool disconnect(const QObject *sender, int signal_index, | |||
| 183 | const QObject *receiver, int method_index); | |||
| 184 | static bool disconnectOne(const QObject *sender, int signal_index, | |||
| 185 | const QObject *receiver, int method_index); | |||
| 186 | // internal slot-name based connect | |||
| 187 | static void connectSlotsByName(QObject *o); | |||
| 188 | ||||
| 189 | // internal index-based signal activation | |||
| 190 | static void activate(QObject *sender, int signal_index, void **argv); | |||
| 191 | static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv); | |||
| 192 | static void activate(QObject *sender, int signal_offset, int local_signal_index, void **argv); | |||
| 193 | ||||
| 194 | static bool invokeMethod(QObject *obj, const char *member, | |||
| 195 | Qt::ConnectionType, | |||
| 196 | QGenericReturnArgument ret, | |||
| 197 | QGenericArgument val0 = QGenericArgument(nullptr), | |||
| 198 | QGenericArgument val1 = QGenericArgument(), | |||
| 199 | QGenericArgument val2 = QGenericArgument(), | |||
| 200 | QGenericArgument val3 = QGenericArgument(), | |||
| 201 | QGenericArgument val4 = QGenericArgument(), | |||
| 202 | QGenericArgument val5 = QGenericArgument(), | |||
| 203 | QGenericArgument val6 = QGenericArgument(), | |||
| 204 | QGenericArgument val7 = QGenericArgument(), | |||
| 205 | QGenericArgument val8 = QGenericArgument(), | |||
| 206 | QGenericArgument val9 = QGenericArgument()); | |||
| 207 | ||||
| 208 | static inline bool invokeMethod(QObject *obj, const char *member, | |||
| 209 | QGenericReturnArgument ret, | |||
| 210 | QGenericArgument val0 = QGenericArgument(nullptr), | |||
| 211 | QGenericArgument val1 = QGenericArgument(), | |||
| 212 | QGenericArgument val2 = QGenericArgument(), | |||
| 213 | QGenericArgument val3 = QGenericArgument(), | |||
| 214 | QGenericArgument val4 = QGenericArgument(), | |||
| 215 | QGenericArgument val5 = QGenericArgument(), | |||
| 216 | QGenericArgument val6 = QGenericArgument(), | |||
| 217 | QGenericArgument val7 = QGenericArgument(), | |||
| 218 | QGenericArgument val8 = QGenericArgument(), | |||
| 219 | QGenericArgument val9 = QGenericArgument()) | |||
| 220 | { | |||
| 221 | return invokeMethod(obj, member, Qt::AutoConnection, ret, val0, val1, val2, val3, | |||
| 222 | val4, val5, val6, val7, val8, val9); | |||
| 223 | } | |||
| 224 | ||||
| 225 | static inline bool invokeMethod(QObject *obj, const char *member, | |||
| 226 | Qt::ConnectionType type, | |||
| 227 | QGenericArgument val0 = QGenericArgument(nullptr), | |||
| 228 | QGenericArgument val1 = QGenericArgument(), | |||
| 229 | QGenericArgument val2 = QGenericArgument(), | |||
| 230 | QGenericArgument val3 = QGenericArgument(), | |||
| 231 | QGenericArgument val4 = QGenericArgument(), | |||
| 232 | QGenericArgument val5 = QGenericArgument(), | |||
| 233 | QGenericArgument val6 = QGenericArgument(), | |||
| 234 | QGenericArgument val7 = QGenericArgument(), | |||
| 235 | QGenericArgument val8 = QGenericArgument(), | |||
| 236 | QGenericArgument val9 = QGenericArgument()) | |||
| 237 | { | |||
| 238 | return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2, | |||
| 239 | val3, val4, val5, val6, val7, val8, val9); | |||
| 240 | } | |||
| 241 | ||||
| 242 | static inline bool invokeMethod(QObject *obj, const char *member, | |||
| 243 | QGenericArgument val0 = QGenericArgument(nullptr), | |||
| 244 | QGenericArgument val1 = QGenericArgument(), | |||
| 245 | QGenericArgument val2 = QGenericArgument(), | |||
| 246 | QGenericArgument val3 = QGenericArgument(), | |||
| 247 | QGenericArgument val4 = QGenericArgument(), | |||
| 248 | QGenericArgument val5 = QGenericArgument(), | |||
| 249 | QGenericArgument val6 = QGenericArgument(), | |||
| 250 | QGenericArgument val7 = QGenericArgument(), | |||
| 251 | QGenericArgument val8 = QGenericArgument(), | |||
| 252 | QGenericArgument val9 = QGenericArgument()) | |||
| 253 | { | |||
| 254 | return invokeMethod(obj, member, Qt::AutoConnection, QGenericReturnArgument(), val0, | |||
| 255 | val1, val2, val3, val4, val5, val6, val7, val8, val9); | |||
| 256 | } | |||
| 257 | ||||
| 258 | #ifdef Q_CLANG_QDOC | |||
| 259 | template<typename Functor, typename FunctorReturnType> | |||
| 260 | static bool invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr); | |||
| 261 | template<typename Functor, typename FunctorReturnType> | |||
| 262 | static bool invokeMethod(QObject *context, Functor function, FunctorReturnType *ret); | |||
| 263 | #else | |||
| 264 | ||||
| 265 | // invokeMethod() for member function pointer | |||
| 266 | template <typename Func> | |||
| 267 | static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction | |||
| 268 | && !std::is_convertible<Func, const char*>::value | |||
| 269 | && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type | |||
| 270 | invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object, | |||
| 271 | Func function, | |||
| 272 | Qt::ConnectionType type = Qt::AutoConnection, | |||
| 273 | typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr) | |||
| 274 | { | |||
| 275 | return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), type, ret); | |||
| 276 | } | |||
| 277 | ||||
| 278 | template <typename Func> | |||
| 279 | static typename std::enable_if<QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction | |||
| 280 | && !std::is_convertible<Func, const char*>::value | |||
| 281 | && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type | |||
| 282 | invokeMethod(typename QtPrivate::FunctionPointer<Func>::Object *object, | |||
| 283 | Func function, | |||
| 284 | typename QtPrivate::FunctionPointer<Func>::ReturnType *ret) | |||
| 285 | { | |||
| 286 | return invokeMethodImpl(object, new QtPrivate::QSlotObjectWithNoArgs<Func>(function), Qt::AutoConnection, ret); | |||
| 287 | } | |||
| 288 | ||||
| 289 | // invokeMethod() for function pointer (not member) | |||
| 290 | template <typename Func> | |||
| 291 | static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction | |||
| 292 | && !std::is_convertible<Func, const char*>::value | |||
| 293 | && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type | |||
| 294 | invokeMethod(QObject *context, Func function, | |||
| 295 | Qt::ConnectionType type = Qt::AutoConnection, | |||
| 296 | typename QtPrivate::FunctionPointer<Func>::ReturnType *ret = nullptr) | |||
| 297 | { | |||
| 298 | return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), type, ret); | |||
| 299 | } | |||
| 300 | ||||
| 301 | template <typename Func> | |||
| 302 | static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction | |||
| 303 | && !std::is_convertible<Func, const char*>::value | |||
| 304 | && QtPrivate::FunctionPointer<Func>::ArgumentCount == 0, bool>::type | |||
| 305 | invokeMethod(QObject *context, Func function, | |||
| 306 | typename QtPrivate::FunctionPointer<Func>::ReturnType *ret) | |||
| 307 | { | |||
| 308 | return invokeMethodImpl(context, new QtPrivate::QFunctorSlotObjectWithNoArgsImplicitReturn<Func>(function), Qt::AutoConnection, ret); | |||
| 309 | } | |||
| 310 | ||||
| 311 | // invokeMethod() for Functor | |||
| 312 | template <typename Func> | |||
| 313 | static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction | |||
| 314 | && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1 | |||
| 315 | && !std::is_convertible<Func, const char*>::value, bool>::type | |||
| 316 | invokeMethod(QObject *context, Func function, | |||
| 317 | Qt::ConnectionType type = Qt::AutoConnection, decltype(function()) *ret = nullptr) | |||
| 318 | { | |||
| 319 | return invokeMethodImpl(context, | |||
| ||||
| 320 | new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)), | |||
| 321 | type, | |||
| 322 | ret); | |||
| 323 | } | |||
| 324 | ||||
| 325 | template <typename Func> | |||
| 326 | static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction | |||
| 327 | && QtPrivate::FunctionPointer<Func>::ArgumentCount == -1 | |||
| 328 | && !std::is_convertible<Func, const char*>::value, bool>::type | |||
| 329 | invokeMethod(QObject *context, Func function, decltype(function()) *ret) | |||
| 330 | { | |||
| 331 | return invokeMethodImpl(context, | |||
| 332 | new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)), | |||
| 333 | Qt::AutoConnection, | |||
| 334 | ret); | |||
| 335 | } | |||
| 336 | ||||
| 337 | #endif | |||
| 338 | ||||
| 339 | QObject *newInstance(QGenericArgument val0 = QGenericArgument(nullptr), | |||
| 340 | QGenericArgument val1 = QGenericArgument(), | |||
| 341 | QGenericArgument val2 = QGenericArgument(), | |||
| 342 | QGenericArgument val3 = QGenericArgument(), | |||
| 343 | QGenericArgument val4 = QGenericArgument(), | |||
| 344 | QGenericArgument val5 = QGenericArgument(), | |||
| 345 | QGenericArgument val6 = QGenericArgument(), | |||
| 346 | QGenericArgument val7 = QGenericArgument(), | |||
| 347 | QGenericArgument val8 = QGenericArgument(), | |||
| 348 | QGenericArgument val9 = QGenericArgument()) const; | |||
| 349 | ||||
| 350 | enum Call { | |||
| 351 | InvokeMetaMethod, | |||
| 352 | ReadProperty, | |||
| 353 | WriteProperty, | |||
| 354 | ResetProperty, | |||
| 355 | CreateInstance, | |||
| 356 | IndexOfMethod, | |||
| 357 | RegisterPropertyMetaType, | |||
| 358 | RegisterMethodArgumentMetaType, | |||
| 359 | BindableProperty, | |||
| 360 | CustomCall | |||
| 361 | }; | |||
| 362 | ||||
| 363 | int static_metacall(Call, int, void **) const; | |||
| 364 | static int metacall(QObject *, Call, int, void **); | |||
| 365 | ||||
| 366 | template <const QMetaObject &MO> static constexpr const QMetaObject *staticMetaObject() | |||
| 367 | { | |||
| 368 | return &MO; | |||
| 369 | } | |||
| 370 | ||||
| 371 | struct SuperData { | |||
| 372 | using Getter = const QMetaObject *(*)(); | |||
| 373 | const QMetaObject *direct; | |||
| 374 | SuperData() = default; | |||
| 375 | constexpr SuperData(std::nullptr_t) : direct(nullptr) {} | |||
| 376 | constexpr SuperData(const QMetaObject *mo) : direct(mo) {} | |||
| 377 | ||||
| 378 | constexpr const QMetaObject *operator->() const { return operator const QMetaObject *(); } | |||
| 379 | ||||
| 380 | #ifdef QT_NO_DATA_RELOCATION | |||
| 381 | Getter indirect = nullptr; | |||
| 382 | constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {} | |||
| 383 | constexpr operator const QMetaObject *() const | |||
| 384 | { return indirect ? indirect() : direct; } | |||
| 385 | template <const QMetaObject &MO> static constexpr SuperData link() | |||
| 386 | { return SuperData(QMetaObject::staticMetaObject<MO>); } | |||
| 387 | #else | |||
| 388 | constexpr SuperData(Getter g) : direct(g()) {} | |||
| 389 | constexpr operator const QMetaObject *() const | |||
| 390 | { return direct; } | |||
| 391 | template <const QMetaObject &MO> static constexpr SuperData link() | |||
| 392 | { return SuperData(QMetaObject::staticMetaObject<MO>()); } | |||
| 393 | #endif | |||
| 394 | }; | |||
| 395 | ||||
| 396 | struct Data { // private data | |||
| 397 | SuperData superdata; | |||
| 398 | const uint *stringdata; | |||
| 399 | const uint *data; | |||
| 400 | typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **); | |||
| 401 | StaticMetacallFunction static_metacall; | |||
| 402 | const SuperData *relatedMetaObjects; | |||
| 403 | const QtPrivate::QMetaTypeInterface *const *metaTypes; | |||
| 404 | void *extradata; //reserved for future use | |||
| 405 | } d; | |||
| 406 | ||||
| 407 | private: | |||
| 408 | static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type, void *ret); | |||
| 409 | friend class QTimer; | |||
| 410 | }; | |||
| 411 | ||||
| 412 | class Q_CORE_EXPORT__attribute__((visibility("default"))) QMetaObject::Connection { | |||
| 413 | void *d_ptr; //QObjectPrivate::Connection* | |||
| 414 | explicit Connection(void *data) : d_ptr(data) { } | |||
| 415 | friend class QObject; | |||
| 416 | friend class QObjectPrivate; | |||
| 417 | friend struct QMetaObject; | |||
| 418 | bool isConnected_helper() const; | |||
| 419 | public: | |||
| 420 | ~Connection(); | |||
| 421 | Connection(); | |||
| 422 | Connection(const Connection &other); | |||
| 423 | Connection &operator=(const Connection &other); | |||
| 424 | #ifdef Q_QDOC | |||
| 425 | operator bool() const; | |||
| 426 | #else | |||
| 427 | // still using the restricted bool trick here, in order to support | |||
| 428 | // code using copy-init (e.g. `bool ok = connect(...)`) | |||
| 429 | typedef void *Connection::*RestrictedBool; | |||
| 430 | operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : nullptr; } | |||
| 431 | #endif | |||
| 432 | ||||
| 433 | Connection(Connection &&other) noexcept : d_ptr(qExchange(other.d_ptr, nullptr)) {} | |||
| 434 | QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Connection)Connection &operator=(Connection &&other) noexcept { swap(other); return *this; } | |||
| 435 | void swap(Connection &other) noexcept { qt_ptr_swap(d_ptr, other.d_ptr); } | |||
| 436 | }; | |||
| 437 | ||||
| 438 | inline void swap(QMetaObject::Connection &lhs, QMetaObject::Connection &rhs) noexcept | |||
| 439 | { | |||
| 440 | lhs.swap(rhs); | |||
| 441 | } | |||
| 442 | ||||
| 443 | inline const QMetaObject *QMetaObject::superClass() const | |||
| 444 | { return d.superdata; } | |||
| 445 | ||||
| 446 | namespace QtPrivate { | |||
| 447 | /* Trait that tells is a the Object has a Q_OBJECT macro */ | |||
| 448 | template <typename Object> struct HasQ_OBJECT_Macro { | |||
| 449 | template <typename T> | |||
| 450 | static char test(int (T::*)(QMetaObject::Call, int, void **)); | |||
| 451 | static int test(int (Object::*)(QMetaObject::Call, int, void **)); | |||
| 452 | enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) }; | |||
| 453 | }; | |||
| 454 | } | |||
| 455 | ||||
| 456 | QT_END_NAMESPACE | |||
| 457 | ||||
| 458 | #endif // QOBJECTDEFS_H |