2022-05-27 02:48:54 +05:30
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright ( C ) 2022 Sefa Eyeoglu < contact @ scrumplex . net >
2013-02-02 00:37:36 +05:30
*
2022-05-27 02:48:54 +05:30
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , version 3.
2013-10-06 18:13:46 +05:30
*
2022-05-27 02:48:54 +05:30
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2013-02-02 00:37:36 +05:30
*
2022-05-27 02:48:54 +05:30
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https : //www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice :
*
* Copyright 2013 - 2021 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 .
2013-02-02 00:37:36 +05:30
*/
2021-11-20 20:52:22 +05:30
# include "Application.h"
2013-11-04 07:23:05 +05:30
# include "NewInstanceDialog.h"
# include "ui_NewInstanceDialog.h"
2013-02-02 00:37:36 +05:30
2015-02-09 06:21:14 +05:30
# include <BaseVersion.h>
# include <icons/IconList.h>
# include <tasks/Task.h>
# include <InstanceList.h>
2013-04-23 02:09:41 +05:30
2013-11-04 07:23:05 +05:30
# include "VersionSelectDialog.h"
2013-09-18 03:30:35 +05:30
# include "ProgressDialog.h"
2013-08-10 22:04:08 +05:30
# include "IconPickerDialog.h"
2013-04-23 02:09:41 +05:30
2013-02-02 00:37:36 +05:30
# include <QLayout>
2013-04-23 02:09:41 +05:30
# include <QPushButton>
2015-02-13 02:31:20 +05:30
# include <QFileDialog>
# include <QValidator>
2018-03-19 07:06:12 +05:30
# include <QDialogButtonBox>
2022-09-26 15:20:31 +05:30
# include <utility>
2015-02-13 02:31:20 +05:30
2021-11-22 08:25:16 +05:30
# include "ui/widgets/PageContainer.h"
# include "ui/pages/modplatform/VanillaPage.h"
# include "ui/pages/modplatform/atlauncher/AtlPage.h"
# include "ui/pages/modplatform/ftb/FtbPage.h"
# include "ui/pages/modplatform/legacy_ftb/Page.h"
# include "ui/pages/modplatform/flame/FlamePage.h"
# include "ui/pages/modplatform/ImportPage.h"
2022-01-31 19:55:36 +05:30
# include "ui/pages/modplatform/modrinth/ModrinthPage.h"
2021-11-22 08:25:16 +05:30
# include "ui/pages/modplatform/technic/TechnicPage.h"
2020-06-07 21:16:12 +05:30
2019-07-10 01:34:52 +05:30
2017-04-22 09:41:26 +05:30
NewInstanceDialog : : NewInstanceDialog ( const QString & initialGroup , const QString & url , QWidget * parent )
2018-07-15 18:21:05 +05:30
: QDialog ( parent ) , ui ( new Ui : : NewInstanceDialog )
2013-02-02 00:37:36 +05:30
{
2018-07-15 18:21:05 +05:30
ui - > setupUi ( this ) ;
2015-02-13 02:31:20 +05:30
2021-11-20 20:52:22 +05:30
setWindowIcon ( APPLICATION - > getThemedIcon ( " new " ) ) ;
2017-03-20 05:14:49 +05:30
2018-07-15 18:21:05 +05:30
InstIconKey = " default " ;
2021-11-20 20:52:22 +05:30
ui - > iconButton - > setIcon ( APPLICATION - > icons ( ) - > getIcon ( InstIconKey ) ) ;
2015-02-13 02:31:20 +05:30
2022-05-02 22:40:45 +05:30
# if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
auto groupList = APPLICATION - > instances ( ) - > getGroups ( ) ;
auto groups = QSet < QString > ( groupList . begin ( ) , groupList . end ( ) ) ;
groupList = groups . values ( ) ;
# else
2021-11-20 20:52:22 +05:30
auto groups = APPLICATION - > instances ( ) - > getGroups ( ) . toSet ( ) ;
2018-07-15 18:21:05 +05:30
auto groupList = QStringList ( groups . toList ( ) ) ;
2022-05-02 22:40:45 +05:30
# endif
2018-07-15 18:21:05 +05:30
groupList . sort ( Qt : : CaseInsensitive ) ;
groupList . removeOne ( " " ) ;
groupList . push_front ( initialGroup ) ;
groupList . push_front ( " " ) ;
ui - > groupBox - > addItems ( groupList ) ;
int index = groupList . indexOf ( initialGroup ) ;
if ( index = = - 1 )
{
index = 0 ;
}
ui - > groupBox - > setCurrentIndex ( index ) ;
ui - > groupBox - > lineEdit ( ) - > setPlaceholderText ( tr ( " No group " ) ) ;
2015-08-21 12:30:35 +05:30
2018-03-01 00:12:30 +05:30
2018-07-31 05:50:04 +05:30
// NOTE: m_buttons must be initialized before PageContainer, because it indirectly accesses m_buttons through setSuggestedPack! Do not move this below.
m_buttons = new QDialogButtonBox ( QDialogButtonBox : : Help | QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel ) ;
2018-03-01 00:12:30 +05:30
2018-07-15 18:21:05 +05:30
m_container = new PageContainer ( this ) ;
m_container - > setSizePolicy ( QSizePolicy : : Policy : : Preferred , QSizePolicy : : Policy : : Expanding ) ;
m_container - > layout ( ) - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
ui - > verticalLayout - > insertWidget ( 2 , m_container ) ;
2018-03-01 00:12:30 +05:30
2018-07-15 18:21:05 +05:30
m_container - > addButtons ( m_buttons ) ;
2018-07-23 04:19:26 +05:30
// Bonk Qt over its stupid head and make sure it understands which button is the default one...
// See: https://stackoverflow.com/questions/24556831/qbuttonbox-set-default-button
auto OkButton = m_buttons - > button ( QDialogButtonBox : : Ok ) ;
OkButton - > setDefault ( true ) ;
OkButton - > setAutoDefault ( true ) ;
connect ( OkButton , & QPushButton : : clicked , this , & NewInstanceDialog : : accept ) ;
auto CancelButton = m_buttons - > button ( QDialogButtonBox : : Cancel ) ;
CancelButton - > setDefault ( false ) ;
CancelButton - > setAutoDefault ( false ) ;
connect ( CancelButton , & QPushButton : : clicked , this , & NewInstanceDialog : : reject ) ;
auto HelpButton = m_buttons - > button ( QDialogButtonBox : : Help ) ;
HelpButton - > setDefault ( false ) ;
HelpButton - > setAutoDefault ( false ) ;
connect ( HelpButton , & QPushButton : : clicked , m_container , & PageContainer : : help ) ;
2018-03-19 07:06:12 +05:30
2018-07-15 18:21:05 +05:30
if ( ! url . isEmpty ( ) )
{
2019-07-10 01:34:52 +05:30
QUrl actualUrl ( url ) ;
2019-11-18 05:08:36 +05:30
m_container - > selectPage ( " import " ) ;
importPage - > setUrl ( url ) ;
2018-07-15 18:21:05 +05:30
}
2018-03-01 00:12:30 +05:30
2018-07-15 18:21:05 +05:30
updateDialogState ( ) ;
2018-03-19 07:06:12 +05:30
2021-11-20 20:52:22 +05:30
restoreGeometry ( QByteArray : : fromBase64 ( APPLICATION - > settings ( ) - > get ( " NewInstanceGeometry " ) . toByteArray ( ) ) ) ;
2013-04-23 02:09:41 +05:30
}
2018-03-28 01:32:57 +05:30
void NewInstanceDialog : : reject ( )
{
2021-11-20 20:52:22 +05:30
APPLICATION - > settings ( ) - > set ( " NewInstanceGeometry " , saveGeometry ( ) . toBase64 ( ) ) ;
2022-10-13 22:19:06 +05:30
// This is just so that the pages get the close() call and can react to it, if needed.
m_container - > prepareToClose ( ) ;
2018-07-15 18:21:05 +05:30
QDialog : : reject ( ) ;
2018-03-28 01:32:57 +05:30
}
void NewInstanceDialog : : accept ( )
{
2021-11-20 20:52:22 +05:30
APPLICATION - > settings ( ) - > set ( " NewInstanceGeometry " , saveGeometry ( ) . toBase64 ( ) ) ;
2018-07-15 18:21:05 +05:30
importIconNow ( ) ;
2022-10-13 22:19:06 +05:30
// This is just so that the pages get the close() call and can react to it, if needed.
m_container - > prepareToClose ( ) ;
2018-07-15 18:21:05 +05:30
QDialog : : accept ( ) ;
2018-03-28 01:32:57 +05:30
}
2018-03-19 07:06:12 +05:30
QList < BasePage * > NewInstanceDialog : : getPages ( )
2017-03-20 05:14:49 +05:30
{
2022-05-30 00:48:34 +05:30
QList < BasePage * > pages ;
2019-07-10 01:21:19 +05:30
importPage = new ImportPage ( this ) ;
2022-05-30 00:48:34 +05:30
pages . append ( new VanillaPage ( this ) ) ;
pages . append ( importPage ) ;
pages . append ( new AtlPage ( this ) ) ;
2022-08-09 00:19:49 +05:30
if ( APPLICATION - > capabilities ( ) & Application : : SupportsFlame )
2022-05-30 00:48:34 +05:30
pages . append ( new FlamePage ( this ) ) ;
pages . append ( new FtbPage ( this ) ) ;
pages . append ( new LegacyFTB : : Page ( this ) ) ;
pages . append ( new ModrinthPage ( this ) ) ;
pages . append ( new TechnicPage ( this ) ) ;
return pages ;
2018-03-19 07:06:12 +05:30
}
QString NewInstanceDialog : : dialogTitle ( )
{
2018-07-15 18:21:05 +05:30
return tr ( " New Instance " ) ;
2017-03-20 05:14:49 +05:30
}
2013-05-04 01:11:37 +05:30
NewInstanceDialog : : ~ NewInstanceDialog ( )
2013-04-23 02:09:41 +05:30
{
2018-07-15 18:21:05 +05:30
delete ui ;
2013-04-23 02:09:41 +05:30
}
2022-09-26 15:20:31 +05:30
void NewInstanceDialog : : setSuggestedPack ( const QString & name , InstanceTask * task )
2013-04-23 02:09:41 +05:30
{
2018-07-15 18:21:05 +05:30
creationTask . reset ( task ) ;
2022-07-15 00:43:23 +05:30
2018-07-15 18:21:05 +05:30
ui - > instNameTextBox - > setPlaceholderText ( name ) ;
2022-07-15 00:43:23 +05:30
importVersion . clear ( ) ;
2018-03-01 00:12:30 +05:30
2022-07-15 00:43:23 +05:30
if ( ! task ) {
ui - > iconButton - > setIcon ( APPLICATION - > icons ( ) - > getIcon ( " default " ) ) ;
importIcon = false ;
}
auto allowOK = task & & ! instName ( ) . isEmpty ( ) ;
m_buttons - > button ( QDialogButtonBox : : Ok ) - > setEnabled ( allowOK ) ;
}
2022-09-26 15:20:31 +05:30
void NewInstanceDialog : : setSuggestedPack ( const QString & name , QString version , InstanceTask * task )
2022-07-15 00:43:23 +05:30
{
creationTask . reset ( task ) ;
ui - > instNameTextBox - > setPlaceholderText ( name ) ;
2022-09-26 15:20:31 +05:30
importVersion = std : : move ( version ) ;
2022-07-15 00:43:23 +05:30
if ( ! task ) {
2021-11-20 20:52:22 +05:30
ui - > iconButton - > setIcon ( APPLICATION - > icons ( ) - > getIcon ( " default " ) ) ;
2018-08-02 04:22:31 +05:30
importIcon = false ;
}
2018-07-15 18:21:05 +05:30
auto allowOK = task & & ! instName ( ) . isEmpty ( ) ;
m_buttons - > button ( QDialogButtonBox : : Ok ) - > setEnabled ( allowOK ) ;
2013-04-23 02:09:41 +05:30
}
2018-04-07 19:45:58 +05:30
void NewInstanceDialog : : setSuggestedIconFromFile ( const QString & path , const QString & name )
{
2018-07-15 18:21:05 +05:30
importIcon = true ;
importIconPath = path ;
importIconName = name ;
2018-04-07 19:45:58 +05:30
2018-07-15 18:21:05 +05:30
//Hmm, for some reason they can be to small
ui - > iconButton - > setIcon ( QIcon ( path ) ) ;
2018-04-07 19:45:58 +05:30
}
2021-06-19 19:49:39 +05:30
void NewInstanceDialog : : setSuggestedIcon ( const QString & key )
{
2021-11-20 20:52:22 +05:30
auto icon = APPLICATION - > icons ( ) - > getIcon ( key ) ;
2021-06-19 19:49:39 +05:30
importIcon = false ;
ui - > iconButton - > setIcon ( icon ) ;
}
2018-03-19 07:06:12 +05:30
InstanceTask * NewInstanceDialog : : extractTask ( )
2013-04-23 02:09:41 +05:30
{
2018-07-15 18:21:05 +05:30
InstanceTask * extracted = creationTask . get ( ) ;
creationTask . release ( ) ;
2022-07-15 00:43:23 +05:30
InstanceName inst_name ( ui - > instNameTextBox - > placeholderText ( ) . trimmed ( ) , importVersion ) ;
inst_name . setName ( ui - > instNameTextBox - > text ( ) . trimmed ( ) ) ;
extracted - > setName ( inst_name ) ;
2018-07-15 18:21:05 +05:30
extracted - > setGroup ( instGroup ( ) ) ;
extracted - > setIcon ( iconKey ( ) ) ;
return extracted ;
2018-03-19 07:06:12 +05:30
}
2013-10-06 18:13:46 +05:30
2018-03-19 07:06:12 +05:30
void NewInstanceDialog : : updateDialogState ( )
{
2018-07-15 18:21:05 +05:30
auto allowOK = creationTask & & ! instName ( ) . isEmpty ( ) ;
2018-07-23 04:19:26 +05:30
auto OkButton = m_buttons - > button ( QDialogButtonBox : : Ok ) ;
if ( OkButton - > isEnabled ( ) ! = allowOK )
{
OkButton - > setEnabled ( allowOK ) ;
}
2013-04-23 02:09:41 +05:30
}
2013-04-23 03:45:18 +05:30
QString NewInstanceDialog : : instName ( ) const
{
2018-07-29 01:38:09 +05:30
auto result = ui - > instNameTextBox - > text ( ) . trimmed ( ) ;
2018-07-15 18:21:05 +05:30
if ( result . size ( ) )
{
2018-07-29 01:38:09 +05:30
return result ;
2018-07-15 18:21:05 +05:30
}
2018-07-29 01:38:09 +05:30
result = ui - > instNameTextBox - > placeholderText ( ) . trimmed ( ) ;
2018-07-15 18:21:05 +05:30
if ( result . size ( ) )
{
2018-07-29 01:38:09 +05:30
return result ;
2018-07-15 18:21:05 +05:30
}
return QString ( ) ;
2013-04-23 03:45:18 +05:30
}
2015-08-21 12:30:35 +05:30
2014-11-09 01:47:28 +05:30
QString NewInstanceDialog : : instGroup ( ) const
{
2018-07-15 18:21:05 +05:30
return ui - > groupBox - > currentText ( ) ;
2014-11-09 01:47:28 +05:30
}
2013-04-23 03:45:18 +05:30
QString NewInstanceDialog : : iconKey ( ) const
{
2018-07-15 18:21:05 +05:30
return InstIconKey ;
2013-04-23 03:45:18 +05:30
}
2013-05-07 07:58:28 +05:30
2013-08-10 22:04:08 +05:30
void NewInstanceDialog : : on_iconButton_clicked ( )
{
2018-07-15 18:21:05 +05:30
importIconNow ( ) ; //so the user can switch back
IconPickerDialog dlg ( this ) ;
dlg . execWithSelection ( InstIconKey ) ;
2013-10-06 18:13:46 +05:30
2018-07-15 18:21:05 +05:30
if ( dlg . result ( ) = = QDialog : : Accepted )
{
InstIconKey = dlg . selectedIconKey ;
2021-11-20 20:52:22 +05:30
ui - > iconButton - > setIcon ( APPLICATION - > icons ( ) - > getIcon ( InstIconKey ) ) ;
2018-07-15 18:21:05 +05:30
importIcon = false ;
}
2013-08-10 22:04:08 +05:30
}
2013-05-07 07:58:28 +05:30
void NewInstanceDialog : : on_instNameTextBox_textChanged ( const QString & arg1 )
{
2018-07-15 18:21:05 +05:30
updateDialogState ( ) ;
2013-05-07 07:58:28 +05:30
}
2018-04-07 19:45:58 +05:30
void NewInstanceDialog : : importIconNow ( )
{
2018-07-15 18:21:05 +05:30
if ( importIcon ) {
2021-11-20 20:52:22 +05:30
APPLICATION - > icons ( ) - > installIcon ( importIconPath , importIconName ) ;
2018-07-15 18:21:05 +05:30
InstIconKey = importIconName ;
importIcon = false ;
}
2021-11-20 20:52:22 +05:30
APPLICATION - > settings ( ) - > set ( " NewInstanceGeometry " , saveGeometry ( ) . toBase64 ( ) ) ;
2018-04-07 19:45:58 +05:30
}