improved settings dialog API
This commit is contained in:
parent
4cca128180
commit
87fd94a2e0
|
@ -18,12 +18,15 @@ set(HEADER_FILES
|
|||
settingsdialog/optioncategorymodel.h
|
||||
settingsdialog/optionpage.h
|
||||
settingsdialog/settingsdialog.h
|
||||
settingsdialog/qtsettings.h
|
||||
widgets/buttonoverlay.h
|
||||
widgets/clearcombobox.h
|
||||
widgets/clearlineedit.h
|
||||
widgets/clearplaintextedit.h
|
||||
widgets/clearspinbox.h
|
||||
widgets/iconbutton.h
|
||||
paletteeditor/paletteeditor.h
|
||||
paletteeditor/colorbutton.h
|
||||
)
|
||||
set(SRC_FILES
|
||||
aboutdialog/aboutdialog.cpp
|
||||
|
@ -38,18 +41,24 @@ set(SRC_FILES
|
|||
settingsdialog/optioncategorymodel.cpp
|
||||
settingsdialog/optionpage.cpp
|
||||
settingsdialog/settingsdialog.cpp
|
||||
settingsdialog/qtsettings.cpp
|
||||
widgets/buttonoverlay.cpp
|
||||
widgets/clearcombobox.cpp
|
||||
widgets/clearlineedit.cpp
|
||||
widgets/clearplaintextedit.cpp
|
||||
widgets/clearspinbox.cpp
|
||||
widgets/iconbutton.cpp
|
||||
paletteeditor/paletteeditor.cpp
|
||||
paletteeditor/colorbutton.cpp
|
||||
resources/qtutilsicons.qrc
|
||||
)
|
||||
set(WIDGETS_UI_FILES
|
||||
aboutdialog/aboutdialog.ui
|
||||
enterpassworddialog/enterpassworddialog.ui
|
||||
settingsdialog/settingsdialog.ui
|
||||
settingsdialog/qtappearanceoptionpage.ui
|
||||
settingsdialog/qtlanguageoptionpage.ui
|
||||
paletteeditor/paletteeditor.ui
|
||||
)
|
||||
|
||||
# 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()) {
|
||||
return true;
|
||||
}
|
||||
if(displayName().contains(searchKeyWord, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
if(!m_keywordsInitialized) {
|
||||
if(!m_widget) {
|
||||
m_widget.reset(setupWidget()); // ensure widget has been created
|
||||
}
|
||||
m_keywords << m_widget->windowTitle();
|
||||
// find common subwidgets
|
||||
for(const QLabel *label : m_widget->findChildren<QLabel *>())
|
||||
m_keywords << label->text();
|
||||
|
@ -81,7 +79,7 @@ bool OptionPage::matches(const QString &searchKeyWord)
|
|||
m_keywordsInitialized = true;
|
||||
}
|
||||
for(const QString &keyword : m_keywords)
|
||||
if (keyword.contains(searchKeyWord, Qt::CaseInsensitive))
|
||||
if(keyword.contains(searchKeyWord, Qt::CaseInsensitive))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -17,15 +17,16 @@ public:
|
|||
virtual ~OptionPage();
|
||||
|
||||
QWidget *parentWindow() const;
|
||||
virtual QString displayName() const = 0;
|
||||
QWidget *widget();
|
||||
bool hasBeenShown() const;
|
||||
virtual bool apply() = 0;
|
||||
virtual void reset() = 0;
|
||||
bool matches(const QString &searchKeyWord);
|
||||
const QStringList &errors() const;
|
||||
|
||||
protected:
|
||||
virtual QWidget *setupWidget() = 0;
|
||||
QStringList &errors();
|
||||
|
||||
private:
|
||||
std::unique_ptr<QWidget> m_widget;
|
||||
|
@ -33,6 +34,7 @@ private:
|
|||
bool m_shown;
|
||||
bool m_keywordsInitialized;
|
||||
QStringList m_keywords;
|
||||
QStringList m_errors;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -51,6 +53,25 @@ inline bool OptionPage::hasBeenShown() const
|
|||
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
|
||||
* \brief The UiFileBasedOptionPage class is the base class for SettingsDialog pages using UI files
|
||||
|
@ -65,7 +86,6 @@ public:
|
|||
explicit UiFileBasedOptionPage(QWidget *parentWindow = nullptr);
|
||||
virtual ~UiFileBasedOptionPage();
|
||||
|
||||
virtual QString displayName() const = 0;
|
||||
virtual bool apply() = 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
|
||||
|
|
|
@ -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 <QShowEvent>
|
||||
#include <QScrollArea>
|
||||
#include <QStringBuilder>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace Dialogs {
|
||||
|
||||
|
@ -30,7 +32,8 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
|
|||
m_categoryModel(new OptionCategoryModel(this)),
|
||||
m_categoryFilterModel(new OptionCategoryFilterModel(this)),
|
||||
m_currentCategory(nullptr),
|
||||
m_tabBarAlwaysVisible(true)
|
||||
m_tabBarAlwaysVisible(true),
|
||||
m_categoriesAlwaysVisible(true)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
makeHeading(m_ui->headingLabel);
|
||||
|
@ -61,7 +64,6 @@ SettingsDialog::~SettingsDialog()
|
|||
|
||||
/*!
|
||||
* \brief Sets whether the tab bar is always visible.
|
||||
*
|
||||
* \sa SettingsDialog::isTabBarAlwaysVisible()
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -155,14 +172,14 @@ void SettingsDialog::updateTabWidget()
|
|||
if(index < m_ui->pagesTabWidget->count()) {
|
||||
scrollArea = qobject_cast<QScrollArea *>(m_ui->pagesTabWidget->widget(index));
|
||||
scrollArea->takeWidget();
|
||||
m_ui->pagesTabWidget->setTabText(index, page->displayName());
|
||||
m_ui->pagesTabWidget->setTabText(index, page->widget()->windowTitle());
|
||||
} else {
|
||||
scrollArea = new QScrollArea(m_ui->pagesTabWidget);
|
||||
scrollArea->setFrameStyle(QFrame::NoFrame);
|
||||
scrollArea->setBackgroundRole(QPalette::Base);
|
||||
scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
m_ui->pagesTabWidget->addTab(scrollArea, page->displayName());
|
||||
m_ui->pagesTabWidget->addTab(scrollArea, page->widget()->windowTitle());
|
||||
}
|
||||
if(page->widget()->layout()) {
|
||||
page->widget()->layout()->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
|
@ -189,15 +206,41 @@ void SettingsDialog::updateTabWidget()
|
|||
*/
|
||||
bool SettingsDialog::apply()
|
||||
{
|
||||
QString errorMessage;
|
||||
for(OptionCategory *category : m_categoryModel->categories()) {
|
||||
for(OptionPage *page : category->pages()) {
|
||||
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();
|
||||
return true;
|
||||
return errorMessage.isEmpty();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -21,13 +21,16 @@ class SettingsDialog;
|
|||
class LIB_EXPORT SettingsDialog : public QDialog
|
||||
{
|
||||
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:
|
||||
explicit SettingsDialog(QWidget *parent = nullptr);
|
||||
virtual ~SettingsDialog();
|
||||
~SettingsDialog();
|
||||
bool isTabBarAlwaysVisible() const;
|
||||
void setTabBarAlwaysVisible(bool value);
|
||||
bool areCategoriesAlwaysVisible() const;
|
||||
void setCategoriesAlwaysVisible(bool value);
|
||||
OptionCategoryModel *categoryModel();
|
||||
OptionCategory *category(int categoryIndex) const;
|
||||
OptionPage *page(int categoryIndex, int pageIndex) const;
|
||||
|
@ -54,6 +57,7 @@ private:
|
|||
OptionCategoryFilterModel *m_categoryFilterModel;
|
||||
OptionCategory *m_currentCategory;
|
||||
bool m_tabBarAlwaysVisible;
|
||||
bool m_categoriesAlwaysVisible;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -68,6 +72,18 @@ inline bool SettingsDialog::isTabBarAlwaysVisible() const
|
|||
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.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue