diff options
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | data/minecraftprocess.cpp | 38 | ||||
-rw-r--r-- | data/minecraftprocess.h | 6 | ||||
-rw-r--r-- | gui/consolewindow.cpp | 73 | ||||
-rw-r--r-- | gui/consolewindow.h | 69 | ||||
-rw-r--r-- | gui/consolewindow.ui | 66 | ||||
-rw-r--r-- | main.cpp | 13 |
7 files changed, 257 insertions, 11 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 03f1f514..070dcc15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,6 +165,7 @@ gui/logindialog.h gui/taskdialog.h gui/browserdialog.h gui/aboutdialog.h +gui/consolewindow.h data/version.h data/userinfo.h @@ -208,6 +209,7 @@ gui/logindialog.cpp gui/taskdialog.cpp gui/browserdialog.cpp gui/aboutdialog.cpp +gui/consolewindow.cpp java/javautils.cpp java/annotations.cpp @@ -228,6 +230,7 @@ gui/logindialog.ui gui/taskdialog.ui gui/browserdialog.ui gui/aboutdialog.ui +gui/consolewindow.ui ) diff --git a/data/minecraftprocess.cpp b/data/minecraftprocess.cpp index 4cbe7208..d08b767c 100644 --- a/data/minecraftprocess.cpp +++ b/data/minecraftprocess.cpp @@ -117,9 +117,33 @@ MinecraftProcess::MinecraftProcess(InstancePtr inst, QString user, QString sessi this->setWorkingDirectory(mcDir.absolutePath()); m_prepostlaunchprocess.setWorkingDirectory(mcDir.absolutePath()); - //TODO: do console redirection + // std channels + connect(this, SIGNAL(readyReadStandardError()), SLOT(on_stdErr())); + connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut())); } +// console window +void MinecraftProcess::on_stdErr() +{ + if (m_console != nullptr) + m_console->write(readAllStandardError(), ConsoleWindow::ERROR); +} + +void MinecraftProcess::on_stdOut() +{ + if (m_console != nullptr) + m_console->write(readAllStandardOutput(), ConsoleWindow::DEFAULT); +} + +void MinecraftProcess::log(QString text) +{ + if (m_console != nullptr) + m_console->write(text); + else + qDebug(qPrintable(text)); +} + +// exit handler void MinecraftProcess::finish(int code, ExitStatus status) { if (status != NormalExit) @@ -127,6 +151,8 @@ void MinecraftProcess::finish(int code, ExitStatus status) //TODO: error handling } + log("Minecraft exited."); + m_prepostlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(code)); // run post-exit @@ -140,6 +166,9 @@ void MinecraftProcess::finish(int code, ExitStatus status) } } + if (m_console != nullptr) + m_console->setMayClose(true); + emit ended(); } @@ -162,14 +191,17 @@ void MinecraftProcess::launch() genArgs(); - qDebug("Minecraft folder is: '%s'", qPrintable(workingDirectory())); - qDebug("Instance launched with arguments: '%s'", qPrintable(m_arguments.join("' '"))); + log(QString("Minecraft folder is: '%1'").arg(workingDirectory())); + log(QString("Instance launched with arguments: '%1'").arg(m_arguments.join("' '"))); start(m_instance->getJavaPath(), m_arguments); if (!waitForStarted()) { //TODO: error handling } + + if(m_console != nullptr) + m_console->setMayClose(false); } void MinecraftProcess::genArgs() diff --git a/data/minecraftprocess.h b/data/minecraftprocess.h index 99a3bed6..bede9486 100644 --- a/data/minecraftprocess.h +++ b/data/minecraftprocess.h @@ -19,7 +19,7 @@ #include <QProcess> -class ConsoleWindow; +#include "gui/consolewindow.h" #include "instance.h" @@ -86,9 +86,13 @@ protected: QStringList m_arguments; void genArgs(); + void log(QString text); protected slots: void finish(int, QProcess::ExitStatus status); + void on_stdErr(); + void on_stdOut(); + }; #endif // MINECRAFTPROCESS_H diff --git a/gui/consolewindow.cpp b/gui/consolewindow.cpp new file mode 100644 index 00000000..1d84fe04 --- /dev/null +++ b/gui/consolewindow.cpp @@ -0,0 +1,73 @@ +#include "consolewindow.h" +#include "ui_consolewindow.h" + +#include <QScrollBar> + +ConsoleWindow::ConsoleWindow(QWidget *parent) : + QDialog(parent), + ui(new Ui::ConsoleWindow), + m_mayclose(true) +{ + ui->setupUi(this); +} + +ConsoleWindow::~ConsoleWindow() +{ + delete ui; +} + +void ConsoleWindow::writeColor(QString text, const char *color) +{ + // append a paragraph + if (color != nullptr) + ui->text->appendHtml(QString("<font color=%1>%2</font>").arg(color).arg(text)); + else + ui->text->appendPlainText(text); + // scroll down + QScrollBar *bar = ui->text->verticalScrollBar(); + bar->setValue(bar->maximum()); +} + +void ConsoleWindow::write(QString data, WriteMode mode) +{ + if (data.endsWith('\n')) + data = data.left(data.length()-1); + QStringList paragraphs = data.split('\n'); + QListIterator<QString> iter(paragraphs); + if (mode == MULTIMC) + while(iter.hasNext()) + writeColor(iter.next(), "blue"); + else if (mode == ERROR) + while(iter.hasNext()) + writeColor(iter.next(), "red"); + else + while(iter.hasNext()) + writeColor(iter.next()); +} + +void ConsoleWindow::clear() +{ + ui->text->clear(); +} + +void ConsoleWindow::on_closeButton_clicked() +{ + close(); +} + +void ConsoleWindow::setMayClose(bool mayclose) +{ + m_mayclose = mayclose; + if (mayclose) + ui->closeButton->setEnabled(true); + else + ui->closeButton->setEnabled(false); +} + +void ConsoleWindow::closeEvent(QCloseEvent * event) +{ + if(!m_mayclose) + event->ignore(); + else + QDialog::closeEvent(event); +} diff --git a/gui/consolewindow.h b/gui/consolewindow.h new file mode 100644 index 00000000..1d322afb --- /dev/null +++ b/gui/consolewindow.h @@ -0,0 +1,69 @@ +#ifndef CONSOLEWINDOW_H +#define CONSOLEWINDOW_H + +#include <QDialog> + +namespace Ui { +class ConsoleWindow; +} + +class ConsoleWindow : public QDialog +{ + Q_OBJECT + +public: + /** + * @brief The WriteMode enum + * defines how stuff is displayed + */ + enum WriteMode { + DEFAULT, + ERROR, + MULTIMC + }; + + explicit ConsoleWindow(QWidget *parent = 0); + ~ConsoleWindow(); + + /** + * @brief specify if the window is allowed to close + * @param mayclose + * used to keep it alive while MC runs + */ + void setMayClose(bool mayclose); + +public slots: + /** + * @brief write a string + * @param data the string + * @param mode the WriteMode + * lines have to be put through this as a whole! + */ + void write(QString data, WriteMode mode=MULTIMC); + + /** + * @brief write a colored paragraph + * @param data the string + * @param color the css color name + * this will only insert a single paragraph. + * \n are ignored. a real \n is always appended. + */ + void writeColor(QString data, const char *color=nullptr); + + /** + * @brief clear the text widget + */ + void clear(); + +private slots: + void on_closeButton_clicked(); + +protected: + void closeEvent(QCloseEvent *); + +private: + Ui::ConsoleWindow *ui; + bool m_mayclose; +}; + +#endif // CONSOLEWINDOW_H diff --git a/gui/consolewindow.ui b/gui/consolewindow.ui new file mode 100644 index 00000000..f8c87aa0 --- /dev/null +++ b/gui/consolewindow.ui @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ConsoleWindow</class> + <widget class="QDialog" name="ConsoleWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>400</height> + </rect> + </property> + <property name="windowTitle"> + <string>MultiMC Console</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPlainTextEdit" name="text"> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="undoRedoEnabled"> + <bool>false</bool> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="plainText"> + <string notr="true"/> + </property> + <property name="centerOnScroll"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="closeButton"> + <property name="text"> + <string>Close</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> @@ -24,6 +24,7 @@ #include "gui/mainwindow.h" #include "gui/logindialog.h" #include "gui/taskdialog.h" +#include "gui/consolewindow.h" #include "instancelist.h" #include "appsettings.h" @@ -49,6 +50,7 @@ private: QString instId; InstancePtr instance; MinecraftProcess *proc; + ConsoleWindow *console; public: InstanceLauncher(QString instId) : QObject(), instances(settings->getInstanceDir()) { @@ -82,15 +84,12 @@ private slots: void onLoginComplete(LoginResponse response) { // TODO: console - proc = new MinecraftProcess(instance, response.getUsername(), response.getSessionID(), nullptr); + console = new ConsoleWindow(); + proc = new MinecraftProcess(instance, response.getUsername(), response.getSessionID(), console); + //if (instance->getShowConsole()) + console->show(); connect(proc, SIGNAL(ended()), SLOT(onTerminated())); proc->launch(); - /*if (proc->pid() == 0) - { - std::cout << "Could not start instance." << std::endl; - QApplication::instance()->quit(); - return; - }*/ } void doLogin(const QString &errorMsg) |