diff options
Diffstat (limited to 'gui/dialogs')
43 files changed, 5821 insertions, 0 deletions
diff --git a/gui/dialogs/AboutDialog.cpp b/gui/dialogs/AboutDialog.cpp new file mode 100644 index 00000000..58d61dd0 --- /dev/null +++ b/gui/dialogs/AboutDialog.cpp @@ -0,0 +1,37 @@ +/* Copyright 2013 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 "AboutDialog.h" +#include "ui_AboutDialog.h" +#include <QIcon> +#include "MultiMC.h" +#include "gui/Platform.h" + +AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + + ui->icon->setPixmap(QIcon(":/icons/multimc/scalable/apps/multimc.svg").pixmap(64)); + ui->title->setText("MultiMC " + MMC->version().toString()); + connect(ui->closeButton, SIGNAL(clicked()), SLOT(close())); + + MMC->connect(ui->aboutQt, SIGNAL(clicked()), SLOT(aboutQt())); +} + +AboutDialog::~AboutDialog() +{ + delete ui; +} diff --git a/gui/dialogs/AboutDialog.h b/gui/dialogs/AboutDialog.h new file mode 100644 index 00000000..9d747bac --- /dev/null +++ b/gui/dialogs/AboutDialog.h @@ -0,0 +1,35 @@ +/* Copyright 2013 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 <QDialog> + +namespace Ui +{ +class AboutDialog; +} + +class AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent = 0); + ~AboutDialog(); + +private: + Ui::AboutDialog *ui; +}; diff --git a/gui/dialogs/AboutDialog.ui b/gui/dialogs/AboutDialog.ui new file mode 100644 index 00000000..0a189d9c --- /dev/null +++ b/gui/dialogs/AboutDialog.ui @@ -0,0 +1,316 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AboutDialog</class> + <widget class="QDialog" name="AboutDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>450</width> + <height>429</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>450</width> + <height>400</height> + </size> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <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="QLabel" name="icon"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>64</width> + <height>64</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>64</width> + <height>64</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../multimc.qrc">:/icons/multimc/scalable/apps/multimc.svg</pixmap> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QLabel" name="title"> + <property name="font"> + <font> + <pointsize>15</pointsize> + </font> + </property> + <property name="text"> + <string>MultiMC</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QToolBox" name="toolBox"> + <widget class="QWidget" name="aboutPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>432</width> + <height>179</height> + </rect> + </property> + <attribute name="label"> + <string>About</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="aboutLabel"> + <property name="text"> + <string><html><head/><body><p>MultiMC is a custom launcher that makes managing Minecraft easier by allowing you to have multiple instances of Minecraft at once.</p></body></html></string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="copyLabel"> + <property name="font"> + <font> + <pointsize>8</pointsize> + <kerning>true</kerning> + </font> + </property> + <property name="text"> + <string>© 2013 MultiMC Contributors</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="urlLabel"> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="text"> + <string><html><head/><body><p><a href="http://github.com/Forkk/MultiMC5"><span style=" text-decoration: underline; color:#0000ff;">http://github.com/MultiMC/MultiMC5</span></a></p></body></html></string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="creditsPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>98</width> + <height>120</height> + </rect> + </property> + <attribute name="label"> + <string>Credits</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QTextEdit" name="creditsText"> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="html"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Andrew Okin &lt;</span><a href="mailto:forkk@forkk.net"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">forkk@forkk.net</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Petr Mrázek &lt;</span><a href="mailto:peterix@gmail.com"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">peterix@gmail.com</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Orochimarufan &lt;</span><a href="mailto:orochimarufan.x3@gmail.com"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">orochimarufan.x3@gmail.com</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">TakSuyu &lt;</span><a href="mailto:taksuyu@gmail.com"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">taksuyu@gmail.com</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Sky (Drayshak) &lt;</span><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">multimc@bunnies.cc</span><span style=" font-family:'Ubuntu';">&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Kilobyte &lt;</span><a href="mailto:stiepen22@gmx.de"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">stiepen22@gmx.de</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p></body></html></string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="translationInfo"> + <property name="text"> + <string extracomment="Hey, Translator, feel free to put credit to you here">No Language file loaded.</string> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="licensePage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>98</width> + <height>88</height> + </rect> + </property> + <attribute name="label"> + <string>License</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QTextEdit" name="licenseText"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="html"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Copyright 2012 MultiMC Contributors</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">you may not use this file except in compliance with the License.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">You may obtain a copy of the License at</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;"> http://www.apache.org/licenses/LICENSE-2.0</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Unless required by applicable law or agreed to in writing, software</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">See the License for the specific language governing permissions and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">limitations under the License.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">MultiMC uses QSLog, </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Copyright (c) 2010, Razvan Petru</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">All rights reserved.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Redistribution and use in source and binary forms, with or without modification,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">are permitted provided that the following conditions are met:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">* Redistributions of source code must retain the above copyright notice, this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;"> list of conditions and the following disclaimer.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">* Redistributions in binary form must reproduce the above copyright notice, this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;"> list of conditions and the following disclaimer in the documentation and/or other</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;"> materials provided with the distribution.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">* The name of the contributors may not be used to endorse or promote products</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;"> derived from this software without specific prior written permission.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">OF THE POSSIBILITY OF SUCH DAMAGE.</span></p></body></html></string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QPushButton" name="aboutQt"> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="text"> + <string>About Qt</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <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> + <include location="../../multimc.qrc"/> + <include location="../../multimc.qrc"/> + </resources> + <connections/> +</ui> diff --git a/gui/dialogs/CopyInstanceDialog.cpp b/gui/dialogs/CopyInstanceDialog.cpp new file mode 100644 index 00000000..4d588a1e --- /dev/null +++ b/gui/dialogs/CopyInstanceDialog.cpp @@ -0,0 +1,84 @@ +/* Copyright 2013 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 <QLayout> +#include <QPushButton> + +#include "MultiMC.h" +#include "CopyInstanceDialog.h" +#include "ui_CopyInstanceDialog.h" + +#include "gui/Platform.h" +#include "gui/dialogs/VersionSelectDialog.h" +#include "gui/dialogs/ProgressDialog.h" +#include "gui/dialogs/IconPickerDialog.h" + +#include "logic/InstanceFactory.h" +#include "logic/BaseVersion.h" +#include "logic/lists/IconList.h" +#include "logic/lists/MinecraftVersionList.h" +#include "logic/tasks/Task.h" +#include "logic/BaseInstance.h" + +CopyInstanceDialog::CopyInstanceDialog(BaseInstance *original, QWidget *parent) + : m_original(original), QDialog(parent), ui(new Ui::CopyInstanceDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + resize(minimumSizeHint()); + layout()->setSizeConstraint(QLayout::SetFixedSize); + + InstIconKey = original->iconKey(); + ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey)); + ui->instNameTextBox->setText(original->name()); + ui->instNameTextBox->setFocus(); +} + +CopyInstanceDialog::~CopyInstanceDialog() +{ + delete ui; +} + +void CopyInstanceDialog::updateDialogState() +{ + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!instName().isEmpty()); +} + +QString CopyInstanceDialog::instName() const +{ + return ui->instNameTextBox->text(); +} + +QString CopyInstanceDialog::iconKey() const +{ + return InstIconKey; +} + +void CopyInstanceDialog::on_iconButton_clicked() +{ + IconPickerDialog dlg(this); + dlg.exec(InstIconKey); + + if (dlg.result() == QDialog::Accepted) + { + InstIconKey = dlg.selectedIconKey; + ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey)); + } +} + +void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) +{ + updateDialogState(); +} diff --git a/gui/dialogs/CopyInstanceDialog.h b/gui/dialogs/CopyInstanceDialog.h new file mode 100644 index 00000000..7ab366e2 --- /dev/null +++ b/gui/dialogs/CopyInstanceDialog.h @@ -0,0 +1,50 @@ +/* Copyright 2013 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 <QDialog> +#include "logic/BaseVersion.h" + +class BaseInstance; + +namespace Ui +{ +class CopyInstanceDialog; +} + +class CopyInstanceDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CopyInstanceDialog(BaseInstance *original, QWidget *parent = 0); + ~CopyInstanceDialog(); + + void updateDialogState(); + + QString instName() const; + QString iconKey() const; + +private +slots: + void on_iconButton_clicked(); + void on_instNameTextBox_textChanged(const QString &arg1); + +private: + Ui::CopyInstanceDialog *ui; + QString InstIconKey; + BaseInstance *m_original; +}; diff --git a/gui/dialogs/CopyInstanceDialog.ui b/gui/dialogs/CopyInstanceDialog.ui new file mode 100644 index 00000000..dd7ce641 --- /dev/null +++ b/gui/dialogs/CopyInstanceDialog.ui @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CopyInstanceDialog</class> + <widget class="QDialog" name="CopyInstanceDialog"> + <property name="windowModality"> + <enum>Qt::ApplicationModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>345</width> + <height>205</height> + </rect> + </property> + <property name="windowTitle"> + <string>Copy Instance</string> + </property> + <property name="windowIcon"> + <iconset resource="../../multimc.qrc"> + <normaloff>:/icons/toolbar/copy</normaloff>:/icons/toolbar/copy</iconset> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="iconBtnLayout"> + <item> + <spacer name="iconBtnLeftSpacer"> + <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="QToolButton" name="iconButton"> + <property name="icon"> + <iconset resource="../../multimc.qrc"> + <normaloff>:/icons/instances/infinity</normaloff>:/icons/instances/infinity</iconset> + </property> + <property name="iconSize"> + <size> + <width>80</width> + <height>80</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="iconBtnRightSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QLineEdit" name="instNameTextBox"> + <property name="placeholderText"> + <string>Name</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../multimc.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>CopyInstanceDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>CopyInstanceDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/gui/dialogs/CustomMessageBox.cpp b/gui/dialogs/CustomMessageBox.cpp new file mode 100644 index 00000000..1d2ab58a --- /dev/null +++ b/gui/dialogs/CustomMessageBox.cpp @@ -0,0 +1,34 @@ +/* Copyright 2013 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 "CustomMessageBox.h" + +namespace CustomMessageBox +{ +QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text, + QMessageBox::Icon icon, QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton) +{ + QMessageBox *messageBox = new QMessageBox(parent); + messageBox->setWindowTitle(title); + messageBox->setText(text); + messageBox->setStandardButtons(buttons); + messageBox->setDefaultButton(defaultButton); + messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse); + messageBox->setIcon(icon); + + return messageBox; +} +} diff --git a/gui/dialogs/CustomMessageBox.h b/gui/dialogs/CustomMessageBox.h new file mode 100644 index 00000000..b08b9f57 --- /dev/null +++ b/gui/dialogs/CustomMessageBox.h @@ -0,0 +1,26 @@ +/* Copyright 2013 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 <QMessageBox> + +namespace CustomMessageBox +{ +QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text, + QMessageBox::Icon icon = QMessageBox::NoIcon, + QMessageBox::StandardButtons buttons = QMessageBox::Ok, + QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); +} diff --git a/gui/dialogs/EditNotesDialog.cpp b/gui/dialogs/EditNotesDialog.cpp new file mode 100644 index 00000000..cd52e694 --- /dev/null +++ b/gui/dialogs/EditNotesDialog.cpp @@ -0,0 +1,42 @@ +/* Copyright 2013 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 "EditNotesDialog.h" +#include "ui_EditNotesDialog.h" +#include "gui/Platform.h" + +#include <QIcon> +#include <QApplication> + +EditNotesDialog::EditNotesDialog(QString notes, QString name, QWidget *parent) + : m_instance_notes(notes), m_instance_name(name), QDialog(parent), + ui(new Ui::EditNotesDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + ui->noteEditor->setText(notes); + setWindowTitle(tr("Edit notes of %1").arg(m_instance_name)); + // connect(ui->closeButton, SIGNAL(clicked()), SLOT(close())); +} + +EditNotesDialog::~EditNotesDialog() +{ + delete ui; +} + +QString EditNotesDialog::getText() +{ + return ui->noteEditor->toPlainText(); +} diff --git a/gui/dialogs/EditNotesDialog.h b/gui/dialogs/EditNotesDialog.h new file mode 100644 index 00000000..b74558c4 --- /dev/null +++ b/gui/dialogs/EditNotesDialog.h @@ -0,0 +1,38 @@ +/* Copyright 2013 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 <QDialog> + +namespace Ui +{ +class EditNotesDialog; +} + +class EditNotesDialog : public QDialog +{ + Q_OBJECT + +public: + explicit EditNotesDialog(QString notes, QString name, QWidget *parent = 0); + ~EditNotesDialog(); + QString getText(); + +private: + Ui::EditNotesDialog *ui; + QString m_instance_name; + QString m_instance_notes; +}; diff --git a/gui/dialogs/EditNotesDialog.ui b/gui/dialogs/EditNotesDialog.ui new file mode 100644 index 00000000..487dfb84 --- /dev/null +++ b/gui/dialogs/EditNotesDialog.ui @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>EditNotesDialog</class> + <widget class="QDialog" name="EditNotesDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>459</width> + <height>399</height> + </rect> + </property> + <property name="windowTitle"> + <string>Edit Notes</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTextEdit" name="noteEditor"> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOn</enum> + </property> + <property name="acceptRichText"> + <bool>false</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>EditNotesDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>EditNotesDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/gui/dialogs/IconPickerDialog.cpp b/gui/dialogs/IconPickerDialog.cpp new file mode 100644 index 00000000..99d6dc9a --- /dev/null +++ b/gui/dialogs/IconPickerDialog.cpp @@ -0,0 +1,156 @@ +/* Copyright 2013 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 <QKeyEvent> +#include <QPushButton> +#include <QFileDialog> + +#include "MultiMC.h" + +#include "IconPickerDialog.h" +#include "ui_IconPickerDialog.h" + +#include "gui/Platform.h" +#include "gui/widgets/InstanceDelegate.h" + +#include "logic/lists/IconList.h" + +IconPickerDialog::IconPickerDialog(QWidget *parent) + : QDialog(parent), ui(new Ui::IconPickerDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + setWindowModality(Qt::WindowModal); + + auto contentsWidget = ui->iconView; + contentsWidget->setViewMode(QListView::IconMode); + contentsWidget->setFlow(QListView::LeftToRight); + contentsWidget->setIconSize(QSize(48, 48)); + contentsWidget->setMovement(QListView::Static); + contentsWidget->setResizeMode(QListView::Adjust); + contentsWidget->setSelectionMode(QAbstractItemView::SingleSelection); + contentsWidget->setSpacing(5); + contentsWidget->setWordWrap(false); + contentsWidget->setWrapping(true); + contentsWidget->setUniformItemSizes(true); + contentsWidget->setTextElideMode(Qt::ElideRight); + contentsWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + contentsWidget->setItemDelegate(new ListViewDelegate()); + + // contentsWidget->setAcceptDrops(true); + contentsWidget->setDropIndicatorShown(true); + contentsWidget->viewport()->setAcceptDrops(true); + contentsWidget->setDragDropMode(QAbstractItemView::DropOnly); + contentsWidget->setDefaultDropAction(Qt::CopyAction); + + contentsWidget->installEventFilter(this); + + contentsWidget->setModel(MMC->icons().get()); + + auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"), QDialogButtonBox::ResetRole); + auto buttonRemove = + ui->buttonBox->addButton(tr("Remove Icon"), QDialogButtonBox::ResetRole); + + connect(buttonAdd, SIGNAL(clicked(bool)), SLOT(addNewIcon())); + connect(buttonRemove, SIGNAL(clicked(bool)), SLOT(removeSelectedIcon())); + + connect(contentsWidget, SIGNAL(doubleClicked(QModelIndex)), SLOT(activated(QModelIndex))); + + connect(contentsWidget->selectionModel(), + SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + SLOT(selectionChanged(QItemSelection, QItemSelection))); +} +bool IconPickerDialog::eventFilter(QObject *obj, QEvent *evt) +{ + if (obj != ui->iconView) + return QDialog::eventFilter(obj, evt); + if (evt->type() != QEvent::KeyPress) + { + return QDialog::eventFilter(obj, evt); + } + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt); + switch (keyEvent->key()) + { + case Qt::Key_Delete: + removeSelectedIcon(); + return true; + case Qt::Key_Plus: + addNewIcon(); + return true; + default: + break; + } + return QDialog::eventFilter(obj, evt); +} + +void IconPickerDialog::addNewIcon() +{ + //: The title of the select icons open file dialog + QString selectIcons = tr("Select Icons"); + //: The type of icon files + QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(), + tr("Icons") + "(*.png *.jpg *.jpeg)"); + MMC->icons()->installIcons(fileNames); +} + +void IconPickerDialog::removeSelectedIcon() +{ + MMC->icons()->deleteIcon(selectedIconKey); +} + +void IconPickerDialog::activated(QModelIndex index) +{ + selectedIconKey = index.data(Qt::UserRole).toString(); + accept(); +} + +void IconPickerDialog::selectionChanged(QItemSelection selected, QItemSelection deselected) +{ + if (selected.empty()) + return; + + QString key = selected.first().indexes().first().data(Qt::UserRole).toString(); + if (!key.isEmpty()) + selectedIconKey = key; +} + +int IconPickerDialog::exec(QString selection) +{ + auto list = MMC->icons(); + auto contentsWidget = ui->iconView; + selectedIconKey = selection; + + int index_nr = list->getIconIndex(selection); + auto model_index = list->index(index_nr); + contentsWidget->selectionModel()->select( + model_index, QItemSelectionModel::Current | QItemSelectionModel::Select); + + QMetaObject::invokeMethod(this, "delayed_scroll", Qt::QueuedConnection, + Q_ARG(QModelIndex, model_index)); + return QDialog::exec(); +} + +void IconPickerDialog::delayed_scroll(QModelIndex model_index) +{ + auto contentsWidget = ui->iconView; + contentsWidget->scrollTo(model_index); +} + +IconPickerDialog::~IconPickerDialog() +{ + delete ui; +} diff --git a/gui/dialogs/IconPickerDialog.h b/gui/dialogs/IconPickerDialog.h new file mode 100644 index 00000000..f00c2388 --- /dev/null +++ b/gui/dialogs/IconPickerDialog.h @@ -0,0 +1,48 @@ +/* Copyright 2013 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 <QDialog> +#include <QItemSelection> + +namespace Ui +{ +class IconPickerDialog; +} + +class IconPickerDialog : public QDialog +{ + Q_OBJECT + +public: + explicit IconPickerDialog(QWidget *parent = 0); + ~IconPickerDialog(); + int exec(QString selection); + QString selectedIconKey; + +protected: + virtual bool eventFilter(QObject *, QEvent *); + +private: + Ui::IconPickerDialog *ui; + +private +slots: + void selectionChanged(QItemSelection, QItemSelection); + void activated(QModelIndex); + void delayed_scroll(QModelIndex); + void addNewIcon(); + void removeSelectedIcon(); +}; diff --git a/gui/dialogs/IconPickerDialog.ui b/gui/dialogs/IconPickerDialog.ui new file mode 100644 index 00000000..c548edfb --- /dev/null +++ b/gui/dialogs/IconPickerDialog.ui @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>IconPickerDialog</class> + <widget class="QDialog" name="IconPickerDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>676</width> + <height>555</height> + </rect> + </property> + <property name="windowTitle"> + <string>Pick icon</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QListView" name="iconView"/> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>IconPickerDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>IconPickerDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/gui/dialogs/InstanceSettings.cpp b/gui/dialogs/InstanceSettings.cpp new file mode 100644 index 00000000..57dd6a81 --- /dev/null +++ b/gui/dialogs/InstanceSettings.cpp @@ -0,0 +1,180 @@ +/* Copyright 2013 MultiMC Contributors + * + * Authors: Andrew Okin + * Peterix + * Orochimarufan <orochimarufan.x3@gmail.com> + * + * 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 "InstanceSettings.h" +#include "ui_InstanceSettings.h" +#include "gui/Platform.h" + +InstanceSettings::InstanceSettings(SettingsObject *obj, QWidget *parent) + : m_obj(obj), QDialog(parent), ui(new Ui::InstanceSettings) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + loadSettings(); +} + +InstanceSettings::~InstanceSettings() +{ + delete ui; +} + +void InstanceSettings::showEvent(QShowEvent *ev) +{ + QDialog::showEvent(ev); + adjustSize(); +} + +void InstanceSettings::on_customCommandsGroupBox_toggled(bool state) +{ + ui->labelCustomCmdsDescription->setEnabled(state); +} + +void InstanceSettings::on_buttonBox_accepted() +{ + applySettings(); + accept(); +} + +void InstanceSettings::on_buttonBox_rejected() +{ + reject(); +} + +void InstanceSettings::applySettings() +{ + // Console + bool console = ui->consoleSettingsBox->isChecked(); + m_obj->set("OverrideConsole", console); + if (console) + { + m_obj->set("ShowConsole", ui->showConsoleCheck->isChecked()); + m_obj->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); + } + else + { + m_obj->reset("ShowConsole"); + m_obj->reset("AutoCloseConsole"); + } + + // Window Size + bool window = ui->windowSizeGroupBox->isChecked(); + m_obj->set("OverrideWindow", window); + if (window) + { + m_obj->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); + m_obj->set("MinecraftWinWidth", ui->windowWidthSpinBox->value()); + m_obj->set("MinecraftWinHeight", ui->windowHeightSpinBox->value()); + } + else + { + m_obj->reset("LaunchMaximized"); + m_obj->reset("MinecraftWinWidth"); + m_obj->reset("MinecraftWinHeight"); + } + + // Auto Login + bool login = ui->accountSettingsGroupBox->isChecked(); + m_obj->set("OverrideLogin", login); + if (login) + { + m_obj->set("AutoLogin", ui->autoLoginChecBox->isChecked()); + } + else + { + m_obj->reset("AutoLogin"); + } + + // Memory + bool memory = ui->memoryGroupBox->isChecked(); + m_obj->set("OverrideMemory", memory); + if (memory) + { + m_obj->set("MinMemAlloc", ui->minMemSpinBox->value()); + m_obj->set("MaxMemAlloc", ui->maxMemSpinBox->value()); + m_obj->set("PermGen", ui->permGenSpinBox->value()); + } + else + { + m_obj->reset("MinMemAlloc"); + m_obj->reset("MaxMemAlloc"); + m_obj->reset("PermGen"); + } + + // Java Settings + bool java = ui->javaSettingsGroupBox->isChecked(); + m_obj->set("OverrideJava", java); + if (java) + { + m_obj->set("JavaPath", ui->javaPathTextBox->text()); + m_obj->set("JvmArgs", ui->jvmArgsTextBox->text()); + } + else + { + m_obj->reset("JavaPath"); + m_obj->reset("JvmArgs"); + } + + // Custom Commands + bool custcmd = ui->customCommandsGroupBox->isChecked(); + m_obj->set("OverrideCommands", custcmd); + if (custcmd) + { + m_obj->set("PreLaunchCommand", ui->preLaunchCmdTextBox->text()); + m_obj->set("PostExitCommand", ui->postExitCmdTextBox->text()); + } + else + { + m_obj->reset("PreLaunchCommand"); + m_obj->reset("PostExitCommand"); + } +} + +void InstanceSettings::loadSettings() +{ + // Console + ui->consoleSettingsBox->setChecked(m_obj->get("OverrideConsole").toBool()); + ui->showConsoleCheck->setChecked(m_obj->get("ShowConsole").toBool()); + ui->autoCloseConsoleCheck->setChecked(m_obj->get("AutoCloseConsole").toBool()); + + // Window Size + ui->windowSizeGroupBox->setChecked(m_obj->get("OverrideWindow").toBool()); + ui->maximizedCheckBox->setChecked(m_obj->get("LaunchMaximized").toBool()); + ui->windowWidthSpinBox->setValue(m_obj->get("MinecraftWinWidth").toInt()); + ui->windowHeightSpinBox->setValue(m_obj->get("MinecraftWinHeight").toInt()); + + // Auto Login + ui->accountSettingsGroupBox->setChecked(m_obj->get("OverrideLogin").toBool()); + ui->autoLoginChecBox->setChecked(m_obj->get("AutoLogin").toBool()); + + // Memory + ui->memoryGroupBox->setChecked(m_obj->get("OverrideMemory").toBool()); + ui->minMemSpinBox->setValue(m_obj->get("MinMemAlloc").toInt()); + ui->maxMemSpinBox->setValue(m_obj->get("MaxMemAlloc").toInt()); + ui->permGenSpinBox->setValue(m_obj->get("PermGen").toInt()); + + // Java Settings + ui->javaSettingsGroupBox->setChecked(m_obj->get("OverrideJava").toBool()); + ui->javaPathTextBox->setText(m_obj->get("JavaPath").toString()); + ui->jvmArgsTextBox->setText(m_obj->get("JvmArgs").toString()); + + // Custom Commands + ui->customCommandsGroupBox->setChecked(m_obj->get("OverrideCommands").toBool()); + ui->preLaunchCmdTextBox->setText(m_obj->get("PreLaunchCommand").toString()); + ui->postExitCmdTextBox->setText(m_obj->get("PostExitCommand").toString()); +} diff --git a/gui/dialogs/InstanceSettings.h b/gui/dialogs/InstanceSettings.h new file mode 100644 index 00000000..452e7a58 --- /dev/null +++ b/gui/dialogs/InstanceSettings.h @@ -0,0 +1,50 @@ +/* Copyright 2013 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 <QDialog> +#include "settingsobject.h" + +namespace Ui +{ +class InstanceSettings; +} + +class InstanceSettings : public QDialog +{ + Q_OBJECT + +public: + explicit InstanceSettings(SettingsObject *s, QWidget *parent = 0); + ~InstanceSettings(); + + void updateCheckboxStuff(); + + void applySettings(); + void loadSettings(); + +protected: + virtual void showEvent(QShowEvent *); +private +slots: + void on_customCommandsGroupBox_toggled(bool arg1); + void on_buttonBox_accepted(); + void on_buttonBox_rejected(); + +private: + Ui::InstanceSettings *ui; + SettingsObject *m_obj; +}; diff --git a/gui/dialogs/InstanceSettings.ui b/gui/dialogs/InstanceSettings.ui new file mode 100644 index 00000000..b536e9ff --- /dev/null +++ b/gui/dialogs/InstanceSettings.ui @@ -0,0 +1,422 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>InstanceSettings</class> + <widget class="QDialog" name="InstanceSettings"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>526</width> + <height>590</height> + </rect> + </property> + <property name="windowTitle"> + <string/> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="settingsTabs"> + <property name="tabShape"> + <enum>QTabWidget::Rounded</enum> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="minecraftTab"> + <attribute name="title"> + <string>Minecraft</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QGroupBox" name="windowSizeGroupBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Window Size</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QCheckBox" name="maximizedCheckBox"> + <property name="text"> + <string>Start Minecraft maximized?</string> + </property> + </widget> + </item> + <item> + <layout class="QGridLayout" name="gridLayoutWindowSize"> + <item row="1" column="0"> + <widget class="QLabel" name="labelWindowHeight"> + <property name="text"> + <string>Window height:</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelWindowWidth"> + <property name="text"> + <string>Window width:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="windowWidthSpinBox"> + <property name="minimum"> + <number>854</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + <property name="value"> + <number>854</number> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="windowHeightSpinBox"> + <property name="minimum"> + <number>480</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + <property name="value"> + <number>480</number> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="consoleSettingsBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Console Settings</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QCheckBox" name="showConsoleCheck"> + <property name="text"> + <string>Show console while the game is running?</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="autoCloseConsoleCheck"> + <property name="text"> + <string>Automatically close console when the game quits?</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="accountSettingsGroupBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Account Settings</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <widget class="QCheckBox" name="autoLoginChecBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Login automatically when an instance icon is double clicked?</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacerMinecraft"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="javaTab"> + <attribute name="title"> + <string>Java</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QGroupBox" name="memoryGroupBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Memory</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="1"> + <widget class="QSpinBox" name="maxMemSpinBox"> + <property name="minimum"> + <number>512</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + <property name="singleStep"> + <number>128</number> + </property> + <property name="value"> + <number>1024</number> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelMinMem"> + <property name="text"> + <string>Minimum memory allocation:</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelMaxMem"> + <property name="text"> + <string>Maximum memory allocation:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="minMemSpinBox"> + <property name="minimum"> + <number>256</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + <property name="singleStep"> + <number>128</number> + </property> + <property name="value"> + <number>256</number> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="permGenSpinBox"> + <property name="minimum"> + <number>64</number> + </property> + <property name="maximum"> + <number>999999999</number> + </property> + <property name="singleStep"> + <number>8</number> + </property> + <property name="value"> + <number>64</number> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelPermGen"> + <property name="text"> + <string>PermGen:</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="javaSettingsGroupBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Java Settings</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="labelJavaPath"> + <property name="text"> + <string>Java path:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="javaPathTextBox"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelJVMArgs"> + <property name="text"> + <string>JVM arguments:</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>Auto-detect</string> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QLineEdit" name="jvmArgsTextBox"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="customCommandsGroupBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Custom Commands</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="1"> + <widget class="QLineEdit" name="preLaunchCmdTextBox"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelPostExitCmd"> + <property name="text"> + <string>Post-exit command:</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelPreLaunchCmd"> + <property name="text"> + <string>Pre-launch command:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="postExitCmdTextBox"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QLabel" name="labelCustomCmdsDescription"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Pre-launch command runs before the instance launches and post-exit command runs after it exits. Both will be run in MultiMC's working directory with INST_ID, INST_DIR, and INST_NAME as environment variables.</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>settingsTabs</tabstop> + <tabstop>buttonBox</tabstop> + <tabstop>windowSizeGroupBox</tabstop> + <tabstop>maximizedCheckBox</tabstop> + <tabstop>windowWidthSpinBox</tabstop> + <tabstop>windowHeightSpinBox</tabstop> + <tabstop>consoleSettingsBox</tabstop> + <tabstop>showConsoleCheck</tabstop> + <tabstop>autoCloseConsoleCheck</tabstop> + <tabstop>accountSettingsGroupBox</tabstop> + <tabstop>autoLoginChecBox</tabstop> + <tabstop>memoryGroupBox</tabstop> + <tabstop>minMemSpinBox</tabstop> + <tabstop>maxMemSpinBox</tabstop> + <tabstop>permGenSpinBox</tabstop> + <tabstop>javaSettingsGroupBox</tabstop> + <tabstop>javaPathTextBox</tabstop> + <tabstop>pushButton</tabstop> + <tabstop>jvmArgsTextBox</tabstop> + <tabstop>customCommandsGroupBox</tabstop> + <tabstop>preLaunchCmdTextBox</tabstop> + <tabstop>postExitCmdTextBox</tabstop> + </tabstops> + <resources/> + <connections/> +</ui> diff --git a/gui/dialogs/LegacyModEditDialog.cpp b/gui/dialogs/LegacyModEditDialog.cpp new file mode 100644 index 00000000..25a1c616 --- /dev/null +++ b/gui/dialogs/LegacyModEditDialog.cpp @@ -0,0 +1,393 @@ +/* Copyright 2013 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 "MultiMC.h" +#include "LegacyModEditDialog.h" +#include "ModEditDialogCommon.h" +#include "VersionSelectDialog.h" +#include "ProgressDialog.h" +#include "ui_LegacyModEditDialog.h" +#include "logic/ModList.h" +#include "logic/lists/ForgeVersionList.h" +#include "gui/Platform.h" + +#include <pathutils.h> +#include <QFileDialog> +//#include <QMessageBox> +#include <QDebug> +#include <QEvent> +#include <QKeyEvent> + +LegacyModEditDialog::LegacyModEditDialog(LegacyInstance *inst, QWidget *parent) + : m_inst(inst), QDialog(parent), ui(new Ui::LegacyModEditDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + + // Jar mods + { + ensureFolderPathExists(m_inst->jarModsDir()); + m_jarmods = m_inst->jarModList(); + ui->jarModsTreeView->setModel(m_jarmods.get()); +#ifndef Q_OS_LINUX + // FIXME: internal DnD causes segfaults later + ui->jarModsTreeView->setDragDropMode(QAbstractItemView::DragDrop); + // FIXME: DnD is glitched with contiguous (we move only first item in selection) + ui->jarModsTreeView->setSelectionMode(QAbstractItemView::SingleSelection); +#endif + ui->jarModsTreeView->installEventFilter(this); + m_jarmods->startWatching(); + auto smodel = ui->jarModsTreeView->selectionModel(); + connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + SLOT(jarCurrent(QModelIndex, QModelIndex))); + } + // Core mods + { + ensureFolderPathExists(m_inst->coreModsDir()); + m_coremods = m_inst->coreModList(); + ui->coreModsTreeView->setModel(m_coremods.get()); + ui->coreModsTreeView->installEventFilter(this); + m_coremods->startWatching(); + auto smodel = ui->coreModsTreeView->selectionModel(); + connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + SLOT(coreCurrent(QModelIndex, QModelIndex))); + } + // Loader mods + { + ensureFolderPathExists(m_inst->loaderModsDir()); + m_mods = m_inst->loaderModList(); + ui->loaderModTreeView->setModel(m_mods.get()); + ui->loaderModTreeView->installEventFilter(this); + m_mods->startWatching(); + auto smodel = ui->loaderModTreeView->selectionModel(); + connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + SLOT(loaderCurrent(QModelIndex, QModelIndex))); + } + // texture packs + { + ensureFolderPathExists(m_inst->texturePacksDir()); + m_texturepacks = m_inst->texturePackList(); + ui->texPackTreeView->setModel(m_texturepacks.get()); + ui->texPackTreeView->installEventFilter(this); + m_texturepacks->startWatching(); + } +} + +LegacyModEditDialog::~LegacyModEditDialog() +{ + m_mods->stopWatching(); + m_coremods->stopWatching(); + m_jarmods->stopWatching(); + m_texturepacks->stopWatching(); + delete ui; +} + +bool LegacyModEditDialog::coreListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Delete: + on_rmCoreBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addCoreBtn_clicked(); + return true; + default: + break; + } + return QDialog::eventFilter(ui->coreModsTreeView, keyEvent); +} + +bool LegacyModEditDialog::jarListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Up: + { + if (keyEvent->modifiers() & Qt::ControlModifier) + { + on_moveJarUpBtn_clicked(); + return true; + } + break; + } + case Qt::Key_Down: + { + if (keyEvent->modifiers() & Qt::ControlModifier) + { + on_moveJarDownBtn_clicked(); + return true; + } + break; + } + case Qt::Key_Delete: + on_rmJarBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addJarBtn_clicked(); + return true; + default: + break; + } + return QDialog::eventFilter(ui->jarModsTreeView, keyEvent); +} + +bool LegacyModEditDialog::loaderListFilter(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 QDialog::eventFilter(ui->loaderModTreeView, keyEvent); +} + +bool LegacyModEditDialog::texturePackListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Delete: + on_rmTexPackBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addTexPackBtn_clicked(); + return true; + default: + break; + } + return QDialog::eventFilter(ui->texPackTreeView, keyEvent); +} + +bool LegacyModEditDialog::eventFilter(QObject *obj, QEvent *ev) +{ + if (ev->type() != QEvent::KeyPress) + { + return QDialog::eventFilter(obj, ev); + } + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev); + if (obj == ui->jarModsTreeView) + return jarListFilter(keyEvent); + if (obj == ui->coreModsTreeView) + return coreListFilter(keyEvent); + if (obj == ui->loaderModTreeView) + return loaderListFilter(keyEvent); + if (obj == ui->texPackTreeView) + return texturePackListFilter(keyEvent); + return QDialog::eventFilter(obj, ev); +} + +void LegacyModEditDialog::on_addCoreBtn_clicked() +{ + //: Title of core mod selection dialog + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Core Mods")); + for (auto filename : fileNames) + { + m_coremods->stopWatching(); + m_coremods->installMod(QFileInfo(filename)); + m_coremods->startWatching(); + } +} +void LegacyModEditDialog::on_addForgeBtn_clicked() +{ + VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this); + vselect.setFilter(1, m_inst->intendedVersionId()); + if (vselect.exec() && vselect.selectedVersion()) + { + ForgeVersionPtr forge = + std::dynamic_pointer_cast<ForgeVersion>(vselect.selectedVersion()); + if (!forge) + return; + auto entry = MMC->metacache()->resolveEntry("minecraftforge", forge->filename); + if (entry->stale) + { + NetJob *fjob = new NetJob("Forge download"); + fjob->addNetAction(CacheDownload::make(forge->universal_url, entry)); + ProgressDialog dlg(this); + dlg.exec(fjob); + if (dlg.result() == QDialog::Accepted) + { + m_jarmods->stopWatching(); + m_jarmods->installMod(QFileInfo(entry->getFullPath())); + m_jarmods->startWatching(); + } + else + { + // failed to download forge :/ + } + } + else + { + m_jarmods->stopWatching(); + m_jarmods->installMod(QFileInfo(entry->getFullPath())); + m_jarmods->startWatching(); + } + } +} +void LegacyModEditDialog::on_addJarBtn_clicked() +{ + //: Title of jar mod selection dialog + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Jar Mods")); + for (auto filename : fileNames) + { + m_jarmods->stopWatching(); + m_jarmods->installMod(QFileInfo(filename)); + m_jarmods->startWatching(); + } +} +void LegacyModEditDialog::on_addModBtn_clicked() +{ + //: Title of regular mod selection dialog + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Loader Mods")); + for (auto filename : fileNames) + { + m_mods->stopWatching(); + m_mods->installMod(QFileInfo(filename)); + m_mods->startWatching(); + } +} +void LegacyModEditDialog::on_addTexPackBtn_clicked() +{ + //: Title of texture pack selection dialog + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Texture Packs")); + for (auto filename : fileNames) + { + m_texturepacks->stopWatching(); + m_texturepacks->installMod(QFileInfo(filename)); + m_texturepacks->startWatching(); + } +} + +void LegacyModEditDialog::on_moveJarDownBtn_clicked() +{ + int first, last; + auto list = ui->jarModsTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + + m_jarmods->moveModsDown(first, last); +} +void LegacyModEditDialog::on_moveJarUpBtn_clicked() +{ + int first, last; + auto list = ui->jarModsTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_jarmods->moveModsUp(first, last); +} +void LegacyModEditDialog::on_rmCoreBtn_clicked() +{ + int first, last; + auto list = ui->coreModsTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_coremods->stopWatching(); + m_coremods->deleteMods(first, last); + m_coremods->startWatching(); +} +void LegacyModEditDialog::on_rmJarBtn_clicked() +{ + int first, last; + auto list = ui->jarModsTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_jarmods->stopWatching(); + m_jarmods->deleteMods(first, last); + m_jarmods->startWatching(); +} +void LegacyModEditDialog::on_rmModBtn_clicked() +{ + int first, last; + auto list = ui->loaderModTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_mods->stopWatching(); + m_mods->deleteMods(first, last); + m_mods->startWatching(); +} +void LegacyModEditDialog::on_rmTexPackBtn_clicked() +{ + int first, last; + auto list = ui->texPackTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_texturepacks->stopWatching(); + m_texturepacks->deleteMods(first, last); + m_texturepacks->startWatching(); +} +void LegacyModEditDialog::on_viewCoreBtn_clicked() +{ + openDirInDefaultProgram(m_inst->coreModsDir(), true); +} +void LegacyModEditDialog::on_viewModBtn_clicked() +{ + openDirInDefaultProgram(m_inst->loaderModsDir(), true); +} +void LegacyModEditDialog::on_viewTexPackBtn_clicked() +{ + openDirInDefaultProgram(m_inst->texturePacksDir(), true); +} + +void LegacyModEditDialog::on_buttonBox_rejected() +{ + close(); +} + +void LegacyModEditDialog::jarCurrent(QModelIndex current, QModelIndex previous) +{ + if (!current.isValid()) + { + ui->jarMIFrame->clear(); + return; + } + int row = current.row(); + Mod &m = m_jarmods->operator[](row); + ui->jarMIFrame->updateWithMod(m); +} + +void LegacyModEditDialog::coreCurrent(QModelIndex current, QModelIndex previous) +{ + if (!current.isValid()) + { + ui->coreMIFrame->clear(); + return; + } + int row = current.row(); + Mod &m = m_coremods->operator[](row); + ui->coreMIFrame->updateWithMod(m); +} + +void LegacyModEditDialog::loaderCurrent(QModelIndex current, QModelIndex previous) +{ + if (!current.isValid()) + { + ui->loaderMIFrame->clear(); + return; + } + int row = current.row(); + Mod &m = m_mods->operator[](row); + ui->loaderMIFrame->updateWithMod(m); +} diff --git a/gui/dialogs/LegacyModEditDialog.h b/gui/dialogs/LegacyModEditDialog.h new file mode 100644 index 00000000..d5582aef --- /dev/null +++ b/gui/dialogs/LegacyModEditDialog.h @@ -0,0 +1,78 @@ +/* Copyright 2013 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 <QDialog> +#include "logic/LegacyInstance.h" +#include <logic/net/NetJob.h> + +namespace Ui +{ +class LegacyModEditDialog; +} + +class LegacyModEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit LegacyModEditDialog(LegacyInstance *inst, QWidget *parent = 0); + ~LegacyModEditDialog(); + +private +slots: + + void on_addJarBtn_clicked(); + void on_rmJarBtn_clicked(); + void on_addForgeBtn_clicked(); + void on_moveJarUpBtn_clicked(); + void on_moveJarDownBtn_clicked(); + + void on_addCoreBtn_clicked(); + void on_rmCoreBtn_clicked(); + void on_viewCoreBtn_clicked(); + + void on_addModBtn_clicked(); + void on_rmModBtn_clicked(); + void on_viewModBtn_clicked(); + + void on_addTexPackBtn_clicked(); + void on_rmTexPackBtn_clicked(); + void on_viewTexPackBtn_clicked(); + + // Questionable: SettingsDialog doesn't need this for some reason? + void on_buttonBox_rejected(); + + void jarCurrent(QModelIndex current, QModelIndex previous); + void coreCurrent(QModelIndex current, QModelIndex previous); + void loaderCurrent(QModelIndex current, QModelIndex previous); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + bool jarListFilter(QKeyEvent *ev); + bool coreListFilter(QKeyEvent *ev); + bool loaderListFilter(QKeyEvent *ev); + bool texturePackListFilter(QKeyEvent *ev); + +private: + Ui::LegacyModEditDialog *ui; + std::shared_ptr<ModList> m_mods; + std::shared_ptr<ModList> m_coremods; + std::shared_ptr<ModList> m_jarmods; + std::shared_ptr<ModList> m_texturepacks; + LegacyInstance *m_inst; + NetJobPtr forgeJob; +}; diff --git a/gui/dialogs/LegacyModEditDialog.ui b/gui/dialogs/LegacyModEditDialog.ui new file mode 100644 index 00000000..47db0079 --- /dev/null +++ b/gui/dialogs/LegacyModEditDialog.ui @@ -0,0 +1,321 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>LegacyModEditDialog</class> + <widget class="QDialog" name="LegacyModEditDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>540</width> + <height>420</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="jarTab"> + <attribute name="title"> + <string>Jar Mods</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="ModListView" name="jarModsTreeView"> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOn</enum> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="jarModsButtonBox"> + <item> + <widget class="QPushButton" name="addJarBtn"> + <property name="text"> + <string>&Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="rmJarBtn"> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="addForgeBtn"> + <property name="text"> + <string>MCForge</string> + </property> + </widget> + </item> + <item> + <spacer name="jarModsButtonSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="moveJarUpBtn"> + <property name="text"> + <string>Move &Up</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="moveJarDownBtn"> + <property name="text"> + <string>Move &Down</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="MCModInfoFrame" name="jarMIFrame"> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="coreTab"> + <attribute name="title"> + <string>Core Mods</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="ModListView" name="coreModsTreeView"> + <property name="dragDropMode"> + <enum>QAbstractItemView::DropOnly</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="coreModsButtonBox"> + <item> + <widget class="QPushButton" name="addCoreBtn"> + <property name="text"> + <string>&Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="rmCoreBtn"> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <spacer name="coreModsButtonSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="viewCoreBtn"> + <property name="text"> + <string>&View Folder</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="MCModInfoFrame" name="coreMIFrame"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="modTab"> + <attribute name="title"> + <string>Loader Mods</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="ModListView" name="loaderModTreeView"> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="dragDropMode"> + <enum>QAbstractItemView::DropOnly</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="mlModsButtonBox"> + <item> + <widget class="QPushButton" name="addModBtn"> + <property name="text"> + <string>&Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="rmModBtn"> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <spacer name="mlModsButtonSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="viewModBtn"> + <property name="text"> + <string>&View Folder</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="MCModInfoFrame" name="loaderMIFrame"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="texPackTab"> + <property name="acceptDrops"> + <bool>false</bool> + </property> + <attribute name="title"> + <string>Texture Packs</string> + </attribute> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="ModListView" name="texPackTreeView"> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="dragDropMode"> + <enum>QAbstractItemView::DropOnly</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="texturePacksButtonBox"> + <item> + <widget class="QPushButton" name="addTexPackBtn"> + <property name="text"> + <string>&Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="rmTexPackBtn"> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <spacer name="texturePacksButtonSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="viewTexPackBtn"> + <property name="text"> + <string>&View Folder</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ModListView</class> + <extends>QTreeView</extends> + <header>gui/widgets/ModListView.h</header> + </customwidget> + <customwidget> + <class>MCModInfoFrame</class> + <extends>QFrame</extends> + <header>gui/widgets/MCModInfoFrame.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/gui/dialogs/LoginDialog.cpp b/gui/dialogs/LoginDialog.cpp new file mode 100644 index 00000000..19c6437d --- /dev/null +++ b/gui/dialogs/LoginDialog.cpp @@ -0,0 +1,252 @@ +/* Copyright 2013 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 "LoginDialog.h" +#include "ui_LoginDialog.h" +#include "keyring.h" +#include "gui/Platform.h" +#include "MultiMC.h" + +#include <QFile> +#include <QJsonObject> +#include <QJsonArray> +#include <QJsonParseError> +#include "logic/net/HttpMetaCache.h" +#include "logger/QsLog.h" + +LoginDialog::LoginDialog(QWidget *parent, const QString &loginErrMsg) + : QDialog(parent), ui(new Ui::LoginDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + + //: Use offline mode one time + offlineButton = new QPushButton(tr("Offline Once")); + + ui->loginButtonBox->addButton(offlineButton, QDialogButtonBox::ActionRole); + + blockToggles = false; + isOnline_ = true; + onlineForced = false; + + //: The username during login (placeholder) + ui->usernameTextBox->lineEdit()->setPlaceholderText(tr("Name")); + + connect(ui->usernameTextBox, SIGNAL(currentTextChanged(QString)), this, + SLOT(userTextChanged(QString))); + connect(ui->forgetButton, SIGNAL(clicked(bool)), this, SLOT(forgetCurrentUser())); + connect(offlineButton, SIGNAL(clicked(bool)), this, SLOT(launchOffline())); + + if (loginErrMsg.isEmpty()) + ui->loginErrorLabel->setVisible(false); + else + { + ui->loginErrorLabel->setVisible(true); + ui->loginErrorLabel->setText( + QString("<span style=\" color:#ff0000;\">%1</span>").arg(loginErrMsg)); + } + + ui->lblFace->setVisible(false); + + resize(minimumSizeHint()); + layout()->setSizeConstraint(QLayout::SetFixedSize); + Keyring *k = Keyring::instance(); + QStringList accounts = k->getStoredAccounts("minecraft"); + ui->usernameTextBox->addItems(accounts); + + // TODO: restore last selected account here, if applicable + + int index = ui->usernameTextBox->currentIndex(); + if (index != -1) + { + ui->passwordTextBox->setFocus(Qt::OtherFocusReason); + } + + connect(ui->rememberUsernameCheckbox, SIGNAL(toggled(bool)), SLOT(usernameToggled(bool))); + connect(ui->rememberPasswordCheckbox, SIGNAL(toggled(bool)), SLOT(passwordToggled(bool))); +} + +LoginDialog::~LoginDialog() +{ + delete offlineButton; + delete ui; +} + +QString LoginDialog::getUsername() const +{ + return ui->usernameTextBox->currentText(); +} + +QString LoginDialog::getPassword() const +{ + return ui->passwordTextBox->text(); +} + +void LoginDialog::forgetCurrentUser() +{ + Keyring *k = Keyring::instance(); + QString acct = ui->usernameTextBox->currentText(); + k->removeStoredAccount("minecraft", acct); + ui->passwordTextBox->clear(); + int index = ui->usernameTextBox->findText(acct); + if (index != -1) + ui->usernameTextBox->removeItem(index); + if (!ui->usernameTextBox->count()) + { + blockToggles = true; + ui->rememberUsernameCheckbox->setChecked(false); + ui->rememberPasswordCheckbox->setChecked(false); + blockToggles = false; + } +} + +void LoginDialog::passwordToggled(bool state) +{ + // if toggled off + if (blockToggles) + return; + blockToggles = true; + if (!state) + { + QLOG_DEBUG() << "password disabled"; + } + else + { + if (!ui->rememberUsernameCheckbox->isChecked()) + { + ui->rememberUsernameCheckbox->setChecked(true); + } + QLOG_DEBUG() << "password enabled"; + } + blockToggles = false; +} + +void LoginDialog::usernameToggled(bool state) +{ + // if toggled off + if (blockToggles) + return; + blockToggles = true; + if (!state) + { + if (ui->rememberPasswordCheckbox->isChecked()) + { + ui->rememberPasswordCheckbox->setChecked(false); + } + QLOG_DEBUG() << "username disabled"; + } + else + { + QLOG_DEBUG() << "username enabled"; + } + blockToggles = false; +} + +void LoginDialog::userTextChanged(const QString &user) +{ + blockToggles = true; + Keyring *k = Keyring::instance(); + QStringList sl = k->getStoredAccounts("minecraft"); + bool gotFace = false; + + if (sl.contains(user)) + { + ui->rememberUsernameCheckbox->setChecked(true); + QString passwd = k->getPassword("minecraft", user); + ui->rememberPasswordCheckbox->setChecked(!passwd.isEmpty()); + ui->passwordTextBox->setText(passwd); + + QByteArray data; + { + auto filename = + MMC->metacache()->resolveEntry("skins", "skins.json")->getFullPath(); + QFile listFile(filename); + if (!listFile.open(QIODevice::ReadOnly)) + return; + data = listFile.readAll(); + } + + QJsonParseError jsonError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); + QJsonObject root = jsonDoc.object(); + QJsonObject mappings = root.value("mappings").toObject(); + + if (!mappings[user].isUndefined()) + { + QJsonArray usernames = mappings.value(user).toArray(); + if (!usernames.isEmpty()) + { + QString mapped_username = usernames[0].toString(); + + if (!mapped_username.isEmpty()) + { + QFile fskin(MMC->metacache() + ->resolveEntry("skins", mapped_username + ".png") + ->getFullPath()); + if (fskin.exists()) + { + QPixmap skin(MMC->metacache() + ->resolveEntry("skins", mapped_username + ".png") + ->getFullPath()); + QPixmap face = + skin.copy(8, 8, 8, 8).scaled(48, 48, Qt::KeepAspectRatio); + + ui->lblFace->setPixmap(face); + gotFace = true; + } + } + } + } + } + + ui->lblFace->setVisible(gotFace); + blockToggles = false; +} + +void LoginDialog::accept() +{ + bool saveName = ui->rememberUsernameCheckbox->isChecked(); + bool savePass = ui->rememberPasswordCheckbox->isChecked(); + Keyring *k = Keyring::instance(); + if (saveName) + { + if (savePass) + { + k->storePassword("minecraft", getUsername(), getPassword()); + } + else + { + k->storePassword("minecraft", getUsername(), QString()); + } + } + else + { + QString acct = ui->usernameTextBox->currentText(); + k->removeStoredAccount("minecraft", acct); + } + QDialog::accept(); +} + +void LoginDialog::launchOffline() +{ + isOnline_ = false; + QDialog::accept(); +} + +void LoginDialog::forceOnline() +{ + onlineForced = true; + offlineButton->setEnabled(false); +} diff --git a/gui/dialogs/LoginDialog.h b/gui/dialogs/LoginDialog.h new file mode 100644 index 00000000..73a92aab --- /dev/null +++ b/gui/dialogs/LoginDialog.h @@ -0,0 +1,61 @@ +/* Copyright 2013 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 <QDialog> +#include <QPushButton> + +namespace Ui +{ +class LoginDialog; +} + +class LoginDialog : public QDialog +{ + Q_OBJECT + +public: + explicit LoginDialog(QWidget *parent = 0, const QString &loginErrMsg = ""); + ~LoginDialog(); + + QString getUsername() const; + QString getPassword() const; + + inline bool isOnline() + { + return isOnline_; + } + + void forceOnline(); + +public +slots: + virtual void accept(); + virtual void userTextChanged(const QString &user); + virtual void forgetCurrentUser(); +private +slots: + void usernameToggled(bool); + void passwordToggled(bool); + void launchOffline(); + +private: + Ui::LoginDialog *ui; + bool blockToggles; + QPushButton *offlineButton; + bool isOnline_; + bool onlineForced; +}; diff --git a/gui/dialogs/LoginDialog.ui b/gui/dialogs/LoginDialog.ui new file mode 100644 index 00000000..d15679dd --- /dev/null +++ b/gui/dialogs/LoginDialog.ui @@ -0,0 +1,186 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>LoginDialog</class> + <widget class="QDialog" name="LoginDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>496</width> + <height>168</height> + </rect> + </property> + <property name="windowTitle"> + <string>Login</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="loginErrorLabel"> + <property name="text"> + <string><span style=" color:#ff0000;">Error</span></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="4" rowspan="2"> + <widget class="QLabel" name="lblFace"> + <property name="minimumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../../multimc.qrc">:/icons/instances/steve</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="usernameTextBox"> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="usernameLabel"> + <property name="text"> + <string>Username:</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="passwordLabel"> + <property name="text"> + <string>Password:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="passwordTextBox"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> + <property name="placeholderText"> + <string>Password</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="checkboxLayout"> + <item> + <widget class="QCheckBox" name="rememberUsernameCheckbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Remember Username?</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="rememberPasswordCheckbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>R&emember Password?</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="forgetButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Forget</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="loginButtonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../multimc.qrc"/> + <include location="../multimc.qrc"/> + </resources> + <connections> + <connection> + <sender>loginButtonBox</sender> + <signal>accepted()</signal> + <receiver>LoginDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>loginButtonBox</sender> + <signal>rejected()</signal> + <receiver>LoginDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/gui/dialogs/LwjglSelectDialog.cpp b/gui/dialogs/LwjglSelectDialog.cpp new file mode 100644 index 00000000..046a4e2e --- /dev/null +++ b/gui/dialogs/LwjglSelectDialog.cpp @@ -0,0 +1,72 @@ +/* Copyright 2013 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 "MultiMC.h" +#include "LwjglSelectDialog.h" +#include "ui_LwjglSelectDialog.h" +#include "gui/Platform.h" + +#include "logic/lists/LwjglVersionList.h" + +LWJGLSelectDialog::LWJGLSelectDialog(QWidget *parent) + : QDialog(parent), ui(new Ui::LWJGLSelectDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + ui->labelStatus->setVisible(false); + auto lwjgllist = MMC->lwjgllist(); + ui->lwjglListView->setModel(lwjgllist.get()); + + connect(lwjgllist.get(), SIGNAL(loadingStateUpdated(bool)), + SLOT(loadingStateUpdated(bool))); + connect(lwjgllist.get(), SIGNAL(loadListFailed(QString)), SLOT(loadingFailed(QString))); + loadingStateUpdated(lwjgllist->isLoading()); +} + +LWJGLSelectDialog::~LWJGLSelectDialog() +{ + delete ui; +} + +QString LWJGLSelectDialog::selectedVersion() const +{ + return MMC->lwjgllist() + ->data(ui->lwjglListView->selectionModel()->currentIndex(), Qt::DisplayRole) + .toString(); +} + +void LWJGLSelectDialog::on_refreshButton_clicked() +{ + if (!MMC->lwjgllist()->isLoading()) + MMC->lwjgllist()->loadList(); +} + +void LWJGLSelectDialog::loadingStateUpdated(bool loading) +{ + setEnabled(!loading); + if (loading) + { + ui->labelStatus->setText(tr("Loading LWJGL version list...")); + ui->labelStatus->setStyleSheet("QLabel { color: black; }"); + } + ui->labelStatus->setVisible(loading); +} + +void LWJGLSelectDialog::loadingFailed(QString error) +{ + ui->labelStatus->setText(error); + ui->labelStatus->setStyleSheet("QLabel { color: red; }"); + ui->labelStatus->setVisible(true); +} diff --git a/gui/dialogs/LwjglSelectDialog.h b/gui/dialogs/LwjglSelectDialog.h new file mode 100644 index 00000000..2724cbe8 --- /dev/null +++ b/gui/dialogs/LwjglSelectDialog.h @@ -0,0 +1,44 @@ +/* Copyright 2013 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 <QDialog> + +namespace Ui +{ +class LWJGLSelectDialog; +} + +class LWJGLSelectDialog : public QDialog +{ + Q_OBJECT + +public: + explicit LWJGLSelectDialog(QWidget *parent = 0); + ~LWJGLSelectDialog(); + + QString selectedVersion() const; + +private +slots: + void on_refreshButton_clicked(); + + void loadingStateUpdated(bool loading); + void loadingFailed(QString error); + +private: + Ui::LWJGLSelectDialog *ui; +}; diff --git a/gui/dialogs/LwjglSelectDialog.ui b/gui/dialogs/LwjglSelectDialog.ui new file mode 100644 index 00000000..c715cc07 --- /dev/null +++ b/gui/dialogs/LwjglSelectDialog.ui @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>LWJGLSelectDialog</class> + <widget class="QDialog" name="LWJGLSelectDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="labelStatus"> + <property name="text"> + <string>Status label...</string> + </property> + </widget> + </item> + <item> + <widget class="QListView" name="lwjglListView"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="refreshButton"> + <property name="text"> + <string>&Refresh</string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>LWJGLSelectDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>LWJGLSelectDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/gui/dialogs/ModEditDialogCommon.cpp b/gui/dialogs/ModEditDialogCommon.cpp new file mode 100644 index 00000000..9a15d92d --- /dev/null +++ b/gui/dialogs/ModEditDialogCommon.cpp @@ -0,0 +1,57 @@ +/* Copyright 2013 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 "ModEditDialogCommon.h" +#include "CustomMessageBox.h" +#include <QDesktopServices> +#include <QMessageBox> +#include <QString> +#include <QUrl> +bool lastfirst(QModelIndexList &list, int &first, int &last) +{ + if (!list.size()) + return false; + first = last = list[0].row(); + for (auto item : list) + { + int row = item.row(); + if (row < first) + first = row; + if (row > last) + last = row; + } + return true; +} + +void showWebsiteForMod(QWidget *parentDlg, Mod &m) +{ + QString url = m.homeurl(); + if (url.size()) + { + // catch the cases where the protocol is missing + if (!url.startsWith("http")) + { + url = "http://" + url; + } + QDesktopServices::openUrl(url); + } + else + { + CustomMessageBox::selectable( + parentDlg, parentDlg->tr("How sad!"), + parentDlg->tr("The mod author didn't provide a website link for this mod."), + QMessageBox::Warning); + } +} diff --git a/gui/dialogs/ModEditDialogCommon.h b/gui/dialogs/ModEditDialogCommon.h new file mode 100644 index 00000000..a226d5a9 --- /dev/null +++ b/gui/dialogs/ModEditDialogCommon.h @@ -0,0 +1,22 @@ +/* Copyright 2013 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 <QAbstractItemModel> +#include <logic/Mod.h> + +bool lastfirst(QModelIndexList &list, int &first, int &last); + +void showWebsiteForMod(QWidget *parentDlg, Mod &m);
\ No newline at end of file diff --git a/gui/dialogs/NewInstanceDialog.cpp b/gui/dialogs/NewInstanceDialog.cpp new file mode 100644 index 00000000..5b2cd086 --- /dev/null +++ b/gui/dialogs/NewInstanceDialog.cpp @@ -0,0 +1,125 @@ +/* Copyright 2013 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 "MultiMC.h" +#include "NewInstanceDialog.h" +#include "ui_NewInstanceDialog.h" + +#include "logic/InstanceFactory.h" +#include "logic/BaseVersion.h" +#include "logic/lists/IconList.h" +#include "logic/lists/MinecraftVersionList.h" +#include "logic/tasks/Task.h" + +#include "gui/Platform.h" +#include "VersionSelectDialog.h" +#include "ProgressDialog.h" +#include "IconPickerDialog.h" + +#include <QLayout> +#include <QPushButton> + +NewInstanceDialog::NewInstanceDialog(QWidget *parent) + : QDialog(parent), ui(new Ui::NewInstanceDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + resize(minimumSizeHint()); + layout()->setSizeConstraint(QLayout::SetFixedSize); + /* + if (!MinecraftVersionList::getMainList().isLoaded()) + { + TaskDialog *taskDlg = new TaskDialog(this); + Task *loadTask = MinecraftVersionList::getMainList().getLoadTask(); + loadTask->setParent(taskDlg); + taskDlg->exec(loadTask); + } + */ + setSelectedVersion(MMC->minecraftlist()->getLatestStable()); + InstIconKey = "infinity"; + ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey)); +} + +NewInstanceDialog::~NewInstanceDialog() +{ + delete ui; +} + +void NewInstanceDialog::updateDialogState() +{ + ui->buttonBox->button(QDialogButtonBox::Ok) + ->setEnabled(!instName().isEmpty() && m_selectedVersion); +} + +void NewInstanceDialog::setSelectedVersion(BaseVersionPtr version) +{ + m_selectedVersion = version; + + if (m_selectedVersion) + { + ui->versionTextBox->setText(version->name()); + } + else + { + ui->versionTextBox->setText(""); + } + + updateDialogState(); +} + +QString NewInstanceDialog::instName() const +{ + return ui->instNameTextBox->text(); +} + +QString NewInstanceDialog::iconKey() const +{ + return InstIconKey; +} + +BaseVersionPtr NewInstanceDialog::selectedVersion() const +{ + return m_selectedVersion; +} + +void NewInstanceDialog::on_btnChangeVersion_clicked() +{ + VersionSelectDialog vselect(MMC->minecraftlist().get(), tr("Change Minecraft version"), + this); + vselect.exec(); + if (vselect.result() == QDialog::Accepted) + { + BaseVersionPtr version = vselect.selectedVersion(); + if (version) + setSelectedVersion(version); + } +} + +void NewInstanceDialog::on_iconButton_clicked() +{ + IconPickerDialog dlg(this); + dlg.exec(InstIconKey); + + if (dlg.result() == QDialog::Accepted) + { + InstIconKey = dlg.selectedIconKey; + ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey)); + } +} + +void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) +{ + updateDialogState(); +} diff --git a/gui/dialogs/NewInstanceDialog.h b/gui/dialogs/NewInstanceDialog.h new file mode 100644 index 00000000..4357c28d --- /dev/null +++ b/gui/dialogs/NewInstanceDialog.h @@ -0,0 +1,55 @@ +/* Copyright 2013 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 <QDialog> +#include "logic/BaseVersion.h" + +namespace Ui +{ +class NewInstanceDialog; +} + +class NewInstanceDialog : public QDialog +{ + Q_OBJECT + +public: + explicit NewInstanceDialog(QWidget *parent = 0); + ~NewInstanceDialog(); + + void updateDialogState(); + + void setSelectedVersion(BaseVersionPtr version); + + void loadVersionList(); + + QString instName() const; + QString iconKey() const; + BaseVersionPtr selectedVersion() const; + +private +slots: + void on_btnChangeVersion_clicked(); + void on_iconButton_clicked(); + void on_instNameTextBox_textChanged(const QString &arg1); + +private: + Ui::NewInstanceDialog *ui; + + BaseVersionPtr m_selectedVersion; + QString InstIconKey; +}; diff --git a/gui/dialogs/NewInstanceDialog.ui b/gui/dialogs/NewInstanceDialog.ui new file mode 100644 index 00000000..b4b8723e --- /dev/null +++ b/gui/dialogs/NewInstanceDialog.ui @@ -0,0 +1,179 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>NewInstanceDialog</class> + <widget class="QDialog" name="NewInstanceDialog"> + <property name="windowModality"> + <enum>Qt::ApplicationModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>220</width> + <height>234</height> + </rect> + </property> + <property name="windowTitle"> + <string>New Instance</string> + </property> + <property name="windowIcon"> + <iconset resource="../../multimc.qrc"> + <normaloff>:/icons/toolbar/new</normaloff>:/icons/toolbar/new</iconset> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="iconBtnLayout"> + <item> + <spacer name="iconBtnLeftSpacer"> + <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="QToolButton" name="iconButton"> + <property name="icon"> + <iconset resource="../../multimc.qrc"> + <normaloff>:/icons/instances/infinity</normaloff>:/icons/instances/infinity</iconset> + </property> + <property name="iconSize"> + <size> + <width>80</width> + <height>80</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="iconBtnRightSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QLineEdit" name="instNameTextBox"> + <property name="placeholderText"> + <string>Name</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="labelVersion"> + <property name="text"> + <string>Version:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="versionTextBox"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="btnChangeVersion"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../multimc.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>NewInstanceDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>NewInstanceDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/gui/dialogs/OneSixModEditDialog.cpp b/gui/dialogs/OneSixModEditDialog.cpp new file mode 100644 index 00000000..dea1b86b --- /dev/null +++ b/gui/dialogs/OneSixModEditDialog.cpp @@ -0,0 +1,322 @@ +/* Copyright 2013 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 "MultiMC.h" + +#include <pathutils.h> +#include <QFileDialog> +#include <QMessageBox> +#include <QDebug> +#include <QEvent> +#include <QKeyEvent> +#include <QDesktopServices> + +#include "OneSixModEditDialog.h" +#include "ModEditDialogCommon.h" +#include "ui_OneSixModEditDialog.h" + +#include "gui/Platform.h" +#include "gui/dialogs/CustomMessageBox.h" +#include "gui/dialogs/VersionSelectDialog.h" + +#include "gui/dialogs/ProgressDialog.h" + +#include "logic/ModList.h" +#include "logic/OneSixVersion.h" +#include "logic/EnabledItemFilter.h" +#include "logic/lists/ForgeVersionList.h" +#include "logic/ForgeInstaller.h" + +OneSixModEditDialog::OneSixModEditDialog(OneSixInstance *inst, QWidget *parent) + : m_inst(inst), QDialog(parent), ui(new Ui::OneSixModEditDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + // libraries! + + m_version = m_inst->getFullVersion(); + if (m_version) + { + main_model = new EnabledItemFilter(this); + main_model->setActive(true); + main_model->setSourceModel(m_version.get()); + ui->libraryTreeView->setModel(main_model); + ui->libraryTreeView->installEventFilter(this); + ui->mainClassEdit->setText(m_version->mainClass); + updateVersionControls(); + } + else + { + disableVersionControls(); + } + // Loader mods + { + ensureFolderPathExists(m_inst->loaderModsDir()); + m_mods = m_inst->loaderModList(); + ui->loaderModTreeView->setModel(m_mods.get()); + ui->loaderModTreeView->installEventFilter(this); + m_mods->startWatching(); + auto smodel = ui->loaderModTreeView->selectionModel(); + connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + SLOT(loaderCurrent(QModelIndex, QModelIndex))); + } + // resource packs + { + ensureFolderPathExists(m_inst->resourcePacksDir()); + m_resourcepacks = m_inst->resourcePackList(); + ui->resPackTreeView->setModel(m_resourcepacks.get()); + ui->resPackTreeView->installEventFilter(this); + m_resourcepacks->startWatching(); + } +} + +OneSixModEditDialog::~OneSixModEditDialog() +{ + m_mods->stopWatching(); + m_resourcepacks->stopWatching(); + delete ui; +} + +void OneSixModEditDialog::updateVersionControls() +{ + bool customVersion = m_inst->versionIsCustom(); + ui->customizeBtn->setEnabled(!customVersion); + ui->revertBtn->setEnabled(customVersion); + ui->forgeBtn->setEnabled(true); +} + +void OneSixModEditDialog::disableVersionControls() +{ + ui->customizeBtn->setEnabled(false); + ui->revertBtn->setEnabled(false); + ui->forgeBtn->setEnabled(false); +} + +void OneSixModEditDialog::on_customizeBtn_clicked() +{ + if (m_inst->customizeVersion()) + { + m_version = m_inst->getFullVersion(); + main_model->setSourceModel(m_version.get()); + updateVersionControls(); + } +} + +void OneSixModEditDialog::on_revertBtn_clicked() +{ + auto response = CustomMessageBox::selectable( + this, tr("Revert?"), tr("Do you want to revert the " + "version of this instance to its original configuration?"), + QMessageBox::Question, QMessageBox::Yes | QMessageBox::No)->exec(); + if (response == QMessageBox::Yes) + { + if (m_inst->revertCustomVersion()) + { + m_version = m_inst->getFullVersion(); + main_model->setSourceModel(m_version.get()); + updateVersionControls(); + } + } +} + +void OneSixModEditDialog::on_forgeBtn_clicked() +{ + VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this); + vselect.setFilter(1, m_inst->currentVersionId()); + if (vselect.exec() && vselect.selectedVersion()) + { + if (m_inst->versionIsCustom()) + { + auto reply = QMessageBox::question( + this, tr("Revert?"), + tr("This will revert any " + "changes you did to the version up to this point. Is that " + "OK?"), + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::Yes) + { + m_inst->revertCustomVersion(); + m_inst->customizeVersion(); + { + m_version = m_inst->getFullVersion(); + main_model->setSourceModel(m_version.get()); + updateVersionControls(); + } + } + else + return; + } + else + { + m_inst->customizeVersion(); + m_version = m_inst->getFullVersion(); + main_model->setSourceModel(m_version.get()); + updateVersionControls(); + } + ForgeVersionPtr forgeVersion = + std::dynamic_pointer_cast<ForgeVersion>(vselect.selectedVersion()); + if (!forgeVersion) + return; + auto entry = MMC->metacache()->resolveEntry("minecraftforge", forgeVersion->filename); + if (entry->stale) + { + NetJob *fjob = new NetJob("Forge download"); + fjob->addNetAction(CacheDownload::make(forgeVersion->installer_url, entry)); + ProgressDialog dlg(this); + dlg.exec(fjob); + if (dlg.result() == QDialog::Accepted) + { + // install + QString forgePath = entry->getFullPath(); + ForgeInstaller forge(forgePath, forgeVersion->universal_url); + if (!forge.apply(m_version)) + { + // failure notice + } + } + else + { + // failed to download forge :/ + } + } + else + { + // install + QString forgePath = entry->getFullPath(); + ForgeInstaller forge(forgePath, forgeVersion->universal_url); + if (!forge.apply(m_version)) + { + // failure notice + } + } + } +} + +bool OneSixModEditDialog::loaderListFilter(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 QDialog::eventFilter(ui->loaderModTreeView, keyEvent); +} + +bool OneSixModEditDialog::resourcePackListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Delete: + on_rmResPackBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addResPackBtn_clicked(); + return true; + default: + break; + } + return QDialog::eventFilter(ui->resPackTreeView, keyEvent); +} + +bool OneSixModEditDialog::eventFilter(QObject *obj, QEvent *ev) +{ + if (ev->type() != QEvent::KeyPress) + { + return QDialog::eventFilter(obj, ev); + } + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev); + if (obj == ui->loaderModTreeView) + return loaderListFilter(keyEvent); + if (obj == ui->resPackTreeView) + return resourcePackListFilter(keyEvent); + return QDialog::eventFilter(obj, ev); +} + +void OneSixModEditDialog::on_buttonBox_rejected() +{ + close(); +} + +void OneSixModEditDialog::on_addModBtn_clicked() +{ + QStringList fileNames = QFileDialog::getOpenFileNames( + this, QApplication::translate("LegacyModEditDialog", "Select Loader Mods")); + for (auto filename : fileNames) + { + m_mods->stopWatching(); + m_mods->installMod(QFileInfo(filename)); + m_mods->startWatching(); + } +} +void OneSixModEditDialog::on_rmModBtn_clicked() +{ + int first, last; + auto list = ui->loaderModTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_mods->stopWatching(); + m_mods->deleteMods(first, last); + m_mods->startWatching(); +} +void OneSixModEditDialog::on_viewModBtn_clicked() +{ + openDirInDefaultProgram(m_inst->loaderModsDir(), true); +} + +void OneSixModEditDialog::on_addResPackBtn_clicked() +{ + QStringList fileNames = QFileDialog::getOpenFileNames( + this, QApplication::translate("LegacyModEditDialog", "Select Resource Packs")); + for (auto filename : fileNames) + { + m_resourcepacks->stopWatching(); + m_resourcepacks->installMod(QFileInfo(filename)); + m_resourcepacks->startWatching(); + } +} +void OneSixModEditDialog::on_rmResPackBtn_clicked() +{ + int first, last; + auto list = ui->resPackTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_resourcepacks->stopWatching(); + m_resourcepacks->deleteMods(first, last); + m_resourcepacks->startWatching(); +} +void OneSixModEditDialog::on_viewResPackBtn_clicked() +{ + openDirInDefaultProgram(m_inst->resourcePacksDir(), true); +} + +void OneSixModEditDialog::loaderCurrent(QModelIndex current, 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/gui/dialogs/OneSixModEditDialog.h b/gui/dialogs/OneSixModEditDialog.h new file mode 100644 index 00000000..5376e526 --- /dev/null +++ b/gui/dialogs/OneSixModEditDialog.h @@ -0,0 +1,67 @@ +/* Copyright 2013 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 <QDialog> + +#include <logic/OneSixInstance.h> + +class EnabledItemFilter; +namespace Ui +{ +class OneSixModEditDialog; +} + +class OneSixModEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit OneSixModEditDialog(OneSixInstance *inst, QWidget *parent = 0); + virtual ~OneSixModEditDialog(); + +private +slots: + void on_addModBtn_clicked(); + void on_rmModBtn_clicked(); + void on_viewModBtn_clicked(); + + void on_addResPackBtn_clicked(); + void on_rmResPackBtn_clicked(); + void on_viewResPackBtn_clicked(); + // Questionable: SettingsDialog doesn't need this for some reason? + void on_buttonBox_rejected(); + void on_forgeBtn_clicked(); + void on_customizeBtn_clicked(); + void on_revertBtn_clicked(); + void updateVersionControls(); + void disableVersionControls(); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + bool loaderListFilter(QKeyEvent *ev); + bool resourcePackListFilter(QKeyEvent *ev); + +private: + Ui::OneSixModEditDialog *ui; + std::shared_ptr<OneSixVersion> m_version; + std::shared_ptr<ModList> m_mods; + std::shared_ptr<ModList> m_resourcepacks; + EnabledItemFilter *main_model; + OneSixInstance *m_inst; +public +slots: + void loaderCurrent(QModelIndex current, QModelIndex previous); +}; diff --git a/gui/dialogs/OneSixModEditDialog.ui b/gui/dialogs/OneSixModEditDialog.ui new file mode 100644 index 00000000..8f301438 --- /dev/null +++ b/gui/dialogs/OneSixModEditDialog.ui @@ -0,0 +1,319 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>OneSixModEditDialog</class> + <widget class="QDialog" name="OneSixModEditDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>555</width> + <height>463</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QTabWidget" name="tabWidget"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="currentIndex"> + <number>1</number> + </property> + <widget class="QWidget" name="libTab"> + <attribute name="title"> + <string>Version</string> + </attribute> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_10"> + <item> + <widget class="ModListView" name="libraryTreeView"> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOn</enum> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Main Class:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="mainClassEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QPushButton" name="forgeBtn"> + <property name="toolTip"> + <string>Replace any current custom version with Minecraft Forge</string> + </property> + <property name="text"> + <string>Install Forge</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="customizeBtn"> + <property name="toolTip"> + <string>Create an customized copy of the base version</string> + </property> + <property name="text"> + <string>Customize</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="revertBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Revert to original base version</string> + </property> + <property name="text"> + <string>Revert</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="addLibraryBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Add new libraries</string> + </property> + <property name="text"> + <string>&Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="removeLibraryBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Remove selected libraries</string> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_7"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWidget" name="modTab"> + <attribute name="title"> + <string>Loader Mods</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="ModListView" name="loaderModTreeView"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="dragDropMode"> + <enum>QAbstractItemView::DropOnly</enum> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QPushButton" name="addModBtn"> + <property name="text"> + <string>&Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="rmModBtn"> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="viewModBtn"> + <property name="text"> + <string>&View Folder</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="MCModInfoFrame" name="frame"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="resPackTab"> + <attribute name="title"> + <string>Resource Packs</string> + </attribute> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="ModListView" name="resPackTreeView"> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="dragDropMode"> + <enum>QAbstractItemView::DropOnly</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QPushButton" name="addResPackBtn"> + <property name="text"> + <string>&Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="rmResPackBtn"> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="viewResPackBtn"> + <property name="text"> + <string>&View Folder</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + <item row="1" column="0"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ModListView</class> + <extends>QTreeView</extends> + <header>gui/widgets/ModListView.h</header> + </customwidget> + <customwidget> + <class>MCModInfoFrame</class> + <extends>QFrame</extends> + <header>gui/widgets/MCModInfoFrame.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/gui/dialogs/ProgressDialog.cpp b/gui/dialogs/ProgressDialog.cpp new file mode 100644 index 00000000..ca433dab --- /dev/null +++ b/gui/dialogs/ProgressDialog.cpp @@ -0,0 +1,107 @@ +/* Copyright 2013 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 "ProgressDialog.h" +#include "ui_ProgressDialog.h" + +#include <QKeyEvent> + +#include "logic/tasks/Task.h" +#include "gui/Platform.h" + +ProgressDialog::ProgressDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ProgressDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + updateSize(); + + changeProgress(0, 100); +} + +ProgressDialog::~ProgressDialog() +{ + delete ui; +} + +void ProgressDialog::updateSize() +{ + resize(QSize(480, minimumSizeHint().height())); +} + +int ProgressDialog::exec(ProgressProvider *task) +{ + this->task = task; + + // Connect signals. + connect(task, SIGNAL(started()), SLOT(onTaskStarted())); + connect(task, SIGNAL(failed(QString)), SLOT(onTaskFailed(QString))); + connect(task, SIGNAL(succeeded()), SLOT(onTaskSucceeded())); + connect(task, SIGNAL(status(QString)), SLOT(changeStatus(const QString &))); + connect(task, SIGNAL(progress(qint64, qint64)), SLOT(changeProgress(qint64, qint64))); + + // this makes sure that the task is started after the dialog is created + QMetaObject::invokeMethod(task, "start", Qt::QueuedConnection); + return QDialog::exec(); +} + +ProgressProvider *ProgressDialog::getTask() +{ + return task; +} + +void ProgressDialog::onTaskStarted() +{ +} + +void ProgressDialog::onTaskFailed(QString failure) +{ + reject(); +} + +void ProgressDialog::onTaskSucceeded() +{ + accept(); +} + +void ProgressDialog::changeStatus(const QString &status) +{ + ui->statusLabel->setText(status); + updateSize(); +} + +void ProgressDialog::changeProgress(qint64 current, qint64 total) +{ + ui->taskProgressBar->setMaximum(total); + ui->taskProgressBar->setValue(current); +} + +void ProgressDialog::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Escape) + return; + QDialog::keyPressEvent(e); +} + +void ProgressDialog::closeEvent(QCloseEvent *e) +{ + if (task && task->isRunning()) + { + e->ignore(); + } + else + { + QDialog::closeEvent(e); + } +} diff --git a/gui/dialogs/ProgressDialog.h b/gui/dialogs/ProgressDialog.h new file mode 100644 index 00000000..0029d3ec --- /dev/null +++ b/gui/dialogs/ProgressDialog.h @@ -0,0 +1,60 @@ +/* Copyright 2013 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 <QDialog> + +class ProgressProvider; + +namespace Ui +{ +class ProgressDialog; +} + +class ProgressDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ProgressDialog(QWidget *parent = 0); + ~ProgressDialog(); + + void updateSize(); + + int exec(ProgressProvider *task); + + ProgressProvider *getTask(); + +public +slots: + void onTaskStarted(); + void onTaskFailed(QString failure); + void onTaskSucceeded(); + + void changeStatus(const QString &status); + void changeProgress(qint64 current, qint64 total); + +signals: + +protected: + virtual void keyPressEvent(QKeyEvent *e); + virtual void closeEvent(QCloseEvent *e); + +private: + Ui::ProgressDialog *ui; + + ProgressProvider *task; +}; diff --git a/gui/dialogs/ProgressDialog.ui b/gui/dialogs/ProgressDialog.ui new file mode 100644 index 00000000..a56d2a92 --- /dev/null +++ b/gui/dialogs/ProgressDialog.ui @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ProgressDialog</class> + <widget class="QDialog" name="ProgressDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>68</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>600</width> + <height>16777215</height> + </size> + </property> + <property name="windowTitle"> + <string>Please wait...</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="statusLabel"> + <property name="text"> + <string>Task Status...</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QProgressBar" name="taskProgressBar"> + <property name="value"> + <number>24</number> + </property> + <property name="textVisible"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/gui/dialogs/SettingsDialog.cpp b/gui/dialogs/SettingsDialog.cpp new file mode 100644 index 00000000..e4f22d83 --- /dev/null +++ b/gui/dialogs/SettingsDialog.cpp @@ -0,0 +1,260 @@ +/* Copyright 2013 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 "MultiMC.h" + +#include "gui/dialogs/SettingsDialog.h" +#include "ui_SettingsDialog.h" + +#include "gui/Platform.h" +#include "gui/dialogs/VersionSelectDialog.h" +#include "gui/dialogs/CustomMessageBox.h" + +#include "logic/JavaUtils.h" +#include "logic/NagUtils.h" +#include "logic/lists/JavaVersionList.h" + +#include <settingsobject.h> +#include <pathutils.h> +#include <QFileDialog> +#include <QMessageBox> +#include <QDir> + +SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SettingsDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name); + ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch); + + loadSettings(MMC->settings().get()); + updateCheckboxStuff(); +} + +SettingsDialog::~SettingsDialog() +{ + delete ui; +} +void SettingsDialog::showEvent(QShowEvent *ev) +{ + QDialog::showEvent(ev); + adjustSize(); +} + +void SettingsDialog::updateCheckboxStuff() +{ + ui->windowWidthSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked()); + ui->windowHeightSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked()); +} + +void SettingsDialog::on_instDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Directory"), + ui->instDirTextBox->text()); + QString cooked_dir = NormalizePath(raw_dir); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) + { + ui->instDirTextBox->setText(cooked_dir); + } +} + +void SettingsDialog::on_modsDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Directory"), + ui->modsDirTextBox->text()); + QString cooked_dir = NormalizePath(raw_dir); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) + { + ui->modsDirTextBox->setText(cooked_dir); + } +} + +void SettingsDialog::on_lwjglDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("LWJGL Directory"), + ui->lwjglDirTextBox->text()); + QString cooked_dir = NormalizePath(raw_dir); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) + { + ui->lwjglDirTextBox->setText(cooked_dir); + } +} + +void SettingsDialog::on_compatModeCheckBox_clicked(bool checked) +{ + Q_UNUSED(checked); + updateCheckboxStuff(); +} + +void SettingsDialog::on_maximizedCheckBox_clicked(bool checked) +{ + Q_UNUSED(checked); + updateCheckboxStuff(); +} + +void SettingsDialog::on_buttonBox_accepted() +{ + applySettings(MMC->settings().get()); +} + +void SettingsDialog::applySettings(SettingsObject *s) +{ + // Special cases + + // Warn about dev builds. + if (!ui->devBuildsCheckBox->isChecked()) + { + s->set("UseDevBuilds", false); + } + else if (!s->get("UseDevBuilds").toBool()) + { + auto response = CustomMessageBox::selectable( + this, tr("Development builds"), + tr("Development builds contain experimental features " + "and may be unstable. Are you sure you want to enable them?"), + QMessageBox::Question, QMessageBox::Yes | QMessageBox::No)->exec(); + if (response == QMessageBox::Yes) + { + s->set("UseDevBuilds", true); + } + } + + // Updates + s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked()); + + // Folders + // TODO: Offer to move instances to new instance folder. + s->set("InstanceDir", ui->instDirTextBox->text()); + s->set("CentralModsDir", ui->modsDirTextBox->text()); + s->set("LWJGLDir", ui->lwjglDirTextBox->text()); + + // Console + s->set("ShowConsole", ui->showConsoleCheck->isChecked()); + s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); + + // Window Size + s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); + s->set("MinecraftWinWidth", ui->windowWidthSpinBox->value()); + s->set("MinecraftWinHeight", ui->windowHeightSpinBox->value()); + + // Auto Login + s->set("AutoLogin", ui->autoLoginCheckBox->isChecked()); + + // Memory + s->set("MinMemAlloc", ui->minMemSpinBox->value()); + s->set("MaxMemAlloc", ui->maxMemSpinBox->value()); + s->set("PermGen", ui->permGenSpinBox->value()); + + // Java Settings + s->set("JavaPath", ui->javaPathTextBox->text()); + s->set("JvmArgs", ui->jvmArgsTextBox->text()); + NagUtils::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget()); + + // Custom Commands + s->set("PreLaunchCommand", ui->preLaunchCmdTextBox->text()); + s->set("PostExitCommand", ui->postExitCmdTextBox->text()); + + auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId(); + switch (sortMode) + { + case Sort_LastLaunch: + s->set("InstSortMode", "LastLaunch"); + break; + case Sort_Name: + default: + s->set("InstSortMode", "Name"); + break; + } + + s->set("PostExitCommand", ui->postExitCmdTextBox->text()); +} + +void SettingsDialog::loadSettings(SettingsObject *s) +{ + // Updates + ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool()); + ui->devBuildsCheckBox->setChecked(s->get("UseDevBuilds").toBool()); + + // Folders + ui->instDirTextBox->setText(s->get("InstanceDir").toString()); + ui->modsDirTextBox->setText(s->get("CentralModsDir").toString()); + ui->lwjglDirTextBox->setText(s->get("LWJGLDir").toString()); + + // Console + ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); + ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool()); + + // Window Size + ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool()); + ui->windowWidthSpinBox->setValue(s->get("MinecraftWinWidth").toInt()); + ui->windowHeightSpinBox->setValue(s->get("MinecraftWinHeight").toInt()); + + // Auto Login + ui->autoLoginCheckBox->setChecked(s->get("AutoLogin").toBool()); + + // Memory + ui->minMemSpinBox->setValue(s->get("MinMemAlloc").toInt()); + ui->maxMemSpinBox->setValue(s->get("MaxMemAlloc").toInt()); + ui->permGenSpinBox->setValue(s->get("PermGen").toInt()); + + QString sortMode = s->get("InstSortMode").toString(); + + if (sortMode == "LastLaunch") + { + ui->sortLastLaunchedBtn->setChecked(true); + } + else + { + ui->sortByNameBtn->setChecked(true); + } + + // Java Settings + ui->javaPathTextBox->setText(s->get("JavaPath").toString()); + ui->jvmArgsTextBox->setText(s->get("JvmArgs").toString()); + + // Custom Commands + ui->preLaunchCmdTextBox->setText(s->get("PreLaunchCommand").toString()); + ui->postExitCmdTextBox->setText(s->get("PostExitCommand").toString()); +} + +void SettingsDialog::on_pushButton_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<JavaVersion>(vselect.selectedVersion()); + ui->javaPathTextBox->setText(java->path); + } +} + +void SettingsDialog::on_btnBrowse_clicked() +{ + QString dir = QFileDialog::getOpenFileName(this, tr("Find Java executable")); + if (!dir.isNull()) + { + ui->javaPathTextBox->setText(dir); + } +} diff --git a/gui/dialogs/SettingsDialog.h b/gui/dialogs/SettingsDialog.h new file mode 100644 index 00000000..e24047c3 --- /dev/null +++ b/gui/dialogs/SettingsDialog.h @@ -0,0 +1,63 @@ +/* Copyright 2013 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 <QDialog> + +class SettingsObject; + +namespace Ui +{ +class SettingsDialog; +} + +class SettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SettingsDialog(QWidget *parent = 0); + ~SettingsDialog(); + + void updateCheckboxStuff(); + + void applySettings(SettingsObject *s); + void loadSettings(SettingsObject *s); + +protected: + virtual void showEvent(QShowEvent *); + +private +slots: + void on_instDirBrowseBtn_clicked(); + + void on_modsDirBrowseBtn_clicked(); + + void on_lwjglDirBrowseBtn_clicked(); + + void on_compatModeCheckBox_clicked(bool checked); + + void on_maximizedCheckBox_clicked(bool checked); + + void on_buttonBox_accepted(); + + void on_pushButton_clicked(); + + void on_btnBrowse_clicked(); + +private: + Ui::SettingsDialog *ui; +}; diff --git a/gui/dialogs/SettingsDialog.ui b/gui/dialogs/SettingsDialog.ui new file mode 100644 index 00000000..6da9420e --- /dev/null +++ b/gui/dialogs/SettingsDialog.ui @@ -0,0 +1,569 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SettingsDialog</class> + <widget class="QDialog" name="SettingsDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>502</width> + <height>599</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>Settings</string> + </property> + <property name="windowIcon"> + <iconset resource="../../multimc.qrc"> + <normaloff>:/icons/toolbar/settings</normaloff>:/icons/toolbar/settings</iconset> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="mainLayout"> + <item> + <widget class="QTabWidget" name="settingsTabs"> + <property name="tabShape"> + <enum>QTabWidget::Rounded</enum> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="generalTab"> + <attribute name="title"> + <string>General</string> + </attribute> + <layout class="QVBoxLayout" name="generalTabLayout"> + <item> + <widget class="QGroupBox" name="sortingModeBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Sorting Mode</string> + </property> + <layout class="QHBoxLayout" name="sortingModeBoxLayout"> + <item> + <widget class="QRadioButton" name="sortLastLaunchedBtn"> + <property name="text"> + <string>By last launched</string> + </property> + <attribute name="buttonGroup"> + <string notr="true">sortingModeGroup</string> + </attribute> + </widget> + </item> + <item> + <widget class="QRadioButton" name="sortByNameBtn"> + <property name="text"> + <string>By name</string> + </property> + <attribute name="buttonGroup"> + <string notr="true">sortingModeGroup</string> + </attribute> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="updateSettingsBox"> + <property name="title"> + <string>Update Settings</string> + </property> + <layout class="QVBoxLayout" name="updateSettingsBoxLayout"> + <item> + <widget class="QCheckBox" name="devBuildsCheckBox"> + <property name="text"> + <string>Use development builds?</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="autoUpdateCheckBox"> + <property name="text"> + <string>Check for updates when MultiMC starts?</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="foldersBox"> + <property name="title"> + <string>Folders</string> + </property> + <layout class="QGridLayout" name="foldersBoxLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="labelInstDir"> + <property name="text"> + <string>Instances:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="instDirTextBox"/> + </item> + <item row="0" column="2"> + <widget class="QToolButton" name="instDirBrowseBtn"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelModsDir"> + <property name="text"> + <string>Mods:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="modsDirTextBox"/> + </item> + <item row="1" column="2"> + <widget class="QToolButton" name="modsDirBrowseBtn"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelLWJGLDir"> + <property name="text"> + <string>LWJGL:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="lwjglDirTextBox"/> + </item> + <item row="2" column="2"> + <widget class="QToolButton" name="lwjglDirBrowseBtn"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="generalTabSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="minecraftTab"> + <attribute name="title"> + <string>Minecraft</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QGroupBox" name="windowSizeGroupBox"> + <property name="title"> + <string>Window Size</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QCheckBox" name="maximizedCheckBox"> + <property name="text"> + <string>Start Minecraft maximized?</string> + </property> + </widget> + </item> + <item> + <layout class="QGridLayout" name="gridLayoutWindowSize"> + <item row="1" column="0"> + <widget class="QLabel" name="labelWindowHeight"> + <property name="text"> + <string>Window height:</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelWindowWidth"> + <property name="text"> + <string>Window width:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="windowWidthSpinBox"> + <property name="minimum"> + <number>854</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + <property name="value"> + <number>854</number> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="windowHeightSpinBox"> + <property name="minimum"> + <number>480</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + <property name="value"> + <number>480</number> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="consoleSettingsBox"> + <property name="title"> + <string>Console Settings</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QCheckBox" name="showConsoleCheck"> + <property name="text"> + <string>Show console while the game is running?</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="autoCloseConsoleCheck"> + <property name="text"> + <string>Automatically close console when the game quits?</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QCheckBox" name="autoLoginCheckBox"> + <property name="text"> + <string>Login automatically when an instance icon is double clicked?</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacerMinecraft"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="javaTab"> + <attribute name="title"> + <string>Java</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QGroupBox" name="memoryGroupBox"> + <property name="title"> + <string>Memory</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="1"> + <widget class="QSpinBox" name="maxMemSpinBox"> + <property name="minimum"> + <number>512</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + <property name="singleStep"> + <number>128</number> + </property> + <property name="value"> + <number>1024</number> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelMinMem"> + <property name="text"> + <string>Minimum memory allocation:</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelMaxMem"> + <property name="text"> + <string>Maximum memory allocation:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="minMemSpinBox"> + <property name="minimum"> + <number>256</number> + </property> + <property name="maximum"> + <number>65536</number> + </property> + <property name="singleStep"> + <number>128</number> + </property> + <property name="value"> + <number>256</number> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelPermGen"> + <property name="text"> + <string>PermGen:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="permGenSpinBox"> + <property name="minimum"> + <number>64</number> + </property> + <property name="maximum"> + <number>999999999</number> + </property> + <property name="singleStep"> + <number>8</number> + </property> + <property name="value"> + <number>64</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="javaSettingsGroupBox"> + <property name="title"> + <string>Java Settings</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="labelJavaPath"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Java path:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelJVMArgs"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>JVM arguments:</string> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QPushButton" name="btnBrowse"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Browse...</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="3"> + <widget class="QLineEdit" name="javaPathTextBox"/> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="pushButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Auto-detect...</string> + </property> + </widget> + </item> + <item row="2" column="1" colspan="3"> + <widget class="QLineEdit" name="jvmArgsTextBox"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="customCommandsGroupBox"> + <property name="title"> + <string>Custom Commands</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="1" column="0"> + <widget class="QLabel" name="labelPostExitCmd"> + <property name="text"> + <string>Post-exit command:</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelPreLaunchCmd"> + <property name="text"> + <string>Pre-launch command:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="preLaunchCmdTextBox"/> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="postExitCmdTextBox"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QLabel" name="labelCustomCmdsDescription"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Pre-launch command runs before the instance launches and post-exit command runs after it exits. Both will be run in MultiMC's working directory with INST_ID, INST_DIR, and INST_NAME as environment variables.</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>settingsTabs</tabstop> + <tabstop>buttonBox</tabstop> + <tabstop>sortLastLaunchedBtn</tabstop> + <tabstop>sortByNameBtn</tabstop> + <tabstop>devBuildsCheckBox</tabstop> + <tabstop>autoUpdateCheckBox</tabstop> + <tabstop>instDirTextBox</tabstop> + <tabstop>modsDirTextBox</tabstop> + <tabstop>lwjglDirTextBox</tabstop> + <tabstop>instDirBrowseBtn</tabstop> + <tabstop>modsDirBrowseBtn</tabstop> + <tabstop>lwjglDirBrowseBtn</tabstop> + <tabstop>maximizedCheckBox</tabstop> + <tabstop>windowWidthSpinBox</tabstop> + <tabstop>windowHeightSpinBox</tabstop> + <tabstop>showConsoleCheck</tabstop> + <tabstop>autoCloseConsoleCheck</tabstop> + <tabstop>autoLoginCheckBox</tabstop> + <tabstop>minMemSpinBox</tabstop> + <tabstop>maxMemSpinBox</tabstop> + <tabstop>permGenSpinBox</tabstop> + <tabstop>javaPathTextBox</tabstop> + <tabstop>pushButton</tabstop> + <tabstop>btnBrowse</tabstop> + <tabstop>jvmArgsTextBox</tabstop> + <tabstop>preLaunchCmdTextBox</tabstop> + <tabstop>postExitCmdTextBox</tabstop> + </tabstops> + <resources> + <include location="../../multimc.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>SettingsDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>257</x> + <y>410</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>SettingsDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>325</x> + <y>410</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> + <buttongroups> + <buttongroup name="sortingModeGroup"/> + </buttongroups> +</ui> diff --git a/gui/dialogs/VersionSelectDialog.cpp b/gui/dialogs/VersionSelectDialog.cpp new file mode 100644 index 00000000..d6efe3c0 --- /dev/null +++ b/gui/dialogs/VersionSelectDialog.cpp @@ -0,0 +1,111 @@ +/* Copyright 2013 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 "VersionSelectDialog.h" +#include "ui_VersionSelectDialog.h" + +#include <QHeaderView> + +#include <QDebug> + +#include <gui/dialogs/ProgressDialog.h> +#include "gui/Platform.h" + +#include <logic/BaseVersion.h> +#include <logic/lists/BaseVersionList.h> +#include <logic/tasks/Task.h> + +VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent, + bool cancelable) + : QDialog(parent), ui(new Ui::VersionSelectDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + setWindowModality(Qt::WindowModal); + setWindowTitle(title); + + m_vlist = vlist; + + m_proxyModel = new QSortFilterProxyModel(this); + m_proxyModel->setSourceModel(vlist); + + ui->listView->setModel(m_proxyModel); + ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); + + if (!cancelable) + { + ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false); + } +} + +VersionSelectDialog::~VersionSelectDialog() +{ + delete ui; +} + +void VersionSelectDialog::setResizeOn(int column) +{ + ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::ResizeToContents); + resizeOnColumn = column; + ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); +} + +int VersionSelectDialog::exec() +{ + QDialog::open(); + if (!m_vlist->isLoaded()) + loadList(); + return QDialog::exec(); +} + +void VersionSelectDialog::loadList() +{ + ProgressDialog *taskDlg = new ProgressDialog(this); + Task *loadTask = m_vlist->getLoadTask(); + loadTask->setParent(taskDlg); + taskDlg->exec(loadTask); +} + +BaseVersionPtr VersionSelectDialog::selectedVersion() const +{ + auto currentIndex = ui->listView->selectionModel()->currentIndex(); + auto variant = m_proxyModel->data(currentIndex, BaseVersionList::VersionPointerRole); + return variant.value<BaseVersionPtr>(); +} + +void VersionSelectDialog::on_refreshButton_clicked() +{ + loadList(); +} + +void VersionSelectDialog::setFilter(int column, QString filter) +{ + m_proxyModel->setFilterKeyColumn(column); + m_proxyModel->setFilterFixedString(filter); + /* + QStringList filteredTypes; + if (!ui->filterSnapshotsCheckbox->isChecked()) + filteredTypes += "Snapshot"; + if (!ui->filterMCNostalgiaCheckbox->isChecked()) + filteredTypes += "Nostalgia"; + + QString regexStr = "^.*$"; + if (filteredTypes.length() > 0) + regexStr = QString("^((?!%1).)*$").arg(filteredTypes.join('|')); + + QLOG_DEBUG() << "Filter:" << regexStr; + */ +} diff --git a/gui/dialogs/VersionSelectDialog.h b/gui/dialogs/VersionSelectDialog.h new file mode 100644 index 00000000..e36341db --- /dev/null +++ b/gui/dialogs/VersionSelectDialog.h @@ -0,0 +1,61 @@ +/* Copyright 2013 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 <QDialog> +#include <QSortFilterProxyModel> + +#include "logic/BaseVersion.h" + +class BaseVersionList; + +namespace Ui +{ +class VersionSelectDialog; +} + +class VersionSelectDialog : public QDialog +{ + Q_OBJECT + +public: + explicit VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent = 0, + bool cancelable = true); + ~VersionSelectDialog(); + + virtual int exec(); + + //! Starts a task that loads the list. + void loadList(); + + BaseVersionPtr selectedVersion() const; + + void setFilter(int column, QString filter); + void setResizeOn(int column); + +private +slots: + void on_refreshButton_clicked(); + +private: + Ui::VersionSelectDialog *ui; + + BaseVersionList *m_vlist; + + QSortFilterProxyModel *m_proxyModel; + + int resizeOnColumn = 0; +}; diff --git a/gui/dialogs/VersionSelectDialog.ui b/gui/dialogs/VersionSelectDialog.ui new file mode 100644 index 00000000..222f29cf --- /dev/null +++ b/gui/dialogs/VersionSelectDialog.ui @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>VersionSelectDialog</class> + <widget class="QDialog" name="VersionSelectDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>347</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTreeView" name="listView"> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <attribute name="headerCascadingSectionResizes"> + <bool>true</bool> + </attribute> + <attribute name="headerStretchLastSection"> + <bool>false</bool> + </attribute> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="refreshButton"> + <property name="toolTip"> + <string>Reloads the version list.</string> + </property> + <property name="text"> + <string>&Refresh</string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>VersionSelectDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>257</x> + <y>290</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>VersionSelectDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>325</x> + <y>290</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> |