view src/main.h @ 213:131463be208b

Split the custom SQL models code into sqlmodels.cpp
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 18 Dec 2017 11:28:00 +0200
parents 6585cac42b75
children 58af72da7f60
line wrap: on
line source

//
// Syntilista - debt list/management database program
// Programmed and designed by Matti Hämäläinen <ccr@tnsp.org>
// (C) Copyright 2017 Tecnic Software productions (TNSP)
//
// Distributed under 3-clause BSD style license, refer to
// included file "COPYING" for exact terms.
//
#ifndef SYNTILISTA_H
#define SYNTILISTA_H

#include <QMainWindow>
#include <QShortcut>
#include <QDialog>
#include <QtSql>
#include <QSqlQueryModel>
#include <QPainter>
#include <QPrinter>
#include <QProgressDialog>
#ifdef USE_QTHTTP
#    include <QNetworkAccessManager>
#    include <QNetworkRequest>
#    include <QNetworkReply>
#    include <QHttpMultiPart>
#endif


//
// Global application defines
//
#define APP_VENDOR           "TNSP"                    // Vendor ID (for settings, etc.)
#define APP_ID               "Kampus Syntilista"       // Application ID (for settings)
#define APP_NAME             "Café Kampus Syntilista"  // Application title/name
#define APP_SQLITE_FILE      "syntilista.sqlite3"      // SQLite3 database file name (without path)
#define APP_LOG_FILE         "log.txt"                 // Application log file name (without path)

// SQL database field width/lengths
#define SQL_LEN_FIRST_NAME   128
#define SQL_LEN_LAST_NAME    128
#define SQL_LEN_EXTRA_INFO   2048

// Supported database backup modes
#define BACKUP_NONE          0  // No backup
#define BACKUP_HTTP          1  // HTTP(s) POST to a PHP script



//
// Person information record
//
class SLPersonInfo : public QObject
{
    Q_OBJECT

public:
    explicit SLPersonInfo()
    {
        id = -1;
        firstName = "";
        lastName = "";
        extraInfo = "";
        balance = 0;
    }

    ~SLPersonInfo()
    {
    }

    void dump();

    qint64 id;
    QString firstName, lastName, extraInfo;
    double balance;
    QDateTime added, updated;
};


//
// Global functions
//
double slMoneyStrToValue(const QString &str);
QString slMoneyValueToStr(double val);
QString slMoneyValueToStrSign(double val);
QString slCleanupStr(const QString &str);
const QDateTime slDateTimeToLocal(const QDateTime &val);
const QString slDateTimeToStr(const QDateTime &val);

void slLog(const QString &mtype, const QString &msg);
int slErrorMsg(const QString &title, const QString &msg);
bool slCheckAndReportSQLError(const QString where, const QSqlError &err, bool report = false);

void slGetPersonInfoRec(QSqlQuery &query, SLPersonInfo &info);


//
// Custom SQL models
//
class SLPersonSQLModel : public QSqlQueryModel
{
    Q_OBJECT

private:

public:
    SLPersonSQLModel(QObject *parent = 0);

    QVariant data(const QModelIndex &item, int role) const Q_DECL_OVERRIDE;

    int  updatePerson(const SLPersonInfo &person);
    qint64  addPerson(const SLPersonInfo &person);
    int  deletePerson(qint64 id);
    void updateModel();
};



class SLTransactionSQLModel : public QSqlQueryModel
{
    Q_OBJECT

private:

public:
    SLTransactionSQLModel(QObject *parent = 0);

    QVariant data(const QModelIndex &item, int role) const Q_DECL_OVERRIDE;

    void updateModel();
};



//
// Main window
//
namespace Ui
{
    class SyntilistaMainWindow;
    class EditPerson;
    class AboutWindow;
}

typedef struct
{
    int nlinesPerPage;
    int npages;
} SLPageInfo;


class SyntilistaMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit SyntilistaMainWindow(QWidget *parent = 0);
    ~SyntilistaMainWindow();

    void statusMsg(const QString &msg);

    void readSettings();
    void saveSettings();
    void setActivePerson(qint64 id);
    int  addTransaction(qint64 id, double value, SLPersonInfo &info);
    int  addTransactionGUI(qint64 id, bool debt, double value);
    void updatePersonList();
    void updateMiscValues();
    void backupDatabase();
    void backupSuccess();

    bool printDocumentPage(const bool getPageInfo, const int page, QPainter *pt, QPrinter *printer);

    SLPersonSQLModel *model_People;

public slots:
    void focusDebtEdit();

private slots:
    void on_button_AddPerson_clicked();
    void on_button_EditPerson_clicked();
    void on_button_DeletePerson_clicked();

    void on_edit_PersonFilter_textChanged(const QString &arg1);
    void on_button_ClearFilter_clicked();

    void on_button_Quit_clicked();
    void on_button_About_clicked();
    void on_button_Print_clicked();

    void on_button_AddDebt_clicked();
    void on_button_PayDebt_clicked();
    void on_button_PayFullDebt_clicked();

    void on_tableview_People_doubleClicked(const QModelIndex &index);

    void selectedPersonChanged(const QModelIndex &, const QModelIndex &);

    void changeSelectedRow(const int delta);
    void selectRowPrev();
    void selectRowNext();

    void changeUIZoomIn();
    void changeUIZoomOut();
    void changeUIZoomReset();

    void updateSortOrder(int index, Qt::SortOrder order);

    void printDocument(QPrinter *printer);

#ifdef USE_QTHTTP
    void httpBackupProgress(qint64 bytesSent, qint64 bytesTotal);
    void httpBackupFinished();
    void httpBackupError(QNetworkReply::NetworkError code);
#endif


private:
    Ui::SyntilistaMainWindow *ui;

    QProgressDialog *backupDialog;
#ifdef USE_QTHTTP
    QNetworkReply *httpBackupReply;
#endif

    SLTransactionSQLModel *model_Latest;
    SLPersonInfo currPerson;

    int peopleSortIndex;
    Qt::SortOrder peopleSortOrder;
    QString peopleFilter;

    SLPageInfo pinfo;

    int totalPeople;
    double totalBalance;
};


//
// Person edit / new person dialog
//
class EditPerson : public QDialog
{
    Q_OBJECT

public:
    explicit EditPerson(QWidget *parent = 0);
    ~EditPerson();

    void statusMsg(const QString &msg);

    void clearForm();
    bool validateForm();
    void setPerson(qint64 id);

private slots:
    void on_button_OK_clicked();
    void on_button_Cancel_clicked();

    void on_edit_FirstName_textChanged(const QString &arg1);
    void on_edit_LastName_textChanged(const QString &arg1);
    void on_textedit_ExtraInfo_textChanged();

private:
    Ui::EditPerson *ui;

    SLPersonInfo selPerson;
    SLTransactionSQLModel *model_Transactions;
};


//
// About dialog
//
class AboutWindow : public QDialog
{
    Q_OBJECT

public:
    explicit AboutWindow(QWidget *parent = 0);
    ~AboutWindow();

private slots:
    void on_button_Close_clicked();

private:
    Ui::AboutWindow *ui;
};


//
// Custom painter drawing helper class
//
class SLDrawContext : public QObject
{
    Q_OBJECT

public:
    QPointF m_pos;
    QString m_str;
    qreal m_lf_add;

    explicit SLDrawContext(QPainter *pt)
    {
        painter = pt;
        metrics = NULL;
        m_str = "ABC";
        setPos(0, 0);
        m_lf_add = 0;
    }

    ~SLDrawContext()
    {
        if (metrics)
            delete metrics;
    }

    void setFont(const QFont &ft)
    {
        if (metrics)
            delete metrics;

        font = QFont(ft, painter->device());
        painter->setFont(font);
        metrics = new QFontMetricsF(font);
    }

    void setLFAdd(const qreal lf_add)
    {
        m_lf_add = lf_add;
    }

    void drawText(const QPointF &pos, const QString &str)
    {
        m_str = str;
        painter->drawText(m_pos + pos, str);
    }

    void drawText(const QString &str)
    {
        drawText(QPointF(0, 0), str);
    }

    void drawText(const qreal xc, const qreal width, const QString &str, const int flags = 0)
    {
        m_str = str;
        painter->drawText(
            m_pos.x() + xc, m_pos.y(),
            width, boundRect().height(),
            flags,
            str);
    }

    const QRectF boundRect(const QString str)
    {
        return metrics->boundingRect(str);
    }

    const QRectF boundRect()
    {
        return metrics->boundingRect(m_str);
    }

    void lf(qreal yadd)
    {
        m_pos.setY(m_pos.y() + boundRect().height() + yadd);
    }

    qreal lfq(qreal yadd)
    {
        return m_pos.y() + boundRect().height() + yadd;
    }

    void lf()
    {
        lf(m_lf_add);
    }

    qreal lfq()
    {
        return m_pos.y() + boundRect().height() + m_lf_add;
    }

    void setPos(const QPointF &pos)
    {
        m_pos = pos;
    }

    void setPos(const qreal x, const qreal y)
    {
        setPos(QPointF(x, y));
    }

    void move(const QPointF &pos)
    {
        m_pos += pos;
    }

    void move(const qreal x, const qreal y)
    {
        move(QPointF(x, y));
    }

private:
    QPainter *painter;
    QFont font;
    QFontMetricsF *metrics;
};


#endif // SYNTILISTA_H