GitHub Viewer
#include "CondFormatManager.h"
#include "ui_CondFormatManager.h"
#include "CondFormat.h"
#include "Settings.h"
#include "FilterLineEdit.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
// Styled Item Delegate for non-editable columns (all except Condition)
class DefaultDelegate: public QStyledItemDelegate {
public:
explicit DefaultDelegate(QObject* parent=nullptr): QStyledItemDelegate(parent) {}
QWidget* createEditor(QWidget* /* parent */, const QStyleOptionViewItem& /* option */, const QModelIndex& /* index */) const override {
return nullptr;
}
};
// Styled Item Delegate for the Condition column as a filter line editor.
class FilterEditDelegate: public QStyledItemDelegate {
public:
explicit FilterEditDelegate(QObject* parent=nullptr): QStyledItemDelegate(parent) {}
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& /* option */, const QModelIndex& /* index */) const override {
FilterLineEdit* filterEditor = new FilterLineEdit(parent);
filterEditor->setConditionFormatContextMenuEnabled(false);
return filterEditor;
}
};
CondFormatManager::CondFormatManager(const std::vector& condFormats, const QString& encoding, QWidget *parent) :
QDialog(parent),
ui(new Ui::CondFormatManager),
m_condFormats(condFormats),
m_encoding(encoding)
{
ui->setupUi(this);
for(const CondFormat& aCondFormat : condFormats)
addItem(aCondFormat);
// Make condition editable as a filter line editor.
ui->tableCondFormats->setEditTriggers(QAbstractItemView::AllEditTriggers);
ui->tableCondFormats->setItemDelegateForColumn(ColumnFilter, new FilterEditDelegate(this));
// Make columns not text-editable, except for the condition.
for(int col = ColumnForeground; col < ColumnFilter; ++col) {
ui->tableCondFormats->setItemDelegateForColumn(col, new DefaultDelegate(this));
ui->tableCondFormats->resizeColumnToContents(col);
}
connect(ui->buttonAdd, &QToolButton::clicked, this, &CondFormatManager::addNewItem);
connect(ui->buttonRemove, &QToolButton::clicked, this, &CondFormatManager::removeItem);
connect(ui->buttonDown, &QToolButton::clicked, this, &CondFormatManager::downItem);
connect(ui->buttonUp, &QToolButton::clicked, this, &CondFormatManager::upItem);
connect(ui->tableCondFormats, &QTreeWidget::itemClicked, this, &CondFormatManager::itemClicked);
}
CondFormatManager::~CondFormatManager()
{
delete ui;
}
void CondFormatManager::addNewItem()
{
// Clear focus from the current widget, so if there is some input, it is saved now.
QWidget* currentWidget = ui->tableCondFormats->itemWidget(ui->tableCondFormats->currentItem(), ColumnFilter);
if (currentWidget != nullptr)
currentWidget->clearFocus();
QFont font = QFont(Settings::getValue("databrowser", "font").toString());
font.setPointSize(Settings::getValue("databrowser", "fontsize").toInt());
CondFormat newCondFormat("", QColor(Settings::getValue("databrowser", "reg_fg_colour").toString()),
m_condFormatPalette.nextSerialColor(Palette::appHasDarkTheme()),
font,
CondFormat::AlignLeft,
m_encoding);
addItem(newCondFormat);
}
void CondFormatManager::addItem(const CondFormat& aCondFormat)
{
int i = ui->tableCondFormats->topLevelItemCount();
QTreeWidgetItem *newItem = new QTreeWidgetItem(ui->tableCondFormats);
newItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable);
newItem->setForeground(ColumnForeground, aCondFormat.foregroundColor());
newItem->setBackground(ColumnForeground, aCondFormat.foregroundColor());
newItem->setForeground(ColumnBackground, aCondFormat.backgroundColor());
newItem->setBackground(ColumnBackground, aCondFormat.backgroundColor());
newItem->setToolTip(ColumnBackground, tr("Click to select color"));
newItem->setToolTip(ColumnForeground, tr("Click to select color"));
QFontComboBox* fontCombo = new QFontComboBox(ui->tableCondFormats);
fontCombo->setCurrentFont(aCondFormat.font());
// Avoid that the font combo box gets too wide and work around a possible Qt bug where the box overlaps the next column.
fontCombo->setMaximumWidth(150);
ui->tableCondFormats->setItemWidget(newItem, ColumnFont, fontCombo);
QSpinBox* sizeBox = new QSpinBox(ui->tableCondFormats);
sizeBox->setMinimum(1);
sizeBox->setValue(aCondFormat.font().pointSize());
ui->tableCondFormats->setItemWidget(newItem, ColumnSize, sizeBox);
newItem->setCheckState(ColumnBold, aCondFormat.isBold() ? Qt::Checked : Qt::Unchecked);
newItem->setCheckState(ColumnItalic, aCondFormat.isItalic() ? Qt::Checked : Qt::Unchecked);
newItem->setCheckState(ColumnUnderline, aCondFormat.isUnderline() ? Qt::Checked : Qt::Unchecked);
QComboBox* alignCombo = new QComboBox(ui->tableCondFormats);
alignCombo->addItems(CondFormat::alignmentTexts());
alignCombo->setCurrentIndex(aCondFormat.alignment());
ui->tableCondFormats->setItemWidget(newItem, ColumnAlignment, alignCombo);
newItem->setText(ColumnFilter, aCondFormat.filter());
ui->tableCondFormats->insertTopLevelItem(i, newItem);
for(int col = ColumnForeground; col < ColumnFilter; ++col) {
ui->tableCondFormats->resizeColumnToContents(col);
}
}
void CondFormatManager::removeItem()
{
QTreeWidgetItem* item = ui->tableCondFormats->takeTopLevelItem(ui->tableCondFormats->currentIndex().row());
delete item;
}
void CondFormatManager::moveItem(int offset)
{
if (!ui->tableCondFormats->currentIndex().isValid())
return;
int selectedRow = ui->tableCondFormats->currentIndex().row();
int newRow = selectedRow + offset;
if(newRow < 0 || newRow >= ui->tableCondFormats->topLevelItemCount())
return;
QTreeWidgetItem* item = ui->tableCondFormats->topLevelItem(selectedRow);
// Rescue widgets, since they will be deleted, and add them later.
QFontComboBox* fontCombo = qobject_cast(ui->tableCondFormats->itemWidget(item, ColumnFont));
QFontComboBox* fontCombo2 = new QFontComboBox(ui->tableCondFormats);
fontCombo2->setCurrentFont(fontCombo->currentFont());
QSpinBox* sizeBox = qobject_cast(ui->tableCondFormats->itemWidget(item, ColumnSize));
QSpinBox* sizeBox2 = new QSpinBox(ui->tableCondFormats);
sizeBox2->setValue(sizeBox->value());
sizeBox2->setMinimum(sizeBox->minimum());
QComboBox* alignCombo = qobject_cast(ui->tableCondFormats->itemWidget(item, ColumnAlignment));
QComboBox* alignCombo2 = new QComboBox(ui->tableCondFormats);
alignCombo2->addItems(CondFormat::alignmentTexts());
alignCombo2->setCurrentIndex(alignCombo->currentIndex());
item = ui->tableCondFormats->takeTopLevelItem(selectedRow);
ui->tableCondFormats->insertTopLevelItem(newRow, item);
// Restore widgets and state
ui->tableCondFormats->setItemWidget(item, ColumnFont, fontCombo2);
ui->tableCondFormats->setItemWidget(item, ColumnSize, sizeBox2);
ui->tableCondFormats->setItemWidget(item, ColumnAlignment, alignCombo2);
ui->tableCondFormats->setCurrentIndex(ui->tableCondFormats->currentIndex().sibling(newRow,
ui->tableCondFormats->currentIndex().column()));
// This is added so the widgets are readjusted. Otherwise they can be misplaced when moving an item to the top.
ui->tableCondFormats->adjustSize();
}
void CondFormatManager::upItem()
{
moveItem(-1);
}
void CondFormatManager::downItem()
{
moveItem(+1);
}
std::vector CondFormatManager::getCondFormats() const
{
std::vector result;
for (int i = 0; i < ui->tableCondFormats->topLevelItemCount(); ++i)
{
QTreeWidgetItem* item = ui->tableCondFormats->topLevelItem(i);
QFontComboBox* fontCombo = qobject_cast(ui->tableCondFormats->itemWidget(item, ColumnFont));
QSpinBox* sizeBox = qobject_cast(ui->tableCondFormats->itemWidget(item, ColumnSize));
QFont font = fontCombo->currentFont();
font.setPointSize(sizeBox->value());
font.setBold(item->checkState(ColumnBold) == Qt::Checked);
font.setItalic(item->checkState(ColumnItalic) == Qt::Checked);
font.setUnderline(item->checkState(ColumnUnderline) == Qt::Checked);
QComboBox* alignCombo = qobject_cast(ui->tableCondFormats->itemWidget(item, ColumnAlignment));
result.emplace_back(item->text(ColumnFilter),
item->background(ColumnForeground).color(),
item->background(ColumnBackground).color(),
font,
static_cast(alignCombo->currentIndex()),
m_encoding);
}
return result;
}
void CondFormatManager::itemClicked(QTreeWidgetItem* item, int column)
{
switch (column) {
case ColumnForeground:
case ColumnBackground: {
QColor color = QColorDialog::getColor(item->background(column).color(), this);
if(color.isValid()) {
item->setForeground(column, color);
item->setBackground(column, color);
}
break;
}
case ColumnBold:
case ColumnItalic:
case ColumnUnderline:
item->setCheckState(column, item->checkState(column) != Qt::Checked ? Qt::Checked : Qt::Unchecked);
break;
default:
// Nothing to do
break;
}
}
void CondFormatManager::buttonBoxClicked(QAbstractButton* button)
{
if (button == ui->buttonBox->button(QDialogButtonBox::Cancel))
reject();
else if (button == ui->buttonBox->button(QDialogButtonBox::Ok))
accept();
else if (button == ui->buttonBox->button(QDialogButtonBox::Help))
QDesktopServices::openUrl(QUrl("https://github.com/sqlitebrowser/sqlitebrowser/wiki/Conditional-Formats"));
else if (button == ui->buttonBox->button(QDialogButtonBox::Reset)) {
if (QMessageBox::warning(this,
QApplication::applicationName(),
tr("Are you sure you want to clear all the conditional formats of this field?"),
QMessageBox::Reset | QMessageBox::Cancel,
QMessageBox::Cancel) == QMessageBox::Reset)
if(ui->tableCondFormats->model()->hasChildren())
ui->tableCondFormats->model()->removeRows(0, ui->tableCondFormats->model()->rowCount());
}
}