1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Designer of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include "signalslotdialog_p.h" |
30 | #include "ui_signalslotdialog.h" |
31 | #include "metadatabase_p.h" |
32 | #include "widgetdatabase_p.h" |
33 | |
34 | #include "qdesigner_formwindowcommand_p.h" |
35 | #include "iconloader_p.h" |
36 | |
37 | #include <QtDesigner/membersheet.h> |
38 | #include <QtDesigner/qextensionmanager.h> |
39 | #include <QtDesigner/abstractformeditor.h> |
40 | #include <QtDesigner/abstractformwindow.h> |
41 | #include <QtDesigner/abstractwidgetfactory.h> |
42 | #include <abstractdialoggui_p.h> |
43 | |
44 | #include <QtGui/qstandarditemmodel.h> |
45 | #include <QtGui/qvalidator.h> |
46 | #include <QtWidgets/qitemdelegate.h> |
47 | #include <QtWidgets/qlineedit.h> |
48 | #include <QtWidgets/qapplication.h> |
49 | #include <QtWidgets/qmessagebox.h> |
50 | |
51 | #include <QtCore/qregularexpression.h> |
52 | #include <QtCore/qdebug.h> |
53 | |
54 | QT_BEGIN_NAMESPACE |
55 | |
56 | // Regexp to match a function signature, arguments potentially |
57 | // with namespace colons. |
58 | static const char *signatureRegExp = "^[\\w+_]+\\(([\\w+:]\\*?,?)*\\)$" ; |
59 | static const char *methodNameRegExp = "^[\\w+_]+$" ; |
60 | |
61 | static QStandardItem *createEditableItem(const QString &text) |
62 | { |
63 | QStandardItem *rc = new QStandardItem(text); |
64 | rc->setFlags(Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsSelectable); |
65 | return rc; |
66 | } |
67 | |
68 | static QStandardItem *createDisabledItem(const QString &text) |
69 | { |
70 | QStandardItem *rc = new QStandardItem(text); |
71 | Qt::ItemFlags flags = rc->flags(); |
72 | rc->setFlags(flags & ~(Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsSelectable)); |
73 | return rc; |
74 | } |
75 | |
76 | static void fakeMethodsFromMetaDataBase(QDesignerFormEditorInterface *core, QObject *o, QStringList &slotList, QStringList &signalList) |
77 | { |
78 | slotList.clear(); |
79 | signalList.clear(); |
80 | if (qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast<qdesigner_internal::MetaDataBase *>(object: core->metaDataBase())) |
81 | if (const qdesigner_internal::MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(object: o)) { |
82 | slotList = item->fakeSlots(); |
83 | signalList = item->fakeSignals(); |
84 | } |
85 | } |
86 | |
87 | static void fakeMethodsToMetaDataBase(QDesignerFormEditorInterface *core, QObject *o, const QStringList &slotList, const QStringList &signalList) |
88 | { |
89 | if (qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast<qdesigner_internal::MetaDataBase *>(object: core->metaDataBase())) { |
90 | qdesigner_internal::MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(object: o); |
91 | Q_ASSERT(item); |
92 | item->setFakeSlots(slotList); |
93 | item->setFakeSignals(signalList); |
94 | } |
95 | } |
96 | |
97 | static void existingMethodsFromMemberSheet(QDesignerFormEditorInterface *core, |
98 | QObject *o, |
99 | QStringList &slotList, QStringList &signalList) |
100 | { |
101 | slotList.clear(); |
102 | signalList.clear(); |
103 | |
104 | QDesignerMemberSheetExtension *msheet = qt_extension<QDesignerMemberSheetExtension*>(manager: core->extensionManager(), object: o); |
105 | if (!msheet) |
106 | return; |
107 | |
108 | for (int i = 0, count = msheet->count(); i < count; ++i) |
109 | if (msheet->isVisible(index: i)) { |
110 | if (msheet->isSlot(index: i)) |
111 | slotList += msheet->signature(index: i); |
112 | else |
113 | if (msheet->isSignal(index: i)) |
114 | signalList += msheet->signature(index: i); |
115 | } |
116 | } |
117 | |
118 | namespace { |
119 | // Internal helper class: A Delegate that validates using RegExps and additionally checks |
120 | // on closing (adds missing parentheses). |
121 | class SignatureDelegate : public QItemDelegate { |
122 | public: |
123 | SignatureDelegate(QObject * parent = nullptr); |
124 | QWidget * createEditor (QWidget * parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const override; |
125 | void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; |
126 | |
127 | private: |
128 | const QRegularExpression m_signatureRegexp; |
129 | const QRegularExpression m_methodNameRegexp; |
130 | }; |
131 | |
132 | SignatureDelegate::SignatureDelegate(QObject * parent) : |
133 | QItemDelegate(parent), |
134 | m_signatureRegexp(QLatin1String(signatureRegExp)), |
135 | m_methodNameRegexp(QLatin1String(methodNameRegExp)) |
136 | { |
137 | Q_ASSERT(m_signatureRegexp.isValid()); |
138 | Q_ASSERT(m_methodNameRegexp.isValid()); |
139 | } |
140 | |
141 | QWidget * SignatureDelegate::createEditor ( QWidget * parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const |
142 | { |
143 | QWidget *rc = QItemDelegate::createEditor(parent, option, index); |
144 | QLineEdit *le = qobject_cast<QLineEdit *>(object: rc); |
145 | Q_ASSERT(le); |
146 | le->setValidator(new QRegularExpressionValidator(m_signatureRegexp, le)); |
147 | return rc; |
148 | } |
149 | |
150 | void SignatureDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const |
151 | { |
152 | QLineEdit *le = qobject_cast<QLineEdit *>(object: editor); |
153 | Q_ASSERT(le); |
154 | // Did the user just type a name? .. Add parentheses |
155 | QString signature = le->text(); |
156 | if (!m_signatureRegexp.match(subject: signature).hasMatch()) { |
157 | if (m_methodNameRegexp.match(subject: signature).hasMatch()) { |
158 | signature += QStringLiteral("()" ); |
159 | le->setText(signature); |
160 | } else { |
161 | return; |
162 | } |
163 | } |
164 | QItemDelegate::setModelData(editor, model, index); |
165 | } |
166 | |
167 | // ------ FakeMethodMetaDBCommand: Undo Command to change fake methods in the meta DB. |
168 | class FakeMethodMetaDBCommand : public qdesigner_internal::QDesignerFormWindowCommand { |
169 | |
170 | public: |
171 | explicit FakeMethodMetaDBCommand(QDesignerFormWindowInterface *formWindow); |
172 | |
173 | void init(QObject *o, |
174 | const QStringList &oldFakeSlots, const QStringList &oldFakeSignals, |
175 | const QStringList &newFakeSlots, const QStringList &newFakeSignals); |
176 | |
177 | void undo() override |
178 | { fakeMethodsToMetaDataBase(core: core(), o: m_object, slotList: m_oldFakeSlots, signalList: m_oldFakeSignals); } |
179 | void redo() override |
180 | { fakeMethodsToMetaDataBase(core: core(), o: m_object, slotList: m_newFakeSlots, signalList: m_newFakeSignals); } |
181 | |
182 | private: |
183 | QObject *m_object; |
184 | QStringList m_oldFakeSlots; |
185 | QStringList m_oldFakeSignals; |
186 | QStringList m_newFakeSlots; |
187 | QStringList m_newFakeSignals; |
188 | }; |
189 | |
190 | FakeMethodMetaDBCommand::FakeMethodMetaDBCommand(QDesignerFormWindowInterface *formWindow) : |
191 | qdesigner_internal::QDesignerFormWindowCommand(QApplication::translate(context: "Command" , key: "Change signals/slots" ), formWindow), |
192 | m_object(nullptr) |
193 | { |
194 | } |
195 | |
196 | void FakeMethodMetaDBCommand::init(QObject *o, |
197 | const QStringList &oldFakeSlots, const QStringList &oldFakeSignals, |
198 | const QStringList &newFakeSlots, const QStringList &newFakeSignals) |
199 | { |
200 | m_object = o; |
201 | m_oldFakeSlots = oldFakeSlots; |
202 | m_oldFakeSignals = oldFakeSignals; |
203 | m_newFakeSlots = newFakeSlots; |
204 | m_newFakeSignals = newFakeSignals; |
205 | } |
206 | } |
207 | |
208 | namespace qdesigner_internal { |
209 | |
210 | // ------ SignalSlotDialogData |
211 | void SignalSlotDialogData::clear() |
212 | { |
213 | m_existingMethods.clear(); |
214 | m_fakeMethods.clear(); |
215 | } |
216 | |
217 | // ------ SignatureModel |
218 | SignatureModel::SignatureModel(QObject *parent) : |
219 | QStandardItemModel(parent) |
220 | { |
221 | } |
222 | |
223 | bool SignatureModel::setData(const QModelIndex &index, const QVariant &value, int role) |
224 | { |
225 | if (role != Qt::EditRole) |
226 | return QStandardItemModel::setData(index, value, role); |
227 | // check via signal (unless it is the same), in which case we can't be bothered. |
228 | const QStandardItem *item = itemFromIndex(index); |
229 | Q_ASSERT(item); |
230 | const QString signature = value.toString(); |
231 | if (item->text() == signature) |
232 | return true; |
233 | |
234 | bool ok = true; |
235 | emit checkSignature(signature, ok: &ok); |
236 | if (!ok) |
237 | return false; |
238 | |
239 | return QStandardItemModel::setData(index, value, role); |
240 | } |
241 | |
242 | // ------ SignaturePanel |
243 | SignaturePanel::SignaturePanel(QObject *parent, QListView *listView, QToolButton *addButton, QToolButton *removeButton, const QString &newPrefix) : |
244 | QObject(parent), |
245 | m_newPrefix(newPrefix), |
246 | m_model(new SignatureModel(this)), |
247 | m_listView(listView), |
248 | m_removeButton(removeButton) |
249 | { |
250 | m_removeButton->setEnabled(false); |
251 | |
252 | connect(sender: addButton, signal: &QAbstractButton::clicked, receiver: this, slot: &SignaturePanel::slotAdd); |
253 | connect(sender: m_removeButton, signal: &QAbstractButton::clicked, receiver: this, slot: &SignaturePanel::slotRemove); |
254 | |
255 | m_listView->setModel(m_model); |
256 | SignatureDelegate *delegate = new SignatureDelegate(this); |
257 | m_listView->setItemDelegate(delegate); |
258 | connect(sender: m_model, signal: &SignatureModel::checkSignature, |
259 | receiver: this, slot: &SignaturePanel::checkSignature); |
260 | connect(sender: m_listView->selectionModel(), signal: &QItemSelectionModel::selectionChanged, |
261 | receiver: this, slot: &SignaturePanel::slotSelectionChanged); |
262 | } |
263 | |
264 | void SignaturePanel::slotAdd() |
265 | { |
266 | m_listView->selectionModel()->clearSelection(); |
267 | // find unique name |
268 | for (int i = 1; ; i++) { |
269 | QString newSlot = m_newPrefix; |
270 | newSlot += QString::number(i); // Always add number, Avoid setting 'slot' for first entry |
271 | newSlot += QLatin1Char('('); |
272 | // check for function name independent of parameters |
273 | if (m_model->findItems(text: newSlot, flags: Qt::MatchStartsWith, column: 0).isEmpty()) { |
274 | newSlot += QLatin1Char(')'); |
275 | QStandardItem * item = createEditableItem(text: newSlot); |
276 | m_model->appendRow(aitem: item); |
277 | const QModelIndex index = m_model->indexFromItem (item); |
278 | m_listView->setCurrentIndex (index); |
279 | m_listView->edit(index); |
280 | return; |
281 | } |
282 | } |
283 | } |
284 | |
285 | int SignaturePanel::count(const QString &signature) const |
286 | { |
287 | return m_model->findItems(text: signature).size(); |
288 | } |
289 | |
290 | void SignaturePanel::slotRemove() |
291 | { |
292 | const QModelIndexList selectedIndexes = m_listView->selectionModel()->selectedIndexes (); |
293 | if (selectedIndexes.isEmpty()) |
294 | return; |
295 | |
296 | closeEditor(); |
297 | // scroll to previous |
298 | if (const int row = selectedIndexes.constFirst().row()) |
299 | m_listView->setCurrentIndex (selectedIndexes.constFirst().sibling(arow: row - 1, acolumn: 0)); |
300 | |
301 | for (int i = selectedIndexes.size() - 1; i >= 0; i--) |
302 | qDeleteAll(c: m_model->takeRow(row: selectedIndexes[i].row())); |
303 | } |
304 | |
305 | void SignaturePanel::slotSelectionChanged(const QItemSelection &selected, const QItemSelection &) |
306 | { |
307 | m_removeButton->setEnabled(!selected.indexes().isEmpty()); |
308 | } |
309 | |
310 | void SignaturePanel::setData(const SignalSlotDialogData &d) |
311 | { |
312 | m_model->clear(); |
313 | |
314 | QStandardItem *lastExisting = nullptr; |
315 | for (const QString &s : d.m_existingMethods) { |
316 | lastExisting = createDisabledItem(text: s); |
317 | m_model->appendRow(aitem: lastExisting); |
318 | } |
319 | for (const QString &s : d.m_fakeMethods) |
320 | m_model->appendRow(aitem: createEditableItem(text: s)); |
321 | if (lastExisting) |
322 | m_listView->scrollTo(index: m_model->indexFromItem(item: lastExisting)); |
323 | } |
324 | |
325 | QStringList SignaturePanel::fakeMethods() const |
326 | { |
327 | QStringList rc; |
328 | if (const int rowCount = m_model->rowCount()) |
329 | for (int i = 0; i < rowCount; i++) { |
330 | const QStandardItem *item = m_model->item(row: i); |
331 | if (item->flags() & Qt::ItemIsEditable) |
332 | rc += item->text(); |
333 | } |
334 | return rc; |
335 | } |
336 | |
337 | void SignaturePanel::closeEditor() |
338 | { |
339 | const QModelIndex idx = m_listView->currentIndex(); |
340 | if (idx.isValid()) |
341 | m_listView->closePersistentEditor(index: idx); |
342 | } |
343 | |
344 | // ------ SignalSlotDialog |
345 | |
346 | SignalSlotDialog::SignalSlotDialog(QDesignerDialogGuiInterface *dialogGui, QWidget *parent, FocusMode mode) : |
347 | QDialog(parent), |
348 | m_focusMode(mode), |
349 | m_ui(new Ui::SignalSlotDialogClass), |
350 | m_dialogGui(dialogGui) |
351 | { |
352 | setModal(true); |
353 | m_ui->setupUi(this); |
354 | |
355 | const QIcon plusIcon = qdesigner_internal::createIconSet(name: QString::fromUtf8(str: "plus.png" )); |
356 | const QIcon minusIcon = qdesigner_internal::createIconSet(name: QString::fromUtf8(str: "minus.png" )); |
357 | m_ui->addSlotButton->setIcon(plusIcon); |
358 | m_ui->removeSlotButton->setIcon(minusIcon); |
359 | m_ui->addSignalButton->setIcon(plusIcon); |
360 | m_ui->removeSignalButton->setIcon(minusIcon); |
361 | |
362 | m_slotPanel = new SignaturePanel(this, m_ui->slotListView, m_ui->addSlotButton, m_ui->removeSlotButton, QStringLiteral("slot" )); |
363 | m_signalPanel = new SignaturePanel(this, m_ui->signalListView, m_ui->addSignalButton, m_ui->removeSignalButton, QStringLiteral("signal" )); |
364 | connect(sender: m_slotPanel, signal: &SignaturePanel::checkSignature, |
365 | receiver: this, slot: &SignalSlotDialog::slotCheckSignature); |
366 | connect(sender: m_signalPanel, signal: &SignaturePanel::checkSignature, |
367 | receiver: this, slot: &SignalSlotDialog::slotCheckSignature); |
368 | |
369 | connect(sender: m_ui->buttonBox, signal: &QDialogButtonBox::accepted, receiver: this, slot: &QDialog::accept); |
370 | connect(sender: m_ui->buttonBox, signal: &QDialogButtonBox::rejected, receiver: this, slot: &QDialog::reject); |
371 | |
372 | switch(m_focusMode) { |
373 | case FocusSlots: |
374 | m_ui->slotListView->setFocus(Qt::OtherFocusReason); |
375 | break; |
376 | case FocusSignals: |
377 | m_ui->signalListView->setFocus(Qt::OtherFocusReason); |
378 | break; |
379 | } |
380 | } |
381 | |
382 | SignalSlotDialog::~SignalSlotDialog() |
383 | { |
384 | delete m_ui; |
385 | } |
386 | |
387 | void SignalSlotDialog::slotCheckSignature(const QString &signature, bool *ok) |
388 | { |
389 | QString errorMessage; |
390 | do { |
391 | if (m_slotPanel->count(signature)) { |
392 | errorMessage = tr(s: "There is already a slot with the signature '%1'." ).arg(a: signature); |
393 | *ok = false; |
394 | break; |
395 | } |
396 | if (m_signalPanel->count(signature)) { |
397 | errorMessage = tr(s: "There is already a signal with the signature '%1'." ).arg(a: signature); |
398 | *ok = false; |
399 | break; |
400 | } |
401 | } while (false); |
402 | if (!*ok) |
403 | m_dialogGui->message(parent: this, context: QDesignerDialogGuiInterface::SignalSlotDialogMessage, |
404 | icon: QMessageBox::Warning, title: tr(s: "%1 - Duplicate Signature" ).arg(a: windowTitle()), text: errorMessage, buttons: QMessageBox::Close); |
405 | } |
406 | |
407 | QDialog::DialogCode SignalSlotDialog::showDialog(SignalSlotDialogData &slotData, SignalSlotDialogData &signalData) |
408 | { |
409 | m_slotPanel->setData(slotData); |
410 | m_signalPanel->setData(signalData); |
411 | |
412 | const DialogCode rc = static_cast<DialogCode>(exec()); |
413 | if (rc == Rejected) |
414 | return rc; |
415 | |
416 | slotData.m_fakeMethods = m_slotPanel->fakeMethods(); |
417 | signalData.m_fakeMethods = m_signalPanel->fakeMethods(); |
418 | return rc; |
419 | } |
420 | |
421 | bool SignalSlotDialog::editMetaDataBase(QDesignerFormWindowInterface *fw, QObject *object, QWidget *parent, FocusMode mode) |
422 | { |
423 | QDesignerFormEditorInterface *core = fw->core(); |
424 | SignalSlotDialog dlg(core->dialogGui(), parent, mode); |
425 | dlg.setWindowTitle(tr(s: "Signals/Slots of %1" ).arg(a: object->objectName())); |
426 | |
427 | SignalSlotDialogData slotData; |
428 | SignalSlotDialogData signalData; |
429 | |
430 | existingMethodsFromMemberSheet(core, o: object, slotList&: slotData.m_existingMethods, signalList&: signalData.m_existingMethods); |
431 | fakeMethodsFromMetaDataBase(core, o: object, slotList&: slotData.m_fakeMethods, signalList&: signalData.m_fakeMethods); |
432 | |
433 | const QStringList oldSlots = slotData.m_fakeMethods; |
434 | const QStringList oldSignals = signalData.m_fakeMethods; |
435 | |
436 | if (dlg.showDialog(slotData, signalData) == QDialog::Rejected) |
437 | return false; |
438 | |
439 | if (oldSlots == slotData.m_fakeMethods && oldSignals == signalData.m_fakeMethods) |
440 | return false; |
441 | |
442 | FakeMethodMetaDBCommand *cmd = new FakeMethodMetaDBCommand(fw); |
443 | cmd->init(o: object, oldFakeSlots: oldSlots, oldFakeSignals: oldSignals, newFakeSlots: slotData.m_fakeMethods, newFakeSignals: signalData.m_fakeMethods); |
444 | fw->commandHistory()->push(cmd); |
445 | return true; |
446 | } |
447 | |
448 | bool SignalSlotDialog::editPromotedClass(QDesignerFormEditorInterface *core, const QString &promotedClassName, QWidget *parent, FocusMode mode) |
449 | { |
450 | const int index = core->widgetDataBase()->indexOfClassName(className: promotedClassName); |
451 | if (index == -1) |
452 | return false; |
453 | |
454 | const QString baseClassName = core->widgetDataBase()->item(index)->extends(); |
455 | if (baseClassName.isEmpty()) |
456 | return false; |
457 | |
458 | QWidget *widget = core->widgetFactory()->createWidget(name: baseClassName, parentWidget: nullptr); |
459 | if (!widget) |
460 | return false; |
461 | const bool rc = editPromotedClass(core, promotedClassName, baseObject: widget, parent, m: mode); |
462 | widget->deleteLater(); |
463 | return rc; |
464 | } |
465 | |
466 | bool SignalSlotDialog::editPromotedClass(QDesignerFormEditorInterface *core, QObject *baseObject, QWidget *parent, FocusMode mode) |
467 | { |
468 | if (!baseObject->isWidgetType()) |
469 | return false; |
470 | |
471 | const QString promotedClassName = promotedCustomClassName(core, w: qobject_cast<QWidget*>(o: baseObject)); |
472 | if (promotedClassName.isEmpty()) |
473 | return false; |
474 | return editPromotedClass(core, promotedClassName, baseObject, parent, m: mode); |
475 | } |
476 | |
477 | |
478 | bool SignalSlotDialog::editPromotedClass(QDesignerFormEditorInterface *core, const QString &promotedClassName, QObject *object, QWidget *parent, FocusMode mode) |
479 | { |
480 | WidgetDataBase *db = qobject_cast<WidgetDataBase *>(object: core->widgetDataBase()); |
481 | if (!db) |
482 | return false; |
483 | |
484 | const int index = core->widgetDataBase()->indexOfClassName(className: promotedClassName); |
485 | if (index == -1) |
486 | return false; |
487 | |
488 | WidgetDataBaseItem* item = static_cast<WidgetDataBaseItem*>(db->item(index)); |
489 | |
490 | SignalSlotDialogData slotData; |
491 | SignalSlotDialogData signalData; |
492 | |
493 | existingMethodsFromMemberSheet(core, o: object, slotList&: slotData.m_existingMethods, signalList&: signalData.m_existingMethods); |
494 | slotData.m_fakeMethods = item->fakeSlots(); |
495 | signalData.m_fakeMethods = item->fakeSignals(); |
496 | |
497 | const QStringList oldSlots = slotData.m_fakeMethods; |
498 | const QStringList oldSignals = signalData.m_fakeMethods; |
499 | |
500 | SignalSlotDialog dlg(core->dialogGui(), parent, mode); |
501 | dlg.setWindowTitle(tr(s: "Signals/Slots of %1" ).arg(a: promotedClassName)); |
502 | |
503 | if (dlg.showDialog(slotData, signalData) == QDialog::Rejected) |
504 | return false; |
505 | |
506 | if (oldSlots == slotData.m_fakeMethods && oldSignals == signalData.m_fakeMethods) |
507 | return false; |
508 | |
509 | item->setFakeSlots(slotData.m_fakeMethods); |
510 | item->setFakeSignals(signalData.m_fakeMethods); |
511 | |
512 | return true; |
513 | } |
514 | |
515 | } |
516 | |
517 | QT_END_NAMESPACE |
518 | |