diff --git a/src/CondFormat.h b/src/CondFormat.h index 8c764b63..bbef47d8 100644 --- a/src/CondFormat.h +++ b/src/CondFormat.h @@ -43,13 +43,25 @@ private: 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; } + void setBackgroundColor(QColor color) { m_bgColor = color; } + void setForegroundColor(QColor color) { m_fgColor = color; } + bool isBold() const { return m_font.bold(); } bool isItalic() const { return m_font.italic(); } bool isUnderline() const { return m_font.underline(); } + void setBold(bool value) { m_font.setBold(value); } + void setItalic(bool value) { m_font.setItalic(value); } + void setUnderline(bool value) { m_font.setUnderline(value); } + QFont font() const { return m_font; } + void setFontFamily(const QString &family) { m_font.setFamily(family); } + void setFontPointSize(int pointSize) { m_font.setPointSize(pointSize); } + Alignment alignment() const { return m_align; } + void setAlignment(Alignment value) { m_align = value; } Qt::AlignmentFlag alignmentFlag() const; }; diff --git a/src/ExtendedTableWidget.h b/src/ExtendedTableWidget.h index 86d650f7..b7b0f7ba 100644 --- a/src/ExtendedTableWidget.h +++ b/src/ExtendedTableWidget.h @@ -70,6 +70,8 @@ signals: void openFileFromDropEvent(QString); void selectedRowsToBeDeleted(); void editCondFormats(int column); + // Make the inherited protected signal public + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); private: void copyMimeData(const QModelIndexList& fromIndices, QMimeData* mimeData, const bool withHeaders, const bool inSQL); diff --git a/src/FilterLineEdit.cpp b/src/FilterLineEdit.cpp index 39008437..c2717182 100644 --- a/src/FilterLineEdit.cpp +++ b/src/FilterLineEdit.cpp @@ -184,7 +184,7 @@ void FilterLineEdit::showContextMenu(const QPoint &pos) emit clearAllCondFormats(); }); } else { - conditionalFormatAction = new QAction(QIcon(":/icons/cond_formats"), tr("Use for Conditional Format"), editContextMenu); + conditionalFormatAction = new QAction(QIcon(":/icons/add_cond_format"), tr("Use for Conditional Format"), editContextMenu); connect(conditionalFormatAction, &QAction::triggered, [&]() { emit addFilterAsCondFormat(text()); }); diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 360d0f29..b0689085 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -124,6 +124,21 @@ You can drag SQL statements from an object row and drop them into other applicat Browse Data + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + diff --git a/src/TableBrowser.cpp b/src/TableBrowser.cpp index e04946bb..8511ff2a 100644 --- a/src/TableBrowser.cpp +++ b/src/TableBrowser.cpp @@ -18,6 +18,7 @@ #include #include #include +#include QMap TableBrowser::browseTableSettings; QString TableBrowser::defaultBrowseTableEncoding; @@ -127,6 +128,114 @@ TableBrowser::TableBrowser(QWidget* parent) : connect(ui->dataTable->verticalHeader(), &QHeaderView::customContextMenuRequested, this, &TableBrowser::showRecordPopupMenu); connect(ui->dataTable, &ExtendedTableWidget::openFileFromDropEvent, this, &TableBrowser::requestFileOpen); connect(ui->dataTable, &ExtendedTableWidget::selectedRowsToBeDeleted, this, &TableBrowser::deleteRecord); + + connect(ui->fontComboBox, &QFontComboBox::currentFontChanged, this, [this](const QFont &font) { + modifyColumnFormat(ui->dataTable->selectedCols(), [font](CondFormat& format) { format.setFontFamily(font.family()); }); + }); + connect(ui->fontSizeBox, QOverload::of(&QSpinBox::valueChanged), this, [this](int pointSize) { + modifyColumnFormat(ui->dataTable->selectedCols(), [pointSize](CondFormat& format) { format.setFontPointSize(pointSize); }); + }); + + connect(ui->actionFontColor, &QAction::triggered, this, [this]() { + QColor color = QColorDialog::getColor(QColor(m_browseTableModel->data(currentIndex(), Qt::ForegroundRole).toString())); + if(color.isValid()) + modifyColumnFormat(ui->dataTable->selectedCols(), [color](CondFormat& format) { format.setForegroundColor(color); }); + }); + connect(ui->actionBackgroundColor, &QAction::triggered, this, [this]() { + QColor color = QColorDialog::getColor(QColor(m_browseTableModel->data(currentIndex(), Qt::BackgroundRole).toString())); + if(color.isValid()) + modifyColumnFormat(ui->dataTable->selectedCols(), [color](CondFormat& format) { format.setBackgroundColor(color); }); + }); + + connect(ui->actionBold, &QAction::toggled, this, [this](bool checked) { + modifyColumnFormat(ui->dataTable->selectedCols(), [checked](CondFormat& format) { format.setBold(checked); }); + }); + connect(ui->actionItalic, &QAction::toggled, this, [this](bool checked) { + modifyColumnFormat(ui->dataTable->selectedCols(), [checked](CondFormat& format) { format.setItalic(checked); }); + }); + connect(ui->actionUnderline, &QAction::toggled, this, [this](bool checked) { + modifyColumnFormat(ui->dataTable->selectedCols(), [checked](CondFormat& format) { format.setUnderline(checked); }); + }); + + connect(ui->actionLeftAlign, &QAction::triggered, this, [this]() { + ui->actionLeftAlign->setChecked(true); + ui->actionRightAlign->setChecked(false); + ui->actionCenter->setChecked(false); + ui->actionJustify->setChecked(false); + modifyColumnFormat(ui->dataTable->selectedCols(), [](CondFormat& format) { format.setAlignment(CondFormat::AlignLeft); }); + }); + connect(ui->actionRightAlign, &QAction::triggered, this, [this]() { + ui->actionLeftAlign->setChecked(false); + ui->actionRightAlign->setChecked(true); + ui->actionCenter->setChecked(false); + ui->actionJustify->setChecked(false); + modifyColumnFormat(ui->dataTable->selectedCols(), [](CondFormat& format) { format.setAlignment(CondFormat::AlignRight); }); + }); + connect(ui->actionCenter, &QAction::triggered, this, [this]() { + ui->actionLeftAlign->setChecked(false); + ui->actionRightAlign->setChecked(false); + ui->actionCenter->setChecked(true); + ui->actionJustify->setChecked(false); + modifyColumnFormat(ui->dataTable->selectedCols(), [](CondFormat& format) { format.setAlignment(CondFormat::AlignCenter); }); + }); + connect(ui->actionJustify, &QAction::triggered, this, [this]() { + ui->actionLeftAlign->setChecked(false); + ui->actionRightAlign->setChecked(false); + ui->actionCenter->setChecked(false); + ui->actionJustify->setChecked(true); + modifyColumnFormat(ui->dataTable->selectedCols(), [](CondFormat& format) { format.setAlignment(CondFormat::AlignJustify); }); + }); + + connect(ui->actionEditCondFormats, &QAction::triggered, this, [this]() { editCondFormats(currentIndex().column()); }); + connect(ui->actionClearFormat, &QAction::triggered, this, [this]() { + for (int column : ui->dataTable->selectedCols()) + clearAllCondFormats(column); + }); + + connect(ui->dataTable, &ExtendedTableWidget::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &) { + // Get cell current format for updating the format toolbar values. Block signals, so the format change is not reapplied. + QFont font = QFont(m_browseTableModel->data(current, Qt::FontRole).toString()); + ui->fontComboBox->blockSignals(true); + ui->fontComboBox->setCurrentFont(font); + ui->fontComboBox->blockSignals(false); + + ui->fontSizeBox->blockSignals(true); + ui->fontSizeBox->setValue(font.pointSize()); + ui->fontSizeBox->blockSignals(false); + + ui->actionBold->blockSignals(true); + ui->actionBold->setChecked(font.bold()); + ui->actionBold->blockSignals(false); + + ui->actionItalic->blockSignals(true); + ui->actionItalic->setChecked(font.italic()); + ui->actionItalic->blockSignals(false); + + ui->actionUnderline->blockSignals(true); + ui->actionUnderline->setChecked(font.underline()); + ui->actionUnderline->blockSignals(false); + + Qt::Alignment align = Qt::Alignment(m_browseTableModel->data(current, Qt::TextAlignmentRole).toInt()); + ui->actionLeftAlign->blockSignals(true); + ui->actionLeftAlign->setChecked(align.testFlag(Qt::AlignLeft)); + ui->actionLeftAlign->blockSignals(false); + + ui->actionRightAlign->blockSignals(true); + ui->actionRightAlign->setChecked(align.testFlag(Qt::AlignRight)); + ui->actionRightAlign->blockSignals(false); + + ui->actionCenter->blockSignals(true); + ui->actionCenter->setChecked(align.testFlag(Qt::AlignCenter)); + ui->actionCenter->blockSignals(false); + + ui->actionJustify->blockSignals(true); + ui->actionJustify->setChecked(align.testFlag(Qt::AlignJustify)); + ui->actionJustify->blockSignals(false); + }); + + connect(ui->actionToggleFormatToolbar, &QAction::toggled, ui->formatFrame, &QFrame::setVisible); + ui->actionToggleFormatToolbar->setChecked(false); + ui->formatFrame->setVisible(false); } TableBrowser::~TableBrowser() @@ -473,6 +582,35 @@ void TableBrowser::editCondFormats(int column) } } +void TableBrowser::modifyColumnFormat(std::unordered_set columns, std::function changeFunction) +{ + for (int column : columns) { + std::vector& columnFormats = browseTableSettings[currentlyBrowsedTableName()].condFormats[column]; + + auto it = std::find_if(columnFormats.begin(), columnFormats.end(), [](const CondFormat& format) { + return format.sqlCondition().isEmpty(); + }); + if(it != columnFormats.end()) { + changeFunction(*it); + m_browseTableModel->addCondFormat(column, *it); + } else { + + QFont font = QFont(Settings::getValue("databrowser", "font").toString()); + font.setPointSize(Settings::getValue("databrowser", "fontsize").toInt()); + + CondFormat newCondFormat(QString(""), QColor(Settings::getValue("databrowser", "reg_fg_colour").toString()), + QColor(Settings::getValue("databrowser", "reg_bg_colour").toString()), + font, + CondFormat::AlignLeft, + m_browseTableModel->encoding()); + changeFunction(newCondFormat); + m_browseTableModel->addCondFormat(column, newCondFormat); + browseTableSettings[currentlyBrowsedTableName()].condFormats[column].push_back(newCondFormat); + } + } + emit projectModified(); +} + void TableBrowser::updateRecordsetLabel() { // Get all the numbers, i.e. the number of the first row and the last row as well as the total number of rows diff --git a/src/TableBrowser.h b/src/TableBrowser.h index 3feafa99..fd1594cd 100644 --- a/src/TableBrowser.h +++ b/src/TableBrowser.h @@ -9,6 +9,8 @@ #include #include +#include + class DBBrowserDB; class ExtendedTableWidget; class SqliteTableModel; @@ -169,6 +171,8 @@ private: static QString defaultBrowseTableEncoding; Palette m_condFormatPalette; + + void modifyColumnFormat(std::unordered_set columns, std::function changeFunction); }; #endif diff --git a/src/TableBrowser.ui b/src/TableBrowser.ui index 868e7f5c..7b73be4b 100644 --- a/src/TableBrowser.ui +++ b/src/TableBrowser.ui @@ -6,7 +6,7 @@ 0 0 - 552 + 651 362 @@ -14,6 +14,9 @@ Browse Data + + 1 + 0 @@ -28,6 +31,12 @@ + + 2 + + + 2 + @@ -74,6 +83,8 @@ + + @@ -97,6 +108,64 @@ + + + + + 5 + + + 2 + + + 0 + + + 2 + + + 0 + + + + + + + + + 50 + 16777215 + + + + 1 + + + + + + + Qt::ToolButtonIconOnly + + + + + + + + + + + + + + + + + + + + @@ -127,6 +196,18 @@ + + 2 + + + 2 + + + 2 + + + 2 + @@ -507,6 +588,186 @@ Qt::WidgetShortcut + + + true + + + + :/icons/text_bold.png:/icons/text_bold.png + + + Bold + + + Bold + + + Ctrl+B + + + + + true + + + + :/icons/text_italic.png:/icons/text_italic.png + + + Italic + + + Italic + + + + + true + + + + :/icons/text_underline.png:/icons/text_underline.png + + + Underline + + + Underline + + + Ctrl+U + + + + + true + + + + :/icons/text_align_right.png:/icons/text_align_right.png + + + Align Right + + + Align Right + + + + + true + + + + :/icons/text_align_left.png:/icons/text_align_left.png + + + Align Left + + + Align Left + + + + + true + + + + :/icons/text_align_center.png:/icons/text_align_center.png + + + Center Horizontally + + + Center Horizontally + + + + + true + + + + :/icons/text_align_justify.png:/icons/text_align_justify.png + + + Justify + + + Justify + + + + + + :/icons/edit_cond_formats:/icons/edit_cond_formats + + + Edit Conditional Formats... + + + Edit Conditional Formats... + + + + + + :/icons/clear_cond_formats:/icons/clear_cond_formats + + + Clear Format + + + Clear All Conditional Formats + + + + + + :/icons/foreground_color:/icons/foreground_color + + + Font Color + + + Font Color + + + + + + :/icons/background_color:/icons/background_color + + + Background Color + + + Background Color + + + + + true + + + + :/icons/cond_formats:/icons/cond_formats + + + Toggle Format Toolbar + + + Show/hide format toolbar + + + This button shows or hides the formatting toolbar of the Data Browser + + + This button shows or hides the formatting toolbar of the Data Browser + + diff --git a/src/icons/clear_cond_formats.png b/src/icons/clear_cond_formats.png deleted file mode 100644 index 1646b12c..00000000 Binary files a/src/icons/clear_cond_formats.png and /dev/null differ diff --git a/src/icons/icons.qrc b/src/icons/icons.qrc index 1baac7e6..f9e08049 100644 --- a/src/icons/icons.qrc +++ b/src/icons/icons.qrc @@ -80,12 +80,21 @@ page_foreign_key.png save_all.png page_white_text.png - color_swatch.png - clear_cond_formats.png - edit_cond_formats.png + color_swatch.png + edit_cond_formats.png clear_sorting.png text_bold.png text_italic.png text_underline.png + text_align_center.png + text_align_justify.png + text_align_left.png + text_align_right.png + page_paintbrush.png + text_paintbrush.png + style.png + style_edit.png + style_delete.png + style_add.png diff --git a/src/icons/page_paintbrush.png b/src/icons/page_paintbrush.png new file mode 100644 index 00000000..246a2f0b Binary files /dev/null and b/src/icons/page_paintbrush.png differ diff --git a/src/icons/style.png b/src/icons/style.png new file mode 100644 index 00000000..81e41de7 Binary files /dev/null and b/src/icons/style.png differ diff --git a/src/icons/style_add.png b/src/icons/style_add.png new file mode 100644 index 00000000..e0369c6b Binary files /dev/null and b/src/icons/style_add.png differ diff --git a/src/icons/style_delete.png b/src/icons/style_delete.png new file mode 100644 index 00000000..640f187e Binary files /dev/null and b/src/icons/style_delete.png differ diff --git a/src/icons/style_edit.png b/src/icons/style_edit.png new file mode 100644 index 00000000..25bb5b67 Binary files /dev/null and b/src/icons/style_edit.png differ diff --git a/src/icons/text_align_center.png b/src/icons/text_align_center.png new file mode 100644 index 00000000..57beb381 Binary files /dev/null and b/src/icons/text_align_center.png differ diff --git a/src/icons/text_align_justify.png b/src/icons/text_align_justify.png new file mode 100644 index 00000000..2fbdd692 Binary files /dev/null and b/src/icons/text_align_justify.png differ diff --git a/src/icons/text_align_left.png b/src/icons/text_align_left.png new file mode 100644 index 00000000..6c8fcc11 Binary files /dev/null and b/src/icons/text_align_left.png differ diff --git a/src/icons/text_align_right.png b/src/icons/text_align_right.png new file mode 100644 index 00000000..a1502571 Binary files /dev/null and b/src/icons/text_align_right.png differ diff --git a/src/icons/text_paintbrush.png b/src/icons/text_paintbrush.png new file mode 100644 index 00000000..61876930 Binary files /dev/null and b/src/icons/text_paintbrush.png differ diff --git a/src/sqlitetablemodel.cpp b/src/sqlitetablemodel.cpp index 53fab3b8..f3a032ee 100644 --- a/src/sqlitetablemodel.cpp +++ b/src/sqlitetablemodel.cpp @@ -822,7 +822,15 @@ std::vector SqliteTableModel::getColumns(std::shared_ptr p void SqliteTableModel::addCondFormat(int column, const CondFormat& condFormat) { - m_mCondFormats[column].push_back(condFormat); + // If the condition is already present in the vector, update that entry and respect the order, since two entries with the same + // condition do not make sense. + auto it = std::find_if(m_mCondFormats[column].begin(), m_mCondFormats[column].end(), [condFormat](const CondFormat& format) { + return format.sqlCondition() == condFormat.sqlCondition(); + }); + if(it != m_mCondFormats[column].end()) { + *it = condFormat; + } else + m_mCondFormats[column].push_back(condFormat); emit layoutChanged(); }