XMLCommProtocolWidget.cc 5.72 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2 3
#include <QFileDialog>
#include <QTextBrowser>
#include <QMessageBox>
4
#include <QSettings>
pixhawk's avatar
pixhawk committed
5 6 7 8

#include "XMLCommProtocolWidget.h"
#include "ui_XMLCommProtocolWidget.h"
#include "MAVLinkXMLParser.h"
9
#include "MAVLinkSyntaxHighlighter.h"
10
#include "QGC.h"
pixhawk's avatar
pixhawk committed
11 12 13 14 15

#include <QDebug>
#include <iostream>

XMLCommProtocolWidget::XMLCommProtocolWidget(QWidget *parent) :
16 17
    QWidget(parent),
    m_ui(new Ui::XMLCommProtocolWidget)
pixhawk's avatar
pixhawk committed
18 19 20
{
    m_ui->setupUi(this);

21
    // Now set syntax highlighter
22
    //highlighter = new MAVLinkSyntaxHighlighter(m_ui->xmlTextView->document());
23

pixhawk's avatar
pixhawk committed
24 25 26 27 28 29 30 31 32
    connect(m_ui->selectFileButton, SIGNAL(clicked()), this, SLOT(selectXMLFile()));
    connect(m_ui->selectOutputButton, SIGNAL(clicked()), this, SLOT(selectOutputDirectory()));
    connect(m_ui->generateButton, SIGNAL(clicked()), this, SLOT(generate()));
    connect(m_ui->saveButton, SIGNAL(clicked()), this, SLOT(save()));
}

void XMLCommProtocolWidget::selectXMLFile()
{
    //QString fileName = QFileDialog::getOpenFileName(this, tr("Load Protocol Definition File"), ".", "*.xml");
33
    QSettings settings(QGC::COMPANYNAME, QGC::APPNAME);
34 35
    const QString mavlinkXML = "MAVLINK_XML_FILE";
    QString dirPath = settings.value(mavlinkXML, QCoreApplication::applicationDirPath() + "../").toString();
36
    QFileInfo dir(dirPath);
pixhawk's avatar
pixhawk committed
37
    QFileDialog dialog;
38
    dialog.setDirectory(dir.absoluteDir());
pixhawk's avatar
pixhawk committed
39 40 41 42
    dialog.setFileMode(QFileDialog::AnyFile);
    dialog.setFilter(tr("MAVLink XML (*.xml)"));
    dialog.setViewMode(QFileDialog::Detail);
    QStringList fileNames;
43
    if (dialog.exec()) {
pixhawk's avatar
pixhawk committed
44 45 46
        fileNames = dialog.selectedFiles();
    }

47
    if (fileNames.size() > 0) {
pixhawk's avatar
pixhawk committed
48 49
        m_ui->fileNameLabel->setText(fileNames.first());
        QFile file(fileNames.first());
50

51
        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
pixhawk's avatar
pixhawk committed
52 53
            const QString instanceText(QString::fromUtf8(file.readAll()));
            setXML(instanceText);
54 55
            // Store filename for next time
            settings.setValue(mavlinkXML, QFileInfo(file).absoluteFilePath());
56
            settings.sync();
57
        } else {
pixhawk's avatar
pixhawk committed
58
            QMessageBox msgBox;
59
            msgBox.setText("Could not read XML file. Permission denied");
pixhawk's avatar
pixhawk committed
60 61 62 63 64 65 66 67 68 69
            msgBox.exec();
        }
    }
}

void XMLCommProtocolWidget::setXML(const QString& xml)
{
    m_ui->xmlTextView->setText(xml);
    QDomDocument doc;

70
    if (doc.setContent(xml)) {
71
        m_ui->validXMLLabel->setText(tr("<font color=\"green\">Valid XML file</font>"));
72
    } else {
73
        m_ui->validXMLLabel->setText(tr("<font color=\"red\">File is NOT valid XML, please fix in editor</font>"));
pixhawk's avatar
pixhawk committed
74 75
    }

76
    if (model != NULL) {
pixhawk's avatar
pixhawk committed
77 78 79 80 81
        m_ui->xmlTreeView->reset();
        //delete model;
    }
    model = new DomModel(doc, this);
    m_ui->xmlTreeView->setModel(model);
82
    m_ui->xmlTreeView->expandAll();
pixhawk's avatar
pixhawk committed
83 84 85 86 87
    m_ui->xmlTreeView->repaint();
}

void XMLCommProtocolWidget::selectOutputDirectory()
{
88
    QSettings settings(QGC::COMPANYNAME, QGC::APPNAME);
89 90
    const QString mavlinkOutputDir = "MAVLINK_OUTPUT_DIR";
    QString dirPath = settings.value(mavlinkOutputDir, QCoreApplication::applicationDirPath() + "../").toString();
pixhawk's avatar
pixhawk committed
91
    QFileDialog dialog;
92
    dialog.setDirectory(dirPath);
pixhawk's avatar
pixhawk committed
93 94 95
    dialog.setFileMode(QFileDialog::Directory);
    dialog.setViewMode(QFileDialog::Detail);
    QStringList fileNames;
96
    if (dialog.exec()) {
pixhawk's avatar
pixhawk committed
97 98 99
        fileNames = dialog.selectedFiles();
    }

100
    if (fileNames.size() > 0) {
pixhawk's avatar
pixhawk committed
101
        m_ui->outputDirNameLabel->setText(fileNames.first());
102
        // Store directory for next time
103
        settings.setValue(mavlinkOutputDir, QFileInfo(fileNames.first()).absoluteFilePath());
104
        settings.sync();
pixhawk's avatar
pixhawk committed
105 106 107 108 109 110
        //QFile file(fileName);
    }
}

void XMLCommProtocolWidget::generate()
{
111
    // Check if input file is present
112
    if (!QFileInfo(m_ui->fileNameLabel->text().trimmed()).isFile()) {
113 114 115 116 117
        QMessageBox::critical(this, tr("Please select an XML input file first"), tr("You have to select an input XML file before generating C files."), QMessageBox::Ok);
        return;
    }

    // Check if output dir is selected
118
    if (!QFileInfo(m_ui->outputDirNameLabel->text().trimmed()).isDir()) {
119 120 121 122
        QMessageBox::critical(this, tr("Please select output directory first"), tr("You have to select an output directory before generating C files."), QMessageBox::Ok);
        return;
    }

pixhawk's avatar
pixhawk committed
123 124
    // First save file
    save();
125 126
    // Clean log
    m_ui->compileLog->clear();
127

128 129 130
    // Check XML validity
    if (!m_ui->xmlTextView->syntaxcheck()) return;

131 132 133
    MAVLinkXMLParser* parser = new MAVLinkXMLParser(m_ui->fileNameLabel->text().trimmed(), m_ui->outputDirNameLabel->text().trimmed());
    connect(parser, SIGNAL(parseState(QString)), m_ui->compileLog, SLOT(appendHtml(QString)));
    bool result = parser->generate();
134
    if (result) {
pixhawk's avatar
pixhawk committed
135 136 137
        QMessageBox msgBox;
        msgBox.setText(QString("The C code / headers have been generated in folder\n%1").arg(m_ui->outputDirNameLabel->text().trimmed()));
        msgBox.exec();
138
    } else {
139
        QMessageBox::critical(this, tr("C code generation failed, please see the compile log for further information"), QString("The C code / headers could not be written to folder\n%1").arg(m_ui->outputDirNameLabel->text().trimmed()), QMessageBox::Ok);
pixhawk's avatar
pixhawk committed
140
    }
141
    delete parser;
pixhawk's avatar
pixhawk committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
}

void XMLCommProtocolWidget::save()
{
    QFile file(m_ui->fileNameLabel->text().trimmed());
    setXML(m_ui->xmlTextView->document()->toPlainText().toUtf8());
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    file.write(m_ui->xmlTextView->document()->toPlainText().toUtf8());
}

XMLCommProtocolWidget::~XMLCommProtocolWidget()
{
    delete model;
    delete m_ui;
}

void XMLCommProtocolWidget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}