From 1792f42dac7122226e007ba597d803728781877d Mon Sep 17 00:00:00 2001 From: eelke Date: Fri, 23 Aug 2019 09:43:48 +0200 Subject: [PATCH] Improved working of BackupDialog - improved layout - automatically switch to output component when start is clicked - coloured output for succes/error message - highlighter for pg_dump output that highlights error lines Note: all output of pg_dump goes to stderr because stdout is reserved for output of the backup data. --- pglab/BackupDialog.cpp | 335 ++++++++++++++++++------------ pglab/BackupDialog.h | 46 ++-- pglab/PgDumpOutputHighlighter.cpp | 19 ++ pglab/PgDumpOutputHighlighter.h | 20 ++ pglab/SqlSyntaxHighlighter.h | 2 +- pglab/pglab.pro | 2 + 6 files changed, 274 insertions(+), 150 deletions(-) create mode 100644 pglab/PgDumpOutputHighlighter.cpp create mode 100644 pglab/PgDumpOutputHighlighter.h diff --git a/pglab/BackupDialog.cpp b/pglab/BackupDialog.cpp index c00317d..30e5ee8 100644 --- a/pglab/BackupDialog.cpp +++ b/pglab/BackupDialog.cpp @@ -1,7 +1,7 @@ #include "BackupDialog.h" #include "BackupFormatModel.h" - +#include "PgDumpOutputHighlighter.h" #include #include #include @@ -14,11 +14,14 @@ #include #include #include +#include #include #include #include #include +#include #include +#include #include #include #include @@ -54,151 +57,179 @@ QPlainTextEdit* createStdOutput(QWidget *parent) stdOutput->setFont(font); stdOutput->setLineWrapMode(QPlainTextEdit::NoWrap); stdOutput->setReadOnly(true); + + new PgDumpOutputHighlighter(stdOutput->document()); + + return stdOutput; } BackupDialog::BackupDialog(QWidget *parent) : QDialog(parent) { + // Options tab contents + // Filename + labelFileName = new QLabel(this); + labelFileName->setObjectName(QString::fromUtf8("labelFileName")); - btnStart = new QPushButton(this); - btnStart->setObjectName(QString::fromUtf8("btnStart")); - btnStart->setGeometry(QRect(270, 630, 75, 23)); - - tabWidget = new QTabWidget(this); - tabWidget->setObjectName(QString::fromUtf8("tabWidget")); - tabWidget->setGeometry(QRect(30, 90, 601, 501)); - - tab = new QWidget(); - tab->setObjectName(QString::fromUtf8("tab")); - - verticalLayout = new QVBoxLayout(tab); - verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); - - formLayout = new QFormLayout(); - formLayout->setObjectName(QString::fromUtf8("formLayout")); - - label = new QLabel(tab); - label->setObjectName(QString::fromUtf8("label")); - - formLayout->setWidget(0, QFormLayout::LabelRole, label); - - widget = new QWidget(tab); - widget->setObjectName(QString::fromUtf8("widget")); - horizontalLayout = new QHBoxLayout(widget); - horizontalLayout->setSpacing(0); - horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); - horizontalLayout->setContentsMargins(0, 0, 0, 0); - editFilename = new QLineEdit(widget); + // Filename edit+button + editFilename = new QLineEdit(this); editFilename->setObjectName(QString::fromUtf8("editFilename")); - horizontalLayout->addWidget(editFilename); - - selectDestination = new QPushButton(widget); + selectDestination = new QPushButton; selectDestination->setObjectName(QString::fromUtf8("selectDestination")); - horizontalLayout->addWidget(selectDestination); + layoutDestination = new QHBoxLayout; + layoutDestination->setSpacing(0); + layoutDestination->setObjectName(QString::fromUtf8("layoutDestination")); + layoutDestination->setContentsMargins(0, 0, 0, 0); + layoutDestination->addWidget(editFilename); + layoutDestination->addWidget(selectDestination); + widgetDestination = new QWidget; + widgetDestination->setObjectName(QString::fromUtf8("widgetDestination")); + widgetDestination->setLayout(layoutDestination); - formLayout->setWidget(0, QFormLayout::FieldRole, widget); - - label_2 = new QLabel(tab); - label_2->setObjectName(QString::fromUtf8("label_2")); - - formLayout->setWidget(1, QFormLayout::LabelRole, label_2); - - backupFormat = new QComboBox(tab); + // Backup format + labelFormat = new QLabel; + labelFormat->setObjectName(QString::fromUtf8("labelFormat")); + backupFormat = new QComboBox; backupFormat->setObjectName(QString::fromUtf8("backupFormat")); backupFormat->setModelColumn(0); - formLayout->setWidget(1, QFormLayout::FieldRole, backupFormat); - - label_3 = new QLabel(tab); - label_3->setObjectName(QString::fromUtf8("label_3")); - - formLayout->setWidget(2, QFormLayout::LabelRole, label_3); - - jobs = new QSpinBox(tab); + // Jobs + labelJobs = new QLabel; + labelJobs->setObjectName(QString::fromUtf8("labelJobs")); + jobs = new QSpinBox; jobs->setObjectName(QString::fromUtf8("jobs")); - formLayout->setWidget(2, QFormLayout::FieldRole, jobs); - - chkbxVerbose = new QCheckBox(tab); + // Verbose + chkbxVerbose = new QCheckBox; chkbxVerbose->setObjectName(QString::fromUtf8("chkbxVerbose")); - formLayout->setWidget(3, QFormLayout::FieldRole, chkbxVerbose); - - label_5 = new QLabel(tab); - label_5->setObjectName(QString::fromUtf8("label_5")); - - formLayout->setWidget(4, QFormLayout::LabelRole, label_5); - - compression = new QSpinBox(tab); + // Compression + labelCompression = new QLabel; + labelCompression->setObjectName(QString::fromUtf8("labelCompression")); + compression = new QSpinBox; compression->setObjectName(QString::fromUtf8("compression")); compression->setMinimum(-1); compression->setMaximum(9); compression->setValue(-1); - formLayout->setWidget(4, QFormLayout::FieldRole, compression); - - chkbxIncludeBlobs = new QCheckBox(tab); + // Include BLOBs + chkbxIncludeBlobs = new QCheckBox(this); chkbxIncludeBlobs->setObjectName(QString::fromUtf8("chkbxIncludeBlobs")); - formLayout->setWidget(6, QFormLayout::FieldRole, chkbxIncludeBlobs); - - chkbxClean = new QCheckBox(tab); + // Clean + chkbxClean = new QCheckBox(this); chkbxClean->setObjectName(QString::fromUtf8("chkbxClean")); - formLayout->setWidget(7, QFormLayout::FieldRole, chkbxClean); - - chkbxCreate = new QCheckBox(tab); - chkbxCreate->setObjectName(QString::fromUtf8("chkbxCreate")); - - formLayout->setWidget(8, QFormLayout::FieldRole, chkbxCreate); - - noOwner = new QCheckBox(tab); - noOwner->setObjectName(QString::fromUtf8("noOwner")); - - formLayout->setWidget(9, QFormLayout::FieldRole, noOwner); - - oids = new QCheckBox(tab); - oids->setObjectName(QString::fromUtf8("oids")); - - formLayout->setWidget(10, QFormLayout::FieldRole, oids); - - what = new QComboBox(tab); + // Data and/or Schema + labelDataOrSchema = new QLabel(this); + labelDataOrSchema->setObjectName(QString::fromUtf8("labelDataOrSchema")); + what = new QComboBox(this); what->addItem(QString()); what->addItem(QString()); what->addItem(QString()); what->setObjectName(QString::fromUtf8("what")); - - formLayout->setWidget(5, QFormLayout::FieldRole, what); - - label_4 = new QLabel(tab); - label_4->setObjectName(QString::fromUtf8("label_4")); - - formLayout->setWidget(5, QFormLayout::LabelRole, label_4); - - noAcl = new QCheckBox(tab); + // create + chkbxCreate = new QCheckBox(this); + chkbxCreate->setObjectName(QString::fromUtf8("chkbxCreate")); + // owner + noOwner = new QCheckBox(this); + noOwner->setObjectName(QString::fromUtf8("noOwner")); + // with oids + oids = new QCheckBox(this); + oids->setObjectName(QString::fromUtf8("oids")); + // without acl (permissions) + noAcl = new QCheckBox(this); noAcl->setObjectName(QString::fromUtf8("noAcl")); - formLayout->setWidget(11, QFormLayout::FieldRole, noAcl); + // Options layout + auto formLayout = new QFormLayout; + formLayout->setObjectName(QString::fromUtf8("formLayout")); + int form_row = 0; + formLayout->setWidget(form_row, QFormLayout::LabelRole, labelFileName); + formLayout->setWidget(form_row, QFormLayout::FieldRole, widgetDestination); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::LabelRole, labelFormat); + formLayout->setWidget(form_row, QFormLayout::FieldRole, backupFormat); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::LabelRole, labelJobs); + formLayout->setWidget(form_row, QFormLayout::FieldRole, jobs); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::FieldRole, chkbxVerbose); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::LabelRole, labelCompression); + formLayout->setWidget(form_row, QFormLayout::FieldRole, compression); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::FieldRole, what); + formLayout->setWidget(form_row, QFormLayout::LabelRole, labelDataOrSchema); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::FieldRole, chkbxIncludeBlobs); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::FieldRole, chkbxClean); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::FieldRole, chkbxCreate); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::FieldRole, noOwner); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::FieldRole, oids); + ++form_row; + formLayout->setWidget(form_row, QFormLayout::FieldRole, noAcl); + + btnStart = new QPushButton; + btnStart->setObjectName(QString::fromUtf8("btnStart")); + + auto verticalLayout = new QVBoxLayout; + verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); verticalLayout->addLayout(formLayout); + verticalLayout->addWidget(btnStart); - tabWidget->addTab(tab, QString()); - tab_2 = new QWidget(); - tab_2->setObjectName(QString::fromUtf8("tab_2")); - verticalLayout_2 = new QVBoxLayout(tab_2); - verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); + optionsView = new QWidget(); + optionsView->setObjectName(QString::fromUtf8("tabOptions")); + optionsView->setLayout(verticalLayout); + // Progress tab stdOutput = createStdOutput(this); - verticalLayout_2->addWidget(stdOutput); - tabWidget->addTab(tab_2, QString()); - tabWidget->setCurrentIndex(0); + m_OutputOkFormat.setForeground(Qt::white); + m_OutputOkFormat.setBackground(QBrush(Qt::darkGreen)); + m_OutputOkFormat.setFontWeight(QFont::Bold); + m_OutputErrorFormat.setForeground(Qt::white); + m_OutputErrorFormat.setBackground(QBrush(Qt::darkRed)); + m_OutputErrorFormat.setFontWeight(QFont::Bold); + + btnBack = new QPushButton; + btnBack->setObjectName("btnBack"); + btnClose = new QPushButton; + btnClose->setObjectName("btnClose"); + + auto layoutButtons = new QHBoxLayout; + layoutButtons->addWidget(btnBack); + layoutButtons->addWidget(btnClose); + + auto progressMainLayout = new QVBoxLayout; + progressMainLayout->setObjectName(QString::fromUtf8("progressMainLayout")); + progressMainLayout->addWidget(stdOutput); + progressMainLayout->addLayout(layoutButtons); + + progressView = new QWidget; + progressView->setObjectName(QString::fromUtf8("progressTab")); + progressView->setLayout(progressMainLayout); + + + viewStack = new QStackedLayout; + viewStack->setObjectName(QString::fromUtf8("viewStack")); + viewStack->addWidget(optionsView); + viewStack->addWidget(progressView); + viewStack->setCurrentWidget(optionsView); + + setLayout(viewStack); QMetaObject::connectSlotsByName(this); + connect(btnClose, &QPushButton::clicked, this, &QDialog::close); auto format_model = new BackupFormatModel(this); backupFormat->setModel(format_model); @@ -213,17 +244,17 @@ BackupDialog::~BackupDialog() void BackupDialog::retranslateUi() { - setWindowTitle(QApplication::translate("BackupDialog", "Dialog", nullptr)); - label->setText(QApplication::translate("BackupDialog", "Filename", nullptr)); + setWindowTitle(QApplication::translate("BackupDialog", "Backup database", nullptr)); + labelFileName->setText(QApplication::translate("BackupDialog", "Filename", nullptr)); selectDestination->setText(QApplication::translate("BackupDialog", "...", nullptr)); - label_2->setText(QApplication::translate("BackupDialog", "Format", nullptr)); - label_3->setText(QApplication::translate("BackupDialog", "Jobs:", nullptr)); + labelFormat->setText(QApplication::translate("BackupDialog", "Format", nullptr)); + labelJobs->setText(QApplication::translate("BackupDialog", "Jobs:", nullptr)); chkbxVerbose->setText(QApplication::translate("BackupDialog", "Verbose (-v)", nullptr)); - label_5->setText(QApplication::translate("BackupDialog", "Compression (-Z)", nullptr)); + labelCompression->setText(QApplication::translate("BackupDialog", "Compression (-Z)", nullptr)); #ifndef QT_NO_TOOLTIP compression->setToolTip(QApplication::translate("BackupDialog", "-1 means default, 0-9 is no compression to max compression", nullptr)); #endif // QT_NO_TOOLTIP - label_4->setText(QApplication::translate("BackupDialog", "What", nullptr)); + labelDataOrSchema->setText(QApplication::translate("BackupDialog", "What", nullptr)); what->setItemText(0, QApplication::translate("BackupDialog", "data + schema", nullptr)); what->setItemText(1, QApplication::translate("BackupDialog", "data only (-a)", nullptr)); what->setItemText(2, QApplication::translate("BackupDialog", "schema-only (-s)", nullptr)); @@ -235,9 +266,9 @@ void BackupDialog::retranslateUi() oids->setText(QApplication::translate("BackupDialog", "Oids (-o)", nullptr)); noAcl->setText(QApplication::translate("BackupDialog", "No privileges/acl (-x)", nullptr)); btnStart->setText(QApplication::translate("BackupDialog", "START", nullptr)); - tabWidget->setTabText(tabWidget->indexOf(tab), QApplication::translate("BackupDialog", "Tab 1", nullptr)); - stdOutput->setPlainText(QApplication::translate("BackupDialog", "Test text.", nullptr)); - tabWidget->setTabText(tabWidget->indexOf(tab_2), QApplication::translate("BackupDialog", "Tab 2", nullptr)); + btnBack->setText(QApplication::translate("BackupDialog", "Back", nullptr)); + btnClose->setText(QApplication::translate("BackupDialog", "Close", nullptr)); + } // retranslateUi void BackupDialog::setConfig(const ConnectionConfig &cfg) @@ -254,47 +285,58 @@ void BackupDialog::ConnectTo(QProcess *process) process->setProcessChannelMode(QProcess::MergedChannels); process->setReadChannel(QProcess::StandardOutput); - connect(process, SIGNAL(readyRead()), this, SLOT(on_process_readyRead())); + connect(process, SIGNAL(readyRead()), this, SLOT(process_readyRead())); connect(process, SIGNAL(errorOccurred(QProcess::ProcessError)), this, - SLOT(on_process_errorOccurred(QProcess::ProcessError))); + SLOT(process_errorOccurred(QProcess::ProcessError))); connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, - SLOT(on_process_finished(int, QProcess::ExitStatus))); + SLOT(process_finished(int, QProcess::ExitStatus))); } } void BackupDialog::disconnectCurrentProcess() { if (m_process) { - disconnect(m_process, SIGNAL(readyRead()), this, SLOT(on_process_readyRead())); + disconnect(m_process, SIGNAL(readyRead()), this, SLOT(process_readyRead())); disconnect(m_process, SIGNAL(errorOccurred(QProcess::ProcessError)), this, - SLOT(on_process_errorOccurred(QProcess::ProcessError))); + SLOT(process_errorOccurred(QProcess::ProcessError))); disconnect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, - SLOT(on_process_finished(int, QProcess::ExitStatus))); + SLOT(process_finished(int, QProcess::ExitStatus))); m_process = nullptr; } } -void BackupDialog::writeOutput(const QString &s) +void BackupDialog::writeOutput(const QString &s, Format f) { - stdOutput->appendPlainText(s); + switch (f) { + case Format::Normal: + stdOutput->appendPlainText(s); + break; + case Format::Error: + stdOutput->appendHtml("" + s.toHtmlEscaped() + ""); + break; + case Format::Success: + stdOutput->appendHtml("" + s.toHtmlEscaped() + ""); + break; + } + QScrollBar *bar = stdOutput->verticalScrollBar(); bar->setValue(bar->maximum()); } -void BackupDialog::on_process_readyRead() +void BackupDialog::process_readyRead() { QByteArray data = m_process->readAllStandardOutput(); writeOutput(QString::fromUtf8(data)); } -void BackupDialog::on_process_errorOccurred(QProcess::ProcessError error) +void BackupDialog::process_errorOccurred(QProcess::ProcessError error) { QString msg; switch (error) { case 0: - msg = tr("Failed to start"); + msg = tr("Failed to start. Possibly the executable does not exist or you have insufficient privileges to invoke the program."); break; case 1: msg = tr("Crashed"); @@ -316,16 +358,21 @@ void BackupDialog::on_process_errorOccurred(QProcess::ProcessError error) } - auto res = QMessageBox::critical(this, "pglab", msg, QMessageBox::Close); - if (res == QMessageBox::Yes) { - QApplication::quit(); - } - +// auto res = QMessageBox::critical(this, "pglab", msg, QMessageBox::Close); +// if (res == QMessageBox::Yes) { +// QApplication::quit(); +// } + writeOutput(msg, Format::Error); + btnBack->setEnabled(true); + btnClose->setEnabled(true); } -void BackupDialog::on_process_finished(int exitCode, QProcess::ExitStatus ) +void BackupDialog::process_finished(int exitCode, QProcess::ExitStatus) { - writeOutput(tr("Completed, with exitcode %1\n").arg(exitCode)); + btnBack->setEnabled(true); + btnClose->setEnabled(true); + QString msg = tr("Completed, with exitcode %1\n").arg(exitCode); + writeOutput(msg, exitCode == 0 ? Format::Success : Format::Error); } void BackupDialog::setParams(QStringList &args) @@ -385,9 +432,31 @@ void BackupDialog::setParams(QStringList &args) void BackupDialog::on_btnStart_clicked() { stdOutput->clear(); + btnBack->setEnabled(false); + btnClose->setEnabled(false); + viewStack->setCurrentWidget(progressView); + QSettings user_settings; // Default constructor is for UserScope + QVariant var = user_settings.value("pg_tools_path", {}); + QDir dir; + if (var.type() == QMetaType::QString) { + dir.setPath(var.toString()); + } + if (!dir.exists() || !dir.exists("pg_dump.exe")) { + QString result = QInputDialog::getText(this, tr("Postgres tools location"), tr("Please specify the folder that contains the postgresql tools executables")); + if (!result.isEmpty()) { + QDir d(result); + if (d.exists() && d.exists("pg_dump.exe")) { + user_settings.setValue("pg_tools_path", result); + dir = d; + } + else { + return; + } + } + } //QString program = R"-(C:\Prog\bigsql\pg96\bin\pg_dump.exe)-"; - QString program = "C:/Prog/bigsql/pg11/bin/pg_dump.exe"; + QString program = dir.path() + "/pg_dump.exe"; QStringList arguments; setParams(arguments); @@ -442,3 +511,7 @@ void BackupDialog::on_selectDestination_clicked() } } +void BackupDialog::on_btnBack_clicked() +{ + viewStack->setCurrentWidget(optionsView); +} diff --git a/pglab/BackupDialog.h b/pglab/BackupDialog.h index c0ccc9b..104a296 100644 --- a/pglab/BackupDialog.h +++ b/pglab/BackupDialog.h @@ -2,6 +2,7 @@ #define BACKUPDIALOG_H #include +#include #include "ConnectionConfig.h" #include @@ -18,6 +19,7 @@ class QCheckBox; class QPlainTextEdit; class QLineEdit; class QFormLayout; +class QStackedLayout; class BackupDialog : public QDialog @@ -38,18 +40,21 @@ private: QProcess *m_process = nullptr; ConnectionConfig m_config; - QPushButton *btnStart; - QTabWidget *tabWidget; - QWidget *tab; - QVBoxLayout *verticalLayout; - QFormLayout *formLayout; - QWidget *widget; - QHBoxLayout *horizontalLayout; + QLabel *labelFileName; QLineEdit *editFilename; QPushButton *selectDestination; + QHBoxLayout *layoutDestination; + QWidget *widgetDestination; + + QPushButton *btnStart; + QWidget *optionsView; + + QLabel *labelFormat; QComboBox *backupFormat; + QLabel *labelJobs; QSpinBox *jobs; QCheckBox *chkbxVerbose; + QLabel *labelCompression; QSpinBox *compression; QCheckBox *chkbxIncludeBlobs; QCheckBox *chkbxClean; @@ -58,27 +63,32 @@ private: QCheckBox *oids; QComboBox *what; QCheckBox *noAcl; - QWidget *tab_2; - QVBoxLayout *verticalLayout_2; + QWidget *progressView; QPlainTextEdit *stdOutput; - QLabel *label; - QLabel *label_2; - QLabel *label_3; - QLabel *label_4; - QLabel *label_5; + QTextCharFormat m_OutputOkFormat; + QTextCharFormat m_OutputErrorFormat; + QLabel *labelDataOrSchema; - void writeOutput(const QString &s); + QPushButton *btnBack; + QPushButton *btnClose; + QStackedLayout *viewStack; + + enum class Format { + Normal, Success, Error + }; + void writeOutput(const QString &s, Format f = Format::Normal); void setParams(QStringList &args); private slots: - void on_process_readyRead(); - void on_process_errorOccurred(QProcess::ProcessError error); - void on_process_finished(int exitCode, QProcess::ExitStatus exitStatus); + void process_readyRead(); + void process_errorOccurred(QProcess::ProcessError error); + void process_finished(int exitCode, QProcess::ExitStatus exitStatus); void on_btnStart_clicked(); void on_backupFormat_currentIndexChanged(int index); void on_selectDestination_clicked(); + void on_btnBack_clicked(); }; #endif // BACKUPDIALOG_H diff --git a/pglab/PgDumpOutputHighlighter.cpp b/pglab/PgDumpOutputHighlighter.cpp new file mode 100644 index 0000000..3ef2cfe --- /dev/null +++ b/pglab/PgDumpOutputHighlighter.cpp @@ -0,0 +1,19 @@ +#include "PgDumpOutputHighlighter.h" + +PgDumpOutputHighlighter::PgDumpOutputHighlighter(QTextDocument *parent) + : QSyntaxHighlighter(parent) +{ + m_errorFormat.setForeground(QColor(255, 128, 128)); + m_errorFormat.setFontWeight(QFont::Bold); +} + +PgDumpOutputHighlighter::~PgDumpOutputHighlighter() +{ + +} + +void PgDumpOutputHighlighter::highlightBlock(const QString &text) +{ + if (text.startsWith("pg_dump: error")) + setFormat(0, text.length(), m_errorFormat); +} diff --git a/pglab/PgDumpOutputHighlighter.h b/pglab/PgDumpOutputHighlighter.h new file mode 100644 index 0000000..43f4f82 --- /dev/null +++ b/pglab/PgDumpOutputHighlighter.h @@ -0,0 +1,20 @@ +#ifndef PGDUMPOUTPUTHIGHLIGHTER_H +#define PGDUMPOUTPUTHIGHLIGHTER_H + +#include +#include + +class PgDumpOutputHighlighter : public QSyntaxHighlighter +{ + Q_OBJECT +public: + PgDumpOutputHighlighter(QTextDocument *parent = nullptr); + ~PgDumpOutputHighlighter() override; +protected: + void highlightBlock(const QString &text) override; + +private: + QTextCharFormat m_errorFormat; +}; + +#endif // PGDUMPOUTPUTHIGHLIGHTER_H diff --git a/pglab/SqlSyntaxHighlighter.h b/pglab/SqlSyntaxHighlighter.h index 32a9767..379ff00 100644 --- a/pglab/SqlSyntaxHighlighter.h +++ b/pglab/SqlSyntaxHighlighter.h @@ -14,7 +14,7 @@ class SqlSyntaxHighlighter : public QSyntaxHighlighter public: SqlSyntaxHighlighter(QTextDocument *parent = nullptr); - ~SqlSyntaxHighlighter(); + ~SqlSyntaxHighlighter() override; void setTypes(const PgTypeContainer& types); protected: diff --git a/pglab/pglab.pro b/pglab/pglab.pro index da4670f..3d0e3f9 100644 --- a/pglab/pglab.pro +++ b/pglab/pglab.pro @@ -24,6 +24,7 @@ SOURCES += main.cpp\ NotificationListWidget.cpp \ NotificationModel.cpp \ NotificationService.cpp \ + PgDumpOutputHighlighter.cpp \ QueryResultModel.cpp \ QueryExplainModel.cpp \ CreateDatabaseDialog.cpp \ @@ -88,6 +89,7 @@ HEADERS += \ NotificationListWidget.h \ NotificationModel.h \ NotificationService.h \ + PgDumpOutputHighlighter.h \ QueryResultModel.h \ QueryExplainModel.h \ CreateDatabaseDialog.h \