2022-06-12 17:20:58 +05:30
// SPDX-License-Identifier: GPL-3.0-only
/*
2022-12-14 20:32:04 +05:30
* Prism Launcher - Minecraft Launcher
2022-06-12 17:20:58 +05:30
* Copyright ( C ) 2022 Sefa Eyeoglu < contact @ scrumplex . net >
2022-12-14 20:32:04 +05:30
* Copyright ( C ) 2022 TheKodeToad < TheKodeToad @ proton . me >
2013-02-20 04:37:52 +05:30
*
2022-06-12 17:20:58 +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-01-09 23:52:22 +05:30
*
2022-06-12 17:20:58 +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-03-12 02:49:17 +05:30
*
2022-06-12 17:20:58 +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/>.
2013-01-09 23:52:22 +05:30
*
2022-06-12 17:20:58 +05:30
* This file incorporates work covered by the following copyright and
* permission notice :
2013-02-20 04:37:52 +05:30
*
2022-06-12 17:20:58 +05:30
* Copyright 2013 - 2021 MultiMC Contributors
2013-01-09 23:52:22 +05:30
*
2022-06-12 17:20:58 +05:30
* Authors : Andrew Okin
* Peterix
* Orochimarufan < orochimarufan . x3 @ gmail . com >
2013-03-12 02:49:17 +05:30
*
2022-06-12 17:20:58 +05:30
* 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
2013-01-09 23:52:22 +05:30
*
2022-06-12 17:20:58 +05:30
* 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-01-09 23:52:22 +05:30
*/
2022-06-12 17:20:58 +05:30
2021-11-20 20:52:22 +05:30
# include "Application.h"
2014-04-06 07:29:37 +05:30
# include "BuildConfig.h"
2022-10-22 20:26:27 +05:30
# include "FileSystem.h"
2013-01-09 23:52:22 +05:30
2013-11-04 07:23:05 +05:30
# include "MainWindow.h"
2022-12-31 05:38:10 +05:30
# include "ui_MainWindow.h"
2015-03-02 02:50:57 +05:30
2022-05-02 22:40:45 +05:30
# include <QVariant>
# include <QUrl>
# include <QDir>
# include <QFileInfo>
# include <QKeyEvent>
# include <QAction>
2022-11-15 13:49:46 +05:30
# include <QActionGroup>
2022-05-02 22:40:45 +05:30
# include <QApplication>
# include <QButtonGroup>
# include <QHBoxLayout>
# include <QHeaderView>
# include <QMainWindow>
# include <QStatusBar>
# include <QToolBar>
# include <QWidget>
# include <QMenu>
# include <QMenuBar>
# include <QMessageBox>
2022-10-19 19:23:57 +05:30
# include <QFileDialog>
2022-05-02 22:40:45 +05:30
# include <QInputDialog>
# include <QLabel>
# include <QToolButton>
# include <QWidgetAction>
# include <QProgressDialog>
# include <QShortcut>
2015-10-20 20:48:53 +05:30
# include <BaseInstance.h>
# include <InstanceList.h>
2022-11-19 22:01:58 +05:30
# include <minecraft/MinecraftInstance.h>
2015-10-20 20:48:53 +05:30
# include <MMCZip.h>
# include <icons/IconList.h>
# include <java/JavaUtils.h>
2016-01-02 05:05:54 +05:30
# include <java/JavaInstallList.h>
2015-10-20 20:48:53 +05:30
# include <launch/LaunchTask.h>
2021-07-27 01:14:11 +05:30
# include <minecraft/auth/AccountList.h>
2016-04-10 07:59:29 +05:30
# include <SkinUtils.h>
2020-07-18 19:48:02 +05:30
# include <BuildConfig.h>
2015-10-20 20:48:53 +05:30
# include <net/NetJob.h>
2016-05-28 23:24:17 +05:30
# include <net/Download.h>
2022-02-10 17:25:07 +05:30
# include <news/NewsChecker.h>
2015-10-20 20:48:53 +05:30
# include <tools/BaseProfiler.h>
# include <updater/DownloadTask.h>
# include <updater/UpdateChecker.h>
2016-01-05 12:02:52 +05:30
# include <DesktopServices.h>
2016-08-06 19:09:29 +05:30
# include "InstanceWindow.h"
2015-10-20 20:48:53 +05:30
# include "InstancePageProvider.h"
# include "JavaCommon.h"
2016-08-11 04:14:01 +05:30
# include "LaunchController.h"
2021-11-22 08:25:16 +05:30
# include "ui/instanceview/InstanceProxyModel.h"
# include "ui/instanceview/InstanceView.h"
# include "ui/instanceview/InstanceDelegate.h"
# include "ui/widgets/LabeledToolButton.h"
# include "ui/dialogs/NewInstanceDialog.h"
2022-06-26 04:45:16 +05:30
# include "ui/dialogs/NewsDialog.h"
2021-11-22 08:25:16 +05:30
# include "ui/dialogs/ProgressDialog.h"
# include "ui/dialogs/AboutDialog.h"
# include "ui/dialogs/VersionSelectDialog.h"
# include "ui/dialogs/CustomMessageBox.h"
# include "ui/dialogs/IconPickerDialog.h"
# include "ui/dialogs/CopyInstanceDialog.h"
# include "ui/dialogs/UpdateDialog.h"
# include "ui/dialogs/EditAccountDialog.h"
# include "ui/dialogs/ExportInstanceDialog.h"
2022-12-31 06:36:17 +05:30
# include "ui/dialogs/ImportResourceDialog.h"
2022-11-15 04:29:26 +05:30
# include "ui/themes/ITheme.h"
2023-01-09 21:28:27 +05:30
# include "ui/themes/ThemeManager.h"
2021-11-22 08:25:16 +05:30
2022-12-31 06:36:17 +05:30
# include "minecraft/mod/tasks/LocalResourceParse.h"
# include "minecraft/mod/ModFolderModel.h"
# include "minecraft/WorldList.h"
2022-11-19 21:58:35 +05:30
2016-11-18 20:34:08 +05:30
# include "UpdateController.h"
2018-03-15 13:57:45 +05:30
# include "KonamiCode.h"
2021-11-22 08:25:16 +05:30
# include "InstanceImportTask.h"
# include "InstanceCopyTask.h"
2021-09-29 03:50:34 +05:30
# include "MMCTime.h"
2015-10-20 20:48:53 +05:30
2021-07-27 01:14:11 +05:30
namespace {
QString profileInUseFilter ( const QString & profile , bool used )
{
if ( used )
{
return QObject : : tr ( " %1 (in use) " ) . arg ( profile ) ;
}
else
{
return profile ;
}
}
}
2022-12-31 05:38:10 +05:30
MainWindow : : MainWindow ( QWidget * parent ) : QMainWindow ( parent ) , ui ( new Ui : : MainWindow )
2017-10-02 04:25:34 +05:30
{
2022-12-31 05:38:10 +05:30
ui - > setupUi ( this ) ;
2022-04-16 13:02:08 +05:30
2022-12-31 05:38:10 +05:30
// instance toolbar stuff
2022-04-16 13:02:08 +05:30
{
2022-12-31 05:38:10 +05:30
// Qt doesn't like vertical moving toolbars, so we have to force them...
// See https://github.com/PolyMC/PolyMC/issues/493
connect ( ui - > instanceToolBar , & QToolBar : : orientationChanged ,
[ = ] ( Qt : : Orientation ) { ui - > instanceToolBar - > setOrientation ( Qt : : Vertical ) ; } ) ;
2022-04-16 13:02:08 +05:30
2022-12-31 05:38:10 +05:30
// if you try to add a widget to a toolbar in a .ui file
// qt designer will delete it when you save the file >:(
changeIconButton = new LabeledToolButton ( this ) ;
2018-07-15 18:21:05 +05:30
changeIconButton - > setObjectName ( QStringLiteral ( " changeIconButton " ) ) ;
2021-11-20 20:52:22 +05:30
changeIconButton - > setIcon ( APPLICATION - > getThemedIcon ( " news " ) ) ;
2018-07-15 18:21:05 +05:30
changeIconButton - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Preferred ) ;
2022-12-31 05:38:10 +05:30
connect ( changeIconButton , & QToolButton : : clicked , this , & MainWindow : : on_actionChangeInstIcon_triggered ) ;
ui - > instanceToolBar - > insertWidgetBefore ( ui - > actionLaunchInstance , changeIconButton ) ;
2018-07-15 18:21:05 +05:30
2022-12-31 05:38:10 +05:30
renameButton = new LabeledToolButton ( this ) ;
2018-07-15 18:21:05 +05:30
renameButton - > setObjectName ( QStringLiteral ( " renameButton " ) ) ;
renameButton - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Preferred ) ;
2022-12-31 05:38:10 +05:30
connect ( renameButton , & QToolButton : : clicked , this , & MainWindow : : on_actionRenameInstance_triggered ) ;
ui - > instanceToolBar - > insertWidgetBefore ( ui - > actionLaunchInstance , renameButton ) ;
2018-07-15 18:21:05 +05:30
2022-12-31 05:38:10 +05:30
// restore the instance toolbar settings
auto const setting_name = QString ( " WideBarVisibility_%1 " ) . arg ( ui - > instanceToolBar - > objectName ( ) ) ;
if ( ! APPLICATION - > settings ( ) - > contains ( setting_name ) )
instanceToolbarSetting = APPLICATION - > settings ( ) - > registerSetting ( setting_name ) ;
else
instanceToolbarSetting = APPLICATION - > settings ( ) - > getSetting ( setting_name ) ;
2022-10-22 18:09:53 +05:30
2022-12-31 05:38:10 +05:30
ui - > instanceToolBar - > setVisibilityState ( instanceToolbarSetting - > get ( ) . toByteArray ( ) ) ;
2023-01-09 07:17:38 +05:30
2022-04-16 13:02:08 +05:30
}
2022-12-31 05:38:10 +05:30
// set the menu for the folders and help tool buttons
2022-04-16 13:02:08 +05:30
{
2022-12-31 05:38:10 +05:30
auto foldersMenuButton = dynamic_cast < QToolButton * > ( ui - > mainToolBar - > widgetForAction ( ui - > actionFoldersButton ) ) ;
foldersMenuButton - > setMenu ( ui - > foldersMenu ) ;
foldersMenuButton - > setPopupMode ( QToolButton : : InstantPopup ) ;
2018-07-15 18:21:05 +05:30
2022-12-31 05:38:10 +05:30
helpMenuButton = dynamic_cast < QToolButton * > ( ui - > mainToolBar - > widgetForAction ( ui - > actionHelpButton ) ) ;
helpMenuButton - > setMenu ( ui - > helpMenu ) ;
helpMenuButton - > setPopupMode ( QToolButton : : InstantPopup ) ;
2018-07-15 18:21:05 +05:30
}
2022-12-31 05:38:10 +05:30
// hide, disable and show stuff
2018-07-15 18:21:05 +05:30
{
2022-12-31 05:38:10 +05:30
ui - > actionReportBug - > setVisible ( ! BuildConfig . BUG_TRACKER_URL . isEmpty ( ) ) ;
ui - > actionMATRIX - > setVisible ( ! BuildConfig . MATRIX_URL . isEmpty ( ) ) ;
ui - > actionDISCORD - > setVisible ( ! BuildConfig . DISCORD_URL . isEmpty ( ) ) ;
ui - > actionREDDIT - > setVisible ( ! BuildConfig . SUBREDDIT_URL . isEmpty ( ) ) ;
2018-07-15 18:21:05 +05:30
2022-12-31 05:38:10 +05:30
ui - > actionCheckUpdate - > setVisible ( BuildConfig . UPDATER_ENABLED ) ;
2018-07-15 18:21:05 +05:30
2022-12-31 05:38:10 +05:30
ui - > actionAddToPATH - > setVisible ( false ) ;
# ifdef Q_OS_MAC
ui - > actionAddToPATH - > setVisible ( true ) ;
# endif
2022-05-09 09:12:37 +05:30
2022-12-31 05:38:10 +05:30
// disabled until we have an instance selected
ui - > instanceToolBar - > setEnabled ( false ) ;
ui - > actionKillInstance - > setEnabled ( false ) ;
ui - > actionLaunchInstance - > setEnabled ( false ) ;
setInstanceActionsEnabled ( false ) ;
}
2015-03-02 02:50:57 +05:30
2022-12-31 05:38:10 +05:30
// add the toolbar toggles to the view menu
ui - > viewMenu - > addAction ( ui - > instanceToolBar - > toggleViewAction ( ) ) ;
ui - > viewMenu - > addAction ( ui - > newsToolBar - > toggleViewAction ( ) ) ;
2018-07-15 18:21:05 +05:30
2022-12-31 05:38:10 +05:30
updateThemeMenu ( ) ;
updateMainToolBar ( ) ;
2018-07-15 18:21:05 +05:30
// OSX magic.
setUnifiedTitleAndToolBarOnMac ( true ) ;
// Global shortcuts
{
2022-12-31 05:38:10 +05:30
// you can't set QKeySequence::StandardKey shortcuts in qt designer >:(
ui - > actionAddInstance - > setShortcut ( QKeySequence : : New ) ;
ui - > actionSettings - > setShortcut ( QKeySequence : : Preferences ) ;
ui - > actionUndoTrashInstance - > setShortcut ( QKeySequence : : Undo ) ;
ui - > actionDeleteInstance - > setShortcuts ( { QKeySequence ( tr ( " Backspace " ) ) , QKeySequence : : Delete } ) ;
ui - > actionCloseWindow - > setShortcut ( QKeySequence : : Close ) ;
connect ( ui - > actionCloseWindow , & QAction : : triggered , APPLICATION , & Application : : closeCurrentWindow ) ;
2018-07-15 18:21:05 +05:30
// FIXME: This is kinda weird. and bad. We need some kind of managed shutdown.
auto q = new QShortcut ( QKeySequence : : Quit , this ) ;
2022-12-31 05:38:10 +05:30
connect ( q , & QShortcut : : activated , APPLICATION , & Application : : quit ) ;
2018-07-15 18:21:05 +05:30
}
// Konami Code
{
secretEventFilter = new KonamiCode ( this ) ;
connect ( secretEventFilter , & KonamiCode : : triggered , this , & MainWindow : : konamiTriggered ) ;
}
2022-02-10 17:25:07 +05:30
// Add the news label to the news toolbar.
{
m_newsChecker . reset ( new NewsChecker ( APPLICATION - > network ( ) , BuildConfig . NEWS_RSS_URL ) ) ;
2022-12-31 05:38:10 +05:30
newsLabel = dynamic_cast < QToolButton * > ( ui - > newsToolBar - > widgetForAction ( ui - > actionNewsLabel ) ) ;
//add a spacer before the more news button
QWidget * spacer = new QWidget ( ) ;
spacer - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
ui - > newsToolBar - > insertWidget ( ui - > actionMoreNews , spacer ) ;
2022-02-10 17:25:07 +05:30
QObject : : connect ( newsLabel , & QAbstractButton : : clicked , this , & MainWindow : : newsButtonClicked ) ;
QObject : : connect ( m_newsChecker . get ( ) , & NewsChecker : : newsLoaded , this , & MainWindow : : updateNewsLabel ) ;
updateNewsLabel ( ) ;
}
2018-07-15 18:21:05 +05:30
// Create the instance list widget
{
2021-10-26 03:21:42 +05:30
view = new InstanceView ( ui - > centralWidget ) ;
2018-07-15 18:21:05 +05:30
view - > setSelectionMode ( QAbstractItemView : : SingleSelection ) ;
// FIXME: leaks ListViewDelegate
view - > setItemDelegate ( new ListViewDelegate ( this ) ) ;
view - > setFrameShape ( QFrame : : NoFrame ) ;
// do not show ugly blue border on the mac
view - > setAttribute ( Qt : : WA_MacShowFocusRect , false ) ;
view - > installEventFilter ( this ) ;
view - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
connect ( view , & QWidget : : customContextMenuRequested , this , & MainWindow : : showInstanceContextMenu ) ;
2022-12-31 06:36:17 +05:30
connect ( view , & InstanceView : : droppedURLs , this , & MainWindow : : processURLs , Qt : : QueuedConnection ) ;
2018-07-15 18:21:05 +05:30
proxymodel = new InstanceProxyModel ( this ) ;
2021-11-20 20:52:22 +05:30
proxymodel - > setSourceModel ( APPLICATION - > instances ( ) . get ( ) ) ;
2018-07-15 18:21:05 +05:30
proxymodel - > sort ( 0 ) ;
connect ( proxymodel , & InstanceProxyModel : : dataChanged , this , & MainWindow : : instanceDataChanged ) ;
view - > setModel ( proxymodel ) ;
2019-08-20 06:28:27 +05:30
view - > setSourceOfGroupCollapseStatus ( [ ] ( const QString & groupName ) - > bool {
2021-11-20 20:52:22 +05:30
return APPLICATION - > instances ( ) - > isGroupCollapsed ( groupName ) ;
2019-08-20 06:28:27 +05:30
} ) ;
2021-11-20 20:52:22 +05:30
connect ( view , & InstanceView : : groupStateChanged , APPLICATION - > instances ( ) . get ( ) , & InstanceList : : on_GroupStateChanged ) ;
2018-07-15 18:21:05 +05:30
ui - > horizontalLayout - > addWidget ( view ) ;
}
// The cat background
{
2022-12-31 05:38:10 +05:30
// set the cat action priority here so you can still see the action in qt designer
ui - > actionCAT - > setPriority ( QAction : : LowPriority ) ;
2021-11-20 20:52:22 +05:30
bool cat_enable = APPLICATION - > settings ( ) - > get ( " TheCat " ) . toBool ( ) ;
2018-07-15 18:21:05 +05:30
ui - > actionCAT - > setChecked ( cat_enable ) ;
2022-12-31 05:38:10 +05:30
connect ( ui - > actionCAT , & QAction : : toggled , this , & MainWindow : : onCatToggled ) ;
2023-01-20 19:43:25 +05:30
connect ( APPLICATION , & Application : : currentCatChanged , this , & MainWindow : : onCatChanged ) ;
2018-07-15 18:21:05 +05:30
setCatBackground ( cat_enable ) ;
}
2022-10-26 03:52:11 +05:30
// Lock toolbars
{
bool toolbarsLocked = APPLICATION - > settings ( ) - > get ( " ToolbarsLocked " ) . toBool ( ) ;
ui - > actionLockToolbars - > setChecked ( toolbarsLocked ) ;
2022-11-06 02:40:36 +05:30
connect ( ui - > actionLockToolbars , & QAction : : toggled , this , & MainWindow : : lockToolbars ) ;
2022-10-26 03:52:11 +05:30
lockToolbars ( toolbarsLocked ) ;
}
2018-07-15 18:21:05 +05:30
// start instance when double-clicked
2021-10-26 03:21:42 +05:30
connect ( view , & InstanceView : : activated , this , & MainWindow : : instanceActivated ) ;
2018-07-15 18:21:05 +05:30
// track the selection -- update the instance toolbar
connect ( view - > selectionModel ( ) , & QItemSelectionModel : : currentChanged , this , & MainWindow : : instanceChanged ) ;
// track icon changes and update the toolbar!
2021-11-20 20:52:22 +05:30
connect ( APPLICATION - > icons ( ) . get ( ) , & IconList : : iconUpdated , this , & MainWindow : : iconUpdated ) ;
2018-07-15 18:21:05 +05:30
// model reset -> selection is invalid. All the instance pointers are wrong.
2021-11-20 20:52:22 +05:30
connect ( APPLICATION - > instances ( ) . get ( ) , & InstanceList : : dataIsInvalid , this , & MainWindow : : selectionBad ) ;
2018-07-15 18:21:05 +05:30
2019-06-17 19:43:52 +05:30
// handle newly added instances
2021-11-20 20:52:22 +05:30
connect ( APPLICATION - > instances ( ) . get ( ) , & InstanceList : : instanceSelectRequest , this , & MainWindow : : instanceSelectRequest ) ;
2019-06-17 19:43:52 +05:30
2019-06-01 15:58:53 +05:30
// When the global settings page closes, we want to know about it and update our state
2021-11-20 20:52:22 +05:30
connect ( APPLICATION , & Application : : globalSettingsClosed , this , & MainWindow : : globalSettingsClosed ) ;
2019-06-01 15:58:53 +05:30
2018-07-15 18:21:05 +05:30
m_statusLeft = new QLabel ( tr ( " No instance selected " ) , this ) ;
2021-10-02 03:50:25 +05:30
m_statusCenter = new QLabel ( tr ( " Total playtime: 0s " ) , this ) ;
2018-07-15 18:21:05 +05:30
statusBar ( ) - > addPermanentWidget ( m_statusLeft , 1 ) ;
2021-10-10 04:55:31 +05:30
statusBar ( ) - > addPermanentWidget ( m_statusCenter , 0 ) ;
2018-07-15 18:21:05 +05:30
// Add "manage accounts" button, right align
QWidget * spacer = new QWidget ( ) ;
spacer - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
2022-12-31 05:38:10 +05:30
ui - > mainToolBar - > insertWidget ( ui - > actionAccountsButton , spacer ) ;
2018-07-15 18:21:05 +05:30
accountMenu = new QMenu ( this ) ;
2022-05-09 12:50:53 +05:30
// Use undocumented property... https://stackoverflow.com/questions/7121718/create-a-scrollbar-in-a-submenu-qt
accountMenu - > setStyleSheet ( " QMenu { menu-scrollable: 1; } " ) ;
2018-07-15 18:21:05 +05:30
repopulateAccountsMenu ( ) ;
2022-12-31 05:38:10 +05:30
accountMenuButton = dynamic_cast < QToolButton * > ( ui - > mainToolBar - > widgetForAction ( ui - > actionAccountsButton ) ) ;
2018-07-15 18:21:05 +05:30
accountMenuButton - > setMenu ( accountMenu ) ;
accountMenuButton - > setPopupMode ( QToolButton : : InstantPopup ) ;
// Update the menu when the active account changes.
// Shouldn't have to use lambdas here like this, but if I don't, the compiler throws a fit.
// Template hell sucks...
2021-07-27 01:14:11 +05:30
connect (
2021-11-20 20:52:22 +05:30
APPLICATION - > accounts ( ) . get ( ) ,
& AccountList : : defaultAccountChanged ,
2021-07-27 01:14:11 +05:30
[ this ] {
2021-11-20 20:52:22 +05:30
defaultAccountChanged ( ) ;
2021-07-27 01:14:11 +05:30
}
) ;
connect (
2021-11-20 20:52:22 +05:30
APPLICATION - > accounts ( ) . get ( ) ,
2021-07-27 01:14:11 +05:30
& AccountList : : listChanged ,
[ this ]
{
repopulateAccountsMenu ( ) ;
}
) ;
2018-07-15 18:21:05 +05:30
// Show initial account
2021-11-20 20:52:22 +05:30
defaultAccountChanged ( ) ;
2018-07-15 18:21:05 +05:30
2021-07-27 01:14:11 +05:30
// TODO: refresh accounts here?
2021-11-20 20:52:22 +05:30
// auto accounts = APPLICATION->accounts();
2018-07-15 18:21:05 +05:30
2022-02-10 17:25:07 +05:30
// load the news
{
m_newsChecker - > reloadNews ( ) ;
updateNewsLabel ( ) ;
}
2018-07-15 18:21:05 +05:30
if ( BuildConfig . UPDATER_ENABLED )
{
2021-11-20 20:52:22 +05:30
bool updatesAllowed = APPLICATION - > updatesAreAllowed ( ) ;
2018-07-15 18:21:05 +05:30
updatesAllowedChanged ( updatesAllowed ) ;
2022-12-31 05:38:10 +05:30
connect ( ui - > actionCheckUpdate , & QAction : : triggered , this , & MainWindow : : checkForUpdates ) ;
2018-07-15 18:21:05 +05:30
// set up the updater object.
2021-11-20 20:52:22 +05:30
auto updater = APPLICATION - > updateChecker ( ) ;
2018-07-15 18:21:05 +05:30
connect ( updater . get ( ) , & UpdateChecker : : updateAvailable , this , & MainWindow : : updateAvailable ) ;
connect ( updater . get ( ) , & UpdateChecker : : noUpdateFound , this , & MainWindow : : updateNotAvailable ) ;
// if automatic update checks are allowed, start one.
2021-11-20 20:52:22 +05:30
if ( APPLICATION - > settings ( ) - > get ( " AutoUpdate " ) . toBool ( ) & & updatesAllowed )
2018-07-15 18:21:05 +05:30
{
2021-11-20 20:52:22 +05:30
updater - > checkForUpdate ( APPLICATION - > settings ( ) - > get ( " UpdateChannel " ) . toString ( ) , false ) ;
2018-07-15 18:21:05 +05:30
}
2022-04-21 08:04:13 +05:30
2022-04-26 05:03:17 +05:30
if ( APPLICATION - > updateChecker ( ) - > getExternalUpdater ( ) )
{
connect ( APPLICATION - > updateChecker ( ) - > getExternalUpdater ( ) ,
& ExternalUpdater : : canCheckForUpdatesChanged ,
this ,
& MainWindow : : updatesAllowedChanged ) ;
}
2018-07-15 18:21:05 +05:30
}
2022-12-31 05:38:10 +05:30
connect ( ui - > actionUndoTrashInstance , & QAction : : triggered , this , & MainWindow : : undoTrashInstance ) ;
2022-10-30 23:38:02 +05:30
2021-11-20 20:52:22 +05:30
setSelectedInstanceById ( APPLICATION - > settings ( ) - > get ( " SelectedInstance " ) . toString ( ) ) ;
2018-07-15 18:21:05 +05:30
// removing this looks stupid
view - > setFocus ( ) ;
2021-06-19 04:42:54 +05:30
retranslateUi ( ) ;
}
2022-04-09 01:51:52 +05:30
// macOS always has a native menu bar, so these fixes are not applicable
// Other systems may or may not have a native menu bar (most do not - it seems like only Ubuntu Unity does)
2022-04-09 02:30:42 +05:30
# ifndef Q_OS_MAC
2022-04-09 01:51:52 +05:30
void MainWindow : : keyReleaseEvent ( QKeyEvent * event )
{
2022-04-16 03:55:37 +05:30
if ( event - > key ( ) = = Qt : : Key_Alt & & ! APPLICATION - > settings ( ) - > get ( " MenuBarInsteadOfToolBar " ) . toBool ( ) )
2022-04-09 01:51:52 +05:30
ui - > menuBar - > setVisible ( ! ui - > menuBar - > isVisible ( ) ) ;
2022-04-09 02:30:42 +05:30
else
QMainWindow : : keyReleaseEvent ( event ) ;
2022-04-09 01:51:52 +05:30
}
# endif
2021-06-19 04:42:54 +05:30
void MainWindow : : retranslateUi ( )
{
2021-11-20 20:52:22 +05:30
auto accounts = APPLICATION - > accounts ( ) ;
MinecraftAccountPtr defaultAccount = accounts - > defaultAccount ( ) ;
if ( defaultAccount ) {
auto profileLabel = profileInUseFilter ( defaultAccount - > profileName ( ) , defaultAccount - > isInUse ( ) ) ;
2021-07-27 01:14:11 +05:30
accountMenuButton - > setText ( profileLabel ) ;
}
else {
2022-10-31 03:25:15 +05:30
accountMenuButton - > setText ( tr ( " Accounts " ) ) ;
2021-07-27 01:14:11 +05:30
}
2021-06-19 04:42:54 +05:30
if ( m_selectedInstance ) {
m_statusLeft - > setText ( m_selectedInstance - > getStatusbarDescription ( ) ) ;
} else {
m_statusLeft - > setText ( tr ( " No instance selected " ) ) ;
}
ui - > retranslateUi ( this ) ;
2022-12-31 05:38:10 +05:30
changeIconButton - > setToolTip ( ui - > actionChangeInstIcon - > toolTip ( ) ) ;
renameButton - > setToolTip ( ui - > actionRenameInstance - > toolTip ( ) ) ;
// replace the %1 with the launcher display name in some actions
if ( helpMenuButton - > toolTip ( ) . contains ( " %1 " ) )
helpMenuButton - > setToolTip ( helpMenuButton - > toolTip ( ) . arg ( BuildConfig . LAUNCHER_DISPLAYNAME ) ) ;
for ( auto action : ui - > helpMenu - > actions ( ) ) {
if ( action - > text ( ) . contains ( " %1 " ) )
action - > setText ( action - > text ( ) . arg ( BuildConfig . LAUNCHER_DISPLAYNAME ) ) ;
if ( action - > toolTip ( ) . contains ( " %1 " ) )
action - > setToolTip ( action - > toolTip ( ) . arg ( BuildConfig . LAUNCHER_DISPLAYNAME ) ) ;
}
2013-01-09 23:52:22 +05:30
}
MainWindow : : ~ MainWindow ( )
{
2013-03-12 02:49:17 +05:30
}
2019-07-16 05:00:09 +05:30
QMenu * MainWindow : : createPopupMenu ( )
{
QMenu * filteredMenu = QMainWindow : : createPopupMenu ( ) ;
filteredMenu - > removeAction ( ui - > mainToolBar - > toggleViewAction ( ) ) ;
2022-10-26 03:52:11 +05:30
filteredMenu - > addAction ( ui - > actionLockToolbars ) ;
2019-07-16 05:00:09 +05:30
return filteredMenu ;
}
2022-10-26 03:52:11 +05:30
void MainWindow : : lockToolbars ( bool state )
{
ui - > mainToolBar - > setMovable ( ! state ) ;
ui - > instanceToolBar - > setMovable ( ! state ) ;
ui - > newsToolBar - > setMovable ( ! state ) ;
APPLICATION - > settings ( ) - > set ( " ToolbarsLocked " , state ) ;
}
2019-07-16 05:00:09 +05:30
2018-03-15 13:57:45 +05:30
void MainWindow : : konamiTriggered ( )
{
2018-07-15 18:21:05 +05:30
qDebug ( ) < < " Super Secret Mode ACTIVATED! " ;
2018-03-15 13:57:45 +05:30
}
2014-01-27 07:30:49 +05:30
void MainWindow : : showInstanceContextMenu ( const QPoint & pos )
2014-01-05 05:36:59 +05:30
{
2018-07-15 18:21:05 +05:30
QList < QAction * > actions ;
QAction * actionSep = new QAction ( " " , this ) ;
actionSep - > setSeparator ( true ) ;
bool onInstance = view - > indexAt ( pos ) . isValid ( ) ;
if ( onInstance )
{
2022-12-31 05:38:10 +05:30
// reuse the file menu actions
actions = ui - > fileMenu - > actions ( ) ;
2018-07-15 18:21:05 +05:30
2022-12-31 05:38:10 +05:30
// remove the add instance action, launcher settings action and close action
actions . removeFirst ( ) ;
actions . removeLast ( ) ;
actions . removeLast ( ) ;
2018-07-15 18:21:05 +05:30
2022-12-31 05:38:10 +05:30
actions . prepend ( ui - > actionChangeInstIcon ) ;
actions . prepend ( ui - > actionRenameInstance ) ;
2018-07-15 18:21:05 +05:30
// add header
actions . prepend ( actionSep ) ;
QAction * actionVoid = new QAction ( m_selectedInstance - > name ( ) , this ) ;
actionVoid - > setEnabled ( false ) ;
actions . prepend ( actionVoid ) ;
}
else
{
auto group = view - > groupNameAt ( pos ) ;
2022-10-18 13:20:27 +05:30
QAction * actionVoid = new QAction ( BuildConfig . LAUNCHER_DISPLAYNAME , this ) ;
2018-07-15 18:21:05 +05:30
actionVoid - > setEnabled ( false ) ;
QAction * actionCreateInstance = new QAction ( tr ( " Create instance " ) , this ) ;
actionCreateInstance - > setToolTip ( ui - > actionAddInstance - > toolTip ( ) ) ;
if ( ! group . isNull ( ) )
{
QVariantMap data ;
data [ " group " ] = group ;
actionCreateInstance - > setData ( data ) ;
}
connect ( actionCreateInstance , SIGNAL ( triggered ( bool ) ) , SLOT ( on_actionAddInstance_triggered ( ) ) ) ;
actions . prepend ( actionSep ) ;
actions . prepend ( actionVoid ) ;
actions . append ( actionCreateInstance ) ;
if ( ! group . isNull ( ) )
{
QAction * actionDeleteGroup = new QAction ( tr ( " Delete group '%1' " ) . arg ( group ) , this ) ;
QVariantMap data ;
data [ " group " ] = group ;
actionDeleteGroup - > setData ( data ) ;
connect ( actionDeleteGroup , SIGNAL ( triggered ( bool ) ) , SLOT ( deleteGroup ( ) ) ) ;
actions . append ( actionDeleteGroup ) ;
}
}
QMenu myMenu ;
myMenu . addActions ( actions ) ;
/*
if ( onInstance )
myMenu . setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
*/
myMenu . exec ( view - > mapToGlobal ( pos ) ) ;
2014-01-05 05:36:59 +05:30
}
2022-04-16 03:55:37 +05:30
void MainWindow : : updateMainToolBar ( )
{
ui - > menuBar - > setVisible ( APPLICATION - > settings ( ) - > get ( " MenuBarInsteadOfToolBar " ) . toBool ( ) ) ;
ui - > mainToolBar - > setVisible ( ui - > menuBar - > isNativeMenuBar ( ) | | ! APPLICATION - > settings ( ) - > get ( " MenuBarInsteadOfToolBar " ) . toBool ( ) ) ;
}
2014-02-16 16:19:55 +05:30
void MainWindow : : updateToolsMenu ( )
{
2022-06-20 00:03:34 +05:30
bool currentInstanceRunning = m_selectedInstance & & m_selectedInstance - > isRunning ( ) ;
ui - > actionLaunchInstance - > setDisabled ( ! m_selectedInstance | | currentInstanceRunning ) ;
ui - > actionLaunchInstanceOffline - > setDisabled ( ! m_selectedInstance | | currentInstanceRunning ) ;
2022-07-12 00:16:11 +05:30
ui - > actionLaunchInstanceDemo - > setDisabled ( ! m_selectedInstance | | currentInstanceRunning ) ;
2018-07-15 18:21:05 +05:30
QMenu * launchMenu = ui - > actionLaunchInstance - > menu ( ) ;
if ( launchMenu )
{
launchMenu - > clear ( ) ;
}
else
{
launchMenu = new QMenu ( this ) ;
}
QAction * normalLaunch = launchMenu - > addAction ( tr ( " Launch " ) ) ;
2022-04-16 13:02:08 +05:30
normalLaunch - > setShortcut ( QKeySequence : : Open ) ;
2022-10-11 02:50:21 +05:30
QAction * normalLaunchOffline = launchMenu - > addAction ( tr ( " Launch Offline " ) ) ;
2022-04-16 13:02:08 +05:30
normalLaunchOffline - > setShortcut ( QKeySequence ( tr ( " Ctrl+Shift+O " ) ) ) ;
2022-10-11 02:50:21 +05:30
QAction * normalLaunchDemo = launchMenu - > addAction ( tr ( " Launch Demo " ) ) ;
2022-07-14 02:23:36 +05:30
normalLaunchDemo - > setShortcut ( QKeySequence ( tr ( " Ctrl+Alt+O " ) ) ) ;
2022-04-17 22:14:24 +05:30
if ( m_selectedInstance )
{
2022-06-20 00:03:34 +05:30
normalLaunch - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
normalLaunchOffline - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
2022-07-12 00:16:11 +05:30
normalLaunchDemo - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
2022-06-20 00:03:34 +05:30
2022-04-17 22:14:24 +05:30
connect ( normalLaunch , & QAction : : triggered , [ this ] ( ) {
2022-07-12 00:16:11 +05:30
APPLICATION - > launch ( m_selectedInstance , true , false ) ;
2022-04-17 22:14:24 +05:30
} ) ;
connect ( normalLaunchOffline , & QAction : : triggered , [ this ] ( ) {
2022-07-12 00:16:11 +05:30
APPLICATION - > launch ( m_selectedInstance , false , false ) ;
} ) ;
connect ( normalLaunchDemo , & QAction : : triggered , [ this ] ( ) {
APPLICATION - > launch ( m_selectedInstance , false , true ) ;
2022-04-17 22:14:24 +05:30
} ) ;
}
else
{
normalLaunch - > setDisabled ( true ) ;
normalLaunchOffline - > setDisabled ( true ) ;
2022-07-12 00:16:11 +05:30
normalLaunchDemo - > setDisabled ( true ) ;
2022-04-17 22:14:24 +05:30
}
2022-09-16 03:53:58 +05:30
// Disable demo-mode if not available.
auto instance = dynamic_cast < MinecraftInstance * > ( m_selectedInstance . get ( ) ) ;
if ( instance ) {
normalLaunchDemo - > setEnabled ( instance - > supportsDemo ( ) ) ;
}
2019-04-15 02:32:01 +05:30
QString profilersTitle = tr ( " Profilers " ) ;
launchMenu - > addSeparator ( ) - > setText ( profilersTitle ) ;
2021-11-20 20:52:22 +05:30
for ( auto profiler : APPLICATION - > profilers ( ) . values ( ) )
2018-07-15 18:21:05 +05:30
{
QAction * profilerAction = launchMenu - > addAction ( profiler - > name ( ) ) ;
2022-10-11 18:28:34 +05:30
QAction * profilerOfflineAction = launchMenu - > addAction ( tr ( " %1 Offline " ) . arg ( profiler - > name ( ) ) ) ;
2018-07-15 18:21:05 +05:30
QString error ;
if ( ! profiler - > check ( & error ) )
{
profilerAction - > setDisabled ( true ) ;
2019-04-15 04:12:06 +05:30
profilerOfflineAction - > setDisabled ( true ) ;
2019-04-15 02:32:01 +05:30
QString profilerToolTip = tr ( " Profiler not setup correctly. Go into settings, \" External Tools \" . " ) ;
profilerAction - > setToolTip ( profilerToolTip ) ;
profilerOfflineAction - > setToolTip ( profilerToolTip ) ;
2018-07-15 18:21:05 +05:30
}
2022-04-17 22:14:24 +05:30
else if ( m_selectedInstance )
2018-07-15 18:21:05 +05:30
{
2022-06-20 00:03:34 +05:30
profilerAction - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
profilerOfflineAction - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
2018-07-15 18:21:05 +05:30
connect ( profilerAction , & QAction : : triggered , [ this , profiler ] ( )
{
2022-07-12 00:16:11 +05:30
APPLICATION - > launch ( m_selectedInstance , true , false , profiler . get ( ) ) ;
2018-07-15 18:21:05 +05:30
} ) ;
2019-04-15 04:12:06 +05:30
connect ( profilerOfflineAction , & QAction : : triggered , [ this , profiler ] ( )
{
2022-07-12 00:16:11 +05:30
APPLICATION - > launch ( m_selectedInstance , false , false , profiler . get ( ) ) ;
} ) ;
2018-07-15 18:21:05 +05:30
}
2022-04-17 22:14:24 +05:30
else
{
profilerAction - > setDisabled ( true ) ;
profilerOfflineAction - > setDisabled ( true ) ;
}
2018-07-15 18:21:05 +05:30
}
ui - > actionLaunchInstance - > setMenu ( launchMenu ) ;
2014-02-16 16:19:55 +05:30
}
2022-11-15 01:03:25 +05:30
void MainWindow : : updateThemeMenu ( )
{
QMenu * themeMenu = ui - > actionChangeTheme - > menu ( ) ;
2022-11-15 14:08:31 +05:30
if ( themeMenu ) {
2022-11-15 01:03:25 +05:30
themeMenu - > clear ( ) ;
2022-11-15 14:08:31 +05:30
} else {
2022-11-15 01:03:25 +05:30
themeMenu = new QMenu ( this ) ;
}
2022-11-15 04:29:26 +05:30
auto themes = APPLICATION - > getValidApplicationThemes ( ) ;
2022-11-17 14:50:53 +05:30
QActionGroup * themesGroup = new QActionGroup ( this ) ;
2022-11-15 04:29:26 +05:30
2022-11-16 20:54:28 +05:30
for ( auto * theme : themes ) {
2022-11-15 04:29:26 +05:30
QAction * themeAction = themeMenu - > addAction ( theme - > name ( ) ) ;
themeAction - > setCheckable ( true ) ;
2022-11-15 14:08:31 +05:30
if ( APPLICATION - > settings ( ) - > get ( " ApplicationTheme " ) . toString ( ) = = theme - > id ( ) ) {
themeAction - > setChecked ( true ) ;
}
2022-11-17 15:09:05 +05:30
themeAction - > setActionGroup ( themesGroup ) ;
2022-11-15 04:29:26 +05:30
connect ( themeAction , & QAction : : triggered , [ theme ] ( ) {
2022-10-22 23:13:04 +05:30
APPLICATION - > setApplicationTheme ( theme - > id ( ) ) ;
2022-11-15 14:39:13 +05:30
APPLICATION - > settings ( ) - > set ( " ApplicationTheme " , theme - > id ( ) ) ;
2022-11-15 04:29:26 +05:30
} ) ;
}
2022-11-15 01:03:25 +05:30
ui - > actionChangeTheme - > setMenu ( themeMenu ) ;
}
2013-11-28 04:09:49 +05:30
void MainWindow : : repopulateAccountsMenu ( )
{
2018-07-15 18:21:05 +05:30
accountMenu - > clear ( ) ;
2022-12-31 05:38:10 +05:30
ui - > accountsMenu - > clear ( ) ;
2018-07-15 18:21:05 +05:30
2021-11-20 20:52:22 +05:30
auto accounts = APPLICATION - > accounts ( ) ;
MinecraftAccountPtr defaultAccount = accounts - > defaultAccount ( ) ;
2018-07-15 18:21:05 +05:30
2021-07-27 01:14:11 +05:30
QString active_profileId = " " ;
2021-11-20 20:52:22 +05:30
if ( defaultAccount )
2018-07-15 18:21:05 +05:30
{
// this can be called before accountMenuButton exists
2021-07-27 01:14:11 +05:30
if ( accountMenuButton )
2018-07-15 18:21:05 +05:30
{
2021-11-20 20:52:22 +05:30
auto profileLabel = profileInUseFilter ( defaultAccount - > profileName ( ) , defaultAccount - > isInUse ( ) ) ;
2018-07-15 18:21:05 +05:30
accountMenuButton - > setText ( profileLabel ) ;
}
}
if ( accounts - > count ( ) < = 0 )
{
2022-12-31 05:38:10 +05:30
ui - > actionNoAccountsAdded - > setText ( " No accounts added! " ) ;
2022-05-09 08:49:23 +05:30
ui - > actionNoAccountsAdded - > setEnabled ( false ) ;
accountMenu - > addAction ( ui - > actionNoAccountsAdded ) ;
2022-12-31 05:38:10 +05:30
ui - > accountsMenu - > addAction ( ui - > actionNoAccountsAdded ) ;
2018-07-15 18:21:05 +05:30
}
else
{
// TODO: Nicer way to iterate?
for ( int i = 0 ; i < accounts - > count ( ) ; i + + )
{
2021-07-27 01:14:11 +05:30
MinecraftAccountPtr account = accounts - > at ( i ) ;
auto profileLabel = profileInUseFilter ( account - > profileName ( ) , account - > isInUse ( ) ) ;
QAction * action = new QAction ( profileLabel , this ) ;
2021-11-10 07:32:51 +05:30
action - > setData ( i ) ;
2021-07-27 01:14:11 +05:30
action - > setCheckable ( true ) ;
2021-11-20 20:52:22 +05:30
if ( defaultAccount = = account )
2018-07-15 18:21:05 +05:30
{
2021-07-27 01:14:11 +05:30
action - > setChecked ( true ) ;
2018-07-15 18:21:05 +05:30
}
2021-07-27 01:14:11 +05:30
2021-11-10 07:32:51 +05:30
auto face = account - > getFace ( ) ;
if ( ! face . isNull ( ) ) {
action - > setIcon ( face ) ;
}
else {
2021-11-20 20:52:22 +05:30
action - > setIcon ( APPLICATION - > getThemedIcon ( " noaccount " ) ) ;
2021-11-10 07:32:51 +05:30
}
2022-04-16 05:25:49 +05:30
const int highestNumberKey = 9 ;
if ( i < highestNumberKey )
{
action - > setShortcut ( QKeySequence ( tr ( " Ctrl+%1 " ) . arg ( i + 1 ) ) ) ;
}
2021-07-27 01:14:11 +05:30
accountMenu - > addAction ( action ) ;
2022-12-31 05:38:10 +05:30
ui - > accountsMenu - > addAction ( action ) ;
2021-07-27 01:14:11 +05:30
connect ( action , SIGNAL ( triggered ( bool ) ) , SLOT ( changeActiveAccount ( ) ) ) ;
2018-07-15 18:21:05 +05:30
}
}
accountMenu - > addSeparator ( ) ;
2022-12-31 05:38:10 +05:30
ui - > accountsMenu - > addSeparator ( ) ;
2018-07-15 18:21:05 +05:30
2022-12-31 05:38:10 +05:30
ui - > actionNoDefaultAccount = new QAction ( this ) ;
2022-05-09 08:49:23 +05:30
ui - > actionNoDefaultAccount - > setObjectName ( QStringLiteral ( " actionNoDefaultAccount " ) ) ;
2022-12-31 05:38:10 +05:30
ui - > actionNoDefaultAccount - > setText ( " No Default Account " ) ;
2022-05-09 08:49:23 +05:30
ui - > actionNoDefaultAccount - > setCheckable ( true ) ;
ui - > actionNoDefaultAccount - > setIcon ( APPLICATION - > getThemedIcon ( " noaccount " ) ) ;
ui - > actionNoDefaultAccount - > setData ( - 1 ) ;
ui - > actionNoDefaultAccount - > setShortcut ( QKeySequence ( tr ( " Ctrl+0 " ) ) ) ;
2021-11-20 20:52:22 +05:30
if ( ! defaultAccount ) {
2022-05-09 08:49:23 +05:30
ui - > actionNoDefaultAccount - > setChecked ( true ) ;
2018-07-15 18:21:05 +05:30
}
2022-05-09 08:49:23 +05:30
accountMenu - > addAction ( ui - > actionNoDefaultAccount ) ;
2022-12-31 05:38:10 +05:30
ui - > accountsMenu - > addAction ( ui - > actionNoDefaultAccount ) ;
2022-05-09 08:49:23 +05:30
connect ( ui - > actionNoDefaultAccount , SIGNAL ( triggered ( bool ) ) , SLOT ( changeActiveAccount ( ) ) ) ;
2018-07-15 18:21:05 +05:30
accountMenu - > addSeparator ( ) ;
2022-12-31 05:38:10 +05:30
ui - > accountsMenu - > addSeparator ( ) ;
2018-07-15 18:21:05 +05:30
accountMenu - > addAction ( ui - > actionManageAccounts ) ;
2022-12-31 05:38:10 +05:30
ui - > accountsMenu - > addAction ( ui - > actionManageAccounts ) ;
2013-11-28 04:09:49 +05:30
}
2017-05-02 05:13:18 +05:30
void MainWindow : : updatesAllowedChanged ( bool allowed )
{
2018-07-15 18:21:05 +05:30
if ( ! BuildConfig . UPDATER_ENABLED )
{
return ;
}
ui - > actionCheckUpdate - > setEnabled ( allowed ) ;
2017-05-02 05:13:18 +05:30
}
2013-11-28 04:09:49 +05:30
/*
* Assumes the sender is a QAction
*/
void MainWindow : : changeActiveAccount ( )
{
2018-07-15 18:21:05 +05:30
QAction * sAction = ( QAction * ) sender ( ) ;
2021-11-10 07:32:51 +05:30
2018-07-15 18:21:05 +05:30
// Profile's associated Mojang username
2021-11-10 07:32:51 +05:30
if ( sAction - > data ( ) . type ( ) ! = QVariant : : Type : : Int )
2018-07-15 18:21:05 +05:30
return ;
2013-11-28 04:09:49 +05:30
2018-07-15 18:21:05 +05:30
QVariant data = sAction - > data ( ) ;
2021-11-10 07:32:51 +05:30
bool valid = false ;
int index = data . toInt ( & valid ) ;
if ( ! valid ) {
index = - 1 ;
2018-07-15 18:21:05 +05:30
}
2021-11-20 20:52:22 +05:30
auto accounts = APPLICATION - > accounts ( ) ;
accounts - > setDefaultAccount ( index = = - 1 ? nullptr : accounts - > at ( index ) ) ;
defaultAccountChanged ( ) ;
2013-11-28 04:09:49 +05:30
}
2021-11-20 20:52:22 +05:30
void MainWindow : : defaultAccountChanged ( )
2013-11-27 22:26:15 +05:30
{
2018-07-15 18:21:05 +05:30
repopulateAccountsMenu ( ) ;
2013-11-28 04:09:49 +05:30
2021-11-20 20:52:22 +05:30
MinecraftAccountPtr account = APPLICATION - > accounts ( ) - > defaultAccount ( ) ;
2013-11-27 22:26:15 +05:30
2021-07-27 01:14:11 +05:30
// FIXME: this needs adjustment for MSA
2021-11-20 20:52:22 +05:30
if ( account & & account - > profileName ( ) ! = " " )
2018-07-15 18:21:05 +05:30
{
2021-07-27 01:14:11 +05:30
auto profileLabel = profileInUseFilter ( account - > profileName ( ) , account - > isInUse ( ) ) ;
accountMenuButton - > setText ( profileLabel ) ;
2021-11-10 07:32:51 +05:30
auto face = account - > getFace ( ) ;
if ( face . isNull ( ) ) {
2021-11-20 20:52:22 +05:30
accountMenuButton - > setIcon ( APPLICATION - > getThemedIcon ( " noaccount " ) ) ;
2021-11-10 07:32:51 +05:30
}
else {
accountMenuButton - > setIcon ( face ) ;
}
2021-07-27 01:14:11 +05:30
return ;
2018-07-15 18:21:05 +05:30
}
2013-11-28 04:09:49 +05:30
2018-07-15 18:21:05 +05:30
// Set the icon to the "no account" icon.
2021-11-20 20:52:22 +05:30
accountMenuButton - > setIcon ( APPLICATION - > getThemedIcon ( " noaccount " ) ) ;
2022-10-31 03:25:15 +05:30
accountMenuButton - > setText ( tr ( " Accounts " ) ) ;
2013-11-27 22:26:15 +05:30
}
2013-10-06 04:43:40 +05:30
bool MainWindow : : eventFilter ( QObject * obj , QEvent * ev )
2013-08-12 04:09:19 +05:30
{
2018-07-15 18:21:05 +05:30
if ( obj = = view )
{
if ( ev - > type ( ) = = QEvent : : KeyPress )
{
secretEventFilter - > input ( ev ) ;
QKeyEvent * keyEvent = static_cast < QKeyEvent * > ( ev ) ;
switch ( keyEvent - > key ( ) )
{
2018-11-22 06:20:32 +05:30
/*
2018-07-15 18:21:05 +05:30
case Qt : : Key_Enter :
case Qt : : Key_Return :
activateInstance ( m_selectedInstance ) ;
return true ;
2018-11-22 06:20:32 +05:30
*/
2018-07-15 18:21:05 +05:30
case Qt : : Key_Delete :
on_actionDeleteInstance_triggered ( ) ;
return true ;
case Qt : : Key_F5 :
refreshInstances ( ) ;
return true ;
case Qt : : Key_F2 :
on_actionRenameInstance_triggered ( ) ;
return true ;
default :
break ;
}
}
}
return QMainWindow : : eventFilter ( obj , ev ) ;
2013-08-12 04:09:19 +05:30
}
2022-02-10 17:25:07 +05:30
void MainWindow : : updateNewsLabel ( )
{
if ( m_newsChecker - > isLoadingNews ( ) )
{
newsLabel - > setText ( tr ( " Loading news... " ) ) ;
newsLabel - > setEnabled ( false ) ;
2022-08-13 02:03:10 +05:30
ui - > actionMoreNews - > setVisible ( false ) ;
2022-02-10 17:25:07 +05:30
}
else
{
QList < NewsEntryPtr > entries = m_newsChecker - > getNewsEntries ( ) ;
if ( entries . length ( ) > 0 )
{
newsLabel - > setText ( entries [ 0 ] - > title ) ;
newsLabel - > setEnabled ( true ) ;
2022-08-13 02:03:10 +05:30
ui - > actionMoreNews - > setVisible ( true ) ;
2022-02-10 17:25:07 +05:30
}
else
{
newsLabel - > setText ( tr ( " No news available. " ) ) ;
newsLabel - > setEnabled ( false ) ;
2022-08-13 02:03:10 +05:30
ui - > actionMoreNews - > setVisible ( false ) ;
2022-02-10 17:25:07 +05:30
}
}
}
2015-02-08 22:26:14 +05:30
void MainWindow : : updateAvailable ( GoUpdate : : Status status )
2013-12-02 05:25:24 +05:30
{
2021-11-20 20:52:22 +05:30
if ( ! APPLICATION - > updatesAreAllowed ( ) )
2018-07-15 18:21:05 +05:30
{
updateNotAvailable ( ) ;
return ;
}
UpdateDialog dlg ( true , this ) ;
UpdateAction action = ( UpdateAction ) dlg . exec ( ) ;
switch ( action )
{
case UPDATE_LATER :
qDebug ( ) < < " Update will be installed later. " ;
break ;
case UPDATE_NOW :
downloadUpdates ( status ) ;
break ;
}
2013-12-02 05:25:24 +05:30
}
2014-07-14 04:27:54 +05:30
void MainWindow : : updateNotAvailable ( )
{
2018-07-15 18:21:05 +05:30
UpdateDialog dlg ( false , this ) ;
dlg . exec ( ) ;
2014-07-14 04:27:54 +05:30
}
2014-01-03 23:49:27 +05:30
QList < int > stringToIntList ( const QString & string )
{
2022-05-02 22:40:45 +05:30
# if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
QStringList split = string . split ( ' , ' , Qt : : SkipEmptyParts ) ;
# else
2018-07-15 18:21:05 +05:30
QStringList split = string . split ( ' , ' , QString : : SkipEmptyParts ) ;
2022-05-02 22:40:45 +05:30
# endif
2018-07-15 18:21:05 +05:30
QList < int > out ;
for ( int i = 0 ; i < split . size ( ) ; + + i )
{
out . append ( split . at ( i ) . toInt ( ) ) ;
}
return out ;
2014-01-03 23:49:27 +05:30
}
QString intListToString ( const QList < int > & list )
{
2018-07-15 18:21:05 +05:30
QStringList slist ;
for ( int i = 0 ; i < list . size ( ) ; + + i )
{
slist . append ( QString : : number ( list . at ( i ) ) ) ;
}
return slist . join ( ' , ' ) ;
2014-01-03 23:49:27 +05:30
}
2015-06-08 03:12:22 +05:30
void MainWindow : : downloadUpdates ( GoUpdate : : Status status )
2013-12-07 00:29:58 +05:30
{
2021-11-20 20:52:22 +05:30
if ( ! APPLICATION - > updatesAreAllowed ( ) )
2018-07-15 18:21:05 +05:30
{
return ;
}
qDebug ( ) < < " Downloading updates. " ;
ProgressDialog updateDlg ( this ) ;
2021-11-20 20:52:22 +05:30
status . rootPath = APPLICATION - > root ( ) ;
2018-07-15 18:21:05 +05:30
2021-11-20 20:52:22 +05:30
auto dlPath = FS : : PathCombine ( APPLICATION - > root ( ) , " update " , " XXXXXX " ) ;
2018-07-15 18:21:05 +05:30
if ( ! FS : : ensureFilePathExists ( dlPath ) )
{
CustomMessageBox : : selectable ( this , tr ( " Error " ) , tr ( " Couldn't create folder for update downloads: \n %1 " ) . arg ( dlPath ) , QMessageBox : : Warning ) - > show ( ) ;
}
2021-11-22 03:51:12 +05:30
GoUpdate : : DownloadTask updateTask ( APPLICATION - > network ( ) , status , dlPath , & updateDlg ) ;
2018-07-15 18:21:05 +05:30
// If the task succeeds, install the updates.
if ( updateDlg . execWithTask ( & updateTask ) )
{
/**
* NOTE : This disables launching instances until the update either succeeds ( and this process exits )
* or the update fails ( and the control leaves this scope ) .
*/
2021-11-20 20:52:22 +05:30
APPLICATION - > updateIsRunning ( true ) ;
UpdateController update ( this , APPLICATION - > root ( ) , updateTask . updateFilesDir ( ) , updateTask . operations ( ) ) ;
2018-07-15 18:21:05 +05:30
update . installUpdates ( ) ;
2021-11-20 20:52:22 +05:30
APPLICATION - > updateIsRunning ( false ) ;
2018-07-15 18:21:05 +05:30
}
else
{
CustomMessageBox : : selectable ( this , tr ( " Error " ) , updateTask . failReason ( ) , QMessageBox : : Warning ) - > show ( ) ;
}
2013-12-07 00:29:58 +05:30
}
2013-10-06 04:43:40 +05:30
void MainWindow : : onCatToggled ( bool state )
2013-08-26 02:18:41 +05:30
{
2018-07-15 18:21:05 +05:30
setCatBackground ( state ) ;
2021-11-20 20:52:22 +05:30
APPLICATION - > settings ( ) - > set ( " TheCat " , state ) ;
2013-08-26 02:18:41 +05:30
}
2013-10-06 04:43:40 +05:30
void MainWindow : : setCatBackground ( bool enabled )
2013-08-26 02:18:41 +05:30
{
2023-01-09 21:28:27 +05:30
if ( enabled ) {
2018-12-24 07:56:14 +05:30
view - > setStyleSheet ( QString ( R " (
2021-10-26 03:21:42 +05:30
InstanceView
2018-07-24 04:12:18 +05:30
{
2018-12-24 07:56:14 +05:30
background - image : url ( : / backgrounds / % 1 ) ;
2018-07-24 04:12:18 +05:30
background - attachment : fixed ;
background - clip : padding ;
2022-12-14 13:06:35 +05:30
background - position : bottom right ;
2018-07-24 04:12:18 +05:30
background - repeat : none ;
background - color : palette ( base ) ;
2022-11-02 03:36:27 +05:30
} ) " )
2023-01-09 21:28:27 +05:30
. arg ( ThemeManager : : getCatImage ( ) ) ) ;
} else {
2018-07-15 18:21:05 +05:30
view - > setStyleSheet ( QString ( ) ) ;
}
2013-08-26 02:18:41 +05:30
}
2016-10-03 04:25:54 +05:30
void MainWindow : : runModalTask ( Task * task )
2015-01-28 03:01:07 +05:30
{
2018-07-15 18:21:05 +05:30
connect ( task , & Task : : failed , [ this ] ( QString reason )
{
CustomMessageBox : : selectable ( this , tr ( " Error " ) , reason , QMessageBox : : Critical ) - > show ( ) ;
} ) ;
connect ( task , & Task : : succeeded , [ this , task ] ( )
{
QStringList warnings = task - > warnings ( ) ;
if ( warnings . count ( ) )
{
CustomMessageBox : : selectable ( this , tr ( " Warnings " ) , warnings . join ( ' \n ' ) , QMessageBox : : Warning ) - > show ( ) ;
}
} ) ;
2022-07-29 00:28:04 +05:30
connect ( task , & Task : : aborted , [ this ]
{
CustomMessageBox : : selectable ( this , tr ( " Task aborted " ) , tr ( " The task has been aborted by the user. " ) , QMessageBox : : Information ) - > show ( ) ;
} ) ;
2018-07-15 18:21:05 +05:30
ProgressDialog loadDialog ( this ) ;
loadDialog . setSkipButton ( true , tr ( " Abort " ) ) ;
loadDialog . execWithTask ( task ) ;
2016-10-03 04:25:54 +05:30
}
2015-02-13 02:31:20 +05:30
2018-03-19 07:06:12 +05:30
void MainWindow : : instanceFromInstanceTask ( InstanceTask * rawTask )
2016-10-03 04:25:54 +05:30
{
2021-11-20 20:52:22 +05:30
unique_qobject_ptr < Task > task ( APPLICATION - > instances ( ) - > wrapInstanceTask ( rawTask ) ) ;
2018-07-15 18:21:05 +05:30
runModalTask ( task . get ( ) ) ;
2018-03-01 00:12:30 +05:30
}
2016-10-03 04:25:54 +05:30
void MainWindow : : on_actionCopyInstance_triggered ( )
2015-01-28 03:01:07 +05:30
{
2018-07-15 18:21:05 +05:30
if ( ! m_selectedInstance )
return ;
2015-02-01 07:38:25 +05:30
2018-07-15 18:21:05 +05:30
CopyInstanceDialog copyInstDlg ( m_selectedInstance , this ) ;
if ( ! copyInstDlg . exec ( ) )
return ;
2015-01-28 03:01:07 +05:30
2022-10-23 08:34:36 +05:30
auto copyTask = new InstanceCopyTask ( m_selectedInstance , copyInstDlg . getChosenOptions ( ) ) ;
2018-07-15 18:21:05 +05:30
copyTask - > setName ( copyInstDlg . instName ( ) ) ;
copyTask - > setGroup ( copyInstDlg . instGroup ( ) ) ;
copyTask - > setIcon ( copyInstDlg . iconKey ( ) ) ;
2021-11-20 20:52:22 +05:30
unique_qobject_ptr < Task > task ( APPLICATION - > instances ( ) - > wrapInstanceTask ( copyTask ) ) ;
2018-07-15 18:21:05 +05:30
runModalTask ( task . get ( ) ) ;
2015-01-28 03:01:07 +05:30
}
2015-02-13 02:31:20 +05:30
2015-01-28 03:01:07 +05:30
void MainWindow : : finalizeInstance ( InstancePtr inst )
{
2018-07-15 18:21:05 +05:30
view - > updateGeometries ( ) ;
setSelectedInstanceById ( inst - > id ( ) ) ;
2021-11-20 20:52:22 +05:30
if ( APPLICATION - > accounts ( ) - > anyAccountIsValid ( ) )
2018-07-15 18:21:05 +05:30
{
ProgressDialog loadDialog ( this ) ;
auto update = inst - > createUpdateTask ( Net : : Mode : : Online ) ;
connect ( update . get ( ) , & Task : : failed , [ this ] ( QString reason )
{
QString error = QString ( " Instance load failed: %1 " ) . arg ( reason ) ;
CustomMessageBox : : selectable ( this , tr ( " Error " ) , error , QMessageBox : : Warning ) - > show ( ) ;
} ) ;
if ( update )
{
loadDialog . setSkipButton ( true , tr ( " Abort " ) ) ;
loadDialog . execWithTask ( update . get ( ) ) ;
}
}
else
{
2021-10-18 04:17:02 +05:30
CustomMessageBox : : selectable (
this ,
tr ( " Error " ) ,
tr ( " The launcher cannot download Minecraft or update instances unless you have at least "
" one account added. \n Please add your Mojang or Minecraft account. " ) ,
QMessageBox : : Warning
) - > show ( ) ;
2018-07-15 18:21:05 +05:30
}
2013-01-09 23:52:22 +05:30
}
2017-04-22 09:41:26 +05:30
void MainWindow : : addInstance ( QString url )
2015-01-28 03:01:07 +05:30
{
2018-07-15 18:21:05 +05:30
QString groupName ;
do
{
QObject * obj = sender ( ) ;
if ( ! obj )
break ;
QAction * action = qobject_cast < QAction * > ( obj ) ;
if ( ! action )
break ;
auto map = action - > data ( ) . toMap ( ) ;
if ( ! map . contains ( " group " ) )
break ;
groupName = map [ " group " ] . toString ( ) ;
} while ( 0 ) ;
if ( groupName . isEmpty ( ) )
{
2021-11-20 20:52:22 +05:30
groupName = APPLICATION - > settings ( ) - > get ( " LastUsedGroupForNewInstance " ) . toString ( ) ;
2018-07-15 18:21:05 +05:30
}
NewInstanceDialog newInstDlg ( groupName , url , this ) ;
if ( ! newInstDlg . exec ( ) )
return ;
2021-11-20 20:52:22 +05:30
APPLICATION - > settings ( ) - > set ( " LastUsedGroupForNewInstance " , newInstDlg . instGroup ( ) ) ;
2018-07-15 18:21:05 +05:30
InstanceTask * creationTask = newInstDlg . extractTask ( ) ;
if ( creationTask )
{
instanceFromInstanceTask ( creationTask ) ;
}
2015-01-28 03:01:07 +05:30
}
2017-04-22 09:41:26 +05:30
void MainWindow : : on_actionAddInstance_triggered ( )
{
2018-07-15 18:21:05 +05:30
addInstance ( ) ;
2017-04-22 09:41:26 +05:30
}
2022-12-31 06:36:17 +05:30
void MainWindow : : processURLs ( QList < QUrl > urls )
2017-04-22 09:41:26 +05:30
{
2022-11-27 23:08:56 +05:30
// NOTE: This loop only processes one dropped file!
2022-11-19 21:58:35 +05:30
for ( auto & url : urls ) {
2023-01-14 01:41:20 +05:30
qDebug ( ) < < " Processing " < < url ;
2022-12-31 06:36:17 +05:30
2022-12-02 07:24:03 +05:30
// The isLocalFile() check below doesn't work as intended without an explicit scheme.
if ( url . scheme ( ) . isEmpty ( ) )
url . setScheme ( " file " ) ;
2022-11-27 23:08:56 +05:30
if ( ! url . isLocalFile ( ) ) { // probably instance/modpack
2018-07-15 18:21:05 +05:30
addInstance ( url . toString ( ) ) ;
2022-11-27 23:08:56 +05:30
break ;
2018-07-15 18:21:05 +05:30
}
2022-11-19 21:58:35 +05:30
2023-01-02 21:25:32 +05:30
auto localFileName = QDir : : toNativeSeparators ( url . toLocalFile ( ) ) ;
2022-11-27 23:08:56 +05:30
QFileInfo localFileInfo ( localFileName ) ;
2022-12-31 06:36:17 +05:30
auto type = ResourceUtils : : identify ( localFileInfo ) ;
2022-11-27 23:08:56 +05:30
2023-01-14 01:41:20 +05:30
if ( ResourceUtils : : ValidResourceTypes . count ( type ) = = 0 ) { // probably instance/modpack
2022-11-27 23:08:56 +05:30
addInstance ( localFileName ) ;
2022-12-31 06:36:17 +05:30
continue ;
2022-11-27 23:08:56 +05:30
}
2022-12-31 06:36:17 +05:30
ImportResourceDialog dlg ( localFileName , type , this ) ;
2022-11-27 23:08:56 +05:30
if ( dlg . exec ( ) ! = QDialog : : Accepted )
2022-12-31 06:36:17 +05:30
continue ;
2022-11-27 23:08:56 +05:30
2022-12-31 06:36:17 +05:30
qDebug ( ) < < " Adding resource " < < localFileName < < " to " < < dlg . selectedInstanceKey ;
2022-11-27 23:08:56 +05:30
auto inst = APPLICATION - > instances ( ) - > getInstanceById ( dlg . selectedInstanceKey ) ;
auto minecraftInst = std : : dynamic_pointer_cast < MinecraftInstance > ( inst ) ;
2022-12-31 06:36:17 +05:30
switch ( type ) {
case PackedResourceType : : ResourcePack :
2022-12-31 07:57:26 +05:30
minecraftInst - > resourcePackList ( ) - > installResource ( localFileName ) ;
break ;
2022-12-31 06:36:17 +05:30
case PackedResourceType : : TexturePack :
2022-12-31 07:57:26 +05:30
minecraftInst - > texturePackList ( ) - > installResource ( localFileName ) ;
break ;
2022-12-31 06:36:17 +05:30
case PackedResourceType : : DataPack :
2022-12-31 07:57:26 +05:30
qWarning ( ) < < " Importing of Data Packs not supported at this time. Ignoring " < < localFileName ;
break ;
2022-12-31 06:36:17 +05:30
case PackedResourceType : : Mod :
2022-12-31 07:57:26 +05:30
minecraftInst - > loaderModList ( ) - > installMod ( localFileName ) ;
break ;
2022-12-31 06:36:17 +05:30
case PackedResourceType : : ShaderPack :
2022-12-31 07:57:26 +05:30
minecraftInst - > shaderPackList ( ) - > installResource ( localFileName ) ;
break ;
2022-12-31 06:36:17 +05:30
case PackedResourceType : : WorldSave :
2022-12-31 07:57:26 +05:30
minecraftInst - > worldList ( ) - > installWorld ( localFileInfo ) ;
break ;
2022-12-31 06:36:17 +05:30
case PackedResourceType : : UNKNOWN :
default :
2022-12-31 07:57:26 +05:30
qDebug ( ) < < " Can't Identify " < < localFileName < < " Ignoring it. " ;
break ;
2022-12-31 06:36:17 +05:30
}
2018-07-15 18:21:05 +05:30
}
2017-04-22 09:41:26 +05:30
}
2015-09-16 02:32:21 +05:30
void MainWindow : : on_actionREDDIT_triggered ( )
{
2021-06-18 16:54:20 +05:30
DesktopServices : : openUrl ( QUrl ( BuildConfig . SUBREDDIT_URL ) ) ;
2015-09-16 02:32:21 +05:30
}
2016-01-09 06:09:51 +05:30
void MainWindow : : on_actionDISCORD_triggered ( )
{
2021-06-18 16:54:20 +05:30
DesktopServices : : openUrl ( QUrl ( BuildConfig . DISCORD_URL ) ) ;
2016-01-09 06:09:51 +05:30
}
2022-03-08 23:11:23 +05:30
void MainWindow : : on_actionMATRIX_triggered ( )
{
DesktopServices : : openUrl ( QUrl ( BuildConfig . MATRIX_URL ) ) ;
}
2013-08-10 22:04:08 +05:30
void MainWindow : : on_actionChangeInstIcon_triggered ( )
2013-03-19 10:54:34 +05:30
{
2018-07-15 18:21:05 +05:30
if ( ! m_selectedInstance )
return ;
2013-10-06 04:43:40 +05:30
2018-07-15 18:21:05 +05:30
IconPickerDialog dlg ( this ) ;
dlg . execWithSelection ( m_selectedInstance - > iconKey ( ) ) ;
if ( dlg . result ( ) = = QDialog : : Accepted )
{
m_selectedInstance - > setIconKey ( dlg . selectedIconKey ) ;
2021-11-20 20:52:22 +05:30
auto icon = APPLICATION - > icons ( ) - > getIcon ( dlg . selectedIconKey ) ;
2018-07-15 18:21:05 +05:30
ui - > actionChangeInstIcon - > setIcon ( icon ) ;
2022-12-31 05:38:10 +05:30
changeIconButton - > setIcon ( icon ) ;
2018-07-15 18:21:05 +05:30
}
2013-03-19 10:54:34 +05:30
}
2013-12-31 05:54:28 +05:30
void MainWindow : : iconUpdated ( QString icon )
{
2018-07-15 18:21:05 +05:30
if ( icon = = m_currentInstIcon )
{
2021-11-20 20:52:22 +05:30
auto icon = APPLICATION - > icons ( ) - > getIcon ( m_currentInstIcon ) ;
2018-07-15 18:21:05 +05:30
ui - > actionChangeInstIcon - > setIcon ( icon ) ;
2022-12-31 05:38:10 +05:30
changeIconButton - > setIcon ( icon ) ;
2018-07-15 18:21:05 +05:30
}
2013-03-19 10:54:34 +05:30
}
2013-12-31 05:54:28 +05:30
void MainWindow : : updateInstanceToolIcon ( QString new_icon )
{
2018-07-15 18:21:05 +05:30
m_currentInstIcon = new_icon ;
2021-11-20 20:52:22 +05:30
auto icon = APPLICATION - > icons ( ) - > getIcon ( m_currentInstIcon ) ;
2018-07-15 18:21:05 +05:30
ui - > actionChangeInstIcon - > setIcon ( icon ) ;
2022-12-31 05:38:10 +05:30
changeIconButton - > setIcon ( icon ) ;
2013-12-31 05:54:28 +05:30
}
2014-01-06 14:31:40 +05:30
void MainWindow : : setSelectedInstanceById ( const QString & id )
{
2018-07-15 18:21:05 +05:30
if ( id . isNull ( ) )
return ;
2021-11-20 20:52:22 +05:30
const QModelIndex index = APPLICATION - > instances ( ) - > getInstanceIndexById ( id ) ;
2018-07-15 18:21:05 +05:30
if ( index . isValid ( ) )
{
QModelIndex selectionIndex = proxymodel - > mapFromSource ( index ) ;
view - > selectionModel ( ) - > setCurrentIndex ( selectionIndex , QItemSelectionModel : : ClearAndSelect ) ;
2019-07-10 07:53:24 +05:30
updateStatusCenter ( ) ;
2018-07-15 18:21:05 +05:30
}
2014-01-06 14:31:40 +05:30
}
2013-08-10 22:04:08 +05:30
void MainWindow : : on_actionChangeInstGroup_triggered ( )
{
2018-07-15 18:21:05 +05:30
if ( ! m_selectedInstance )
return ;
2013-10-06 04:43:40 +05:30
2018-07-15 18:21:05 +05:30
bool ok = false ;
2018-07-31 05:24:08 +05:30
InstanceId instId = m_selectedInstance - > id ( ) ;
2021-11-20 20:52:22 +05:30
QString name ( APPLICATION - > instances ( ) - > getInstanceGroup ( instId ) ) ;
auto groups = APPLICATION - > instances ( ) - > getGroups ( ) ;
2018-07-15 18:21:05 +05:30
groups . insert ( 0 , " " ) ;
groups . sort ( Qt : : CaseInsensitive ) ;
int foo = groups . indexOf ( name ) ;
2013-12-15 22:40:51 +05:30
2018-07-15 18:21:05 +05:30
name = QInputDialog : : getItem ( this , tr ( " Group name " ) , tr ( " Enter a new group name. " ) , groups , foo , true , & ok ) ;
name = name . simplified ( ) ;
if ( ok )
2018-07-31 05:24:08 +05:30
{
2021-11-20 20:52:22 +05:30
APPLICATION - > instances ( ) - > setInstanceGroup ( instId , name ) ;
2018-07-31 05:24:08 +05:30
}
2013-08-10 22:04:08 +05:30
}
2017-12-14 04:59:00 +05:30
void MainWindow : : deleteGroup ( )
2016-04-11 05:00:50 +05:30
{
2018-07-15 18:21:05 +05:30
QObject * obj = sender ( ) ;
if ( ! obj )
return ;
QAction * action = qobject_cast < QAction * > ( obj ) ;
if ( ! action )
return ;
auto map = action - > data ( ) . toMap ( ) ;
if ( ! map . contains ( " group " ) )
return ;
QString groupName = map [ " group " ] . toString ( ) ;
if ( ! groupName . isEmpty ( ) )
{
2022-03-18 17:49:09 +05:30
auto reply = QMessageBox : : question ( this , tr ( " Delete group " ) , tr ( " Are you sure you want to delete the group %1? " )
2018-11-08 22:00:30 +05:30
. arg ( groupName ) , QMessageBox : : Yes | QMessageBox : : No ) ;
if ( reply = = QMessageBox : : Yes )
{
2021-11-20 20:52:22 +05:30
APPLICATION - > instances ( ) - > deleteGroup ( groupName ) ;
2018-11-08 22:00:30 +05:30
}
2018-07-15 18:21:05 +05:30
}
2016-04-11 05:00:50 +05:30
}
2022-07-30 23:12:33 +05:30
void MainWindow : : undoTrashInstance ( )
{
APPLICATION - > instances ( ) - > undoTrashInstance ( ) ;
2022-10-30 23:07:03 +05:30
ui - > actionUndoTrashInstance - > setEnabled ( APPLICATION - > instances ( ) - > trashedSomething ( ) ) ;
2022-07-30 23:12:33 +05:30
}
2013-01-09 23:52:22 +05:30
void MainWindow : : on_actionViewInstanceFolder_triggered ( )
{
2021-11-20 20:52:22 +05:30
QString str = APPLICATION - > settings ( ) - > get ( " InstanceDir " ) . toString ( ) ;
2018-07-15 18:21:05 +05:30
DesktopServices : : openDirectory ( str ) ;
2013-01-09 23:52:22 +05:30
}
2017-12-14 04:59:00 +05:30
void MainWindow : : refreshInstances ( )
2013-01-09 23:52:22 +05:30
{
2021-11-20 20:52:22 +05:30
APPLICATION - > instances ( ) - > loadList ( ) ;
2013-01-09 23:52:22 +05:30
}
void MainWindow : : on_actionViewCentralModsFolder_triggered ( )
{
2021-11-20 20:52:22 +05:30
DesktopServices : : openDirectory ( APPLICATION - > settings ( ) - > get ( " CentralModsDir " ) . toString ( ) , true ) ;
2013-01-09 23:52:22 +05:30
}
2017-12-14 04:59:00 +05:30
void MainWindow : : checkForUpdates ( )
2013-01-09 23:52:22 +05:30
{
2018-07-15 18:21:05 +05:30
if ( BuildConfig . UPDATER_ENABLED )
{
2021-11-20 20:52:22 +05:30
auto updater = APPLICATION - > updateChecker ( ) ;
updater - > checkForUpdate ( APPLICATION - > settings ( ) - > get ( " UpdateChannel " ) . toString ( ) , true ) ;
2018-07-15 18:21:05 +05:30
}
else
{
qWarning ( ) < < " Updater not set up. Cannot check for updates. " ;
}
2013-01-09 23:52:22 +05:30
}
2014-07-16 03:43:40 +05:30
void MainWindow : : on_actionSettings_triggered ( )
{
2021-11-20 20:52:22 +05:30
APPLICATION - > ShowGlobalSettings ( this , " global-settings " ) ;
2019-06-01 15:58:53 +05:30
}
void MainWindow : : globalSettingsClosed ( )
{
2018-07-15 18:21:05 +05:30
// FIXME: quick HACK to make this work. improve, optimize.
2021-11-20 20:52:22 +05:30
APPLICATION - > instances ( ) - > loadList ( ) ;
2018-07-15 18:21:05 +05:30
proxymodel - > invalidate ( ) ;
proxymodel - > sort ( 0 ) ;
2022-04-16 03:55:37 +05:30
updateMainToolBar ( ) ;
2018-07-15 18:21:05 +05:30
updateToolsMenu ( ) ;
2022-11-15 14:16:24 +05:30
updateThemeMenu ( ) ;
2021-10-14 02:44:02 +05:30
updateStatusCenter ( ) ;
2022-05-17 04:51:57 +05:30
// This needs to be done to prevent UI elements disappearing in the event the config is changed
2022-10-18 20:07:04 +05:30
// but Prism Launcher exits abnormally, causing the window state to never be saved:
2022-05-17 04:51:57 +05:30
APPLICATION - > settings ( ) - > set ( " MainWindowState " , saveState ( ) . toBase64 ( ) ) ;
2018-07-15 18:21:05 +05:30
update ( ) ;
2014-07-16 03:43:40 +05:30
}
2014-06-18 04:45:01 +05:30
void MainWindow : : on_actionEditInstance_triggered ( )
{
2021-11-20 20:52:22 +05:30
APPLICATION - > showInstanceWindow ( m_selectedInstance ) ;
2014-06-18 04:45:01 +05:30
}
2013-11-20 23:50:35 +05:30
void MainWindow : : on_actionManageAccounts_triggered ( )
{
2021-11-20 20:52:22 +05:30
APPLICATION - > ShowGlobalSettings ( this , " accounts " ) ;
2013-11-20 23:50:35 +05:30
}
2013-01-09 23:52:22 +05:30
void MainWindow : : on_actionReportBug_triggered ( )
{
2021-06-18 16:54:20 +05:30
DesktopServices : : openUrl ( QUrl ( BuildConfig . BUG_TRACKER_URL ) ) ;
2013-01-09 23:52:22 +05:30
}
2022-10-10 16:15:44 +05:30
void MainWindow : : on_actionClearMetadata_triggered ( )
{
APPLICATION - > metacache ( ) - > evictAll ( ) ;
2022-11-06 05:35:10 +05:30
APPLICATION - > metacache ( ) - > SaveNow ( ) ;
2022-10-10 16:15:44 +05:30
}
2022-11-05 20:01:07 +05:30
# ifdef Q_OS_MAC
2022-11-14 23:07:24 +05:30
void MainWindow : : on_actionAddToPATH_triggered ( )
{
2022-11-05 19:45:31 +05:30
auto binaryPath = APPLICATION - > applicationFilePath ( ) ;
2022-11-14 23:07:24 +05:30
auto targetPath = QString ( " /usr/local/bin/%1 " ) . arg ( BuildConfig . LAUNCHER_APP_BINARY_NAME ) ;
qDebug ( ) < < " Symlinking " < < binaryPath < < " to " < < targetPath ;
QStringList args ;
args < < " -e " ;
args < < QString ( " do shell script \" mkdir -p /usr/local/bin && ln -sf '%1' '%2' \" with administrator privileges " )
. arg ( binaryPath , targetPath ) ;
auto outcome = QProcess : : execute ( " /usr/bin/osascript " , args ) ;
2022-10-19 19:23:57 +05:30
if ( ! outcome ) {
2022-11-14 23:07:24 +05:30
QMessageBox : : information ( this , tr ( " Successfully added %1 to PATH " ) . arg ( BuildConfig . LAUNCHER_DISPLAYNAME ) ,
tr ( " %1 was successfully added to your PATH. You can now start it by running `%2`. " )
. arg ( BuildConfig . LAUNCHER_DISPLAYNAME , BuildConfig . LAUNCHER_APP_BINARY_NAME ) ) ;
2022-10-19 19:23:57 +05:30
} else {
2022-11-14 23:07:24 +05:30
QMessageBox : : critical ( this , tr ( " Failed to add %1 to PATH " ) . arg ( BuildConfig . LAUNCHER_DISPLAYNAME ) ,
tr ( " An error occurred while trying to add %1 to PATH " ) . arg ( BuildConfig . LAUNCHER_DISPLAYNAME ) ) ;
2022-10-19 19:23:57 +05:30
}
}
2022-11-05 20:01:07 +05:30
# endif
2022-10-19 19:23:57 +05:30
2022-04-09 01:07:18 +05:30
void MainWindow : : on_actionOpenWiki_triggered ( )
{
2022-04-16 02:14:27 +05:30
DesktopServices : : openUrl ( QUrl ( BuildConfig . HELP_URL . arg ( " " ) ) ) ;
2022-04-09 01:07:18 +05:30
}
2022-02-10 17:25:07 +05:30
void MainWindow : : on_actionMoreNews_triggered ( )
{
2022-06-26 04:45:16 +05:30
auto entries = m_newsChecker - > getNewsEntries ( ) ;
NewsDialog news_dialog ( entries , this ) ;
news_dialog . exec ( ) ;
2022-02-10 17:25:07 +05:30
}
void MainWindow : : newsButtonClicked ( )
{
2022-06-26 04:45:16 +05:30
auto entries = m_newsChecker - > getNewsEntries ( ) ;
NewsDialog news_dialog ( entries , this ) ;
news_dialog . toggleArticleList ( ) ;
news_dialog . exec ( ) ;
2022-02-10 17:25:07 +05:30
}
2023-01-20 19:43:25 +05:30
void MainWindow : : onCatChanged ( int ) {
setCatBackground ( APPLICATION - > settings ( ) - > get ( " TheCat " ) . toBool ( ) ) ;
}
2013-01-09 23:52:22 +05:30
void MainWindow : : on_actionAbout_triggered ( )
{
2018-07-15 18:21:05 +05:30
AboutDialog dialog ( this ) ;
dialog . exec ( ) ;
2013-01-09 23:52:22 +05:30
}
2013-01-30 11:22:37 +05:30
2013-06-24 01:40:32 +05:30
void MainWindow : : on_actionDeleteInstance_triggered ( )
{
2022-12-03 19:24:41 +05:30
if ( ! m_selectedInstance ) {
2018-07-15 18:21:05 +05:30
return ;
}
2022-07-30 23:12:33 +05:30
2019-06-17 20:15:32 +05:30
auto id = m_selectedInstance - > id ( ) ;
2022-12-03 19:24:41 +05:30
2022-12-17 14:56:06 +05:30
auto response = CustomMessageBox : : selectable ( this , tr ( " Confirm Deletion " ) ,
2022-12-26 20:03:50 +05:30
tr ( " You are about to delete \" %1 \" . \n "
2022-12-14 20:32:04 +05:30
" This may be permanent and will completely delete the instance. \n \n "
" Are you sure? " )
. arg ( m_selectedInstance - > name ( ) ) ,
QMessageBox : : Warning , QMessageBox : : Yes | QMessageBox : : No , QMessageBox : : No )
- > exec ( ) ;
2022-12-03 19:24:41 +05:30
2022-12-14 20:32:04 +05:30
if ( response ! = QMessageBox : : Yes )
return ;
2022-12-03 19:24:41 +05:30
2022-12-14 20:32:04 +05:30
if ( APPLICATION - > instances ( ) - > trashInstance ( id ) ) {
ui - > actionUndoTrashInstance - > setEnabled ( APPLICATION - > instances ( ) - > trashedSomething ( ) ) ;
return ;
2018-07-15 18:21:05 +05:30
}
2022-12-14 20:32:04 +05:30
APPLICATION - > instances ( ) - > deleteInstance ( id ) ;
2013-06-24 01:40:32 +05:30
}
2015-02-13 02:31:20 +05:30
void MainWindow : : on_actionExportInstance_triggered ( )
{
2018-07-15 18:21:05 +05:30
if ( m_selectedInstance )
{
ExportInstanceDialog dlg ( m_selectedInstance , this ) ;
dlg . exec ( ) ;
}
2015-02-13 02:31:20 +05:30
}
2013-06-24 01:40:32 +05:30
void MainWindow : : on_actionRenameInstance_triggered ( )
{
2018-07-15 18:21:05 +05:30
if ( m_selectedInstance )
{
2018-11-22 06:20:32 +05:30
view - > edit ( view - > currentIndex ( ) ) ;
2018-07-15 18:21:05 +05:30
}
2013-06-24 01:40:32 +05:30
}
void MainWindow : : on_actionViewSelectedInstFolder_triggered ( )
{
2018-07-15 18:21:05 +05:30
if ( m_selectedInstance )
{
QString str = m_selectedInstance - > instanceRoot ( ) ;
DesktopServices : : openDirectory ( QDir ( str ) . absolutePath ( ) ) ;
}
2013-06-24 01:40:32 +05:30
}
2013-10-06 04:43:40 +05:30
void MainWindow : : closeEvent ( QCloseEvent * event )
2013-01-30 11:22:37 +05:30
{
2018-07-15 18:21:05 +05:30
// Save the window state and geometry.
2021-11-20 20:52:22 +05:30
APPLICATION - > settings ( ) - > set ( " MainWindowState " , saveState ( ) . toBase64 ( ) ) ;
APPLICATION - > settings ( ) - > set ( " MainWindowGeometry " , saveGeometry ( ) . toBase64 ( ) ) ;
2022-12-31 05:38:10 +05:30
instanceToolbarSetting - > set ( ui - > instanceToolBar - > getVisibilityState ( ) ) ;
2018-07-15 18:21:05 +05:30
event - > accept ( ) ;
emit isClosing ( ) ;
2013-01-30 11:22:37 +05:30
}
2013-03-12 02:49:17 +05:30
2016-12-05 06:59:08 +05:30
void MainWindow : : changeEvent ( QEvent * event )
{
2018-07-15 18:21:05 +05:30
if ( event - > type ( ) = = QEvent : : LanguageChange )
{
2021-06-19 04:42:54 +05:30
retranslateUi ( ) ;
2018-07-15 18:21:05 +05:30
}
QMainWindow : : changeEvent ( event ) ;
2016-12-05 06:59:08 +05:30
}
2013-10-22 01:55:50 +05:30
void MainWindow : : instanceActivated ( QModelIndex index )
{
2018-07-15 18:21:05 +05:30
if ( ! index . isValid ( ) )
return ;
QString id = index . data ( InstanceList : : InstanceIDRole ) . toString ( ) ;
2021-11-20 20:52:22 +05:30
InstancePtr inst = APPLICATION - > instances ( ) - > getInstanceById ( id ) ;
2018-07-15 18:21:05 +05:30
if ( ! inst )
return ;
2013-10-22 01:55:50 +05:30
2018-07-15 18:21:05 +05:30
activateInstance ( inst ) ;
2013-10-22 01:55:50 +05:30
}
2013-02-06 04:04:20 +05:30
void MainWindow : : on_actionLaunchInstance_triggered ( )
{
2022-06-20 00:03:34 +05:30
if ( m_selectedInstance & & ! m_selectedInstance - > isRunning ( ) )
2018-07-15 18:21:05 +05:30
{
2021-11-20 20:52:22 +05:30
APPLICATION - > launch ( m_selectedInstance ) ;
2018-07-15 18:21:05 +05:30
}
2013-02-06 04:04:20 +05:30
}
2016-11-26 22:36:08 +05:30
void MainWindow : : activateInstance ( InstancePtr instance )
{
2021-11-20 20:52:22 +05:30
APPLICATION - > launch ( instance ) ;
2016-11-26 22:36:08 +05:30
}
2014-01-27 07:30:49 +05:30
void MainWindow : : on_actionLaunchInstanceOffline_triggered ( )
{
2018-07-15 18:21:05 +05:30
if ( m_selectedInstance )
{
2021-11-20 20:52:22 +05:30
APPLICATION - > launch ( m_selectedInstance , false ) ;
2018-07-15 18:21:05 +05:30
}
2015-07-04 23:32:43 +05:30
}
2022-07-12 00:16:11 +05:30
void MainWindow : : on_actionLaunchInstanceDemo_triggered ( )
{
if ( m_selectedInstance )
{
APPLICATION - > launch ( m_selectedInstance , false , true ) ;
}
}
2022-06-20 00:03:34 +05:30
void MainWindow : : on_actionKillInstance_triggered ( )
{
if ( m_selectedInstance & & m_selectedInstance - > isRunning ( ) )
{
APPLICATION - > kill ( m_selectedInstance ) ;
}
}
2022-10-22 18:09:53 +05:30
void MainWindow : : on_actionCreateInstanceShortcut_triggered ( )
{
if ( m_selectedInstance )
{
2022-10-22 20:26:27 +05:30
auto desktopPath = FS : : getDesktopDir ( ) ;
if ( desktopPath . isEmpty ( ) ) {
2022-10-22 18:09:53 +05:30
// TODO come up with an alternative solution (open "save file" dialog)
2022-10-22 20:26:27 +05:30
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Couldn't find desktop?! " ) ) ;
2022-10-22 18:09:53 +05:30
return ;
}
2022-11-13 00:11:52 +05:30
# if defined(Q_OS_MACOS)
2022-11-13 19:17:37 +05:30
QString appPath = QApplication : : applicationFilePath ( ) ;
2022-11-13 21:21:29 +05:30
if ( appPath . startsWith ( " /private/var/ " ) ) {
2022-11-13 19:17:37 +05:30
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " The launcher is in the folder it was extracted from, therefore it cannot create shortcuts. " ) ) ;
return ;
2022-11-13 19:19:28 +05:30
}
2022-11-13 00:06:49 +05:30
2022-11-13 00:11:52 +05:30
if ( FS : : createShortcut ( FS : : PathCombine ( desktopPath , m_selectedInstance - > name ( ) ) ,
2022-11-13 21:21:29 +05:30
appPath , { " --launch " , m_selectedInstance - > id ( ) } ,
m_selectedInstance - > name ( ) , " " ) ) {
2022-11-13 00:06:49 +05:30
QMessageBox : : information ( this , tr ( " Create instance shortcut " ) , tr ( " Created a shortcut to this instance on your desktop! " ) ) ;
}
else
{
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Failed to create instance shortcut! " ) ) ;
}
2022-11-13 00:11:52 +05:30
# elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
2022-11-13 21:21:29 +05:30
QString appPath = QApplication : : applicationFilePath ( ) ;
if ( appPath . startsWith ( " /tmp/.mount_ " ) ) {
// AppImage!
appPath = QProcessEnvironment : : systemEnvironment ( ) . value ( QStringLiteral ( " APPIMAGE " ) ) ;
if ( appPath . isEmpty ( ) )
{
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Launcher is running as misconfigured AppImage? ($APPIMAGE environment variable is missing) " ) ) ;
}
else if ( appPath . endsWith ( " / " ) )
{
appPath . chop ( 1 ) ;
}
}
2022-10-25 20:07:30 +05:30
auto icon = APPLICATION - > icons ( ) - > icon ( m_selectedInstance - > iconKey ( ) ) ;
2022-11-13 23:48:51 +05:30
if ( icon = = nullptr )
{
icon = APPLICATION - > icons ( ) - > icon ( " grass " ) ;
}
2022-11-13 21:21:29 +05:30
QString iconPath = FS : : PathCombine ( m_selectedInstance - > instanceRoot ( ) , " icon.png " ) ;
2022-12-14 20:32:04 +05:30
2022-11-13 21:21:29 +05:30
QFile iconFile ( iconPath ) ;
if ( ! iconFile . open ( QFile : : WriteOnly ) )
{
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Failed to create icon for shortcut. " ) ) ;
return ;
}
bool success = icon - > icon ( ) . pixmap ( 64 , 64 ) . save ( & iconFile , " PNG " ) ;
iconFile . close ( ) ;
2022-12-14 20:32:04 +05:30
2022-11-13 21:21:29 +05:30
if ( ! success )
{
iconFile . remove ( ) ;
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Failed to create icon for shortcut. " ) ) ;
return ;
}
2022-12-08 19:16:58 +05:30
QString desktopFilePath = FS : : PathCombine ( desktopPath , m_selectedInstance - > name ( ) + " .desktop " ) ;
QStringList args ;
if ( DesktopServices : : isFlatpak ( ) ) {
QFileDialog fileDialog ;
// workaround to make sure the portal file dialog opens in the desktop directory
fileDialog . setDirectoryUrl ( desktopPath ) ;
desktopFilePath = fileDialog . getSaveFileName (
this , tr ( " Create Shortcut " ) , desktopFilePath ,
tr ( " Desktop Entries (*.desktop) " ) ) ;
if ( desktopFilePath . isEmpty ( ) )
return ; // file dialog canceled by user
appPath = " flatpak " ;
QString flatpakAppId = BuildConfig . LAUNCHER_DESKTOPFILENAME ;
flatpakAppId . remove ( " .desktop " ) ;
args . append ( { " run " , flatpakAppId } ) ;
}
args . append ( { " --launch " , m_selectedInstance - > id ( ) } ) ;
if ( FS : : createShortcut ( desktopFilePath , appPath , args , m_selectedInstance - > name ( ) , iconPath ) ) {
2022-11-13 00:11:52 +05:30
QMessageBox : : information ( this , tr ( " Create instance shortcut " ) , tr ( " Created a shortcut to this instance on your desktop! " ) ) ;
}
else
{
2022-11-13 21:21:29 +05:30
iconFile . remove ( ) ;
2022-11-13 00:11:52 +05:30
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Failed to create instance shortcut! " ) ) ;
}
# elif defined(Q_OS_WIN)
auto icon = APPLICATION - > icons ( ) - > icon ( m_selectedInstance - > iconKey ( ) ) ;
2022-11-13 23:48:51 +05:30
if ( icon = = nullptr )
{
icon = APPLICATION - > icons ( ) - > icon ( " grass " ) ;
}
2022-11-13 00:11:52 +05:30
QString iconPath = FS : : PathCombine ( m_selectedInstance - > instanceRoot ( ) , " icon.ico " ) ;
2022-12-14 20:32:04 +05:30
2022-10-28 23:41:51 +05:30
// part of fix for weird bug involving the window icon being replaced
// dunno why it happens, but this 2-line fix seems to be enough, so w/e
2022-11-10 01:25:13 +05:30
auto appIcon = APPLICATION - > getThemedIcon ( " logo " ) ;
2022-10-28 23:41:51 +05:30
2022-10-28 20:12:29 +05:30
QFile iconFile ( iconPath ) ;
if ( ! iconFile . open ( QFile : : WriteOnly ) )
{
2022-11-13 21:21:29 +05:30
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Failed to create icon for shortcut. " ) ) ;
2022-10-28 20:12:29 +05:30
return ;
}
2022-11-10 01:25:13 +05:30
bool success = icon - > icon ( ) . pixmap ( 64 , 64 ) . save ( & iconFile , " ICO " ) ;
iconFile . close ( ) ;
// restore original window icon
QGuiApplication : : setWindowIcon ( appIcon ) ;
2022-10-28 20:12:29 +05:30
2022-11-13 00:11:52 +05:30
if ( ! success )
2022-10-28 20:12:29 +05:30
{
iconFile . remove ( ) ;
2022-11-13 21:21:29 +05:30
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Failed to create icon for shortcut. " ) ) ;
2022-10-28 20:12:29 +05:30
return ;
}
2022-12-14 20:32:04 +05:30
2022-10-22 20:26:27 +05:30
if ( FS : : createShortcut ( FS : : PathCombine ( desktopPath , m_selectedInstance - > name ( ) ) ,
2022-11-13 21:21:29 +05:30
QApplication : : applicationFilePath ( ) , { " --launch " , m_selectedInstance - > id ( ) } ,
m_selectedInstance - > name ( ) , iconPath ) ) {
2022-10-22 20:26:27 +05:30
QMessageBox : : information ( this , tr ( " Create instance shortcut " ) , tr ( " Created a shortcut to this instance on your desktop! " ) ) ;
}
else
{
2022-11-13 00:13:58 +05:30
iconFile . remove ( ) ;
2022-10-22 20:26:27 +05:30
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Failed to create instance shortcut! " ) ) ;
}
2022-11-13 00:11:52 +05:30
# else
QMessageBox : : critical ( this , tr ( " Create instance shortcut " ) , tr ( " Not supported on your platform! " ) ) ;
# endif
2022-10-22 18:09:53 +05:30
}
}
2013-08-09 03:56:35 +05:30
void MainWindow : : taskEnd ( )
2013-05-07 03:49:20 +05:30
{
2018-07-15 18:21:05 +05:30
QObject * sender = QObject : : sender ( ) ;
if ( sender = = m_versionLoadTask )
m_versionLoadTask = NULL ;
2013-10-06 04:43:40 +05:30
2018-07-15 18:21:05 +05:30
sender - > deleteLater ( ) ;
2013-05-07 03:49:20 +05:30
}
void MainWindow : : startTask ( Task * task )
{
2018-07-15 18:21:05 +05:30
connect ( task , SIGNAL ( succeeded ( ) ) , SLOT ( taskEnd ( ) ) ) ;
connect ( task , SIGNAL ( failed ( QString ) ) , SLOT ( taskEnd ( ) ) ) ;
task - > start ( ) ;
2013-05-07 03:49:20 +05:30
}
2013-10-06 04:43:40 +05:30
void MainWindow : : instanceChanged ( const QModelIndex & current , const QModelIndex & previous )
2013-08-25 05:02:42 +05:30
{
2018-07-15 18:21:05 +05:30
if ( ! current . isValid ( ) )
{
2021-11-20 20:52:22 +05:30
APPLICATION - > settings ( ) - > set ( " SelectedInstance " , QString ( ) ) ;
2018-07-15 18:21:05 +05:30
selectionBad ( ) ;
return ;
}
2022-06-10 07:55:13 +05:30
if ( m_selectedInstance ) {
2022-06-10 13:18:18 +05:30
disconnect ( m_selectedInstance . get ( ) , & BaseInstance : : runningStatusChanged , this , & MainWindow : : refreshCurrentInstance ) ;
2022-06-10 07:55:13 +05:30
}
2018-07-15 18:21:05 +05:30
QString id = current . data ( InstanceList : : InstanceIDRole ) . toString ( ) ;
2021-11-20 20:52:22 +05:30
m_selectedInstance = APPLICATION - > instances ( ) - > getInstanceById ( id ) ;
2018-07-15 18:21:05 +05:30
if ( m_selectedInstance )
{
ui - > instanceToolBar - > setEnabled ( true ) ;
2022-12-31 05:38:10 +05:30
setInstanceActionsEnabled ( true ) ;
2022-06-20 00:03:34 +05:30
ui - > actionLaunchInstance - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
2018-07-15 18:21:05 +05:30
ui - > actionLaunchInstanceOffline - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
2022-07-12 00:16:11 +05:30
ui - > actionLaunchInstanceDemo - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
2022-09-16 03:53:58 +05:30
// Disable demo-mode if not available.
auto instance = dynamic_cast < MinecraftInstance * > ( m_selectedInstance . get ( ) ) ;
if ( instance ) {
ui - > actionLaunchInstanceDemo - > setEnabled ( instance - > supportsDemo ( ) ) ;
}
2022-06-20 00:03:34 +05:30
ui - > actionKillInstance - > setEnabled ( m_selectedInstance - > isRunning ( ) ) ;
2018-07-15 18:21:05 +05:30
ui - > actionExportInstance - > setEnabled ( m_selectedInstance - > canExport ( ) ) ;
2022-12-31 05:38:10 +05:30
renameButton - > setText ( m_selectedInstance - > name ( ) ) ;
2018-07-15 18:21:05 +05:30
m_statusLeft - > setText ( m_selectedInstance - > getStatusbarDescription ( ) ) ;
2019-07-10 07:53:24 +05:30
updateStatusCenter ( ) ;
2018-07-15 18:21:05 +05:30
updateInstanceToolIcon ( m_selectedInstance - > iconKey ( ) ) ;
updateToolsMenu ( ) ;
2021-11-20 20:52:22 +05:30
APPLICATION - > settings ( ) - > set ( " SelectedInstance " , m_selectedInstance - > id ( ) ) ;
2022-06-10 07:55:13 +05:30
2022-06-10 13:18:18 +05:30
connect ( m_selectedInstance . get ( ) , & BaseInstance : : runningStatusChanged , this , & MainWindow : : refreshCurrentInstance ) ;
2018-07-15 18:21:05 +05:30
}
else
{
ui - > instanceToolBar - > setEnabled ( false ) ;
2022-12-31 05:38:10 +05:30
setInstanceActionsEnabled ( false ) ;
2022-06-20 00:03:34 +05:30
ui - > actionLaunchInstance - > setEnabled ( false ) ;
ui - > actionLaunchInstanceOffline - > setEnabled ( false ) ;
2022-07-12 00:16:11 +05:30
ui - > actionLaunchInstanceDemo - > setEnabled ( false ) ;
2022-06-20 00:03:34 +05:30
ui - > actionKillInstance - > setEnabled ( false ) ;
2021-11-20 20:52:22 +05:30
APPLICATION - > settings ( ) - > set ( " SelectedInstance " , QString ( ) ) ;
2018-07-15 18:21:05 +05:30
selectionBad ( ) ;
return ;
}
2013-08-26 10:00:11 +05:30
}
2019-06-23 18:24:17 +05:30
void MainWindow : : instanceSelectRequest ( QString id )
2019-06-17 19:43:52 +05:30
{
setSelectedInstanceById ( id ) ;
}
2015-10-20 20:52:13 +05:30
void MainWindow : : instanceDataChanged ( const QModelIndex & topLeft , const QModelIndex & bottomRight )
2015-04-07 04:51:03 +05:30
{
2018-07-15 18:21:05 +05:30
auto current = view - > selectionModel ( ) - > currentIndex ( ) ;
QItemSelection test ( topLeft , bottomRight ) ;
if ( test . contains ( current ) )
{
instanceChanged ( current , current ) ;
}
2015-04-07 04:51:03 +05:30
}
2013-08-26 10:00:11 +05:30
void MainWindow : : selectionBad ( )
{
2018-07-15 18:21:05 +05:30
// start by reseting everything...
m_selectedInstance = nullptr ;
2013-12-31 05:54:28 +05:30
2018-07-15 18:21:05 +05:30
statusBar ( ) - > clearMessage ( ) ;
ui - > instanceToolBar - > setEnabled ( false ) ;
2022-12-31 05:38:10 +05:30
setInstanceActionsEnabled ( false ) ;
2022-06-20 00:30:51 +05:30
updateToolsMenu ( ) ;
2022-12-31 05:38:10 +05:30
renameButton - > setText ( tr ( " Rename Instance " ) ) ;
2021-10-16 04:12:01 +05:30
updateInstanceToolIcon ( " grass " ) ;
2014-01-06 14:31:40 +05:30
2018-07-15 18:21:05 +05:30
// ...and then see if we can enable the previously selected instance
2021-11-20 20:52:22 +05:30
setSelectedInstanceById ( APPLICATION - > settings ( ) - > get ( " SelectedInstance " ) . toString ( ) ) ;
2013-07-15 01:31:30 +05:30
}
2013-08-26 02:18:41 +05:30
2014-07-27 19:20:03 +05:30
void MainWindow : : checkInstancePathForProblems ( )
{
2021-11-20 20:52:22 +05:30
QString instanceFolder = APPLICATION - > settings ( ) - > get ( " InstanceDir " ) . toString ( ) ;
2018-07-15 18:21:05 +05:30
if ( FS : : checkProblemticPathJava ( QDir ( instanceFolder ) ) )
{
QMessageBox warning ( this ) ;
warning . setText ( tr ( " Your instance folder contains \' ! \' and this is known to cause Java problems! " ) ) ;
2021-10-18 04:17:02 +05:30
warning . setInformativeText (
tr (
" You have now two options: <br/> "
" - change the instance folder in the settings <br/> "
" - move this installation of %1 to a different folder "
2022-10-18 13:20:27 +05:30
) . arg ( BuildConfig . LAUNCHER_DISPLAYNAME )
2021-10-18 04:17:02 +05:30
) ;
2018-07-15 18:21:05 +05:30
warning . setDefaultButton ( QMessageBox : : Ok ) ;
warning . exec ( ) ;
}
auto tempFolderText = tr ( " This is a problem: <br/> "
2021-10-18 04:17:02 +05:30
" - The launcher will likely be deleted without warning by the operating system <br/> "
" - close the launcher now and extract it to a real location, not a temporary folder " ) ;
2018-07-15 18:21:05 +05:30
QString pathfoldername = QDir ( instanceFolder ) . absolutePath ( ) ;
if ( pathfoldername . contains ( " Rar$ " , Qt : : CaseInsensitive ) )
{
QMessageBox warning ( this ) ;
2021-10-18 04:17:02 +05:30
warning . setText ( tr ( " Your instance folder contains \' Rar$ \' - that means you haven't extracted the launcher archive! " ) ) ;
2018-07-15 18:21:05 +05:30
warning . setInformativeText ( tempFolderText ) ;
warning . setDefaultButton ( QMessageBox : : Ok ) ;
warning . exec ( ) ;
}
2019-08-05 00:44:59 +05:30
else if ( pathfoldername . startsWith ( QDir : : tempPath ( ) ) | | pathfoldername . contains ( " /TempState/ " ) )
2018-07-15 18:21:05 +05:30
{
QMessageBox warning ( this ) ;
warning . setText ( tr ( " Your instance folder is in a temporary folder: \' %1 \' ! " ) . arg ( QDir : : tempPath ( ) ) ) ;
warning . setInformativeText ( tempFolderText ) ;
warning . setDefaultButton ( QMessageBox : : Ok ) ;
warning . exec ( ) ;
}
2014-07-27 19:20:03 +05:30
}
2019-07-10 07:53:24 +05:30
void MainWindow : : updateStatusCenter ( )
{
2021-11-20 20:52:22 +05:30
m_statusCenter - > setVisible ( APPLICATION - > settings ( ) - > get ( " ShowGlobalGameTime " ) . toBool ( ) ) ;
2021-10-14 02:44:02 +05:30
2021-11-20 20:52:22 +05:30
int timePlayed = APPLICATION - > instances ( ) - > getTotalPlayTime ( ) ;
2021-09-29 03:50:34 +05:30
if ( timePlayed > 0 ) {
m_statusCenter - > setText ( tr ( " Total playtime: %1 " ) . arg ( Time : : prettifyDuration ( timePlayed ) ) ) ;
}
2019-07-10 07:53:24 +05:30
}
2022-12-31 05:38:10 +05:30
// "Instance actions" are actions that require an instance to be selected (i.e. "new instance" is not here)
// Actions that also require other conditions (e.g. a running instance) won't be changed.
void MainWindow : : setInstanceActionsEnabled ( bool enabled )
{
ui - > actionEditInstance - > setEnabled ( enabled ) ;
ui - > actionChangeInstGroup - > setEnabled ( enabled ) ;
ui - > actionViewSelectedInstFolder - > setEnabled ( enabled ) ;
ui - > actionExportInstance - > setEnabled ( enabled ) ;
ui - > actionDeleteInstance - > setEnabled ( enabled ) ;
ui - > actionCopyInstance - > setEnabled ( enabled ) ;
ui - > actionCreateInstanceShortcut - > setEnabled ( enabled ) ;
}
2022-06-10 07:55:13 +05:30
2022-06-10 13:18:18 +05:30
void MainWindow : : refreshCurrentInstance ( bool running )
2022-06-10 07:55:13 +05:30
{
auto current = view - > selectionModel ( ) - > currentIndex ( ) ;
instanceChanged ( current , current ) ;
}