Prevent QtColorButton crash with AnnotationTableView

Task-number: QDS-4068
Change-Id: I56c130e0d252f6926a64d0d0c37d3b482d2dbbc5
Reviewed-by: Michael Winkelmann <michael.winkelmann@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Tapani Mattila
2021-04-12 16:53:46 +03:00
committed by Michael Winkelmann
parent 8dbb741bbe
commit 03aed5c5a6
4 changed files with 91 additions and 5 deletions

View File

@@ -54,6 +54,7 @@ public:
#endif
bool m_backgroundCheckered;
bool m_alphaAllowed;
bool m_dialogOpen;
};
void QtColorButtonPrivate::slotEditColor()
@@ -61,9 +62,14 @@ void QtColorButtonPrivate::slotEditColor()
QColorDialog::ColorDialogOptions options;
if (m_alphaAllowed)
options |= QColorDialog::ShowAlphaChannel;
emit q_ptr->colorChangeStarted();
m_dialogOpen = true;
const QColor newColor = QColorDialog::getColor(m_color, q_ptr, QString(), options);
if (!newColor.isValid() || newColor == q_ptr->color())
m_dialogOpen = false;
if (!newColor.isValid() || newColor == q_ptr->color()) {
emit q_ptr->colorUnchanged();
return;
}
q_ptr->setColor(newColor);
emit q_ptr->colorChanged(m_color);
}
@@ -117,6 +123,7 @@ QtColorButton::QtColorButton(QWidget *parent)
d_ptr->m_dragging = false;
d_ptr->m_backgroundCheckered = true;
d_ptr->m_alphaAllowed = true;
d_ptr->m_dialogOpen = false;
setAcceptDrops(true);
@@ -165,6 +172,11 @@ bool QtColorButton::isAlphaAllowed() const
return d_ptr->m_alphaAllowed;
}
bool QtColorButton::isDialogOpen() const
{
return d_ptr->m_dialogOpen;
}
void QtColorButton::paintEvent(QPaintEvent *event)
{
QToolButton::paintEvent(event);

View File

@@ -49,11 +49,16 @@ public:
QColor color() const;
bool isDialogOpen() const;
public slots:
void setColor(const QColor &color);
signals:
void colorChangeStarted();
void colorChanged(const QColor &color);
void colorUnchanged();
protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
@@ -63,7 +68,7 @@ protected:
void dragLeaveEvent(QDragLeaveEvent *event) override;
void dropEvent(QDropEvent *event) override;
#endif
private:
class QtColorButtonPrivate *d_ptr;
friend class QtColorButtonPrivate;
};

View File

@@ -187,12 +187,46 @@ void CommentValueDelegate::setEditorData(QWidget *editor, const QModelIndex &ind
auto *e = qobject_cast<QLineEdit *>(editor);
e->setText(data.toString());
} else if (data.userType() == QMetaType::QColor) {
auto *e = qobject_cast<Utils::QtColorButton *>(editor);
auto *e = qobject_cast<AnnotationTableColorButton *>(editor);
e->setColor(data.value<QColor>());
e->installEventFilter(e);
connect(e,
&AnnotationTableColorButton::editorFinished,
this,
&CommentValueDelegate::slotEditorFinished,
Qt::UniqueConnection);
connect(e,
&AnnotationTableColorButton::editorCanceled,
this,
&CommentValueDelegate::slotEditorCanceled,
Qt::UniqueConnection);
} else
QItemDelegate::setEditorData(editor, index);
}
bool AnnotationTableColorButton::eventFilter(QObject *object, QEvent *event)
{
AnnotationTableColorButton *editor = qobject_cast<AnnotationTableColorButton*>(object);
if (editor && event->type() == QEvent::FocusOut && editor->isDialogOpen())
return true;
return QObject::eventFilter(object, event);
}
void CommentValueDelegate::slotEditorCanceled(QWidget *editor)
{
emit closeEditor(editor);
}
void CommentValueDelegate::slotEditorFinished(QWidget *editor)
{
AnnotationTableColorButton* e = qobject_cast<AnnotationTableColorButton *>(editor);
if (e) {
emit commitData(editor);
emit closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);
}
}
void CommentValueDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
@@ -201,9 +235,11 @@ void CommentValueDelegate::setModelData(QWidget *editor,
if (data.userType() == qMetaTypeId<RichTextProxy>())
return;
else if (data.userType() == QMetaType::QColor)
{
model->setData(index,
qobject_cast<Utils::QtColorButton *>(editor)->color(),
qobject_cast<AnnotationTableColorButton *>(editor)->color(),
Qt::DisplayRole);
}
else if (data.userType() == QMetaType::QString)
model->setData(index, qobject_cast<QLineEdit *>(editor)->text(), Qt::DisplayRole);
else
@@ -247,6 +283,16 @@ void RichTextCellEditor::mouseReleaseEvent(QMouseEvent *)
emit clicked();
}
AnnotationTableColorButton::AnnotationTableColorButton(QWidget *parent)
: Utils::QtColorButton(parent)
{
connect(this, &Utils::QtColorButton::colorChangeStarted, this, [this](){emit editorStarted(this);});
connect(this, &Utils::QtColorButton::colorChanged, this, [this](QColor){emit editorFinished(this);});
connect(this, &Utils::QtColorButton::colorUnchanged, this, [this](){emit editorCanceled(this);});
}
AnnotationTableColorButton::~AnnotationTableColorButton() {}
AnnotationTableView::AnnotationTableView(QWidget *parent)
: QTableView(parent)
, m_model(std::make_unique<QStandardItemModel>())
@@ -283,7 +329,7 @@ AnnotationTableView::AnnotationTableView(QWidget *parent)
m_editorFactory->registerEditor(qMetaTypeId<RichTextProxy>(),
new QItemEditorCreator<RichTextCellEditor>("richText"));
m_editorFactory->registerEditor(QMetaType::QColor,
new QItemEditorCreator<Utils::QtColorButton>("color"));
new QItemEditorCreator<AnnotationTableColorButton>("color"));
m_valueDelegate.setItemEditorFactory(m_editorFactory.get());
connect(&m_valueDelegate,

View File

@@ -33,12 +33,15 @@
#include "annotation.h"
#include "defaultannotations.h"
#include <utils/qtcolorbutton.h>
QT_BEGIN_NAMESPACE
class QStandardItemModel;
class QCompleter;
QT_END_NAMESPACE
namespace QmlDesigner {
class CommentDelegate : public QItemDelegate
{
Q_OBJECT
@@ -98,6 +101,11 @@ public:
void setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const override;
public slots:
void slotEditorFinished(QWidget* editor);
void slotEditorCanceled(QWidget* editor);
signals:
void richTextEditorRequested(int index, QString const &richText);
};
@@ -129,6 +137,21 @@ private:
QMetaObject::Connection m_connection;
};
class AnnotationTableColorButton : public Utils::QtColorButton
{
Q_OBJECT
public:
AnnotationTableColorButton(QWidget* parent);
~AnnotationTableColorButton();
bool eventFilter(QObject *object, QEvent *event) override;
signals:
void editorStarted(QWidget* editor);
void editorFinished(QWidget* editor);
void editorCanceled(QWidget* editor);
};
class AnnotationTableView : public QTableView
{
Q_OBJECT