Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+474
@@ -0,0 +1,474 @@
|
||||
#include "ui_QueryUi.h"
|
||||
|
||||
#include "Query.h"
|
||||
#include "QueryThread.h"
|
||||
#include "AddLine.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QCheckBox>
|
||||
#include <QRadioButton>
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#define NEWLINE "\r\n"
|
||||
#else
|
||||
#define NEWLINE "\n"
|
||||
#endif
|
||||
|
||||
Query::Query(//const QString &queryString,
|
||||
QueryWorker *queryWorker,
|
||||
QWidget* parent) // MV[C]
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::Query)
|
||||
, m_model(new DataModel())
|
||||
, m_queryWorker(queryWorker)
|
||||
, m_addLines(nullptr)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
setCustomQuery(); // for safety, disable table sensitive buttons, until table name is set
|
||||
|
||||
qRegisterMetaType<QList<QModelIndex>>("QList<QModelIndex>");
|
||||
|
||||
|
||||
connect(m_ui->pbQueryDelete, &QPushButton::clicked, this, &Query::onQueryDelete);
|
||||
connect(m_ui->pbQueryInsert, &QPushButton::clicked, this, &Query::onQueryInsert);
|
||||
connect(m_ui->pbQueryUpdate, &QPushButton::clicked, this, &Query::onQueryUpdate);
|
||||
|
||||
// NEW ARCH
|
||||
// Delete Lines
|
||||
connect(this, &Query::signalDeleteLines,
|
||||
queryWorker, &QueryWorker::slotDeleteLines); // request => QueryWorker
|
||||
|
||||
connect(queryWorker, &QueryWorker::signalDeleteLinesResult,
|
||||
this, &Query::slotDeleteLinesResult); // reply => this
|
||||
|
||||
|
||||
// Custom Query
|
||||
connect(this, &Query::signalCustomQuery,
|
||||
queryWorker, &QueryWorker::slotCustomQuery);
|
||||
|
||||
connect(queryWorker, &QueryWorker::signalCustomQueryResult,
|
||||
this, &Query::slotCustomQueryResult);
|
||||
|
||||
|
||||
// Table Query
|
||||
connect(this, &Query::signalTableQuery,
|
||||
queryWorker, &QueryWorker::slotTableQuery);
|
||||
|
||||
connect(queryWorker, &QueryWorker::signalTableQueryResult,
|
||||
this, &Query::slotTableQueryResult);
|
||||
|
||||
|
||||
// Add Lines
|
||||
connect(this, &Query::signalAddLines,
|
||||
queryWorker, &QueryWorker::slotAddLines);
|
||||
|
||||
connect(queryWorker, &QueryWorker::signalAddLinesResult,
|
||||
this, &Query::slotAddLinesResult);
|
||||
|
||||
|
||||
// Set Data
|
||||
connect(m_model, &DataModel::signalSetData, // comes from the model ..
|
||||
this, &Query::slotSetData);
|
||||
|
||||
connect(this, &Query::signalSetData,
|
||||
queryWorker, &QueryWorker::slotSetData);
|
||||
|
||||
connect(queryWorker, &QueryWorker::signalSetDataResult, // .. and comes back to THIS ! (query)
|
||||
this, &Query::slotSetDataResult);
|
||||
|
||||
|
||||
connect(m_ui->pbQuery, &QPushButton::clicked, this, &Query::slotCustomQuery);
|
||||
connect(m_ui->pbAddLine, &QPushButton::clicked, this, &Query::slotStartAddLines);
|
||||
connect(m_ui->pbDeleteLine, &QPushButton::clicked, this, &Query::slotDeleteLine);
|
||||
connect(m_ui->pbReload, &QPushButton::clicked, this, &Query::slotTableQuery);
|
||||
connect(m_ui->pbExport, &QPushButton::clicked, this, &Query::slotExportCSV);
|
||||
|
||||
m_ui->dataTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); // TODO: qt4
|
||||
|
||||
setModel();
|
||||
}
|
||||
|
||||
|
||||
Query::~Query()
|
||||
{
|
||||
delete m_ui;
|
||||
delete m_model;
|
||||
}
|
||||
|
||||
|
||||
void Query::slotExportCSV()
|
||||
{
|
||||
//qWarning() << "slotExportCSV";
|
||||
|
||||
QFileDialog dialog(this); // save dialog
|
||||
//dialog.setFileMode(QFileDialog::ExistingFile); // single file selection
|
||||
dialog.setNameFilter(tr("CSV File (*.csv)"));
|
||||
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||
|
||||
QStringList fileNames;
|
||||
if (dialog.exec())
|
||||
fileNames = dialog.selectedFiles();
|
||||
|
||||
if (!fileNames.count())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file;
|
||||
file.setFileName(fileNames.at(0));
|
||||
|
||||
if (!file.open(QFile::ReadWrite))
|
||||
{
|
||||
QMessageBox::critical(this, tr("CSV Export Error"), tr("File '%1' is not accessible!").arg(fileNames.at(0)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// file is open, now save to csv file
|
||||
int colCount = m_model->columnCount();
|
||||
|
||||
// get column names
|
||||
QStringList columnNames;
|
||||
columnNames.reserve(colCount);
|
||||
|
||||
for (int i = 0; i < colCount; i++)
|
||||
{
|
||||
columnNames.append(m_model->headerData(i, Qt::Horizontal).toString());
|
||||
}
|
||||
|
||||
|
||||
// get rows & row values
|
||||
QStringList rows;
|
||||
int rowsCount = m_sortModel.rowCount();
|
||||
rows.reserve(rowsCount);
|
||||
|
||||
QStringList rowData;
|
||||
for (int row = 0; row < rowsCount; row++)
|
||||
{
|
||||
// get row's values
|
||||
rowData.clear();
|
||||
|
||||
for (int col = 0; col < colCount; col++)
|
||||
{
|
||||
rowData.append(m_sortModel.data(m_sortModel.index(row, col)).toString());
|
||||
}
|
||||
|
||||
rows.append(rowData.join(QLatin1Char(',')));
|
||||
}
|
||||
|
||||
|
||||
file.write(columnNames.join(QLatin1Char(',')).toUtf8()); // write header
|
||||
file.write(NEWLINE);
|
||||
|
||||
for (const QString &row : qAsConst(rows))
|
||||
{
|
||||
file.write(row.toUtf8());
|
||||
file.write(NEWLINE);
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
QMessageBox::information(this, tr("CSV Export Success"), tr("CSV Export was successful"));
|
||||
}
|
||||
|
||||
void Query::onQueryDelete()
|
||||
{
|
||||
m_ui->queryText->setText(tr("DELETE FROM %1 WHERE %2").arg(m_model->getTableName(), m_idInWhere ? QStringLiteral("id = ") : QString()));
|
||||
}
|
||||
|
||||
void Query::onQueryInsert()
|
||||
{
|
||||
m_ui->queryText->setText(tr("INSERT INTO %1 (%2) VALUES ()").arg(m_model->getTableName(), checkedColumnsNames().join(QStringLiteral(", "))));
|
||||
}
|
||||
|
||||
void Query::onQueryUpdate()
|
||||
{
|
||||
const QStringList sl = checkedColumnsNames();
|
||||
QStringList sl2;
|
||||
sl2.reserve(sl.size());
|
||||
for (const QString &s : sl)
|
||||
sl2.append(tr("%1 = ").arg(s));
|
||||
m_ui->queryText->setText(tr("UPDATE %1 SET %2 WHERE %3").arg(m_model->getTableName(), sl2.join(QStringLiteral(", ")), m_idInWhere ? QStringLiteral("id = ") : QString()));
|
||||
}
|
||||
|
||||
void Query::handleError(const QString &errorText)
|
||||
{
|
||||
emit signalHideWait();
|
||||
|
||||
if (errorText.isEmpty())
|
||||
return; // nothing to handle
|
||||
|
||||
QMessageBox::critical(this, tr("Error while executing query"),
|
||||
tr("There was an error executing the query:\n%1").arg(errorText));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Delete Lines
|
||||
void Query::slotDeleteLine() // called from UI
|
||||
{
|
||||
int result = QMessageBox::question(this, tr("SqlBrowser"),
|
||||
tr("Do you really want to delete selected data?"),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||
if (result == QMessageBox::No)
|
||||
return;
|
||||
|
||||
emit signalShowWait(QStringLiteral("Deleting line(s).."));
|
||||
|
||||
const QModelIndexList unmapped = m_ui->dataTable->selectionModel()->selectedRows();
|
||||
QModelIndexList mapped;
|
||||
mapped.reserve(unmapped.size());
|
||||
|
||||
for (const auto &idx : unmapped)
|
||||
mapped.append(m_sortModel.mapToSource(idx));
|
||||
|
||||
emit signalDeleteLines(this, mapped, m_model); // => QueryWorker
|
||||
}
|
||||
|
||||
|
||||
void Query::slotDeleteLinesResult(Query* caller, int affectedRowsCount, QString errorText, const QList<QModelIndex> &affectedRowsList) // => from QueryWorker
|
||||
{
|
||||
if (caller != this)
|
||||
return;
|
||||
|
||||
if (errorText.isEmpty() && !affectedRowsCount) // no error but no rows affected?
|
||||
{
|
||||
errorText = tr("The row to be deleted could not be found - This is probably a type-conversion error! Please report that to Mike");
|
||||
}
|
||||
|
||||
handleError(errorText);
|
||||
|
||||
//qWarning() << "Query::slotDeleteLinesResult: errorText = " << errorText << "affectedRowsCount = " << affectedRowsCount;
|
||||
|
||||
if (affectedRowsCount == affectedRowsList.count())
|
||||
{
|
||||
m_model->deleteLines(affectedRowsList); // tell the model to delete that rows (and tell the view about it)
|
||||
}
|
||||
}
|
||||
|
||||
// Custom Query
|
||||
void Query::slotCustomQuery()
|
||||
{
|
||||
emit signalShowWait(QStringLiteral("Executing query.."));
|
||||
emit signalCustomQuery(this, m_ui->queryText->document()->toPlainText(), m_model);
|
||||
}
|
||||
|
||||
|
||||
void Query::slotCustomQueryResult(Query* caller, const QString &errorText)
|
||||
{
|
||||
if (caller != this)
|
||||
return;
|
||||
|
||||
setCustomQuery();
|
||||
|
||||
handleError(errorText);
|
||||
|
||||
//qWarning() << "Query::slotCustomQueryResult: errorText = " << errorText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Table Query
|
||||
void Query::slotTableQuery()
|
||||
{
|
||||
emit signalShowWait(QStringLiteral("Getting table data .."));
|
||||
//qWarning() << "Query: model" << m_model;
|
||||
emit signalTableQuery(this, m_model);
|
||||
}
|
||||
|
||||
void Query::slotTableQueryResult(Query* caller, const QString &errorText)
|
||||
{
|
||||
if (caller != this)
|
||||
return;
|
||||
|
||||
handleError(errorText);
|
||||
|
||||
// Don't put it in twice
|
||||
if (!m_checkboxes.isEmpty())
|
||||
return;
|
||||
|
||||
for(const auto &item : m_model->getHeaderList())
|
||||
{
|
||||
QCheckBox *cb = new QCheckBox(item.first, this);
|
||||
m_ui->checkboxes->addWidget(cb);
|
||||
m_checkboxes << cb;
|
||||
|
||||
if (item.first.compare(QStringLiteral("id"), Qt::CaseInsensitive) != 0)
|
||||
continue;
|
||||
|
||||
// Only for ID:
|
||||
QRadioButton *rbwhere = new QRadioButton(tr("in WHERE"), this);
|
||||
m_ui->checkboxes->addWidget(rbwhere);
|
||||
QRadioButton *rbnormal = new QRadioButton(tr("normal"), this);
|
||||
m_ui->checkboxes->addWidget(rbnormal);
|
||||
|
||||
rbnormal->setEnabled(cb->isChecked());
|
||||
rbwhere->setEnabled(cb->isChecked());
|
||||
|
||||
connect(cb, &QCheckBox::toggled, rbwhere, &QRadioButton::setEnabled);
|
||||
connect(cb, &QCheckBox::toggled, rbnormal, &QRadioButton::setEnabled);
|
||||
connect(rbwhere, &QRadioButton::toggled, this, [this, rbwhere, cb] { m_idInWhere = rbwhere->isChecked() && cb->isChecked(); });
|
||||
connect(cb, &QRadioButton::toggled, this, [this, rbwhere, cb] { m_idInWhere = rbwhere->isChecked() && cb->isChecked(); });
|
||||
|
||||
rbwhere->setChecked(true);
|
||||
}
|
||||
m_ui->checkboxes->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
||||
//qWarning() << "Query::slotTableQueryResult: errorText = " << errorText;
|
||||
}
|
||||
|
||||
QStringList Query::checkedColumnsNames() const
|
||||
{
|
||||
QStringList sl;
|
||||
for(const auto &cb : m_checkboxes)
|
||||
{
|
||||
if (cb->isChecked())
|
||||
{
|
||||
if ((cb->text().compare(QStringLiteral("id"), Qt::CaseInsensitive) == 0) && m_idInWhere)
|
||||
continue;
|
||||
sl << cb->text();
|
||||
}
|
||||
}
|
||||
return sl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Add Lines
|
||||
void Query::slotStartAddLines()
|
||||
{
|
||||
if (!m_addLines)
|
||||
{
|
||||
m_addLines = new AddLines(this);
|
||||
|
||||
connect(m_addLines, &AddLines::signalAddLines,
|
||||
this, &Query::slotAddLines);
|
||||
|
||||
m_addLines->copyDataFromModel(m_model);
|
||||
}
|
||||
|
||||
m_addLines->show();
|
||||
}
|
||||
|
||||
|
||||
void Query::slotAddLines(AddModel *model)
|
||||
{
|
||||
emit signalShowWait(QStringLiteral("Adding line(s).."));
|
||||
emit signalAddLines(this, model);
|
||||
}
|
||||
|
||||
|
||||
void Query::slotAddLinesResult(Query* caller, int , const QString &errorText)
|
||||
{
|
||||
if (caller != this)
|
||||
return;
|
||||
|
||||
handleError(errorText);
|
||||
|
||||
//qWarning() << "Query::slotAddLinesResult: affectedRows = " << affectedRows << "errorText = " << errorText;
|
||||
|
||||
if (errorText.isEmpty()) // no error
|
||||
{
|
||||
// if (affectedRows) // only get new data when something changed
|
||||
// {
|
||||
// emit signalTableQuery(m_model); // re-get table!
|
||||
// }
|
||||
|
||||
m_addLines->deleteLater(); // done, close add lines window and delete it..
|
||||
m_addLines = nullptr;
|
||||
|
||||
emit signalTableQuery(this, m_model); // get fresh data from db
|
||||
}
|
||||
else // error
|
||||
{
|
||||
if (!m_addLines) // FIXME: needed! but not logically needed ;) what's going on here?
|
||||
{
|
||||
//qWarning() << "Query::slotAddLinesResult: !m_addLines";
|
||||
}
|
||||
else
|
||||
m_addLines->show(); // show again, error!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Set Data
|
||||
void Query::slotSetData(DataModel* model, const QModelIndex &index, const QVariant &val)
|
||||
{
|
||||
int result = QMessageBox::question(this, tr("SqlBrowser"),
|
||||
tr("Do you really want to change the data?"),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||
if (result == QMessageBox::No)
|
||||
return;
|
||||
|
||||
emit signalShowWait(QStringLiteral("Setting data.."));
|
||||
emit signalSetData(this, model, index, val);
|
||||
}
|
||||
|
||||
|
||||
void Query::slotSetDataResult(Query* caller, const QString &errorText)
|
||||
{
|
||||
if (caller != this)
|
||||
return;
|
||||
|
||||
handleError(errorText);
|
||||
|
||||
//qWarning() << "Query::slotSetDataResult: errorText =" << errorText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Query::setTable(const QString &tableName)
|
||||
{
|
||||
emit signalShowWait(QStringLiteral("Updating value.."));
|
||||
|
||||
if (tableName.isEmpty())
|
||||
{
|
||||
//qWarning() << "Query::setTable: tableName.isEmpty()";
|
||||
return;
|
||||
}
|
||||
|
||||
m_model->setTableName(tableName);
|
||||
|
||||
setTableQuery();
|
||||
|
||||
slotTableQuery();
|
||||
}
|
||||
|
||||
|
||||
void Query::setModel()
|
||||
{
|
||||
m_sortModel.setSourceModel(m_model);
|
||||
m_ui->dataTable->setModel(/*(QAbstractTableModel*)*/&m_sortModel);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Query::setCustomQuery() // cannot add/delete/reload
|
||||
{
|
||||
m_ui->pbAddLine->setEnabled(false);
|
||||
m_ui->pbDeleteLine->setEnabled(false);
|
||||
m_ui->pbReload->setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
void Query::setTableQuery() // cannot add/delete/reload
|
||||
{
|
||||
m_ui->pbAddLine->setEnabled(true);
|
||||
m_ui->pbDeleteLine->setEnabled(true);
|
||||
m_ui->pbReload->setEnabled(true);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user