- Qt 5.5
- Qt SQL
- SQL Browser
- browser.cpp Example File
- Qt 5.5.1 Reference Documentation

# browser.cpp Example File

sqlbrowser/browser.cpp

    /****************************************************************************
    **
    ** Copyright (C) 2015 The Qt Company Ltd.
    ** Contact: http://www.qt.io/licensing/
    **
    ** This file is part of the demonstration applications of the Qt Toolkit.
    **
    ** $QT_BEGIN_LICENSE:LGPL21$
    ** Commercial License Usage
    ** Licensees holding valid commercial Qt licenses may use this file in
    ** accordance with the commercial license agreement provided with the
    ** Software or, alternatively, in accordance with the terms contained in
    ** a written agreement between you and The Qt Company. For licensing terms
    ** and conditions see http://www.qt.io/terms-conditions. For further
    ** information use the contact form at http://www.qt.io/contact-us.
    **
    ** GNU Lesser General Public License Usage
    ** Alternatively, this file may be used under the terms of the GNU Lesser
    ** General Public License version 2.1 or version 3 as published by the Free
    ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
    ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
    ** following information to ensure the GNU Lesser General Public License
    ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
    ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    **
    ** As a special exception, The Qt Company gives you certain additional
    ** rights. These rights are described in The Qt Company LGPL Exception
    ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    **
    ** $QT_END_LICENSE$
    **
    ****************************************************************************/

    #include "browser.h"
    #include "qsqlconnectiondialog.h"

    #include <QtWidgets>
    #include <QtSql>

    Browser::Browser(QWidget *parent)
        : QWidget(parent)
    {
        setupUi(this);

        table->addAction(insertRowAction);
        table->addAction(deleteRowAction);
        table->addAction(fieldStrategyAction);
        table->addAction(rowStrategyAction);
        table->addAction(manualStrategyAction);
        table->addAction(submitAction);
        table->addAction(revertAction);
        table->addAction(selectAction);

        if (QSqlDatabase::drivers().isEmpty())
            QMessageBox::information(this, tr("No database drivers found"),
                                     tr("This demo requires at least one Qt database driver. "
                                        "Please check the documentation how to build the "
                                        "Qt SQL plugins."));

        emit statusMessage(tr("Ready."));
    }

    Browser::~Browser()
    {
    }

    void Browser::exec()
    {
        QSqlQueryModel *model = new QSqlQueryModel(table);
        model->setQuery(QSqlQuery(sqlEdit->toPlainText(), connectionWidget->currentDatabase()));
        table->setModel(model);

        if (model->lastError().type() != QSqlError::NoError)
            emit statusMessage(model->lastError().text());
        else if (model->query().isSelect())
            emit statusMessage(tr("Query OK."));
        else
            emit statusMessage(tr("Query OK, number of affected rows: %1").arg(
                               model->query().numRowsAffected()));

        updateActions();
    }

    QSqlError Browser::addConnection(const QString &driver, const QString &dbName, const QString &host,
                                const QString &user, const QString &passwd, int port)
    {
        static int cCount = 0;

        QSqlError err;
        QSqlDatabase db = QSqlDatabase::addDatabase(driver, QString("Browser%1").arg(++cCount));
        db.setDatabaseName(dbName);
        db.setHostName(host);
        db.setPort(port);
        if (!db.open(user, passwd)) {
            err = db.lastError();
            db = QSqlDatabase();
            QSqlDatabase::removeDatabase(QString("Browser%1").arg(cCount));
        }
        connectionWidget->refresh();

        return err;
    }

    void Browser::addConnection()
    {
        QSqlConnectionDialog dialog(this);
        if (dialog.exec() != QDialog::Accepted)
            return;

        if (dialog.useInMemoryDatabase()) {
            QSqlDatabase::database("in_mem_db", false).close();
            QSqlDatabase::removeDatabase("in_mem_db");
            QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "in_mem_db");
            db.setDatabaseName(":memory:");
            if (!db.open())
                QMessageBox::warning(this, tr("Unable to open database"), tr("An error occurred while "
                                                                             "opening the connection: ") + db.lastError().text());
            QSqlQuery q("", db);
            q.exec("drop table Movies");
            q.exec("drop table Names");
            q.exec("create table Movies (id integer primary key, Title varchar, Director varchar, Rating number)");
            q.exec("insert into Movies values (0, 'Metropolis', 'Fritz Lang', '8.4')");
            q.exec("insert into Movies values (1, 'Nosferatu, eine Symphonie des Grauens', 'F.W. Murnau', '8.1')");
            q.exec("insert into Movies values (2, 'Bis ans Ende der Welt', 'Wim Wenders', '6.5')");
            q.exec("insert into Movies values (3, 'Hardware', 'Richard Stanley', '5.2')");
            q.exec("insert into Movies values (4, 'Mitchell', 'Andrew V. McLaglen', '2.1')");
            q.exec("create table Names (id integer primary key, Firstname varchar, Lastname varchar, City varchar)");
            q.exec("insert into Names values (0, 'Sala', 'Palmer', 'Morristown')");
            q.exec("insert into Names values (1, 'Christopher', 'Walker', 'Morristown')");
            q.exec("insert into Names values (2, 'Donald', 'Duck', 'Andeby')");
            q.exec("insert into Names values (3, 'Buck', 'Rogers', 'Paris')");
            q.exec("insert into Names values (4, 'Sherlock', 'Holmes', 'London')");
            connectionWidget->refresh();
        } else {
            QSqlError err = addConnection(dialog.driverName(), dialog.databaseName(), dialog.hostName(),
                               dialog.userName(), dialog.password(), dialog.port());
            if (err.type() != QSqlError::NoError)
                QMessageBox::warning(this, tr("Unable to open database"), tr("An error occurred while "
                                           "opening the connection: ") + err.text());
        }
    }

    void Browser::showTable(const QString &t)
    {
        QSqlTableModel *model = new CustomModel(table, connectionWidget->currentDatabase());
        model->setEditStrategy(QSqlTableModel::OnRowChange);
        model->setTable(connectionWidget->currentDatabase().driver()->escapeIdentifier(t, QSqlDriver::TableName));
        model->select();
        if (model->lastError().type() != QSqlError::NoError)
            emit statusMessage(model->lastError().text());
        table->setModel(model);
        table->setEditTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed);

        connect(table->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
                this, SLOT(currentChanged()));
        updateActions();
    }

    void Browser::showMetaData(const QString &t)
    {
        QSqlRecord rec = connectionWidget->currentDatabase().record(t);
        QStandardItemModel *model = new QStandardItemModel(table);

        model->insertRows(0, rec.count());
        model->insertColumns(0, 7);

        model->setHeaderData(0, Qt::Horizontal, "Fieldname");
        model->setHeaderData(1, Qt::Horizontal, "Type");
        model->setHeaderData(2, Qt::Horizontal, "Length");
        model->setHeaderData(3, Qt::Horizontal, "Precision");
        model->setHeaderData(4, Qt::Horizontal, "Required");
        model->setHeaderData(5, Qt::Horizontal, "AutoValue");
        model->setHeaderData(6, Qt::Horizontal, "DefaultValue");

        for (int i = 0; i < rec.count(); ++i) {
            QSqlField fld = rec.field(i);
            model->setData(model->index(i, 0), fld.name());
            model->setData(model->index(i, 1), fld.typeID() == -1
                    ? QString(QMetaType::typeName(fld.type()))
                    : QString("%1 (%2)").arg(QMetaType::typeName(fld.type())).arg(fld.typeID()));
            model->setData(model->index(i, 2), fld.length());
            model->setData(model->index(i, 3), fld.precision());
            model->setData(model->index(i, 4), fld.requiredStatus() == -1 ? QVariant("?")
                    : QVariant(bool(fld.requiredStatus())));
            model->setData(model->index(i, 5), fld.isAutoValue());
            model->setData(model->index(i, 6), fld.defaultValue());
        }

        table->setModel(model);
        table->setEditTriggers(QAbstractItemView::NoEditTriggers);

        updateActions();
    }

    void Browser::insertRow()
    {
        QSqlTableModel *model = qobject_cast<QSqlTableModel *>(table->model());
        if (!model)
            return;

        QModelIndex insertIndex = table->currentIndex();
        int row = insertIndex.row() == -1 ? 0 : insertIndex.row();
        model->insertRow(row);
        insertIndex = model->index(row, 0);
        table->setCurrentIndex(insertIndex);
        table->edit(insertIndex);
    }

    void Browser::deleteRow()
    {
        QSqlTableModel *model = qobject_cast<QSqlTableModel *>(table->model());
        if (!model)
            return;

        QModelIndexList currentSelection = table->selectionModel()->selectedIndexes();
        for (int i = 0; i < currentSelection.count(); ++i) {
            if (currentSelection.at(i).column() != 0)
                continue;
            model->removeRow(currentSelection.at(i).row());
        }

        updateActions();
    }

    void Browser::updateActions()
    {
        QSqlTableModel * tm = qobject_cast<QSqlTableModel *>(table->model());
        bool enableIns = tm;
        bool enableDel = enableIns && table->currentIndex().isValid();

        insertRowAction->setEnabled(enableIns);
        deleteRowAction->setEnabled(enableDel);

        fieldStrategyAction->setEnabled(tm);
        rowStrategyAction->setEnabled(tm);
        manualStrategyAction->setEnabled(tm);
        submitAction->setEnabled(tm);
        revertAction->setEnabled(tm);
        selectAction->setEnabled(tm);

        if (tm) {
            QSqlTableModel::EditStrategy es = tm->editStrategy();
            fieldStrategyAction->setChecked(es == QSqlTableModel::OnFieldChange);
            rowStrategyAction->setChecked(es == QSqlTableModel::OnRowChange);
            manualStrategyAction->setChecked(es == QSqlTableModel::OnManualSubmit);
        }
    }

    void Browser::about()
    {
        QMessageBox::about(this, tr("About"), tr("The SQL Browser demonstration "
            "shows how a data browser can be used to visualize the results of SQL"
                                                 "statements on a live database"));
    }

    void Browser::on_fieldStrategyAction_triggered()
    {
        QSqlTableModel * tm = qobject_cast<QSqlTableModel *>(table->model());
        if (tm)
            tm->setEditStrategy(QSqlTableModel::OnFieldChange);
    }

    void Browser::on_rowStrategyAction_triggered()
    {
        QSqlTableModel * tm = qobject_cast<QSqlTableModel *>(table->model());
        if (tm)
            tm->setEditStrategy(QSqlTableModel::OnRowChange);
    }

    void Browser::on_manualStrategyAction_triggered()
    {
        QSqlTableModel * tm = qobject_cast<QSqlTableModel *>(table->model());
        if (tm)
            tm->setEditStrategy(QSqlTableModel::OnManualSubmit);
    }

    void Browser::on_submitAction_triggered()
    {
        QSqlTableModel * tm = qobject_cast<QSqlTableModel *>(table->model());
        if (tm)
            tm->submitAll();
    }

    void Browser::on_revertAction_triggered()
    {
        QSqlTableModel * tm = qobject_cast<QSqlTableModel *>(table->model());
        if (tm)
            tm->revertAll();
    }

    void Browser::on_selectAction_triggered()
    {
        QSqlTableModel * tm = qobject_cast<QSqlTableModel *>(table->model());
        if (tm)
            tm->select();
    }