source: ogBrowser-Git/src/mainwindow.cpp @ ac45929

jenkinsmain
Last change on this file since ac45929 was 59c8a0f, checked in by Ramón M. Gómez <ramongomez@…>, 6 years ago

#919: Fix bug with quotation marks in constants.

  • Property mode set to 100644
File size: 17.4 KB
RevLine 
[050d67a]1#include "mainwindow.h"
2#include <QtWebKit>
3#include <QStringList>
4#include <QWebView>
5#include <QDockWidget>
6#include <QtDebug>
7#include <QWebPage>
8#include <QProcess>
9#include <QTextEdit>
10#include <QMessageBox>
11#include <QPushButton>
12#include <QDateTime>
[23de05d]13#include <QProgressBar>
14#include <QTabWidget>
[2e2ba31]15#include <QLineEdit>
[2518513]16#include <QNetworkReply>
17#include <QSslError>
[75617e0]18#include <QTimer>
[d2c6ca7]19#include <libintl.h>
[050d67a]20
21#include "qtermwidget.h"
[099ac5d]22#include "digitalclock.h"
[050d67a]23
24#define BUFFERSIZE 2048
[9d6a1e3]25#define REGEXP_STRING "^\\[(\\d+)\\]"
[050d67a]26
[75617e0]27#define CURRENT_TIME() QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm:ss")
[050d67a]28
29MainWindow::MainWindow(QWidget *parent)
[b93c220]30    : QMainWindow(parent),m_web(new QWebView()),m_output(new QTextEdit()),
31      m_process(new QProcess(this)),
32      m_logfile(0),m_logstream(0),m_numberTerminal(0)
[050d67a]33{
34    // Graphic
[987869c]35    showFullScreen();
[099ac5d]36    setWindowTitle(tr("OpenGnsys Browser"));
[b93c220]37    setCentralWidget(m_web);
[0b5cc5a]38    readEnvironmentValues();
39
[75617e0]40    // Open the log file for append
41    if(m_env.contains("OGLOGFILE") && m_env["OGLOGFILE"]!="")
42    {
43        QFile* m_logfile=new QFile(m_env["OGLOGFILE"]);
44        if(!m_logfile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append))
45        {
46            delete m_logfile;
47            print(tr(gettext("El fichero de log no ha podido ser abierto: "))+m_env["OGLOGFILE"]+".");
48        }
49        else
50        {
51            m_logstream=new QTextStream(m_logfile);
52        }
53    }
54
[23de05d]55    // Output
[b93c220]56    m_output->setReadOnly(true);
[1b0403f]57    m_output->setFontPointSize(16);
[23de05d]58
[2e2ba31]59    // Button Dock
[23de05d]60    QDockWidget* dock=new QDockWidget();
[050d67a]61    dock->setAllowedAreas(Qt::BottomDockWidgetArea);
[23de05d]62    QWidget* dummy=new QWidget();
63    dummy->setMaximumHeight(0);
64    dock->setTitleBarWidget(dummy);
[050d67a]65
[23de05d]66    // TabWidget
[b93c220]67    m_tabs=new QTabWidget(dock);
[1ed6e72]68    QPushButton *button=new QPushButton(tr(gettext("&Nueva Terminal")));
[2e2ba31]69    button->setFocusPolicy(Qt::TabFocus);
[b93c220]70    m_tabs->setCornerWidget(button);
71    m_tabs->setFocusPolicy(Qt::NoFocus);
[f272f65]72    m_tabs->addTab(m_output,tr(gettext("Salida")));
[55d467e]73    slotCreateTerminal();
[0dff9e1]74    // Assign tabs to dock
[b93c220]75    dock->setWidget(m_tabs);
[0dff9e1]76    // Assign tabs dock to the mainwindow if admin mode is active
[9608e6e]77    if(m_env.contains("ogactiveadmin") && m_env["ogactiveadmin"] == "true")
[75617e0]78        addDockWidget(Qt::BottomDockWidgetArea,dock);
[050d67a]79
[2e2ba31]80    // Top Dock
81    dock=new QDockWidget();
82    dock->setAllowedAreas(Qt::TopDockWidgetArea);
83    QWidget* dummy2=new QWidget();
84    dummy2->setMaximumHeight(0);
85    dock->setTitleBarWidget(dummy2);
86    // WebBar
[b93c220]87    m_webBar=new QLineEdit(dock);
[0dff9e1]88    // WebBar to dock
[b93c220]89    dock->setWidget(m_webBar);
[0dff9e1]90    // Assign top dock to the mainwindow if admin mode is active
[9608e6e]91    if(m_env.contains("ogactiveadmin") && m_env["ogactiveadmin"] == "true")
[75617e0]92        addDockWidget(Qt::TopDockWidgetArea,dock);
[2e2ba31]93
[23de05d]94    // Status bar
95    QStatusBar* st=statusBar();
96    st->setSizeGripEnabled(false);
[c646cde]97    // OpenGnsys logo (or alternate text)
98    m_logo=new QLabel();
99    QPixmap logo;
[e9b8eab]100    if(logo.load("/opt/opengnsys/lib/pictures/oglogo.png"))
[75617e0]101        m_logo->setPixmap(logo);
[c646cde]102    else
[75617e0]103        m_logo->setText("OG");
[df98390]104    m_logo->setToolTip(tr(gettext("Proyecto OpenGnsys"))+"\nhttps://opengnsys.es");
[c646cde]105    // Progress bar
[b93c220]106    m_progressBar=new QProgressBar(this);
[0dff9e1]107    m_progressBar->setRange(0,100);
[c646cde]108    // Connection speed
109    QString speed=readSpeed();
110    m_speedInfo=new QLabel(speed);
111    m_speedInfo->setAlignment(Qt::AlignCenter);
[e9b8eab]112    if(m_env.contains("DEFAULTSPEED") && m_env["DEFAULTSPEED"]!="")
[75617e0]113        if(speed.compare(m_env["DEFAULTSPEED"])!=0)
114            m_speedInfo->setStyleSheet("background-color: darkred; color: white; font-weight: bold;");
[c646cde]115    // Clock
[099ac5d]116    m_clock=new DigitalClock(this);
[050d67a]117
[b93c220]118    m_web->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
[050d67a]119
120    // Web signals
[b93c220]121    connect(m_web,SIGNAL(linkClicked(const QUrl&)),this,
[050d67a]122            SLOT(slotLinkHandle(const QUrl&)));
[b93c220]123    connect(m_web,SIGNAL(loadStarted()),this,SLOT(slotWebLoadStarted()));
124    connect(m_web,SIGNAL(loadFinished(bool)),this,SLOT(slotWebLoadFinished(bool)));
125    connect(m_web,SIGNAL(loadProgress(int)),this,SLOT(slotWebLoadProgress(int)));
[c646cde]126    connect(m_web,SIGNAL(urlChanged(const QUrl&)),this,SLOT(slotUrlChanged(const QUrl&)));
[2518513]127    // Ignore SSL errors.
128    connect(m_web->page()->networkAccessManager(),
129            SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError> &)), this,
130            SLOT(slotSslErrors(QNetworkReply*)));
[050d67a]131
132    // Process signals
[b93c220]133    connect(m_process,SIGNAL(started()),this,SLOT(slotProcessStarted()));
134    connect(m_process,SIGNAL(finished(int,QProcess::ExitStatus)),
[050d67a]135            this,SLOT(slotProcessFinished(int,QProcess::ExitStatus)));
[b93c220]136    connect(m_process,SIGNAL(error(QProcess::ProcessError)),
[050d67a]137            this,SLOT(slotProcessError(QProcess::ProcessError)));
[b93c220]138    connect(m_process,SIGNAL(readyReadStandardOutput()),this,SLOT(slotProcessOutput()));
139    connect(m_process,SIGNAL(readyReadStandardError()),
[050d67a]140            this,SLOT(slotProcessErrorOutput()));
141
[2e2ba31]142    // Dock signals
[55d467e]143    connect(button,SIGNAL(clicked()),this,SLOT(slotCreateTerminal()));
[b93c220]144    connect(m_webBar,SIGNAL(returnPressed()),this,SLOT(slotWebBarReturnPressed()));
[55d467e]145
[2e2ba31]146    QStringList arguments=QCoreApplication::arguments();
[b93c220]147    m_webBar->setText(arguments[1]);
148    m_web->load(QUrl(arguments[1]));
[050d67a]149}
150
151MainWindow::~MainWindow()
152{
[b93c220]153    if(m_logfile)
[050d67a]154    {
[b93c220]155        m_logfile->close();
156        delete m_logfile;
[050d67a]157    }
[b93c220]158    if(m_logstream)
159        delete m_logstream;
[050d67a]160}
161
162void MainWindow::slotLinkHandle(const QUrl &url)
163{
[0dff9e1]164    // Check if it's executing another process
[1b0403f]165    if(m_process->state() != QProcess::NotRunning)
[23de05d]166    {
[75617e0]167        print(tr(gettext("Hay otro proceso en ejecución. Por favor espere.")));
168        return;
[23de05d]169    }
[b93c220]170    QString urlString = url.toString();
[1b0403f]171    QString urlScheme = url.scheme();
172    // Clear the output widget for a normal user
173    if(! m_env.contains("ogactiveadmin") || m_env["ogactiveadmin"] != "true")
[050d67a]174    {
[1b0403f]175        m_output->clear();
[9d6a1e3]176    }
[59c8a0f]177    if(urlScheme == COMMAND_CONFIRM || urlScheme == COMMAND_CONFIRM_OUTPUT ||
178       urlScheme == COMMAND_OUTPUT_CONFIRM || urlScheme == COMMAND_WITH_CONFIRMATION)
[9d6a1e3]179    {
[1b0403f]180        // For all command with confirmation links, show a popup box
[9d6a1e3]181        QMessageBox msgBox;
[75617e0]182        msgBox.setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
[1ed6e72]183        msgBox.setWindowTitle(tr(gettext("AVISO")));
[75617e0]184        msgBox.setIcon(QMessageBox::Question);
[553385e]185        msgBox.setTextFormat(Qt::RichText);
[1ed6e72]186        msgBox.setText(tr(gettext("La siguiente acci&oacute;n puede modificar datos o tardar varios minutos. El equipo no podr&aacute; ser utilizado durante su ejecuci&oacute;n.")));
187        QPushButton *execButton = msgBox.addButton(tr(gettext("Ejecutar")), QMessageBox::ActionRole);
188        msgBox.addButton(tr(gettext("Cancelar")), QMessageBox::RejectRole);
[2f7db25]189        msgBox.setDefaultButton(execButton);
190        msgBox.exec();
[1b0403f]191        // Continue if user press the execution button
[2f7db25]192        if (msgBox.clickedButton() == execButton)
[9d6a1e3]193        {
[1b0403f]194            // For command with confirmation and output link, show an output window to non-admin user
[59c8a0f]195            if((urlScheme == COMMAND_CONFIRM_OUTPUT || urlScheme == COMMAND_OUTPUT_CONFIRM) &&
[1b0403f]196               (! m_env.contains("ogactiveadmin") || m_env["ogactiveadmin"] != "true"))
197            {
198                int w=MainWindow::width(), h=MainWindow::height();
199                m_output->setWindowFlags(Qt::Window);
200                m_output->move(100, 100);
201                m_output->setFixedSize(w*0.8-100, h*0.8-100);
202                m_output->show();
203            }
204            // Execute the command
205            executeCommand(urlString.remove(0, urlScheme.length()+1));
[9d6a1e3]206        }
[050d67a]207    }
[59c8a0f]208    else if(urlScheme == COMMAND || urlScheme == COMMAND_OUTPUT)
[1b0403f]209    {
210        // For command with output link, show an output window to non-admin user
[59c8a0f]211        if(urlScheme == COMMAND_OUTPUT &&
[1b0403f]212           (! m_env.contains("ogactiveadmin") || m_env["ogactiveadmin"] != "true"))
213        {
214            int w=MainWindow::width(), h=MainWindow::height();
215            m_output->setWindowFlags(Qt::Window);
216            m_output->move(100, 100);
217            m_output->setFixedSize(w*0.8-100, h*0.8-100);
218            m_output->show();
219        }
220        // Execute the command
221        executeCommand(urlString.remove(0, urlScheme.length()+1));
222    }
[050d67a]223    else
224    {
[0dff9e1]225        // For other link, load webpage
[b93c220]226        m_web->load(url);
[050d67a]227    }
228}
229
230void MainWindow::slotWebLoadStarted()
231{
[9d8d163]232    startProgressBar();
[1ed6e72]233    m_progressBar->setFormat(gettext("%p% Cargando"));
[050d67a]234}
235
236void MainWindow::slotWebLoadProgress(int progress)
237{
[b93c220]238    m_progressBar->setValue(progress);
[050d67a]239}
240
241void MainWindow::slotWebLoadFinished(bool ok)
242{
243    // If any error ocurred, show a pop up
244    // Sometimes when the url hasn't got a dot, i.e /var/www/pageweb,
245    // the return value is always true so we check the bytes received too
[e443ace]246    if(ok == false)
[050d67a]247    {
248        QMessageBox msgBox;
[75617e0]249        msgBox.setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
[1ed6e72]250        msgBox.setWindowTitle(tr(gettext("AVISO")));
[75617e0]251        msgBox.setIcon(QMessageBox::Question);
[2f7db25]252        msgBox.setTextFormat(Qt::RichText);
[1ed6e72]253        msgBox.setText(tr(gettext("La p&aacute;gina no se puede cargar.")));
[050d67a]254
[1ed6e72]255        QPushButton *reloadButton = msgBox.addButton(tr(gettext("Recargar")), QMessageBox::ActionRole);
256        msgBox.addButton(tr(gettext("Abortar")), QMessageBox::RejectRole);
[050d67a]257        msgBox.exec();
258
259        if (msgBox.clickedButton() == reloadButton)
260        {
[b93c220]261            m_web->reload();
[050d67a]262        }
263        else
264        {
265            close();
266        }
267    }
268    else
[23de05d]269    {
[9d8d163]270        finishProgressBar();
[23de05d]271    }
[050d67a]272}
273
[2e2ba31]274void MainWindow::slotUrlChanged(const QUrl &url)
275{
[b93c220]276    m_webBar->setText(url.toString());
[2e2ba31]277}
278
[2518513]279void MainWindow::slotSslErrors(QNetworkReply* reply)
280{
281    reply->ignoreSslErrors();
282}
283
[050d67a]284void MainWindow::slotProcessStarted()
285{
[9d8d163]286    startProgressBar();
[050d67a]287}
288
289void MainWindow::slotProcessOutput()
290{
[b93c220]291    m_process->setReadChannel(QProcess::StandardOutput);
[050d67a]292    char buf[BUFFERSIZE];
[b93c220]293    while((m_process->readLine(buf,BUFFERSIZE) > 0))
[050d67a]294    {
[9d8d163]295        QString s(buf);
[1b0403f]296        if(m_env.contains("ogactiveadmin") && m_env["ogactiveadmin"] == "true")
297        {
298            m_output->insertPlainText(tr("Proc. stdout: "));
299        }
300        print(s);
[9d8d163]301        captureOutputForStatusBar(s);
[050d67a]302    }
303}
304
305void MainWindow::slotProcessErrorOutput()
306{
[b93c220]307    m_process->setReadChannel(QProcess::StandardError);
[050d67a]308    char buf[BUFFERSIZE];
[b93c220]309    while((m_process->readLine(buf,BUFFERSIZE) > 0))
[050d67a]310    {
[1fc67a0]311        QString s(buf);
[1b0403f]312        if(m_env.contains("ogactiveadmin") && m_env["ogactiveadmin"] == "true")
313        {
314            m_output->insertPlainText(tr("Proc. stderr: "));
315        }
[2f7db25]316        m_output->setTextColor(QColor(Qt::darkBlue));
317        print(s);
318        m_output->setTextColor(QColor(Qt::black));
[050d67a]319    }
320}
321
[1b0403f]322void MainWindow::slotProcessFinished(int code, QProcess::ExitStatus status)
[050d67a]323{
[1b0403f]324    if(m_env.contains("ogactiveadmin") && m_env["ogactiveadmin"] == "true")
[050d67a]325    {
[1b0403f]326        // Admin user: show process status
327        if(status==QProcess::NormalExit)
328        {
329            if(code > 0)
[59c8a0f]330            {
[1b0403f]331                m_output->setTextColor(QColor(Qt::darkRed));
[59c8a0f]332            }
[1b0403f]333            print("\n"+tr(gettext("Fin del proceso. Valor de retorno: "))+QString::number(code));
334        }
335        else
336        {
337            m_output->setTextColor(QColor(Qt::darkRed));
338            print("\n"+tr(gettext("El proceso ha fallado inesperadamente. Salida: ")+code));
339        }
340        m_output->setTextColor(QColor(Qt::black));
[050d67a]341    }
342    else
343    {
[1b0403f]344        // Non-admin user: show instruction to close the popup window
345        write(tr(gettext("Fin del proceso. Valor de retorno: "))+QString::number(code));
346        m_output->setFontUnderline(true);
347        print("\n\n"+tr(gettext("AVISO: Pulsar el botón superior derecho para cerrar"))+" [X]");
348        m_output->setFontUnderline(false);
[050d67a]349    }
[75617e0]350    // On error, show a message box
[1b0403f]351    if(code > 0 && ! m_output->isActiveWindow())
352    {
[75617e0]353        showErrorMessage(gettext("Código de salida: ")+QString::number(code));
[1b0403f]354    }
[9d8d163]355    finishProgressBar();
[050d67a]356}
357
358void MainWindow::slotProcessError(QProcess::ProcessError error)
359{
[75617e0]360    QString errorMsg;
[050d67a]361    switch(error)
362    {
363        case QProcess::FailedToStart:
[75617e0]364            errorMsg=tr(gettext("Imposible lanzar el proceso."));
[b93c220]365            break;
366        case QProcess::WriteError:
[75617e0]367            errorMsg=tr(gettext("Error de escritura en el proceso."));
[b93c220]368            break;
369        case QProcess::ReadError:
[75617e0]370            errorMsg=tr(gettext("Error de lectura del proceso."));
[050d67a]371            break;
372        // No capturo crashed porque la pillo por finished
373        case QProcess::Crashed:
374        case QProcess::Timedout:
[b93c220]375            break;
[050d67a]376        case QProcess::UnknownError:
377        default:
[75617e0]378            errorMsg=tr(gettext("Error desconocido."));
[050d67a]379            break;
380    }
[75617e0]381    // Print error and show message box with timeout.
382    if(!errorMsg.isNull()) {
383        m_output->setTextColor(QColor(Qt::darkRed));
384        print(errorMsg);
385        m_output->setTextColor(QColor(Qt::black));
386        showErrorMessage(errorMsg);
387    }
[c70d4be]388    finishProgressBar();
[050d67a]389}
390
[55d467e]391void MainWindow::slotCreateTerminal()
392{
[2e2ba31]393    QTermWidget* console = new QTermWidget(1,this);
[55d467e]394    QFont font = QApplication::font();
[5656dd1]395    font.setFamily("DejaVu Sans Mono");
[55d467e]396    font.setPointSize(12);
397   
398    console->setTerminalFont(font);
[2e2ba31]399    console->setFocusPolicy(Qt::StrongFocus);
[55d467e]400    console->setScrollBarPosition(QTermWidget::ScrollBarRight);
401
[b93c220]402    ++m_numberTerminal;
[55d467e]403
[2e2ba31]404    connect(console,SIGNAL(finished()),this,SLOT(slotDeleteTerminal()));
405
[b93c220]406    QString name=tr("Term ")+QString::number(m_numberTerminal);
407    m_tabs->addTab(console,name);
[55d467e]408}
409
[2e2ba31]410void MainWindow::slotDeleteTerminal()
411{
[b93c220]412    QWidget *widget = qobject_cast<QWidget *>(sender());
413    Q_ASSERT(widget);
414    m_tabs->removeTab(m_tabs->indexOf(widget));
415    delete widget;
[2e2ba31]416}
417
418void MainWindow::slotWebBarReturnPressed()
419{
[b93c220]420    QUrl url(m_webBar->text());
421    if(url.isValid())
[75617e0]422        slotLinkHandle(url);
[2e2ba31]423}
424
[050d67a]425int MainWindow::readEnvironmentValues()
426{
427    // The return value
428    int ret=true;
429
430    // Get all environment variables
431    QStringList environmentlist=QProcess::systemEnvironment();
432    // This is the list of the important variables
433    QStringList variablelist=QString(ENVIRONMENT).split(",");
434
435    // This is an auxiliar variable
436    QStringList stringlist;
437
438    foreach (QString str,variablelist)
439    {
440        // Look for the variable in the environment
441        stringlist=environmentlist.filter(str+"=");
442
443        if(stringlist.isEmpty())
444        {
[b93c220]445            m_env[str]="";
[050d67a]446            ret=false;
447        }
448        else
449        {
450            // Get the first element and get the value part
[b93c220]451            m_env[str]=(stringlist.first().split("="))[1];
[050d67a]452        }
453    }
454
455    return ret;
456}
[b93c220]457
[1b0403f]458// Write a string to the log file
459void MainWindow::write(QString s)
[b93c220]460{
[1b0403f]461    if(! s.endsWith("\n"))
[75617e0]462        s+="\n";
463    if(m_logstream)
464    {
465        *m_logstream<<CURRENT_TIME()<<": browser: "<<s;
466        m_logstream->flush();
467    }
[1b0403f]468}
469
470// Print and log a string
471void MainWindow::print(QString s)
472{
473    if(! s.endsWith("\n"))
474        s+="\n";
475    write(s);
[75617e0]476    if(m_output)
477        m_output->insertPlainText(s);
[b93c220]478}
[9d8d163]479
[1b0403f]480// Show message in status bar
[9d8d163]481void MainWindow::captureOutputForStatusBar(QString output)
482{
[1b0403f]483    // Modify the status bar
[75617e0]484    output=output.trimmed();
[1b0403f]485    // Get percentage (string starts with "[Number]")
[75617e0]486    QRegExp regexp(REGEXP_STRING);
487    if(regexp.indexIn(output) != -1)
488    {
489        int pass=regexp.cap(1).toInt();
490        output.replace(regexp,"");
491        m_progressBar->setValue(pass);
492        m_progressBar->setFormat("%p%"+output);
493    }
[9d8d163]494}
495
[c646cde]496// Init status bar
[9d8d163]497void MainWindow::startProgressBar()
498{
499    QStatusBar* st=statusBar();
500    st->clearMessage();
[c646cde]501    st->addWidget(m_logo);
[099ac5d]502    st->addWidget(m_progressBar,90);
[c646cde]503    st->addWidget(m_speedInfo,5);
504    st->addWidget(m_clock,5);
[9d8d163]505    m_progressBar->show();
[099ac5d]506    m_clock->show();
[9d8d163]507    m_web->setEnabled(false);
508}
509
[1b0403f]510// Reset status bar
[9d8d163]511void MainWindow::finishProgressBar()
512{
[0dff9e1]513    m_progressBar->reset();
[9d8d163]514    m_web->setEnabled(true);
515}
[9d6a1e3]516
[1b0403f]517// Execute a command
[9d6a1e3]518void MainWindow::executeCommand(QString &string)
519{
520    QStringList list=string.split(" ",QString::SkipEmptyParts);
521    QString program=list.takeFirst();
522    m_process->setReadChannel(QProcess::StandardOutput);
[c646cde]523    // Assign the same Browser's environment to the process
[9d6a1e3]524    m_process->setEnvironment(QProcess::systemEnvironment());
525    m_process->start(program,list);
[1b0403f]526    // Only show the command line to admin user
527    if(m_env.contains("ogactiveadmin") && m_env["ogactiveadmin"] == "true")
528    {
529        m_output->setTextColor(QColor(Qt::darkGreen));
530        print(tr(gettext("Lanzando el comando: "))+string);
531        m_output->setTextColor(QColor(Qt::black));
532    }
533    else
534    {
535        write(tr(gettext("Lanzando el comando: "))+string);
536    }
[9d6a1e3]537    startProgressBar();
538}
[c646cde]539
540// Returns communication speed
541QString MainWindow::readSpeed() {
542    if(m_env.contains("OGLOGFILE"))
543    {
544        QString infoFile=m_env["OGLOGFILE"].replace(".log", ".info.html");
[e9b8eab]545        QString command="grep -hoe \"[0-9]*Mb/s\" "+infoFile+" 2>/dev/null";
[c646cde]546        QProcess process;
547        process.start(command);
548        process.waitForFinished();
549        QString speed(process.readAllStandardOutput());
550        return speed.simplified();
551    }
552    else
553    {
554        return QString("");
555    }
556}
[75617e0]557
558// Show an error box with timeout
559void MainWindow::showErrorMessage(QString text)
560{
561    QMessageBox* msgBox=new QMessageBox();
562    msgBox->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
563    msgBox->setWindowTitle(gettext("ERROR"));
564    msgBox->setIcon(QMessageBox::Warning);
565    msgBox->setText(text);
566    msgBox->show();
567    QTimer::singleShot(5000, msgBox, SLOT(close()));
568}
Note: See TracBrowser for help on using the repository browser.