From db877ba121ff87a4e029daf8555d85dfef45993a Mon Sep 17 00:00:00 2001 From: Petr Mrázek Date: Mon, 9 Feb 2015 01:51:14 +0100 Subject: NOISSUE move everything. --- application/pages/BasePage.h | 38 ++ application/pages/BasePageProvider.h | 69 ++++ application/pages/InstanceSettingsPage.cpp | 216 ++++++++++ application/pages/InstanceSettingsPage.h | 74 ++++ application/pages/InstanceSettingsPage.ui | 453 +++++++++++++++++++++ application/pages/LogPage.cpp | 222 +++++++++++ application/pages/LogPage.h | 86 ++++ application/pages/LogPage.ui | 140 +++++++ application/pages/ModFolderPage.cpp | 160 ++++++++ application/pages/ModFolderPage.h | 94 +++++ application/pages/ModFolderPage.ui | 124 ++++++ application/pages/NotesPage.cpp | 21 + application/pages/NotesPage.h | 61 +++ application/pages/NotesPage.ui | 60 +++ application/pages/OtherLogsPage.cpp | 150 +++++++ application/pages/OtherLogsPage.h | 72 ++++ application/pages/OtherLogsPage.ui | 117 ++++++ application/pages/ResourcePackPage.h | 19 + application/pages/ScreenshotsPage.cpp | 362 +++++++++++++++++ application/pages/ScreenshotsPage.h | 79 ++++ application/pages/ScreenshotsPage.ui | 109 +++++ application/pages/TexturePackPage.h | 17 + application/pages/VersionPage.cpp | 321 +++++++++++++++ application/pages/VersionPage.h | 80 ++++ application/pages/VersionPage.ui | 204 ++++++++++ application/pages/global/AccountListPage.cpp | 142 +++++++ application/pages/global/AccountListPage.h | 86 ++++ application/pages/global/AccountListPage.ui | 115 ++++++ application/pages/global/ExternalToolsPage.cpp | 238 +++++++++++ application/pages/global/ExternalToolsPage.h | 74 ++++ application/pages/global/ExternalToolsPage.ui | 197 +++++++++ application/pages/global/JavaPage.cpp | 146 +++++++ application/pages/global/JavaPage.h | 73 ++++ application/pages/global/JavaPage.ui | 303 ++++++++++++++ application/pages/global/MinecraftPage.cpp | 92 +++++ application/pages/global/MinecraftPage.h | 70 ++++ application/pages/global/MinecraftPage.ui | 148 +++++++ application/pages/global/MultiMCPage.cpp | 459 +++++++++++++++++++++ application/pages/global/MultiMCPage.h | 100 +++++ application/pages/global/MultiMCPage.ui | 532 +++++++++++++++++++++++++ application/pages/global/ProxyPage.cpp | 95 +++++ application/pages/global/ProxyPage.h | 66 +++ application/pages/global/ProxyPage.ui | 197 +++++++++ 43 files changed, 6481 insertions(+) create mode 100644 application/pages/BasePage.h create mode 100644 application/pages/BasePageProvider.h create mode 100644 application/pages/InstanceSettingsPage.cpp create mode 100644 application/pages/InstanceSettingsPage.h create mode 100644 application/pages/InstanceSettingsPage.ui create mode 100644 application/pages/LogPage.cpp create mode 100644 application/pages/LogPage.h create mode 100644 application/pages/LogPage.ui create mode 100644 application/pages/ModFolderPage.cpp create mode 100644 application/pages/ModFolderPage.h create mode 100644 application/pages/ModFolderPage.ui create mode 100644 application/pages/NotesPage.cpp create mode 100644 application/pages/NotesPage.h create mode 100644 application/pages/NotesPage.ui create mode 100644 application/pages/OtherLogsPage.cpp create mode 100644 application/pages/OtherLogsPage.h create mode 100644 application/pages/OtherLogsPage.ui create mode 100644 application/pages/ResourcePackPage.h create mode 100644 application/pages/ScreenshotsPage.cpp create mode 100644 application/pages/ScreenshotsPage.h create mode 100644 application/pages/ScreenshotsPage.ui create mode 100644 application/pages/TexturePackPage.h create mode 100644 application/pages/VersionPage.cpp create mode 100644 application/pages/VersionPage.h create mode 100644 application/pages/VersionPage.ui create mode 100644 application/pages/global/AccountListPage.cpp create mode 100644 application/pages/global/AccountListPage.h create mode 100644 application/pages/global/AccountListPage.ui create mode 100644 application/pages/global/ExternalToolsPage.cpp create mode 100644 application/pages/global/ExternalToolsPage.h create mode 100644 application/pages/global/ExternalToolsPage.ui create mode 100644 application/pages/global/JavaPage.cpp create mode 100644 application/pages/global/JavaPage.h create mode 100644 application/pages/global/JavaPage.ui create mode 100644 application/pages/global/MinecraftPage.cpp create mode 100644 application/pages/global/MinecraftPage.h create mode 100644 application/pages/global/MinecraftPage.ui create mode 100644 application/pages/global/MultiMCPage.cpp create mode 100644 application/pages/global/MultiMCPage.h create mode 100644 application/pages/global/MultiMCPage.ui create mode 100644 application/pages/global/ProxyPage.cpp create mode 100644 application/pages/global/ProxyPage.h create mode 100644 application/pages/global/ProxyPage.ui (limited to 'application/pages') diff --git a/application/pages/BasePage.h b/application/pages/BasePage.h new file mode 100644 index 00000000..ecf0692c --- /dev/null +++ b/application/pages/BasePage.h @@ -0,0 +1,38 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +class BasePage +{ +public: + virtual ~BasePage() {} + virtual QString id() const = 0; + virtual QString displayName() const = 0; + virtual QIcon icon() const = 0; + virtual bool apply() { return true; } + virtual bool shouldDisplay() const { return true; } + virtual QString helpPage() const { return QString(); } + virtual void opened() {} + virtual void closed() {} + int stackIndex = -1; + int listIndex = -1; +}; + +typedef std::shared_ptr BasePagePtr; diff --git a/application/pages/BasePageProvider.h b/application/pages/BasePageProvider.h new file mode 100644 index 00000000..c55683e0 --- /dev/null +++ b/application/pages/BasePageProvider.h @@ -0,0 +1,69 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BasePage.h" +#include +#include + +class BasePageProvider +{ +public: + virtual QList getPages() = 0; + virtual QString dialogTitle() = 0; +}; + +class GenericPageProvider : public BasePageProvider +{ + typedef std::function PageCreator; +public: + explicit GenericPageProvider(const QString &dialogTitle) + : m_dialogTitle(dialogTitle) + { + } + + QList getPages() override + { + QList pages; + for (PageCreator creator : m_creators) + { + pages.append(creator()); + } + return pages; + } + QString dialogTitle() override { return m_dialogTitle; } + + void setDialogTitle(const QString &title) + { + m_dialogTitle = title; + } + void addPageCreator(PageCreator page) + { + m_creators.append(page); + } + + template + void addPage() + { + addPageCreator([](){return new PageClass();}); + } + +private: + QList m_creators; + QString m_dialogTitle; +}; + +typedef std::shared_ptr BasePageProviderPtr; diff --git a/application/pages/InstanceSettingsPage.cpp b/application/pages/InstanceSettingsPage.cpp new file mode 100644 index 00000000..1e571eff --- /dev/null +++ b/application/pages/InstanceSettingsPage.cpp @@ -0,0 +1,216 @@ +#include "InstanceSettingsPage.h" +#include "ui_InstanceSettingsPage.h" + +#include +#include +#include + +#include "dialogs/VersionSelectDialog.h" +#include "NagUtils.h" +#include "java/JavaVersionList.h" +#include "MultiMC.h" + +InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) + : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst) +{ + m_settings = &(inst->settings()); + ui->setupUi(this); + loadSettings(); +} + +bool InstanceSettingsPage::shouldDisplay() const +{ + return !m_instance->isRunning(); +} + +InstanceSettingsPage::~InstanceSettingsPage() +{ + delete ui; +} + +bool InstanceSettingsPage::apply() +{ + applySettings(); + return true; +} + +void InstanceSettingsPage::applySettings() +{ + // Console + bool console = ui->consoleSettingsBox->isChecked(); + m_settings->set("OverrideConsole", console); + if (console) + { + m_settings->set("ShowConsole", ui->showConsoleCheck->isChecked()); + m_settings->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); + } + else + { + m_settings->reset("ShowConsole"); + m_settings->reset("AutoCloseConsole"); + } + + // Window Size + bool window = ui->windowSizeGroupBox->isChecked(); + m_settings->set("OverrideWindow", window); + if (window) + { + m_settings->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); + m_settings->set("MinecraftWinWidth", ui->windowWidthSpinBox->value()); + m_settings->set("MinecraftWinHeight", ui->windowHeightSpinBox->value()); + } + else + { + m_settings->reset("LaunchMaximized"); + m_settings->reset("MinecraftWinWidth"); + m_settings->reset("MinecraftWinHeight"); + } + + // Memory + bool memory = ui->memoryGroupBox->isChecked(); + m_settings->set("OverrideMemory", memory); + if (memory) + { + m_settings->set("MinMemAlloc", ui->minMemSpinBox->value()); + m_settings->set("MaxMemAlloc", ui->maxMemSpinBox->value()); + m_settings->set("PermGen", ui->permGenSpinBox->value()); + } + else + { + m_settings->reset("MinMemAlloc"); + m_settings->reset("MaxMemAlloc"); + m_settings->reset("PermGen"); + } + + // Java Install Settings + bool javaInstall = ui->javaSettingsGroupBox->isChecked(); + m_settings->set("OverrideJavaLocation", javaInstall); + if (javaInstall) + { + m_settings->set("JavaPath", ui->javaPathTextBox->text()); + } + else + { + m_settings->reset("JavaPath"); + } + + // Java arguments + bool javaArgs = ui->javaArgumentsGroupBox->isChecked(); + m_settings->set("OverrideJavaArgs", javaArgs); + if(javaArgs) + { + m_settings->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " ")); + NagUtils::checkJVMArgs(m_settings->get("JvmArgs").toString(), this->parentWidget()); + } + else + { + m_settings->reset("JvmArgs"); + } + + // old generic 'override both' is removed. + m_settings->reset("OverrideJava"); + + // Custom Commands + bool custcmd = ui->customCommandsGroupBox->isChecked(); + m_settings->set("OverrideCommands", custcmd); + if (custcmd) + { + m_settings->set("PreLaunchCommand", ui->preLaunchCmdTextBox->text()); + m_settings->set("PostExitCommand", ui->postExitCmdTextBox->text()); + } + else + { + m_settings->reset("PreLaunchCommand"); + m_settings->reset("PostExitCommand"); + } +} + +void InstanceSettingsPage::loadSettings() +{ + // Console + ui->consoleSettingsBox->setChecked(m_settings->get("OverrideConsole").toBool()); + ui->showConsoleCheck->setChecked(m_settings->get("ShowConsole").toBool()); + ui->autoCloseConsoleCheck->setChecked(m_settings->get("AutoCloseConsole").toBool()); + + // Window Size + ui->windowSizeGroupBox->setChecked(m_settings->get("OverrideWindow").toBool()); + ui->maximizedCheckBox->setChecked(m_settings->get("LaunchMaximized").toBool()); + ui->windowWidthSpinBox->setValue(m_settings->get("MinecraftWinWidth").toInt()); + ui->windowHeightSpinBox->setValue(m_settings->get("MinecraftWinHeight").toInt()); + + // Memory + ui->memoryGroupBox->setChecked(m_settings->get("OverrideMemory").toBool()); + ui->minMemSpinBox->setValue(m_settings->get("MinMemAlloc").toInt()); + ui->maxMemSpinBox->setValue(m_settings->get("MaxMemAlloc").toInt()); + ui->permGenSpinBox->setValue(m_settings->get("PermGen").toInt()); + + // Java Settings + bool overrideJava = m_settings->get("OverrideJava").toBool(); + bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava; + bool overrideArgs = m_settings->get("OverrideJavaArgs").toBool() || overrideJava; + + ui->javaSettingsGroupBox->setChecked(overrideLocation); + ui->javaPathTextBox->setText(m_settings->get("JavaPath").toString()); + + ui->javaArgumentsGroupBox->setChecked(overrideArgs); + ui->jvmArgsTextBox->setPlainText(m_settings->get("JvmArgs").toString()); + + // Custom Commands + ui->customCommandsGroupBox->setChecked(m_settings->get("OverrideCommands").toBool()); + ui->preLaunchCmdTextBox->setText(m_settings->get("PreLaunchCommand").toString()); + ui->postExitCmdTextBox->setText(m_settings->get("PostExitCommand").toString()); +} + +void InstanceSettingsPage::on_javaDetectBtn_clicked() +{ + JavaVersionPtr java; + + VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true); + vselect.setResizeOn(2); + vselect.exec(); + + if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) + { + java = std::dynamic_pointer_cast(vselect.selectedVersion()); + ui->javaPathTextBox->setText(java->path); + } +} + +void InstanceSettingsPage::on_javaBrowseBtn_clicked() +{ + QString dir = QFileDialog::getOpenFileName(this, tr("Find Java executable")); + if (!dir.isNull()) + { + ui->javaPathTextBox->setText(dir); + } +} + +void InstanceSettingsPage::on_javaTestBtn_clicked() +{ + checker.reset(new JavaChecker()); + connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this, + SLOT(checkFinished(JavaCheckResult))); + checker->path = ui->javaPathTextBox->text(); + checker->performCheck(); +} + +void InstanceSettingsPage::checkFinished(JavaCheckResult result) +{ + if (result.valid) + { + QString text; + text += "Java test succeeded!\n"; + if (result.is_64bit) + text += "Using 64bit java.\n"; + text += "\n"; + text += "Platform reported: " + result.realPlatform; + QMessageBox::information(this, tr("Java test success"), text); + } + else + { + QMessageBox::warning( + this, tr("Java test failure"), + tr("The specified java binary didn't work. You should use the auto-detect feature, " + "or set the path to the java executable.")); + } +} diff --git a/application/pages/InstanceSettingsPage.h b/application/pages/InstanceSettingsPage.h new file mode 100644 index 00000000..85df5880 --- /dev/null +++ b/application/pages/InstanceSettingsPage.h @@ -0,0 +1,74 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "net/NetJob.h" +#include "java/JavaChecker.h" +#include "BaseInstance.h" +#include "BasePage.h" +#include "MultiMC.h" + +class JavaChecker; +namespace Ui +{ +class InstanceSettingsPage; +} + +class InstanceSettingsPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0); + virtual ~InstanceSettingsPage(); + virtual QString displayName() const override + { + return tr("Settings"); + } + virtual QIcon icon() const override + { + return MMC->getThemedIcon("instance-settings"); + } + virtual QString id() const override + { + return "settings"; + } + virtual bool apply(); + virtual QString helpPage() const override + { + return "Instance-settings"; + } + virtual bool shouldDisplay() const; +private slots: + void on_javaDetectBtn_clicked(); + + void on_javaTestBtn_clicked(); + + void on_javaBrowseBtn_clicked(); + + void checkFinished(JavaCheckResult result); + + void applySettings(); + void loadSettings(); + +private: + Ui::InstanceSettingsPage *ui; + BaseInstance *m_instance; + SettingsObject *m_settings; + std::shared_ptr checker; +}; diff --git a/application/pages/InstanceSettingsPage.ui b/application/pages/InstanceSettingsPage.ui new file mode 100644 index 00000000..64109378 --- /dev/null +++ b/application/pages/InstanceSettingsPage.ui @@ -0,0 +1,453 @@ + + + InstanceSettingsPage + + + + 0 + 0 + 458 + 426 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QTabWidget::Rounded + + + 0 + + + + Java + + + + + + true + + + Java installation + + + true + + + false + + + + + + + + + Auto-detect... + + + + + + + Browse... + + + + + + + Test + + + + + + + + + + true + + + Memory + + + true + + + false + + + + + + The maximum amount of memory Minecraft is allowed to use. + + + MB + + + 512 + + + 65536 + + + 128 + + + 1024 + + + + + + + Minimum memory allocation: + + + + + + + Maximum memory allocation: + + + + + + + The amount of memory Minecraft is started with. + + + MB + + + 256 + + + 65536 + + + 128 + + + 256 + + + + + + + The amount of memory available to store loaded Java classes. + + + MB + + + 64 + + + 999999999 + + + 8 + + + 64 + + + + + + + PermGen: + + + + + + + + + + true + + + Java arguments + + + true + + + false + + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + Game windows + + + + + + true + + + Game Window + + + true + + + false + + + + + + Start Minecraft maximized? + + + + + + + + + Window height: + + + + + + + Window width: + + + + + + + 1 + + + 65536 + + + 1 + + + 854 + + + + + + + 1 + + + 65536 + + + 480 + + + + + + + + + + + + true + + + Console Settings + + + true + + + false + + + + + + Show console while the game is running? + + + + + + + Automatically close console when the game quits? + + + + + + + + + + Qt::Vertical + + + + 88 + 125 + + + + + + + + + Custom commands + + + + + + true + + + Custom Commands + + + true + + + false + + + + + + + + + Post-exit command: + + + + + + + Pre-launch command: + + + + + + + + + + + + + <html><head/><body><p>Pre-launch command runs before the instance launches and post-exit command runs after it exits.</p><p>Both will be run in MultiMC's working directory with extra environment variables:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">INST_NAME - Name of the instance</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">INST_ID - ID of the instance</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">INST_DIR - absolute path of the instance</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">INST_MC_DIR - absolute path of minecraft</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">INST_JAVA - java binary used for launch</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">INST_JAVA_ARGS - command-line parameters used for launch</li></ul></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + Qt::Vertical + + + + 88 + 186 + + + + + + + + + + + + settingsTabs + javaSettingsGroupBox + javaPathTextBox + javaDetectBtn + javaBrowseBtn + javaTestBtn + memoryGroupBox + minMemSpinBox + maxMemSpinBox + permGenSpinBox + javaArgumentsGroupBox + jvmArgsTextBox + windowSizeGroupBox + maximizedCheckBox + windowWidthSpinBox + windowHeightSpinBox + consoleSettingsBox + showConsoleCheck + autoCloseConsoleCheck + customCommandsGroupBox + preLaunchCmdTextBox + postExitCmdTextBox + + + + diff --git a/application/pages/LogPage.cpp b/application/pages/LogPage.cpp new file mode 100644 index 00000000..8f9edb96 --- /dev/null +++ b/application/pages/LogPage.cpp @@ -0,0 +1,222 @@ +#include "LogPage.h" +#include "ui_LogPage.h" + +#include "MultiMC.h" + +#include +#include +#include + +#include "BaseProcess.h" +#include "GuiUtil.h" + +LogPage::LogPage(BaseProcess *proc, QWidget *parent) + : QWidget(parent), ui(new Ui::LogPage), m_process(proc) +{ + ui->setupUi(this); + ui->tabWidget->tabBar()->hide(); + connect(m_process, SIGNAL(log(QString, MessageLevel::Enum)), this, + SLOT(write(QString, MessageLevel::Enum))); + + // create the format and set its font + defaultFormat = new QTextCharFormat(ui->text->currentCharFormat()); + QString fontFamily = MMC->settings()->get("ConsoleFont").toString(); + bool conversionOk = false; + int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk); + if(!conversionOk) + { + fontSize = 11; + } + defaultFormat->setFont(QFont(fontFamily, fontSize)); + + auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this); + connect(findShortcut, SIGNAL(activated()), SLOT(findActivated())); + auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this); + connect(findNextShortcut, SIGNAL(activated()), SLOT(findNextActivated())); + connect(ui->searchBar, SIGNAL(returnPressed()), SLOT(on_findButton_clicked())); + auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this); + connect(findPreviousShortcut, SIGNAL(activated()), SLOT(findPreviousActivated())); +} + +LogPage::~LogPage() +{ + delete ui; + delete defaultFormat; +} + +bool LogPage::apply() +{ + return true; +} + +bool LogPage::shouldDisplay() const +{ + return m_process->instance()->isRunning(); +} + +void LogPage::on_btnPaste_clicked() +{ + GuiUtil::uploadPaste(ui->text->toPlainText(), this); +} + +void LogPage::on_btnCopy_clicked() +{ + GuiUtil::setClipboardText(ui->text->toPlainText()); +} + +void LogPage::on_btnClear_clicked() +{ + ui->text->clear(); +} + +void LogPage::on_trackLogCheckbox_clicked(bool checked) +{ + m_write_active = checked; +} + +void LogPage::on_findButton_clicked() +{ + auto modifiers = QApplication::keyboardModifiers(); + if (modifiers & Qt::ShiftModifier) + { + findPreviousActivated(); + } + else + { + findNextActivated(); + } +} + +void LogPage::findActivated() +{ + // focus the search bar if it doesn't have focus + if (!ui->searchBar->hasFocus()) + { + auto searchForCursor = ui->text->textCursor(); + auto searchForString = searchForCursor.selectedText(); + if (searchForString.size()) + { + ui->searchBar->setText(searchForString); + } + ui->searchBar->setFocus(); + ui->searchBar->selectAll(); + } +} + +void LogPage::findNextActivated() +{ + auto toSearch = ui->searchBar->text(); + if (toSearch.size()) + { + ui->text->find(toSearch); + } +} + +void LogPage::findPreviousActivated() +{ + auto toSearch = ui->searchBar->text(); + if (toSearch.size()) + { + ui->text->find(toSearch, QTextDocument::FindBackward); + } +} + +void LogPage::write(QString data, MessageLevel::Enum mode) +{ + if (!m_write_active) + { + if (mode != MessageLevel::PrePost && mode != MessageLevel::MultiMC) + { + return; + } + } + + // save the cursor so it can be restored. + auto savedCursor = ui->text->cursor(); + + 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) + { + //TODO: implement filtering here. + filtered.append(paragraph); + } + QListIterator iter(filtered); + QTextCharFormat format(*defaultFormat); + + switch(mode) + { + case MessageLevel::MultiMC: + { + format.setForeground(QColor("blue")); + break; + } + case MessageLevel::Debug: + { + format.setForeground(QColor("green")); + break; + } + case MessageLevel::Warning: + { + format.setForeground(QColor("orange")); + break; + } + case MessageLevel::Error: + { + format.setForeground(QColor("red")); + break; + } + case MessageLevel::Fatal: + { + format.setForeground(QColor("red")); + format.setBackground(QColor("black")); + break; + } + case MessageLevel::PrePost: + { + format.setForeground(QColor("grey")); + break; + } + case MessageLevel::Info: + case MessageLevel::Message: + default: + { + // do nothing, keep original + } + } + + while (iter.hasNext()) + { + // append a paragraph/line + auto workCursor = ui->text->textCursor(); + workCursor.movePosition(QTextCursor::End); + workCursor.insertText(iter.next(), format); + workCursor.insertBlock(); + } + + if (isVisible()) + { + if (m_scroll_active) + { + bar->setValue(bar->maximum()); + } + m_last_scroll_value = bar->value(); + } + ui->text->setCursor(savedCursor); +} diff --git a/application/pages/LogPage.h b/application/pages/LogPage.h new file mode 100644 index 00000000..fe7bbecb --- /dev/null +++ b/application/pages/LogPage.h @@ -0,0 +1,86 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "BaseInstance.h" +#include "net/NetJob.h" +#include "BaseProcess.h" +#include "BasePage.h" +#include + +namespace Ui +{ +class LogPage; +} +class QTextCharFormat; + +class LogPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit LogPage(BaseProcess *proc, QWidget *parent = 0); + virtual ~LogPage(); + virtual QString displayName() const override + { + return tr("Minecraft Log"); + } + virtual QIcon icon() const override + { + return MMC->getThemedIcon("log"); + } + virtual QString id() const override + { + return "console"; + } + virtual bool apply(); + virtual QString helpPage() const override + { + return "Minecraft-Logs"; + } + virtual bool shouldDisplay() const; + +private 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, MessageLevel::Enum level = MessageLevel::MultiMC); + void on_btnPaste_clicked(); + void on_btnCopy_clicked(); + void on_btnClear_clicked(); + + void on_trackLogCheckbox_clicked(bool checked); + + void on_findButton_clicked(); + void findActivated(); + void findNextActivated(); + void findPreviousActivated(); + +private: + Ui::LogPage *ui; + BaseProcess *m_process; + int m_last_scroll_value = 0; + bool m_scroll_active = true; + int m_saved_offset = 0; + bool m_write_active = true; + + QTextCharFormat * defaultFormat; +}; diff --git a/application/pages/LogPage.ui b/application/pages/LogPage.ui new file mode 100644 index 00000000..089bc906 --- /dev/null +++ b/application/pages/LogPage.ui @@ -0,0 +1,140 @@ + + + LogPage + + + + 0 + 0 + 825 + 782 + + + + Log + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + Tab 1 + + + + + + Search: + + + + + + + Find + + + + + + + false + + + true + + + + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + false + + + + + + + + + Keep updating + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Copy the whole log into the clipboard + + + &Copy + + + + + + + Upload the log to paste.ee - it will stay online for a month + + + Upload + + + + + + + Clear the log + + + Clear + + + + + + + + + + + + + + + + + diff --git a/application/pages/ModFolderPage.cpp b/application/pages/ModFolderPage.cpp new file mode 100644 index 00000000..3c55aefc --- /dev/null +++ b/application/pages/ModFolderPage.cpp @@ -0,0 +1,160 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ModFolderPage.h" +#include "ui_ModFolderPage.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include "MultiMC.h" +#include "dialogs/CustomMessageBox.h" +#include "dialogs/ModEditDialogCommon.h" +#include "minecraft/ModList.h" +#include "minecraft/Mod.h" +#include "minecraft/VersionFilterData.h" + +ModFolderPage::ModFolderPage(BaseInstance *inst, std::shared_ptr mods, QString id, + QString iconName, QString displayName, QString helpPage, + QWidget *parent) + : QWidget(parent), ui(new Ui::ModFolderPage) +{ + ui->setupUi(this); + ui->tabWidget->tabBar()->hide(); + m_inst = inst; + m_mods = mods; + m_id = id; + m_displayName = displayName; + m_iconName = iconName; + m_helpName = helpPage; + ui->modTreeView->setModel(m_mods.get()); + ui->modTreeView->installEventFilter(this); + m_mods->startWatching(); + auto smodel = ui->modTreeView->selectionModel(); + connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + SLOT(modCurrent(QModelIndex, QModelIndex))); +} + +CoreModFolderPage::CoreModFolderPage(BaseInstance *inst, std::shared_ptr mods, + QString id, QString iconName, QString displayName, + QString helpPage, QWidget *parent) + : ModFolderPage(inst, mods, id, iconName, displayName, helpPage, parent) +{ +} + +ModFolderPage::~ModFolderPage() +{ + m_mods->stopWatching(); + delete ui; +} + +bool ModFolderPage::shouldDisplay() const +{ + if (m_inst) + return !m_inst->isRunning(); + return true; +} + +bool CoreModFolderPage::shouldDisplay() const +{ + if (ModFolderPage::shouldDisplay()) + { + auto inst = dynamic_cast(m_inst); + if (!inst) + return true; + auto version = inst->getMinecraftProfile(); + if (!version) + return true; + if (version->m_releaseTime < g_VersionFilterData.legacyCutoffDate) + { + return true; + } + } + return false; +} + +bool ModFolderPage::modListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Delete: + on_rmModBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addModBtn_clicked(); + return true; + default: + break; + } + return QWidget::eventFilter(ui->modTreeView, keyEvent); +} + +bool ModFolderPage::eventFilter(QObject *obj, QEvent *ev) +{ + if (ev->type() != QEvent::KeyPress) + { + return QWidget::eventFilter(obj, ev); + } + QKeyEvent *keyEvent = static_cast(ev); + if (obj == ui->modTreeView) + return modListFilter(keyEvent); + return QWidget::eventFilter(obj, ev); +} + +void ModFolderPage::on_addModBtn_clicked() +{ + QStringList fileNames = QFileDialog::getOpenFileNames( + this, QApplication::translate("ModFolderPage", "Select Loader Mods")); + for (auto filename : fileNames) + { + m_mods->stopWatching(); + m_mods->installMod(QFileInfo(filename)); + m_mods->startWatching(); + } +} +void ModFolderPage::on_rmModBtn_clicked() +{ + int first, last; + auto list = ui->modTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_mods->stopWatching(); + m_mods->deleteMods(first, last); + m_mods->startWatching(); +} + +void ModFolderPage::on_viewModBtn_clicked() +{ + openDirInDefaultProgram(m_mods->dir().absolutePath(), true); +} + +void ModFolderPage::modCurrent(const QModelIndex ¤t, const QModelIndex &previous) +{ + if (!current.isValid()) + { + ui->frame->clear(); + return; + } + int row = current.row(); + Mod &m = m_mods->operator[](row); + ui->frame->updateWithMod(m); +} diff --git a/application/pages/ModFolderPage.h b/application/pages/ModFolderPage.h new file mode 100644 index 00000000..4e89f85f --- /dev/null +++ b/application/pages/ModFolderPage.h @@ -0,0 +1,94 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "minecraft/OneSixInstance.h" +#include "net/NetJob.h" +#include "BasePage.h" +#include + +class ModList; +namespace Ui +{ +class ModFolderPage; +} + +class ModFolderPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit ModFolderPage(BaseInstance *inst, std::shared_ptr mods, QString id, + QString iconName, QString displayName, QString helpPage = "", + QWidget *parent = 0); + virtual ~ModFolderPage(); + virtual QString displayName() const override + { + return m_displayName; + } + virtual QIcon icon() const override + { + return MMC->getThemedIcon(m_iconName); + } + virtual QString id() const override + { + return m_id; + } + virtual QString helpPage() const override + { + return m_helpName; + } + virtual bool shouldDisplay() const; + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + bool modListFilter(QKeyEvent *ev); + +protected: + BaseInstance *m_inst; + +private: + Ui::ModFolderPage *ui; + std::shared_ptr m_mods; + QString m_iconName; + QString m_id; + QString m_displayName; + QString m_helpName; + +public +slots: + void modCurrent(const QModelIndex ¤t, const QModelIndex &previous); + +private +slots: + void on_addModBtn_clicked(); + void on_rmModBtn_clicked(); + void on_viewModBtn_clicked(); +}; + +class CoreModFolderPage : public ModFolderPage +{ +public: + explicit CoreModFolderPage(BaseInstance *inst, std::shared_ptr mods, QString id, + QString iconName, QString displayName, QString helpPage = "", + QWidget *parent = 0); + virtual ~CoreModFolderPage() + { + } + virtual bool shouldDisplay() const; +}; diff --git a/application/pages/ModFolderPage.ui b/application/pages/ModFolderPage.ui new file mode 100644 index 00000000..353b62c5 --- /dev/null +++ b/application/pages/ModFolderPage.ui @@ -0,0 +1,124 @@ + + + ModFolderPage + + + + 0 + 0 + 723 + 532 + + + + Mods + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + Tab 1 + + + + + + + 0 + 0 + + + + true + + + QAbstractItemView::DropOnly + + + + + + + + + &Add + + + + + + + &Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + &View Folder + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + ModListView + QTreeView +
widgets/ModListView.h
+
+ + MCModInfoFrame + QFrame +
widgets/MCModInfoFrame.h
+ 1 +
+
+ + +
diff --git a/application/pages/NotesPage.cpp b/application/pages/NotesPage.cpp new file mode 100644 index 00000000..48bb468c --- /dev/null +++ b/application/pages/NotesPage.cpp @@ -0,0 +1,21 @@ +#include "NotesPage.h" +#include "ui_NotesPage.h" + +NotesPage::NotesPage(BaseInstance *inst, QWidget *parent) + : QWidget(parent), ui(new Ui::NotesPage), m_inst(inst) +{ + ui->setupUi(this); + ui->tabWidget->tabBar()->hide(); + ui->noteEditor->setText(m_inst->notes()); +} + +NotesPage::~NotesPage() +{ + delete ui; +} + +bool NotesPage::apply() +{ + m_inst->setNotes(ui->noteEditor->toPlainText()); + return true; +} diff --git a/application/pages/NotesPage.h b/application/pages/NotesPage.h new file mode 100644 index 00000000..62e0c692 --- /dev/null +++ b/application/pages/NotesPage.h @@ -0,0 +1,61 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "BaseInstance.h" +#include "net/NetJob.h" +#include "BasePage.h" +#include + +namespace Ui +{ +class NotesPage; +} + +class NotesPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit NotesPage(BaseInstance *inst, QWidget *parent = 0); + virtual ~NotesPage(); + virtual QString displayName() const override + { + return tr("Notes"); + } + virtual QIcon icon() const override + { + auto icon = MMC->getThemedIcon("notes"); + if(icon.isNull()) + icon = MMC->getThemedIcon("news"); + return icon; + } + virtual QString id() const override + { + return "notes"; + } + virtual bool apply(); + virtual QString helpPage() const override + { + return "Notes"; + } + +private: + Ui::NotesPage *ui; + BaseInstance *m_inst; +}; diff --git a/application/pages/NotesPage.ui b/application/pages/NotesPage.ui new file mode 100644 index 00000000..8da01c8b --- /dev/null +++ b/application/pages/NotesPage.ui @@ -0,0 +1,60 @@ + + + NotesPage + + + + 0 + 0 + 731 + 538 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + Tab 1 + + + + + + Qt::ScrollBarAlwaysOn + + + false + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + diff --git a/application/pages/OtherLogsPage.cpp b/application/pages/OtherLogsPage.cpp new file mode 100644 index 00000000..b037a6c7 --- /dev/null +++ b/application/pages/OtherLogsPage.cpp @@ -0,0 +1,150 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "OtherLogsPage.h" +#include "ui_OtherLogsPage.h" + +#include +#include + +#include "GuiUtil.h" +#include "RecursiveFileSystemWatcher.h" +#include + +OtherLogsPage::OtherLogsPage(QString path, QWidget *parent) + : QWidget(parent), ui(new Ui::OtherLogsPage), m_path(path), + m_watcher(new RecursiveFileSystemWatcher(this)) +{ + ui->setupUi(this); + ui->tabWidget->tabBar()->hide(); + + m_watcher->setFileExpression("(.*\\.log(\\.[0-9]*)?$)|(crash-.*\\.txt)"); + m_watcher->setRootDir(QDir::current().absoluteFilePath(m_path)); + + connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, this, + &OtherLogsPage::populateSelectLogBox); + populateSelectLogBox(); +} + +OtherLogsPage::~OtherLogsPage() +{ + delete ui; +} + +void OtherLogsPage::opened() +{ + m_watcher->enable(); +} +void OtherLogsPage::closed() +{ + m_watcher->disable(); +} + +void OtherLogsPage::populateSelectLogBox() +{ + ui->selectLogBox->clear(); + ui->selectLogBox->addItems(m_watcher->files()); + if (m_currentFile.isNull()) + { + ui->selectLogBox->setCurrentIndex(-1); + } + else + { + const int index = ui->selectLogBox->findText(m_currentFile); + if (index != -1) + ui->selectLogBox->setCurrentIndex(index); + } +} + +void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) +{ + QString file; + if (index != -1) + { + file = ui->selectLogBox->itemText(index); + } + + if (file.isEmpty() || !QFile::exists(PathCombine(m_path, file))) + { + m_currentFile = QString(); + ui->text->clear(); + setControlsEnabled(false); + } + else + { + m_currentFile = file; + on_btnReload_clicked(); + setControlsEnabled(true); + } +} + +void OtherLogsPage::on_btnReload_clicked() +{ + QFile file(PathCombine(m_path, m_currentFile)); + if (!file.open(QFile::ReadOnly)) + { + setControlsEnabled(false); + ui->btnReload->setEnabled(true); // allow reload + m_currentFile = QString(); + QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2") + .arg(m_currentFile, file.errorString())); + } + else + { + if (file.size() < 10000000ll) + { + ui->text->setPlainText(QString::fromUtf8(file.readAll())); + } + else + { + ui->text->setPlainText( + tr("The file (%1) is too big. You may want to open it in a viewer optimized " + "for large files.").arg(file.fileName())); + } + } +} + +void OtherLogsPage::on_btnPaste_clicked() +{ + GuiUtil::uploadPaste(ui->text->toPlainText(), this); +} +void OtherLogsPage::on_btnCopy_clicked() +{ + GuiUtil::setClipboardText(ui->text->toPlainText()); +} +void OtherLogsPage::on_btnDelete_clicked() +{ + if (QMessageBox::question(this, tr("Delete"), + tr("Do you really want to delete %1?").arg(m_currentFile), + QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) + { + return; + } + QFile file(PathCombine(m_path, m_currentFile)); + if (!file.remove()) + { + QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2") + .arg(m_currentFile, file.errorString())); + } +} + +void OtherLogsPage::setControlsEnabled(const bool enabled) +{ + ui->btnReload->setEnabled(enabled); + ui->btnDelete->setEnabled(enabled); + ui->btnCopy->setEnabled(enabled); + ui->btnPaste->setEnabled(enabled); + ui->text->setEnabled(enabled); +} diff --git a/application/pages/OtherLogsPage.h b/application/pages/OtherLogsPage.h new file mode 100644 index 00000000..d6e4ec9f --- /dev/null +++ b/application/pages/OtherLogsPage.h @@ -0,0 +1,72 @@ +/* Copyright 2013-201