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