Subversion Repositories Projects

Rev

Rev 674 | Rev 750 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/***************************************************************************
 *   Copyright (C) 2009 by Manuel Schrape                                  *
 *   manuel.schrape@gmx.de                                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License.        *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <QMessageBox>
#include <QCryptographicHash>

#include "dlg_Main.h"

// Konstruktor Main-Form
dlg_Main::dlg_Main()
{
    setupUi(this);

    o_Settings = new cSettings();

    o_Settings->read_DebugLabels(0);

    o_Input = new Input();

    init_GUI();
    init_Connections();
    init_Plotter();
}

// Grafische Oberfläche initialisieren
void dlg_Main::init_GUI()
{
    setWindowTitle(QA_NAME + " " + QA_VERSION);

    resize(o_Settings->GUI.Size);
    move(o_Settings->GUI.Point);

    if (o_Settings->GUI.isMax)
    {
        showMaximized();
    }

    for(int z = 0; z < o_Settings->SERVER.IP_MAX; z++)
    {
        if (cb_Server->findText(o_Settings->SERVER.IP[z]) == -1)
        {
            cb_Server->addItem(o_Settings->SERVER.IP[z]);
        }
    }

    cb_Server->setCurrentIndex(o_Settings->SERVER.IP_ID);

    le_Password->setText(o_Settings->SERVER.Password);

    sb_Intervall->setValue(o_Settings->DATA.Debug_Intervall);

    btn_Start->setCheckable(true);

    ac_Plotter->setChecked(true);

    Font_1.setFamily(QString::fromUtf8("Adobe Courier"));
    Font_1.setBold(true);
    Font_1.setWeight(75);

    for(int z = 0; z < MAX_DebugData; z++)
    {

        lb_Debug[z] = new QLabel(wg_Debug);
        le_Debug[z] = new QLineEdit(wg_Debug);
        cb_Debug[z] = new QCheckBox(wg_Config);
        le_Debug[z]->setFont(Font_1);
        le_Debug[z]->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
        le_Debug[z]->setReadOnly(true);

        wg_Grid->addWidget(lb_Debug[z], (z % 8), z / 8 * 2, 0);
        wg_Grid->addWidget(le_Debug[z], (z % 8), z / 8 * 2 + 1 , 0);

        wg_Grid_2->addWidget(cb_Debug[z], (z % 8), z / 8, 0);

        lb_Debug[z]->setText(o_Settings->DebugData.Label[z]);
        cb_Debug[z]->setText(o_Settings->DebugData.Label[z]);

        cb_Debug[z]->setChecked(o_Settings->DebugData.Show_Plotter[z]);
    }
}

// Signale mit Slots verbinden
void dlg_Main::init_Connections()
{
    connect(sb_Intervall, SIGNAL(valueChanged(int)), this, SLOT(slot_sb_Intervall(int)));

    connect(ac_Connect, SIGNAL(triggered()), this, SLOT(slot_ac_Connect()));
    connect(ac_Plotter, SIGNAL(triggered()), this, SLOT(slot_ac_Plotter()));
    connect(ac_Debug,   SIGNAL(triggered()), this, SLOT(slot_ac_Debug()));
    connect(ac_Chose,   SIGNAL(triggered()), this, SLOT(slot_ac_Chose()));

    connect(ac_ReadLabels, SIGNAL(triggered()), this, SLOT(slot_ac_ReadLabels()));

    connect(rb_NC,      SIGNAL(clicked()), this, SLOT(slot_rb_Hardware()));
    connect(rb_FC,      SIGNAL(clicked()), this, SLOT(slot_rb_Hardware()));
    connect(rb_MK3MAG,  SIGNAL(clicked()), this, SLOT(slot_rb_Hardware()));

    connect(Plotter_Scroll, SIGNAL(valueChanged(int)), this, SLOT(slot_Plotter_Scroll(int)));

    connect(btn_Start, SIGNAL(clicked()), this, SLOT(slot_Plotter_Start()));
    connect(btn_ChoseOK, SIGNAL(clicked()), this, SLOT(slot_btn_ChoseOK()));

    // About QMK-Kernel & About-QT Dialog einfügen
    connect(ac_About, SIGNAL(triggered()), this, SLOT(slot_ac_About()));
    menu_Help->addAction(trUtf8("Über &Qt"), qApp, SLOT(aboutQt()));
}

void dlg_Main::init_Plotter()
{
    NextPlot = 0;

    qwt_Plotter->setCanvasBackground(QColor(QRgb(0x00000000)));

    qwt_Plotter->insertLegend(new QwtLegend(), QwtPlot::RightLegend);

    QwtPlotGrid *Grid = new QwtPlotGrid();
    Grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));

    Grid->attach(qwt_Plotter);

    qwt_Plotter->setAxisScale(QwtPlot::xBottom,0,o_Settings->DATA.Plotter_Count,0);

    for (int a = 0; a < MAX_DebugData; a++)
    {
        Plot[a] = new QwtPlotCurve(o_Settings->DebugData.Label[a]);
        Plot[a]->setPen(QPen(QColor(DEF_DebugColors[a])));
        Plot[a]->setRenderHint(QwtPlotItem::RenderAntialiased);

        if (o_Settings->DebugData.Show_Plotter[a])
            Plot[a]->attach(qwt_Plotter);
    }
    qwt_Plotter->replot();
}

void dlg_Main::update_Plotter()
{
    pl_ID[NextPlot] = NextPlot;

    for (int a = 0; a < MAX_DebugData; a++)
    {
        pl_Data[a][NextPlot] = Debug_Data[a];
        Plot[a]->setData(pl_ID,pl_Data[a],NextPlot);
    }

    NextPlot++;

    if ((NextPlot > o_Settings->DATA.Plotter_Count))
    {
        Plotter_Scroll->setMaximum(NextPlot - o_Settings->DATA.Plotter_Count);
    }

    if ((Plotter_Scroll->value() == NextPlot - (o_Settings->DATA.Plotter_Count + 1)))
    {
        qwt_Plotter->setAxisScale(QwtPlot::xBottom,NextPlot - o_Settings->DATA.Plotter_Count,NextPlot,0);
        Plotter_Scroll->setValue(NextPlot - o_Settings->DATA.Plotter_Count);
    }

    qwt_Plotter->replot();
}

void dlg_Main::config_Plotter()
{
    qwt_Plotter->setAxisScale(QwtPlot::xBottom,0,o_Settings->DATA.Plotter_Count,0);

    for (int a = 0; a < MAX_DebugData; a++)
    {
        Plot[a]->detach();
        Plot[a]->setPen(QPen(QColor(DEF_DebugColors[a])));

        if (o_Settings->DebugData.Show_Plotter[a])
        {
            Plot[a]->setTitle(o_Settings->DebugData.Label[a]);
            Plot[a]->attach(qwt_Plotter);
        }
    }
    qwt_Plotter->replot();
}

void dlg_Main::slot_Plotter_Scroll(int Position)
{
    qwt_Plotter->setAxisScale(QwtPlot::xBottom,Position,Position + o_Settings->DATA.Plotter_Count,0);
    qwt_Plotter->replot();
}

// IP-Input-Daten verarbeiten.
void dlg_Main::parse_IP_Data(QString t_Data)
{
    QStringList Data;
    Data = t_Data.split(":");

    if (Data.count() > 1)
    {
        int CMD = Data[2].toInt();

        switch(CMD)
        {
            case 101 :
            {
                o_Input->send_Data(HandlerIP::make_Frame(ID_SCOPE, 101, QA_NAME + " " + QA_VERSION));
            }
            case 502 :
            {
                switch (Data[3].toInt())
                {
                    case 105 :
                    {
                        QString s_MD5PW;
                        QByteArray a_MD5PW;

                        a_MD5PW = QCryptographicHash::hash(le_Password->text().toAscii(),QCryptographicHash::Md5);

                        s_MD5PW = QString(a_MD5PW.toHex().data());

                        o_Input->send_Data(HandlerIP::make_Frame(ID_SCOPE, 105, s_MD5PW));
                    }
                    break;
                    case 106 :
                    {
                        o_Input->send_Data(HandlerIP::make_Frame(ID_SCOPE, 106, DataFields));
                    }
                    break;
                }
            }
            break;
            case 505 :
            {
                if (Data[3] == "OK")
                {
                }
                else
                {
                    QMessageBox::warning(this, QA_NAME, trUtf8("Authentifizierung fehlgeschlagen. <br />Daten senden zum Mikrokopter nicht möglich."), QMessageBox::Ok);
                }
            }
            break;
        }
    }
}

// MK-Eingangsdaten verarbeiten
void dlg_Main::parse_MK_Data(QString t_Data)
{
    unsigned char OutData[150];
    char *InData = t_Data.toLatin1().data();

    if (HandlerMK::Decode_64(InData, t_Data.length(), OutData) != 0)
    {
        switch(InData[2])
        {
            case 'A' : // 0.76e - Debug-Labels
                {
                    o_Input->stop_Resend(DATA_READ_LABEL);
                    int Position = OutData[0];
                    if (Position < 32)
                    {
                        o_Settings->DebugData.Label[Position] = HandlerMK::Data2QString(OutData,1,17).trimmed();
                        if (o_Settings->DebugData.Label[Position] == "")
                        {
                            o_Settings->DebugData.Label[Position] = "Debug-" + QString("%1").arg(Position);
                        }
                        lb_Debug[Position]->setText("" + o_Settings->DebugData.Label[Position]);
                        cb_Debug[Position]->setText("" + o_Settings->DebugData.Label[Position]);

                        Position ++;

                        if ((Position < 32) && (get_Analoglabels == true))
                        {
                            c_Data[0] = Position;
                            o_Input->send_Data(HandlerMK::make_Frame('a', ADDRESS_ALL, c_Data, 1).toLatin1().data(), DATA_READ_LABEL);
                        }
                    }
                    if (Position == 32)
                    {
                        o_Settings->DebugData.Version = VersionInfo.Version;
                        o_Settings->write_DebugLabels(VersionInfo.ID);
                        config_Plotter();
                        get_Analoglabels = false;
                    }
                }
            break;

            case 'D' : // 0.75a - Debug-Daten
                {
                    for (int z = 0; z < MAX_DebugData; z++)
                    {
                        Debug_Data[z] = HandlerMK::Data2Int(OutData, (z * 2) + 2);
                        if (ac_Debug->isChecked())
                        {
                            le_Debug[z]->setText(QString("%1").arg(Debug_Data[z]));
                        }
                    }
                    if (btn_Start->isChecked())
                    {
                        update_Plotter();
                    }
                }
            break;

            case 'V' : // 0.75a - Versions-Info
                {
                    o_Input->stop_Resend(DATA_VERSION);
                    VersionInfo = HandlerMK::parse_Version(OutData, InData[1] - 'a');
                    setWindowTitle(QA_NAME + " " + QA_VERSION + " - " + VersionInfo.Hardware + " " + VersionInfo.Version);

                    if (VersionInfo.ID == ADDRESS_FC)
                    {
                        rb_FC->setChecked(true);
                    }
                    if (VersionInfo.ID == ADDRESS_NC)
                    {
                        rb_NC->setChecked(true);
                    }
                    if (VersionInfo.ID == ADDRESS_MK3MAG)
                    {
                        rb_MK3MAG->setChecked(true);
                    }

                    o_Settings->read_DebugLabels(VersionInfo.ID);

                    if (o_Settings->DebugData.Version != VersionInfo.Version)
                    {
//                        qDebug(QString("Debug-Labels unterschiedlich. Neue anforden. " + o_Settings->DebugData.Version + " <> " + VersionInfo.Version).toLatin1().data());

                        usleep(50000);

                        slot_ac_ReadLabels();
//                        o_Input->send_Data(HandlerMK::make_Frame('a', ADDRESS_ALL, c_Data, 1).toLatin1().data());
                    }
                    else
                    {
                        for(int z = 0; z < MAX_DebugData; z++)
                        {
                            lb_Debug[z]->setText(o_Settings->DebugData.Label[z]);
                            cb_Debug[z]->setText(o_Settings->DebugData.Label[z]);
                            cb_Debug[z]->setChecked(o_Settings->DebugData.Show_Plotter[z]);
                        }
                        config_Plotter();
                    }
                    c_Data[0] = sb_Intervall->value() / 10;
                    o_Input->send_Data(HandlerMK::make_Frame('d', ADDRESS_ALL, c_Data, 1).toLatin1().data());
                }
            break;
        }
    }
}

///////////
// Slots //
///////////
void dlg_Main::slot_Plotter_Start()
{
    if (btn_Start->isChecked())
    {
        btn_Start->setText(tr("Plotter stoppen"));
    }
    else
    {
        btn_Start->setText(tr("Plotter starten"));
    }
}

void dlg_Main::slot_btn_ChoseOK()
{
    for(int z = 0; z < MAX_DebugData; z++)
    {
        o_Settings->DebugData.Show_Plotter[z] = cb_Debug[z]->isChecked();
    }
    config_Plotter();
    o_Settings->write_DebugLabels(VersionInfo.ID);
}

void dlg_Main::slot_ac_Chose()
{

    for(int z = 0; z < MAX_DebugData; z++)
    {
        cb_Debug[z]->setChecked(o_Settings->DebugData.Show_Plotter[z]);
    }

    ac_Chose->setChecked(true);
    ac_Debug->setChecked(false);
    ac_Plotter->setChecked(false);
    wg_Pages->setCurrentIndex(2);
}

void dlg_Main::slot_ac_Debug()
{
    ac_Debug->setChecked(true);
    ac_Chose->setChecked(false);
    ac_Plotter->setChecked(false);
    wg_Pages->setCurrentIndex(1);
}

void dlg_Main::slot_ac_Plotter()
{
    ac_Plotter->setChecked(true);
    ac_Debug->setChecked(false);
    ac_Chose->setChecked(false);
    wg_Pages->setCurrentIndex(0);
}

void dlg_Main::slot_ac_ReadLabels()
{
    get_Analoglabels = true;
    c_Data[0] = 0;
    o_Input->send_Data(HandlerMK::make_Frame('a', ADDRESS_ALL, c_Data, 1).toLatin1().data(), DATA_READ_LABEL);
}

// About-Dialog
void dlg_Main::slot_ac_About()
{
    QMessageBox::about(this, trUtf8(("Über ")) + QA_NAME, QA_ABOUT);
}

// Datenintervall geändert.
void dlg_Main::slot_sb_Intervall(int t_Intervall)
{
    if (t_Intervall == 0)
    {
        c_Data[0] = 0;
    }
    else
    {
        c_Data[0] = t_Intervall / 10;
    }
    o_Input->send_Data(HandlerMK::make_Frame('d', ADDRESS_ALL, c_Data, 1).toLatin1().data());
}

// Hardware auswählen.
void dlg_Main::slot_rb_Hardware()
{
    if ((rb_NC->isChecked() == false) && (VersionInfo.ID != ADDRESS_NC))
    {
        o_Input->send_Data(HandlerMK::get_SelectNC());
    }

    if (rb_FC->isChecked())
    {
        o_Input->send_Data(HandlerMK::get_SelectFC());
    }
    else
    if (rb_MK3MAG->isChecked())
    {
        o_Input->send_Data(HandlerMK::get_SelectMK3MAG());
    }
    else
    if (rb_NC->isChecked())
    {
        o_Input->send_Data(HandlerMK::get_SelectNC());
    }

    o_Input->send_Data(HandlerMK::make_Frame('v', 0, c_Data, 0).toLatin1().data(), DATA_VERSION);
}

// Verbindung zum Server aufbauen
void dlg_Main::slot_ac_Connect()
{
    if (!o_Input->IsOpen())
    {
        if (cb_Server->findText(cb_Server->currentText()) == -1)
        {
            cb_Server->addItem(cb_Server->currentText());
            cb_Server->setCurrentIndex(cb_Server->findText(cb_Server->currentText()));
        }

        cb_Server->setEnabled(false);
        le_Password->setEnabled(false);

        // Connect über Device
        if (cb_Server->currentText().startsWith('/'))
        {
            o_Input = new Input_TTY();
            o_Input->Init();

            set_Input s_Input;
            s_Input.Main = cb_Server->currentText();

            if (o_Input->Open(s_Input) == true)
            {
                ac_Connect->setText(tr("Trennen"));
                connect(o_Input, SIGNAL(sig_NewData(QString)), this, SLOT(slot_Input_Data(QString)));

                o_Input->send_Data(HandlerMK::make_Frame('v', 0, c_Data, 0).toLatin1().data(), DATA_VERSION);
            }
            else
            {
                cb_Server->setEnabled(true);
                le_Password->setEnabled(true);
            }

        }
        else // Connect über TCPIP
        {
            o_Input = new Input_TCP();
            o_Input->Init();

            set_Input s_Input;

            QStringList Server = cb_Server->currentText().split(":");

            s_Input.Main = Server[0];
            s_Input.Sub  = Server[1];

            if (o_Input->Open(s_Input) == true)
            {
                connect(o_Input, SIGNAL(sig_Disconnected(int)), this, SLOT(slot_Input_Disconnected(int)));
                connect(o_Input, SIGNAL(sig_Connected()), this, SLOT(slot_Input_Connected()));
            }
        }
    }
    else
    {
        cb_Server->setEnabled(true);
        le_Password->setEnabled(true);

        ac_Connect->setText(tr("Verbinden"));
        o_Input->Close();
        disconnect(o_Input, SIGNAL(sig_NewData(QString)), 0, 0);
        if (o_Input->Mode() == TCP)
        {
            disconnect(o_Input, SIGNAL(sig_Disconnected(int)), 0, 0);
            disconnect(o_Input, SIGNAL(sig_Connected()), 0, 0);
        }
    }
}

// Neue Daten empfangen.
void dlg_Main::slot_Input_Data(QString t_Data)
{
    if ((t_Data[0] == '#'))
    {
        if ((HandlerMK::Check_CRC(t_Data.toLatin1().data(), t_Data.length() - 1)) || ((o_Input->Mode() == TTY)  && (HandlerMK::Check_CRC(t_Data.toLatin1().data(), t_Data.length()))))
        {
            parse_MK_Data(t_Data);
        }
        else
        {
            qDebug(QString("CRC-Error - " + t_Data).toLatin1().data());
        }
    }
    else if ((o_Input->Mode() == TCP) && (t_Data[0] == '$'))
    {
        parse_IP_Data(t_Data);
    }
}

void dlg_Main::slot_Input_Disconnected(int Error)
{
    cb_Server->setEnabled(true);
    le_Password->setEnabled(true);

    disconnect(o_Input, SIGNAL(sig_NewData(QString)), 0, 0);
    disconnect(o_Input, SIGNAL(sig_Disconnected(int)), 0, 0);
    disconnect(o_Input, SIGNAL(sig_Connected()), 0, 0);

    ac_Connect->setChecked(false);
    ac_Connect->setText(tr("Verbinden"));

    switch (Error)
    {
        case REMOTECLOSED :
        {
//            lb_Status->setText(tr("Verbindung vom Server beendet."));
            QMessageBox::warning(this, QA_NAME,tr("QMK-Datenserver: Verbindung wurde vom Server beendet."), QMessageBox::Ok);
        }
        break;
        case REFUSED :
        {
//            lb_Status->setText(tr("Server nicht gefunden."));
            QMessageBox::warning(this, QA_NAME,tr("QMK-Datenserver: Kann nicht zum Server verbinden."), QMessageBox::Ok);
        }
        break;
        case 3 :
        {
//            lb_Status->setText(tr("Serververbindung getrennt. Logindaten falsch."));
            QMessageBox::warning(this, QA_NAME,tr("QMK-Datenserver: Loginname oder Password falsch."), QMessageBox::Ok);
        }
        break;
        default :
        {
//            lb_Status->setText(tr("Getrennt vom QMK-Datenserver."));
        }
        break;
    }

}

void dlg_Main::slot_Input_Connected()
{
    connect(o_Input, SIGNAL(sig_NewData(QString)), this, SLOT(slot_Input_Data(QString)));

//    o_Input->send_Data(HandlerIP::make_Frame(ID_SCOPE, 101, QA_NAME + " " + QA_VERSION));
    o_Input->send_Data(HandlerMK::make_Frame('v', 0, c_Data, 0).toLatin1().data(), DATA_VERSION);
    ac_Connect->setText(tr("Trennen"));
}

// Programm Ende
dlg_Main::~dlg_Main()
{
    o_Settings->GUI.isMax       = isMaximized();
    o_Settings->GUI.Size        = size();
    o_Settings->GUI.Point       = pos();

    o_Settings->DATA.Debug_Intervall = sb_Intervall->value();

    o_Settings->SERVER.Password = le_Password->text();
    o_Settings->SERVER.IP_MAX  = cb_Server->count();
    o_Settings->SERVER.IP_ID   = cb_Server->currentIndex();

    for (int z = 0; z < cb_Server->count(); z++)
    {
        if (z < 10)
        {
            o_Settings->SERVER.IP[z] = cb_Server->itemText(z);
        }
    }

    o_Settings->write_Settings();

//    qDebug("Ende.");
}