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.
This commit is contained in:
eelke 2019-08-23 09:43:48 +02:00
parent 221cc33bb4
commit 1792f42dac
6 changed files with 274 additions and 150 deletions

View file

@ -1,7 +1,7 @@
#include "BackupDialog.h" #include "BackupDialog.h"
#include "BackupFormatModel.h" #include "BackupFormatModel.h"
#include "PgDumpOutputHighlighter.h"
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>
#include <QProcess> #include <QProcess>
@ -14,11 +14,14 @@
#include <QDialog> #include <QDialog>
#include <QFormLayout> #include <QFormLayout>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QInputDialog>
#include <QLabel> #include <QLabel>
#include <QLineEdit> #include <QLineEdit>
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QPushButton> #include <QPushButton>
#include <QSettings>
#include <QSpinBox> #include <QSpinBox>
#include <QStackedLayout>
#include <QTabWidget> #include <QTabWidget>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QWidget> #include <QWidget>
@ -54,151 +57,179 @@ QPlainTextEdit* createStdOutput(QWidget *parent)
stdOutput->setFont(font); stdOutput->setFont(font);
stdOutput->setLineWrapMode(QPlainTextEdit::NoWrap); stdOutput->setLineWrapMode(QPlainTextEdit::NoWrap);
stdOutput->setReadOnly(true); stdOutput->setReadOnly(true);
new PgDumpOutputHighlighter(stdOutput->document());
return stdOutput; return stdOutput;
} }
BackupDialog::BackupDialog(QWidget *parent) BackupDialog::BackupDialog(QWidget *parent)
: QDialog(parent) : QDialog(parent)
{ {
// Options tab contents
// Filename
labelFileName = new QLabel(this);
labelFileName->setObjectName(QString::fromUtf8("labelFileName"));
btnStart = new QPushButton(this); // Filename edit+button
btnStart->setObjectName(QString::fromUtf8("btnStart")); editFilename = new QLineEdit(this);
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);
editFilename->setObjectName(QString::fromUtf8("editFilename")); editFilename->setObjectName(QString::fromUtf8("editFilename"));
horizontalLayout->addWidget(editFilename); selectDestination = new QPushButton;
selectDestination = new QPushButton(widget);
selectDestination->setObjectName(QString::fromUtf8("selectDestination")); 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); // Backup format
labelFormat = new QLabel;
label_2 = new QLabel(tab); labelFormat->setObjectName(QString::fromUtf8("labelFormat"));
label_2->setObjectName(QString::fromUtf8("label_2")); backupFormat = new QComboBox;
formLayout->setWidget(1, QFormLayout::LabelRole, label_2);
backupFormat = new QComboBox(tab);
backupFormat->setObjectName(QString::fromUtf8("backupFormat")); backupFormat->setObjectName(QString::fromUtf8("backupFormat"));
backupFormat->setModelColumn(0); backupFormat->setModelColumn(0);
formLayout->setWidget(1, QFormLayout::FieldRole, backupFormat); // Jobs
labelJobs = new QLabel;
label_3 = new QLabel(tab); labelJobs->setObjectName(QString::fromUtf8("labelJobs"));
label_3->setObjectName(QString::fromUtf8("label_3")); jobs = new QSpinBox;
formLayout->setWidget(2, QFormLayout::LabelRole, label_3);
jobs = new QSpinBox(tab);
jobs->setObjectName(QString::fromUtf8("jobs")); jobs->setObjectName(QString::fromUtf8("jobs"));
formLayout->setWidget(2, QFormLayout::FieldRole, jobs); // Verbose
chkbxVerbose = new QCheckBox;
chkbxVerbose = new QCheckBox(tab);
chkbxVerbose->setObjectName(QString::fromUtf8("chkbxVerbose")); chkbxVerbose->setObjectName(QString::fromUtf8("chkbxVerbose"));
formLayout->setWidget(3, QFormLayout::FieldRole, chkbxVerbose); // Compression
labelCompression = new QLabel;
label_5 = new QLabel(tab); labelCompression->setObjectName(QString::fromUtf8("labelCompression"));
label_5->setObjectName(QString::fromUtf8("label_5")); compression = new QSpinBox;
formLayout->setWidget(4, QFormLayout::LabelRole, label_5);
compression = new QSpinBox(tab);
compression->setObjectName(QString::fromUtf8("compression")); compression->setObjectName(QString::fromUtf8("compression"));
compression->setMinimum(-1); compression->setMinimum(-1);
compression->setMaximum(9); compression->setMaximum(9);
compression->setValue(-1); compression->setValue(-1);
formLayout->setWidget(4, QFormLayout::FieldRole, compression); // Include BLOBs
chkbxIncludeBlobs = new QCheckBox(this);
chkbxIncludeBlobs = new QCheckBox(tab);
chkbxIncludeBlobs->setObjectName(QString::fromUtf8("chkbxIncludeBlobs")); chkbxIncludeBlobs->setObjectName(QString::fromUtf8("chkbxIncludeBlobs"));
formLayout->setWidget(6, QFormLayout::FieldRole, chkbxIncludeBlobs); // Clean
chkbxClean = new QCheckBox(this);
chkbxClean = new QCheckBox(tab);
chkbxClean->setObjectName(QString::fromUtf8("chkbxClean")); chkbxClean->setObjectName(QString::fromUtf8("chkbxClean"));
formLayout->setWidget(7, QFormLayout::FieldRole, chkbxClean); // Data and/or Schema
labelDataOrSchema = new QLabel(this);
chkbxCreate = new QCheckBox(tab); labelDataOrSchema->setObjectName(QString::fromUtf8("labelDataOrSchema"));
chkbxCreate->setObjectName(QString::fromUtf8("chkbxCreate")); what = new QComboBox(this);
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);
what->addItem(QString()); what->addItem(QString());
what->addItem(QString()); what->addItem(QString());
what->addItem(QString()); what->addItem(QString());
what->setObjectName(QString::fromUtf8("what")); what->setObjectName(QString::fromUtf8("what"));
// create
formLayout->setWidget(5, QFormLayout::FieldRole, what); chkbxCreate = new QCheckBox(this);
chkbxCreate->setObjectName(QString::fromUtf8("chkbxCreate"));
label_4 = new QLabel(tab); // owner
label_4->setObjectName(QString::fromUtf8("label_4")); noOwner = new QCheckBox(this);
noOwner->setObjectName(QString::fromUtf8("noOwner"));
formLayout->setWidget(5, QFormLayout::LabelRole, label_4); // with oids
oids = new QCheckBox(this);
noAcl = new QCheckBox(tab); oids->setObjectName(QString::fromUtf8("oids"));
// without acl (permissions)
noAcl = new QCheckBox(this);
noAcl->setObjectName(QString::fromUtf8("noAcl")); 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->addLayout(formLayout);
verticalLayout->addWidget(btnStart);
tabWidget->addTab(tab, QString()); optionsView = new QWidget();
tab_2 = new QWidget(); optionsView->setObjectName(QString::fromUtf8("tabOptions"));
tab_2->setObjectName(QString::fromUtf8("tab_2")); optionsView->setLayout(verticalLayout);
verticalLayout_2 = new QVBoxLayout(tab_2);
verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
// Progress tab
stdOutput = createStdOutput(this); 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); QMetaObject::connectSlotsByName(this);
connect(btnClose, &QPushButton::clicked, this, &QDialog::close);
auto format_model = new BackupFormatModel(this); auto format_model = new BackupFormatModel(this);
backupFormat->setModel(format_model); backupFormat->setModel(format_model);
@ -213,17 +244,17 @@ BackupDialog::~BackupDialog()
void BackupDialog::retranslateUi() void BackupDialog::retranslateUi()
{ {
setWindowTitle(QApplication::translate("BackupDialog", "Dialog", nullptr)); setWindowTitle(QApplication::translate("BackupDialog", "Backup database", nullptr));
label->setText(QApplication::translate("BackupDialog", "Filename", nullptr)); labelFileName->setText(QApplication::translate("BackupDialog", "Filename", nullptr));
selectDestination->setText(QApplication::translate("BackupDialog", "...", nullptr)); selectDestination->setText(QApplication::translate("BackupDialog", "...", nullptr));
label_2->setText(QApplication::translate("BackupDialog", "Format", nullptr)); labelFormat->setText(QApplication::translate("BackupDialog", "Format", nullptr));
label_3->setText(QApplication::translate("BackupDialog", "Jobs:", nullptr)); labelJobs->setText(QApplication::translate("BackupDialog", "Jobs:", nullptr));
chkbxVerbose->setText(QApplication::translate("BackupDialog", "Verbose (-v)", 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 #ifndef QT_NO_TOOLTIP
compression->setToolTip(QApplication::translate("BackupDialog", "-1 means default, 0-9 is no compression to max compression", nullptr)); compression->setToolTip(QApplication::translate("BackupDialog", "-1 means default, 0-9 is no compression to max compression", nullptr));
#endif // QT_NO_TOOLTIP #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(0, QApplication::translate("BackupDialog", "data + schema", nullptr));
what->setItemText(1, QApplication::translate("BackupDialog", "data only (-a)", nullptr)); what->setItemText(1, QApplication::translate("BackupDialog", "data only (-a)", nullptr));
what->setItemText(2, QApplication::translate("BackupDialog", "schema-only (-s)", 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)); oids->setText(QApplication::translate("BackupDialog", "Oids (-o)", nullptr));
noAcl->setText(QApplication::translate("BackupDialog", "No privileges/acl (-x)", nullptr)); noAcl->setText(QApplication::translate("BackupDialog", "No privileges/acl (-x)", nullptr));
btnStart->setText(QApplication::translate("BackupDialog", "START", nullptr)); btnStart->setText(QApplication::translate("BackupDialog", "START", nullptr));
tabWidget->setTabText(tabWidget->indexOf(tab), QApplication::translate("BackupDialog", "Tab 1", nullptr)); btnBack->setText(QApplication::translate("BackupDialog", "Back", nullptr));
stdOutput->setPlainText(QApplication::translate("BackupDialog", "Test text.", nullptr)); btnClose->setText(QApplication::translate("BackupDialog", "Close", nullptr));
tabWidget->setTabText(tabWidget->indexOf(tab_2), QApplication::translate("BackupDialog", "Tab 2", nullptr));
} // retranslateUi } // retranslateUi
void BackupDialog::setConfig(const ConnectionConfig &cfg) void BackupDialog::setConfig(const ConnectionConfig &cfg)
@ -254,47 +285,58 @@ void BackupDialog::ConnectTo(QProcess *process)
process->setProcessChannelMode(QProcess::MergedChannels); process->setProcessChannelMode(QProcess::MergedChannels);
process->setReadChannel(QProcess::StandardOutput); 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, 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, connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this,
SLOT(on_process_finished(int, QProcess::ExitStatus))); SLOT(process_finished(int, QProcess::ExitStatus)));
} }
} }
void BackupDialog::disconnectCurrentProcess() void BackupDialog::disconnectCurrentProcess()
{ {
if (m_process) { 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, 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, 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; 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("<span style='background-color: maroon; color: white; font-weight: bold'>" + s.toHtmlEscaped() + "</span>");
break;
case Format::Success:
stdOutput->appendHtml("<span style='background-color: green; color: white; font-weight: bold'>" + s.toHtmlEscaped() + "</span>");
break;
}
QScrollBar *bar = stdOutput->verticalScrollBar(); QScrollBar *bar = stdOutput->verticalScrollBar();
bar->setValue(bar->maximum()); bar->setValue(bar->maximum());
} }
void BackupDialog::on_process_readyRead() void BackupDialog::process_readyRead()
{ {
QByteArray data = m_process->readAllStandardOutput(); QByteArray data = m_process->readAllStandardOutput();
writeOutput(QString::fromUtf8(data)); writeOutput(QString::fromUtf8(data));
} }
void BackupDialog::on_process_errorOccurred(QProcess::ProcessError error) void BackupDialog::process_errorOccurred(QProcess::ProcessError error)
{ {
QString msg; QString msg;
switch (error) { switch (error) {
case 0: 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; break;
case 1: case 1:
msg = tr("Crashed"); msg = tr("Crashed");
@ -316,16 +358,21 @@ void BackupDialog::on_process_errorOccurred(QProcess::ProcessError error)
} }
auto res = QMessageBox::critical(this, "pglab", msg, QMessageBox::Close); // auto res = QMessageBox::critical(this, "pglab", msg, QMessageBox::Close);
if (res == QMessageBox::Yes) { // if (res == QMessageBox::Yes) {
QApplication::quit(); // 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) void BackupDialog::setParams(QStringList &args)
@ -385,9 +432,31 @@ void BackupDialog::setParams(QStringList &args)
void BackupDialog::on_btnStart_clicked() void BackupDialog::on_btnStart_clicked()
{ {
stdOutput->clear(); 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 = 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; QStringList arguments;
setParams(arguments); setParams(arguments);
@ -442,3 +511,7 @@ void BackupDialog::on_selectDestination_clicked()
} }
} }
void BackupDialog::on_btnBack_clicked()
{
viewStack->setCurrentWidget(optionsView);
}

View file

@ -2,6 +2,7 @@
#define BACKUPDIALOG_H #define BACKUPDIALOG_H
#include <QDialog> #include <QDialog>
#include <QTextCharFormat>
#include "ConnectionConfig.h" #include "ConnectionConfig.h"
#include <QProcess> #include <QProcess>
@ -18,6 +19,7 @@ class QCheckBox;
class QPlainTextEdit; class QPlainTextEdit;
class QLineEdit; class QLineEdit;
class QFormLayout; class QFormLayout;
class QStackedLayout;
class BackupDialog : public QDialog class BackupDialog : public QDialog
@ -38,18 +40,21 @@ private:
QProcess *m_process = nullptr; QProcess *m_process = nullptr;
ConnectionConfig m_config; ConnectionConfig m_config;
QPushButton *btnStart; QLabel *labelFileName;
QTabWidget *tabWidget;
QWidget *tab;
QVBoxLayout *verticalLayout;
QFormLayout *formLayout;
QWidget *widget;
QHBoxLayout *horizontalLayout;
QLineEdit *editFilename; QLineEdit *editFilename;
QPushButton *selectDestination; QPushButton *selectDestination;
QHBoxLayout *layoutDestination;
QWidget *widgetDestination;
QPushButton *btnStart;
QWidget *optionsView;
QLabel *labelFormat;
QComboBox *backupFormat; QComboBox *backupFormat;
QLabel *labelJobs;
QSpinBox *jobs; QSpinBox *jobs;
QCheckBox *chkbxVerbose; QCheckBox *chkbxVerbose;
QLabel *labelCompression;
QSpinBox *compression; QSpinBox *compression;
QCheckBox *chkbxIncludeBlobs; QCheckBox *chkbxIncludeBlobs;
QCheckBox *chkbxClean; QCheckBox *chkbxClean;
@ -58,27 +63,32 @@ private:
QCheckBox *oids; QCheckBox *oids;
QComboBox *what; QComboBox *what;
QCheckBox *noAcl; QCheckBox *noAcl;
QWidget *tab_2; QWidget *progressView;
QVBoxLayout *verticalLayout_2;
QPlainTextEdit *stdOutput; QPlainTextEdit *stdOutput;
QLabel *label; QTextCharFormat m_OutputOkFormat;
QLabel *label_2; QTextCharFormat m_OutputErrorFormat;
QLabel *label_3;
QLabel *label_4;
QLabel *label_5;
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); void setParams(QStringList &args);
private slots: private slots:
void on_process_readyRead(); void process_readyRead();
void on_process_errorOccurred(QProcess::ProcessError error); void process_errorOccurred(QProcess::ProcessError error);
void on_process_finished(int exitCode, QProcess::ExitStatus exitStatus); void process_finished(int exitCode, QProcess::ExitStatus exitStatus);
void on_btnStart_clicked(); void on_btnStart_clicked();
void on_backupFormat_currentIndexChanged(int index); void on_backupFormat_currentIndexChanged(int index);
void on_selectDestination_clicked(); void on_selectDestination_clicked();
void on_btnBack_clicked();
}; };
#endif // BACKUPDIALOG_H #endif // BACKUPDIALOG_H

View file

@ -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);
}

View file

@ -0,0 +1,20 @@
#ifndef PGDUMPOUTPUTHIGHLIGHTER_H
#define PGDUMPOUTPUTHIGHLIGHTER_H
#include <QSyntaxHighlighter>
#include <QTextFormat>
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

View file

@ -14,7 +14,7 @@ class SqlSyntaxHighlighter : public QSyntaxHighlighter
public: public:
SqlSyntaxHighlighter(QTextDocument *parent = nullptr); SqlSyntaxHighlighter(QTextDocument *parent = nullptr);
~SqlSyntaxHighlighter(); ~SqlSyntaxHighlighter() override;
void setTypes(const PgTypeContainer& types); void setTypes(const PgTypeContainer& types);
protected: protected:

View file

@ -24,6 +24,7 @@ SOURCES += main.cpp\
NotificationListWidget.cpp \ NotificationListWidget.cpp \
NotificationModel.cpp \ NotificationModel.cpp \
NotificationService.cpp \ NotificationService.cpp \
PgDumpOutputHighlighter.cpp \
QueryResultModel.cpp \ QueryResultModel.cpp \
QueryExplainModel.cpp \ QueryExplainModel.cpp \
CreateDatabaseDialog.cpp \ CreateDatabaseDialog.cpp \
@ -88,6 +89,7 @@ HEADERS += \
NotificationListWidget.h \ NotificationListWidget.h \
NotificationModel.h \ NotificationModel.h \
NotificationService.h \ NotificationService.h \
PgDumpOutputHighlighter.h \
QueryResultModel.h \ QueryResultModel.h \
QueryExplainModel.h \ QueryExplainModel.h \
CreateDatabaseDialog.h \ CreateDatabaseDialog.h \