mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-13 10:04:13 +02:00
Merge pull request #693 from ispyisail/fix/color-editor-crash-bug323
Fix crash changing dynamic text color and confirming with Enter (bugtracker #323) Works like charm: - color is updated immediately - no additional errors or warnings - no crash anymore!
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include <QStandardItem>
|
#include <QStandardItem>
|
||||||
|
#include <QTimer>
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
|
|
||||||
static int src_txt_row = 0;
|
static int src_txt_row = 0;
|
||||||
@@ -1595,6 +1596,15 @@ DynamicTextItemDelegate::DynamicTextItemDelegate(QObject *parent) :
|
|||||||
QStyledItemDelegate(parent)
|
QStyledItemDelegate(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void DynamicTextItemDelegate::commitAndCloseDeferred(QWidget *editor) const
|
||||||
|
{
|
||||||
|
auto *self = const_cast<DynamicTextItemDelegate *>(this);
|
||||||
|
QTimer::singleShot(0, self, [self, editor]() {
|
||||||
|
emit self->commitData(editor);
|
||||||
|
emit self->closeEditor(editor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *DynamicTextItemDelegate::createEditor(
|
QWidget *DynamicTextItemDelegate::createEditor(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
const QStyleOptionViewItem &option,
|
const QStyleOptionViewItem &option,
|
||||||
@@ -1682,13 +1692,43 @@ QWidget *DynamicTextItemDelegate::createEditor(
|
|||||||
w->setProperty("ok", ok);
|
w->setProperty("ok", ok);
|
||||||
}
|
}
|
||||||
w->setObjectName("font_dialog");
|
w->setObjectName("font_dialog");
|
||||||
|
commitAndCloseDeferred(w);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
case DynamicElementTextModel::color:
|
case DynamicElementTextModel::color:
|
||||||
{
|
{
|
||||||
QColorDialog *cd = new QColorDialog(index.data(Qt::EditRole).value<QColor>(), parent);
|
/* Like the font case above: run the dialog synchronously via
|
||||||
cd->setObjectName("color_dialog");
|
* its static convenience function and stash the result on a
|
||||||
return cd;
|
* plain placeholder widget, rather than handing back the
|
||||||
|
* QColorDialog itself as the item view's "editor".
|
||||||
|
*
|
||||||
|
* The item view's own Enter/Escape handling (the base
|
||||||
|
* QStyledItemDelegate::eventFilter(), since "color_dialog"
|
||||||
|
* isn't one of the objectNames special-cased in this
|
||||||
|
* delegate's own eventFilter() above) treats whatever
|
||||||
|
* createEditor() returned as a small inline editor it
|
||||||
|
* commits and destroys directly on a key press. A QColorDialog
|
||||||
|
* is not that: on Windows it can hand off to the native
|
||||||
|
* color picker, whose own accept/close path then races the
|
||||||
|
* view's -- pressing Enter fired both, one tearing down an
|
||||||
|
* object the other was still using (case #323 on the bug
|
||||||
|
* tracker: "QObject::installEventFilter(): Cannot filter
|
||||||
|
* events for objects in a different thread" immediately
|
||||||
|
* followed by a segfault; clicking the dialog's own OK
|
||||||
|
* button with the mouse didn't reach the view's key
|
||||||
|
* handling, so it didn't crash). Resolving the dialog
|
||||||
|
* before returning removes the second, competing teardown
|
||||||
|
* path entirely. */
|
||||||
|
QColor color = QColorDialog::getColor(index.data(Qt::EditRole).value<QColor>(), parent);
|
||||||
|
QWidget *w = new QWidget(parent);
|
||||||
|
if (color.isValid())
|
||||||
|
{
|
||||||
|
w->setProperty("color", color);
|
||||||
|
w->setProperty("ok", true);
|
||||||
|
}
|
||||||
|
w->setObjectName("color_dialog");
|
||||||
|
commitAndCloseDeferred(w);
|
||||||
|
return w;
|
||||||
}
|
}
|
||||||
case DynamicElementTextModel::pos:
|
case DynamicElementTextModel::pos:
|
||||||
{
|
{
|
||||||
@@ -1788,15 +1828,15 @@ void DynamicTextItemDelegate::setModelData(
|
|||||||
{
|
{
|
||||||
if(QStandardItem *qsi = qsim->itemFromIndex(index))
|
if(QStandardItem *qsi = qsim->itemFromIndex(index))
|
||||||
{
|
{
|
||||||
QColorDialog *cd = static_cast<QColorDialog *> (editor);
|
if (editor->property("ok").toBool() == true)
|
||||||
if (cd->result() == QDialog::Accepted)
|
|
||||||
{
|
{
|
||||||
qsi->setData(cd->selectedColor(), Qt::EditRole);
|
QColor color = editor->property("color").value<QColor>();
|
||||||
qsi->setData(cd->selectedColor(), Qt::ForegroundRole);
|
qsi->setData(color, Qt::EditRole);
|
||||||
|
qsi->setData(color, Qt::ForegroundRole);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (editor->objectName() == "info_text")
|
else if (editor->objectName() == "info_text")
|
||||||
|
|||||||
@@ -155,6 +155,21 @@ class DynamicTextItemDelegate : public QStyledItemDelegate
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList availableInfo(DynamicElementTextItem *deti) const;
|
QStringList availableInfo(DynamicElementTextItem *deti) const;
|
||||||
|
/**
|
||||||
|
@brief commitAndCloseDeferred
|
||||||
|
Schedule commitData()/closeEditor() for @a editor on the next
|
||||||
|
event loop iteration. For editors resolved synchronously inside
|
||||||
|
createEditor() (font/color, both run their picker dialog before
|
||||||
|
returning) there is no user interaction left to drive the base
|
||||||
|
QStyledItemDelegate::eventFilter()'s usual Enter/focus-out commit
|
||||||
|
path, so without this the value sits picked-but-uncommitted
|
||||||
|
until something unrelated (e.g. clicking elsewhere) happens to
|
||||||
|
trigger it. Deferred rather than called immediately: the view
|
||||||
|
only registers the widget createEditor() returns as "the active
|
||||||
|
editor" *after* createEditor() itself returns, so emitting here
|
||||||
|
would target an editor the view doesn't know about yet.
|
||||||
|
*/
|
||||||
|
void commitAndCloseDeferred(QWidget *editor) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DYNAMICELEMENTTEXTMODEL_H
|
#endif // DYNAMICELEMENTTEXTMODEL_H
|
||||||
|
|||||||
Reference in New Issue
Block a user