2022-05-26 22:18:54 +01:00
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright ( C ) 2022 Sefa Eyeoglu < contact @ scrumplex . net >
2013-02-01 19:07:36 +00:00
*
2022-05-26 22:18:54 +01:00
* 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 13:43:46 +01:00
*
2022-05-26 22:18:54 +01:00
* 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-01 19:07:36 +00:00
*
2022-05-26 22:18:54 +01:00
* 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-01 19:07:36 +00:00
*/
2013-11-04 01:53:05 +00:00
# include "NewInstanceDialog.h"
2023-07-13 16:41:29 +01:00
# include "Application.h"
# include "ui/pages/modplatform/import_ftb/ImportFTBPage.h"
2013-11-04 01:53:05 +00:00
# include "ui_NewInstanceDialog.h"
2013-02-01 19:07:36 +00:00
2015-02-09 00:51:14 +00:00
# include <BaseVersion.h>
2023-07-13 16:41:29 +01:00
# include <InstanceList.h>
2015-02-09 00:51:14 +00:00
# include <icons/IconList.h>
# include <tasks/Task.h>
2013-04-22 21:39:41 +01:00
2013-08-10 17:34:08 +01:00
# include "IconPickerDialog.h"
2023-07-13 16:41:29 +01:00
# include "ProgressDialog.h"
# include "VersionSelectDialog.h"
2013-04-22 21:39:41 +01:00
2023-07-13 16:41:29 +01:00
# include <QDialogButtonBox>
# include <QFileDialog>
2013-02-01 19:07:36 +00:00
# include <QLayout>
2013-04-22 21:39:41 +01:00
# include <QPushButton>
2015-02-12 21:01:20 +00:00
# include <QValidator>
2022-09-26 10:50:31 +01:00
# include <utility>
2015-02-12 21:01:20 +00:00
2023-06-24 22:54:05 +01:00
# include "ui/pages/modplatform/CustomPage.h"
2023-07-13 16:41:29 +01:00
# include "ui/pages/modplatform/ImportPage.h"
2021-11-22 02:55:16 +00:00
# include "ui/pages/modplatform/atlauncher/AtlPage.h"
# include "ui/pages/modplatform/flame/FlamePage.h"
2023-07-13 16:41:29 +01:00
# include "ui/pages/modplatform/legacy_ftb/Page.h"
2022-01-31 14:25:36 +00:00
# include "ui/pages/modplatform/modrinth/ModrinthPage.h"
2021-11-22 02:55:16 +00:00
# include "ui/pages/modplatform/technic/TechnicPage.h"
2023-07-13 16:41:29 +01:00
# include "ui/widgets/PageContainer.h"
2020-06-07 16:46:12 +01:00
2023-07-13 16:41:29 +01:00
NewInstanceDialog : : NewInstanceDialog ( const QString & initialGroup , const QString & url , QWidget * parent )
2018-07-15 13:51:05 +01:00
: QDialog ( parent ) , ui ( new Ui : : NewInstanceDialog )
2013-02-01 19:07:36 +00:00
{
2018-07-15 13:51:05 +01:00
ui - > setupUi ( this ) ;
2015-02-12 21:01:20 +00:00
2021-11-20 15:22:22 +00:00
setWindowIcon ( APPLICATION - > getThemedIcon ( " new " ) ) ;
2017-03-19 23:44:49 +00:00
2018-07-15 13:51:05 +01:00
InstIconKey = " default " ;
2021-11-20 15:22:22 +00:00
ui - > iconButton - > setIcon ( APPLICATION - > icons ( ) - > getIcon ( InstIconKey ) ) ;
2015-02-12 21:01:20 +00:00
2022-05-02 18:10:45 +01:00
# 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 15:22:22 +00:00
auto groups = APPLICATION - > instances ( ) - > getGroups ( ) . toSet ( ) ;
2018-07-15 13:51:05 +01:00
auto groupList = QStringList ( groups . toList ( ) ) ;
2022-05-02 18:10:45 +01:00
# endif
2018-07-15 13:51:05 +01:00
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 08:00:35 +01:00
2018-02-28 18:42:30 +00:00
2018-07-31 01:20:04 +01:00
// 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-02-28 18:42:30 +00:00
2023-05-28 10:15:39 +01:00
m_container = new PageContainer ( this , { } , this ) ;
2018-07-15 13:51:05 +01:00
m_container - > setSizePolicy ( QSizePolicy : : Policy : : Preferred , QSizePolicy : : Policy : : Expanding ) ;
m_container - > layout ( ) - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
ui - > verticalLayout - > insertWidget ( 2 , m_container ) ;
2018-02-28 18:42:30 +00:00
2018-07-15 13:51:05 +01:00
m_container - > addButtons ( m_buttons ) ;
2018-07-22 23:49:26 +01:00
// 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 01:36:12 +00:00
2018-07-15 13:51:05 +01:00
if ( ! url . isEmpty ( ) )
{
2019-07-09 21:04:52 +01:00
QUrl actualUrl ( url ) ;
2019-11-17 23:38:36 +00:00
m_container - > selectPage ( " import " ) ;
importPage - > setUrl ( url ) ;
2018-07-15 13:51:05 +01:00
}
2018-02-28 18:42:30 +00:00
2018-07-15 13:51:05 +01:00
updateDialogState ( ) ;
2018-03-19 01:36:12 +00:00
2021-11-20 15:22:22 +00:00
restoreGeometry ( QByteArray : : fromBase64 ( APPLICATION - > settings ( ) - > get ( " NewInstanceGeometry " ) . toByteArray ( ) ) ) ;
2013-04-22 21:39:41 +01:00
}
2018-03-27 21:02:57 +01:00
void NewInstanceDialog : : reject ( )
{
2021-11-20 15:22:22 +00:00
APPLICATION - > settings ( ) - > set ( " NewInstanceGeometry " , saveGeometry ( ) . toBase64 ( ) ) ;
2022-10-13 17:49:06 +01:00
// This is just so that the pages get the close() call and can react to it, if needed.
m_container - > prepareToClose ( ) ;
2018-07-15 13:51:05 +01:00
QDialog : : reject ( ) ;
2018-03-27 21:02:57 +01:00
}
void NewInstanceDialog : : accept ( )
{
2021-11-20 15:22:22 +00:00
APPLICATION - > settings ( ) - > set ( " NewInstanceGeometry " , saveGeometry ( ) . toBase64 ( ) ) ;
2018-07-15 13:51:05 +01:00
importIconNow ( ) ;
2022-10-13 17:49:06 +01:00
// This is just so that the pages get the close() call and can react to it, if needed.
m_container - > prepareToClose ( ) ;
2018-07-15 13:51:05 +01:00
QDialog : : accept ( ) ;
2018-03-27 21:02:57 +01:00
}
2018-03-19 01:36:12 +00:00
QList < BasePage * > NewInstanceDialog : : getPages ( )
2017-03-19 23:44:49 +00:00
{
2022-05-29 20:18:34 +01:00
QList < BasePage * > pages ;
2019-07-09 20:51:19 +01:00
importPage = new ImportPage ( this ) ;
2022-05-29 20:18:34 +01:00
2023-06-24 22:54:05 +01:00
pages . append ( new CustomPage ( this ) ) ;
2022-05-29 20:18:34 +01:00
pages . append ( importPage ) ;
pages . append ( new AtlPage ( this ) ) ;
2022-08-08 19:49:49 +01:00
if ( APPLICATION - > capabilities ( ) & Application : : SupportsFlame )
2022-05-29 20:18:34 +01:00
pages . append ( new FlamePage ( this ) ) ;
pages . append ( new LegacyFTB : : Page ( this ) ) ;
2023-07-13 16:41:29 +01:00
pages . append ( new FTBImportAPP : : ImportFTBPage ( this ) ) ;
2022-05-29 20:18:34 +01:00
pages . append ( new ModrinthPage ( this ) ) ;
pages . append ( new TechnicPage ( this ) ) ;
return pages ;
2018-03-19 01:36:12 +00:00
}
QString NewInstanceDialog : : dialogTitle ( )
{
2018-07-15 13:51:05 +01:00
return tr ( " New Instance " ) ;
2017-03-19 23:44:49 +00:00
}
2013-05-03 20:41:37 +01:00
NewInstanceDialog : : ~ NewInstanceDialog ( )
2013-04-22 21:39:41 +01:00
{
2018-07-15 13:51:05 +01:00
delete ui ;
2013-04-22 21:39:41 +01:00
}
2022-09-26 10:50:31 +01:00
void NewInstanceDialog : : setSuggestedPack ( const QString & name , InstanceTask * task )
2013-04-22 21:39:41 +01:00
{
2018-07-15 13:51:05 +01:00
creationTask . reset ( task ) ;
2022-07-14 20:13:23 +01:00
2018-07-15 13:51:05 +01:00
ui - > instNameTextBox - > setPlaceholderText ( name ) ;
2022-07-14 20:13:23 +01:00
importVersion . clear ( ) ;
2018-02-28 18:42:30 +00:00
2022-07-14 20:13:23 +01:00
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 10:50:31 +01:00
void NewInstanceDialog : : setSuggestedPack ( const QString & name , QString version , InstanceTask * task )
2022-07-14 20:13:23 +01:00
{
creationTask . reset ( task ) ;
ui - > instNameTextBox - > setPlaceholderText ( name ) ;
2022-09-26 10:50:31 +01:00
importVersion = std : : move ( version ) ;
2022-07-14 20:13:23 +01:00
if ( ! task ) {
2021-11-20 15:22:22 +00:00
ui - > iconButton - > setIcon ( APPLICATION - > icons ( ) - > getIcon ( " default " ) ) ;
2018-08-01 23:52:31 +01:00
importIcon = false ;
}
2018-07-15 13:51:05 +01:00
auto allowOK = task & & ! instName ( ) . isEmpty ( ) ;
m_buttons - > button ( QDialogButtonBox : : Ok ) - > setEnabled ( allowOK ) ;
2013-04-22 21:39:41 +01:00
}
2018-04-07 15:15:58 +01:00
void NewInstanceDialog : : setSuggestedIconFromFile ( const QString & path , const QString & name )
{
2018-07-15 13:51:05 +01:00
importIcon = true ;
importIconPath = path ;
importIconName = name ;
2018-04-07 15:15:58 +01:00
2018-07-15 13:51:05 +01:00
//Hmm, for some reason they can be to small
ui - > iconButton - > setIcon ( QIcon ( path ) ) ;
2018-04-07 15:15:58 +01:00
}
2021-06-19 15:19:39 +01:00
void NewInstanceDialog : : setSuggestedIcon ( const QString & key )
{
2021-11-20 15:22:22 +00:00
auto icon = APPLICATION - > icons ( ) - > getIcon ( key ) ;
2021-06-19 15:19:39 +01:00
importIcon = false ;
ui - > iconButton - > setIcon ( icon ) ;
}
2018-03-19 01:36:12 +00:00
InstanceTask * NewInstanceDialog : : extractTask ( )
2013-04-22 21:39:41 +01:00
{
2018-07-15 13:51:05 +01:00
InstanceTask * extracted = creationTask . get ( ) ;
creationTask . release ( ) ;
2022-07-14 20:13:23 +01:00
InstanceName inst_name ( ui - > instNameTextBox - > placeholderText ( ) . trimmed ( ) , importVersion ) ;
inst_name . setName ( ui - > instNameTextBox - > text ( ) . trimmed ( ) ) ;
extracted - > setName ( inst_name ) ;
2018-07-15 13:51:05 +01:00
extracted - > setGroup ( instGroup ( ) ) ;
extracted - > setIcon ( iconKey ( ) ) ;
return extracted ;
2018-03-19 01:36:12 +00:00
}
2013-10-06 13:43:46 +01:00
2018-03-19 01:36:12 +00:00
void NewInstanceDialog : : updateDialogState ( )
{
2018-07-15 13:51:05 +01:00
auto allowOK = creationTask & & ! instName ( ) . isEmpty ( ) ;
2018-07-22 23:49:26 +01:00
auto OkButton = m_buttons - > button ( QDialogButtonBox : : Ok ) ;
if ( OkButton - > isEnabled ( ) ! = allowOK )
{
OkButton - > setEnabled ( allowOK ) ;
}
2013-04-22 21:39:41 +01:00
}
2013-04-22 23:15:18 +01:00
QString NewInstanceDialog : : instName ( ) const
{
2018-07-28 21:08:09 +01:00
auto result = ui - > instNameTextBox - > text ( ) . trimmed ( ) ;
2018-07-15 13:51:05 +01:00
if ( result . size ( ) )
{
2018-07-28 21:08:09 +01:00
return result ;
2018-07-15 13:51:05 +01:00
}
2018-07-28 21:08:09 +01:00
result = ui - > instNameTextBox - > placeholderText ( ) . trimmed ( ) ;
2018-07-15 13:51:05 +01:00
if ( result . size ( ) )
{
2018-07-28 21:08:09 +01:00
return result ;
2018-07-15 13:51:05 +01:00
}
return QString ( ) ;
2013-04-22 23:15:18 +01:00
}
2015-08-21 08:00:35 +01:00
2014-11-08 20:17:28 +00:00
QString NewInstanceDialog : : instGroup ( ) const
{
2018-07-15 13:51:05 +01:00
return ui - > groupBox - > currentText ( ) ;
2014-11-08 20:17:28 +00:00
}
2013-04-22 23:15:18 +01:00
QString NewInstanceDialog : : iconKey ( ) const
{
2018-07-15 13:51:05 +01:00
return InstIconKey ;
2013-04-22 23:15:18 +01:00
}
2013-05-07 03:28:28 +01:00
2013-08-10 17:34:08 +01:00
void NewInstanceDialog : : on_iconButton_clicked ( )
{
2023-07-27 23:16:00 +01:00
importIconNow ( ) ; // so the user can switch back
2018-07-15 13:51:05 +01:00
IconPickerDialog dlg ( this ) ;
dlg . execWithSelection ( InstIconKey ) ;
2013-10-06 13:43:46 +01:00
2023-07-27 23:16:00 +01:00
if ( dlg . result ( ) = = QDialog : : Accepted ) {
2018-07-15 13:51:05 +01:00
InstIconKey = dlg . selectedIconKey ;
2021-11-20 15:22:22 +00:00
ui - > iconButton - > setIcon ( APPLICATION - > icons ( ) - > getIcon ( InstIconKey ) ) ;
2018-07-15 13:51:05 +01:00
importIcon = false ;
}
2013-08-10 17:34:08 +01:00
}
2023-08-10 19:38:32 +01:00
void NewInstanceDialog : : on_instNameTextBox_textChanged ( [[maybe_unused]] const QString & arg1 )
2013-05-07 03:28:28 +01:00
{
2018-07-15 13:51:05 +01:00
updateDialogState ( ) ;
2013-05-07 03:28:28 +01:00
}
2018-04-07 15:15:58 +01:00
void NewInstanceDialog : : importIconNow ( )
{
2023-07-27 23:16:00 +01:00
if ( importIcon ) {
2021-11-20 15:22:22 +00:00
APPLICATION - > icons ( ) - > installIcon ( importIconPath , importIconName ) ;
2023-07-28 11:16:57 +01:00
InstIconKey = importIconName . mid ( 0 , importIconName . lastIndexOf ( ' . ' ) ) ;
2018-07-15 13:51:05 +01:00
importIcon = false ;
}
2021-11-20 15:22:22 +00:00
APPLICATION - > settings ( ) - > set ( " NewInstanceGeometry " , saveGeometry ( ) . toBase64 ( ) ) ;
2018-04-07 15:15:58 +01:00
}