improved settings dialog API
This commit is contained in:
parent
4cca128180
commit
87fd94a2e0
|
@ -18,12 +18,15 @@ set(HEADER_FILES
|
||||||
settingsdialog/optioncategorymodel.h
|
settingsdialog/optioncategorymodel.h
|
||||||
settingsdialog/optionpage.h
|
settingsdialog/optionpage.h
|
||||||
settingsdialog/settingsdialog.h
|
settingsdialog/settingsdialog.h
|
||||||
|
settingsdialog/qtsettings.h
|
||||||
widgets/buttonoverlay.h
|
widgets/buttonoverlay.h
|
||||||
widgets/clearcombobox.h
|
widgets/clearcombobox.h
|
||||||
widgets/clearlineedit.h
|
widgets/clearlineedit.h
|
||||||
widgets/clearplaintextedit.h
|
widgets/clearplaintextedit.h
|
||||||
widgets/clearspinbox.h
|
widgets/clearspinbox.h
|
||||||
widgets/iconbutton.h
|
widgets/iconbutton.h
|
||||||
|
paletteeditor/paletteeditor.h
|
||||||
|
paletteeditor/colorbutton.h
|
||||||
)
|
)
|
||||||
set(SRC_FILES
|
set(SRC_FILES
|
||||||
aboutdialog/aboutdialog.cpp
|
aboutdialog/aboutdialog.cpp
|
||||||
|
@ -38,18 +41,24 @@ set(SRC_FILES
|
||||||
settingsdialog/optioncategorymodel.cpp
|
settingsdialog/optioncategorymodel.cpp
|
||||||
settingsdialog/optionpage.cpp
|
settingsdialog/optionpage.cpp
|
||||||
settingsdialog/settingsdialog.cpp
|
settingsdialog/settingsdialog.cpp
|
||||||
|
settingsdialog/qtsettings.cpp
|
||||||
widgets/buttonoverlay.cpp
|
widgets/buttonoverlay.cpp
|
||||||
widgets/clearcombobox.cpp
|
widgets/clearcombobox.cpp
|
||||||
widgets/clearlineedit.cpp
|
widgets/clearlineedit.cpp
|
||||||
widgets/clearplaintextedit.cpp
|
widgets/clearplaintextedit.cpp
|
||||||
widgets/clearspinbox.cpp
|
widgets/clearspinbox.cpp
|
||||||
widgets/iconbutton.cpp
|
widgets/iconbutton.cpp
|
||||||
|
paletteeditor/paletteeditor.cpp
|
||||||
|
paletteeditor/colorbutton.cpp
|
||||||
resources/qtutilsicons.qrc
|
resources/qtutilsicons.qrc
|
||||||
)
|
)
|
||||||
set(WIDGETS_UI_FILES
|
set(WIDGETS_UI_FILES
|
||||||
aboutdialog/aboutdialog.ui
|
aboutdialog/aboutdialog.ui
|
||||||
enterpassworddialog/enterpassworddialog.ui
|
enterpassworddialog/enterpassworddialog.ui
|
||||||
settingsdialog/settingsdialog.ui
|
settingsdialog/settingsdialog.ui
|
||||||
|
settingsdialog/qtappearanceoptionpage.ui
|
||||||
|
settingsdialog/qtlanguageoptionpage.ui
|
||||||
|
paletteeditor/paletteeditor.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
# meta data
|
# meta data
|
||||||
|
|
|
@ -0,0 +1,233 @@
|
||||||
|
#include "./colorbutton.h"
|
||||||
|
|
||||||
|
#include <QColorDialog>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QDragEnterEvent>
|
||||||
|
#include <QDrag>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
namespace Widgets {
|
||||||
|
|
||||||
|
class ColorButtonPrivate
|
||||||
|
{
|
||||||
|
ColorButton *q_ptr;
|
||||||
|
Q_DECLARE_PUBLIC(ColorButton)
|
||||||
|
public:
|
||||||
|
QColor m_color;
|
||||||
|
#ifndef QT_NO_DRAGANDDROP
|
||||||
|
QColor m_dragColor;
|
||||||
|
QPoint m_dragStart;
|
||||||
|
bool m_dragging;
|
||||||
|
#endif
|
||||||
|
bool m_backgroundCheckered;
|
||||||
|
|
||||||
|
void slotEditColor();
|
||||||
|
QColor shownColor() const;
|
||||||
|
QPixmap generatePixmap() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ColorButtonPrivate::slotEditColor()
|
||||||
|
{
|
||||||
|
const QColor newColor = QColorDialog::getColor(m_color, q_ptr, QString(), QColorDialog::ShowAlphaChannel);
|
||||||
|
if (!newColor.isValid() || newColor == q_ptr->color())
|
||||||
|
return;
|
||||||
|
q_ptr->setColor(newColor);
|
||||||
|
emit q_ptr->colorChanged(m_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor ColorButtonPrivate::shownColor() const
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_DRAGANDDROP
|
||||||
|
if (m_dragging)
|
||||||
|
return m_dragColor;
|
||||||
|
#endif
|
||||||
|
return m_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap ColorButtonPrivate::generatePixmap() const
|
||||||
|
{
|
||||||
|
QPixmap pix(24, 24);
|
||||||
|
|
||||||
|
int pixSize = 20;
|
||||||
|
QBrush br(shownColor());
|
||||||
|
|
||||||
|
QPixmap pm(2 * pixSize, 2 * pixSize);
|
||||||
|
QPainter pmp(&pm);
|
||||||
|
pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
|
||||||
|
pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
|
||||||
|
pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
|
||||||
|
pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
|
||||||
|
pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, shownColor());
|
||||||
|
br = QBrush(pm);
|
||||||
|
|
||||||
|
QPainter p(&pix);
|
||||||
|
int corr = 1;
|
||||||
|
QRect r = pix.rect().adjusted(corr, corr, -corr, -corr);
|
||||||
|
p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
|
||||||
|
p.fillRect(r, br);
|
||||||
|
|
||||||
|
p.fillRect(r.width() / 4 + corr, r.height() / 4 + corr,
|
||||||
|
r.width() / 2, r.height() / 2,
|
||||||
|
QColor(shownColor().rgb()));
|
||||||
|
p.drawRect(pix.rect().adjusted(0, 0, -1, -1));
|
||||||
|
|
||||||
|
return pix;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
|
||||||
|
ColorButton::ColorButton(QWidget *parent)
|
||||||
|
: QToolButton(parent), d_ptr(new ColorButtonPrivate)
|
||||||
|
{
|
||||||
|
d_ptr->q_ptr = this;
|
||||||
|
d_ptr->m_dragging = false;
|
||||||
|
d_ptr->m_backgroundCheckered = true;
|
||||||
|
|
||||||
|
setAcceptDrops(true);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(clicked()), this, SLOT(slotEditColor()));
|
||||||
|
setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorButton::~ColorButton()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorButton::setColor(const QColor &color)
|
||||||
|
{
|
||||||
|
if (d_ptr->m_color == color)
|
||||||
|
return;
|
||||||
|
d_ptr->m_color = color;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor ColorButton::color() const
|
||||||
|
{
|
||||||
|
return d_ptr->m_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorButton::setBackgroundCheckered(bool checkered)
|
||||||
|
{
|
||||||
|
if (d_ptr->m_backgroundCheckered == checkered)
|
||||||
|
return;
|
||||||
|
d_ptr->m_backgroundCheckered = checkered;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ColorButton::isBackgroundCheckered() const
|
||||||
|
{
|
||||||
|
return d_ptr->m_backgroundCheckered;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorButton::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
QToolButton::paintEvent(event);
|
||||||
|
if (!isEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int pixSize = 10;
|
||||||
|
QBrush br(d_ptr->shownColor());
|
||||||
|
if (d_ptr->m_backgroundCheckered) {
|
||||||
|
QPixmap pm(2 * pixSize, 2 * pixSize);
|
||||||
|
QPainter pmp(&pm);
|
||||||
|
pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
|
||||||
|
pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
|
||||||
|
pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
|
||||||
|
pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
|
||||||
|
pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, d_ptr->shownColor());
|
||||||
|
br = QBrush(pm);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainter p(this);
|
||||||
|
const int corr = 4;
|
||||||
|
QRect r = rect().adjusted(corr, corr, -corr, -corr);
|
||||||
|
p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
|
||||||
|
p.fillRect(r, br);
|
||||||
|
|
||||||
|
//const int adjX = qRound(r.width() / 4.0);
|
||||||
|
//const int adjY = qRound(r.height() / 4.0);
|
||||||
|
//p.fillRect(r.adjusted(adjX, adjY, -adjX, -adjY),
|
||||||
|
// QColor(d_ptr->shownColor().rgb()));
|
||||||
|
/*
|
||||||
|
p.fillRect(r.adjusted(0, r.height() * 3 / 4, 0, 0),
|
||||||
|
QColor(d_ptr->shownColor().rgb()));
|
||||||
|
p.fillRect(r.adjusted(0, 0, 0, -r.height() * 3 / 4),
|
||||||
|
QColor(d_ptr->shownColor().rgb()));
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
const QColor frameColor0(0, 0, 0, qRound(0.2 * (0xFF - d_ptr->shownColor().alpha())));
|
||||||
|
p.setPen(frameColor0);
|
||||||
|
p.drawRect(r.adjusted(adjX, adjY, -adjX - 1, -adjY - 1));
|
||||||
|
*/
|
||||||
|
|
||||||
|
const QColor frameColor1(0, 0, 0, 26);
|
||||||
|
p.setPen(frameColor1);
|
||||||
|
p.drawRect(r.adjusted(1, 1, -2, -2));
|
||||||
|
const QColor frameColor2(0, 0, 0, 51);
|
||||||
|
p.setPen(frameColor2);
|
||||||
|
p.drawRect(r.adjusted(0, 0, -1, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorButton::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_DRAGANDDROP
|
||||||
|
if (event->button() == Qt::LeftButton)
|
||||||
|
d_ptr->m_dragStart = event->pos();
|
||||||
|
#endif
|
||||||
|
QToolButton::mousePressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorButton::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_DRAGANDDROP
|
||||||
|
if (event->buttons() & Qt::LeftButton &&
|
||||||
|
(d_ptr->m_dragStart - event->pos()).manhattanLength() > QApplication::startDragDistance()) {
|
||||||
|
QMimeData *mime = new QMimeData;
|
||||||
|
mime->setColorData(color());
|
||||||
|
QDrag *drg = new QDrag(this);
|
||||||
|
drg->setMimeData(mime);
|
||||||
|
drg->setPixmap(d_ptr->generatePixmap());
|
||||||
|
setDown(false);
|
||||||
|
event->accept();
|
||||||
|
drg->start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
QToolButton::mouseMoveEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_DRAGANDDROP
|
||||||
|
void ColorButton::dragEnterEvent(QDragEnterEvent *event)
|
||||||
|
{
|
||||||
|
const QMimeData *mime = event->mimeData();
|
||||||
|
if (!mime->hasColor())
|
||||||
|
return;
|
||||||
|
|
||||||
|
event->accept();
|
||||||
|
d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
|
||||||
|
d_ptr->m_dragging = true;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorButton::dragLeaveEvent(QDragLeaveEvent *event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
d_ptr->m_dragging = false;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorButton::dropEvent(QDropEvent *event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
d_ptr->m_dragging = false;
|
||||||
|
if (d_ptr->m_dragColor == color())
|
||||||
|
return;
|
||||||
|
setColor(d_ptr->m_dragColor);
|
||||||
|
emit colorChanged(color());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_colorbutton.cpp"
|
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef COLORBUTTON_H
|
||||||
|
#define COLORBUTTON_H
|
||||||
|
|
||||||
|
#include <c++utilities/application/global.h>
|
||||||
|
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
|
namespace Widgets {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The ColorButton class is used by PaletteEditor.
|
||||||
|
*
|
||||||
|
* This is taken from qttools/src/shared/qtgradienteditor/qtcolorbutton.h.
|
||||||
|
*/
|
||||||
|
class LIB_EXPORT ColorButton : public QToolButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
|
||||||
|
public:
|
||||||
|
ColorButton(QWidget *parent = nullptr);
|
||||||
|
~ColorButton();
|
||||||
|
|
||||||
|
bool isBackgroundCheckered() const;
|
||||||
|
void setBackgroundCheckered(bool checkered);
|
||||||
|
|
||||||
|
QColor color() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setColor(const QColor &color);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void colorChanged(const QColor &color);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event);
|
||||||
|
void mousePressEvent(QMouseEvent *event);
|
||||||
|
void mouseMoveEvent(QMouseEvent *event);
|
||||||
|
#ifndef QT_NO_DRAGANDDROP
|
||||||
|
void dragEnterEvent(QDragEnterEvent *event);
|
||||||
|
void dragLeaveEvent(QDragLeaveEvent *event);
|
||||||
|
void dropEvent(QDropEvent *event);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<class ColorButtonPrivate> d_ptr;
|
||||||
|
Q_DECLARE_PRIVATE(ColorButton)
|
||||||
|
Q_DISABLE_COPY(ColorButton)
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void slotEditColor())
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,561 @@
|
||||||
|
#include "./paletteeditor.h"
|
||||||
|
#include "./colorbutton.h"
|
||||||
|
|
||||||
|
#include <QMetaProperty>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
|
using namespace Widgets;
|
||||||
|
|
||||||
|
namespace Dialogs {
|
||||||
|
|
||||||
|
enum { BrushRole = 33 };
|
||||||
|
|
||||||
|
PaletteEditor::PaletteEditor(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
m_currentColorGroup(QPalette::Active),
|
||||||
|
m_paletteModel(new PaletteModel(this)),
|
||||||
|
m_modelUpdated(false),
|
||||||
|
m_paletteUpdated(false),
|
||||||
|
m_compute(true)
|
||||||
|
{
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
m_ui.paletteView->setModel(m_paletteModel);
|
||||||
|
updatePreviewPalette();
|
||||||
|
updateStyledButton();
|
||||||
|
m_ui.paletteView->setModel(m_paletteModel);
|
||||||
|
ColorDelegate *delegate = new ColorDelegate(this);
|
||||||
|
m_ui.paletteView->setItemDelegate(delegate);
|
||||||
|
m_ui.paletteView->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||||
|
connect(m_paletteModel, &PaletteModel::paletteChanged,
|
||||||
|
this, &PaletteEditor::paletteChanged);
|
||||||
|
m_ui.paletteView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
m_ui.paletteView->setDragEnabled(true);
|
||||||
|
m_ui.paletteView->setDropIndicatorShown(true);
|
||||||
|
m_ui.paletteView->setRootIsDecorated(false);
|
||||||
|
m_ui.paletteView->setColumnHidden(2, true);
|
||||||
|
m_ui.paletteView->setColumnHidden(3, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
PaletteEditor::~PaletteEditor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QPalette PaletteEditor::palette() const
|
||||||
|
{
|
||||||
|
return m_editPalette;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::setPalette(const QPalette &palette)
|
||||||
|
{
|
||||||
|
m_editPalette = palette;
|
||||||
|
const uint mask = palette.resolve();
|
||||||
|
for (int i = 0; i < (int)QPalette::NColorRoles; i++) {
|
||||||
|
if (!(mask & (1 << i))) {
|
||||||
|
m_editPalette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(i),
|
||||||
|
m_parentPalette.brush(QPalette::Active, static_cast<QPalette::ColorRole>(i)));
|
||||||
|
m_editPalette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i),
|
||||||
|
m_parentPalette.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i)));
|
||||||
|
m_editPalette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i),
|
||||||
|
m_parentPalette.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_editPalette.resolve(mask);
|
||||||
|
updatePreviewPalette();
|
||||||
|
updateStyledButton();
|
||||||
|
m_paletteUpdated = true;
|
||||||
|
if (!m_modelUpdated)
|
||||||
|
m_paletteModel->setPalette(m_editPalette, m_parentPalette);
|
||||||
|
m_paletteUpdated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::setPalette(const QPalette &palette, const QPalette &parentPalette)
|
||||||
|
{
|
||||||
|
m_parentPalette = parentPalette;
|
||||||
|
setPalette(palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::on_buildButton_colorChanged(const QColor &)
|
||||||
|
{
|
||||||
|
buildPalette();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::on_activeRadio_clicked()
|
||||||
|
{
|
||||||
|
m_currentColorGroup = QPalette::Active;
|
||||||
|
updatePreviewPalette();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::on_inactiveRadio_clicked()
|
||||||
|
{
|
||||||
|
m_currentColorGroup = QPalette::Inactive;
|
||||||
|
updatePreviewPalette();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::on_disabledRadio_clicked()
|
||||||
|
{
|
||||||
|
m_currentColorGroup = QPalette::Disabled;
|
||||||
|
updatePreviewPalette();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::on_computeRadio_clicked()
|
||||||
|
{
|
||||||
|
if (m_compute)
|
||||||
|
return;
|
||||||
|
m_ui.paletteView->setColumnHidden(2, true);
|
||||||
|
m_ui.paletteView->setColumnHidden(3, true);
|
||||||
|
m_compute = true;
|
||||||
|
m_paletteModel->setCompute(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::on_detailsRadio_clicked()
|
||||||
|
{
|
||||||
|
if (!m_compute)
|
||||||
|
return;
|
||||||
|
const int w = m_ui.paletteView->columnWidth(1);
|
||||||
|
m_ui.paletteView->setColumnHidden(2, false);
|
||||||
|
m_ui.paletteView->setColumnHidden(3, false);
|
||||||
|
QHeaderView *header = m_ui.paletteView->header();
|
||||||
|
header->resizeSection(1, w / 3);
|
||||||
|
header->resizeSection(2, w / 3);
|
||||||
|
header->resizeSection(3, w / 3);
|
||||||
|
m_compute = false;
|
||||||
|
m_paletteModel->setCompute(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::paletteChanged(const QPalette &palette)
|
||||||
|
{
|
||||||
|
m_modelUpdated = true;
|
||||||
|
if (!m_paletteUpdated)
|
||||||
|
setPalette(palette);
|
||||||
|
m_modelUpdated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::buildPalette()
|
||||||
|
{
|
||||||
|
const QColor btn = m_ui.buildButton->color();
|
||||||
|
const QPalette temp = QPalette(btn);
|
||||||
|
setPalette(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::updatePreviewPalette()
|
||||||
|
{
|
||||||
|
const QPalette::ColorGroup g = currentColorGroup();
|
||||||
|
// build the preview palette
|
||||||
|
const QPalette currentPalette = palette();
|
||||||
|
QPalette previewPalette;
|
||||||
|
for(int i = QPalette::WindowText; i < QPalette::NColorRoles; ++i) {
|
||||||
|
const QPalette::ColorRole r = static_cast<QPalette::ColorRole>(i);
|
||||||
|
const QBrush br = currentPalette.brush(g, r);
|
||||||
|
previewPalette.setBrush(QPalette::Active, r, br);
|
||||||
|
previewPalette.setBrush(QPalette::Inactive, r, br);
|
||||||
|
previewPalette.setBrush(QPalette::Disabled, r, br);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteEditor::updateStyledButton()
|
||||||
|
{
|
||||||
|
m_ui.buildButton->setColor(palette().color(QPalette::Active, QPalette::Button));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPalette PaletteEditor::getPalette(QWidget *parent, const QPalette &init,
|
||||||
|
const QPalette &parentPal, int *ok)
|
||||||
|
{
|
||||||
|
PaletteEditor dlg(parent);
|
||||||
|
QPalette parentPalette(parentPal);
|
||||||
|
uint mask = init.resolve();
|
||||||
|
for (int i = 0; i < (int)QPalette::NColorRoles; ++i) {
|
||||||
|
if (!(mask & (1 << i))) {
|
||||||
|
parentPalette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(i),
|
||||||
|
init.brush(QPalette::Active, static_cast<QPalette::ColorRole>(i)));
|
||||||
|
parentPalette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i),
|
||||||
|
init.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i)));
|
||||||
|
parentPalette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i),
|
||||||
|
init.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dlg.setPalette(init, parentPalette);
|
||||||
|
|
||||||
|
const int result = dlg.exec();
|
||||||
|
if (ok) *ok = result;
|
||||||
|
|
||||||
|
return result == QDialog::Accepted ? dlg.palette() : init;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
|
||||||
|
PaletteModel::PaletteModel(QObject *parent) :
|
||||||
|
QAbstractTableModel(parent),
|
||||||
|
m_compute(true)
|
||||||
|
{
|
||||||
|
const QMetaObject *meta = metaObject();
|
||||||
|
const int index = meta->indexOfProperty("colorRole");
|
||||||
|
const QMetaProperty p = meta->property(index);
|
||||||
|
const QMetaEnum e = p.enumerator();
|
||||||
|
for (int r = QPalette::WindowText; r < QPalette::NColorRoles; r++) {
|
||||||
|
m_roleNames[static_cast<QPalette::ColorRole>(r)] = QLatin1String(e.key(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PaletteModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return m_roleNames.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PaletteModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PaletteModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
if (index.row() < 0 || index.row() >= QPalette::NColorRoles)
|
||||||
|
return QVariant();
|
||||||
|
if (index.column() < 0 || index.column() >= 4)
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (index.column() == 0) {
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return m_roleNames[static_cast<QPalette::ColorRole>(index.row())];
|
||||||
|
if (role == Qt::EditRole) {
|
||||||
|
const uint mask = m_palette.resolve();
|
||||||
|
if (mask & (1 << index.row()))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
if (role == BrushRole)
|
||||||
|
return m_palette.brush(columnToGroup(index.column()),
|
||||||
|
static_cast<QPalette::ColorRole>(index.row()));
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PaletteModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (index.column() != 0 && role == BrushRole) {
|
||||||
|
const QBrush br = qvariant_cast<QBrush>(value);
|
||||||
|
const QPalette::ColorRole r = static_cast<QPalette::ColorRole>(index.row());
|
||||||
|
const QPalette::ColorGroup g = columnToGroup(index.column());
|
||||||
|
m_palette.setBrush(g, r, br);
|
||||||
|
|
||||||
|
QModelIndex idxBegin = PaletteModel::index(r, 0);
|
||||||
|
QModelIndex idxEnd = PaletteModel::index(r, 3);
|
||||||
|
if (m_compute) {
|
||||||
|
m_palette.setBrush(QPalette::Inactive, r, br);
|
||||||
|
switch (r) {
|
||||||
|
case QPalette::WindowText:
|
||||||
|
case QPalette::Text:
|
||||||
|
case QPalette::ButtonText:
|
||||||
|
case QPalette::Base:
|
||||||
|
break;
|
||||||
|
case QPalette::Dark:
|
||||||
|
m_palette.setBrush(QPalette::Disabled, QPalette::WindowText, br);
|
||||||
|
m_palette.setBrush(QPalette::Disabled, QPalette::Dark, br);
|
||||||
|
m_palette.setBrush(QPalette::Disabled, QPalette::Text, br);
|
||||||
|
m_palette.setBrush(QPalette::Disabled, QPalette::ButtonText, br);
|
||||||
|
idxBegin = PaletteModel::index(0, 0);
|
||||||
|
idxEnd = PaletteModel::index(m_roleNames.count() - 1, 3);
|
||||||
|
break;
|
||||||
|
case QPalette::Window:
|
||||||
|
m_palette.setBrush(QPalette::Disabled, QPalette::Base, br);
|
||||||
|
m_palette.setBrush(QPalette::Disabled, QPalette::Window, br);
|
||||||
|
idxBegin = PaletteModel::index(QPalette::Base, 0);
|
||||||
|
break;
|
||||||
|
case QPalette::Highlight:
|
||||||
|
//m_palette.setBrush(QPalette::Disabled, QPalette::Highlight, c.dark(120));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_palette.setBrush(QPalette::Disabled, r, br);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit paletteChanged(m_palette);
|
||||||
|
emit dataChanged(idxBegin, idxEnd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (index.column() == 0 && role == Qt::EditRole) {
|
||||||
|
uint mask = m_palette.resolve();
|
||||||
|
const bool isMask = qvariant_cast<bool>(value);
|
||||||
|
const int r = index.row();
|
||||||
|
if (isMask)
|
||||||
|
mask |= (1 << r);
|
||||||
|
else {
|
||||||
|
m_palette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(r),
|
||||||
|
m_parentPalette.brush(QPalette::Active, static_cast<QPalette::ColorRole>(r)));
|
||||||
|
m_palette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(r),
|
||||||
|
m_parentPalette.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(r)));
|
||||||
|
m_palette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(r),
|
||||||
|
m_parentPalette.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(r)));
|
||||||
|
|
||||||
|
mask &= ~(1 << index.row());
|
||||||
|
}
|
||||||
|
m_palette.resolve(mask);
|
||||||
|
emit paletteChanged(m_palette);
|
||||||
|
const QModelIndex idxEnd = PaletteModel::index(r, 3);
|
||||||
|
emit dataChanged(index, idxEnd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags PaletteModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return Qt::ItemIsEnabled;
|
||||||
|
return Qt::ItemIsEditable | Qt::ItemIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PaletteModel::headerData(int section, Qt::Orientation orientation,
|
||||||
|
int role) const
|
||||||
|
{
|
||||||
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||||
|
if (section == 0)
|
||||||
|
return tr("Color Role");
|
||||||
|
if (section == groupToColumn(QPalette::Active))
|
||||||
|
return tr("Active");
|
||||||
|
if (section == groupToColumn(QPalette::Inactive))
|
||||||
|
return tr("Inactive");
|
||||||
|
if (section == groupToColumn(QPalette::Disabled))
|
||||||
|
return tr("Disabled");
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPalette PaletteModel::getPalette() const
|
||||||
|
{
|
||||||
|
return m_palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteModel::setPalette(const QPalette &palette, const QPalette &parentPalette)
|
||||||
|
{
|
||||||
|
m_parentPalette = parentPalette;
|
||||||
|
m_palette = palette;
|
||||||
|
const QModelIndex idxBegin = index(0, 0);
|
||||||
|
const QModelIndex idxEnd = index(m_roleNames.count() - 1, 3);
|
||||||
|
emit dataChanged(idxBegin, idxEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPalette::ColorGroup PaletteModel::columnToGroup(int index) const
|
||||||
|
{
|
||||||
|
if (index == 1)
|
||||||
|
return QPalette::Active;
|
||||||
|
if (index == 2)
|
||||||
|
return QPalette::Inactive;
|
||||||
|
return QPalette::Disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PaletteModel::groupToColumn(QPalette::ColorGroup group) const
|
||||||
|
{
|
||||||
|
if (group == QPalette::Active)
|
||||||
|
return 1;
|
||||||
|
if (group == QPalette::Inactive)
|
||||||
|
return 2;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
|
||||||
|
BrushEditor::BrushEditor(QWidget *parent) :
|
||||||
|
QWidget(parent),
|
||||||
|
m_button(new ColorButton(this)),
|
||||||
|
m_changed(false)
|
||||||
|
{
|
||||||
|
QLayout *layout = new QHBoxLayout(this);
|
||||||
|
layout->setMargin(0);
|
||||||
|
layout->addWidget(m_button);
|
||||||
|
connect(m_button, &ColorButton::colorChanged, this, &BrushEditor::brushChanged);
|
||||||
|
setFocusProxy(m_button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrushEditor::setBrush(const QBrush &brush)
|
||||||
|
{
|
||||||
|
m_button->setColor(brush.color());
|
||||||
|
m_changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QBrush BrushEditor::brush() const
|
||||||
|
{
|
||||||
|
return QBrush(m_button->color());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrushEditor::brushChanged()
|
||||||
|
{
|
||||||
|
m_changed = true;
|
||||||
|
emit changed(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BrushEditor::changed() const
|
||||||
|
{
|
||||||
|
return m_changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
|
||||||
|
RoleEditor::RoleEditor(QWidget *parent) :
|
||||||
|
QWidget(parent),
|
||||||
|
m_label(new QLabel(this)),
|
||||||
|
m_edited(false)
|
||||||
|
{
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||||
|
layout->setMargin(0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
|
||||||
|
layout->addWidget(m_label);
|
||||||
|
m_label->setAutoFillBackground(true);
|
||||||
|
m_label->setIndent(3); // ### hardcode it should have the same value of textMargin in QItemDelegate
|
||||||
|
setFocusProxy(m_label);
|
||||||
|
|
||||||
|
QToolButton *button = new QToolButton(this);
|
||||||
|
button->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||||
|
button->setIcon(QIcon(QStringLiteral(":/qtutilities/icons/hicolor/16x16/actions/edit-clear.png")));
|
||||||
|
button->setIconSize(QSize(8,8));
|
||||||
|
button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding));
|
||||||
|
layout->addWidget(button);
|
||||||
|
connect(button, &QAbstractButton::clicked, this, &RoleEditor::emitResetProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoleEditor::setLabel(const QString &label)
|
||||||
|
{
|
||||||
|
m_label->setText(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoleEditor::setEdited(bool on)
|
||||||
|
{
|
||||||
|
QFont font;
|
||||||
|
if (on == true) {
|
||||||
|
font.setBold(on);
|
||||||
|
}
|
||||||
|
m_label->setFont(font);
|
||||||
|
m_edited = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RoleEditor::edited() const
|
||||||
|
{
|
||||||
|
return m_edited;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RoleEditor::emitResetProperty()
|
||||||
|
{
|
||||||
|
setEdited(false);
|
||||||
|
emit changed(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
ColorDelegate::ColorDelegate(QObject *parent) :
|
||||||
|
QItemDelegate(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *ColorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QWidget *ed = nullptr;
|
||||||
|
if (index.column() == 0) {
|
||||||
|
RoleEditor *editor = new RoleEditor(parent);
|
||||||
|
connect(editor, &RoleEditor::changed, this, &ColorDelegate::commitData);
|
||||||
|
//editor->setFocusPolicy(Qt::NoFocus);
|
||||||
|
//editor->installEventFilter(const_cast<ColorDelegate *>(this));
|
||||||
|
ed = editor;
|
||||||
|
} else {
|
||||||
|
typedef void (BrushEditor::*BrushEditorWidgetSignal)(QWidget *);
|
||||||
|
|
||||||
|
BrushEditor *editor = new BrushEditor(parent);
|
||||||
|
connect(editor, static_cast<BrushEditorWidgetSignal>(&BrushEditor::changed),
|
||||||
|
this, &ColorDelegate::commitData);
|
||||||
|
editor->setFocusPolicy(Qt::NoFocus);
|
||||||
|
editor->installEventFilter(const_cast<ColorDelegate *>(this));
|
||||||
|
ed = editor;
|
||||||
|
}
|
||||||
|
return ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorDelegate::setEditorData(QWidget *ed, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (index.column() == 0) {
|
||||||
|
const bool mask = qvariant_cast<bool>(index.model()->data(index, Qt::EditRole));
|
||||||
|
RoleEditor *editor = static_cast<RoleEditor *>(ed);
|
||||||
|
editor->setEdited(mask);
|
||||||
|
const QString colorName = qvariant_cast<QString>(index.model()->data(index, Qt::DisplayRole));
|
||||||
|
editor->setLabel(colorName);
|
||||||
|
} else {
|
||||||
|
const QBrush br = qvariant_cast<QBrush>(index.model()->data(index, BrushRole));
|
||||||
|
BrushEditor *editor = static_cast<BrushEditor *>(ed);
|
||||||
|
editor->setBrush(br);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorDelegate::setModelData(QWidget *ed, QAbstractItemModel *model,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (index.column() == 0) {
|
||||||
|
RoleEditor *editor = static_cast<RoleEditor *>(ed);
|
||||||
|
const bool mask = editor->edited();
|
||||||
|
model->setData(index, mask, Qt::EditRole);
|
||||||
|
} else {
|
||||||
|
BrushEditor *editor = static_cast<BrushEditor *>(ed);
|
||||||
|
if (editor->changed()) {
|
||||||
|
QBrush br = editor->brush();
|
||||||
|
model->setData(index, br, BrushRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorDelegate::updateEditorGeometry(QWidget *ed,
|
||||||
|
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QItemDelegate::updateEditorGeometry(ed, option, index);
|
||||||
|
ed->setGeometry(ed->geometry().adjusted(0, 0, -1, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QStyleOptionViewItem option = opt;
|
||||||
|
const bool mask = qvariant_cast<bool>(index.model()->data(index, Qt::EditRole));
|
||||||
|
if (index.column() == 0 && mask) {
|
||||||
|
option.font.setBold(true);
|
||||||
|
}
|
||||||
|
QBrush br = qvariant_cast<QBrush>(index.model()->data(index, BrushRole));
|
||||||
|
if (br.style() == Qt::LinearGradientPattern ||
|
||||||
|
br.style() == Qt::RadialGradientPattern ||
|
||||||
|
br.style() == Qt::ConicalGradientPattern) {
|
||||||
|
painter->save();
|
||||||
|
painter->translate(option.rect.x(), option.rect.y());
|
||||||
|
painter->scale(option.rect.width(), option.rect.height());
|
||||||
|
QGradient gr = *(br.gradient());
|
||||||
|
gr.setCoordinateMode(QGradient::LogicalMode);
|
||||||
|
br = QBrush(gr);
|
||||||
|
painter->fillRect(0, 0, 1, 1, br);
|
||||||
|
painter->restore();
|
||||||
|
} else {
|
||||||
|
painter->save();
|
||||||
|
painter->setBrushOrigin(option.rect.x(), option.rect.y());
|
||||||
|
painter->fillRect(option.rect, br);
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
QItemDelegate::paint(painter, option, index);
|
||||||
|
|
||||||
|
|
||||||
|
const QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &option));
|
||||||
|
const QPen oldPen = painter->pen();
|
||||||
|
painter->setPen(QPen(color));
|
||||||
|
|
||||||
|
painter->drawLine(option.rect.right(), option.rect.y(),
|
||||||
|
option.rect.right(), option.rect.bottom());
|
||||||
|
painter->drawLine(option.rect.x(), option.rect.bottom(),
|
||||||
|
option.rect.right(), option.rect.bottom());
|
||||||
|
painter->setPen(oldPen);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ColorDelegate::sizeHint(const QStyleOptionViewItem &opt, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
return QItemDelegate::sizeHint(opt, index) + QSize(4, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,178 @@
|
||||||
|
#ifndef PALETTEEDITOR_H
|
||||||
|
#define PALETTEEDITOR_H
|
||||||
|
|
||||||
|
#include "ui_paletteeditor.h"
|
||||||
|
|
||||||
|
#include <c++utilities/application/global.h>
|
||||||
|
|
||||||
|
#include <QItemDelegate>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QListView)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QLabel)
|
||||||
|
|
||||||
|
namespace Widgets {
|
||||||
|
class ColorButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Dialogs {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The PaletteEditor class provides a dialog to customize a QPalette.
|
||||||
|
*
|
||||||
|
* This is taken from qttools/src/designer/src/components/propertyeditor/paletteeditor.cpp.
|
||||||
|
* In contrast to the original version this version doesn't provide a preview.
|
||||||
|
*/
|
||||||
|
class LIB_EXPORT PaletteEditor : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
PaletteEditor(QWidget *parent);
|
||||||
|
~PaletteEditor();
|
||||||
|
|
||||||
|
static QPalette getPalette(QWidget *parent, const QPalette &init = QPalette(),
|
||||||
|
const QPalette &parentPal = QPalette(), int *result = nullptr);
|
||||||
|
|
||||||
|
QPalette palette() const;
|
||||||
|
void setPalette(const QPalette &palette);
|
||||||
|
void setPalette(const QPalette &palette, const QPalette &parentPalette);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_buildButton_colorChanged(const QColor &);
|
||||||
|
void on_activeRadio_clicked();
|
||||||
|
void on_inactiveRadio_clicked();
|
||||||
|
void on_disabledRadio_clicked();
|
||||||
|
void on_computeRadio_clicked();
|
||||||
|
void on_detailsRadio_clicked();
|
||||||
|
|
||||||
|
void paletteChanged(const QPalette &palette);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void buildPalette();
|
||||||
|
|
||||||
|
void updatePreviewPalette();
|
||||||
|
void updateStyledButton();
|
||||||
|
|
||||||
|
QPalette::ColorGroup currentColorGroup() const
|
||||||
|
{
|
||||||
|
return m_currentColorGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ui::PaletteEditor m_ui;
|
||||||
|
QPalette m_editPalette;
|
||||||
|
QPalette m_parentPalette;
|
||||||
|
QPalette::ColorGroup m_currentColorGroup;
|
||||||
|
class PaletteModel *m_paletteModel;
|
||||||
|
bool m_modelUpdated;
|
||||||
|
bool m_paletteUpdated;
|
||||||
|
bool m_compute;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The PaletteModel class is used by PaletteEditor.
|
||||||
|
*/
|
||||||
|
class LIB_EXPORT PaletteModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QPalette::ColorRole colorRole READ colorRole)
|
||||||
|
public:
|
||||||
|
explicit PaletteModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
|
int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
|
QPalette getPalette() const;
|
||||||
|
void setPalette(const QPalette &palette, const QPalette &parentPalette);
|
||||||
|
|
||||||
|
QPalette::ColorRole colorRole() const { return QPalette::NoRole; }
|
||||||
|
void setCompute(bool on) { m_compute = on; }
|
||||||
|
signals:
|
||||||
|
void paletteChanged(const QPalette &palette);
|
||||||
|
private:
|
||||||
|
|
||||||
|
QPalette::ColorGroup columnToGroup(int index) const;
|
||||||
|
int groupToColumn(QPalette::ColorGroup group) const;
|
||||||
|
|
||||||
|
QPalette m_palette;
|
||||||
|
QPalette m_parentPalette;
|
||||||
|
QMap<QPalette::ColorRole, QString> m_roleNames;
|
||||||
|
bool m_compute;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The BrushEditor class is used by PaletteEditor.
|
||||||
|
*/
|
||||||
|
class LIB_EXPORT BrushEditor : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit BrushEditor(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void setBrush(const QBrush &brush);
|
||||||
|
QBrush brush() const;
|
||||||
|
bool changed() const;
|
||||||
|
signals:
|
||||||
|
void changed(QWidget *widget);
|
||||||
|
private slots:
|
||||||
|
void brushChanged();
|
||||||
|
private:
|
||||||
|
Widgets::ColorButton *m_button;
|
||||||
|
bool m_changed;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The RoleEditor class is used by PaletteEditor.
|
||||||
|
*/
|
||||||
|
class LIB_EXPORT RoleEditor : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit RoleEditor(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void setLabel(const QString &label);
|
||||||
|
void setEdited(bool on);
|
||||||
|
bool edited() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void changed(QWidget *widget);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void emitResetProperty();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLabel *m_label;
|
||||||
|
bool m_edited;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The ColorDelegate class is used by PaletteEditor.
|
||||||
|
*/
|
||||||
|
class LIB_EXPORT ColorDelegate : public QItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ColorDelegate(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const;
|
||||||
|
|
||||||
|
void setEditorData(QWidget *ed, const QModelIndex &index) const;
|
||||||
|
void setModelData(QWidget *ed, QAbstractItemModel *model,
|
||||||
|
const QModelIndex &index) const;
|
||||||
|
|
||||||
|
void updateEditorGeometry(QWidget *ed,
|
||||||
|
const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
|
||||||
|
virtual void paint(QPainter *painter, const QStyleOptionViewItem &opt,
|
||||||
|
const QModelIndex &index) const;
|
||||||
|
QSize sizeHint(const QStyleOptionViewItem &opt, const QModelIndex &index) const Q_DECL_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PALETTEEDITOR_H
|
|
@ -0,0 +1,175 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Dialogs::PaletteEditor</class>
|
||||||
|
<widget class="QDialog" name="Dialogs::PaletteEditor">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>365</width>
|
||||||
|
<height>409</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Edit Palette</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="advancedBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Tune Palette</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item row="1" column="0" colspan="4">
|
||||||
|
<widget class="QTreeView" name="paletteView">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>200</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QRadioButton" name="detailsRadio">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show Detai&ls</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QRadioButton" name="computeRadio">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Compute Details</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Quick</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="Widgets::ColorButton" name="buildButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Ignored">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>Widgets::ColorButton</class>
|
||||||
|
<extends>QToolButton</extends>
|
||||||
|
<header>paletteeditor/colorbutton.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>Dialogs::PaletteEditor</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>180</x>
|
||||||
|
<y>331</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>134</x>
|
||||||
|
<y>341</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>Dialogs::PaletteEditor</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>287</x>
|
||||||
|
<y>329</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>302</x>
|
||||||
|
<y>342</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -60,13 +60,11 @@ bool OptionPage::matches(const QString &searchKeyWord)
|
||||||
if(searchKeyWord.isEmpty()) {
|
if(searchKeyWord.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(displayName().contains(searchKeyWord, Qt::CaseInsensitive)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if(!m_keywordsInitialized) {
|
if(!m_keywordsInitialized) {
|
||||||
if(!m_widget) {
|
if(!m_widget) {
|
||||||
m_widget.reset(setupWidget()); // ensure widget has been created
|
m_widget.reset(setupWidget()); // ensure widget has been created
|
||||||
}
|
}
|
||||||
|
m_keywords << m_widget->windowTitle();
|
||||||
// find common subwidgets
|
// find common subwidgets
|
||||||
for(const QLabel *label : m_widget->findChildren<QLabel *>())
|
for(const QLabel *label : m_widget->findChildren<QLabel *>())
|
||||||
m_keywords << label->text();
|
m_keywords << label->text();
|
||||||
|
@ -81,7 +79,7 @@ bool OptionPage::matches(const QString &searchKeyWord)
|
||||||
m_keywordsInitialized = true;
|
m_keywordsInitialized = true;
|
||||||
}
|
}
|
||||||
for(const QString &keyword : m_keywords)
|
for(const QString &keyword : m_keywords)
|
||||||
if (keyword.contains(searchKeyWord, Qt::CaseInsensitive))
|
if(keyword.contains(searchKeyWord, Qt::CaseInsensitive))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,16 @@ public:
|
||||||
virtual ~OptionPage();
|
virtual ~OptionPage();
|
||||||
|
|
||||||
QWidget *parentWindow() const;
|
QWidget *parentWindow() const;
|
||||||
virtual QString displayName() const = 0;
|
|
||||||
QWidget *widget();
|
QWidget *widget();
|
||||||
bool hasBeenShown() const;
|
bool hasBeenShown() const;
|
||||||
virtual bool apply() = 0;
|
virtual bool apply() = 0;
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
bool matches(const QString &searchKeyWord);
|
bool matches(const QString &searchKeyWord);
|
||||||
|
const QStringList &errors() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QWidget *setupWidget() = 0;
|
virtual QWidget *setupWidget() = 0;
|
||||||
|
QStringList &errors();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<QWidget> m_widget;
|
std::unique_ptr<QWidget> m_widget;
|
||||||
|
@ -33,6 +34,7 @@ private:
|
||||||
bool m_shown;
|
bool m_shown;
|
||||||
bool m_keywordsInitialized;
|
bool m_keywordsInitialized;
|
||||||
QStringList m_keywords;
|
QStringList m_keywords;
|
||||||
|
QStringList m_errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -51,6 +53,25 @@ inline bool OptionPage::hasBeenShown() const
|
||||||
return m_widget != nullptr && m_shown;
|
return m_widget != nullptr && m_shown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the errors which haven been occurred when applying the changes.
|
||||||
|
*/
|
||||||
|
inline const QStringList &OptionPage::errors() const
|
||||||
|
{
|
||||||
|
return m_errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the errors which haven been occurred when applying the changes.
|
||||||
|
*
|
||||||
|
* Error messages should be added when implementing apply() and something goes wrong.
|
||||||
|
* In this case, apply() should return false.
|
||||||
|
*/
|
||||||
|
inline QStringList &OptionPage::errors()
|
||||||
|
{
|
||||||
|
return m_errors;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \class Dialogs::UiFileBasedOptionPage
|
* \class Dialogs::UiFileBasedOptionPage
|
||||||
* \brief The UiFileBasedOptionPage class is the base class for SettingsDialog pages using UI files
|
* \brief The UiFileBasedOptionPage class is the base class for SettingsDialog pages using UI files
|
||||||
|
@ -65,7 +86,6 @@ public:
|
||||||
explicit UiFileBasedOptionPage(QWidget *parentWindow = nullptr);
|
explicit UiFileBasedOptionPage(QWidget *parentWindow = nullptr);
|
||||||
virtual ~UiFileBasedOptionPage();
|
virtual ~UiFileBasedOptionPage();
|
||||||
|
|
||||||
virtual QString displayName() const = 0;
|
|
||||||
virtual bool apply() = 0;
|
virtual bool apply() = 0;
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
|
|
||||||
|
@ -114,4 +134,45 @@ inline UiClass *UiFileBasedOptionPage<UiClass>::ui()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BEGIN_DECLARE_OPTION_PAGE(SomeClass) \
|
||||||
|
class SomeClass : public ::Dialogs::OptionPage \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
explicit SomeClass(QWidget *parentWidget = nullptr); \
|
||||||
|
~SomeClass(); \
|
||||||
|
bool apply(); \
|
||||||
|
void reset(); \
|
||||||
|
private:
|
||||||
|
|
||||||
|
#define BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE(SomeClass) \
|
||||||
|
namespace Ui { \
|
||||||
|
class SomeClass; \
|
||||||
|
} \
|
||||||
|
typedef ::Dialogs::UiFileBasedOptionPage<Ui::SomeClass> SomeClass ## Base; \
|
||||||
|
class SomeClass : public ::Dialogs::UiFileBasedOptionPage<Ui::SomeClass> \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
explicit SomeClass(QWidget *parentWidget = nullptr); \
|
||||||
|
~SomeClass(); \
|
||||||
|
bool apply(); \
|
||||||
|
void reset(); \
|
||||||
|
private:
|
||||||
|
|
||||||
|
#define END_DECLARE_OPTION_PAGE \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DECLARE_SETUP_WIDGETS \
|
||||||
|
protected: \
|
||||||
|
QWidget *setupWidget(); \
|
||||||
|
private:
|
||||||
|
|
||||||
|
#define DECLARE_UI_FILE_BASED_OPTION_PAGE(SomeClass) \
|
||||||
|
BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE(SomeClass) \
|
||||||
|
END_DECLARE_OPTION_PAGE
|
||||||
|
|
||||||
|
#define DECLARE_UI_FILE_BASED_OPTION_PAGE_CUSTOM_SETUP(SomeClass) \
|
||||||
|
BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE(SomeClass) \
|
||||||
|
DECLARE_SETUP_WIDGETS \
|
||||||
|
END_DECLARE_OPTION_PAGE
|
||||||
|
|
||||||
#endif // OPTIONSPAGE_H
|
#endif // OPTIONSPAGE_H
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>NS::Class</class>
|
||||||
|
<widget class="QWidget" name="NS::Class">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>345</width>
|
||||||
|
<height>146</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Window title</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QGroupBox { font-weight: bold };</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -0,0 +1,277 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Dialogs::QtAppearanceOptionPage</class>
|
||||||
|
<widget class="QWidget" name="Dialogs::QtAppearanceOptionPage">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>514</width>
|
||||||
|
<height>158</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Appearance</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QGroupBox { font-weight: bold };</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="mainGridLayout">
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="styleSheetLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Style sheet</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2" alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QCheckBox" name="fontCheckBox">
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="widgetStyleComboBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QToolButton" name="paletteToolButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>select ...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="widgetStyleLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Widget style</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="fontHorizontalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QFontComboBox" name="fontComboBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="fontPushButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>More options ...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="paletteLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Palette</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="styleSheetHorizontalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="Widgets::ClearLineEdit" name="styleSheetLineEdit">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="styleSheetPushButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Select file ...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="fontLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Font</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="useDefaultLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use system default</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2" alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QCheckBox" name="widgetStyleCheckBox">
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2" alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QCheckBox" name="styleSheetCheckBox">
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="2" alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QCheckBox" name="paletteCheckBox">
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>Widgets::ClearLineEdit</class>
|
||||||
|
<extends>QLineEdit</extends>
|
||||||
|
<header location="global">qtutilities/widgets/clearlineedit.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>fontCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>fontComboBox</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>462</x>
|
||||||
|
<y>38</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>193</x>
|
||||||
|
<y>39</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>fontCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>fontPushButton</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>462</x>
|
||||||
|
<y>38</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>365</x>
|
||||||
|
<y>39</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>widgetStyleCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>widgetStyleComboBox</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>462</x>
|
||||||
|
<y>71</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>240</x>
|
||||||
|
<y>72</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>styleSheetCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>styleSheetLineEdit</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>462</x>
|
||||||
|
<y>104</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>196</x>
|
||||||
|
<y>105</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>styleSheetCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>styleSheetPushButton</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>462</x>
|
||||||
|
<y>104</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>368</x>
|
||||||
|
<y>105</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>paletteCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>paletteToolButton</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>462</x>
|
||||||
|
<y>137</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>99</x>
|
||||||
|
<y>138</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Dialogs::QtLanguageOptionPage</class>
|
||||||
|
<widget class="QWidget" name="Dialogs::QtLanguageOptionPage">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Localization</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QGroupBox { font-weight: bold };</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="localeLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Locale</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="localeComboBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2" alignment="Qt::AlignHCenter">
|
||||||
|
<widget class="QCheckBox" name="localeCheckBox">
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="defaultLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use system default</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>localeCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>localeComboBox</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>159</x>
|
||||||
|
<y>39</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>75</x>
|
||||||
|
<y>39</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -0,0 +1,145 @@
|
||||||
|
#include "./qtsettings.h"
|
||||||
|
|
||||||
|
#include "./optioncategorymodel.h"
|
||||||
|
#include "./optioncategoryfiltermodel.h"
|
||||||
|
#include "./optioncategory.h"
|
||||||
|
#include "./optionpage.h"
|
||||||
|
|
||||||
|
#include "../paletteeditor/paletteeditor.h"
|
||||||
|
|
||||||
|
#include "ui_qtappearanceoptionpage.h"
|
||||||
|
#include "ui_qtlanguageoptionpage.h"
|
||||||
|
|
||||||
|
#include <QStyleFactory>
|
||||||
|
#include <QFontDialog>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace Dialogs {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns a new OptionCatecory containing all Qt related
|
||||||
|
* option pages.
|
||||||
|
*/
|
||||||
|
OptionCategory *qtOptionCategory(QObject *parent)
|
||||||
|
{
|
||||||
|
auto *category = new OptionCategory(parent);
|
||||||
|
category->setDisplayName(QCoreApplication::translate("QtGui::QtOptionCategory", "Qt"));
|
||||||
|
category->setIcon(QIcon::fromTheme(QStringLiteral("qtcreator")));
|
||||||
|
category->assignPages(QList<OptionPage *>()
|
||||||
|
<< new QtAppearanceOptionPage
|
||||||
|
<< new QtLanguageOptionPage);
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtAppearanceOptionPage::QtAppearanceOptionPage(QWidget *parentWidget) :
|
||||||
|
QtAppearanceOptionPageBase(parentWidget),
|
||||||
|
m_fontDialog(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QtAppearanceOptionPage::~QtAppearanceOptionPage()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool QtAppearanceOptionPage::apply()
|
||||||
|
{
|
||||||
|
if(hasBeenShown()) {
|
||||||
|
// read style sheet
|
||||||
|
QString styleSheet;
|
||||||
|
if(!ui()->styleSheetLineEdit->text().isEmpty()) {
|
||||||
|
QFile file(ui()->styleSheetLineEdit->text());
|
||||||
|
if(!file.open(QFile::ReadOnly)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
styleSheet.append(file.readAll());
|
||||||
|
if(file.error() != QFile::NoError) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply config
|
||||||
|
const QFont font = ui()->fontComboBox->font();
|
||||||
|
const QPalette palette = ui()->paletteToolButton->palette();
|
||||||
|
QGuiApplication::setFont(font);
|
||||||
|
QGuiApplication::setPalette(palette);
|
||||||
|
if(auto *qapp = qobject_cast<QApplication *>(QApplication::instance())) {
|
||||||
|
qapp->setStyleSheet(styleSheet);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QApplication::setStyle(ui()->widgetStyleComboBox->currentText());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtAppearanceOptionPage::reset()
|
||||||
|
{
|
||||||
|
if(hasBeenShown()) {
|
||||||
|
ui()->widgetStyleComboBox->setCurrentText(QApplication::style() ? QApplication::style()->objectName() : QString());
|
||||||
|
ui()->styleSheetLineEdit->setText(QString() /* TODO */);
|
||||||
|
ui()->fontComboBox->setCurrentFont(QGuiApplication::font());
|
||||||
|
ui()->fontPushButton->setPalette(QGuiApplication::palette());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *QtAppearanceOptionPage::setupWidget()
|
||||||
|
{
|
||||||
|
// call base implementation first, so ui() is available
|
||||||
|
auto *widget = QtAppearanceOptionPageBase::setupWidget();
|
||||||
|
|
||||||
|
// setup widget style selection
|
||||||
|
ui()->widgetStyleComboBox->addItems(QStyleFactory::keys());
|
||||||
|
|
||||||
|
// setup style sheet selection
|
||||||
|
QObject::connect(ui()->styleSheetPushButton, &QPushButton::clicked, [this] {
|
||||||
|
QString styleSheetPath = QFileDialog::getOpenFileName(this->widget());
|
||||||
|
if(!styleSheetPath.isEmpty()) {
|
||||||
|
ui()->styleSheetLineEdit->setText(styleSheetPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// setup font selection
|
||||||
|
QObject::connect(ui()->fontPushButton, &QPushButton::clicked, [this] {
|
||||||
|
if(!m_fontDialog) {
|
||||||
|
m_fontDialog = new QFontDialog(this->widget());
|
||||||
|
m_fontDialog->setCurrentFont(ui()->fontComboBox->font());
|
||||||
|
QObject::connect(m_fontDialog, &QFontDialog::fontSelected, ui()->fontComboBox, &QFontComboBox::setCurrentFont);
|
||||||
|
QObject::connect(ui()->fontComboBox, &QFontComboBox::currentFontChanged, m_fontDialog, &QFontDialog::setCurrentFont);
|
||||||
|
}
|
||||||
|
m_fontDialog->show();
|
||||||
|
});
|
||||||
|
|
||||||
|
// setup palette selection
|
||||||
|
QObject::connect(ui()->paletteToolButton, &QToolButton::clicked, [this] {
|
||||||
|
ui()->paletteToolButton->setPalette(PaletteEditor::getPalette(this->widget(), ui()->paletteToolButton->palette()));
|
||||||
|
});
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtLanguageOptionPage::QtLanguageOptionPage(QWidget *parentWidget) :
|
||||||
|
QtLanguageOptionPageBase(parentWidget)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QtLanguageOptionPage::~QtLanguageOptionPage()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool QtLanguageOptionPage::apply()
|
||||||
|
{
|
||||||
|
if(hasBeenShown()) {
|
||||||
|
QLocale::setDefault(ui()->localeComboBox->currentText());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtLanguageOptionPage::reset()
|
||||||
|
{
|
||||||
|
if(hasBeenShown()) {
|
||||||
|
ui()->localeComboBox->setCurrentText(QLocale().name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
// The functions and classes declared in this header are experimental.
|
||||||
|
// API/ABI might change in minor release!
|
||||||
|
|
||||||
|
#ifndef QT_UTILITIES_QTSETTINGS_H
|
||||||
|
#define QT_UTILITIES_QTSETTINGS_H
|
||||||
|
|
||||||
|
#include "./optionpage.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QFontDialog)
|
||||||
|
|
||||||
|
namespace Dialogs {
|
||||||
|
|
||||||
|
class OptionCategory;
|
||||||
|
|
||||||
|
OptionCategory LIB_EXPORT *qtOptionCategory(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE(QtAppearanceOptionPage)
|
||||||
|
DECLARE_SETUP_WIDGETS
|
||||||
|
QFontDialog *m_fontDialog;
|
||||||
|
END_DECLARE_OPTION_PAGE
|
||||||
|
|
||||||
|
DECLARE_UI_FILE_BASED_OPTION_PAGE(QtLanguageOptionPage)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QT_UTILITIES_QTSETTINGS_H
|
|
@ -12,6 +12,8 @@
|
||||||
#include <QItemSelectionModel>
|
#include <QItemSelectionModel>
|
||||||
#include <QShowEvent>
|
#include <QShowEvent>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
namespace Dialogs {
|
namespace Dialogs {
|
||||||
|
|
||||||
|
@ -30,7 +32,8 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
|
||||||
m_categoryModel(new OptionCategoryModel(this)),
|
m_categoryModel(new OptionCategoryModel(this)),
|
||||||
m_categoryFilterModel(new OptionCategoryFilterModel(this)),
|
m_categoryFilterModel(new OptionCategoryFilterModel(this)),
|
||||||
m_currentCategory(nullptr),
|
m_currentCategory(nullptr),
|
||||||
m_tabBarAlwaysVisible(true)
|
m_tabBarAlwaysVisible(true),
|
||||||
|
m_categoriesAlwaysVisible(true)
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
makeHeading(m_ui->headingLabel);
|
makeHeading(m_ui->headingLabel);
|
||||||
|
@ -61,7 +64,6 @@ SettingsDialog::~SettingsDialog()
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets whether the tab bar is always visible.
|
* \brief Sets whether the tab bar is always visible.
|
||||||
*
|
|
||||||
* \sa SettingsDialog::isTabBarAlwaysVisible()
|
* \sa SettingsDialog::isTabBarAlwaysVisible()
|
||||||
*/
|
*/
|
||||||
void SettingsDialog::setTabBarAlwaysVisible(bool value)
|
void SettingsDialog::setTabBarAlwaysVisible(bool value)
|
||||||
|
@ -72,6 +74,21 @@ void SettingsDialog::setTabBarAlwaysVisible(bool value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets whether the category selection is always visible.
|
||||||
|
* \sa SettingsDialog::areCategoriesAlwaysVisible()
|
||||||
|
*/
|
||||||
|
void SettingsDialog::setCategoriesAlwaysVisible(bool value)
|
||||||
|
{
|
||||||
|
m_categoriesAlwaysVisible = value;
|
||||||
|
bool visible = value || m_categoryModel->rowCount();
|
||||||
|
m_ui->filterLineEdit->setVisible(visible);
|
||||||
|
m_ui->categoriesListView->setVisible(visible);
|
||||||
|
if(!visible) {
|
||||||
|
m_ui->filterLineEdit->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the category for the specified \a categoryIndex.
|
* \brief Returns the category for the specified \a categoryIndex.
|
||||||
*
|
*
|
||||||
|
@ -155,14 +172,14 @@ void SettingsDialog::updateTabWidget()
|
||||||
if(index < m_ui->pagesTabWidget->count()) {
|
if(index < m_ui->pagesTabWidget->count()) {
|
||||||
scrollArea = qobject_cast<QScrollArea *>(m_ui->pagesTabWidget->widget(index));
|
scrollArea = qobject_cast<QScrollArea *>(m_ui->pagesTabWidget->widget(index));
|
||||||
scrollArea->takeWidget();
|
scrollArea->takeWidget();
|
||||||
m_ui->pagesTabWidget->setTabText(index, page->displayName());
|
m_ui->pagesTabWidget->setTabText(index, page->widget()->windowTitle());
|
||||||
} else {
|
} else {
|
||||||
scrollArea = new QScrollArea(m_ui->pagesTabWidget);
|
scrollArea = new QScrollArea(m_ui->pagesTabWidget);
|
||||||
scrollArea->setFrameStyle(QFrame::NoFrame);
|
scrollArea->setFrameStyle(QFrame::NoFrame);
|
||||||
scrollArea->setBackgroundRole(QPalette::Base);
|
scrollArea->setBackgroundRole(QPalette::Base);
|
||||||
scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
scrollArea->setWidgetResizable(true);
|
scrollArea->setWidgetResizable(true);
|
||||||
m_ui->pagesTabWidget->addTab(scrollArea, page->displayName());
|
m_ui->pagesTabWidget->addTab(scrollArea, page->widget()->windowTitle());
|
||||||
}
|
}
|
||||||
if(page->widget()->layout()) {
|
if(page->widget()->layout()) {
|
||||||
page->widget()->layout()->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
page->widget()->layout()->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||||
|
@ -189,15 +206,41 @@ void SettingsDialog::updateTabWidget()
|
||||||
*/
|
*/
|
||||||
bool SettingsDialog::apply()
|
bool SettingsDialog::apply()
|
||||||
{
|
{
|
||||||
|
QString errorMessage;
|
||||||
for(OptionCategory *category : m_categoryModel->categories()) {
|
for(OptionCategory *category : m_categoryModel->categories()) {
|
||||||
for(OptionPage *page : category->pages()) {
|
for(OptionPage *page : category->pages()) {
|
||||||
if(!page->apply()) {
|
if(!page->apply()) {
|
||||||
return false;
|
if(errorMessage.isEmpty()) {
|
||||||
|
errorMessage = tr("<p><b>Errors occured when applying changes.</b></p><ul>");
|
||||||
|
}
|
||||||
|
if(const_cast<const OptionPage *>(page)->errors().isEmpty()) {
|
||||||
|
errorMessage.append(QStringLiteral("<li><i>")
|
||||||
|
% category->displayName()
|
||||||
|
% QLatin1Char('/')
|
||||||
|
% page->widget()->windowTitle()
|
||||||
|
% QStringLiteral("</i>: ")
|
||||||
|
% tr("unknonw error")
|
||||||
|
% QStringLiteral("</li>"));
|
||||||
|
} else {
|
||||||
|
for(const QString &error : const_cast<const OptionPage *>(page)->errors()) {
|
||||||
|
errorMessage.append(QStringLiteral("<li><i>")
|
||||||
|
% category->displayName()
|
||||||
|
% QLatin1Char('/')
|
||||||
|
% page->widget()->windowTitle()
|
||||||
|
% QStringLiteral("</i>: ")
|
||||||
|
% error
|
||||||
|
% QStringLiteral("</li>"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!errorMessage.isEmpty()) {
|
||||||
|
errorMessage.append(QStringLiteral("</ul>"));
|
||||||
|
QMessageBox::warning(this, windowTitle(), errorMessage);
|
||||||
|
}
|
||||||
emit applied();
|
emit applied();
|
||||||
return true;
|
return errorMessage.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -21,13 +21,16 @@ class SettingsDialog;
|
||||||
class LIB_EXPORT SettingsDialog : public QDialog
|
class LIB_EXPORT SettingsDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool isTabBarAlwaysVisible READ isTabBarAlwaysVisible WRITE setTabBarAlwaysVisible)
|
Q_PROPERTY(bool tabBarAlwaysVisible READ isTabBarAlwaysVisible WRITE setTabBarAlwaysVisible)
|
||||||
|
Q_PROPERTY(bool categoriesAlwaysVisible READ areCategoriesAlwaysVisible WRITE setCategoriesAlwaysVisible)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SettingsDialog(QWidget *parent = nullptr);
|
explicit SettingsDialog(QWidget *parent = nullptr);
|
||||||
virtual ~SettingsDialog();
|
~SettingsDialog();
|
||||||
bool isTabBarAlwaysVisible() const;
|
bool isTabBarAlwaysVisible() const;
|
||||||
void setTabBarAlwaysVisible(bool value);
|
void setTabBarAlwaysVisible(bool value);
|
||||||
|
bool areCategoriesAlwaysVisible() const;
|
||||||
|
void setCategoriesAlwaysVisible(bool value);
|
||||||
OptionCategoryModel *categoryModel();
|
OptionCategoryModel *categoryModel();
|
||||||
OptionCategory *category(int categoryIndex) const;
|
OptionCategory *category(int categoryIndex) const;
|
||||||
OptionPage *page(int categoryIndex, int pageIndex) const;
|
OptionPage *page(int categoryIndex, int pageIndex) const;
|
||||||
|
@ -54,6 +57,7 @@ private:
|
||||||
OptionCategoryFilterModel *m_categoryFilterModel;
|
OptionCategoryFilterModel *m_categoryFilterModel;
|
||||||
OptionCategory *m_currentCategory;
|
OptionCategory *m_currentCategory;
|
||||||
bool m_tabBarAlwaysVisible;
|
bool m_tabBarAlwaysVisible;
|
||||||
|
bool m_categoriesAlwaysVisible;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -68,6 +72,18 @@ inline bool SettingsDialog::isTabBarAlwaysVisible() const
|
||||||
return m_tabBarAlwaysVisible;
|
return m_tabBarAlwaysVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns whether the category selection is always visible.
|
||||||
|
*
|
||||||
|
* The category selection is always visible by default.
|
||||||
|
*
|
||||||
|
* \sa SettingsDialog::setCategoriesAlwaysVisible()
|
||||||
|
*/
|
||||||
|
inline bool SettingsDialog::areCategoriesAlwaysVisible() const
|
||||||
|
{
|
||||||
|
return m_categoriesAlwaysVisible;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the category model used by the settings dialog to manage the categories.
|
* \brief Returns the category model used by the settings dialog to manage the categories.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue