Skip to content

Commit

Permalink
More conditional formats: font style
Browse files Browse the repository at this point in the history
The conditional format manager allows now to set the font style: bold,
italic and underline.

The project format has been updated. This is also the base for setting
other font formats without further changing the project schema.

New icons form the Silk icon set.

See issue sqlitebrowser#1976 and sqlitebrowser#1815.
  • Loading branch information
mgrojo committed Sep 21, 2019
1 parent 6ddd6e9 commit 412c239
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 23 deletions.
5 changes: 3 additions & 2 deletions src/CondFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
#include "Settings.h"
#include "Data.h"

CondFormat::CondFormat(const QString& filter, const QColor& foreground, const QColor& background, const QString& encoding)
CondFormat::CondFormat(const QString& filter, const QColor& foreground, const QColor& background, const QFont& font, const QString& encoding)
: m_filter(filter),
m_bgColor(background),
m_fgColor(foreground)
m_fgColor(foreground),
m_font(font)
{
if (!filter.isEmpty())
m_sqlCondition = filterToSqlCondition(filter, encoding);
Expand Down
9 changes: 7 additions & 2 deletions src/CondFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

#include <QString>
#include <QColor>
#include <QFont>

// Conditional formatting for given format to table cells based on a specified condition.
class CondFormat
{
public:
CondFormat() {}
explicit CondFormat(const QString& filter, const QColor& foreground, const QColor& background, const QString& encoding = QString());
explicit CondFormat(const QString& filter, const QColor& foreground, const QColor& background, const QFont& font, const QString& encoding = QString());

static QString filterToSqlCondition(const QString& value, const QString& encoding = QString());

Expand All @@ -18,13 +19,17 @@ class CondFormat
QString m_filter;
QColor m_bgColor;
QColor m_fgColor;
QFont m_font;

public:
QString sqlCondition() const { return m_sqlCondition; }
QString filter() const { return m_filter; }
QColor backgroundColor() const { return m_bgColor; }
QColor foregroundColor() const { return m_fgColor; }

bool isBold() const { return m_font.bold(); }
bool isItalic() const { return m_font.italic(); }
bool isUnderline() const { return m_font.underline(); }
QFont font() const { return m_font; }
};

#endif // CONDFORMAT_H
20 changes: 18 additions & 2 deletions src/CondFormatManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ CondFormatManager::CondFormatManager(const std::vector<CondFormat>& condFormats,
{
ui->setupUi(this);

// Resize columns to contents, except for the condition
for(int col = ColumnForeground; col < ColumnFilter; ++col)
ui->tableCondFormats->resizeColumnToContents(col);

for(const CondFormat& aCondFormat : condFormats)
addItem(aCondFormat);

Expand All @@ -40,20 +44,24 @@ void CondFormatManager::addNewItem()
{
CondFormat newCondFormat("", QColor(Settings::getValue("databrowser", "reg_fg_colour").toString()),
m_condFormatPalette.nextSerialColor(Palette::appHasDarkTheme()),
QFont(Settings::getValue("databrowser", "font").toString()),
m_encoding);
addItem(newCondFormat);
}

void CondFormatManager::addItem(const CondFormat& aCondFormat)
{
int i = ui->tableCondFormats->topLevelItemCount();
QTreeWidgetItem *newItem = new QTreeWidgetItem({"", "", aCondFormat.filter()});
QTreeWidgetItem *newItem = new QTreeWidgetItem({"", "", "", "", "", aCondFormat.filter()});
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"));
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);
ui->tableCondFormats->insertTopLevelItem(i, newItem);
ui->tableCondFormats->openPersistentEditor(newItem, ColumnFilter);
}
Expand Down Expand Up @@ -100,12 +108,20 @@ void CondFormatManager::downItem()
std::vector<CondFormat> CondFormatManager::getCondFormats()
{
std::vector<CondFormat> result;
QFont font = Settings::getValue("databrowser", "font").toString();

for (int i = 0; i < ui->tableCondFormats->topLevelItemCount(); ++i)
{
QTreeWidgetItem* item = ui->tableCondFormats->topLevelItem(i);

font.setBold(item->checkState(ColumnBold) == Qt::Checked);
font.setItalic(item->checkState(ColumnItalic) == Qt::Checked);
font.setUnderline(item->checkState(ColumnUnderline) == Qt::Checked);

result.emplace_back(item->text(ColumnFilter),
item->background(ColumnForeground).color(),
item->background(ColumnBackground).color(), m_encoding);
item->background(ColumnBackground).color(),
font, m_encoding);
}
return result;
}
Expand Down
5 changes: 4 additions & 1 deletion src/CondFormatManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ class CondFormatManager : public QDialog
enum Columns {
ColumnForeground = 0,
ColumnBackground = 1,
ColumnFilter = 2
ColumnBold = 2,
ColumnItalic = 3,
ColumnUnderline = 4,
ColumnFilter = 5
};
Ui::CondFormatManager *ui;
std::vector<CondFormat> m_condFormats;
Expand Down
42 changes: 39 additions & 3 deletions src/CondFormatManager.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>578</width>
<width>600</width>
<height>463</height>
</rect>
</property>
Expand Down Expand Up @@ -150,8 +150,8 @@
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<attribute name="headerDefaultSectionSize">
<number>150</number>
<attribute name="headerMinimumSectionSize">
<number>25</number>
</attribute>
<column>
<property name="text">
Expand All @@ -163,6 +163,42 @@
<string>Background color</string>
</property>
</column>
<column>
<property name="text">
<string/>
</property>
<property name="toolTip">
<string>Bold</string>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/text_bold.png</normaloff>:/icons/text_bold.png</iconset>
</property>
</column>
<column>
<property name="text">
<string/>
</property>
<property name="toolTip">
<string>Italic</string>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/text_italic.png</normaloff>:/icons/text_italic.png</iconset>
</property>
</column>
<column>
<property name="text">
<string/>
</property>
<property name="toolTip">
<string>Underline</string>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/text_underline.png</normaloff>:/icons/text_underline.png</iconset>
</property>
</column>
<column>
<property name="text">
<string>Condition</string>
Expand Down
9 changes: 8 additions & 1 deletion src/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2246,10 +2246,16 @@ static void loadBrowseDataTableSettings(BrowseDataTableSettings& settings, QXmlS
int index = xml.attributes().value("index").toInt();
while(xml.readNext() != QXmlStreamReader::EndElement && xml.name() != "column") {
if(xml.name() == "format") {
QFont font;
if (xml.attributes().hasAttribute("font"))
font.fromString(xml.attributes().value("font").toString());
else
Settings::getValue("databrowser", "font").toString();

settings.condFormats[index].emplace_back(xml.attributes().value("condition").toString(),
QColor(xml.attributes().value("foreground").toString()),
QColor(xml.attributes().value("background").toString()),
settings.encoding);
font, settings.encoding);
xml.skipCurrentElement();
}
}
Expand Down Expand Up @@ -2587,6 +2593,7 @@ static void saveBrowseDataTableSettings(const BrowseDataTableSettings& object, Q
xml.writeAttribute("condition", format.filter());
xml.writeAttribute("background", format.backgroundColor().name());
xml.writeAttribute("foreground", format.foregroundColor().name());
xml.writeAttribute("font", format.font().toString());
xml.writeEndElement();
}
xml.writeEndElement();
Expand Down
3 changes: 2 additions & 1 deletion src/TableBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,10 @@ void TableBrowser::updateFilter(int column, const QString& value)
void TableBrowser::addCondFormat(int column, const QString& value)
{
// Create automatically a new conditional format with the next serial background color according to the theme and the regular foreground
// color in the settings.
// color and font in the settings.
CondFormat newCondFormat(value, QColor(Settings::getValue("databrowser", "reg_fg_colour").toString()),
m_condFormatPalette.nextSerialColor(Palette::appHasDarkTheme()),
QFont(Settings::getValue("databrowser", "font").toString()),
m_browseTableModel->encoding());
m_browseTableModel->addCondFormat(column, newCondFormat);
browseTableSettings[currentlyBrowsedTableName()].condFormats[column].push_back(newCondFormat);
Expand Down
3 changes: 3 additions & 0 deletions src/icons/icons.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,8 @@
<file alias="clear_cond_formats">clear_cond_formats.png</file>
<file alias="edit_cond_formats">edit_cond_formats.png</file>
<file alias="clear_sorting">clear_sorting.png</file>
<file>text_bold.png</file>
<file>text_italic.png</file>
<file>text_underline.png</file>
</qresource>
</RCC>
Binary file added src/icons/text_bold.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/icons/text_italic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/icons/text_underline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 26 additions & 7 deletions src/sqlitetablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,17 @@ 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
QVariant SqliteTableModel::getMatchingCondFormat(int column, const QString& value, int role) const
{
if (m_mCondFormats.find(column) == m_mCondFormats.end())
return QVariant();

bool isNumber;
value.toFloat(&isNumber);
value.toDouble(&isNumber);
QString sql;

// For each conditional format for this column,
// if the condition matches the current data, return the associated colour.
// if the condition matches the current data, return the associated format.
for (const CondFormat& eachCondFormat : m_mCondFormats.at(column)) {
if (isNumber && !eachCondFormat.sqlCondition().contains("'"))
sql = QString("SELECT %1 %2").arg(value, eachCondFormat.sqlCondition());
Expand All @@ -290,9 +294,16 @@ QColor SqliteTableModel::getMatchingCondFormatColor(int column, const QString& v
// Empty filter means: apply format to any row.
// Query the DB for the condition, waiting in case there is a loading in progress.
if (eachCondFormat.filter().isEmpty() || m_db.querySingleValueFromDb(sql, false, DBBrowserDB::Wait) == "1")
return role == Qt::ForegroundRole ? eachCondFormat.foregroundColor() : eachCondFormat.backgroundColor();
switch (role) {
case Qt::ForegroundRole:
return eachCondFormat.foregroundColor();
case Qt::BackgroundRole:
return eachCondFormat.backgroundColor();
case Qt::FontRole:
return eachCondFormat.font();
}
}
return QColor();
return QVariant();
}

QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
Expand Down Expand Up @@ -346,6 +357,14 @@ QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
QFont font;
if(!row_available || cached_row->at(column).isNull() || nosync_isBinary(index))
font.setItalic(true);
else {
QString value = cached_row->at(column);
// Unlock before querying from DB
lock.unlock();
QVariant condFormatFont = getMatchingCondFormat(index.column(), value, role);
if (condFormatFont.isValid())
return condFormatFont;
}
return font;
} else if(role == Qt::ForegroundRole) {
if(!row_available)
Expand All @@ -358,7 +377,7 @@ QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
QString value = cached_row->at(column);
// Unlock before querying from DB
lock.unlock();
QColor condFormatColor = getMatchingCondFormatColor(index.column(), value, role);
QVariant condFormatColor = getMatchingCondFormat(index.column(), value, role);
if (condFormatColor.isValid())
return condFormatColor;
}
Expand All @@ -375,7 +394,7 @@ QVariant SqliteTableModel::data(const QModelIndex &index, int role) const
QString value = cached_row->at(column);
// Unlock before querying from DB
lock.unlock();
QColor condFormatColor = getMatchingCondFormatColor(index.column(), value, role);
QVariant condFormatColor = getMatchingCondFormat(index.column(), value, role);
if (condFormatColor.isValid())
return condFormatColor;
}
Expand Down
8 changes: 4 additions & 4 deletions src/sqlitetablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <QAbstractTableModel>
#include <QMutex>
#include <QColor>

#include <memory>
#include <vector>
#include <map>
Expand Down Expand Up @@ -150,9 +150,9 @@ public slots:
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;
// Return matching conditional format color/font or invalid value, otherwise.
// Only format roles are expected in role (Qt::ItemDataRole)
QVariant getMatchingCondFormat(int column, const QString& value, int role) const;

DBBrowserDB& m_db;

Expand Down

0 comments on commit 412c239

Please sign in to comment.