2015-02-02 22:25:30 +00:00
/* Copyright 2013-2015 MultiMC Contributors
2013-02-19 23:07:52 +00:00
*
* Authors : Andrew Okin
* Peterix
* Orochimarufan < orochimarufan . x3 @ gmail . com >
2013-01-09 18:22:22 +00:00
*
* 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-03-11 21:19:17 +00:00
*
2013-01-09 18:22:22 +00:00
* 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-11-04 01:53:05 +00:00
# include "MultiMC.h"
2014-04-06 02:59:37 +01:00
# include "BuildConfig.h"
2013-01-09 18:22:22 +00:00
2013-11-04 01:53:05 +00:00
# include "MainWindow.h"
2015-03-01 21:20:57 +00:00
# include <QtCore/QVariant>
2015-10-20 16:18:53 +01:00
# include <QtCore/QUrl>
# include <QtCore/QDir>
# include <QtCore/QFileInfo>
# include <QtGui/QKeyEvent>
2015-03-01 21:20:57 +00:00
# include <QtWidgets/QAction>
# include <QtWidgets/QApplication>
# include <QtWidgets/QButtonGroup>
# include <QtWidgets/QHBoxLayout>
# include <QtWidgets/QHeaderView>
# include <QtWidgets/QMainWindow>
# include <QtWidgets/QStatusBar>
# include <QtWidgets/QToolBar>
# include <QtWidgets/QWidget>
2015-10-20 16:18:53 +01:00
# include <QtWidgets/QMenu>
# include <QtWidgets/QMessageBox>
# include <QtWidgets/QInputDialog>
# include <QtWidgets/QLabel>
# include <QtWidgets/QToolButton>
# include <QtWidgets/QWidgetAction>
# include <QtWidgets/QProgressDialog>
# include <QtWidgets/QShortcut>
# include <BaseInstance.h>
# include <Env.h>
# include <InstanceList.h>
# include <MMCZip.h>
# include <icons/IconList.h>
# include <java/JavaUtils.h>
2016-01-01 23:35:54 +00:00
# include <java/JavaInstallList.h>
2015-10-20 16:18:53 +01:00
# include <launch/LaunchTask.h>
# include <minecraft/MinecraftVersionList.h>
2016-02-27 18:58:40 +00:00
# include <minecraft/legacy/LwjglVersionList.h>
2016-08-10 23:44:01 +01:00
# include <minecraft/auth/MojangAccountList.h>
2016-04-10 03:29:29 +01:00
# include <SkinUtils.h>
2015-10-20 16:18:53 +01:00
# include <net/URLConstants.h>
# include <net/NetJob.h>
2016-05-28 18:54:17 +01:00
# include <net/Download.h>
2015-10-20 16:18:53 +01:00
# include <news/NewsChecker.h>
# include <notifications/NotificationChecker.h>
# include <tools/BaseProfiler.h>
# include <updater/DownloadTask.h>
# include <updater/UpdateChecker.h>
2016-01-05 06:32:52 +00:00
# include <DesktopServices.h>
2016-08-06 14:39:29 +01:00
# include "InstanceWindow.h"
2015-10-20 16:18:53 +01:00
# include "InstancePageProvider.h"
# include "InstanceProxyModel.h"
# include "JavaCommon.h"
2016-08-10 23:44:01 +01:00
# include "LaunchController.h"
2015-10-20 16:18:53 +01:00
# include "SettingsUI.h"
# include "groupview/GroupView.h"
# include "groupview/InstanceDelegate.h"
# include "widgets/LabeledToolButton.h"
# include "widgets/ServerStatus.h"
# include "dialogs/NewInstanceDialog.h"
# include "dialogs/ProgressDialog.h"
# include "dialogs/AboutDialog.h"
# include "dialogs/VersionSelectDialog.h"
# include "dialogs/CustomMessageBox.h"
# include "dialogs/IconPickerDialog.h"
# include "dialogs/CopyInstanceDialog.h"
# include "dialogs/UpdateDialog.h"
# include "dialogs/EditAccountDialog.h"
# include "dialogs/NotificationDialog.h"
# include "dialogs/ExportInstanceDialog.h"
2016-10-02 23:55:54 +01:00
# include <FolderInstanceProvider.h>
# include <InstanceImportTask.h>
2015-10-20 16:18:53 +01:00
class MainWindow : : Ui
2015-03-01 21:20:57 +00:00
{
public :
QAction * actionAddInstance ;
QAction * actionViewInstanceFolder ;
QAction * actionRefresh ;
QAction * actionViewCentralModsFolder ;
QAction * actionCheckUpdate ;
QAction * actionSettings ;
QAction * actionReportBug ;
QAction * actionPatreon ;
QAction * actionMoreNews ;
QAction * actionAbout ;
QAction * actionLaunchInstance ;
QAction * actionRenameInstance ;
QAction * actionChangeInstGroup ;
QAction * actionChangeInstIcon ;
QAction * actionEditInstNotes ;
QAction * actionEditInstance ;
2016-11-02 01:33:55 +00:00
QAction * actionWorlds ;
2015-03-01 21:20:57 +00:00
QAction * actionViewSelectedInstFolder ;
QAction * actionDeleteInstance ;
QAction * actionConfig_Folder ;
QAction * actionCAT ;
2015-09-15 22:02:21 +01:00
QAction * actionREDDIT ;
2016-01-09 00:39:51 +00:00
QAction * actionDISCORD ;
2015-03-01 21:20:57 +00:00
QAction * actionCopyInstance ;
QAction * actionManageAccounts ;
QAction * actionLaunchInstanceOffline ;
QAction * actionScreenshots ;
QAction * actionInstanceSettings ;
QAction * actionExportInstance ;
QWidget * centralWidget ;
QHBoxLayout * horizontalLayout ;
QToolBar * mainToolBar ;
QStatusBar * statusBar ;
QToolBar * instanceToolBar ;
QToolBar * newsToolBar ;
void setupUi ( QMainWindow * MainWindow )
{
if ( MainWindow - > objectName ( ) . isEmpty ( ) )
{
MainWindow - > setObjectName ( QStringLiteral ( " MainWindow " ) ) ;
}
MainWindow - > resize ( 694 , 563 ) ;
MainWindow - > setWindowIcon ( MMC - > getThemedIcon ( " multimc " ) ) ;
actionAddInstance = new QAction ( MainWindow ) ;
actionAddInstance - > setObjectName ( QStringLiteral ( " actionAddInstance " ) ) ;
actionAddInstance - > setIcon ( MMC - > getThemedIcon ( " new " ) ) ;
actionViewInstanceFolder = new QAction ( MainWindow ) ;
actionViewInstanceFolder - > setObjectName ( QStringLiteral ( " actionViewInstanceFolder " ) ) ;
actionViewInstanceFolder - > setIcon ( MMC - > getThemedIcon ( " viewfolder " ) ) ;
actionRefresh = new QAction ( MainWindow ) ;
actionRefresh - > setObjectName ( QStringLiteral ( " actionRefresh " ) ) ;
actionRefresh - > setIcon ( MMC - > getThemedIcon ( " refresh " ) ) ;
actionViewCentralModsFolder = new QAction ( MainWindow ) ;
actionViewCentralModsFolder - > setObjectName ( QStringLiteral ( " actionViewCentralModsFolder " ) ) ;
actionViewCentralModsFolder - > setIcon ( MMC - > getThemedIcon ( " centralmods " ) ) ;
2015-12-28 03:45:49 +00:00
if ( BuildConfig . UPDATER_ENABLED )
{
actionCheckUpdate = new QAction ( MainWindow ) ;
actionCheckUpdate - > setObjectName ( QStringLiteral ( " actionCheckUpdate " ) ) ;
actionCheckUpdate - > setIcon ( MMC - > getThemedIcon ( " checkupdate " ) ) ;
}
2015-03-01 21:20:57 +00:00
actionSettings = new QAction ( MainWindow ) ;
actionSettings - > setObjectName ( QStringLiteral ( " actionSettings " ) ) ;
actionSettings - > setIcon ( MMC - > getThemedIcon ( " settings " ) ) ;
actionSettings - > setMenuRole ( QAction : : PreferencesRole ) ;
actionReportBug = new QAction ( MainWindow ) ;
actionReportBug - > setObjectName ( QStringLiteral ( " actionReportBug " ) ) ;
actionReportBug - > setIcon ( MMC - > getThemedIcon ( " bug " ) ) ;
actionPatreon = new QAction ( MainWindow ) ;
actionPatreon - > setObjectName ( QStringLiteral ( " actionPatreon " ) ) ;
actionPatreon - > setIcon ( MMC - > getThemedIcon ( " patreon " ) ) ;
actionMoreNews = new QAction ( MainWindow ) ;
actionMoreNews - > setObjectName ( QStringLiteral ( " actionMoreNews " ) ) ;
actionMoreNews - > setIcon ( MMC - > getThemedIcon ( " news " ) ) ;
actionAbout = new QAction ( MainWindow ) ;
actionAbout - > setObjectName ( QStringLiteral ( " actionAbout " ) ) ;
actionAbout - > setIcon ( MMC - > getThemedIcon ( " about " ) ) ;
actionAbout - > setMenuRole ( QAction : : AboutRole ) ;
actionLaunchInstance = new QAction ( MainWindow ) ;
actionLaunchInstance - > setObjectName ( QStringLiteral ( " actionLaunchInstance " ) ) ;
actionRenameInstance = new QAction ( MainWindow ) ;
actionRenameInstance - > setObjectName ( QStringLiteral ( " actionRenameInstance " ) ) ;
actionChangeInstGroup = new QAction ( MainWindow ) ;
actionChangeInstGroup - > setObjectName ( QStringLiteral ( " actionChangeInstGroup " ) ) ;
actionChangeInstIcon = new QAction ( MainWindow ) ;
actionChangeInstIcon - > setObjectName ( QStringLiteral ( " actionChangeInstIcon " ) ) ;
actionChangeInstIcon - > setEnabled ( true ) ;
actionChangeInstIcon - > setIcon ( QIcon ( " :/icons/instances/infinity " ) ) ;
actionChangeInstIcon - > setIconVisibleInMenu ( true ) ;
actionEditInstNotes = new QAction ( MainWindow ) ;
actionEditInstNotes - > setObjectName ( QStringLiteral ( " actionEditInstNotes " ) ) ;
actionEditInstance = new QAction ( MainWindow ) ;
actionEditInstance - > setObjectName ( QStringLiteral ( " actionEditInstance " ) ) ;
2016-11-02 01:33:55 +00:00
actionWorlds = new QAction ( MainWindow ) ;
actionWorlds - > setObjectName ( QStringLiteral ( " actionWorlds " ) ) ;
2015-03-01 21:20:57 +00:00
actionViewSelectedInstFolder = new QAction ( MainWindow ) ;
actionViewSelectedInstFolder - > setObjectName ( QStringLiteral ( " actionViewSelectedInstFolder " ) ) ;
actionDeleteInstance = new QAction ( MainWindow ) ;
actionDeleteInstance - > setObjectName ( QStringLiteral ( " actionDeleteInstance " ) ) ;
actionConfig_Folder = new QAction ( MainWindow ) ;
actionConfig_Folder - > setObjectName ( QStringLiteral ( " actionConfig_Folder " ) ) ;
actionCAT = new QAction ( MainWindow ) ;
actionCAT - > setObjectName ( QStringLiteral ( " actionCAT " ) ) ;
actionCAT - > setCheckable ( true ) ;
actionCAT - > setIcon ( MMC - > getThemedIcon ( " cat " ) ) ;
2015-09-15 22:02:21 +01:00
actionREDDIT = new QAction ( MainWindow ) ;
actionREDDIT - > setObjectName ( QStringLiteral ( " actionREDDIT " ) ) ;
actionREDDIT - > setIcon ( MMC - > getThemedIcon ( " reddit-alien " ) ) ;
2016-01-09 00:39:51 +00:00
actionDISCORD = new QAction ( MainWindow ) ;
actionDISCORD - > setObjectName ( QStringLiteral ( " actionDISCORD " ) ) ;
actionDISCORD - > setIcon ( MMC - > getThemedIcon ( " discord " ) ) ;
2015-03-01 21:20:57 +00:00
actionCopyInstance = new QAction ( MainWindow ) ;
actionCopyInstance - > setObjectName ( QStringLiteral ( " actionCopyInstance " ) ) ;
actionCopyInstance - > setIcon ( MMC - > getThemedIcon ( " copy " ) ) ;
actionManageAccounts = new QAction ( MainWindow ) ;
actionManageAccounts - > setObjectName ( QStringLiteral ( " actionManageAccounts " ) ) ;
actionLaunchInstanceOffline = new QAction ( MainWindow ) ;
actionLaunchInstanceOffline - > setObjectName ( QStringLiteral ( " actionLaunchInstanceOffline " ) ) ;
actionScreenshots = new QAction ( MainWindow ) ;
actionScreenshots - > setObjectName ( QStringLiteral ( " actionScreenshots " ) ) ;
actionInstanceSettings = new QAction ( MainWindow ) ;
actionInstanceSettings - > setObjectName ( QStringLiteral ( " actionInstanceSettings " ) ) ;
actionExportInstance = new QAction ( MainWindow ) ;
actionExportInstance - > setObjectName ( QStringLiteral ( " actionExportInstance " ) ) ;
centralWidget = new QWidget ( MainWindow ) ;
centralWidget - > setObjectName ( QStringLiteral ( " centralWidget " ) ) ;
horizontalLayout = new QHBoxLayout ( centralWidget ) ;
horizontalLayout - > setSpacing ( 0 ) ;
horizontalLayout - > setContentsMargins ( 11 , 11 , 11 , 11 ) ;
horizontalLayout - > setObjectName ( QStringLiteral ( " horizontalLayout " ) ) ;
horizontalLayout - > setSizeConstraint ( QLayout : : SetDefaultConstraint ) ;
horizontalLayout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
MainWindow - > setCentralWidget ( centralWidget ) ;
mainToolBar = new QToolBar ( MainWindow ) ;
mainToolBar - > setObjectName ( QStringLiteral ( " mainToolBar " ) ) ;
mainToolBar - > setMovable ( false ) ;
mainToolBar - > setAllowedAreas ( Qt : : TopToolBarArea ) ;
mainToolBar - > setToolButtonStyle ( Qt : : ToolButtonIconOnly ) ;
mainToolBar - > setFloatable ( false ) ;
MainWindow - > addToolBar ( Qt : : TopToolBarArea , mainToolBar ) ;
statusBar = new QStatusBar ( MainWindow ) ;
statusBar - > setObjectName ( QStringLiteral ( " statusBar " ) ) ;
MainWindow - > setStatusBar ( statusBar ) ;
instanceToolBar = new QToolBar ( MainWindow ) ;
instanceToolBar - > setObjectName ( QStringLiteral ( " instanceToolBar " ) ) ;
instanceToolBar - > setEnabled ( true ) ;
2015-10-20 16:22:13 +01:00
instanceToolBar - > setAllowedAreas ( Qt : : LeftToolBarArea | Qt : : RightToolBarArea ) ;
2015-03-01 21:20:57 +00:00
instanceToolBar - > setIconSize ( QSize ( 80 , 80 ) ) ;
instanceToolBar - > setToolButtonStyle ( Qt : : ToolButtonIconOnly ) ;
instanceToolBar - > setFloatable ( false ) ;
MainWindow - > addToolBar ( Qt : : RightToolBarArea , instanceToolBar ) ;
newsToolBar = new QToolBar ( MainWindow ) ;
newsToolBar - > setObjectName ( QStringLiteral ( " newsToolBar " ) ) ;
newsToolBar - > setMovable ( false ) ;
newsToolBar - > setAllowedAreas ( Qt : : BottomToolBarArea ) ;
newsToolBar - > setIconSize ( QSize ( 16 , 16 ) ) ;
newsToolBar - > setToolButtonStyle ( Qt : : ToolButtonTextBesideIcon ) ;
newsToolBar - > setFloatable ( false ) ;
MainWindow - > addToolBar ( Qt : : BottomToolBarArea , newsToolBar ) ;
mainToolBar - > addAction ( actionAddInstance ) ;
mainToolBar - > addAction ( actionCopyInstance ) ;
mainToolBar - > addSeparator ( ) ;
mainToolBar - > addAction ( actionViewInstanceFolder ) ;
mainToolBar - > addAction ( actionViewCentralModsFolder ) ;
mainToolBar - > addAction ( actionRefresh ) ;
mainToolBar - > addSeparator ( ) ;
2015-12-28 03:45:49 +00:00
if ( BuildConfig . UPDATER_ENABLED )
{
mainToolBar - > addAction ( actionCheckUpdate ) ;
}
2015-03-01 21:20:57 +00:00
mainToolBar - > addAction ( actionSettings ) ;
mainToolBar - > addSeparator ( ) ;
mainToolBar - > addAction ( actionReportBug ) ;
mainToolBar - > addAction ( actionAbout ) ;
mainToolBar - > addSeparator ( ) ;
mainToolBar - > addAction ( actionPatreon ) ;
2015-09-15 22:02:21 +01:00
mainToolBar - > addAction ( actionREDDIT ) ;
2016-01-09 00:39:51 +00:00
mainToolBar - > addAction ( actionDISCORD ) ;
2015-03-01 21:20:57 +00:00
mainToolBar - > addAction ( actionCAT ) ;
instanceToolBar - > addAction ( actionChangeInstIcon ) ;
instanceToolBar - > addAction ( actionLaunchInstance ) ;
instanceToolBar - > addAction ( actionLaunchInstanceOffline ) ;
instanceToolBar - > addAction ( actionChangeInstGroup ) ;
instanceToolBar - > addSeparator ( ) ;
instanceToolBar - > addAction ( actionEditInstance ) ;
instanceToolBar - > addAction ( actionInstanceSettings ) ;
instanceToolBar - > addAction ( actionEditInstNotes ) ;
2016-11-02 01:33:55 +00:00
instanceToolBar - > addAction ( actionWorlds ) ;
2015-03-01 21:20:57 +00:00
instanceToolBar - > addAction ( actionScreenshots ) ;
instanceToolBar - > addSeparator ( ) ;
instanceToolBar - > addAction ( actionViewSelectedInstFolder ) ;
instanceToolBar - > addAction ( actionConfig_Folder ) ;
instanceToolBar - > addSeparator ( ) ;
instanceToolBar - > addAction ( actionExportInstance ) ;
instanceToolBar - > addAction ( actionDeleteInstance ) ;
newsToolBar - > addAction ( actionMoreNews ) ;
retranslateUi ( MainWindow ) ;
QMetaObject : : connectSlotsByName ( MainWindow ) ;
} // setupUi
void retranslateUi ( QMainWindow * MainWindow )
{
2016-03-22 22:28:47 +00:00
MainWindow - > setWindowTitle ( " MultiMC 5 " ) ;
2016-11-02 00:17:19 +00:00
actionAddInstance - > setText ( tr ( " Add Instance " ) ) ;
actionAddInstance - > setToolTip ( tr ( " Add a new instance. " ) ) ;
actionViewInstanceFolder - > setText ( tr ( " View Instance Folder " ) ) ;
actionViewInstanceFolder - > setToolTip ( tr ( " Open the instance folder in a file browser. " ) ) ;
actionRefresh - > setText ( tr ( " Refresh " ) ) ;
actionRefresh - > setToolTip ( tr ( " Reload the instance list. " ) ) ;
actionViewCentralModsFolder - > setText ( tr ( " View Central Mods Folder " ) ) ;
actionViewCentralModsFolder - > setToolTip ( tr ( " Open the central mods folder in a file browser. " ) ) ;
2015-12-28 03:45:49 +00:00
if ( BuildConfig . UPDATER_ENABLED )
{
2016-11-02 00:17:19 +00:00
actionCheckUpdate - > setText ( tr ( " Check for Updates " ) ) ;
actionCheckUpdate - > setToolTip ( tr ( " Check for new updates for MultiMC. " ) ) ;
2015-12-28 03:45:49 +00:00
}
2016-11-02 00:17:19 +00:00
actionSettings - > setText ( tr ( " Settings " ) ) ;
actionSettings - > setToolTip ( tr ( " Change settings. " ) ) ;
actionReportBug - > setText ( tr ( " Report a Bug " ) ) ;
actionReportBug - > setToolTip ( tr ( " Open the bug tracker to report a bug with MultiMC. " ) ) ;
actionPatreon - > setText ( tr ( " Support us on Patreon! " ) ) ;
actionPatreon - > setToolTip ( tr ( " Open the MultiMC Patreon page. " ) ) ;
actionMoreNews - > setText ( tr ( " More news... " ) ) ;
actionMoreNews - > setToolTip ( tr ( " Open the MultiMC development blog to read more news about MultiMC. " ) ) ;
actionAbout - > setText ( tr ( " About MultiMC " ) ) ;
actionAbout - > setToolTip ( tr ( " View information about MultiMC. " ) ) ;
actionLaunchInstance - > setText ( tr ( " Play " ) ) ;
actionLaunchInstance - > setToolTip ( tr ( " Launch the selected instance. " ) ) ;
actionRenameInstance - > setText ( tr ( " Instance Name " ) ) ;
actionRenameInstance - > setToolTip ( tr ( " Rename the selected instance. " ) ) ;
actionChangeInstGroup - > setText ( tr ( " Change Group " ) ) ;
actionChangeInstGroup - > setToolTip ( tr ( " Change the selected instance's group. " ) ) ;
actionChangeInstIcon - > setText ( tr ( " Change Icon " ) ) ;
actionChangeInstIcon - > setToolTip ( tr ( " Change the selected instance's icon. " ) ) ;
actionEditInstNotes - > setText ( tr ( " Edit Notes " ) ) ;
actionEditInstNotes - > setToolTip ( tr ( " Edit the notes for the selected instance. " ) ) ;
2016-11-02 01:33:55 +00:00
actionWorlds - > setText ( tr ( " View Worlds " ) ) ;
actionWorlds - > setToolTip ( tr ( " View the worlds of this instance. " ) ) ;
2016-11-02 00:17:19 +00:00
actionEditInstance - > setText ( tr ( " Edit Instance " ) ) ;
actionEditInstance - > setToolTip ( tr ( " Change the instance settings, mods and versions. " ) ) ;
actionViewSelectedInstFolder - > setText ( tr ( " Instance Folder " ) ) ;
actionViewSelectedInstFolder - > setToolTip ( tr ( " Open the selected instance's root folder in a file browser. " ) ) ;
actionDeleteInstance - > setText ( tr ( " Delete " ) ) ;
actionDeleteInstance - > setToolTip ( tr ( " Delete the selected instance. " ) ) ;
actionConfig_Folder - > setText ( tr ( " Config Folder " ) ) ;
actionConfig_Folder - > setToolTip ( tr ( " Open the instance's config folder. " ) ) ;
actionCAT - > setText ( tr ( " Meow " ) ) ;
actionCAT - > setToolTip ( tr ( " It's a fluffy kitty :3 " ) ) ;
actionREDDIT - > setText ( tr ( " Reddit " ) ) ;
actionREDDIT - > setToolTip ( tr ( " Open MultiMC subreddit. " ) ) ;
actionDISCORD - > setText ( tr ( " Discord " ) ) ;
actionDISCORD - > setToolTip ( tr ( " Open MultiMC discord voice chat. " ) ) ;
actionCopyInstance - > setText ( tr ( " Copy Instance " ) ) ;
actionCopyInstance - > setToolTip ( tr ( " Copy the selected instance. " ) ) ;
actionManageAccounts - > setText ( tr ( " Manage Accounts " ) ) ;
actionManageAccounts - > setToolTip ( tr ( " Manage your Mojang or Minecraft accounts. " ) ) ;
actionLaunchInstanceOffline - > setText ( tr ( " Play Offline " ) ) ;
actionLaunchInstanceOffline - > setToolTip ( tr ( " Launch the selected instance in offline mode. " ) ) ;
actionScreenshots - > setText ( tr ( " Manage Screenshots " ) ) ;
actionScreenshots - > setToolTip ( tr ( " View and upload screenshots for this instance. " ) ) ;
actionInstanceSettings - > setText ( tr ( " Instance Settings " ) ) ;
actionInstanceSettings - > setToolTip ( tr ( " Change the settings specific to the instance. " ) ) ;
actionExportInstance - > setText ( tr ( " Export Instance " ) ) ;
mainToolBar - > setWindowTitle ( tr ( " Main Toolbar " ) ) ;
instanceToolBar - > setWindowTitle ( tr ( " Instance Toolbar " ) ) ;
newsToolBar - > setWindowTitle ( tr ( " News Toolbar " ) ) ;
2015-03-01 21:20:57 +00:00
} // retranslateUi
} ;
2015-10-20 16:18:53 +01:00
MainWindow : : MainWindow ( QWidget * parent ) : QMainWindow ( parent ) , ui ( new MainWindow : : Ui )
2013-01-09 18:22:22 +00:00
{
2013-10-06 00:13:40 +01:00
ui - > setupUi ( this ) ;
2014-01-09 00:02:15 +00:00
2015-10-20 16:18:53 +01:00
QString winTitle = tr ( " MultiMC 5 - Version %1 " ) . arg ( BuildConfig . printableVersionString ( ) ) ;
2014-04-05 21:58:47 +01:00
if ( ! BuildConfig . BUILD_PLATFORM . isEmpty ( ) )
2015-10-20 16:18:53 +01:00
{
2016-01-03 15:03:49 +00:00
winTitle + = tr ( " on %1 " , " on platform, as in operating system " ) . arg ( BuildConfig . BUILD_PLATFORM ) ;
2015-10-20 16:18:53 +01:00
}
2014-01-09 00:02:15 +00:00
setWindowTitle ( winTitle ) ;
2013-10-06 00:13:40 +01:00
2013-08-27 15:50:42 +01:00
// OSX magic.
2014-10-19 17:19:37 +01:00
setUnifiedTitleAndToolBarOnMac ( true ) ;
2013-10-06 00:13:40 +01:00
2014-04-17 13:49:03 +01:00
// Global shortcuts
{
2014-06-27 23:05:00 +01:00
// FIXME: This is kinda weird. and bad. We need some kind of managed shutdown.
2014-04-17 13:49:03 +01:00
auto q = new QShortcut ( QKeySequence : : Quit , this ) ;
2014-04-21 20:48:58 +01:00
connect ( q , SIGNAL ( activated ( ) ) , qApp , SLOT ( quit ( ) ) ) ;
2014-04-17 13:49:03 +01:00
}
2013-08-26 06:09:54 +01:00
// The instance action toolbar customizations
{
2013-11-03 20:28:04 +00:00
// disabled until we have an instance selected
2013-08-26 06:09:54 +01:00
ui - > instanceToolBar - > setEnabled ( false ) ;
2013-11-03 20:28:04 +00:00
2013-08-26 06:09:54 +01:00
// the rename label is inside the rename tool button
renameButton = new LabeledToolButton ( ) ;
renameButton - > setText ( " Instance Name " ) ;
2013-08-27 04:39:49 +01:00
renameButton - > setToolTip ( ui - > actionRenameInstance - > toolTip ( ) ) ;
2013-08-26 06:09:54 +01:00
connect ( renameButton , SIGNAL ( clicked ( bool ) ) , SLOT ( on_actionRenameInstance_triggered ( ) ) ) ;
ui - > instanceToolBar - > insertWidget ( ui - > actionLaunchInstance , renameButton ) ;
ui - > instanceToolBar - > insertSeparator ( ui - > actionLaunchInstance ) ;
2013-10-06 00:13:40 +01:00
renameButton - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Preferred ) ;
2013-08-26 06:09:54 +01:00
}
2013-10-06 00:13:40 +01:00
2014-01-02 19:25:38 +00:00
// Add the news label to the news toolbar.
{
2015-10-20 16:18:53 +01:00
m_newsChecker . reset ( new NewsChecker ( BuildConfig . NEWS_RSS_URL ) ) ;
2014-01-02 19:25:38 +00:00
newsLabel = new QToolButton ( ) ;
2015-03-01 21:20:57 +00:00
newsLabel - > setIcon ( MMC - > getThemedIcon ( " news " ) ) ;
2014-01-02 19:25:38 +00:00
newsLabel - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Preferred ) ;
newsLabel - > setToolButtonStyle ( Qt : : ToolButtonTextBesideIcon ) ;
ui - > newsToolBar - > insertWidget ( ui - > actionMoreNews , newsLabel ) ;
2015-10-20 16:22:13 +01:00
QObject : : connect ( newsLabel , & QAbstractButton : : clicked , this , & MainWindow : : newsButtonClicked ) ;
QObject : : connect ( m_newsChecker . get ( ) , & NewsChecker : : newsLoaded , this , & MainWindow : : updateNewsLabel ) ;
2014-01-02 19:25:38 +00:00
updateNewsLabel ( ) ;
}
2013-08-26 06:09:54 +01:00
// Create the instance list widget
{
2014-02-04 00:40:51 +00:00
view = new GroupView ( ui - > centralWidget ) ;
2013-10-06 00:13:40 +01:00
view - > setSelectionMode ( QAbstractItemView : : SingleSelection ) ;
2016-08-19 08:04:58 +01:00
// FIXME: leaks ListViewDelegate
view - > setItemDelegate ( new ListViewDelegate ( this ) ) ;
2015-10-20 16:18:53 +01:00
view - > setFrameShape ( QFrame : : NoFrame ) ;
2013-08-27 15:50:42 +01:00
// do not show ugly blue border on the mac
2013-08-27 15:20:32 +01:00
view - > setAttribute ( Qt : : WA_MacShowFocusRect , false ) ;
2013-10-06 00:13:40 +01:00
2013-08-26 06:09:54 +01:00
view - > installEventFilter ( this ) ;
2015-10-20 16:18:53 +01:00
view - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
connect ( view , & QWidget : : customContextMenuRequested , this , & MainWindow : : showInstanceContextMenu ) ;
2013-03-11 21:19:17 +00:00
2013-10-06 00:13:40 +01:00
proxymodel = new InstanceProxyModel ( this ) ;
proxymodel - > setSourceModel ( MMC - > instances ( ) . get ( ) ) ;
proxymodel - > sort ( 0 ) ;
2015-10-20 16:18:53 +01:00
connect ( proxymodel , & InstanceProxyModel : : dataChanged , this , & MainWindow : : instanceDataChanged ) ;
2014-01-05 00:06:59 +00:00
2015-10-20 16:18:53 +01:00
view - > setModel ( proxymodel ) ;
2013-10-06 00:13:40 +01:00
ui - > horizontalLayout - > addWidget ( view ) ;
2013-08-26 06:09:54 +01:00
}
// The cat background
{
2013-09-07 03:00:58 +01:00
bool cat_enable = MMC - > settings ( ) - > get ( " TheCat " ) . toBool ( ) ;
2013-08-26 06:09:54 +01:00
ui - > actionCAT - > setChecked ( cat_enable ) ;
connect ( ui - > actionCAT , SIGNAL ( toggled ( bool ) ) , SLOT ( onCatToggled ( bool ) ) ) ;
setCatBackground ( cat_enable ) ;
}
// start instance when double-clicked
2015-10-20 16:18:53 +01:00
connect ( view , & GroupView : : doubleClicked , this , & MainWindow : : instanceActivated ) ;
2013-08-26 06:09:54 +01:00
// track the selection -- update the instance toolbar
2015-10-20 16:18:53 +01:00
connect ( view - > selectionModel ( ) , & QItemSelectionModel : : currentChanged , this , & MainWindow : : instanceChanged ) ;
2013-12-31 00:24:28 +00:00
// track icon changes and update the toolbar!
2016-04-10 03:29:29 +01:00
connect ( MMC - > icons ( ) . get ( ) , & IconList : : iconUpdated , this , & MainWindow : : iconUpdated ) ;
2013-12-31 00:24:28 +00:00
2013-08-26 06:09:54 +01:00
// model reset -> selection is invalid. All the instance pointers are wrong.
2015-10-20 16:18:53 +01:00
connect ( MMC - > instances ( ) . get ( ) , & InstanceList : : dataIsInvalid , this , & MainWindow : : selectionBad ) ;
2013-10-06 00:13:40 +01:00
2014-01-02 19:47:34 +00:00
m_statusLeft = new QLabel ( tr ( " No instance selected " ) , this ) ;
2014-05-15 21:32:54 +01:00
m_statusRight = new ServerStatus ( this ) ;
2013-10-26 02:28:50 +01:00
statusBar ( ) - > addPermanentWidget ( m_statusLeft , 1 ) ;
2014-01-12 18:28:42 +00:00
statusBar ( ) - > addPermanentWidget ( m_statusRight , 0 ) ;
2013-10-26 02:28:50 +01:00
2013-11-27 16:56:15 +00:00
// Add "manage accounts" button, right align
2013-12-15 17:10:51 +00:00
QWidget * spacer = new QWidget ( ) ;
2013-11-27 16:56:15 +00:00
spacer - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
ui - > mainToolBar - > addWidget ( spacer ) ;
2013-11-27 22:39:49 +00:00
accountMenu = new QMenu ( this ) ;
2013-11-28 21:46:04 +00:00
manageAccountsAction = new QAction ( tr ( " Manage Accounts " ) , this ) ;
2013-11-27 22:39:49 +00:00
manageAccountsAction - > setCheckable ( false ) ;
2015-10-20 16:18:53 +01:00
manageAccountsAction - > setIcon ( MMC - > getThemedIcon ( " accounts " ) ) ;
2015-10-20 16:22:13 +01:00
connect ( manageAccountsAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( on_actionManageAccounts_triggered ( ) ) ) ;
2013-11-27 22:39:49 +00:00
repopulateAccountsMenu ( ) ;
accountMenuButton = new QToolButton ( this ) ;
2015-08-14 01:27:01 +01:00
accountMenuButton - > setText ( tr ( " Profiles " ) ) ;
2013-11-27 22:39:49 +00:00
accountMenuButton - > setMenu ( accountMenu ) ;
accountMenuButton - > setPopupMode ( QToolButton : : InstantPopup ) ;
accountMenuButton - > setToolButtonStyle ( Qt : : ToolButtonTextBesideIcon ) ;
2015-03-01 21:20:57 +00:00
accountMenuButton - > setIcon ( MMC - > getThemedIcon ( " noaccount " ) ) ;
2013-11-27 22:39:49 +00:00
QWidgetAction * accountMenuButtonAction = new QWidgetAction ( this ) ;
accountMenuButtonAction - > setDefaultWidget ( accountMenuButton ) ;
ui - > mainToolBar - > addAction ( accountMenuButtonAction ) ;
2013-11-27 16:56:15 +00:00
2013-11-28 21:46:04 +00:00
// Update the menu when the active account changes.
2013-12-15 17:10:51 +00:00
// Shouldn't have to use lambdas here like this, but if I don't, the compiler throws a fit.
// Template hell sucks...
connect ( MMC - > accounts ( ) . get ( ) , & MojangAccountList : : activeAccountChanged , [ this ]
2015-10-20 16:22:13 +01:00
{
activeAccountChanged ( ) ;
} ) ;
2013-12-15 17:10:51 +00:00
connect ( MMC - > accounts ( ) . get ( ) , & MojangAccountList : : listChanged , [ this ]
2015-10-20 16:22:13 +01:00
{
repopulateAccountsMenu ( ) ;
} ) ;
2013-11-28 21:46:04 +00:00
2014-01-11 00:22:08 +00:00
// Show initial account
activeAccountChanged ( ) ;
auto accounts = MMC - > accounts ( ) ;
2013-11-27 18:45:29 +00:00
2016-05-28 18:54:17 +01:00
QList < Net : : Download : : Ptr > skin_dls ;
2013-12-15 17:10:51 +00:00
for ( int i = 0 ; i < accounts - > count ( ) ; i + + )
2013-11-27 22:47:15 +00:00
{
2014-01-11 00:22:08 +00:00
auto account = accounts - > at ( i ) ;
2015-10-20 16:18:53 +01:00
if ( ! account )
2013-11-27 18:45:29 +00:00
{
2015-10-20 16:18:53 +01:00
qWarning ( ) < < " Null account at index " < < i ;
continue ;
}
for ( auto profile : account - > profiles ( ) )
{
auto meta = Env : : getInstance ( ) . metacache ( ) - > resolveEntry ( " skins " , profile . id + " .png " ) ;
2016-05-28 18:54:17 +01:00
auto action = Net : : Download : : makeCached ( QUrl ( " https:// " + URLConstants : : SKINS_BASE + profile . id + " .png " ) , meta ) ;
2015-10-20 16:18:53 +01:00
skin_dls . append ( action ) ;
2016-03-26 15:56:57 +00:00
meta - > setStale ( true ) ;
2013-11-27 22:47:15 +00:00
}
2013-11-27 18:45:29 +00:00
}
2014-06-27 23:05:00 +01:00
if ( ! skin_dls . isEmpty ( ) )
{
auto job = new NetJob ( " Startup player skins download " ) ;
2015-04-26 12:47:14 +01:00
connect ( job , & NetJob : : succeeded , this , & MainWindow : : skinJobFinished ) ;
connect ( job , & NetJob : : failed , this , & MainWindow : : skinJobFinished ) ;
2014-06-27 23:05:00 +01:00
for ( auto action : skin_dls )
2015-01-11 21:04:31 +00:00
{
2014-06-27 23:05:00 +01:00
job - > addNetAction ( action ) ;
2015-01-11 21:04:31 +00:00
}
2014-06-27 23:05:00 +01:00
skin_download_job . reset ( job ) ;
job - > start ( ) ;
}
2013-11-27 16:56:15 +00:00
2013-08-26 06:09:54 +01:00
// run the things that load and download other things... FIXME: this is NOT the place
// FIXME: invisible actions in the background = NOPE.
2013-05-17 17:53:22 +01:00
{
2013-09-15 23:54:39 +01:00
if ( ! MMC - > minecraftlist ( ) - > isLoaded ( ) )
2013-08-26 06:09:54 +01:00
{
2013-09-15 23:54:39 +01:00
m_versionLoadTask = MMC - > minecraftlist ( ) - > getLoadTask ( ) ;
2013-08-26 06:09:54 +01:00
startTask ( m_versionLoadTask ) ;
}
2013-09-15 23:54:39 +01:00
if ( ! MMC - > lwjgllist ( ) - > isLoaded ( ) )
2013-08-26 06:09:54 +01:00
{
2013-09-15 23:54:39 +01:00
MMC - > lwjgllist ( ) - > loadList ( ) ;
2013-08-26 06:09:54 +01:00
}
2013-11-17 11:08:07 +00:00
2015-01-27 21:31:07 +00:00
m_newsChecker - > reloadNews ( ) ;
2014-01-02 19:25:38 +00:00
updateNewsLabel ( ) ;
2015-12-28 03:45:49 +00:00
}
2013-12-15 20:48:58 +00:00
2015-12-28 03:45:49 +00:00
if ( BuildConfig . UPDATER_ENABLED )
{
2013-12-01 23:55:24 +00:00
// set up the updater object.
2013-12-04 18:34:12 +00:00
auto updater = MMC - > updateChecker ( ) ;
2015-10-20 16:22:13 +01:00
connect ( updater . get ( ) , & UpdateChecker : : updateAvailable , this , & MainWindow : : updateAvailable ) ;
connect ( updater . get ( ) , & UpdateChecker : : noUpdateFound , this , & MainWindow : : updateNotAvailable ) ;
2013-12-01 23:55:24 +00:00
// if automatic update checks are allowed, start one.
2013-12-15 17:10:51 +00:00
if ( MMC - > settings ( ) - > get ( " AutoUpdate " ) . toBool ( ) )
2014-07-14 00:11:52 +01:00
{
2015-01-31 15:59:03 +00:00
updater - > checkForUpdate ( MMC - > settings ( ) - > get ( " UpdateChannel " ) . toString ( ) , false ) ;
2014-07-14 00:11:52 +01:00
}
2015-12-28 03:45:49 +00:00
}
{
2015-02-07 11:55:18 +00:00
auto checker = new NotificationChecker ( ) ;
checker - > setNotificationsUrl ( QUrl ( BuildConfig . NOTIFICATION_URL ) ) ;
checker - > setApplicationChannel ( BuildConfig . VERSION_CHANNEL ) ;
checker - > setApplicationPlatform ( BuildConfig . BUILD_PLATFORM ) ;
checker - > setApplicationFullVersion ( BuildConfig . FULL_VERSION_STR ) ;
m_notificationChecker . reset ( checker ) ;
2015-10-20 16:22:13 +01:00
connect ( m_notificationChecker . get ( ) , & NotificationChecker : : notificationCheckFinished , this , & MainWindow : : notificationsChanged ) ;
2015-02-07 11:55:18 +00:00
checker - > checkForNotifications ( ) ;
2013-05-17 17:53:22 +01:00
}
2013-11-27 14:00:44 +00:00
2014-01-06 09:01:40 +00:00
setSelectedInstanceById ( MMC - > settings ( ) - > get ( " SelectedInstance " ) . toString ( ) ) ;
2013-11-27 14:00:44 +00:00
// removing this looks stupid
view - > setFocus ( ) ;
2013-01-09 18:22:22 +00:00
}
MainWindow : : ~ MainWindow ( )
{
2013-03-11 21:19:17 +00:00
}
2014-03-30 19:11:05 +01:00
void MainWindow : : skinJobFinished ( )
{
2014-06-27 23:05:00 +01:00
activeAccountChanged ( ) ;
skin_download_job . reset ( ) ;
2014-03-30 19:11:05 +01:00
}
2014-01-27 02:00:49 +00:00
void MainWindow : : showInstanceContextMenu ( const QPoint & pos )
2014-01-05 00:06:59 +00:00
{
2014-04-07 23:16:49 +01:00
QList < QAction * > actions ;
QAction * actionSep = new QAction ( " " , this ) ;
actionSep - > setSeparator ( true ) ;
bool onInstance = view - > indexAt ( pos ) . isValid ( ) ;
if ( onInstance )
2014-01-05 00:06:59 +00:00
{
2014-04-07 23:16:49 +01:00
actions = ui - > instanceToolBar - > actions ( ) ;
QAction * actionVoid = new QAction ( m_selectedInstance - > name ( ) , this ) ;
actionVoid - > setEnabled ( false ) ;
QAction * actionRename = new QAction ( tr ( " Rename " ) , this ) ;
actionRename - > setToolTip ( ui - > actionRenameInstance - > toolTip ( ) ) ;
2014-01-05 00:06:59 +00:00
2014-04-07 23:16:49 +01:00
QAction * actionCopyInstance = new QAction ( tr ( " Copy instance " ) , this ) ;
actionCopyInstance - > setToolTip ( ui - > actionCopyInstance - > toolTip ( ) ) ;
2014-01-05 00:06:59 +00:00
2015-10-20 16:22:13 +01:00
connect ( actionRename , SIGNAL ( triggered ( bool ) ) , SLOT ( on_actionRenameInstance_triggered ( ) ) ) ;
connect ( actionCopyInstance , SIGNAL ( triggered ( bool ) ) , SLOT ( on_actionCopyInstance_triggered ( ) ) ) ;
2014-01-05 00:06:59 +00:00
2014-04-07 23:16:49 +01:00
actions . replace ( 1 , actionRename ) ;
actions . prepend ( actionSep ) ;
actions . prepend ( actionVoid ) ;
actions . append ( actionCopyInstance ) ;
}
else
{
2016-04-11 00:30:50 +01:00
auto group = view - > groupNameAt ( pos ) ;
2016-03-22 22:28:47 +00:00
QAction * actionVoid = new QAction ( " MultiMC " , this ) ;
2014-04-07 23:16:49 +01:00
actionVoid - > setEnabled ( false ) ;
QAction * actionCreateInstance = new QAction ( tr ( " Create instance " ) , this ) ;
actionCreateInstance - > setToolTip ( ui - > actionAddInstance - > toolTip ( ) ) ;
2016-04-11 00:30:50 +01:00
if ( ! group . isNull ( ) )
{
QVariantMap data ;
data [ " group " ] = group ;
actionCreateInstance - > setData ( data ) ;
}
2014-01-05 00:06:59 +00:00
2015-10-20 16:22:13 +01:00
connect ( actionCreateInstance , SIGNAL ( triggered ( bool ) ) , SLOT ( on_actionAddInstance_triggered ( ) ) ) ;
2014-04-07 23:16:49 +01:00
actions . prepend ( actionSep ) ;
actions . prepend ( actionVoid ) ;
actions . append ( actionCreateInstance ) ;
2016-04-11 00:30:50 +01:00
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 ( on_actionDeleteGroup_triggered ( ) ) ) ;
actions . append ( actionDeleteGroup ) ;
}
2014-04-07 23:16:49 +01:00
}
2014-01-05 00:06:59 +00:00
QMenu myMenu ;
myMenu . addActions ( actions ) ;
2014-06-27 23:05:00 +01:00
if ( onInstance )
2014-04-07 23:16:49 +01:00
myMenu . setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
2014-01-05 00:06:59 +00:00
myMenu . exec ( view - > mapToGlobal ( pos ) ) ;
}
2014-02-16 10:49:55 +00:00
void MainWindow : : updateToolsMenu ( )
{
2015-05-02 11:07:18 +01:00
QMenu * launchMenu = ui - > actionLaunchInstance - > menu ( ) ;
2016-11-01 22:33:20 +00:00
QToolButton * launchButton = dynamic_cast < QToolButton * > ( ui - > instanceToolBar - > widgetForAction ( ui - > actionLaunchInstance ) ) ;
launchButton - > setPopupMode ( QToolButton : : MenuButtonPopup ) ;
2015-10-20 16:22:13 +01:00
if ( launchMenu )
2014-02-16 10:49:55 +00:00
{
2015-05-02 11:07:18 +01:00
launchMenu - > clear ( ) ;
2014-02-16 10:49:55 +00:00
}
2015-05-02 11:07:18 +01:00
else
{
launchMenu = new QMenu ( this ) ;
}
2014-02-16 10:49:55 +00:00
QAction * normalLaunch = launchMenu - > addAction ( tr ( " Launch " ) ) ;
2014-06-27 23:05:00 +01:00
connect ( normalLaunch , & QAction : : triggered , [ this ] ( )
2015-10-20 16:22:13 +01:00
{
2016-10-30 01:37:38 +00:00
MMC - > launch ( m_selectedInstance ) ;
2015-10-20 16:22:13 +01:00
} ) ;
2014-02-16 10:49:55 +00:00
launchMenu - > addSeparator ( ) - > setText ( tr ( " Profilers " ) ) ;
for ( auto profiler : MMC - > profilers ( ) . values ( ) )
{
QAction * profilerAction = launchMenu - > addAction ( profiler - > name ( ) ) ;
QString error ;
if ( ! profiler - > check ( & error ) )
{
profilerAction - > setDisabled ( true ) ;
2015-10-20 16:22:13 +01:00
profilerAction - > setToolTip ( tr ( " Profiler not setup correctly. Go into settings, \" External Tools \" . " ) ) ;
2014-02-16 10:49:55 +00:00
}
else
{
2014-06-27 23:05:00 +01:00
connect ( profilerAction , & QAction : : triggered , [ this , profiler ] ( )
2015-10-20 16:22:13 +01:00
{
2016-10-30 01:37:38 +00:00
MMC - > launch ( m_selectedInstance , true , profiler . get ( ) ) ;
2015-10-20 16:22:13 +01:00
} ) ;
2014-02-16 10:49:55 +00:00
}
}
ui - > actionLaunchInstance - > setMenu ( launchMenu ) ;
}
2013-11-27 22:39:49 +00:00
void MainWindow : : repopulateAccountsMenu ( )
{
accountMenu - > clear ( ) ;
std : : shared_ptr < MojangAccountList > accounts = MMC - > accounts ( ) ;
2013-11-27 23:39:36 +00:00
MojangAccountPtr active_account = accounts - > activeAccount ( ) ;
2013-11-27 22:39:49 +00:00
2013-11-27 23:39:36 +00:00
QString active_username = " " ;
2013-11-28 21:46:04 +00:00
if ( active_account ! = nullptr )
2013-11-27 22:39:49 +00:00
{
active_username = accounts - > activeAccount ( ) - > username ( ) ;
}
2013-11-28 21:46:04 +00:00
if ( accounts - > count ( ) < = 0 )
2013-11-27 22:39:49 +00:00
{
QAction * action = new QAction ( tr ( " No accounts added! " ) , this ) ;
action - > setEnabled ( false ) ;
accountMenu - > addAction ( action ) ;
}
else
{
// TODO: Nicer way to iterate?
2013-11-28 21:46:04 +00:00
for ( int i = 0 ; i < accounts - > count ( ) ; i + + )
2013-11-27 22:39:49 +00:00
{
MojangAccountPtr account = accounts - > at ( i ) ;
2013-12-05 01:39:52 +00:00
for ( auto profile : account - > profiles ( ) )
2013-11-27 22:39:49 +00:00
{
2013-12-05 01:39:52 +00:00
QAction * action = new QAction ( profile . name , this ) ;
2013-11-27 22:39:49 +00:00
action - > setData ( account - > username ( ) ) ;
action - > setCheckable ( true ) ;
2013-12-15 17:10:51 +00:00
if ( active_username = = account - > username ( ) )
2013-11-27 22:39:49 +00:00
{
action - > setChecked ( true ) ;
}
2015-09-28 21:43:57 +01:00
action - > setIcon ( SkinUtils : : getFaceFromCache ( profile . id ) ) ;
2013-11-27 22:39:49 +00:00
accountMenu - > addAction ( action ) ;
connect ( action , SIGNAL ( triggered ( bool ) ) , SLOT ( changeActiveAccount ( ) ) ) ;
}
}
}
2015-08-14 01:27:01 +01:00
accountMenu - > addSeparator ( ) ;
2013-11-28 21:46:04 +00:00
QAction * action = new QAction ( tr ( " No Default Account " ) , this ) ;
2013-11-27 23:39:36 +00:00
action - > setCheckable ( true ) ;
2015-03-01 21:20:57 +00:00
action - > setIcon ( MMC - > getThemedIcon ( " noaccount " ) ) ;
2013-11-27 23:39:36 +00:00
action - > setData ( " " ) ;
2013-12-15 17:10:51 +00:00
if ( active_username . isEmpty ( ) )
2013-11-27 23:39:36 +00:00
{
action - > setChecked ( true ) ;
}
accountMenu - > addAction ( action ) ;
connect ( action , SIGNAL ( triggered ( bool ) ) , SLOT ( changeActiveAccount ( ) ) ) ;
accountMenu - > addSeparator ( ) ;
2013-11-27 22:39:49 +00:00
accountMenu - > addAction ( manageAccountsAction ) ;
}
/*
* Assumes the sender is a QAction
*/
void MainWindow : : changeActiveAccount ( )
{
2013-12-15 17:10:51 +00:00
QAction * sAction = ( QAction * ) sender ( ) ;
2013-11-27 22:39:49 +00:00
// Profile's associated Mojang username
2013-11-28 21:46:04 +00:00
// Will need to change when profiles are properly implemented
2013-12-15 17:10:51 +00:00
if ( sAction - > data ( ) . type ( ) ! = QVariant : : Type : : String )
return ;
2013-11-27 22:39:49 +00:00
2013-11-27 23:39:36 +00:00
QVariant data = sAction - > data ( ) ;
QString id = " " ;
2013-11-28 21:46:04 +00:00
if ( ! data . isNull ( ) )
2013-11-27 22:39:49 +00:00
{
2013-11-27 23:39:36 +00:00
id = data . toString ( ) ;
2013-11-27 22:39:49 +00:00
}
2013-11-27 23:39:36 +00:00
MMC - > accounts ( ) - > setActiveAccount ( id ) ;
2013-11-27 22:39:49 +00:00
activeAccountChanged ( ) ;
}
2013-11-27 16:56:15 +00:00
void MainWindow : : activeAccountChanged ( )
{
2013-11-27 22:39:49 +00:00
repopulateAccountsMenu ( ) ;
2013-11-27 16:56:15 +00:00
MojangAccountPtr account = MMC - > accounts ( ) - > activeAccount ( ) ;
2013-11-28 21:46:04 +00:00
if ( account ! = nullptr & & account - > username ( ) ! = " " )
2013-11-27 16:56:15 +00:00
{
2013-11-27 18:45:29 +00:00
const AccountProfile * profile = account - > currentProfile ( ) ;
2013-11-28 21:46:04 +00:00
if ( profile ! = nullptr )
2013-11-27 18:45:29 +00:00
{
2015-09-28 21:43:57 +01:00
accountMenuButton - > setIcon ( SkinUtils : : getFaceFromCache ( profile - > id ) ) ;
2015-08-14 01:27:01 +01:00
accountMenuButton - > setText ( profile - > name ) ;
2013-11-27 22:39:49 +00:00
return ;
2013-11-27 18:45:29 +00:00
}
2013-11-27 16:56:15 +00:00
}
2013-11-27 22:39:49 +00:00
2013-11-28 21:46:04 +00:00
// Set the icon to the "no account" icon.
2015-03-01 21:20:57 +00:00
accountMenuButton - > setIcon ( MMC - > getThemedIcon ( " noaccount " ) ) ;
2015-08-14 01:27:01 +01:00
accountMenuButton - > setText ( tr ( " Profiles " ) ) ;
2013-11-27 16:56:15 +00:00
}
2013-10-06 00:13:40 +01:00
bool MainWindow : : eventFilter ( QObject * obj , QEvent * ev )
2013-08-11 23:39:19 +01:00
{
2013-10-06 00:13:40 +01:00
if ( obj = = view )
2013-08-11 23:39:19 +01:00
{
if ( ev - > type ( ) = = QEvent : : KeyPress )
{
2013-10-06 00:13:40 +01:00
QKeyEvent * keyEvent = static_cast < QKeyEvent * > ( ev ) ;
switch ( keyEvent - > key ( ) )
2013-08-11 23:39:19 +01:00
{
2013-10-06 00:13:40 +01:00
case Qt : : Key_Enter :
case Qt : : Key_Return :
on_actionLaunchInstance_triggered ( ) ;
return true ;
case Qt : : Key_Delete :
on_actionDeleteInstance_triggered ( ) ;
return true ;
case Qt : : Key_F5 :
on_actionRefresh_triggered ( ) ;
return true ;
case Qt : : Key_F2 :
on_actionRenameInstance_triggered ( ) ;
return true ;
default :
break ;
2013-08-11 23:39:19 +01:00
}
}
}
2013-10-06 00:13:40 +01:00
return QMainWindow : : eventFilter ( obj , ev ) ;
2013-08-11 23:39:19 +01:00
}
2014-01-02 19:25:38 +00:00
void MainWindow : : updateNewsLabel ( )
{
2015-01-27 21:31:07 +00:00
if ( m_newsChecker - > isLoadingNews ( ) )
2014-01-02 19:25:38 +00:00
{
newsLabel - > setText ( tr ( " Loading news... " ) ) ;
newsLabel - > setEnabled ( false ) ;
}
else
{
2015-01-27 21:31:07 +00:00
QList < NewsEntryPtr > entries = m_newsChecker - > getNewsEntries ( ) ;
2014-01-02 19:25:38 +00:00
if ( entries . length ( ) > 0 )
{
newsLabel - > setText ( entries [ 0 ] - > title ) ;
newsLabel - > setEnabled ( true ) ;
}
else
{
newsLabel - > setText ( tr ( " No news available. " ) ) ;
newsLabel - > setEnabled ( false ) ;
}
}
}
2015-02-08 16:56:14 +00:00
void MainWindow : : updateAvailable ( GoUpdate : : Status status )
2013-12-01 23:55:24 +00:00
{
UpdateDialog dlg ;
2013-12-15 17:10:51 +00:00
UpdateAction action = ( UpdateAction ) dlg . exec ( ) ;
switch ( action )
2013-12-01 23:55:24 +00:00
{
2013-12-15 17:10:51 +00:00
case UPDATE_LATER :
2015-02-02 01:14:14 +00:00
qDebug ( ) < < " Update will be installed later. " ;
2013-12-15 17:10:51 +00:00
break ;
case UPDATE_NOW :
2015-02-08 16:56:14 +00:00
downloadUpdates ( status ) ;
2013-12-15 17:10:51 +00:00
break ;
2013-12-01 23:55:24 +00:00
}
}
2014-07-13 23:57:54 +01:00
void MainWindow : : updateNotAvailable ( )
{
UpdateDialog dlg ( false ) ;
dlg . exec ( ) ;
}
2014-01-03 18:19:27 +00:00
QList < int > stringToIntList ( const QString & string )
{
QStringList split = string . split ( ' , ' , QString : : SkipEmptyParts ) ;
QList < int > out ;
for ( int i = 0 ; i < split . size ( ) ; + + i )
{
out . append ( split . at ( i ) . toInt ( ) ) ;
}
return out ;
}
QString intListToString ( const QList < int > & list )
{
QStringList slist ;
for ( int i = 0 ; i < list . size ( ) ; + + i )
{
slist . append ( QString : : number ( list . at ( i ) ) ) ;
}
return slist . join ( ' , ' ) ;
}
void MainWindow : : notificationsChanged ( )
{
2015-10-20 16:22:13 +01:00
QList < NotificationChecker : : NotificationEntry > entries = m_notificationChecker - > notificationEntries ( ) ;
QList < int > shownNotifications = stringToIntList ( MMC - > settings ( ) - > get ( " ShownNotifications " ) . toString ( ) ) ;
2014-01-03 18:19:27 +00:00
for ( auto it = entries . begin ( ) ; it ! = entries . end ( ) ; + + it )
{
NotificationChecker : : NotificationEntry entry = * it ;
2015-02-07 11:55:18 +00:00
if ( ! shownNotifications . contains ( entry . id ) )
2014-01-03 18:19:27 +00:00
{
2014-03-15 13:18:29 +00:00
NotificationDialog dialog ( entry , this ) ;
if ( dialog . exec ( ) = = NotificationDialog : : DontShowAgain )
2014-01-03 20:05:03 +00:00
{
shownNotifications . append ( entry . id ) ;
}
2014-01-03 18:19:27 +00:00
}
}
MMC - > settings ( ) - > set ( " ShownNotifications " , intListToString ( shownNotifications ) ) ;
}
2015-06-07 22:42:22 +01:00
void MainWindow : : downloadUpdates ( GoUpdate : : Status status )
2013-12-06 18:59:58 +00:00
{
2015-02-02 01:14:14 +00:00
qDebug ( ) < < " Downloading updates. " ;
2013-12-06 18:59:58 +00:00
ProgressDialog updateDlg ( this ) ;
2016-10-30 01:37:38 +00:00
status . rootPath = MMC - > root ( ) ;
2015-02-08 16:56:14 +00:00
2015-10-05 00:47:27 +01:00
auto dlPath = FS : : PathCombine ( MMC - > root ( ) , " update " , " XXXXXX " ) ;
2015-10-20 16:22:13 +01:00
if ( ! FS : : ensureFilePathExists ( dlPath ) )
2015-06-09 23:46:45 +01:00
{
CustomMessageBox : : selectable ( this , tr ( " Error " ) , tr ( " Couldn't create folder for update downloads: \n %1 " ) . arg ( dlPath ) , QMessageBox : : Warning ) - > show ( ) ;
}
2015-06-09 22:23:46 +01:00
GoUpdate : : DownloadTask updateTask ( status , dlPath , & updateDlg ) ;
2013-12-06 18:59:58 +00:00
// If the task succeeds, install the updates.
2015-09-26 03:04:09 +01:00
if ( updateDlg . execWithTask ( & updateTask ) )
2013-12-06 18:59:58 +00:00
{
2015-06-08 01:43:16 +01:00
MMC - > installUpdates ( updateTask . updateFilesDir ( ) , updateTask . operations ( ) ) ;
2013-12-06 18:59:58 +00:00
}
2015-05-05 07:15:56 +01:00
else
{
CustomMessageBox : : selectable ( this , tr ( " Error " ) , updateTask . failReason ( ) , QMessageBox : : Warning ) - > show ( ) ;
}
2013-12-06 18:59:58 +00:00
}
2013-10-06 00:13:40 +01:00
void MainWindow : : onCatToggled ( bool state )
2013-08-25 21:48:41 +01:00
{
setCatBackground ( state ) ;
2013-09-07 03:00:58 +01:00
MMC - > settings ( ) - > set ( " TheCat " , state ) ;
2013-08-25 21:48:41 +01:00
}
2013-10-06 00:13:40 +01:00
void MainWindow : : setCatBackground ( bool enabled )
2013-08-25 21:48:41 +01:00
{
2013-10-06 00:13:40 +01:00
if ( enabled )
2013-08-25 21:48:41 +01:00
{
2014-02-09 21:55:44 +00:00
view - > setStyleSheet ( " GroupView "
2013-10-06 00:13:40 +01:00
" { "
" background-image: url(:/backgrounds/kitteh); "
" background-attachment: fixed; "
" background-clip: padding; "
" background-position: top right; "
" background-repeat: none; "
" background-color:palette(base); "
" } " ) ;
2013-08-25 21:48:41 +01:00
}
else
{
view - > setStyleSheet ( QString ( ) ) ;
}
}
2015-01-27 21:31:07 +00:00
// FIXME: eliminate, should not be needed
void MainWindow : : waitForMinecraftVersions ( )
2013-01-09 18:22:22 +00:00
{
2015-10-20 16:22:13 +01:00
if ( ! MMC - > minecraftlist ( ) - > isLoaded ( ) & & m_versionLoadTask & & m_versionLoadTask - > isRunning ( ) )
2013-05-06 23:19:20 +01:00
{
QEventLoop waitLoop ;
2016-10-30 01:37:38 +00:00
waitLoop . connect ( m_versionLoadTask , & Task : : failed , & waitLoop , & QEventLoop : : quit ) ;
waitLoop . connect ( m_versionLoadTask , & Task : : succeeded , & waitLoop , & QEventLoop : : quit ) ;
2013-05-06 23:19:20 +01:00
waitLoop . exec ( ) ;
}
2015-01-27 21:31:07 +00:00
}
2013-10-06 00:13:40 +01:00
2016-10-02 23:55:54 +01:00
void MainWindow : : runModalTask ( Task * task )
2015-01-27 21:31:07 +00:00
{
2016-10-02 23:55:54 +01:00
connect ( task , & Task : : failed , [ this ] ( QString reason )
2015-02-12 21:01:20 +00:00
{
2016-10-02 23:55:54 +01:00
CustomMessageBox : : selectable ( this , tr ( " Error " ) , reason , QMessageBox : : Warning ) - > show ( ) ;
} ) ;
ProgressDialog loadDialog ( this ) ;
loadDialog . setSkipButton ( true , tr ( " Abort " ) ) ;
loadDialog . execWithTask ( task ) ;
}
2015-02-12 21:01:20 +00:00
2016-10-02 23:55:54 +01:00
void MainWindow : : instanceFromZipPack ( QString instName , QString instGroup , QString instIcon , QUrl url )
{
std : : unique_ptr < Task > task ( MMC - > folderProvider ( ) - > zipImportTask ( url , instName , instGroup , instIcon ) ) ;
runModalTask ( task . get ( ) ) ;
2015-02-12 21:01:20 +00:00
2016-10-02 23:55:54 +01:00
// FIXME: handle instance selection after creation
// finalizeInstance(newInstance);
}
2015-02-12 21:01:20 +00:00
2016-10-02 23:55:54 +01:00
void MainWindow : : instanceFromVersion ( QString instName , QString instGroup , QString instIcon , BaseVersionPtr version )
{
std : : unique_ptr < Task > task ( MMC - > folderProvider ( ) - > creationTask ( version , instName , instGroup , instIcon ) ) ;
runModalTask ( task . get ( ) ) ;
// FIXME: handle instance selection after creation
// finalizeInstance(newInstance);
2015-01-27 21:31:07 +00:00
}
2016-10-02 23:55:54 +01:00
void MainWindow : : on_actionCopyInstance_triggered ( )
2015-01-27 21:31:07 +00:00
{
2016-10-02 23:55:54 +01:00
if ( ! m_selectedInstance )
return ;
2015-02-01 02:08:25 +00:00
2016-10-02 23:55:54 +01:00
CopyInstanceDialog copyInstDlg ( m_selectedInstance , this ) ;
if ( ! copyInstDlg . exec ( ) )
return ;
2015-01-27 21:31:07 +00:00
2016-10-02 23:55:54 +01:00
std : : unique_ptr < Task > task ( MMC - > folderProvider ( ) - > copyTask ( m_selectedInstance , copyInstDlg . instName ( ) , copyInstDlg . instGroup ( ) ,
copyInstDlg . iconKey ( ) , copyInstDlg . shouldCopySaves ( ) ) ) ;
runModalTask ( task . get ( ) ) ;
2013-12-10 00:13:35 +00:00
2016-10-02 23:55:54 +01:00
// FIXME: handle instance selection after creation
// finalizeInstance(newInstance);
2015-01-27 21:31:07 +00:00
}
2015-02-12 21:01:20 +00:00
2015-01-27 21:31:07 +00:00
void MainWindow : : finalizeInstance ( InstancePtr inst )
{
2015-09-15 23:21:50 +01:00
view - > updateGeometries ( ) ;
setSelectedInstanceById ( inst - > id ( ) ) ;
2013-12-15 17:10:51 +00:00
if ( MMC - > accounts ( ) - > anyAccountIsValid ( ) )
2013-12-10 00:13:35 +00:00
{
ProgressDialog loadDialog ( this ) ;
2015-07-09 23:06:05 +01:00
auto update = inst - > createUpdateTask ( ) ;
2013-12-15 17:10:51 +00:00
connect ( update . get ( ) , & Task : : failed , [ this ] ( QString reason )
2015-10-20 16:22:13 +01:00
{
QString error = QString ( " Instance load failed: %1 " ) . arg ( reason ) ;
CustomMessageBox : : selectable ( this , tr ( " Error " ) , error , QMessageBox : : Warning ) - > show ( ) ;
} ) ;
2016-04-27 22:55:18 +01:00
if ( update )
{
2016-08-14 01:33:31 +01:00
loadDialog . setSkipButton ( true , tr ( " Abort " ) ) ;
2016-04-27 22:55:18 +01:00
loadDialog . execWithTask ( update . get ( ) ) ;
}
2013-12-10 00:13:35 +00:00
}
2013-12-15 19:42:17 +00:00
else
{
2015-10-20 16:22:13 +01:00
CustomMessageBox : : selectable ( this , tr ( " Error " ) , tr ( " MultiMC 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 ( ) ;
2013-12-15 19:42:17 +00:00
}
2013-01-09 18:22:22 +00:00
}
2015-01-27 21:31:07 +00:00
void MainWindow : : on_actionAddInstance_triggered ( )
{
2016-04-11 00:30:50 +01:00
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 ) ;
2015-01-27 21:31:07 +00:00
waitForMinecraftVersions ( ) ;
2016-04-11 00:30:50 +01:00
if ( groupName . isEmpty ( ) )
{
groupName = MMC - > settings ( ) - > get ( " LastUsedGroupForNewInstance " ) . toString ( ) ;
}
NewInstanceDialog newInstDlg ( groupName , this ) ;
2015-01-27 21:31:07 +00:00
if ( ! newInstDlg . exec ( ) )
return ;
MMC - > settings ( ) - > set ( " LastUsedGroupForNewInstance " , newInstDlg . instGroup ( ) ) ;
const QUrl modpackUrl = newInstDlg . modpackUrl ( ) ;
if ( modpackUrl . isValid ( ) )
{
instanceFromZipPack ( newInstDlg . instName ( ) , newInstDlg . instGroup ( ) , newInstDlg . iconKey ( ) , modpackUrl ) ;
}
else
{
instanceFromVersion ( newInstDlg . instName ( ) , newInstDlg . instGroup ( ) , newInstDlg . iconKey ( ) , newInstDlg . selectedVersion ( ) ) ;
}
}
2015-09-15 22:02:21 +01:00
void MainWindow : : on_actionREDDIT_triggered ( )
{
2016-01-05 06:32:52 +00:00
DesktopServices : : openUrl ( QUrl ( " https://www.reddit.com/r/MultiMC/ " ) ) ;
2015-09-15 22:02:21 +01:00
}
2016-01-09 00:39:51 +00:00
void MainWindow : : on_actionDISCORD_triggered ( )
{
DesktopServices : : openUrl ( QUrl ( " https://discord.gg/0k2zsXGNHs0fE4Wm " ) ) ;
}
2013-08-10 17:34:08 +01:00
void MainWindow : : on_actionChangeInstIcon_triggered ( )
2013-03-19 05:24:34 +00:00
{
2013-10-06 00:13:40 +01:00
if ( ! m_selectedInstance )
2013-08-10 17:34:08 +01:00
return ;
2013-10-06 00:13:40 +01:00
2013-08-10 17:34:08 +01:00
IconPickerDialog dlg ( this ) ;
2015-09-26 03:04:09 +01:00
dlg . execWithSelection ( m_selectedInstance - > iconKey ( ) ) ;
2013-10-06 00:13:40 +01:00
if ( dlg . result ( ) = = QDialog : : Accepted )
2013-03-19 05:24:34 +00:00
{
2013-08-25 00:32:42 +01:00
m_selectedInstance - > setIconKey ( dlg . selectedIconKey ) ;
2016-04-10 03:29:29 +01:00
auto ico = MMC - > icons ( ) - > getBigIcon ( dlg . selectedIconKey ) ;
2013-08-25 00:32:42 +01:00
ui - > actionChangeInstIcon - > setIcon ( ico ) ;
2013-03-19 05:24:34 +00:00
}
}
2013-12-31 00:24:28 +00:00
void MainWindow : : iconUpdated ( QString icon )
{
2014-01-27 02:00:49 +00:00
if ( icon = = m_currentInstIcon )
2013-12-31 00:24:28 +00:00
{
2016-04-10 03:29:29 +01:00
ui - > actionChangeInstIcon - > setIcon ( MMC - > icons ( ) - > getBigIcon ( m_currentInstIcon ) ) ;
2013-03-19 05:24:34 +00:00
}
}
2013-12-31 00:24:28 +00:00
void MainWindow : : updateInstanceToolIcon ( QString new_icon )
{
m_currentInstIcon = new_icon ;
2016-04-10 03:29:29 +01:00
ui - > actionChangeInstIcon - > setIcon ( MMC - > icons ( ) - > getBigIcon ( m_currentInstIcon ) ) ;
2013-12-31 00:24:28 +00:00
}
2014-01-06 09:01:40 +00:00
void MainWindow : : setSelectedInstanceById ( const QString & id )
{
2014-05-11 18:32:17 +01:00
if ( id . isNull ( ) )
return ;
const QModelIndex index = MMC - > instances ( ) - > getInstanceIndexById ( id ) ;
if ( index . isValid ( ) )
2014-01-06 09:01:40 +00:00
{
2014-05-11 18:32:17 +01:00
QModelIndex selectionIndex = proxymodel - > mapFromSource ( index ) ;
view - > selectionModel ( ) - > setCurrentIndex ( selectionIndex , QItemSelectionModel : : ClearAndSelect ) ;
2014-01-06 09:01:40 +00:00
}
}
2013-08-10 17:34:08 +01:00
void MainWindow : : on_actionChangeInstGroup_triggered ( )
{
2013-10-06 00:13:40 +01:00
if ( ! m_selectedInstance )
2013-08-10 17:34:08 +01:00
return ;
2013-10-06 00:13:40 +01:00
2013-08-10 17:34:08 +01:00
bool ok = false ;
2013-10-06 00:13:40 +01:00
QString name ( m_selectedInstance - > group ( ) ) ;
2013-12-15 17:10:51 +00:00
auto groups = MMC - > instances ( ) - > getGroups ( ) ;
2013-12-15 19:42:17 +00:00
groups . insert ( 0 , " " ) ;
2013-12-15 17:10:51 +00:00
groups . sort ( Qt : : CaseInsensitive ) ;
int foo = groups . indexOf ( name ) ;
2015-10-20 16:22:13 +01:00
name = QInputDialog : : getItem ( this , tr ( " Group name " ) , tr ( " Enter a new group name. " ) , groups , foo , true , & ok ) ;
2013-12-15 17:10:51 +00:00
name = name . simplified ( ) ;
2013-10-06 00:13:40 +01:00
if ( ok )
2013-08-25 21:48:41 +01:00
m_selectedInstance - > setGroupPost ( name ) ;
2013-08-10 17:34:08 +01:00
}
2016-04-11 00:30:50 +01:00
void MainWindow : : on_actionDeleteGroup_triggered ( )
{
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 ( ) )
{
MMC - > instances ( ) - > deleteGroup ( groupName ) ;
}
}
2013-01-09 18:22:22 +00:00
void MainWindow : : on_actionViewInstanceFolder_triggered ( )
{
2013-10-06 00:13:40 +01:00
QString str = MMC - > settings ( ) - > get ( " InstanceDir " ) . toString ( ) ;
2016-01-05 06:32:52 +00:00
DesktopServices : : openDirectory ( str ) ;
2013-01-09 18:22:22 +00:00
}
void MainWindow : : on_actionRefresh_triggered ( )
{
2016-10-02 23:55:54 +01:00
MMC - > instances ( ) - > loadList ( true ) ;
2013-01-09 18:22:22 +00:00
}
void MainWindow : : on_actionViewCentralModsFolder_triggered ( )
{
2016-01-05 06:32:52 +00:00
DesktopServices : : openDirectory ( MMC - > settings ( ) - > get ( " CentralModsDir " ) . toString ( ) , true ) ;
2013-01-09 18:22:22 +00:00
}
2013-08-25 00:32:42 +01:00
void MainWindow : : on_actionConfig_Folder_triggered ( )
{
2013-10-06 00:13:40 +01:00
if ( m_selectedInstance )
2013-08-25 00:32:42 +01:00
{
QString str = m_selectedInstance - > instanceConfigFolder ( ) ;
2016-01-05 06:32:52 +00:00
DesktopServices : : openDirectory ( QDir ( str ) . absolutePath ( ) ) ;
2013-08-25 00:32:42 +01:00
}
}
2013-01-09 18:22:22 +00:00
void MainWindow : : on_actionCheckUpdate_triggered ( )
{
2015-12-28 03:45:49 +00:00
if ( BuildConfig . UPDATER_ENABLED )
{
auto updater = MMC - > updateChecker ( ) ;
updater - > checkForUpdate ( MMC - > settings ( ) - > get ( " UpdateChannel " ) . toString ( ) , true ) ;
}
else
{
qWarning ( ) < < " Updater not set up. Cannot check for updates. " ;
}
2013-01-09 18:22:22 +00:00
}
2014-07-15 23:13:40 +01:00
void MainWindow : : on_actionSettings_triggered ( )
{
2015-07-05 01:29:41 +01:00
SettingsUI : : ShowPageDialog ( MMC - > globalSettingsPages ( ) , this , " global-settings " ) ;
2014-07-15 23:13:40 +01:00
// FIXME: quick HACK to make this work. improve, optimize.
proxymodel - > invalidate ( ) ;
proxymodel - > sort ( 0 ) ;
updateToolsMenu ( ) ;
2015-01-28 19:56:23 +00:00
update ( ) ;
2014-07-15 23:13:40 +01:00
}
2014-06-18 00:15:01 +01:00
void MainWindow : : on_actionInstanceSettings_triggered ( )
{
2016-10-30 01:37:38 +00:00
MMC - > showInstanceWindow ( m_selectedInstance , " settings " ) ;
2014-06-18 00:15:01 +01:00
}
void MainWindow : : on_actionEditInstNotes_triggered ( )
{
2016-10-30 01:37:38 +00:00
MMC - > showInstanceWindow ( m_selectedInstance , " notes " ) ;
2014-06-18 00:15:01 +01:00
}
2016-11-02 01:33:55 +00:00
void MainWindow : : on_actionWorlds_triggered ( )
{
MMC - > showInstanceWindow ( m_selectedInstance , " worlds " ) ;
}
2014-06-18 00:15:01 +01:00
void MainWindow : : on_actionEditInstance_triggered ( )
{
2016-10-30 01:37:38 +00:00
MMC - > showInstanceWindow ( m_selectedInstance ) ;
2014-06-18 00:15:01 +01:00
}
2014-06-28 16:07:08 +01:00
void MainWindow : : on_actionScreenshots_triggered ( )
{
2016-10-30 01:37:38 +00:00
MMC - > showInstanceWindow ( m_selectedInstance , " screenshots " ) ;
2014-06-28 16:07:08 +01:00
}
2013-11-20 18:20:35 +00:00
void MainWindow : : on_actionManageAccounts_triggered ( )
{
2015-07-05 01:29:41 +01:00
SettingsUI : : ShowPageDialog ( MMC - > globalSettingsPages ( ) , this , " accounts " ) ;
2013-11-20 18:20:35 +00:00
}
2013-01-09 18:22:22 +00:00
void MainWindow : : on_actionReportBug_triggered ( )
{
2016-01-05 06:32:52 +00:00
DesktopServices : : openUrl ( QUrl ( " https://github.com/MultiMC/MultiMC5/issues " ) ) ;
2013-01-09 18:22:22 +00:00
}
2014-04-11 02:59:30 +01:00
void MainWindow : : on_actionPatreon_triggered ( )
{
2016-01-05 06:32:52 +00:00
DesktopServices : : openUrl ( QUrl ( " http://www.patreon.com/multimc " ) ) ;
2014-04-11 02:59:30 +01:00
}
2014-01-02 19:25:38 +00:00
void MainWindow : : on_actionMoreNews_triggered ( )
2013-01-09 18:22:22 +00:00
{
2016-01-05 06:32:52 +00:00
DesktopServices : : openUrl ( QUrl ( " http://multimc.org/posts.html " ) ) ;
2013-01-09 18:22:22 +00:00
}
2014-01-02 20:37:56 +00:00
void MainWindow : : newsButtonClicked ( )
{
2015-01-27 21:31:07 +00:00
QList < NewsEntryPtr > entries = m_newsChecker - > getNewsEntries ( ) ;
2014-01-02 20:37:56 +00:00
if ( entries . count ( ) > 0 )
2016-01-05 06:32:52 +00:00
{
DesktopServices : : openUrl ( QUrl ( entries [ 0 ] - > link ) ) ;
}
2014-01-02 20:37:56 +00:00
else
2016-01-05 06:32:52 +00:00
{
DesktopServices : : openUrl ( QUrl ( " http://multimc.org/posts.html " ) ) ;
}
2014-01-02 20:37:56 +00:00
}
2013-01-09 18:22:22 +00:00
void MainWindow : : on_actionAbout_triggered ( )
{
2013-10-06 00:13:40 +01:00
AboutDialog dialog ( this ) ;
2013-03-11 21:19:17 +00:00
dialog . exec ( ) ;
2013-01-09 18:22:22 +00:00
}
2013-01-30 05:52:37 +00:00
2013-10-06 00:13:40 +01:00
void MainWindow : : on_mainToolBar_visibilityChanged ( bool )
2013-01-30 05:52:37 +00:00
{
// Don't allow hiding the main toolbar.
// This is the only way I could find to prevent it... :/
2013-10-06 00:13:40 +01:00
ui - > mainToolBar - > setVisible ( true ) ;
2013-01-30 05:52:37 +00:00
}
2013-06-23 21:10:32 +01:00
void MainWindow : : on_actionDeleteInstance_triggered ( )
{
2015-10-20 16:18:53 +01:00
if ( ! m_selectedInstance )
2013-07-04 23:39:41 +01:00
{
2015-10-20 16:18:53 +01:00
return ;
}
auto response = CustomMessageBox : : selectable ( this , tr ( " CAREFUL! " ) , tr ( " About to delete: %1 \n This is permanent and will completely erase "
" all data, even for tracked instances! \n Are you sure? " )
. arg ( m_selectedInstance - > name ( ) ) ,
QMessageBox : : Warning , QMessageBox : : Yes | QMessageBox : : No )
- > exec ( ) ;
if ( response = = QMessageBox : : Yes )
{
m_selectedInstance - > nuke ( ) ;
2013-07-04 23:39:41 +01:00
}
2013-06-23 21:10:32 +01:00
}
2015-02-12 21:01:20 +00:00
void MainWindow : : on_actionExportInstance_triggered ( )
{
if ( m_selectedInstance )
{
2015-04-19 03:19:29 +01:00
ExportInstanceDialog dlg ( m_selectedInstance , this ) ;
dlg . exec ( ) ;
2015-02-12 21:01:20 +00:00
}
}
2013-06-23 21:10:32 +01:00
void MainWindow : : on_actionRenameInstance_triggered ( )
{
2013-10-06 00:13:40 +01:00
if ( m_selectedInstance )
2013-06-23 21:10:32 +01:00
{
bool ok = false ;
2013-10-06 00:13:40 +01:00
QString name ( m_selectedInstance - > name ( ) ) ;
2015-10-20 16:22:13 +01:00
name = QInputDialog : : getText ( this , tr ( " Instance name " ) , tr ( " Enter a new instance name. " ) , QLineEdit : : Normal , name , & ok ) ;
2013-10-06 00:13:40 +01:00
2016-05-03 23:31:27 +01:00
name = name . trimmed ( ) ;
2013-07-07 03:11:24 +01:00
if ( name . length ( ) > 0 )
{
2013-10-06 00:13:40 +01:00
if ( ok & & name . length ( ) )
2013-08-28 20:52:19 +01:00
{
2013-08-25 00:32:42 +01:00
m_selectedInstance - > setName ( name ) ;
2013-08-28 20:52:19 +01:00
renameButton - > setText ( name ) ;
}
2013-07-07 03:11:24 +01:00
}
2013-06-23 21:10:32 +01:00
}
}
void MainWindow : : on_actionViewSelectedInstFolder_triggered ( )
{
2013-10-06 00:13:40 +01:00
if ( m_selectedInstance )
2013-06-23 21:10:32 +01:00
{
2013-08-25 00:32:42 +01:00
QString str = m_selectedInstance - > instanceRoot ( ) ;
2016-01-05 06:32:52 +00:00
DesktopServices : : openDirectory ( QDir ( str ) . absolutePath ( ) ) ;
2013-06-23 21:10:32 +01:00
}
}
2013-10-06 00:13:40 +01:00
void MainWindow : : closeEvent ( QCloseEvent * event )
2013-01-30 05:52:37 +00:00
{
2016-11-06 22:01:08 +00:00
if ( MMC - > numRunningInstances ( ) )
{
auto resBtn = QMessageBox : : question (
this ,
tr ( " Do you want to close MultiMC? " ) ,
tr ( " <p>You still have instances running.</p><p>Closing MultiMC will result in inaccurate time tracking and no Minecraft crash handling.</p><p>Are you sure?</p> " ) ,
QMessageBox : : No | QMessageBox : : Yes ,
QMessageBox : : Yes
) ;
if ( resBtn ! = QMessageBox : : Yes )
{
event - > ignore ( ) ;
return ;
}
}
2013-11-03 00:45:25 +00:00
2016-11-06 22:01:08 +00:00
// no running instances or user said yes.
event - > accept ( ) ;
// Save the window state and geometry.
2013-11-03 00:45:25 +00:00
MMC - > settings ( ) - > set ( " MainWindowState " , saveState ( ) . toBase64 ( ) ) ;
MMC - > settings ( ) - > set ( " MainWindowGeometry " , saveGeometry ( ) . toBase64 ( ) ) ;
2013-10-26 08:38:21 +01:00
QApplication : : exit ( ) ;
2013-01-30 05:52:37 +00:00
}
2013-03-11 21:19:17 +00:00
2013-10-21 21:25:50 +01:00
void MainWindow : : instanceActivated ( QModelIndex index )
{
if ( ! index . isValid ( ) )
return ;
2014-06-27 23:05:00 +01:00
QString id = index . data ( InstanceList : : InstanceIDRole ) . toString ( ) ;
2014-03-30 19:11:05 +01:00
InstancePtr inst = MMC - > instances ( ) - > getInstanceById ( id ) ;
2014-06-27 23:05:00 +01:00
if ( ! inst )
return ;
2013-10-21 21:25:50 +01:00
2016-10-30 01:37:38 +00:00
MMC - > launch ( inst ) ;
2013-10-21 21:25:50 +01:00
}
2013-02-05 22:34:20 +00:00
void MainWindow : : on_actionLaunchInstance_triggered ( )
{
2013-10-06 00:13:40 +01:00
if ( m_selectedInstance )
2013-03-11 21:19:17 +00:00
{
2016-10-30 01:37:38 +00:00
MMC - > launch ( m_selectedInstance ) ;
2013-03-11 21:19:17 +00:00
}
2013-02-05 22:34:20 +00:00
}
2014-01-27 02:00:49 +00:00
void MainWindow : : on_actionLaunchInstanceOffline_triggered ( )
{
if ( m_selectedInstance )
{
2016-10-30 01:37:38 +00:00
MMC - > launch ( m_selectedInstance , false ) ;
2016-03-18 14:02:54 +00:00
}
2015-07-04 19:02:43 +01:00
}
2013-08-08 23:26:35 +01:00
void MainWindow : : taskEnd ( )
2013-05-06 23:19:20 +01:00
{
2013-08-08 23:26:35 +01:00
QObject * sender = QObject : : sender ( ) ;
if ( sender = = m_versionLoadTask )
2013-05-06 23:19:20 +01:00
m_versionLoadTask = NULL ;
2013-10-06 00:13:40 +01:00
2013-08-08 23:26:35 +01:00
sender - > deleteLater ( ) ;
2013-05-06 23:19:20 +01:00
}
void MainWindow : : startTask ( Task * task )
{
2013-08-08 23:26:35 +01:00
connect ( task , SIGNAL ( succeeded ( ) ) , SLOT ( taskEnd ( ) ) ) ;
connect ( task , SIGNAL ( failed ( QString ) ) , SLOT ( taskEnd ( ) ) ) ;
2013-09-17 23:00:35 +01:00
task - > start ( ) ;
2013-05-06 23:19:20 +01:00
}
2013-10-06 00:13:40 +01:00
void MainWindow : : instanceChanged ( const QModelIndex & current , const QModelIndex & previous )
2013-08-25 00:32:42 +01:00
{
2015-10-20 16:22:13 +01:00
if ( ! current . isValid ( ) )
2014-05-11 18:32:17 +01:00
{
MMC - > settings ( ) - > set ( " SelectedInstance " , QString ( ) ) ;
selectionBad ( ) ;
return ;
}
QString id = current . data ( InstanceList : : InstanceIDRole ) . toString ( ) ;
m_selectedInstance = MMC - > instances ( ) - > getInstanceById ( id ) ;
2015-10-20 16:22:13 +01:00
if ( m_selectedInstance )
2013-08-25 00:32:42 +01:00
{
2016-03-18 14:02:54 +00:00
ui - > instanceToolBar - > setEnabled ( true ) ;
ui - > actionLaunchInstance - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
ui - > actionLaunchInstanceOffline - > setEnabled ( m_selectedInstance - > canLaunch ( ) ) ;
2016-04-27 23:04:37 +01:00
ui - > actionExportInstance - > setEnabled ( m_selectedInstance - > canExport ( ) ) ;
2013-08-25 21:48:41 +01:00
renameButton - > setText ( m_selectedInstance - > name ( ) ) ;
2013-10-26 02:28:50 +01:00
m_statusLeft - > setText ( m_selectedInstance - > getStatusbarDescription ( ) ) ;
2013-12-31 00:24:28 +00:00
updateInstanceToolIcon ( m_selectedInstance - > iconKey ( ) ) ;
2013-11-27 14:00:44 +00:00
2014-02-16 10:49:55 +00:00
updateToolsMenu ( ) ;
2014-02-15 21:26:44 +00:00
2013-11-27 14:00:44 +00:00
MMC - > settings ( ) - > set ( " SelectedInstance " , m_selectedInstance - > id ( ) ) ;
2013-08-25 00:32:42 +01:00
}
else
{
2016-03-18 14:02:54 +00:00
ui - > instanceToolBar - > setEnabled ( false ) ;
2014-05-11 18:32:17 +01:00
MMC - > settings ( ) - > set ( " SelectedInstance " , QString ( ) ) ;
selectionBad ( ) ;
return ;
2013-08-25 00:32:42 +01:00
}
2013-08-26 05:30:11 +01:00
}
2015-10-20 16:22:13 +01:00
void MainWindow : : instanceDataChanged ( const QModelIndex & topLeft , const QModelIndex & bottomRight )
2015-04-07 00:21:03 +01:00
{
auto current = view - > selectionModel ( ) - > currentIndex ( ) ;
QItemSelection test ( topLeft , bottomRight ) ;
2015-10-20 16:22:13 +01:00
if ( test . contains ( current ) )
2015-04-07 00:21:03 +01:00
{
instanceChanged ( current , current ) ;
}
}
2013-08-26 05:30:11 +01:00
void MainWindow : : selectionBad ( )
{
2014-01-06 09:01:40 +00:00
// start by reseting everything...
2013-08-26 05:30:11 +01:00
m_selectedInstance = nullptr ;
2013-12-31 00:24:28 +00:00
2013-08-26 05:30:11 +01:00
statusBar ( ) - > clearMessage ( ) ;
ui - > instanceToolBar - > setEnabled ( false ) ;
2013-09-08 17:13:09 +01:00
renameButton - > setText ( tr ( " Rename Instance " ) ) ;
2013-12-31 00:24:28 +00:00
updateInstanceToolIcon ( " infinity " ) ;
2014-01-06 09:01:40 +00:00
// ...and then see if we can enable the previously selected instance
setSelectedInstanceById ( MMC - > settings ( ) - > get ( " SelectedInstance " ) . toString ( ) ) ;
2013-07-14 21:01:30 +01:00
}
2013-08-25 21:48:41 +01:00
2013-10-14 02:59:21 +01:00
void MainWindow : : checkSetDefaultJava ( )
{
2014-06-27 23:05:00 +01:00
const QString javaHack = " IntelHack " ;
2013-10-20 21:28:31 +01:00
bool askForJava = false ;
2014-06-27 23:05:00 +01:00
do
2013-10-14 02:59:21 +01:00
{
2013-10-20 21:28:31 +01:00
QString currentHostName = QHostInfo : : localHostName ( ) ;
QString oldHostName = MMC - > settings ( ) - > get ( " LastHostname " ) . toString ( ) ;
if ( currentHostName ! = oldHostName )
{
MMC - > settings ( ) - > set ( " LastHostname " , currentHostName ) ;
askForJava = true ;
2014-06-27 23:05:00 +01:00
break ;
2013-10-20 21:28:31 +01:00
}
QString currentJavaPath = MMC - > settings ( ) - > get ( " JavaPath " ) . toString ( ) ;
2015-10-05 00:47:27 +01:00
QString actualPath = FS : : ResolveExecutable ( currentJavaPath ) ;
2015-09-30 21:52:55 +01:00
if ( currentJavaPath . isNull ( ) )
2014-11-16 11:56:33 +00:00
{
askForJava = true ;
break ;
}
2015-10-20 16:22:13 +01:00
# if defined Q_OS_WIN32
2014-06-27 23:05:00 +01:00
QString currentHack = MMC - > settings ( ) - > get ( " JavaDetectionHack " ) . toString ( ) ;
if ( currentHack ! = javaHack )
{
2015-10-20 16:22:13 +01:00
CustomMessageBox : : selectable ( this , tr ( " Java detection forced " ) , tr ( " Because of graphics performance issues caused by Intel drivers on Windows, "
" MultiMC java detection was forced. Please select a Java "
" version.<br/><br/>If you have custom java versions set for your instances, "
" make sure you use the 'javaw.exe' executable. " ) ,
QMessageBox : : Warning )
- > exec ( ) ;
2014-06-27 23:05:00 +01:00
askForJava = true ;
break ;
}
2015-10-20 16:22:13 +01:00
# endif
2014-06-27 23:05:00 +01:00
} while ( 0 ) ;
2013-10-20 21:28:31 +01:00
if ( askForJava )
{
2015-02-02 01:14:14 +00:00
qDebug ( ) < < " Java path needs resetting, showing Java selection dialog... " ;
2013-10-14 02:59:21 +01:00
2016-01-01 23:35:54 +00:00
JavaInstallPtr java ;
2013-10-14 02:59:21 +01:00
2015-10-20 16:22:13 +01:00
VersionSelectDialog vselect ( MMC - > javalist ( ) . get ( ) , tr ( " Select a Java version " ) , this , false ) ;
2013-10-14 02:59:21 +01:00
vselect . setResizeOn ( 2 ) ;
vselect . exec ( ) ;
2013-10-24 00:47:54 +01:00
if ( vselect . selectedVersion ( ) )
2016-01-01 23:35:54 +00:00
java = std : : dynamic_pointer_cast < JavaInstall > ( vselect . selectedVersion ( ) ) ;
2013-10-24 00:47:54 +01:00
else
2013-10-14 02:59:21 +01:00
{
2015-10-20 16:22:13 +01:00
CustomMessageBox : : selectable ( this , tr ( " Invalid version selected " ) , tr ( " You didn't select a valid Java version, so MultiMC will "
" select the default. "
" You can change this in the settings dialog. " ) ,
QMessageBox : : Warning )
- > show ( ) ;
2013-10-29 12:40:09 +00:00
2013-10-14 02:59:21 +01:00
JavaUtils ju ;
java = ju . GetDefaultJava ( ) ;
}
2013-10-26 18:55:48 +01:00
if ( java )
2014-06-27 23:05:00 +01:00
{
2013-10-24 00:47:54 +01:00
MMC - > settings ( ) - > set ( " JavaPath " , java - > path ) ;
2014-06-27 23:05:00 +01:00
MMC - > settings ( ) - > set ( " JavaDetectionHack " , javaHack ) ;
}
2013-10-24 00:47:54 +01:00
else
MMC - > settings ( ) - > set ( " JavaPath " , QString ( " java " ) ) ;
2013-10-14 02:59:21 +01:00
}
}
2014-07-27 14:50:03 +01:00
void MainWindow : : checkInstancePathForProblems ( )
{
QString instanceFolder = MMC - > settings ( ) - > get ( " InstanceDir " ) . toString ( ) ;
2015-10-05 00:47:27 +01:00
if ( FS : : checkProblemticPathJava ( QDir ( instanceFolder ) ) )
2014-07-27 14:50:03 +01:00
{
2015-04-25 23:01:41 +01:00
QMessageBox warning ( this ) ;
2015-10-20 16:22:13 +01:00
warning . setText ( tr ( " Your instance folder contains \' ! \' and this is known to cause Java problems! " ) ) ;
warning . setInformativeText ( tr ( " You have now two options: <br/> "
" - change the instance folder in the settings <br/> "
" - move this installation of MultiMC5 to a different folder " ) ) ;
2014-07-27 14:50:03 +01:00
warning . setDefaultButton ( QMessageBox : : Ok ) ;
warning . exec ( ) ;
}
2015-04-25 23:01:41 +01:00
auto tempFolderText = tr ( " This is a problem: <br/> "
2015-10-20 16:22:13 +01:00
" - MultiMC will likely be deleted without warning by the operating system <br/> "
" - close MultiMC now and extract it to a real location, not a temporary folder " ) ;
2015-04-25 23:01:41 +01:00
QString pathfoldername = QDir ( instanceFolder ) . absolutePath ( ) ;
2015-10-20 16:22:13 +01:00
if ( pathfoldername . contains ( " Rar$ " , Qt : : CaseInsensitive ) )
2015-04-25 23:01:41 +01:00
{
QMessageBox warning ( this ) ;
2015-10-20 16:22:13 +01:00
warning . setText ( tr ( " Your instance folder contains \' Rar$ \' - that means you haven't extracted the MultiMC zip! " ) ) ;
2015-04-25 23:01:41 +01:00
warning . setInformativeText ( tempFolderText ) ;
warning . setDefaultButton ( QMessageBox : : Ok ) ;
warning . exec ( ) ;
}
2015-10-20 16:22:13 +01:00
else if ( pathfoldername . contains ( QDir : : tempPath ( ) ) )
2015-04-25 23:01:41 +01:00
{
QMessageBox warning ( this ) ;
2015-10-20 16:22:13 +01:00
warning . setText ( tr ( " Your instance folder is in a temporary folder: \' %1 \' ! " ) . arg ( QDir : : tempPath ( ) ) ) ;
2015-04-25 23:01:41 +01:00
warning . setInformativeText ( tempFolderText ) ;
warning . setDefaultButton ( QMessageBox : : Ok ) ;
warning . exec ( ) ;
}
2014-07-27 14:50:03 +01:00
}