Redo the console window. Log is now a page. Console window has relevant pages.
Dirty fix for screenshot thumbnail generation. Needs more QTimer.
This commit is contained in:
@ -14,27 +14,117 @@
|
||||
*/
|
||||
|
||||
#include "ConsoleWindow.h"
|
||||
#include "ui_ConsoleWindow.h"
|
||||
#include "MultiMC.h"
|
||||
|
||||
#include <QScrollBar>
|
||||
#include <QMessageBox>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <qlayoutitem.h>
|
||||
|
||||
#include <gui/Platform.h>
|
||||
#include <gui/dialogs/CustomMessageBox.h>
|
||||
#include <gui/dialogs/ProgressDialog.h>
|
||||
#include "widgets/PageContainer.h"
|
||||
#include "pages/LogPage.h"
|
||||
|
||||
#include "logic/net/PasteUpload.h"
|
||||
#include "logic/icons/IconList.h"
|
||||
|
||||
class LogPageProvider : public BasePageProvider
|
||||
{
|
||||
public:
|
||||
LogPageProvider(BasePageProviderPtr parent, BasePage * log_page)
|
||||
{
|
||||
m_parent = parent;
|
||||
m_log_page = log_page;
|
||||
}
|
||||
virtual QString dialogTitle() {return "Fake";};
|
||||
virtual QList<BasePage *> getPages()
|
||||
{
|
||||
auto pages = m_parent->getPages();
|
||||
pages.prepend(m_log_page);
|
||||
return pages;
|
||||
}
|
||||
private:
|
||||
BasePageProviderPtr m_parent;
|
||||
BasePage * m_log_page;
|
||||
};
|
||||
|
||||
ConsoleWindow::ConsoleWindow(MinecraftProcess *mcproc, QWidget *parent)
|
||||
: QMainWindow(parent), ui(new Ui::ConsoleWindow), proc(mcproc)
|
||||
: QMainWindow(parent), m_proc(mcproc)
|
||||
{
|
||||
MultiMCPlatform::fixWM_CLASS(this);
|
||||
ui->setupUi(this);
|
||||
connect(mcproc, SIGNAL(log(QString, MessageLevel::Enum)), this,
|
||||
SLOT(write(QString, MessageLevel::Enum)));
|
||||
|
||||
auto instance = m_proc->instance();
|
||||
auto icon = MMC->icons()->getIcon(instance->iconKey());
|
||||
QString windowTitle = tr("Console window for ") + instance->name();
|
||||
|
||||
// Set window properties
|
||||
{
|
||||
setWindowIcon(icon);
|
||||
setWindowTitle(windowTitle);
|
||||
}
|
||||
|
||||
// Add page container
|
||||
{
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
auto provider = std::dynamic_pointer_cast<BasePageProvider>(m_proc->instance());
|
||||
auto proxy_provider = std::make_shared<LogPageProvider>(provider, new LogPage(m_proc));
|
||||
m_container = new PageContainer(proxy_provider, "console", this);
|
||||
mainLayout->addWidget(m_container);
|
||||
mainLayout->setSpacing(0);
|
||||
mainLayout->setContentsMargins(0,0,0,0);
|
||||
setLayout(mainLayout);
|
||||
setCentralWidget(m_container);
|
||||
}
|
||||
|
||||
// Add custom buttons to the page container layout.
|
||||
{
|
||||
auto horizontalLayout = new QHBoxLayout();
|
||||
horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
|
||||
horizontalLayout->setContentsMargins(6, -1, 6, -1);
|
||||
|
||||
auto btnHelp = new QPushButton();
|
||||
btnHelp->setText(tr("Help"));
|
||||
horizontalLayout->addWidget(btnHelp);
|
||||
connect(btnHelp, SIGNAL(clicked(bool)), m_container, SLOT(help()));
|
||||
|
||||
auto spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
horizontalLayout->addSpacerItem(spacer);
|
||||
|
||||
m_killButton = new QPushButton();
|
||||
m_killButton->setText(tr("Kill Minecraft"));
|
||||
horizontalLayout->addWidget(m_killButton);
|
||||
connect(m_killButton, SIGNAL(clicked(bool)), SLOT(on_btnKillMinecraft_clicked()));
|
||||
|
||||
m_closeButton = new QPushButton();
|
||||
m_closeButton->setText(tr("Close"));
|
||||
horizontalLayout->addWidget(m_closeButton);
|
||||
connect(m_closeButton, SIGNAL(clicked(bool)), SLOT(on_closeButton_clicked()));
|
||||
|
||||
m_container->addButtons(horizontalLayout);
|
||||
}
|
||||
|
||||
// restore window state
|
||||
{
|
||||
auto base64State = MMC->settings()->get("ConsoleWindowState").toByteArray();
|
||||
restoreState(QByteArray::fromBase64(base64State));
|
||||
auto base64Geometry = MMC->settings()->get("ConsoleWindowGeometry").toByteArray();
|
||||
restoreGeometry(QByteArray::fromBase64(base64Geometry));
|
||||
}
|
||||
|
||||
// Set up tray icon
|
||||
{
|
||||
m_trayIcon = new QSystemTrayIcon(icon, this);
|
||||
m_trayIcon->setToolTip(windowTitle);
|
||||
|
||||
connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||
SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
|
||||
m_trayIcon->show();
|
||||
}
|
||||
|
||||
// Set up signal connections
|
||||
connect(mcproc, SIGNAL(ended(InstancePtr, int, QProcess::ExitStatus)), this,
|
||||
SLOT(onEnded(InstancePtr, int, QProcess::ExitStatus)));
|
||||
connect(mcproc, SIGNAL(prelaunch_failed(InstancePtr, int, QProcess::ExitStatus)), this,
|
||||
@ -42,34 +132,12 @@ ConsoleWindow::ConsoleWindow(MinecraftProcess *mcproc, QWidget *parent)
|
||||
connect(mcproc, SIGNAL(launch_failed(InstancePtr)), this,
|
||||
SLOT(onLaunchFailed(InstancePtr)));
|
||||
|
||||
restoreState(
|
||||
QByteArray::fromBase64(MMC->settings()->get("ConsoleWindowState").toByteArray()));
|
||||
restoreGeometry(
|
||||
QByteArray::fromBase64(MMC->settings()->get("ConsoleWindowGeometry").toByteArray()));
|
||||
setMayClose(false);
|
||||
|
||||
QString iconKey = proc->instance()->iconKey();
|
||||
QString name = proc->instance()->name();
|
||||
auto icon = MMC->icons()->getIcon(iconKey);
|
||||
setWindowIcon(icon);
|
||||
m_trayIcon = new QSystemTrayIcon(icon, this);
|
||||
// TODO add screenshot upload as a menu item in the tray icon
|
||||
QString consoleTitle = tr("Console window for ") + name;
|
||||
m_trayIcon->setToolTip(consoleTitle);
|
||||
setWindowTitle(consoleTitle);
|
||||
|
||||
connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||
SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
|
||||
m_trayIcon->show();
|
||||
if (mcproc->instance()->settings().get("ShowConsole").toBool())
|
||||
{
|
||||
show();
|
||||
}
|
||||
setMayClose(false);
|
||||
}
|
||||
|
||||
ConsoleWindow::~ConsoleWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ConsoleWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
|
||||
@ -85,110 +153,23 @@ void ConsoleWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleWindow::writeColor(QString text, const char *color, const char * background)
|
||||
{
|
||||
// append a paragraph
|
||||
QString newtext;
|
||||
newtext += "<span style=\"";
|
||||
{
|
||||
if (color)
|
||||
newtext += QString("color:") + color + ";";
|
||||
if (background)
|
||||
newtext += QString("background-color:") + background + ";";
|
||||
newtext += "font-family: monospace;";
|
||||
}
|
||||
newtext += "\">";
|
||||
newtext += text.toHtmlEscaped();
|
||||
newtext += "</span>";
|
||||
ui->text->appendHtml(newtext);
|
||||
}
|
||||
|
||||
void ConsoleWindow::write(QString data, MessageLevel::Enum mode)
|
||||
{
|
||||
QScrollBar *bar = ui->text->verticalScrollBar();
|
||||
int max_bar = bar->maximum();
|
||||
int val_bar = bar->value();
|
||||
if(isVisible())
|
||||
{
|
||||
if (m_scroll_active)
|
||||
{
|
||||
m_scroll_active = (max_bar - val_bar) <= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scroll_active = val_bar == max_bar;
|
||||
}
|
||||
}
|
||||
if (data.endsWith('\n'))
|
||||
data = data.left(data.length() - 1);
|
||||
QStringList paragraphs = data.split('\n');
|
||||
QStringList filtered;
|
||||
for (QString ¶graph : paragraphs)
|
||||
{
|
||||
// Quick hack for
|
||||
if(paragraph.contains("Detected an attempt by a mod null to perform game activity during mod construction"))
|
||||
continue;
|
||||
filtered.append(paragraph.trimmed());
|
||||
}
|
||||
QListIterator<QString> iter(filtered);
|
||||
if (mode == MessageLevel::MultiMC)
|
||||
while (iter.hasNext())
|
||||
writeColor(iter.next(), "blue", 0);
|
||||
else if (mode == MessageLevel::Error)
|
||||
while (iter.hasNext())
|
||||
writeColor(iter.next(), "red", 0);
|
||||
else if (mode == MessageLevel::Warning)
|
||||
while (iter.hasNext())
|
||||
writeColor(iter.next(), "orange", 0);
|
||||
else if (mode == MessageLevel::Fatal)
|
||||
while (iter.hasNext())
|
||||
writeColor(iter.next(), "red", "black");
|
||||
else if (mode == MessageLevel::Debug)
|
||||
while (iter.hasNext())
|
||||
writeColor(iter.next(), "green", 0);
|
||||
else if (mode == MessageLevel::PrePost)
|
||||
while (iter.hasNext())
|
||||
writeColor(iter.next(), "grey", 0);
|
||||
// TODO: implement other MessageLevels
|
||||
else
|
||||
while (iter.hasNext())
|
||||
writeColor(iter.next(), 0, 0);
|
||||
if(isVisible())
|
||||
{
|
||||
if (m_scroll_active)
|
||||
{
|
||||
bar->setValue(bar->maximum());
|
||||
}
|
||||
m_last_scroll_value = bar->value();
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleWindow::clear()
|
||||
{
|
||||
ui->text->clear();
|
||||
}
|
||||
|
||||
void ConsoleWindow::on_closeButton_clicked()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void ConsoleWindow::on_btnScreenshots_clicked()
|
||||
{
|
||||
}
|
||||
|
||||
void ConsoleWindow::setMayClose(bool mayclose)
|
||||
{
|
||||
if(mayclose)
|
||||
ui->closeButton->setText(tr("Close"));
|
||||
m_closeButton->setText(tr("Close"));
|
||||
else
|
||||
ui->closeButton->setText(tr("Hide"));
|
||||
m_closeButton->setText(tr("Hide"));
|
||||
m_mayclose = mayclose;
|
||||
}
|
||||
|
||||
void ConsoleWindow::toggleConsole()
|
||||
{
|
||||
QScrollBar *bar = ui->text->verticalScrollBar();
|
||||
//QScrollBar *bar = ui->text->verticalScrollBar();
|
||||
if (isVisible())
|
||||
{
|
||||
if(!isActiveWindow())
|
||||
@ -196,15 +177,17 @@ void ConsoleWindow::toggleConsole()
|
||||
activateWindow();
|
||||
return;
|
||||
}
|
||||
/*
|
||||
int max_bar = bar->maximum();
|
||||
int val_bar = m_last_scroll_value = bar->value();
|
||||
m_scroll_active = (max_bar - val_bar) <= 1;
|
||||
*/
|
||||
hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
show();
|
||||
isTopLevel();
|
||||
/*
|
||||
if (m_scroll_active)
|
||||
{
|
||||
bar->setValue(bar->maximum());
|
||||
@ -213,6 +196,7 @@ void ConsoleWindow::toggleConsole()
|
||||
{
|
||||
bar->setValue(m_last_scroll_value);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,25 +219,23 @@ void ConsoleWindow::closeEvent(QCloseEvent *event)
|
||||
|
||||
void ConsoleWindow::on_btnKillMinecraft_clicked()
|
||||
{
|
||||
ui->btnKillMinecraft->setEnabled(false);
|
||||
m_killButton->setEnabled(false);
|
||||
auto response = CustomMessageBox::selectable(
|
||||
this, tr("Kill Minecraft?"),
|
||||
tr("This can cause the instance to get corrupted and should only be used if Minecraft "
|
||||
"is frozen for some reason"),
|
||||
QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)->exec();
|
||||
if (response == QMessageBox::Yes)
|
||||
proc->killMinecraft();
|
||||
m_proc->killMinecraft();
|
||||
else
|
||||
ui->btnKillMinecraft->setEnabled(true);
|
||||
m_killButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void ConsoleWindow::onEnded(InstancePtr instance, int code, QProcess::ExitStatus status)
|
||||
{
|
||||
bool peacefulExit = code == 0 && status != QProcess::CrashExit;
|
||||
ui->btnKillMinecraft->setEnabled(false);
|
||||
|
||||
m_killButton->setEnabled(false);
|
||||
setMayClose(true);
|
||||
|
||||
if (instance->settings().get("AutoCloseConsole").toBool())
|
||||
{
|
||||
if (peacefulExit)
|
||||
@ -262,15 +244,8 @@ void ConsoleWindow::onEnded(InstancePtr instance, int code, QProcess::ExitStatus
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if(!peacefulExit)
|
||||
{
|
||||
m_trayIcon->showMessage(tr("Oh no!"), tr("Minecraft crashed!"), QSystemTrayIcon::Critical);
|
||||
}
|
||||
*/
|
||||
if (!isVisible())
|
||||
show();
|
||||
|
||||
// Raise Window
|
||||
if (MMC->settings()->get("RaiseConsole").toBool())
|
||||
{
|
||||
@ -281,23 +256,10 @@ void ConsoleWindow::onEnded(InstancePtr instance, int code, QProcess::ExitStatus
|
||||
|
||||
void ConsoleWindow::onLaunchFailed(InstancePtr instance)
|
||||
{
|
||||
ui->btnKillMinecraft->setEnabled(false);
|
||||
m_killButton->setEnabled(false);
|
||||
|
||||
setMayClose(true);
|
||||
|
||||
if (!isVisible())
|
||||
show();
|
||||
}
|
||||
|
||||
void ConsoleWindow::on_btnPaste_clicked()
|
||||
{
|
||||
auto text = ui->text->toPlainText();
|
||||
ProgressDialog dialog(this);
|
||||
PasteUpload *paste = new PasteUpload(this, text);
|
||||
dialog.exec(paste);
|
||||
if (!paste->successful())
|
||||
{
|
||||
CustomMessageBox::selectable(this, "Upload failed", paste->failReason(),
|
||||
QMessageBox::Critical)->exec();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user