Dialog and foreground configuration for conditional formats

A new dialog for editing conditional formats that can be invoked from the
filter line editor or from the data browser contextual menus. The dialog
allows adding and removing conditional formats, changing the priority order
and editing foreground colour, background colour and filter condition.

The conditional formats have been expanded to allow defining the foreground
colour. By default is the setting configured by user.

This is a continuation of the functionality introduced in PR #1503.
This commit is contained in:
mgrojo
2019-03-23 22:14:18 +01:00
parent 2d35206313
commit 217563fd47
21 changed files with 466 additions and 34 deletions

View File

@@ -2,11 +2,13 @@
#include "Settings.h"
#include "Data.h"
CondFormat::CondFormat(const QString& filter, const QColor& color, const QString& encoding)
CondFormat::CondFormat(const QString& filter, const QColor& foreground, const QColor& background, const QString& encoding)
: m_filter(filter),
m_color(color)
m_fgColor(foreground),
m_bgColor(background)
{
m_sqlCondition = filterToSqlCondition(filter, encoding);
if (!filter.isEmpty())
m_sqlCondition = filterToSqlCondition(filter, encoding);
}
QString CondFormat::filterToSqlCondition(const QString& value, const QString& encoding)

View File

@@ -9,19 +9,21 @@ class CondFormat
{
public:
CondFormat() {};
explicit CondFormat(const QString& filter, const QColor& color, const QString& encoding = QString());
explicit CondFormat(const QString& filter, const QColor& foreground, const QColor& background, const QString& encoding = QString());
static QString filterToSqlCondition(const QString& value, const QString& encoding = QString());
private:
QString m_sqlCondition;
QString m_filter;
QColor m_color;
QColor m_bgColor;
QColor m_fgColor;
public:
QString sqlCondition() const { return m_sqlCondition; };
QString filter() const { return m_filter; };
QColor color() const { return m_color; };
QColor backgroundColor() const { return m_bgColor; };
QColor foregroundColor() const { return m_fgColor; };
};

124
src/CondFormatManager.cpp Normal file
View File

@@ -0,0 +1,124 @@
#include "CondFormatManager.h"
#include "ui_CondFormatManager.h"
#include "CondFormat.h"
#include "Settings.h"
#include "QColorDialog"
CondFormatManager::CondFormatManager(const QVector<CondFormat>& 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);
ui->tableCondFormats->setEditTriggers(QAbstractItemView::AllEditTriggers);
connect(ui->buttonAdd, SIGNAL(clicked(bool)), this, SLOT(addNewItem()));
connect(ui->buttonRemove, SIGNAL(clicked(bool)), this, SLOT(removeItem()));
connect(ui->buttonDown, SIGNAL(clicked(bool)), this, SLOT(downItem()));
connect(ui->buttonUp, SIGNAL(clicked(bool)), this, SLOT(upItem()));
connect(ui->tableCondFormats, &QTreeWidget::itemDoubleClicked, this, &CondFormatManager::itemDoubleClicked);
}
CondFormatManager::~CondFormatManager()
{
delete ui;
}
void CondFormatManager::addNewItem()
{
CondFormat newCondFormat("", QColor(Settings::getValue("databrowser", "reg_fg_colour").toString()),
m_condFormatPalette.nextSerialColor(Palette::appHasDarkTheme()),
m_encoding);
addItem(newCondFormat);
}
void CondFormatManager::addItem(const CondFormat& aCondFormat)
{
int i = ui->tableCondFormats->topLevelItemCount();
QTreeWidgetItem *newItem = new QTreeWidgetItem({aCondFormat.foregroundColor().name(),
aCondFormat.backgroundColor().name(), aCondFormat.filter()});
newItem->setForeground(ColumnForeground, aCondFormat.foregroundColor());
newItem->setBackground(ColumnForeground, aCondFormat.foregroundColor());
newItem->setForeground(ColumnBackground, aCondFormat.backgroundColor());
newItem->setBackground(ColumnBackground, aCondFormat.backgroundColor());
ui->tableCondFormats->insertTopLevelItem(i, newItem);
ui->tableCondFormats->openPersistentEditor(newItem, ColumnFilter);
}
void CondFormatManager::removeItem()
{
QTreeWidgetItem* item = ui->tableCondFormats->takeTopLevelItem(ui->tableCondFormats->currentIndex().row());
delete item;
}
void CondFormatManager::upItem()
{
if (ui->tableCondFormats->selectedItems().isEmpty()) return;
int selectedRow = ui->tableCondFormats->currentIndex().row();
if(selectedRow == 0)
return;
QTreeWidgetItem* item;
item = ui->tableCondFormats->takeTopLevelItem(selectedRow);
ui->tableCondFormats->insertTopLevelItem(selectedRow-1, item);
ui->tableCondFormats->setCurrentIndex(ui->tableCondFormats->currentIndex().sibling(selectedRow-1,
ui->tableCondFormats->currentIndex().column()));
}
void CondFormatManager::downItem()
{
if (ui->tableCondFormats->selectedItems().isEmpty()) return;
int selectedRow = ui->tableCondFormats->currentIndex().row();
if(selectedRow == ui->tableCondFormats->topLevelItemCount() - 1)
return;
QTreeWidgetItem* item;
item = ui->tableCondFormats->takeTopLevelItem(selectedRow);
ui->tableCondFormats->insertTopLevelItem(selectedRow+1, item);
ui->tableCondFormats->setCurrentIndex(ui->tableCondFormats->currentIndex().sibling(selectedRow+1,
ui->tableCondFormats->currentIndex().column()));
}
QVector<CondFormat> CondFormatManager::getCondFormats()
{
QVector<CondFormat> result;
for (int i = 0; i < ui->tableCondFormats->topLevelItemCount(); ++i)
{
QTreeWidgetItem* item = ui->tableCondFormats->topLevelItem(i);
CondFormat aCondFormat(item->text(ColumnFilter),
item->background(ColumnForeground).color(),
item->background(ColumnBackground).color(), m_encoding);
result.append(aCondFormat);
}
return result;
}
void CondFormatManager::itemDoubleClicked(QTreeWidgetItem* item, int column)
{
switch (column) {
case ColumnForeground:
case ColumnBackground: {
QColor color = QColorDialog::getColor(item->background(column).color(), this);
if(color.isValid()) {
item->setTextColor(column, color);
item->setBackgroundColor(column, color);
item->setText(column, color.name());
}
break;
}
case ColumnFilter:
// Nothing to do
break;
}
}

46
src/CondFormatManager.h Normal file
View File

@@ -0,0 +1,46 @@
#ifndef CONDFORMATMANAGER_H
#define CONDFORMATMANAGER_H
#include <QDialog>
#include "Palette.h"
namespace Ui {
class CondFormatManager;
}
class CondFormat;
class QTreeWidgetItem;
class CondFormatManager : public QDialog
{
Q_OBJECT
public:
explicit CondFormatManager(const QVector<CondFormat>& condFormats, const QString& encoding, QWidget *parent = nullptr);
~CondFormatManager() override;
QVector<CondFormat> getCondFormats();
private:
enum Columns {
ColumnForeground = 0,
ColumnBackground = 1,
ColumnFilter = 2
};
Ui::CondFormatManager *ui;
QVector<CondFormat> m_condFormats;
Palette m_condFormatPalette;
QString m_encoding;
private slots:
void addNewItem();
void addItem(const CondFormat& aCondFormat);
void removeItem();
void upItem();
void downItem();
public slots:
void itemDoubleClicked(QTreeWidgetItem* item, int column);
};
#endif // CONDFORMATMANAGER_H

179
src/CondFormatManager.ui Normal file
View File

@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CondFormatManager</class>
<widget class="QDialog" name="CondFormatManager">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>578</width>
<height>463</height>
</rect>
</property>
<property name="windowTitle">
<string>Conditional Format Manager</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="buttonUp">
<property name="text">
<string>&amp;Up</string>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/up</normaloff>:/icons/up</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonDown">
<property name="text">
<string>&amp;Down</string>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/down</normaloff>:/icons/down</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonAdd">
<property name="text">
<string>&amp;Add</string>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/field_add</normaloff>:/icons/field_add</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonRemove">
<property name="text">
<string>&amp;Remove</string>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/field_delete</normaloff>:/icons/field_delete</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeWidget" name="tableCondFormats">
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::AllEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="indentation">
<number>0</number>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<attribute name="headerDefaultSectionSize">
<number>150</number>
</attribute>
<column>
<property name="text">
<string>Text color</string>
</property>
</column>
<column>
<property name="text">
<string>Background color</string>
</property>
</column>
<column>
<property name="text">
<string>Condition</string>
</property>
</column>
</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>
<resources>
<include location="icons/icons.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>CondFormatManager</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>CondFormatManager</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -253,6 +253,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
QAction* lessEqualAction = new QAction(tr("Less or equal"), m_contextMenu);
QAction* inRangeAction = new QAction(tr("Between this and..."), m_contextMenu);
QAction* regexpAction = new QAction(tr("Regular expression"), m_contextMenu);
QAction* condFormatAction = new QAction(QIcon(":/icons/edit_cond_formats"), tr("Edit Conditional Formats..."), m_contextMenu);
QAction* nullAction = new QAction(QIcon(":/icons/set_to_null"), tr("Set to NULL"), m_contextMenu);
QAction* copyAction = new QAction(QIcon(":/icons/copy"), tr("Copy"), m_contextMenu);
@@ -272,6 +273,7 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
filterMenu->addAction(lessEqualAction);
filterMenu->addAction(inRangeAction);
filterMenu->addAction(regexpAction);
m_contextMenu->addAction(condFormatAction);
m_contextMenu->addSeparator();
m_contextMenu->addAction(nullAction);
@@ -309,11 +311,13 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
copyWithHeadersAction->setEnabled(enabled);
copyAsSQLAction->setEnabled(enabled);
printAction->setEnabled(enabled);
condFormatAction->setEnabled(enabled);
// Hide filter actions when there isn't any filters
bool hasFilters = m_tableHeader->hasFilters();
filterAction->setVisible(hasFilters);
filterMenu->menuAction()->setVisible(hasFilters);
condFormatAction->setVisible(hasFilters);
// Try to find out whether the current view is editable and (de)activate menu options according to that
bool editable = editTriggers() != QAbstractItemView::NoEditTriggers;
@@ -354,6 +358,9 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
connect(regexpAction, &QAction::triggered, [&]() {
useAsFilter(QString ("/"), /* binary */ false, QString ("/"));
});
connect(condFormatAction, &QAction::triggered, [&]() {
emit editCondFormats(currentIndex().column());
});
connect(nullAction, &QAction::triggered, [&]() {
for(const QModelIndex& index : selectedIndexes())

View File

@@ -68,6 +68,7 @@ signals:
void switchTable(bool next); // 'next' parameter is set to true if next table should be selected and to false if previous table should be selected
void openFileFromDropEvent(QString);
void selectedRowsToBeDeleted();
void editCondFormats(int column);
private:
void copyMimeData(const QModelIndexList& fromIndices, QMimeData* mimeData, const bool withHeaders, const bool inSQL);

View File

@@ -108,13 +108,22 @@ void FilterLineEdit::showContextMenu(const QPoint &pos)
// This has to be created here, otherwise the set of enabled options would not update accordingly.
QMenu* editContextMenu = createStandardContextMenu();
editContextMenu->addSeparator();
QString conditionalFormatLabel = text().isEmpty() ? tr("Clear All Conditional Formats") : tr("Use for Conditional Format");
QAction* conditionalFormatAction = new QAction(conditionalFormatLabel, editContextMenu);
connect(conditionalFormatAction, &QAction::triggered, [&]() {
if (text().isEmpty())
emit clearAllCondFormats();
else
emit addFilterAsCondFormat(text());
QAction* conditionalFormatAction;
if (text().isEmpty()) {
conditionalFormatAction = new QAction(QIcon(":/icons/clear_cond_formats"), tr("Clear All Conditional Formats"), editContextMenu);
connect(conditionalFormatAction, &QAction::triggered, [&]() {
emit clearAllCondFormats();
});
} else {
conditionalFormatAction = new QAction(QIcon(":/icons/cond_formats"), tr("Use for Conditional Format"), editContextMenu);
connect(conditionalFormatAction, &QAction::triggered, [&]() {
emit addFilterAsCondFormat(text());
});
}
QAction* editCondFormatsAction = new QAction(QIcon(":/icons/edit_cond_formats"), tr("Edit Conditional Formats..."), editContextMenu);
connect(editCondFormatsAction, &QAction::triggered, [&]() {
emit editCondFormats();
});
editContextMenu->addSeparator();
@@ -184,6 +193,7 @@ void FilterLineEdit::showContextMenu(const QPoint &pos)
});
editContextMenu->addAction(conditionalFormatAction);
editContextMenu->addAction(editCondFormatsAction);
filterMenu->addAction(whatsThisAction);
filterMenu->addSeparator();

View File

@@ -25,6 +25,7 @@ signals:
void delayedTextChanged(QString text);
void addFilterAsCondFormat(QString text);
void clearAllCondFormats();
void editCondFormats();
protected:
void keyReleaseEvent(QKeyEvent* event) override;

View File

@@ -38,6 +38,7 @@ void FilterTableHeader::generateFilters(int number, bool showFirst)
connect(l, SIGNAL(delayedTextChanged(QString)), this, SLOT(inputChanged(QString)));
connect(l, SIGNAL(addFilterAsCondFormat(QString)), this, SLOT(addFilterAsCondFormat(QString)));
connect(l, SIGNAL(clearAllCondFormats()), this, SLOT(clearAllCondFormats()));
connect(l, SIGNAL(editCondFormats()), this, SLOT(editCondFormats()));
filterWidgets.push_back(l);
}
@@ -102,6 +103,12 @@ void FilterTableHeader::clearAllCondFormats()
emit clearAllCondFormats(sender()->property("column").toInt());
}
void FilterTableHeader::editCondFormats()
{
// Just get the column number and the new value and send them to anybody interested in editting conditional formatting
emit editCondFormats(sender()->property("column").toInt());
}
void FilterTableHeader::clearFilters()
{
for(FilterLineEdit* filterLineEdit : filterWidgets)

View File

@@ -27,6 +27,7 @@ signals:
void filterChanged(int column, QString value);
void addCondFormat(int column, QString filter);
void clearAllCondFormats(int column);
void editCondFormats(int column);
protected:
void updateGeometries() override;
@@ -35,6 +36,7 @@ private slots:
void inputChanged(const QString& new_value);
void addFilterAsCondFormat(const QString& filter);
void clearAllCondFormats();
void editCondFormats();
private:
QList<FilterLineEdit*> filterWidgets;

View File

@@ -28,6 +28,7 @@
#include "FindReplaceDialog.h"
#include "Data.h"
#include "CondFormat.h"
#include "CondFormatManager.h"
#include "RunSql.h"
#include <chrono>
@@ -175,6 +176,8 @@ void MainWindow::init()
connect(ui->dataTable->filterHeader(), SIGNAL(filterChanged(int,QString)), this, SLOT(updateFilter(int,QString)));
connect(ui->dataTable->filterHeader(), SIGNAL(addCondFormat(int,QString)), this, SLOT(addCondFormat(int,QString)));
connect(ui->dataTable->filterHeader(), SIGNAL(clearAllCondFormats(int)), this, SLOT(clearAllCondFormats(int)));
connect(ui->dataTable->filterHeader(), SIGNAL(editCondFormats(int)), this, SLOT(editCondFormats(int)));
connect(ui->dataTable, SIGNAL(editCondFormats(int)), this, SLOT(editCondFormats(int)));
connect(m_browseTableModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataTableSelectionChanged(QModelIndex)));
// Select in table the rows correspoding to the selected points in plot
@@ -2653,7 +2656,8 @@ static void loadBrowseDataTableSettings(BrowseDataTableSettings& settings, QXmlS
while(xml.readNext() != QXmlStreamReader::EndElement && xml.name() != "column") {
if(xml.name() == "format") {
CondFormat newCondFormat(xml.attributes().value("condition").toString(),
QColor(xml.attributes().value("color").toString()),
QColor(xml.attributes().value("foreground").toString()),
QColor(xml.attributes().value("background").toString()),
settings.encoding);
settings.condFormats[index].append(newCondFormat);
xml.skipCurrentElement();
@@ -2956,7 +2960,8 @@ static void saveBrowseDataTableSettings(const BrowseDataTableSettings& object, Q
for(auto format : iter.value()) {
xml.writeStartElement("format");
xml.writeAttribute("condition", format.filter());
xml.writeAttribute("color", format.color().name());
xml.writeAttribute("background", format.backgroundColor().name());
xml.writeAttribute("foreground", format.foregroundColor().name());
xml.writeEndElement();
}
xml.writeEndElement();
@@ -3171,7 +3176,11 @@ void MainWindow::updateFilter(int column, const QString& value)
void MainWindow::addCondFormat(int column, const QString& value)
{
CondFormat newCondFormat(value, m_condFormatPalette.nextSerialColor(Palette::appHasDarkTheme()), m_browseTableModel->encoding());
// Create automatically a new conditional format with the next serial background color according to the theme and the regular foreground
// color in the settings.
CondFormat newCondFormat(value, QColor(Settings::getValue("databrowser", "reg_fg_colour").toString()),
m_condFormatPalette.nextSerialColor(Palette::appHasDarkTheme()),
m_browseTableModel->encoding());
m_browseTableModel->addCondFormat(column, newCondFormat);
browseTableSettings[currentlyBrowsedTableName()].condFormats[column].append(newCondFormat);
}
@@ -3183,6 +3192,17 @@ void MainWindow::clearAllCondFormats(int column)
browseTableSettings[currentlyBrowsedTableName()].condFormats[column].clear();
}
void MainWindow::editCondFormats(int column)
{
CondFormatManager condFormatDialog(browseTableSettings[currentlyBrowsedTableName()].condFormats[column],
m_browseTableModel->encoding(), this);
if (condFormatDialog.exec()) {
QVector<CondFormat> condFormatVector = condFormatDialog.getCondFormats();
m_browseTableModel->setCondFormats(column, condFormatVector);
browseTableSettings[currentlyBrowsedTableName()].condFormats[column] = condFormatVector;
}
}
void MainWindow::editEncryption()
{
#ifdef ENABLE_SQLCIPHER

View File

@@ -275,6 +275,7 @@ private slots:
void updateFilter(int column, const QString& value);
void addCondFormat(int column, const QString& value);
void clearAllCondFormats(int column);
void editCondFormats(int column);
void editEncryption();
void on_actionClearFilters_triggered();
void copyCurrentCreateStatement();

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

BIN
src/icons/color_swatch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

View File

@@ -80,5 +80,8 @@
<file alias="field_fk">page_foreign_key.png</file>
<file alias="save_all">save_all.png</file>
<file alias="word_wrap">page_white_text.png</file>
<file alias="cond_formats">color_swatch.png</file>
<file alias="clear_cond_formats">clear_cond_formats.png</file>
<file alias="edit_cond_formats">edit_cond_formats.png</file>
</qresource>
</RCC>

View File

@@ -234,6 +234,26 @@ QVariant SqliteTableModel::headerData(int section, Qt::Orientation orientation,
return QString("%1").arg(section + 1);
}
QColor SqliteTableModel::getMatchingCondFormatColor(int column, const QString& value, int role) const
{
bool isNumber;
value.toFloat(&isNumber);
QString sql;
// For each conditional format for this column,
// if the condition matches the current data, return the associated colour.
for (const CondFormat& eachCondFormat : m_mCondFormats.value(column)) {
if (isNumber && !eachCondFormat.sqlCondition().contains("'"))
sql = QString("SELECT %1 %2").arg(value, eachCondFormat.sqlCondition());
else
sql = QString("SELECT '%1' %2").arg(value, eachCondFormat.sqlCondition());
// Query the DB for the condition, waiting in case there is a loading in progress.
if (m_db.querySingleValueFromDb(sql, false, DBBrowserDB::Wait) == "1")
return role == Qt::ForegroundRole ? eachCondFormat.foregroundColor() : eachCondFormat.backgroundColor();
}
return QColor();
}
QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
@@ -291,6 +311,15 @@ QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
return QColor(Settings::getValue("databrowser", "null_fg_colour").toString());
else if (nosync_isBinary(index))
return QColor(Settings::getValue("databrowser", "bin_fg_colour").toString());
else if (m_mCondFormats.contains(index.column())) {
QString value = cached_row->at(index.column());
// Unlock before querying from DB
lock.unlock();
QColor condFormatColor = getMatchingCondFormatColor(index.column(), value, role);
if (condFormatColor.isValid())
return condFormatColor;
}
// Regular case (not null, not binary and no matching conditional format)
return QColor(Settings::getValue("databrowser", "reg_fg_colour").toString());
} else if (role == Qt::BackgroundRole) {
if(!row_available)
@@ -301,23 +330,11 @@ QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
return QColor(Settings::getValue("databrowser", "bin_bg_colour").toString());
else if (m_mCondFormats.contains(index.column())) {
QString value = cached_row->at(index.column());
bool isNumber;
value.toFloat(&isNumber);
QString sql;
// For each conditional format for this column,
// if the condition matches the current data, return the associated colour.
for (const CondFormat& eachCondFormat : m_mCondFormats.value(index.column())) {
if (isNumber && !eachCondFormat.sqlCondition().contains("'"))
sql = QString("SELECT %1 %2").arg(value, eachCondFormat.sqlCondition());
else
sql = QString("SELECT '%1' %2").arg(value, eachCondFormat.sqlCondition());
// Unlock before querying from DB
lock.unlock();
// Query the DB for the condition, waiting in case there is a loading in progress.
if (m_db.querySingleValueFromDb(sql, false, DBBrowserDB::Wait) == "1")
return eachCondFormat.color();
}
// Unlock before querying from DB
lock.unlock();
QColor condFormatColor = getMatchingCondFormatColor(index.column(), value, role);
if (condFormatColor.isValid())
return condFormatColor;
}
// Regular case (not null, not binary and no matching conditional format)
return QColor(Settings::getValue("databrowser", "reg_bg_colour").toString());

View File

@@ -148,6 +148,10 @@ private:
QByteArray encode(const QByteArray& str) const;
QByteArray decode(const QByteArray& str) const;
// Return matching conditional format color or invalid color, otherwise.
// Only Qt::ForegroundRole and Qt::BackgroundRole are expected in role (Qt::ItemDataRole)
QColor getMatchingCondFormatColor(int column, const QString& value, int role) const;
DBBrowserDB& m_db;
/// counts numbers of clearCache() since instantiation; using this

View File

@@ -66,6 +66,7 @@ HEADERS += \
FindReplaceDialog.h \
ExtendedScintilla.h \
FileExtensionManager.h \
CondFormatManager.h \
Data.h \
CipherSettings.h \
DotenvFormat.h \
@@ -115,6 +116,7 @@ SOURCES += \
FindReplaceDialog.cpp \
ExtendedScintilla.cpp \
FileExtensionManager.cpp \
CondFormatManager.cpp \
Data.cpp \
CipherSettings.cpp \
DotenvFormat.cpp \
@@ -148,7 +150,8 @@ FORMS += \
RemoteDock.ui \
RemotePushDialog.ui \
FindReplaceDialog.ui \
FileExtensionManager.ui
FileExtensionManager.ui \
CondFormatManager.ui
TRANSLATIONS += \
translations/sqlb_ar_SA.ts \