Improved backup dialog

This commit is contained in:
Eelke Klein 2019-07-13 08:45:32 +02:00
parent e7bfaeff9a
commit b5cb8a271f
6 changed files with 309 additions and 407 deletions

View file

@ -1,5 +1,4 @@
#include "BackupDialog.h"
#include "ui_BackupDialog.h"
#include "BackupFormatModel.h"
@ -9,25 +8,238 @@
#include <QScrollBar>
#include <QStandardPaths>
#include <QApplication>
#include <QCheckBox>
#include <QComboBox>
#include <QDialog>
#include <QFormLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QSpinBox>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QWidget>
#ifdef WIN32
# include <windows.h> // for CreateProcess flags
#endif
BackupDialog::BackupDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::BackupDialog)
QPlainTextEdit* createStdOutput(QWidget *parent)
{
ui->setupUi(this);
auto stdOutput = new QPlainTextEdit(parent);
stdOutput->setObjectName(QString::fromUtf8("stdOutput"));
QPalette palette;
QBrush brush(QColor(255, 255, 255, 255));
brush.setStyle(Qt::SolidPattern);
palette.setBrush(QPalette::Active, QPalette::Text, brush);
QBrush brush1(QColor(0, 0, 0, 255));
brush1.setStyle(Qt::SolidPattern);
palette.setBrush(QPalette::Active, QPalette::Base, brush1);
palette.setBrush(QPalette::Inactive, QPalette::Text, brush);
palette.setBrush(QPalette::Inactive, QPalette::Base, brush1);
QBrush brush2(QColor(120, 120, 120, 255));
brush2.setStyle(Qt::SolidPattern);
palette.setBrush(QPalette::Disabled, QPalette::Text, brush2);
QBrush brush3(QColor(240, 240, 240, 255));
brush3.setStyle(Qt::SolidPattern);
palette.setBrush(QPalette::Disabled, QPalette::Base, brush3);
stdOutput->setPalette(palette);
QFont font;
font.setFamily(QString::fromUtf8("Source Code Pro"));
font.setPointSize(10);
stdOutput->setFont(font);
stdOutput->setLineWrapMode(QPlainTextEdit::NoWrap);
stdOutput->setReadOnly(true);
return stdOutput;
}
BackupDialog::BackupDialog(QWidget *parent)
: QDialog(parent)
{
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);
editFilename->setObjectName(QString::fromUtf8("editFilename"));
horizontalLayout->addWidget(editFilename);
selectDestination = new QPushButton(widget);
selectDestination->setObjectName(QString::fromUtf8("selectDestination"));
horizontalLayout->addWidget(selectDestination);
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);
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->setObjectName(QString::fromUtf8("jobs"));
formLayout->setWidget(2, QFormLayout::FieldRole, jobs);
chkbxVerbose = new QCheckBox(tab);
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->setObjectName(QString::fromUtf8("compression"));
compression->setMinimum(-1);
compression->setMaximum(9);
compression->setValue(-1);
formLayout->setWidget(4, QFormLayout::FieldRole, compression);
chkbxIncludeBlobs = new QCheckBox(tab);
chkbxIncludeBlobs->setObjectName(QString::fromUtf8("chkbxIncludeBlobs"));
formLayout->setWidget(6, QFormLayout::FieldRole, chkbxIncludeBlobs);
chkbxClean = new QCheckBox(tab);
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);
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);
noAcl->setObjectName(QString::fromUtf8("noAcl"));
formLayout->setWidget(11, QFormLayout::FieldRole, noAcl);
verticalLayout->addLayout(formLayout);
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"));
stdOutput = createStdOutput(this);
verticalLayout_2->addWidget(stdOutput);
tabWidget->addTab(tab_2, QString());
tabWidget->setCurrentIndex(0);
QMetaObject::connectSlotsByName(this);
auto format_model = new BackupFormatModel(this);
ui->backupFormat->setModel(format_model);
backupFormat->setModel(format_model);
retranslateUi();
}
BackupDialog::~BackupDialog()
{
delete ui;
}
void BackupDialog::retranslateUi()
{
setWindowTitle(QApplication::translate("BackupDialog", "Dialog", nullptr));
label->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));
chkbxVerbose->setText(QApplication::translate("BackupDialog", "Verbose (-v)", nullptr));
label_5->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));
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));
chkbxIncludeBlobs->setText(QApplication::translate("BackupDialog", "Include blobs (-b)", nullptr));
chkbxClean->setText(QApplication::translate("BackupDialog", "Clean (-c)", nullptr));
chkbxCreate->setText(QApplication::translate("BackupDialog", "Create (-C)", nullptr));
noOwner->setText(QApplication::translate("BackupDialog", "No owner (-O)", nullptr));
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));
} // retranslateUi
void BackupDialog::setConfig(const ConnectionConfig &cfg)
{
m_config = cfg;
@ -66,8 +278,8 @@ void BackupDialog::disconnectCurrentProcess()
void BackupDialog::writeOutput(const QString &s)
{
ui->stdOutput->appendPlainText(s);
QScrollBar *bar = ui->stdOutput->verticalScrollBar();
stdOutput->appendPlainText(s);
QScrollBar *bar = stdOutput->verticalScrollBar();
bar->setValue(bar->maximum());
}
@ -119,15 +331,15 @@ void BackupDialog::on_process_finished(int exitCode, QProcess::ExitStatus )
void BackupDialog::setParams(QStringList &args)
{
QString short_args("-");
if (ui->chkbxVerbose->checkState() == Qt::Checked)
if (chkbxVerbose->checkState() == Qt::Checked)
short_args += "v";
if (ui->chkbxClean->checkState() == Qt::Checked)
if (chkbxClean->checkState() == Qt::Checked)
short_args += "c";
if (ui->chkbxCreate->checkState() == Qt::Checked)
if (chkbxCreate->checkState() == Qt::Checked)
short_args += "C";
if (ui->chkbxIncludeBlobs->checkState() == Qt::Checked)
if (chkbxIncludeBlobs->checkState() == Qt::Checked)
short_args += "b";
switch (ui->what->currentIndex()) {
switch (what->currentIndex()) {
case 1:
short_args += "a";
break;
@ -135,24 +347,24 @@ void BackupDialog::setParams(QStringList &args)
short_args += "s";
break;
}
if (ui->oids->checkState() == Qt::Checked)
if (oids->checkState() == Qt::Checked)
short_args += "o";
if (ui->noAcl->checkState() == Qt::Checked)
if (noAcl->checkState() == Qt::Checked)
short_args += "x";
if (short_args.length() > 1) // larger then one because always includes '-'
args << short_args;
// Todo check path exists and name is valid?
QFileInfo fi(QDir::fromNativeSeparators(ui->editFilename->text()));
QFileInfo fi(QDir::fromNativeSeparators(editFilename->text()));
QDir dir(fi.absolutePath());
if (!dir.exists())
dir.mkdir(fi.absolutePath());
args << "-f" << ui->editFilename->text(); // R"-(c:\temp\backup.sql)-";
args << "-f" << editFilename->text(); // R"-(c:\temp\backup.sql)-";
int format_index = ui->backupFormat->currentIndex();
auto format_model_base = ui->backupFormat->model();
int format_index = backupFormat->currentIndex();
auto format_model_base = backupFormat->model();
auto *bfm = dynamic_cast<BackupFormatModel *>(format_model_base);
if (bfm) {
QVariant v = bfm->data(bfm->index(format_index, 1));
@ -161,73 +373,24 @@ void BackupDialog::setParams(QStringList &args)
args << format;
}
int jobs = ui->jobs->value();
if (jobs > 0)
args << "-j" << QString::number(jobs);
int j = jobs->value();
if (j > 0)
args << "-j" << QString::number(j);
int compression = ui->compression->value();
if (compression >= 0)
args << "-Z" << QString::number(compression);
int comp = compression->value();
if (comp >= 0)
args << "-Z" << QString::number(comp);
}
void BackupDialog::on_btnStart_clicked()
{
ui->stdOutput->clear();
stdOutput->clear();
//QString program = R"-(C:\Prog\bigsql\pg96\bin\pg_dump.exe)-";
QString program = "/usr/bin/pg_dump";
QString program = "C:/Prog/bigsql/pg11/bin/pg_dump.exe";
QStringList arguments;
setParams(arguments);
// BOOL res = AllocConsole();
// if (!res) {
// DWORD error = GetLastError();
// QMessageBox::critical(this, "pglab", tr("AllocConsole failed %1").arg(error), QMessageBox::Close);
// }
// HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
// DWORD written;
// res = WriteConsoleOutputCharacter(out, L"Hello, world!\n", 14, {0, 0}, &written);
// PROCESS_INFORMATION proc_info;
// STARTUPINFO startup_info;
// memset(&startup_info, 0, sizeof(startup_info));
// startup_info.cb = sizeof(startup_info);
// startup_info.lpReserved;
// startup_info.lpDesktop;
// startup_info.lpTitle;
// startup_info.dwX;
// startup_info.dwY;
// startup_info.dwXSize;
// startup_info.dwYSize;
// startup_info.dwXCountChars;
// startup_info.dwYCountChars;
// startup_info.dwFillAttribute;
// startup_info.dwFlags = STARTF_USESTDHANDLES;
// startup_info.wShowWindow;
// startup_info.cbReserved2;
// startup_info.lpReserved2;
// startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
// startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
// startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
// res = CreateProcess(
// LR"_(C:\Prog\build-conoutputtest-Desktop_Qt_5_8_0_MSVC2015_32bit2-Debug\debug\conoutputtest.exe)_",
// NULL, // _Inout_opt_ LPTSTR lpCommandLine,
// NULL, // _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
// NULL, // _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
// TRUE,
// 0, // _In_ DWORD dwCreationFlags,
// NULL, // _In_opt_ LPVOID lpEnvironment,
// NULL, // _In_opt_ LPCTSTR lpCurrentDirectory,
// &startup_info, // _In_ LPSTARTUPINFO lpStartupInfo,
// &proc_info // _Out_ LPPROCESS_INFORMATION lpProcessInformation
// );
// QString program = R"_(C:\prog\build-conoutputtest-Desktop_Qt_5_8_0_MSVC2015_32bit2-Debug\debug\conoutputtest.exe)_";
// QStringList arguments;
// arguments << "/C" << "DIR /S c:\\";
// Database connection paramters are passed through the environment as this is far less visible to others. Commandline
// parameters can often be viewed even if the user is not the owner of the process.
// We use the systemEnvironment as a sane default. Then we let the connection overwrite all PG variables in it.
@ -238,34 +401,34 @@ void BackupDialog::on_btnStart_clicked()
ConnectTo(p);
p->setProcessEnvironment(env);
#ifdef WIN32
p->setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)
{
args->flags |= CREATE_NEW_CONSOLE;
args->flags &= ~DETACHED_PROCESS;
args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES;
});
// p->setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)
// {
// args->flags |= CREATE_NEW_CONSOLE;
// args->flags &= ~DETACHED_PROCESS;
// args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES;
// });
#endif
p->start(program, arguments);
}
void BackupDialog::on_backupFormat_currentIndexChanged(int /*index*/)
{
int format_index = ui->backupFormat->currentIndex();
auto format_model_base = ui->backupFormat->model();
int format_index = backupFormat->currentIndex();
auto format_model_base = backupFormat->model();
auto *bfm = dynamic_cast<BackupFormatModel *>(format_model_base);
if (bfm) {
QVariant v = bfm->data(bfm->index(format_index, 1));
QString format = v.toString();
bool comp_enable = (format == "c" || format == "d");
ui->compression->setEnabled(comp_enable);
compression->setEnabled(comp_enable);
if (!comp_enable)
ui->compression->setValue(-1);
compression->setValue(-1);
bool jobs_enable = (format == "d");
ui->jobs->setEnabled(jobs_enable);
jobs->setEnabled(jobs_enable);
if (!jobs_enable)
ui->jobs->setValue(0);
jobs->setValue(0);
}
}
@ -275,7 +438,7 @@ void BackupDialog::on_selectDestination_clicked()
QString fn = QFileDialog::getSaveFileName(this, tr("Save backup"), home_dir,
tr("Backup file (*.backup)"));
if (!fn.isEmpty()) {
ui->editFilename->setText(QDir::toNativeSeparators(fn));
editFilename->setText(QDir::toNativeSeparators(fn));
}
}