### Bug Summary

File: | usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h
Warning: | line 319, column 9 Potential memory leak

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dis_stream_dialog.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/build/ui/qt -isystem /builds/wireshark/wireshark/ui/qt -isystem /builds/wireshark/wireshark/ui/qt/lua_debugger -isystem /usr/include/x86_64-linux-gnu/qt6/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt6 -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt6/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt6/QtGui -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore5Compat -isystem /usr/include/x86_64-linux-gnu/qt6/QtConcurrent -isystem /usr/include/x86_64-linux-gnu/qt6/QtPrintSupport -isystem /usr/include/x86_64-linux-gnu/qt6/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt6/QtMultimedia -isystem /usr/include/x86_64-linux-gnu/qt6/QtDBus -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D QT_CONCURRENT_LIB -D QT_CORE5COMPAT_LIB -D QT_CORE_LIB -D QT_DBUS_LIB -D QT_GUI_LIB -D QT_MULTIMEDIA_LIB -D QT_NETWORK_LIB -D QT_PRINTSUPPORT_LIB -D QT_WIDGETS_LIB -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build/ui/qt/qtui_autogen/include -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=c++17 -fdeprecated-macro -ferror-limit 19 -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-05-14-100333-3641-1 -x c++ /builds/wireshark/wireshark/ui/qt/dis_stream_dialog.cpp

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

#### /builds/wireshark/wireshark/ui/qt/dis_stream_dialog.cpp

→

1 | /* dis_stream_dialog.cpp
2 | *
3 | * Wireshark - Network traffic analyzer
4 | * By Gerald Combs <gerald@wireshark.org>
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 <QSignalBlocker>
22 | #include <QTextStream>
23 | #include <QVBoxLayout>
24 |
25 | #include "epan/addr_resolv.h"
26 |
27 | #include "main_application.h"
28 |
29 | DisStreamDialog *DisStreamDialog::pinstance_ = nullptr;
30 | std::mutex DisStreamDialog::mutex_;
31 |
32 | enum {
33 | dis_col_start_time = 0,
34 | dis_col_end_time,
35 | dis_col_src_addr,
36 | dis_col_src_port,
37 | dis_col_dst_addr,
38 | dis_col_dst_port,
39 | dis_col_radio,
40 | dis_col_entity,
41 | dis_col_signal_pkts,
42 | dis_col_tx_pkts,
43 | dis_col_lost,
44 | dis_col_max_delta,
45 | dis_col_mean_jitter,
46 | dis_col_max_jitter,
47 | dis_col_problem,
48 | dis_col_count
49 | };
50 |
51 | static constexpr int disstream_ptr_role = Qt::UserRole + 100;
52 |
53 | bool
54 | DisStreamDialog::DisStreamTreeWidgetItem::operator<(const QTreeWidgetItem &other) const
55 | {
56 | int sort_col = treeWidget() ? treeWidget()->sortColumn() : 0;
57 | QVariant lhs = data(sort_col, Qt::UserRole);
58 | QVariant rhs = other.data(sort_col, Qt::UserRole);
59 |
60 | if (lhs.isValid() && rhs.isValid()) {
61 | #if (QT_VERSION((6<<16)|(4<<8)|(2)) >= QT_VERSION_CHECK(6, 0, 0)((6<<16)|(0<<8)|(0)))
62 | if (lhs.metaType().id() == QMetaType::Double || rhs.metaType().id() == QMetaType::Double) {
63 | #else
64 | if (lhs.type() == QVariant::Double || rhs.type() == QVariant::Double) {
65 | #endif
66 | return lhs.toDouble() < rhs.toDouble();
67 | }
68 |
69 | return lhs.toLongLong() < rhs.toLongLong();
70 | }
71 |
72 | return QTreeWidgetItem::operator<(other);
73 | }
74 |
75 | DisStreamDialog *
76 | DisStreamDialog::openDisStreamDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list)
77 | {
78 | std::lock_guard<std::mutex> lock(mutex_);
79 |
80 | if (!pinstance_) {
81 | pinstance_ = new DisStreamDialog(parent, cf, packet_list);
82 | }
83 |
84 | return pinstance_;
85 | }
86 |
87 | DisStreamDialog::DisStreamDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list) :
88 | WiresharkDialog(parent, cf),
89 | stream_tree_(new QTreeWidget(this)),
90 | button_box_(new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this)),
91 | filter_button_(nullptr),
92 | play_button_(nullptr),
93 | stop_button_(nullptr),
94 | analyze_button_(nullptr),
95 | need_redraw_(false),
96 | packet_list_(packet_list)
97 | #ifdef QT_MULTIMEDIA_LIB1
98 | , audio_stream_(new DisAudioStream(this))
99 | #endif
100 | {
101 | QVBoxLayout *layout = new QVBoxLayout(this);
102 | QFormLayout *summary_layout = new QFormLayout;
103 |
104 | setWindowSubtitle(tr("DIS Streams"));
105 |
106 | layout->addLayout(summary_layout);
107 |
108 | stream_tree_->setRootIsDecorated(false);
109 | stream_tree_->setAlternatingRowColors(true);
110 | stream_tree_->setSortingEnabled(true);
111 | stream_tree_->setSelectionMode(QAbstractItemView::SingleSelection);
112 | stream_tree_->setUniformRowHeights(true);
113 | stream_tree_->setContextMenuPolicy(Qt::ActionsContextMenu);
114 | stream_tree_->setColumnCount(dis_col_count);
115 | stream_tree_->setHeaderLabels(QStringList()
116 | << tr("Start")
117 | << tr("End")
118 | << tr("Src Address")
119 | << tr("Src Port")
120 | << tr("Dst Address")
121 | << tr("Dst Port")
122 | << tr("Radio")
123 | << tr("Entity")
124 | << tr("Signal")
125 | << tr("Tx")
126 | << tr("Lost")
127 | << tr("Max Delta (ms)")
128 | << tr("Mean Jitter (ms)")
129 | << tr("Max Jitter (ms)")
130 | << tr("Pb"));
131 | stream_tree_->header()->setSortIndicator(dis_col_start_time, Qt::AscendingOrder);
132 | stream_tree_->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
133 |
134 | layout->addWidget(stream_tree_);
135 |
136 | filter_button_ = button_box_->addButton(tr("Prepare Filter"), QDialogButtonBox::ActionRole);
137 | play_button_ = button_box_->addButton(tr("Play"), QDialogButtonBox::ActionRole);
138 | stop_button_ = button_box_->addButton(tr("Stop"), QDialogButtonBox::ActionRole);
139 | analyze_button_ = button_box_->addButton(tr("Analyze"), QDialogButtonBox::ActionRole);
140 | layout->addWidget(button_box_);
141 |
142 | connect(button_box_, &QDialogButtonBox::rejected, this, &DisStreamDialog::reject);
143 | connect(filter_button_, &QPushButton::clicked, this, &DisStreamDialog::onPrepareFilter);
144 | connect(analyze_button_, &QPushButton::clicked, this, &DisStreamDialog::onAnalyzeStream);
145 | #ifdef QT_MULTIMEDIA_LIB1
146 | connect(play_button_, &QPushButton::clicked, this, &DisStreamDialog::onPlayStream);
147 | connect(stop_button_, &QPushButton::clicked, this, &DisStreamDialog::onStopStream);
148 | connect(audio_stream_, &DisAudioStream::playbackStateChanged,
149 | this, &DisStreamDialog::onPlaybackStateChanged);
150 | #endif
151 | connect(stream_tree_, &QTreeWidget::itemSelectionChanged, this, &DisStreamDialog::onStreamSelectionChanged);
152 | connect(stream_tree_, &QTreeWidget::itemDoubleClicked, this, &DisStreamDialog::onStreamItemDoubleClicked);
153 | connect(&cap_file_, &CaptureFile::captureEvent, this, &DisStreamDialog::onCaptureEvent);
154 |
155 | if (packet_list_) {
156 | connect(this, SIGNAL(goToPacket(int))qFlagLocation("2" "goToPacket(int)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "156"), packet_list_, SLOT(goToPacket(int))qFlagLocation("1" "goToPacket(int)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "156"));
157 | }
158 | connect(this, SIGNAL(updateFilter(QString, bool))qFlagLocation("2" "updateFilter(QString, bool)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "158"), &parent, SLOT(filterPackets(QString, bool))qFlagLocation("1" "filterPackets(QString, bool)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "158"));
159 |
160 | memset(&tapinfo_, 0, sizeof(tapinfo_));
161 | tapinfo_.mode = DISSTREAM_TAP_ANALYSE;
162 | tapinfo_.tap_reset = tapReset;
163 | tapinfo_.tap_draw = tapDraw;
164 |
165 | register_tap_listener_disstream(&tapinfo_, NULL__null, NULL__null);
166 |
167 | if (cap_file_.isValid()) {
168 | cap_file_.delayedRetapPackets();
169 | }
170 |
171 | loadGeometry(parent.width() * 4 / 5, parent.height() * 2 / 3);
172 | updateWidgets();
173 | }
174 |
175 | DisStreamDialog::~DisStreamDialog()
176 | {
177 | std::lock_guard<std::mutex> lock(mutex_);
178 |
179 | #ifdef QT_MULTIMEDIA_LIB1
180 | audio_stream_->stopPlayback();
181 | #endif
182 |
183 | disstream_reset(&tapinfo_);
184 | remove_tap_listener_disstream(&tapinfo_);
185 | pinstance_ = nullptr;
186 | }
187 |
188 | void
189 | DisStreamDialog::captureFileClosing()
190 | {
191 | #ifdef QT_MULTIMEDIA_LIB1
192 | audio_stream_->stopPlayback();
193 | #endif
194 | remove_tap_listener_disstream(&tapinfo_);
195 | disstream_reset(&tapinfo_);
196 | }
197 |
198 | void
199 | DisStreamDialog::captureFileClosed()
200 | {
201 | #ifdef QT_MULTIMEDIA_LIB1
202 | audio_stream_->stopPlayback();
203 | #endif
204 | stream_tree_->clear();
205 | }
206 |
207 | void
208 | DisStreamDialog::tapReset(disstream_tapinfo_t *tapinfo _U___attribute__((unused)))
209 | {
210 | if (!pinstance_) {
211 | return;
212 | }
213 |
214 | pinstance_->need_redraw_ = true;
215 | }
216 |
217 | void
218 | DisStreamDialog::tapDraw(disstream_tapinfo_t *tapinfo _U___attribute__((unused)))
219 | {
220 | if (!pinstance_) {
1 | Assuming 'pinstance_' is non-null | →
2 | ← | Taking false branch | →
221 | return;
222 | }
223 |
224 | pinstance_->need_redraw_ = true;
225 | QMetaObject::invokeMethod(pinstance_, [=]() { pinstance_->updateStreams(); }, Qt::QueuedConnection);
3 | ← | Calling 'QMetaObject::invokeMethod' | →
226 | }
227 |
228 | disstream_info_t *
229 | DisStreamDialog::selectedStream() const
230 | {
231 | QTreeWidgetItem *current = stream_tree_->currentItem();
232 | if (!current) {
233 | return nullptr;
234 | }
235 |
236 | quintptr ptr = current->data(0, disstream_ptr_role).value<quintptr>();
237 | return reinterpret_cast<disstream_info_t *>(ptr);
238 | }
239 |
240 | void
241 | DisStreamDialog::updateStreams()
242 | {
243 | GList *list;
244 | disstream_info_t *previous = selectedStream();
245 | QTreeWidgetItem *item_to_select = nullptr;
246 |
247 | if (!need_redraw_ || fileClosed()) {
248 | updateWidgets();
249 | return;
250 | }
251 |
252 | QSignalBlocker signal_blocker(stream_tree_);
253 |
254 | stream_tree_->setSortingEnabled(false);
255 | stream_tree_->clear();
256 |
257 | list = g_list_first(tapinfo_.strinfo_list);
258 | while (list) {
259 | disstream_info_t *stream_info = (disstream_info_t *)list->data;
260 | DisStreamTreeWidgetItem *item;
261 | char *src_addr;
262 | char *dst_addr;
263 |
264 | item = new DisStreamTreeWidgetItem(stream_tree_);
265 | item->setData(0, disstream_ptr_role, QVariant::fromValue((quintptr)stream_info));
266 | if ((previous && previous == stream_info) || (!previous && !item_to_select)) {
267 | item_to_select = item;
268 | }
269 |
270 | src_addr = address_to_display(NULL__null, &stream_info->id.src_addr);
271 | dst_addr = address_to_display(NULL__null, &stream_info->id.dst_addr);
272 |
273 | item->setText(dis_col_start_time, QString::number(nstime_to_sec(&stream_info->start_rel_time), 'f', 6));
274 | item->setData(dis_col_start_time, Qt::UserRole, nstime_to_sec(&stream_info->start_rel_time));
275 |
276 | item->setText(dis_col_end_time, QString::number(nstime_to_sec(&stream_info->stop_rel_time), 'f', 6));
277 | item->setData(dis_col_end_time, Qt::UserRole, nstime_to_sec(&stream_info->stop_rel_time));
278 |
279 | item->setText(dis_col_src_addr, src_addr);
280 | item->setText(dis_col_src_port, QString::number(stream_info->id.src_port));
281 | item->setData(dis_col_src_port, Qt::UserRole, (int)stream_info->id.src_port);
282 |
283 | item->setText(dis_col_dst_addr, dst_addr);
284 | item->setText(dis_col_dst_port, QString::number(stream_info->id.dst_port));
285 | item->setData(dis_col_dst_port, Qt::UserRole, (int)stream_info->id.dst_port);
286 |
287 | item->setText(dis_col_radio, QStringLiteral("0x%1")(QString(QtPrivate::qMakeStringPrivate(u"" "0x%1"))).arg(stream_info->id.radio_id, 4, 16, QChar('0')));
288 | item->setData(dis_col_radio, Qt::UserRole, (int)stream_info->id.radio_id);
289 |
290 | item->setText(dis_col_entity, QStringLiteral("%1/%2/%3")(QString(QtPrivate::qMakeStringPrivate(u"" "%1/%2/%3")))
291 | .arg(stream_info->id.entity_id_site)
292 | .arg(stream_info->id.entity_id_appl)
293 | .arg(stream_info->id.entity_id_entity));
294 |
295 | item->setText(dis_col_signal_pkts, QString::number(stream_info->signal_packet_count));
296 | item->setData(dis_col_signal_pkts, Qt::UserRole, (int)stream_info->signal_packet_count);
297 |
298 | item->setText(dis_col_tx_pkts, QString::number(stream_info->transmitter_packet_count));
299 | item->setData(dis_col_tx_pkts, Qt::UserRole, (int)stream_info->transmitter_packet_count);
300 |
301 | item->setText(dis_col_lost, QString::number(stream_info->estimated_lost_packets));
302 | item->setData(dis_col_lost, Qt::UserRole, (int)stream_info->estimated_lost_packets);
303 |
304 | item->setText(dis_col_max_delta, QString::number(stream_info->max_delta_ms, 'f', 3));
305 | item->setData(dis_col_max_delta, Qt::UserRole, stream_info->max_delta_ms);
306 |
307 | item->setText(dis_col_mean_jitter, QString::number(stream_info->mean_jitter_ms, 'f', 3));
308 | item->setData(dis_col_mean_jitter, Qt::UserRole, stream_info->mean_jitter_ms);
309 |
310 | item->setText(dis_col_max_jitter, QString::number(stream_info->max_jitter_ms, 'f', 3));
311 | item->setData(dis_col_max_jitter, Qt::UserRole, stream_info->max_jitter_ms);
312 |
313 | item->setText(dis_col_problem, stream_info->problem ? tr("X") : QString());
314 | item->setTextAlignment(dis_col_problem, Qt::AlignCenter);
315 |
316 | wmem_free(NULL__null, src_addr);
317 | wmem_free(NULL__null, dst_addr);
318 |
319 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : __null);
320 | }
321 |
322 | stream_tree_->setSortingEnabled(true);
323 | stream_tree_->sortByColumn(stream_tree_->header()->sortIndicatorSection(),
324 | stream_tree_->header()->sortIndicatorOrder());
325 | if (item_to_select) {
326 | stream_tree_->setCurrentItem(item_to_select);
327 | }
328 |
329 | need_redraw_ = false;
330 | updateWidgets();
331 | }
332 |
333 | void
334 | DisStreamDialog::updateWidgets()
335 | {
336 | bool has_capture = cap_file_.isValid() && !fileClosed();
337 | disstream_info_t *stream_info = selectedStream();
338 | bool has_selection = stream_info != nullptr;
339 | bool has_audio_data = has_selection && stream_info->signal_packets && stream_info->signal_packets->len > 0;
340 |
341 | stream_tree_->setEnabled(has_capture);
342 | filter_button_->setEnabled(has_capture && has_selection);
343 | play_button_->setEnabled(has_capture && has_audio_data);
344 | analyze_button_->setEnabled(has_capture && has_selection);
345 | #ifdef QT_MULTIMEDIA_LIB1
346 | stop_button_->setEnabled(audio_stream_->isPlaying());
347 | #else
348 | stop_button_->setEnabled(false);
349 | #endif
350 | }
351 |
352 | void
353 | DisStreamDialog::onStreamSelectionChanged()
354 | {
355 | #ifdef QT_MULTIMEDIA_LIB1
356 | disstream_info_t *stream_info = selectedStream();
357 |
358 | if (audio_stream_->currentStream() != nullptr &&
359 | audio_stream_->currentStream() != stream_info &&
360 | (audio_stream_->isPlaying() || audio_stream_->isPaused())) {
361 | audio_stream_->stopPlayback();
362 | }
363 | #endif
364 | updateWidgets();
365 | }
366 |
367 | void
368 | DisStreamDialog::onStreamItemDoubleClicked(QTreeWidgetItem *item, int column _U___attribute__((unused)))
369 | {
370 | quintptr ptr;
371 | disstream_info_t *stream_info;
372 |
373 | if (!item) {
374 | return;
375 | }
376 |
377 | ptr = item->data(0, disstream_ptr_role).value<quintptr>();
378 | stream_info = reinterpret_cast<disstream_info_t *>(ptr);
379 | if (stream_info && stream_info->first_packet_num > 0) {
380 | emit goToPacket((int)stream_info->first_packet_num);
381 | }
382 | }
383 |
384 | void
385 | DisStreamDialog::onPrepareFilter()
386 | {
387 | disstream_info_t *stream_info = selectedStream();
388 | QString filter;
389 |
390 | if (!stream_info) {
391 | return;
392 | }
393 |
394 | 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" )))
395 | "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" )))
396 | "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" )))
397 | "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" )))
398 | .arg(stream_info->id.src_port)
399 | .arg(stream_info->id.dst_port)
400 | .arg(stream_info->id.radio_id)
401 | .arg(stream_info->id.entity_id_site)
402 | .arg(stream_info->id.entity_id_appl)
403 | .arg(stream_info->id.entity_id_entity);
404 |
405 | emit updateFilter(filter, true);
406 | }
407 |
408 | void
409 | DisStreamDialog::onAnalyzeStream()
410 | {
411 | disstream_info_t *stream_info = selectedStream();
412 | QWidget *parent_widget = qobject_cast<QWidget *>(parent());
413 |
414 | if (!stream_info) {
415 | return;
416 | }
417 |
418 | if (!parent_widget) {
419 | parent_widget = this;
420 | }
421 |
422 | DisStreamAnalysisDialog *dialog = DisStreamAnalysisDialog::openDisStreamAnalysisDialog(
423 | *parent_widget, cap_file_, packet_list_);
424 | dialog->selectStream(stream_info);
425 | dialog->show();
426 | dialog->raise();
427 | dialog->activateWindow();
428 | }
429 |
430 | #ifdef QT_MULTIMEDIA_LIB1
431 | void
432 | DisStreamDialog::onPlayStream()
433 | {
434 | disstream_info_t *stream_info = selectedStream();
435 | QString error_message;
436 |
437 | if (!audio_stream_->playDisStream(stream_info, error_message)) {
438 | QMessageBox::warning(this, tr("DIS Playback"), error_message);
439 | return;
440 | }
441 | updateWidgets();
442 | }
443 |
444 | void
445 | DisStreamDialog::onStopStream()
446 | {
447 | audio_stream_->stopPlayback();
448 | updateWidgets();
449 | }
450 |
451 | void
452 | DisStreamDialog::onPlaybackStateChanged(QAudio::State state _U___attribute__((unused)))
453 | {
454 | updateWidgets();
455 | }
456 | #endif
457 |
458 | void
459 | DisStreamDialog::onCaptureEvent(CaptureEvent e)
460 | {
461 | if (e.captureContext() == CaptureEvent::Retap) {
462 | need_redraw_ = true;
463 | }
464 |
465 | updateStreams();
466 | }

←

#### /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h

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,
5 | ← | Potential memory leak
320 | new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
4 | ← | Memory is allocated | →
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