pgLab/pglab/MainWindow.cpp
eelke be0064f730 The codegen now can properly lookup array types.
Array type lookup failed previously because the typemapping class was
not yet receiving the list of types from the database. Fix was to pass
this data
2018-11-17 09:47:50 +01:00

364 lines
8 KiB
C++

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "TablesPage.h"
#include <QStandardPaths>
#include <QFileDialog>
#include <QMessageBox>
#include <QTextTable>
#include <QElapsedTimer>
#include <algorithm>
#include <QCloseEvent>
#include <QMetaObject>
#include <QMetaMethod>
#include "QueryTab.h"
#include "util.h"
#include "PlgPage.h"
#include "CodeGenerator.h"
#include "MasterController.h"
#include "CrudTab.h"
#include "WorkManager.h"
#include "ScopeGuard.h"
namespace pg = Pgsql;
MainWindow::MainWindow(MasterController *master, QWidget *parent)
: ASyncWindow(parent)
, ui(new Ui::MainWindow)
, m_masterController(master)
{
ui->setupUi(this);
ui->tabWidget->setDocumentMode(true);
}
MainWindow::~MainWindow()
{
loader.reset();
delete ui;
}
QueryTab* MainWindow::newSqlPage()
{
QueryTab *qt = new QueryTab(this);
qt->setConfig(m_config, m_database->catalogue());
// ui->tabWidget->addTab(qt, "Tab");
// ui->tabWidget->setCurrentWidget(qt);
addPage(qt, "Tab");
qt->newdoc();
qt->focusEditor();
return qt;
}
void MainWindow::newCrudPage(const PgClass &table)
{
CrudTab *ct = new CrudTab(this);
ct->setConfig(m_database, table);
// ui->tabWidget->addTab(ct, table.name);
// ui->tabWidget->setCurrentWidget(ct);
addPage(ct, table.name);
}
void MainWindow::newCodeGenPage(QString query, std::shared_ptr<const Pgsql::Result> dbres)
{
auto cgtab = new CodeGenerator(this);
cgtab->Init(m_database->catalogue(), query, dbres);
addPage(cgtab, "Codegen");
}
QueryTab *MainWindow::GetActiveQueryTab()
{
QWidget *widget = ui->tabWidget->currentWidget();
QueryTab *qt = dynamic_cast<QueryTab*>(widget);
return qt;
}
void MainWindow::setConfig(const ConnectionConfig &config)
{
m_config = config;
try {
QString title = "pglab - ";
title += m_config.name().c_str();
setWindowTitle(title);
loader = std::make_shared<QLoad>(m_config, [this](QRunnable *) {
QueueTask([this] () { catalogLoaded(); });
} );
WorkManager::getWorkManager()->addRunnable(loader.get());
} catch (std::runtime_error &ex) {
QMessageBox::critical(this, "Error reading database",
QString::fromUtf8(ex.what()));
close();
}
}
void MainWindow::catalogLoaded()
{
try {
SCOPE_EXIT { loader.reset(); };
m_database = loader->GetResult();
auto tt = new TablesPage(this);
tt->setCatalog(m_database->catalogue());
ui->tabWidget->addTab(tt, "Tables");
ui->tabWidget->setCurrentWidget(tt);
newSqlPage();
} catch (std::runtime_error &ex) {
QMessageBox::critical(this, "Error reading database",
QString::fromUtf8(ex.what()));
close();
}
}
void MainWindow::on_actionLoad_SQL_triggered()
{
QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory);
QString file_name = QFileDialog::getOpenFileName(this,
tr("Open sql query"), home_dir, tr("SQL files (*.sql *.txt)"));
if ( ! file_name.isEmpty()) {
QueryTab* qt = newSqlPage();
qt->load(file_name);
}
}
void MainWindow::on_actionSave_SQL_triggered()
{
QueryTab *tab = GetActiveQueryTab();
if (tab) {
tab->save();
}
}
void MainWindow::on_actionSave_SQL_as_triggered()
{
QueryTab *tab = GetActiveQueryTab();
if (tab) {
tab->saveAs();
}
}
void MainWindow::on_actionSave_copy_of_SQL_as_triggered()
{
QueryTab *tab = GetActiveQueryTab();
if (tab) {
tab->saveCopyAs();
}
}
void MainWindow::on_actionExport_data_triggered()
{
QueryTab *tab = GetActiveQueryTab();
if (tab) {
QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory);
QString file_name = QFileDialog::getSaveFileName(this,
tr("Export data"), home_dir, tr("CSV file (*.csv)"));
tab->exportData(file_name);
}
}
void MainWindow::on_actionClose_triggered()
{
//close();
on_tabWidget_tabCloseRequested(ui->tabWidget->currentIndex());
}
void MainWindow::on_actionAbout_triggered()
{
QMessageBox::about(this, "pgLab 0.1", tr(
"Copyrights 2016-2017, Eelke Klein, All Rights Reserved.\n"
"\n"
"The program is provided AS IS with NO WARRANTY OF ANY KIND, "
"INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS "
"FOR A PARTICULAR PURPOSE.\n"
"\n"
"This program is dynamically linked with Qt 5.9 Copyright (C) 2017 "
"The Qt Company Ltd. https://www.qt.io/licensing/. \n"
"\n"
"Icons by fatcow http://www.fatcow.com/free-icons provided under Creative Commons "
"attribution 3.0 license."
));
}
void MainWindow::closeEvent(QCloseEvent* /*event*/)
{
// TODO collect which files need saving
// std::vector<QString> files_to_save;
// int n = ui->tabWidget->count();
// for (int i = 0; i < n; ++i) {
// QWidget *w = ui->tabWidget->widget(i);
// QueryTab *qt = dynamic_cast<QueryTab*>(w);
// if (qt) {
// if (qt->isChanged()) {
// files_to_save.push_back(qt->fileName());
// }
// }
// }
// QString s;
// for (const auto& e : files_to_save) {
// s += e + "\n";
// }
// QMessageBox msgBox;
// msgBox.setIcon(QMessageBox::Warning);
// msgBox.setText("The following documents need to be saved");
// msgBox.setInformativeText(s);
// msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
// msgBox.setDefaultButton(QMessageBox::Cancel);
// //int ret =
// msgBox.exec();
}
void MainWindow::showEvent(QShowEvent *event)
{
if (!event->spontaneous()) {
// m_queryTextChanged = false;
}
event->accept();
}
void MainWindow::on_actionNew_SQL_triggered()
{
newSqlPage();
}
void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
QWidget *widget = ui->tabWidget->widget(index);
PlgPage *plg_page = dynamic_cast<PlgPage*>(widget);
if (plg_page) {
if (plg_page->canClose()) {
removePage(plg_page);
ui->tabWidget->removeTab(index);
}
}
else {
// old behaviour shouldn't be needed any more when all pages have been migrated
// to PlgPage
QueryTab *qt = dynamic_cast<QueryTab*>(widget);
if (qt && qt->canClose()) {
ui->tabWidget->removeTab(index);
}
else if (index > 0) {
ui->tabWidget->removeTab(index);
}
}
}
void MainWindow::on_actionShow_connection_manager_triggered()
{
m_masterController->showConnectionManager();
}
void MainWindow::on_actionCopy_triggered()
{
// What should be copied?
QWidget *w = QApplication::focusWidget();
QTableView *tv = dynamic_cast<QTableView*>(w);
if (tv) {
copySelectionToClipboard(tv);
}
else {
const QMetaObject *meta = w->metaObject();
int i = meta->indexOfSlot("copy");
if (i != -1) {
QMetaMethod method = meta->method(i);
method.invoke(w, Qt::AutoConnection);
}
}
}
void MainWindow::on_actionCopy_as_C_string_triggered()
{
// Find which edit is active, copy the selected text or all text if no selection present
// Put quote's around each line and add escapes.
QueryTab *tab = GetActiveQueryTab();
if (tab) {
tab->copyQueryAsCString();
}
}
void MainWindow::on_actionCopy_as_raw_Cpp_string_triggered()
{
QueryTab *tab = GetActiveQueryTab();
if (tab) {
tab->copyQueryAsRawCppString();
}
}
void MainWindow::addToolBarButtonsForPage(PlgPage *page)
{
std::vector<QAction*> actions = page->getToolbarActions();
QList<QAction*> list;
for (auto act : actions) {
list.append(act);
}
ui->mainToolBar->addActions(list);
}
void MainWindow::removeToolBarButtonsForPage(PlgPage *page)
{
std::vector<QAction*> actions = page->getToolbarActions();
for (auto act : actions) {
ui->mainToolBar->removeAction(act);
}
}
void MainWindow::addPage(PlgPage* page, QString caption)
{
ui->tabWidget->addTab(page, caption);
ui->tabWidget->setCurrentWidget(page);
//addToolBarButtonsForPage(page);
}
void MainWindow::removePage(PlgPage *)
{
}
void MainWindow::on_tabWidget_currentChanged(int index)
{
// remove buttons of old page
if (m_previousPage) {
removeToolBarButtonsForPage(m_previousPage);
}
// add buttons of new page
PlgPage * page = nullptr;
if (index >= 0) {
QWidget *widget = ui->tabWidget->widget(index);
page = dynamic_cast<PlgPage*>(widget);
if (page) {
addToolBarButtonsForPage(page);
}
}
m_previousPage = page;
}
void MainWindow::on_actionGenerate_code_triggered()
{
QueryTab *tab = GetActiveQueryTab();
if (tab) {
tab->generateCode();
}
}