summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.arcconfig4
-rw-r--r--.clang-format2
-rw-r--r--.gitmodules8
-rw-r--r--CMakeLists.txt180
-rw-r--r--COPYING.md350
-rw-r--r--api/gui/CMakeLists.txt24
-rw-r--r--api/gui/DesktopServices.cpp174
-rw-r--r--api/gui/DesktopServices.h40
-rw-r--r--api/gui/SkinUtils.cpp24
-rw-r--r--api/gui/icons/IconList.cpp578
-rw-r--r--api/gui/icons/IconList.h72
-rw-r--r--api/gui/icons/MMCIcon.cpp108
-rw-r--r--api/gui/icons/MMCIcon.h36
-rw-r--r--api/logic/BaseInstaller.cpp36
-rw-r--r--api/logic/BaseInstaller.h18
-rw-r--r--api/logic/BaseInstance.cpp240
-rw-r--r--api/logic/BaseInstance.h398
-rw-r--r--api/logic/BaseInstanceProvider.h64
-rw-r--r--api/logic/BaseVersion.h54
-rw-r--r--api/logic/BaseVersionList.cpp86
-rw-r--r--api/logic/BaseVersionList.h134
-rw-r--r--api/logic/CMakeLists.txt748
-rw-r--r--api/logic/Commandline.cpp730
-rw-r--r--api/logic/Commandline.h324
-rw-r--r--api/logic/DefaultVariable.h54
-rw-r--r--api/logic/Env.cpp208
-rw-r--r--api/logic/Env.h38
-rw-r--r--api/logic/Exception.h36
-rw-r--r--api/logic/FileSystem.cpp634
-rw-r--r--api/logic/FileSystem.h50
-rw-r--r--api/logic/FileSystem_test.cpp274
-rw-r--r--api/logic/Filter.cpp16
-rw-r--r--api/logic/Filter.h30
-rw-r--r--api/logic/FolderInstanceProvider.cpp726
-rw-r--r--api/logic/FolderInstanceProvider.h88
-rw-r--r--api/logic/GZip.cpp208
-rw-r--r--api/logic/GZip.h4
-rw-r--r--api/logic/GZip_test.cpp74
-rw-r--r--api/logic/InstanceCopyTask.cpp64
-rw-r--r--api/logic/InstanceCopyTask.h20
-rw-r--r--api/logic/InstanceCreationTask.cpp34
-rw-r--r--api/logic/InstanceCreationTask.h10
-rw-r--r--api/logic/InstanceImportTask.cpp676
-rw-r--r--api/logic/InstanceImportTask.h52
-rw-r--r--api/logic/InstanceList.cpp460
-rw-r--r--api/logic/InstanceList.h118
-rw-r--r--api/logic/InstanceTask.h82
-rw-r--r--api/logic/Json.cpp268
-rw-r--r--api/logic/Json.h160
-rw-r--r--api/logic/LoggedProcess.cpp214
-rw-r--r--api/logic/LoggedProcess.h70
-rw-r--r--api/logic/MMCStrings.cpp126
-rw-r--r--api/logic/MMCStrings.h2
-rw-r--r--api/logic/MMCZip.cpp398
-rw-r--r--api/logic/MMCZip.h68
-rw-r--r--api/logic/MessageLevel.cpp54
-rw-r--r--api/logic/MessageLevel.h20
-rw-r--r--api/logic/NullInstance.h140
-rw-r--r--api/logic/ProblemProvider.h52
-rw-r--r--api/logic/QObjectPtr.h104
-rw-r--r--api/logic/RWStorage.h108
-rw-r--r--api/logic/RecursiveFileSystemWatcher.cpp142
-rw-r--r--api/logic/RecursiveFileSystemWatcher.h80
-rw-r--r--api/logic/SeparatorPrefixTree.h544
-rw-r--r--api/logic/Usable.h58
-rw-r--r--api/logic/Version.cpp94
-rw-r--r--api/logic/Version.h176
-rw-r--r--api/logic/Version_test.cpp96
-rw-r--r--api/logic/icons/IIconList.h24
-rw-r--r--api/logic/java/JavaChecker.cpp250
-rw-r--r--api/logic/java/JavaChecker.h66
-rw-r--r--api/logic/java/JavaCheckerJob.cpp32
-rw-r--r--api/logic/java/JavaCheckerJob.h52
-rw-r--r--api/logic/java/JavaInstall.cpp28
-rw-r--r--api/logic/java/JavaInstall.h48
-rw-r--r--api/logic/java/JavaInstallList.cpp222
-rw-r--r--api/logic/java/JavaInstallList.h58
-rw-r--r--api/logic/java/JavaUtils.cpp514
-rw-r--r--api/logic/java/JavaUtils.h12
-rw-r--r--api/logic/java/JavaVersion.cpp164
-rw-r--r--api/logic/java/JavaVersion.h68
-rw-r--r--api/logic/java/JavaVersion_test.cpp194
-rw-r--r--api/logic/java/launch/CheckJava.cpp194
-rw-r--r--api/logic/java/launch/CheckJava.h28
-rw-r--r--api/logic/launch/LaunchStep.cpp12
-rw-r--r--api/logic/launch/LaunchStep.h30
-rw-r--r--api/logic/launch/LaunchTask.cpp324
-rw-r--r--api/logic/launch/LaunchTask.h134
-rw-r--r--api/logic/launch/LogModel.cpp218
-rw-r--r--api/logic/launch/LogModel.h70
-rw-r--r--api/logic/launch/steps/PostLaunchCommand.cpp94
-rw-r--r--api/logic/launch/steps/PostLaunchCommand.h26
-rw-r--r--api/logic/launch/steps/PreLaunchCommand.cpp96
-rw-r--r--api/logic/launch/steps/PreLaunchCommand.h26
-rw-r--r--api/logic/launch/steps/TextPrint.cpp18
-rw-r--r--api/logic/launch/steps/TextPrint.h18
-rw-r--r--api/logic/launch/steps/Update.cpp84
-rw-r--r--api/logic/launch/steps/Update.h22
-rw-r--r--api/logic/meta/BaseEntity.cpp200
-rw-r--r--api/logic/meta/BaseEntity.h52
-rw-r--r--api/logic/meta/Index.cpp162
-rw-r--r--api/logic/meta/Index.h48
-rw-r--r--api/logic/meta/Index_test.cpp52
-rw-r--r--api/logic/meta/JsonFormat.cpp258
-rw-r--r--api/logic/meta/JsonFormat.h42
-rw-r--r--api/logic/meta/Version.cpp104
-rw-r--r--api/logic/meta/Version.h136
-rw-r--r--api/logic/meta/VersionList.cpp276
-rw-r--r--api/logic/meta/VersionList.h116
-rw-r--r--api/logic/minecraft/AssetsUtils.cpp340
-rw-r--r--api/logic/minecraft/AssetsUtils.h20
-rw-r--r--api/logic/minecraft/Component.cpp604
-rw-r--r--api/logic/minecraft/Component.h138
-rw-r--r--api/logic/minecraft/ComponentList.cpp1896
-rw-r--r--api/logic/minecraft/ComponentList.h138
-rw-r--r--api/logic/minecraft/ComponentList_p.h44
-rw-r--r--api/logic/minecraft/ComponentUpdateTask.cpp1120
-rw-r--r--api/logic/minecraft/ComponentUpdateTask.h30
-rw-r--r--api/logic/minecraft/ComponentUpdateTask_p.h32
-rw-r--r--api/logic/minecraft/GradleSpecifier.h266
-rw-r--r--api/logic/minecraft/GradleSpecifier_test.cpp126
-rw-r--r--api/logic/minecraft/LaunchProfile.cpp324
-rw-r--r--api/logic/minecraft/LaunchProfile.h140
-rw-r--r--api/logic/minecraft/Library.cpp538
-rw-r--r--api/logic/minecraft/Library.h330
-rw-r--r--api/logic/minecraft/Library_test.cpp498
-rw-r--r--api/logic/minecraft/MinecraftInstance.cpp1410
-rw-r--r--api/logic/minecraft/MinecraftInstance.h174
-rw-r--r--api/logic/minecraft/MinecraftLoadAndCheck.cpp50
-rw-r--r--api/logic/minecraft/MinecraftLoadAndCheck.h20
-rw-r--r--api/logic/minecraft/MinecraftUpdate.cpp234
-rw-r--r--api/logic/minecraft/MinecraftUpdate.h32
-rw-r--r--api/logic/minecraft/Mod.cpp572
-rw-r--r--api/logic/minecraft/Mod.h228
-rw-r--r--api/logic/minecraft/ModsModel.cpp548
-rw-r--r--api/logic/minecraft/ModsModel.h152
-rw-r--r--api/logic/minecraft/MojangDownloadInfo.h110
-rw-r--r--api/logic/minecraft/MojangVersionFormat.cpp578
-rw-r--r--api/logic/minecraft/MojangVersionFormat.h20
-rw-r--r--api/logic/minecraft/MojangVersionFormat_test.cpp76
-rw-r--r--api/logic/minecraft/OneSixVersionFormat.cpp650
-rw-r--r--api/logic/minecraft/OneSixVersionFormat.h28
-rw-r--r--api/logic/minecraft/OpSys.cpp36
-rw-r--r--api/logic/minecraft/OpSys.h8
-rw-r--r--api/logic/minecraft/ParseUtils.cpp36
-rw-r--r--api/logic/minecraft/ParseUtils_test.cpp56
-rw-r--r--api/logic/minecraft/ProfileUtils.cpp264
-rw-r--r--api/logic/minecraft/Rule.cpp106
-rw-r--r--api/logic/minecraft/Rule.h94
-rw-r--r--api/logic/minecraft/SimpleModList.cpp552
-rw-r--r--api/logic/minecraft/SimpleModList.h152
-rw-r--r--api/logic/minecraft/SimpleModList_test.cpp70
-rw-r--r--api/logic/minecraft/SkinUpload.cpp80
-rw-r--r--api/logic/minecraft/SkinUpload.h32
-rw-r--r--api/logic/minecraft/VersionFile.cpp68
-rw-r--r--api/logic/minecraft/VersionFile.h118
-rw-r--r--api/logic/minecraft/VersionFilterData.cpp104
-rw-r--r--api/logic/minecraft/VersionFilterData.h24
-rw-r--r--api/logic/minecraft/World.cpp560
-rw-r--r--api/logic/minecraft/World.h102
-rw-r--r--api/logic/minecraft/WorldList.cpp510
-rw-r--r--api/logic/minecraft/WorldList.h174
-rw-r--r--api/logic/minecraft/auth/AuthSession.cpp32
-rw-r--r--api/logic/minecraft/auth/AuthSession.h70
-rw-r--r--api/logic/minecraft/auth/MojangAccount.cpp442
-rw-r--r--api/logic/minecraft/auth/MojangAccount.h170
-rw-r--r--api/logic/minecraft/auth/MojangAccountList.cpp682
-rw-r--r--api/logic/minecraft/auth/MojangAccountList.h304
-rw-r--r--api/logic/minecraft/auth/YggdrasilTask.cpp356
-rw-r--r--api/logic/minecraft/auth/YggdrasilTask.h212
-rw-r--r--api/logic/minecraft/auth/flows/AuthenticateTask.cpp312
-rw-r--r--api/logic/minecraft/auth/flows/AuthenticateTask.h14
-rw-r--r--api/logic/minecraft/auth/flows/RefreshTask.cpp188
-rw-r--r--api/logic/minecraft/auth/flows/RefreshTask.h12
-rw-r--r--api/logic/minecraft/auth/flows/ValidateTask.cpp32
-rw-r--r--api/logic/minecraft/auth/flows/ValidateTask.h12
-rw-r--r--api/logic/minecraft/forge/ForgeXzDownload.cpp640
-rw-r--r--api/logic/minecraft/forge/ForgeXzDownload.h46
-rw-r--r--api/logic/minecraft/launch/ClaimAccount.cpp20
-rw-r--r--api/logic/minecraft/launch/ClaimAccount.h22
-rw-r--r--api/logic/minecraft/launch/CreateServerResourcePacksFolder.cpp14
-rw-r--r--api/logic/minecraft/launch/CreateServerResourcePacksFolder.h16
-rw-r--r--api/logic/minecraft/launch/DirectJavaLaunch.cpp196
-rw-r--r--api/logic/minecraft/launch/DirectJavaLaunch.h38
-rw-r--r--api/logic/minecraft/launch/ExtractNatives.cpp120
-rw-r--r--api/logic/minecraft/launch/ExtractNatives.h18
-rw-r--r--api/logic/minecraft/launch/LauncherPartLaunch.cpp292
-rw-r--r--api/logic/minecraft/launch/LauncherPartLaunch.h42
-rw-r--r--api/logic/minecraft/launch/ModMinecraftJar.cpp90
-rw-r--r--api/logic/minecraft/launch/ModMinecraftJar.h20
-rw-r--r--api/logic/minecraft/launch/PrintInstanceInfo.h18
-rw-r--r--api/logic/minecraft/legacy/LegacyInstance.cpp226
-rw-r--r--api/logic/minecraft/legacy/LegacyInstance.h216
-rw-r--r--api/logic/minecraft/legacy/LegacyModList.cpp262
-rw-r--r--api/logic/minecraft/legacy/LegacyModList.h28
-rw-r--r--api/logic/minecraft/legacy/LegacyUpgradeTask.cpp200
-rw-r--r--api/logic/minecraft/legacy/LegacyUpgradeTask.h18
-rw-r--r--api/logic/minecraft/testdata/lib-native-arch.json88
-rw-r--r--api/logic/minecraft/testdata/lib-native.json100
-rw-r--r--api/logic/minecraft/testdata/lib-simple.json18
-rw-r--r--api/logic/minecraft/update/AssetUpdateTask.cpp124
-rw-r--r--api/logic/minecraft/update/AssetUpdateTask.h22
-rw-r--r--api/logic/minecraft/update/FMLLibrariesTask.cpp190
-rw-r--r--api/logic/minecraft/update/FMLLibrariesTask.h22
-rw-r--r--api/logic/minecraft/update/FoldersTask.cpp20
-rw-r--r--api/logic/minecraft/update/FoldersTask.h10
-rw-r--r--api/logic/minecraft/update/LibrariesTask.cpp124
-rw-r--r--api/logic/minecraft/update/LibrariesTask.h18
-rw-r--r--api/logic/modplatform/flame/FileResolvingTask.cpp202
-rw-r--r--api/logic/modplatform/flame/FileResolvingTask.h24
-rw-r--r--api/logic/modplatform/flame/PackManifest.cpp88
-rw-r--r--api/logic/modplatform/flame/PackManifest.h64
-rw-r--r--api/logic/modplatform/ftb/FtbPackFetchTask.cpp168
-rw-r--r--api/logic/modplatform/ftb/FtbPackFetchTask.h28
-rw-r--r--api/logic/modplatform/ftb/FtbPackInstallTask.cpp280
-rw-r--r--api/logic/modplatform/ftb/FtbPackInstallTask.h46
-rw-r--r--api/logic/modplatform/ftb/PackHelpers.h40
-rw-r--r--api/logic/net/ByteArraySink.h88
-rw-r--r--api/logic/net/ChecksumValidator.h76
-rw-r--r--api/logic/net/Download.cpp406
-rw-r--r--api/logic/net/Download.h60
-rw-r--r--api/logic/net/FileSink.cpp138
-rw-r--r--api/logic/net/FileSink.h24
-rw-r--r--api/logic/net/HttpMetaCache.cpp366
-rw-r--r--api/logic/net/HttpMetaCache.h152
-rw-r--r--api/logic/net/MetaCacheSink.cpp74
-rw-r--r--api/logic/net/MetaCacheSink.h14
-rw-r--r--api/logic/net/Mode.h4
-rw-r--r--api/logic/net/NetAction.h132
-rw-r--r--api/logic/net/NetJob.cpp312
-rw-r--r--api/logic/net/NetJob.h96
-rw-r--r--api/logic/net/PasteUpload.cpp128
-rw-r--r--api/logic/net/PasteUpload.h62
-rw-r--r--api/logic/net/Sink.h102
-rw-r--r--api/logic/net/URLConstants.cpp4
-rw-r--r--api/logic/net/Validator.h12
-rw-r--r--api/logic/news/NewsChecker.cpp144
-rw-r--r--api/logic/news/NewsChecker.h116
-rw-r--r--api/logic/news/NewsEntry.cpp72
-rw-r--r--api/logic/news/NewsEntry.h52
-rw-r--r--api/logic/notifications/NotificationChecker.cpp158
-rw-r--r--api/logic/notifications/NotificationChecker.h74
-rw-r--r--api/logic/pathmatcher/FSTreeMatcher.h18
-rw-r--r--api/logic/pathmatcher/IPathMatcher.h6
-rw-r--r--api/logic/pathmatcher/MultiMatcher.h42
-rw-r--r--api/logic/pathmatcher/RegexpMatcher.h66
-rw-r--r--api/logic/screenshots/ImgurAlbumCreation.cpp112
-rw-r--r--api/logic/screenshots/ImgurAlbumCreation.h46
-rw-r--r--api/logic/screenshots/ImgurUpload.cpp160
-rw-r--r--api/logic/screenshots/ImgurUpload.h28
-rw-r--r--api/logic/screenshots/Screenshot.h16
-rw-r--r--api/logic/settings/INIFile.cpp180
-rw-r--r--api/logic/settings/INIFile.h16
-rw-r--r--api/logic/settings/INIFile_test.cpp96
-rw-r--r--api/logic/settings/INISettingsObject.cpp108
-rw-r--r--api/logic/settings/INISettingsObject.h48
-rw-r--r--api/logic/settings/OverrideSetting.cpp28
-rw-r--r--api/logic/settings/OverrideSetting.h18
-rw-r--r--api/logic/settings/PassthroughSetting.cpp58
-rw-r--r--api/logic/settings/PassthroughSetting.h18
-rw-r--r--api/logic/settings/Setting.cpp32
-rw-r--r--api/logic/settings/Setting.h146
-rw-r--r--api/logic/settings/SettingsObject.cpp140
-rw-r--r--api/logic/settings/SettingsObject.h312
-rw-r--r--api/logic/status/StatusChecker.cpp166
-rw-r--r--api/logic/status/StatusChecker.h36
-rw-r--r--api/logic/tasks/SequentialTask.cpp56
-rw-r--r--api/logic/tasks/SequentialTask.h22
-rw-r--r--api/logic/tasks/Task.cpp144
-rw-r--r--api/logic/tasks/Task.h98
-rw-r--r--api/logic/tools/BaseExternalTool.cpp10
-rw-r--r--api/logic/tools/BaseExternalTool.h34
-rw-r--r--api/logic/tools/BaseProfiler.cpp24
-rw-r--r--api/logic/tools/BaseProfiler.h20
-rw-r--r--api/logic/tools/JProfiler.cpp114
-rw-r--r--api/logic/tools/JProfiler.h10
-rw-r--r--api/logic/tools/JVisualVM.cpp98
-rw-r--r--api/logic/tools/JVisualVM.h10
-rw-r--r--api/logic/tools/MCEditTool.cpp84
-rw-r--r--api/logic/tools/MCEditTool.h12
-rw-r--r--api/logic/translations/TranslationsModel.cpp458
-rw-r--r--api/logic/translations/TranslationsModel.h48
-rw-r--r--api/logic/updater/DownloadTask.cpp182
-rw-r--r--api/logic/updater/DownloadTask.h110
-rw-r--r--api/logic/updater/DownloadTask_test.cpp336
-rw-r--r--api/logic/updater/GoUpdate.cpp382
-rw-r--r--api/logic/updater/GoUpdate.h138
-rw-r--r--api/logic/updater/UpdateChecker.cpp398
-rw-r--r--api/logic/updater/UpdateChecker.h168
-rw-r--r--api/logic/updater/UpdateChecker_test.cpp242
-rw-r--r--api/logic/updater/testdata/1.json82
-rw-r--r--api/logic/updater/testdata/2.json58
-rw-r--r--api/logic/updater/testdata/channels.json42
-rw-r--r--api/logic/updater/testdata/errorChannels.json42
-rw-r--r--api/logic/updater/testdata/garbageChannels.json40
-rw-r--r--api/logic/updater/testdata/index.json14
-rw-r--r--api/logic/updater/testdata/noChannels.json6
-rw-r--r--api/logic/updater/testdata/oneChannel.json18
-rw-r--r--application/BuildConfig.cpp.in84
-rw-r--r--application/BuildConfig.h90
-rw-r--r--application/ColorCache.cpp30
-rw-r--r--application/ColorCache.h178
-rw-r--r--application/ColumnResizer.cpp280
-rw-r--r--application/ColumnResizer.h20
-rw-r--r--application/GuiUtil.cpp192
-rw-r--r--application/HoeDown.h94
-rw-r--r--application/InstancePageProvider.h98
-rw-r--r--application/InstanceProxyModel.cpp36
-rw-r--r--application/InstanceProxyModel.h6
-rw-r--r--application/InstanceWindow.cpp270
-rw-r--r--application/InstanceWindow.h52
-rw-r--r--application/JavaCommon.cpp142
-rw-r--r--application/JavaCommon.h74
-rw-r--r--application/KonamiCode.cpp50
-rw-r--r--application/KonamiCode.h10
-rw-r--r--application/LaunchController.cpp482
-rw-r--r--application/LaunchController.h84
-rw-r--r--application/MainWindow.cpp2830
-rw-r--r--application/MainWindow.h210
-rw-r--r--application/MultiMC.cpp2008
-rw-r--r--application/MultiMC.h266
-rw-r--r--application/SettingsUI.h16
-rw-r--r--application/UpdateController.cpp736
-rw-r--r--application/UpdateController.h54
-rw-r--r--application/VersionProxyModel.cpp664
-rw-r--r--application/VersionProxyModel.h78
-rw-r--r--application/dialogs/AboutDialog.cpp156
-rw-r--r--application/dialogs/AboutDialog.h22
-rw-r--r--application/dialogs/CopyInstanceDialog.cpp92
-rw-r--r--application/dialogs/CopyInstanceDialog.h30
-rw-r--r--application/dialogs/CustomMessageBox.cpp22
-rw-r--r--application/dialogs/CustomMessageBox.h6
-rw-r--r--application/dialogs/EditAccountDialog.cpp24
-rw-r--r--application/dialogs/EditAccountDialog.h34
-rw-r--r--application/dialogs/ExportInstanceDialog.cpp810
-rw-r--r--application/dialogs/ExportInstanceDialog.h24
-rw-r--r--application/dialogs/IconPickerDialog.cpp186
-rw-r--r--application/dialogs/IconPickerDialog.h26
-rw-r--r--application/dialogs/LoginDialog.cpp82
-rw-r--r--application/dialogs/LoginDialog.h30
-rw-r--r--application/dialogs/ModEditDialogCommon.cpp58
-rw-r--r--application/dialogs/NewComponentDialog.cpp86
-rw-r--r--application/dialogs/NewComponentDialog.h20
-rw-r--r--application/dialogs/NewInstanceDialog.cpp198
-rw-r--r--application/dialogs/NewInstanceDialog.h52
-rw-r--r--application/dialogs/NotificationDialog.cpp114
-rw-r--r--application/dialogs/NotificationDialog.h32
-rw-r--r--application/dialogs/ProfileSelectDialog.cpp124
-rw-r--r--application/dialogs/ProfileSelectDialog.h98
-rw-r--r--application/dialogs/ProgressDialog.cpp208
-rw-r--r--application/dialogs/ProgressDialog.h40
-rw-r--r--application/dialogs/SkinUploadDialog.cpp180
-rw-r--r--application/dialogs/SkinUploadDialog.h18
-rw-r--r--application/dialogs/UpdateDialog.cpp258
-rw-r--r--application/dialogs/UpdateDialog.h40
-rw-r--r--application/dialogs/VersionSelectDialog.cpp100
-rw-r--r--application/dialogs/VersionSelectDialog.h48
-rw-r--r--application/groupview/GroupView.cpp1474
-rw-r--r--application/groupview/GroupView.h184
-rw-r--r--application/groupview/GroupedProxyModel.cpp34
-rw-r--r--application/groupview/GroupedProxyModel.h8
-rw-r--r--application/groupview/InstanceDelegate.cpp550
-rw-r--r--application/groupview/InstanceDelegate.h8
-rw-r--r--application/groupview/VisualGroup.cpp462
-rw-r--r--application/groupview/VisualGroup.h106
-rw-r--r--application/install_prereqs.cmake.in28
-rw-r--r--application/main.cpp62
-rwxr-xr-xapplication/package/linux/MultiMC116
-rw-r--r--application/pagedialog/PageDialog.cpp44
-rw-r--r--application/pagedialog/PageDialog.h10
-rw-r--r--application/pages/BasePage.h54
-rw-r--r--application/pages/BasePageContainer.h8
-rw-r--r--application/pages/BasePageProvider.h66
-rw-r--r--application/pages/global/AccountListPage.cpp140
-rw-r--r--application/pages/global/AccountListPage.h72
-rw-r--r--application/pages/global/CustomCommandsPage.cpp48
-rw-r--r--application/pages/global/CustomCommandsPage.h46
-rw-r--r--application/pages/global/ExternalToolsPage.cpp304
-rw-r--r--application/pages/global/ExternalToolsPage.h70
-rw-r--r--application/pages/global/JavaPage.cpp164
-rw-r--r--application/pages/global/JavaPage.h56
-rw-r--r--application/pages/global/MinecraftPage.cpp42
-rw-r--r--application/pages/global/MinecraftPage.h50
-rw-r--r--application/pages/global/MultiMCPage.cpp774
-rw-r--r--application/pages/global/MultiMCPage.h98
-rw-r--r--application/pages/global/PackagesPage.cpp286
-rw-r--r--application/pages/global/PackagesPage.h38
-rw-r--r--application/pages/global/PasteEEPage.cpp60
-rw-r--r--application/pages/global/PasteEEPage.h50
-rw-r--r--application/pages/global/ProxyPage.cpp88
-rw-r--r--application/pages/global/ProxyPage.h50
-rw-r--r--application/pages/instance/InstanceSettingsPage.cpp388
-rw-r--r--application/pages/instance/InstanceSettingsPage.h62
-rw-r--r--application/pages/instance/LegacyUpgradePage.cpp42
-rw-r--r--application/pages/instance/LegacyUpgradePage.h48
-rw-r--r--application/pages/instance/LogPage.cpp442
-rw-r--r--application/pages/instance/LogPage.h80
-rw-r--r--application/pages/instance/ModFolderPage.cpp220
-rw-r--r--application/pages/instance/ModFolderPage.h110
-rw-r--r--application/pages/instance/NewModFolderPage.cpp168
-rw-r--r--application/pages/instance/NewModFolderPage.h96
-rw-r--r--application/pages/instance/NotesPage.cpp14
-rw-r--r--application/pages/instance/NotesPage.h50
-rw-r--r--application/pages/instance/OtherLogsPage.cpp418
-rw-r--r--application/pages/instance/OtherLogsPage.h76
-rw-r--r--application/pages/instance/ResourcePackPage.h24
-rw-r--r--application/pages/instance/ScreenshotsPage.cpp538
-rw-r--r--application/pages/instance/ScreenshotsPage.h80
-rw-r--r--application/pages/instance/ServersPage.cpp1278
-rw-r--r--application/pages/instance/ServersPage.h78
-rw-r--r--application/pages/instance/TexturePackPage.h22
-rw-r--r--application/pages/instance/VersionPage.cpp788
-rw-r--r--application/pages/instance/VersionPage.h96
-rw-r--r--application/pages/instance/WorldListPage.cpp396
-rw-r--r--application/pages/instance/WorldListPage.h98
-rw-r--r--application/pages/modplatform/FTBPage.cpp292
-rw-r--r--application/pages/modplatform/FTBPage.h80
-rw-r--r--application/pages/modplatform/FtbListModel.cpp208
-rw-r--r--application/pages/modplatform/FtbListModel.h62
-rw-r--r--application/pages/modplatform/ImportPage.cpp152
-rw-r--r--application/pages/modplatform/ImportPage.h54
-rw-r--r--application/pages/modplatform/TechnicPage.cpp10
-rw-r--r--application/pages/modplatform/TechnicPage.h48
-rw-r--r--application/pages/modplatform/TwitchPage.cpp10
-rw-r--r--application/pages/modplatform/TwitchPage.h48
-rw-r--r--application/pages/modplatform/VanillaPage.cpp88
-rw-r--r--application/pages/modplatform/VanillaPage.h62
-rw-r--r--application/resources/OSX/OSX.qrc66
-rw-r--r--application/resources/assets/assets.qrc2
-rw-r--r--application/resources/documents/documents.qrc6
-rw-r--r--application/resources/flat/flat.qrc82
-rw-r--r--application/resources/iOS/iOS.qrc68
-rw-r--r--application/resources/multimc/multimc.qrc556
-rw-r--r--application/resources/pe_blue/pe_blue.qrc68
-rw-r--r--application/resources/pe_colored/pe_colored.qrc68
-rw-r--r--application/resources/pe_dark/pe_dark.qrc68
-rw-r--r--application/resources/pe_light/pe_light.qrc68
-rw-r--r--application/setupwizard/AnalyticsWizardPage.cpp74
-rw-r--r--application/setupwizard/AnalyticsWizardPage.h16
-rw-r--r--application/setupwizard/BaseWizardPage.h42
-rw-r--r--application/setupwizard/JavaWizardPage.cpp90
-rw-r--r--application/setupwizard/JavaWizardPage.h24
-rw-r--r--application/setupwizard/LanguageWizardPage.cpp62
-rw-r--r--application/setupwizard/LanguageWizardPage.h20
-rw-r--r--application/setupwizard/SetupWizard.cpp90
-rw-r--r--application/setupwizard/SetupWizard.h16
-rw-r--r--application/themes/BrightTheme.cpp44
-rw-r--r--application/themes/BrightTheme.h18
-rw-r--r--application/themes/CustomTheme.cpp368
-rw-r--r--application/themes/CustomTheme.h38
-rw-r--r--application/themes/DarkTheme.cpp44
-rw-r--r--application/themes/DarkTheme.h18
-rw-r--r--application/themes/FusionTheme.cpp2
-rw-r--r--application/themes/FusionTheme.h4
-rw-r--r--application/themes/ITheme.cpp68
-rw-r--r--application/themes/ITheme.h32
-rw-r--r--application/themes/SystemTheme.cpp62
-rw-r--r--application/themes/SystemTheme.h28
-rw-r--r--application/widgets/Common.cpp42
-rw-r--r--application/widgets/Common.h2
-rw-r--r--application/widgets/CustomCommands.cpp34
-rw-r--r--application/widgets/CustomCommands.h18
-rw-r--r--application/widgets/FocusLineEdit.cpp22
-rw-r--r--application/widgets/FocusLineEdit.h16
-rw-r--r--application/widgets/IconLabel.cpp40
-rw-r--r--application/widgets/IconLabel.h16
-rw-r--r--application/widgets/JavaSettingsWidget.cpp654
-rw-r--r--application/widgets/JavaSettingsWidget.h122
-rw-r--r--application/widgets/LabeledToolButton.cpp102
-rw-r--r--application/widgets/LabeledToolButton.h20
-rw-r--r--application/widgets/LineSeparator.cpp30
-rw-r--r--application/widgets/LineSeparator.h14
-rw-r--r--application/widgets/LogView.cpp186
-rw-r--r--application/widgets/LogView.h38
-rw-r--r--application/widgets/MCModInfoFrame.cpp210
-rw-r--r--application/widgets/MCModInfoFrame.h26
-rw-r--r--application/widgets/ModListView.cpp74
-rw-r--r--application/widgets/ModListView.h6
-rw-r--r--application/widgets/PageContainer.cpp310
-rw-r--r--application/widgets/PageContainer.h80
-rw-r--r--application/widgets/PageContainer_p.h156
-rw-r--r--application/widgets/ProgressWidget.cpp80
-rw-r--r--application/widgets/ProgressWidget.h22
-rw-r--r--application/widgets/ServerStatus.cpp214
-rw-r--r--application/widgets/ServerStatus.h34
-rw-r--r--application/widgets/VersionListView.cpp162
-rw-r--r--application/widgets/VersionListView.h44
-rw-r--r--application/widgets/VersionSelectWidget.cpp212
-rw-r--r--application/widgets/VersionSelectWidget.h68
-rw-r--r--libraries/LocalPeer/CMakeLists.txt12
-rw-r--r--libraries/LocalPeer/include/LocalPeer.h58
-rw-r--r--libraries/LocalPeer/src/LocalPeer.cpp248
-rw-r--r--libraries/LocalPeer/src/LockedFile.cpp152
-rw-r--r--libraries/LocalPeer/src/LockedFile.h34
-rw-r--r--libraries/LocalPeer/src/LockedFile_unix.cpp96
-rw-r--r--libraries/LocalPeer/src/LockedFile_win.cpp272
-rw-r--r--libraries/classparser/CMakeLists.txt2
-rw-r--r--libraries/classparser/src/annotations.cpp132
-rw-r--r--libraries/classparser/src/annotations.h384
-rw-r--r--libraries/classparser/src/classfile.h272
-rw-r--r--libraries/classparser/src/classparser.cpp92
-rw-r--r--libraries/classparser/src/constants.h384
-rw-r--r--libraries/classparser/src/javaendian.h32
-rw-r--r--libraries/classparser/src/membuffer.h94
-rw-r--r--libraries/ganalytics/include/ganalytics.h72
-rw-r--r--libraries/ganalytics/src/ganalytics.cpp152
-rw-r--r--libraries/ganalytics/src/ganalytics_worker.cpp280
-rw-r--r--libraries/ganalytics/src/ganalytics_worker.h70
-rw-r--r--libraries/hoedown/include/hoedown/autolink.h8
-rw-r--r--libraries/hoedown/include/hoedown/buffer.h32
-rw-r--r--libraries/hoedown/include/hoedown/document.h188
-rw-r--r--libraries/hoedown/include/hoedown/html.h40
-rw-r--r--libraries/hoedown/include/hoedown/stack.h6
-rw-r--r--libraries/hoedown/src/autolink.c414
-rw-r--r--libraries/hoedown/src/buffer.c310
-rw-r--r--libraries/hoedown/src/document.c4030
-rw-r--r--libraries/hoedown/src/escape.c218
-rw-r--r--libraries/hoedown/src/html.c914
-rw-r--r--libraries/hoedown/src/html_smartypants.c546
-rw-r--r--libraries/hoedown/src/stack.c56
-rw-r--r--libraries/hoedown/src/version.c6
-rw-r--r--libraries/iconfix/CMakeLists.txt6
-rw-r--r--libraries/iconfix/internal/qhexstring_p.h60
-rw-r--r--libraries/iconfix/internal/qiconloader.cpp934
-rw-r--r--libraries/iconfix/internal/qiconloader_p.h222
-rw-r--r--libraries/iconfix/xdgicon.cpp106
-rw-r--r--libraries/iconfix/xdgicon.h12
-rw-r--r--libraries/javacheck/CMakeLists.txt2
-rw-r--r--libraries/javacheck/JavaCheck.java38
-rw-r--r--libraries/launcher/CMakeLists.txt18
-rw-r--r--libraries/launcher/net/minecraft/Launcher.java268
-rw-r--r--libraries/launcher/org/multimc/EntryPoint.java232
-rw-r--r--libraries/launcher/org/multimc/Launcher.java2
-rw-r--r--libraries/launcher/org/multimc/ParamBucket.java108
-rw-r--r--libraries/launcher/org/multimc/Utils.java150
-rw-r--r--libraries/launcher/org/multimc/onesix/OneSixLauncher.java408
-rw-r--r--libraries/pack200/CMakeLists.txt42
-rw-r--r--libraries/pack200/anti200.cpp62
-rw-r--r--libraries/pack200/src/bands.cpp642
-rw-r--r--libraries/pack200/src/bands.h604
-rw-r--r--libraries/pack200/src/bytes.cpp246
-rw-r--r--libraries/pack200/src/bytes.h472
-rw-r--r--libraries/pack200/src/coding.cpp1762
-rw-r--r--libraries/pack200/src/coding.h348
-rw-r--r--libraries/pack200/src/constants.h712
-rw-r--r--libraries/pack200/src/unpack.cpp8346
-rw-r--r--libraries/pack200/src/unpack.h990
-rw-r--r--libraries/pack200/src/unpack200.cpp188
-rw-r--r--libraries/pack200/src/utils.cpp28
-rw-r--r--libraries/pack200/src/utils.h6
-rw-r--r--libraries/pack200/src/zip.cpp838
-rw-r--r--libraries/pack200/src/zip.h132
-rw-r--r--libraries/rainbow/CMakeLists.txt6
-rw-r--r--libraries/rainbow/include/rainbow.h12
-rw-r--r--libraries/rainbow/include/rainbow_config.h12
-rw-r--r--libraries/rainbow/src/rainbow.cpp504
-rw-r--r--libraries/systeminfo/CMakeLists.txt16
-rw-r--r--libraries/systeminfo/include/distroutils.h8
-rw-r--r--libraries/systeminfo/include/sys.h50
-rw-r--r--libraries/systeminfo/src/distroutils.cpp418
-rw-r--r--libraries/systeminfo/src/sys_apple.cpp44
-rw-r--r--libraries/systeminfo/src/sys_test.cpp28
-rw-r--r--libraries/systeminfo/src/sys_unix.cpp98
-rw-r--r--libraries/systeminfo/src/sys_win32.cpp50
-rw-r--r--libraries/xz-embedded/CMakeLists.txt16
-rw-r--r--libraries/xz-embedded/include/xz.h36
-rw-r--r--libraries/xz-embedded/src/xz_config.h24
-rw-r--r--libraries/xz-embedded/src/xz_crc32.c38
-rw-r--r--libraries/xz-embedded/src/xz_crc64.c38
-rw-r--r--libraries/xz-embedded/src/xz_dec_bcj.c902
-rw-r--r--libraries/xz-embedded/src/xz_dec_lzma2.c1810
-rw-r--r--libraries/xz-embedded/src/xz_dec_stream.c1198
-rw-r--r--libraries/xz-embedded/src/xz_lzma2.h46
-rw-r--r--libraries/xz-embedded/src/xz_private.h6
-rw-r--r--libraries/xz-embedded/src/xz_stream.h8
-rw-r--r--libraries/xz-embedded/xzminidec.c216
-rw-r--r--travis/prepare.sh68
577 files changed, 54550 insertions, 54550 deletions
diff --git a/.arcconfig b/.arcconfig
index 0e628a13..ab5cbe89 100644
--- a/.arcconfig
+++ b/.arcconfig
@@ -1,5 +1,5 @@
{
- "project_id": "MultiMC5",
- "conduit_uri": "http://ph.multimc.org"
+ "project_id": "MultiMC5",
+ "conduit_uri": "http://ph.multimc.org"
}
diff --git a/.clang-format b/.clang-format
index 8e33c4d1..f4732803 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,4 +1,4 @@
-UseTab: true
+UseTab: false
IndentWidth: 4
TabWidth: 4
ConstructorInitializerIndentWidth: 4
diff --git a/.gitmodules b/.gitmodules
index 5f2a1b8f..bd51ef80 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
[submodule "depends/libnbtplusplus"]
- path = libraries/libnbtplusplus
- url = https://github.com/MultiMC/libnbtplusplus.git
+ path = libraries/libnbtplusplus
+ url = https://github.com/MultiMC/libnbtplusplus.git
[submodule "libraries/quazip"]
- path = libraries/quazip
- url = https://github.com/MultiMC/quazip.git
+ path = libraries/quazip
+ url = https://github.com/MultiMC/quazip.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 33a53da0..bfc9527a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,12 +2,12 @@ cmake_minimum_required(VERSION 3.1)
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BUILD_DIR}" IS_IN_SOURCE_BUILD)
if(IS_IN_SOURCE_BUILD)
- message(AUTHOR_WARNING "You are building MultiMC in-source. This is NOT recommended!")
+ message(AUTHOR_WARNING "You are building MultiMC in-source. This is NOT recommended!")
endif()
if(WIN32)
- # In Qt 5.1+ we have our own main() function, don't autolink to qtmain on Windows
- cmake_policy(SET CMP0020 OLD)
+ # In Qt 5.1+ we have our own main() function, don't autolink to qtmain on Windows
+ cmake_policy(SET CMP0020 OLD)
endif()
project(MultiMC)
@@ -22,7 +22,7 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
# Output all executables and shared libs in the main build folder, not in subfolders.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
if(UNIX)
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
endif()
set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${PROJECT_BINARY_DIR}/jars)
@@ -34,7 +34,7 @@ set(CMAKE_C_STANDARD 11)
include(GenerateExportHeader)
set(CMAKE_CXX_FLAGS " -Wall -pedantic -Werror -D_GLIBCXX_USE_CXX11_ABI=0 -fstack-protector-strong --param=ssp-buffer-size=4 -O3 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS}")
if(UNIX AND APPLE)
- set(CMAKE_CXX_FLAGS " -stdlib=libc++ ${CMAKE_CXX_FLAGS}")
+ set(CMAKE_CXX_FLAGS " -stdlib=libc++ ${CMAKE_CXX_FLAGS}")
endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror=return-type")
@@ -108,124 +108,124 @@ set(MultiMC_LAYOUT "auto" CACHE STRING "The layout for MultiMC installation (aut
set_property(CACHE MultiMC_LAYOUT PROPERTY STRINGS auto win-bundle lin-bundle lin-nodeps lin-system mac-bundle)
if(MultiMC_LAYOUT STREQUAL "auto")
- if(UNIX AND APPLE)
- set(MultiMC_LAYOUT_REAL "mac-bundle")
- elseif(UNIX)
- set(MultiMC_LAYOUT_REAL "lin-nodeps")
- elseif(WIN32)
- set(MultiMC_LAYOUT_REAL "win-bundle")
- else()
- message(FATAL_ERROR "Cannot choose a sensible install layout for your platform.")
- endif()
+ if(UNIX AND APPLE)
+ set(MultiMC_LAYOUT_REAL "mac-bundle")
+ elseif(UNIX)
+ set(MultiMC_LAYOUT_REAL "lin-nodeps")
+ elseif(WIN32)
+ set(MultiMC_LAYOUT_REAL "win-bundle")
+ else()
+ message(FATAL_ERROR "Cannot choose a sensible install layout for your platform.")
+ endif()
else()
- set(MultiMC_LAYOUT_REAL ${MultiMC_LAYOUT})
+ set(MultiMC_LAYOUT_REAL ${MultiMC_LAYOUT})
endif()
if(MultiMC_LAYOUT_REAL STREQUAL "mac-bundle")
- set(BINARY_DEST_DIR "MultiMC.app/Contents/MacOS")
- set(LIBRARY_DEST_DIR "MultiMC.app/Contents/MacOS")
- set(PLUGIN_DEST_DIR "MultiMC.app/Contents/MacOS")
- set(RESOURCES_DEST_DIR "MultiMC.app/Contents/Resources")
- set(JARS_DEST_DIR "MultiMC.app/Contents/MacOS/jars")
+ set(BINARY_DEST_DIR "MultiMC.app/Contents/MacOS")
+ set(LIBRARY_DEST_DIR "MultiMC.app/Contents/MacOS")
+ set(PLUGIN_DEST_DIR "MultiMC.app/Contents/MacOS")
+ set(RESOURCES_DEST_DIR "MultiMC.app/Contents/Resources")
+ set(JARS_DEST_DIR "MultiMC.app/Contents/MacOS/jars")
- set(BUNDLE_DEST_DIR ".")
+ set(BUNDLE_DEST_DIR ".")
- # Apps to bundle
- set(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.app")
+ # Apps to bundle
+ set(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.app")
- # Mac bundle settings
- set(MACOSX_BUNDLE_BUNDLE_NAME "MultiMC")
- set(MACOSX_BUNDLE_INFO_STRING "MultiMC Minecraft launcher and management utility.")
- set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.multimc.MultiMC5")
- set(MACOSX_BUNDLE_BUNDLE_VERSION "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}")
- set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}")
- set(MACOSX_BUNDLE_LONG_VERSION_STRING "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}")
- set(MACOSX_BUNDLE_ICON_FILE MultiMC.icns)
- set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2018 MultiMC Contributors")
+ # Mac bundle settings
+ set(MACOSX_BUNDLE_BUNDLE_NAME "MultiMC")
+ set(MACOSX_BUNDLE_INFO_STRING "MultiMC Minecraft launcher and management utility.")
+ set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.multimc.MultiMC5")
+ set(MACOSX_BUNDLE_BUNDLE_VERSION "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}")
+ set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}")
+ set(MACOSX_BUNDLE_LONG_VERSION_STRING "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}")
+ set(MACOSX_BUNDLE_ICON_FILE MultiMC.icns)
+ set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2018 MultiMC Contributors")
- # directories to look for dependencies
- set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+ # directories to look for dependencies
+ set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
- # install as bundle
- set(INSTALL_BUNDLE "full")
+ # install as bundle
+ set(INSTALL_BUNDLE "full")
- # Add the icon
- install(FILES application/resources/MultiMC.icns DESTINATION ${RESOURCES_DEST_DIR})
+ # Add the icon
+ install(FILES application/resources/MultiMC.icns DESTINATION ${RESOURCES_DEST_DIR})
elseif(MultiMC_LAYOUT_REAL STREQUAL "lin-bundle")
- set(BINARY_DEST_DIR "bin")
- set(LIBRARY_DEST_DIR "bin")
- set(PLUGIN_DEST_DIR "plugins")
- set(BUNDLE_DEST_DIR ".")
- set(RESOURCES_DEST_DIR ".")
- set(JARS_DEST_DIR "bin/jars")
+ set(BINARY_DEST_DIR "bin")
+ set(LIBRARY_DEST_DIR "bin")
+ set(PLUGIN_DEST_DIR "plugins")
+ set(BUNDLE_DEST_DIR ".")
+ set(RESOURCES_DEST_DIR ".")
+ set(JARS_DEST_DIR "bin/jars")
- # Apps to bundle
- set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC")
+ # Apps to bundle
+ set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC")
- # directories to look for dependencies
- set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+ # directories to look for dependencies
+ set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
- # install as bundle
- set(INSTALL_BUNDLE "full")
+ # install as bundle
+ set(INSTALL_BUNDLE "full")
- # Set RPATH
- SET(MultiMC_BINARY_RPATH "$ORIGIN/")
+ # Set RPATH
+ SET(MultiMC_BINARY_RPATH "$ORIGIN/")
- # Install basic runner script
- install(PROGRAMS application/package/linux/MultiMC DESTINATION ${BUNDLE_DEST_DIR})
+ # Install basic runner script
+ install(PROGRAMS application/package/linux/MultiMC DESTINATION ${BUNDLE_DEST_DIR})
elseif(MultiMC_LAYOUT_REAL STREQUAL "lin-nodeps")
- set(BINARY_DEST_DIR "bin")
- set(LIBRARY_DEST_DIR "bin")
- set(PLUGIN_DEST_DIR "plugins")
- set(BUNDLE_DEST_DIR ".")
- set(RESOURCES_DEST_DIR ".")
- set(JARS_DEST_DIR "bin/jars")
+ set(BINARY_DEST_DIR "bin")
+ set(LIBRARY_DEST_DIR "bin")
+ set(PLUGIN_DEST_DIR "plugins")
+ set(BUNDLE_DEST_DIR ".")
+ set(RESOURCES_DEST_DIR ".")
+ set(JARS_DEST_DIR "bin/jars")
- # install as bundle with no dependencies included
- set(INSTALL_BUNDLE "nodeps")
+ # install as bundle with no dependencies included
+ set(INSTALL_BUNDLE "nodeps")
- # Set RPATH
- SET(MultiMC_BINARY_RPATH "$ORIGIN/")
+ # Set RPATH
+ SET(MultiMC_BINARY_RPATH "$ORIGIN/")
- # Install basic runner script
- install(PROGRAMS application/package/linux/MultiMC DESTINATION ${BUNDLE_DEST_DIR})
+ # Install basic runner script
+ install(PROGRAMS application/package/linux/MultiMC DESTINATION ${BUNDLE_DEST_DIR})
elseif(MultiMC_LAYOUT_REAL STREQUAL "lin-system")
- set(MultiMC_APP_BINARY_NAME "multimc" CACHE STRING "Name of the MultiMC binary")
- set(MultiMC_BINARY_DEST_DIR "bin" CACHE STRING "Path to the binary directory")
- set(MultiMC_LIBRARY_DEST_DIR "lib${LIB_SUFFIX}" CACHE STRING "Path to the library directory")
- set(MultiMC_SHARE_DEST_DIR "share/multimc" CACHE STRING "Path to the shared data directory")
- set(JARS_DEST_DIR "${MultiMC_SHARE_DEST_DIR}/jars")
+ set(MultiMC_APP_BINARY_NAME "multimc" CACHE STRING "Name of the MultiMC binary")
+ set(MultiMC_BINARY_DEST_DIR "bin" CACHE STRING "Path to the binary directory")
+ set(MultiMC_LIBRARY_DEST_DIR "lib${LIB_SUFFIX}" CACHE STRING "Path to the library directory")
+ set(MultiMC_SHARE_DEST_DIR "share/multimc" CACHE STRING "Path to the shared data directory")
+ set(JARS_DEST_DIR "${MultiMC_SHARE_DEST_DIR}/jars")
- set(BINARY_DEST_DIR ${MultiMC_BINARY_DEST_DIR})
- set(LIBRARY_DEST_DIR ${MultiMC_LIBRARY_DEST_DIR})
+ set(BINARY_DEST_DIR ${MultiMC_BINARY_DEST_DIR})
+ set(LIBRARY_DEST_DIR ${MultiMC_LIBRARY_DEST_DIR})
- MESSAGE(STATUS "Compiling for linux system with ${MultiMC_SHARE_DEST_DIR} and MULTIMC_LINUX_DATADIR")
- SET(MultiMC_APP_BINARY_DEFS "-DMULTIMC_JARS_LOCATION=${CMAKE_INSTALL_PREFIX}/${JARS_DEST_DIR}" "-DMULTIMC_LINUX_DATADIR")
+ MESSAGE(STATUS "Compiling for linux system with ${MultiMC_SHARE_DEST_DIR} and MULTIMC_LINUX_DATADIR")
+ SET(MultiMC_APP_BINARY_DEFS "-DMULTIMC_JARS_LOCATION=${CMAKE_INSTALL_PREFIX}/${JARS_DEST_DIR}" "-DMULTIMC_LINUX_DATADIR")
- # install as bundle with no dependencies included
- set(INSTALL_BUNDLE "nodeps")
+ # install as bundle with no dependencies included
+ set(INSTALL_BUNDLE "nodeps")
elseif(MultiMC_LAYOUT_REAL STREQUAL "win-bundle")
- set(BINARY_DEST_DIR ".")
- set(LIBRARY_DEST_DIR ".")
- set(PLUGIN_DEST_DIR ".")
- set(BUNDLE_DEST_DIR ".")
- set(RESOURCES_DEST_DIR ".")
- set(JARS_DEST_DIR "jars")
+ set(BINARY_DEST_DIR ".")
+ set(LIBRARY_DEST_DIR ".")
+ set(PLUGIN_DEST_DIR ".")
+ set(BUNDLE_DEST_DIR ".")
+ set(RESOURCES_DEST_DIR ".")
+ set(JARS_DEST_DIR "jars")
- # Apps to bundle
- set(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.exe")
+ # Apps to bundle
+ set(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.exe")
- # directories to look for dependencies
- set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+ # directories to look for dependencies
+ set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
- # install as bundle
- set(INSTALL_BUNDLE "full")
+ # install as bundle
+ set(INSTALL_BUNDLE "full")
else()
- message(FATAL_ERROR "No sensible install layout set.")
+ message(FATAL_ERROR "No sensible install layout set.")
endif()
################################ Included Libs ################################
diff --git a/COPYING.md b/COPYING.md
index ca367df3..21c773b7 100644
--- a/COPYING.md
+++ b/COPYING.md
@@ -1,254 +1,254 @@
# MultiMC
- Copyright 2012-2018 MultiMC Contributors
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
+ Copyright 2012-2018 MultiMC Contributors
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ 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.
+ 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.
# MinGW runtime (Windows)
- Copyright (c) 2012 MinGW.org project
+ Copyright (c) 2012 MinGW.org project
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the "Software"),
- to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense,
- and/or sell copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following conditions:
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
- The above copyright notice, this permission notice and the below disclaimer
- shall be included in all copies or substantial portions of the Software.
+ The above copyright notice, this permission notice and the below disclaimer
+ shall be included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
# Qt 5
- Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
- Contact: http://www.qt-project.org/legal
+ Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+ Contact: http://www.qt-project.org/legal
- Licensed under LGPL v2.1
+ Licensed under LGPL v2.1
# libnbt++
- libnbt++ - A library for the Minecraft Named Binary Tag format.
- Copyright (C) 2013, 2015 ljfa-ag
+ libnbt++ - A library for the Minecraft Named Binary Tag format.
+ Copyright (C) 2013, 2015 ljfa-ag
- libnbt++ is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ libnbt++ is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- libnbt++ 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 Lesser General Public License for more details.
+ libnbt++ 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 Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with libnbt++. If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with libnbt++. If not, see <http://www.gnu.org/licenses/>.
# rainbow (KGuiAddons)
- Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
- Copyright (C) 2007 Olaf Schmidt <ojschmidt@kde.org>
- Copyright (C) 2007 Thomas Zander <zander@kde.org>
- Copyright (C) 2007 Zack Rusin <zack@kde.org>
- Copyright (C) 2015 Petr Mrazek <peterix@gmail.com>
+ Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
+ Copyright (C) 2007 Olaf Schmidt <ojschmidt@kde.org>
+ Copyright (C) 2007 Thomas Zander <zander@kde.org>
+ Copyright (C) 2007 Zack Rusin <zack@kde.org>
+ Copyright (C) 2015 Petr Mrazek <peterix@gmail.com>
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
- This library 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
- Library General Public License for more details.
+ This library 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
+ Library General Public License for more details.
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
# Hoedown
- Copyright (c) 2008, Natacha Porté
- Copyright (c) 2011, Vicent Martí
- Copyright (c) 2014, Xavier Mendez, Devin Torres and the Hoedown authors
+ Copyright (c) 2008, Natacha Porté
+ Copyright (c) 2011, Vicent Martí
+ Copyright (c) 2014, Xavier Mendez, Devin Torres and the Hoedown authors
- Permission to use, copy, modify, and distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# Batch icon set
- You are free to use Batch (the "icon set") or any part thereof (the "icons")
- in any personal, open-source or commercial work without obligation of payment
- (monetary or otherwise) or attribution. Do not sell the icon set, host
- the icon set or rent the icon set (either in existing or modified form).
+ You are free to use Batch (the "icon set") or any part thereof (the "icons")
+ in any personal, open-source or commercial work without obligation of payment
+ (monetary or otherwise) or attribution. Do not sell the icon set, host
+ the icon set or rent the icon set (either in existing or modified form).
- While attribution is optional, it is always appreciated.
+ While attribution is optional, it is always appreciated.
- Intellectual property rights are not transferred with the download of the icons.
+ Intellectual property rights are not transferred with the download of the icons.
- EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL ADAM WHITCROFT
- BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL,
- PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THE USE OF THE ICONS,
- EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL ADAM WHITCROFT
+ BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL,
+ PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THE USE OF THE ICONS,
+ EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
# Material Design Icons
- Copyright (c) 2014, Austin Andrews (http://materialdesignicons.com/),
- with Reserved Font Name Material Design Icons.
- Copyright (c) 2014, Google (http://www.google.com/design/)
- uses the license at https://github.com/google/material-design-icons/blob/master/LICENSE
+ Copyright (c) 2014, Austin Andrews (http://materialdesignicons.com/),
+ with Reserved Font Name Material Design Icons.
+ Copyright (c) 2014, Google (http://www.google.com/design/)
+ uses the license at https://github.com/google/material-design-icons/blob/master/LICENSE
- This Font Software is licensed under the SIL Open Font License, Version 1.1.
- This license is copied below, and is also available with a FAQ at:
- http://scripts.sil.org/OFL
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
+ This license is copied below, and is also available with a FAQ at:
+ http://scripts.sil.org/OFL
# Pack200
- The GNU General Public License (GPL)
+ The GNU General Public License (GPL)
- Version 2, June 1991
+ Version 2, June 1991
- + "CLASSPATH" EXCEPTION TO THE GPL
+ + "CLASSPATH" EXCEPTION TO THE GPL
- Certain source files distributed by Oracle America and/or its affiliates are
- subject to the following clarification and special exception to the GPL, but
- only where Oracle has expressly included in the particular source file's header
- the words "Oracle designates this particular file as subject to the "Classpath"
- exception as provided by Oracle in the LICENSE file that accompanied this code."
+ Certain source files distributed by Oracle America and/or its affiliates are
+ subject to the following clarification and special exception to the GPL, but
+ only where Oracle has expressly included in the particular source file's header
+ the words "Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the LICENSE file that accompanied this code."
- Linking this library statically or dynamically with other modules is making
- a combined work based on this library. Thus, the terms and conditions of
- the GNU General Public License cover the whole combination.
+ Linking this library statically or dynamically with other modules is making
+ a combined work based on this library. Thus, the terms and conditions of
+ the GNU General Public License cover the whole combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent modules,
- and to copy and distribute the resulting executable under terms of your
- choice, provided that you also meet, for each linked independent module,
- the terms and conditions of the license of that module. An independent
- module is a module which is not derived from or based on this library. If
- you modify this library, you may extend this exception to your version of
- the library, but you are not obligated to do so. If you do not wish to do
- so, delete this exception statement from your version.
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent modules,
+ and to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent module,
+ the terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library. If
+ you modify this library, you may extend this exception to your version of
+ the library, but you are not obligated to do so. If you do not wish to do
+ so, delete this exception statement from your version.
# Quazip
- Copyright (C) 2005-2011 Sergey A. Tachenov
+ Copyright (C) 2005-2011 Sergey A. Tachenov
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at
- your option) any later version.
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at
+ your option) any later version.
- 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 Lesser
- General Public License for more details.
+ 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 Lesser
+ General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- See COPYING file for the full LGPL text.
+ See COPYING file for the full LGPL text.
- Original ZIP package is copyrighted by Gilles Vollant, see
- quazip/(un)zip.h files for details, basically it's zlib license.
+ Original ZIP package is copyrighted by Gilles Vollant, see
+ quazip/(un)zip.h files for details, basically it's zlib license.
# xz-minidec
- XZ decompressor
+ XZ decompressor
- Authors: Lasse Collin <lasse.collin@tukaani.org>
- Igor Pavlov <http://7-zip.org/>
+ Authors: Lasse Collin <lasse.collin@tukaani.org>
+ Igor Pavlov <http://7-zip.org/>
- This file has been put into the public domain.
- You can do whatever you want with this file.
+ This file has been put into the public domain.
+ You can do whatever you want with this file.
# ColumnResizer
- Copyright (c) 2011-2016 Aurélien Gâteau and contributors.
+ Copyright (c) 2011-2016 Aurélien Gâteau and contributors.
- All rights reserved.
+ All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted (subject to the limitations in the
- disclaimer below) provided that the following conditions are met:
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted (subject to the limitations in the
+ disclaimer below) provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the
- distribution.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
- * The name of the contributors may not be used to endorse or
- promote products derived from this software without specific prior
- written permission.
+ * The name of the contributors may not be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
- NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
- GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
- HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# lionshead
- Code has been taken from https://github.com/natefoo/lionshead and loosely
- translated to C++ laced with Qt.
+ Code has been taken from https://github.com/natefoo/lionshead and loosely
+ translated to C++ laced with Qt.
- MIT License
+ MIT License
- Copyright (c) 2017 Nate Coraor
+ Copyright (c) 2017 Nate Coraor
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
diff --git a/api/gui/CMakeLists.txt b/api/gui/CMakeLists.txt
index 9a6ede25..ad116a43 100644
--- a/api/gui/CMakeLists.txt
+++ b/api/gui/CMakeLists.txt
@@ -1,17 +1,17 @@
project(MultiMC_gui LANGUAGES CXX)
set(GUI_SOURCES
- DesktopServices.h
- DesktopServices.cpp
+ DesktopServices.h
+ DesktopServices.cpp
- # Icons
- icons/MMCIcon.h
- icons/MMCIcon.cpp
- icons/IconList.h
- icons/IconList.cpp
+ # Icons
+ icons/MMCIcon.h
+ icons/MMCIcon.cpp
+ icons/IconList.h
+ icons/IconList.cpp
- SkinUtils.cpp
- SkinUtils.h
+ SkinUtils.cpp
+ SkinUtils.h
)
################################ COMPILE ################################
@@ -28,7 +28,7 @@ target_include_directories(MultiMC_gui PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" "${C
# Install it
install(
- TARGETS MultiMC_gui
- RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
- LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
+ TARGETS MultiMC_gui
+ RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
+ LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
) \ No newline at end of file
diff --git a/api/gui/DesktopServices.cpp b/api/gui/DesktopServices.cpp
index 3154ea01..5368ddc8 100644
--- a/api/gui/DesktopServices.cpp
+++ b/api/gui/DesktopServices.cpp
@@ -17,132 +17,132 @@
template <typename T>
bool IndirectOpen(T callable, qint64 *pid_forked = nullptr)
{
- auto pid = fork();
- if(pid_forked)
- {
- if(pid > 0)
- *pid_forked = pid;
- else
- *pid_forked = 0;
- }
- if(pid == -1)
- {
- qWarning() << "IndirectOpen failed to fork: " << errno;
- return false;
- }
- // child - do the stuff
- if(pid == 0)
- {
- // unset all this garbage so it doesn't get passed to the child process
- qunsetenv("LD_PRELOAD");
- qunsetenv("LD_LIBRARY_PATH");
- qunsetenv("LD_DEBUG");
- qunsetenv("QT_PLUGIN_PATH");
- qunsetenv("QT_FONTPATH");
+ auto pid = fork();
+ if(pid_forked)
+ {
+ if(pid > 0)
+ *pid_forked = pid;
+ else
+ *pid_forked = 0;
+ }
+ if(pid == -1)
+ {
+ qWarning() << "IndirectOpen failed to fork: " << errno;
+ return false;
+ }
+ // child - do the stuff
+ if(pid == 0)
+ {
+ // unset all this garbage so it doesn't get passed to the child process
+ qunsetenv("LD_PRELOAD");
+ qunsetenv("LD_LIBRARY_PATH");
+ qunsetenv("LD_DEBUG");
+ qunsetenv("QT_PLUGIN_PATH");
+ qunsetenv("QT_FONTPATH");
- // open the URL
- auto status = callable();
+ // open the URL
+ auto status = callable();
- // detach from the parent process group.
- setsid();
+ // detach from the parent process group.
+ setsid();
- // die. now. do not clean up anything, it would just hang forever.
- _exit(status ? 0 : 1);
- }
- else
- {
- //parent - assume it worked.
- int status;
- while (waitpid(pid, &status, 0))
- {
- if(WIFEXITED(status))
- {
- return WEXITSTATUS(status) == 0;
- }
- if(WIFSIGNALED(status))
- {
- return false;
- }
- }
- return true;
- }
+ // die. now. do not clean up anything, it would just hang forever.
+ _exit(status ? 0 : 1);
+ }
+ else
+ {
+ //parent - assume it worked.
+ int status;
+ while (waitpid(pid, &status, 0))
+ {
+ if(WIFEXITED(status))
+ {
+ return WEXITSTATUS(status) == 0;
+ }
+ if(WIFSIGNALED(status))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
}
#endif
namespace DesktopServices {
bool openDirectory(const QString &path, bool ensureExists)
{
- qDebug() << "Opening directory" << path;
- QDir parentPath;
- QDir dir(path);
- if (!dir.exists())
- {
- parentPath.mkpath(dir.absolutePath());
- }
- auto f = [&]()
- {
- return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath()));
- };
+ qDebug() << "Opening directory" << path;
+ QDir parentPath;
+ QDir dir(path);
+ if (!dir.exists())
+ {
+ parentPath.mkpath(dir.absolutePath());
+ }
+ auto f = [&]()
+ {
+ return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath()));
+ };
#if defined(Q_OS_LINUX)
- return IndirectOpen(f);
+ return IndirectOpen(f);
#else
- return f();
+ return f();
#endif
}
bool openFile(const QString &path)
{
- qDebug() << "Opening file" << path;
- auto f = [&]()
- {
- return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
- };
+ qDebug() << "Opening file" << path;
+ auto f = [&]()
+ {
+ return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
+ };
#if defined(Q_OS_LINUX)
- return IndirectOpen(f);
+ return IndirectOpen(f);
#else
- return f();
+ return f();
#endif
}
bool openFile(const QString &application, const QString &path, const QString &workingDirectory, qint64 *pid)
{
- qDebug() << "Opening file" << path << "using" << application;
+ qDebug() << "Opening file" << path << "using" << application;
#if defined(Q_OS_LINUX)
- // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
- return IndirectOpen([&]()
- {
- return QProcess::startDetached(application, QStringList() << path, workingDirectory);
- }, pid);
+ // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
+ return IndirectOpen([&]()
+ {
+ return QProcess::startDetached(application, QStringList() << path, workingDirectory);
+ }, pid);
#else
- return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid);
+ return QProcess::startDetached(application, QStringList() << path, workingDirectory, pid);
#endif
}
bool run(const QString &application, const QStringList &args, const QString &workingDirectory, qint64 *pid)
{
- qDebug() << "Running" << application << "with args" << args.join(' ');
+ qDebug() << "Running" << application << "with args" << args.join(' ');
#if defined(Q_OS_LINUX)
- // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
- return IndirectOpen([&]()
- {
- return QProcess::startDetached(application, args, workingDirectory);
- }, pid);
+ // FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
+ return IndirectOpen([&]()
+ {
+ return QProcess::startDetached(application, args, workingDirectory);
+ }, pid);
#else
- return QProcess::startDetached(application, args, workingDirectory, pid);
+ return QProcess::startDetached(application, args, workingDirectory, pid);
#endif
}
bool openUrl(const QUrl &url)
{
- qDebug() << "Opening URL" << url.toString();
- auto f = [&]()
- {
- return QDesktopServices::openUrl(url);
- };
+ qDebug() << "Opening URL" << url.toString();
+ auto f = [&]()
+ {
+ return QDesktopServices::openUrl(url);
+ };
#if defined(Q_OS_LINUX)
- return IndirectOpen(f);
+ return IndirectOpen(f);
#else
- return f();
+ return f();
#endif
}
diff --git a/api/gui/DesktopServices.h b/api/gui/DesktopServices.h
index f64a62c5..606fa52c 100644
--- a/api/gui/DesktopServices.h
+++ b/api/gui/DesktopServices.h
@@ -10,28 +10,28 @@
*/
namespace DesktopServices
{
- /**
- * Open a file in whatever application is applicable
- */
- MULTIMC_GUI_EXPORT bool openFile(const QString &path);
+ /**
+ * Open a file in whatever application is applicable
+ */
+ MULTIMC_GUI_EXPORT bool openFile(const QString &path);
- /**
- * Open a file in the specified application
- */
- MULTIMC_GUI_EXPORT bool openFile(const QString &application, const QString &path, const QString & workingDirectory = QString(), qint64 *pid = 0);
+ /**
+ * Open a file in the specified application
+ */
+ MULTIMC_GUI_EXPORT bool openFile(const QString &application, const QString &path, const QString & workingDirectory = QString(), qint64 *pid = 0);
- /**
- * Run an application
- */
- MULTIMC_GUI_EXPORT bool run(const QString &application,const QStringList &args, const QString & workingDirectory = QString(), qint64 *pid = 0);
+ /**
+ * Run an application
+ */
+ MULTIMC_GUI_EXPORT bool run(const QString &application,const QStringList &args, const QString & workingDirectory = QString(), qint64 *pid = 0);
- /**
- * Open a directory
- */
- MULTIMC_GUI_EXPORT bool openDirectory(const QString &path, bool ensureExists = false);
+ /**
+ * Open a directory
+ */
+ MULTIMC_GUI_EXPORT bool openDirectory(const QString &path, bool ensureExists = false);
- /**
- * Open the URL, most likely in a browser. Maybe.
- */
- MULTIMC_GUI_EXPORT bool openUrl(const QUrl &url);
+ /**
+ * Open the URL, most likely in a browser. Maybe.
+ */
+ MULTIMC_GUI_EXPORT bool openUrl(const QUrl &url);
}
diff --git a/api/gui/SkinUtils.cpp b/api/gui/SkinUtils.cpp
index 3950cbc0..79edb4b9 100644
--- a/api/gui/SkinUtils.cpp
+++ b/api/gui/SkinUtils.cpp
@@ -29,19 +29,19 @@ namespace SkinUtils
*/
QPixmap getFaceFromCache(QString username, int height, int width)
{
- QFile fskin(ENV.metacache()
- ->resolveEntry("skins", username + ".png")
- ->getFullPath());
+ QFile fskin(ENV.metacache()
+ ->resolveEntry("skins", username + ".png")
+ ->getFullPath());
- if (fskin.exists())
- {
- QPixmap skin(fskin.fileName());
- if(!skin.isNull())
- {
- return skin.copy(8, 8, 8, 8).scaled(height, width, Qt::KeepAspectRatio);
- }
- }
+ if (fskin.exists())
+ {
+ QPixmap skin(fskin.fileName());
+ if(!skin.isNull())
+ {
+ return skin.copy(8, 8, 8, 8).scaled(height, width, Qt::KeepAspectRatio);
+ }
+ }
- return QPixmap();
+ return QPixmap();
}
}
diff --git a/api/gui/icons/IconList.cpp b/api/gui/icons/IconList.cpp
index 997a03db..870b347e 100644
--- a/api/gui/icons/IconList.cpp
+++ b/api/gui/icons/IconList.cpp
@@ -27,394 +27,394 @@
IconList::IconList(const QStringList &builtinPaths, QString path, QObject *parent) : QAbstractListModel(parent)
{
- QSet<QString> builtinNames;
-
- // add builtin icons
- for(auto & builtinPath: builtinPaths)
- {
- QDir instance_icons(builtinPath);
- auto file_info_list = instance_icons.entryInfoList(QDir::Files, QDir::Name);
- for (auto file_info : file_info_list)
- {
- builtinNames.insert(file_info.baseName());
- }
- }
- for(auto & builtinName : builtinNames)
- {
- addThemeIcon(builtinName);
- }
-
- m_watcher.reset(new QFileSystemWatcher());
- is_watching = false;
- connect(m_watcher.get(), SIGNAL(directoryChanged(QString)),
- SLOT(directoryChanged(QString)));
- connect(m_watcher.get(), SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString)));
-
- directoryChanged(path);
+ QSet<QString> builtinNames;
+
+ // add builtin icons
+ for(auto & builtinPath: builtinPaths)
+ {
+ QDir instance_icons(builtinPath);
+ auto file_info_list = instance_icons.entryInfoList(QDir::Files, QDir::Name);
+ for (auto file_info : file_info_list)
+ {
+ builtinNames.insert(file_info.baseName());
+ }
+ }
+ for(auto & builtinName : builtinNames)
+ {
+ addThemeIcon(builtinName);
+ }
+
+ m_watcher.reset(new QFileSystemWatcher());
+ is_watching = false;
+ connect(m_watcher.get(), SIGNAL(directoryChanged(QString)),
+ SLOT(directoryChanged(QString)));
+ connect(m_watcher.get(), SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString)));
+
+ directoryChanged(path);
}
void IconList::directoryChanged(const QString &path)
{
- QDir new_dir (path);
- if(m_dir.absolutePath() != new_dir.absolutePath())
- {
- m_dir.setPath(path);
- m_dir.refresh();
- if(is_watching)
- stopWatching();
- startWatching();
- }
- if(!m_dir.exists())
- if(!FS::ensureFolderPathExists(m_dir.absolutePath()))
- return;
- m_dir.refresh();
- auto new_list = m_dir.entryList(QDir::Files, QDir::Name);
- for (auto it = new_list.begin(); it != new_list.end(); it++)
- {
- QString &foo = (*it);
- foo = m_dir.filePath(foo);
- }
- auto new_set = new_list.toSet();
- QList<QString> current_list;
- for (auto &it : icons)
- {
- if (!it.has(IconType::FileBased))
- continue;
- current_list.push_back(it.m_images[IconType::FileBased].filename);
- }
- QSet<QString> current_set = current_list.toSet();
-
- QSet<QString> to_remove = current_set;
- to_remove -= new_set;
-
- QSet<QString> to_add = new_set;
- to_add -= current_set;
-
- for (auto remove : to_remove)
- {
- qDebug() << "Removing " << remove;
- QFileInfo rmfile(remove);
- QString key = rmfile.baseName();
- int idx = getIconIndex(key);
- if (idx == -1)
- continue;
- icons[idx].remove(IconType::FileBased);
- if (icons[idx].type() == IconType::ToBeDeleted)
- {
- beginRemoveRows(QModelIndex(), idx, idx);
- icons.remove(idx);
- reindex();
- endRemoveRows();
- }
- else
- {
- dataChanged(index(idx), index(idx));
- }
- m_watcher->removePath(remove);
- emit iconUpdated(key);
- }
-
- for (auto add : to_add)
- {
- qDebug() << "Adding " << add;
- QFileInfo addfile(add);
- QString key = addfile.baseName();
- if (addIcon(key, QString(), addfile.filePath(), IconType::FileBased))
- {
- m_watcher->addPath(add);
- emit iconUpdated(key);
- }
- }
+ QDir new_dir (path);
+ if(m_dir.absolutePath() != new_dir.absolutePath())
+ {
+ m_dir.setPath(path);
+ m_dir.refresh();
+ if(is_watching)
+ stopWatching();
+ startWatching();
+ }
+ if(!m_dir.exists())
+ if(!FS::ensureFolderPathExists(m_dir.absolutePath()))
+ return;
+ m_dir.refresh();
+ auto new_list = m_dir.entryList(QDir::Files, QDir::Name);
+ for (auto it = new_list.begin(); it != new_list.end(); it++)
+ {
+ QString &foo = (*it);
+ foo = m_dir.filePath(foo);
+ }
+ auto new_set = new_list.toSet();
+ QList<QString> current_list;
+ for (auto &it : icons)
+ {
+ if (!it.has(IconType::FileBased))
+ continue;
+ current_list.push_back(it.m_images[IconType::FileBased].filename);
+ }
+ QSet<QString> current_set = current_list.toSet();
+
+ QSet<QString> to_remove = current_set;
+ to_remove -= new_set;
+
+ QSet<QString> to_add = new_set;
+ to_add -= current_set;
+
+ for (auto remove : to_remove)
+ {
+ qDebug() << "Removing " << remove;
+ QFileInfo rmfile(remove);
+ QString key = rmfile.baseName();
+ int idx = getIconIndex(key);
+ if (idx == -1)
+ continue;
+ icons[idx].remove(IconType::FileBased);
+ if (icons[idx].type() == IconType::ToBeDeleted)
+ {
+ beginRemoveRows(QModelIndex(), idx, idx);
+ icons.remove(idx);
+ reindex();
+ endRemoveRows();
+ }
+ else
+ {
+ dataChanged(index(idx), index(idx));
+ }
+ m_watcher->removePath(remove);
+ emit iconUpdated(key);
+ }
+
+ for (auto add : to_add)
+ {
+ qDebug() << "Adding " << add;
+ QFileInfo addfile(add);
+ QString key = addfile.baseName();
+ if (addIcon(key, QString(), addfile.filePath(), IconType::FileBased))
+ {
+ m_watcher->addPath(add);
+ emit iconUpdated(key);
+ }
+ }
}
void IconList::fileChanged(const QString &path)
{
- qDebug() << "Checking " << path;
- QFileInfo checkfile(path);
- if (!checkfile.exists())
- return;
- QString key = checkfile.baseName();
- int idx = getIconIndex(key);
- if (idx == -1)
- return;
- QIcon icon(path);
- if (!icon.availableSizes().size())
- return;
-
- icons[idx].m_images[IconType::FileBased].icon = icon;
- dataChanged(index(idx), index(idx));
- emit iconUpdated(key);
+ qDebug() << "Checking " << path;
+ QFileInfo checkfile(path);
+ if (!checkfile.exists())
+ return;
+ QString key = checkfile.baseName();
+ int idx = getIconIndex(key);
+ if (idx == -1)
+ return;
+ QIcon icon(path);
+ if (!icon.availableSizes().size())
+ return;
+
+ icons[idx].m_images[IconType::FileBased].icon = icon;
+ dataChanged(index(idx), index(idx));
+ emit iconUpdated(key);
}
void IconList::SettingChanged(const Setting &setting, QVariant value)
{
- if(setting.id() != "IconsDir")
- return;
+ if(setting.id() != "IconsDir")
+ return;
- directoryChanged(value.toString());
+ directoryChanged(value.toString());
}
void IconList::startWatching()
{
- auto abs_path = m_dir.absolutePath();
- FS::ensureFolderPathExists(abs_path);
- is_watching = m_watcher->addPath(abs_path);
- if (is_watching)
- {
- qDebug() << "Started watching " << abs_path;
- }
- else
- {
- qDebug() << "Failed to start watching " << abs_path;
- }
+ auto abs_path = m_dir.absolutePath();
+ FS::ensureFolderPathExists(abs_path);
+ is_watching = m_watcher->addPath(abs_path);
+ if (is_watching)
+ {
+ qDebug() << "Started watching " << abs_path;
+ }
+ else
+ {
+ qDebug() << "Failed to start watching " << abs_path;
+ }
}
void IconList::stopWatching()
{
- m_watcher->removePaths(m_watcher->files());
- m_watcher->removePaths(m_watcher->directories());
- is_watching = false;
+ m_watcher->removePaths(m_watcher->files());
+ m_watcher->removePaths(m_watcher->directories());
+ is_watching = false;
}
QStringList IconList::mimeTypes() const
{
- QStringList types;
- types << "text/uri-list";
- return types;
+ QStringList types;
+ types << "text/uri-list";
+ return types;
}
Qt::DropActions IconList::supportedDropActions() const
{
- return Qt::CopyAction;
+ return Qt::CopyAction;
}
bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
- const QModelIndex &parent)
+ const QModelIndex &parent)
{
- if (action == Qt::IgnoreAction)
- return true;
- // check if the action is supported
- if (!data || !(action & supportedDropActions()))
- return false;
-
- // files dropped from outside?
- if (data->hasUrls())
- {
- auto urls = data->urls();
- QStringList iconFiles;
- for (auto url : urls)
- {
- // only local files may be dropped...
- if (!url.isLocalFile())
- continue;
- iconFiles += url.toLocalFile();
- }
- installIcons(iconFiles);
- return true;
- }
- return false;
+ if (action == Qt::IgnoreAction)
+ return true;
+ // check if the action is supported
+ if (!data || !(action & supportedDropActions()))
+ return false;
+
+ // files dropped from outside?
+ if (data->hasUrls())
+ {
+ auto urls = data->urls();
+ QStringList iconFiles;
+ for (auto url : urls)
+ {
+ // only local files may be dropped...
+ if (!url.isLocalFile())
+ continue;
+ iconFiles += url.toLocalFile();
+ }
+ installIcons(iconFiles);
+ return true;
+ }
+ return false;
}
Qt::ItemFlags IconList::flags(const QModelIndex &index) const
{
- Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
- if (index.isValid())
- return Qt::ItemIsDropEnabled | defaultFlags;
- else
- return Qt::ItemIsDropEnabled | defaultFlags;
+ Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
+ if (index.isValid())
+ return Qt::ItemIsDropEnabled | defaultFlags;
+ else
+ return Qt::ItemIsDropEnabled | defaultFlags;
}
QVariant IconList::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
-
- if (row < 0 || row >= icons.size())
- return QVariant();
-
- switch (role)
- {
- case Qt::DecorationRole:
- return icons[row].icon();
- case Qt::DisplayRole:
- return icons[row].name();
- case Qt::UserRole:
- return icons[row].m_key;
- default:
- return QVariant();
- }
+ if (!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+
+ if (row < 0 || row >= icons.size())
+ return QVariant();
+
+ switch (role)
+ {
+ case Qt::DecorationRole:
+ return icons[row].icon();
+ case Qt::DisplayRole:
+ return icons[row].name();
+ case Qt::UserRole:
+ return icons[row].m_key;
+ default:
+ return QVariant();
+ }
}
int IconList::rowCount(const QModelIndex &parent) const
{
- return icons.size();
+ return icons.size();
}
void IconList::installIcons(const QStringList &iconFiles)
{
- for (QString file : iconFiles)
- {
- QFileInfo fileinfo(file);
- if (!fileinfo.isReadable() || !fileinfo.isFile())
- continue;
- QString target = FS::PathCombine(m_dir.dirName(), fileinfo.fileName());
-
- QString suffix = fileinfo.suffix();
- if (suffix != "jpeg" && suffix != "png" && suffix != "jpg" && suffix != "ico" && suffix != "svg")
- continue;
-
- if (!QFile::copy(file, target))
- continue;
- }
+ for (QString file : iconFiles)
+ {
+ QFileInfo fileinfo(file);
+ if (!fileinfo.isReadable() || !fileinfo.isFile())
+ continue;
+ QString target = FS::PathCombine(m_dir.dirName(), fileinfo.fileName());
+
+ QString suffix = fileinfo.suffix();
+ if (suffix != "jpeg" && suffix != "png" && suffix != "jpg" && suffix != "ico" && suffix != "svg")
+ continue;
+
+ if (!QFile::copy(file, target))
+ continue;
+ }
}
void IconList::installIcon(const QString &file, const QString &name)
{
- QFileInfo fileinfo(file);
- if(!fileinfo.isReadable() || !fileinfo.isFile())
- return;
+ QFileInfo fileinfo(file);
+ if(!fileinfo.isReadable() || !fileinfo.isFile())
+ return;
- QString target = FS::PathCombine(m_dir.dirName(), name);
+ QString target = FS::PathCombine(m_dir.dirName(), name);
- QFile::copy(file, target);
+ QFile::copy(file, target);
}
bool IconList::iconFileExists(const QString &key) const
{
- auto iconEntry = icon(key);
- if(!iconEntry)
- {
- return false;
- }
- return iconEntry->has(IconType::FileBased);
+ auto iconEntry = icon(key);
+ if(!iconEntry)
+ {
+ return false;
+ }
+ return iconEntry->has(IconType::FileBased);
}
const MMCIcon *IconList::icon(const QString &key) const
{
- int iconIdx = getIconIndex(key);
- if (iconIdx == -1)
- return nullptr;
- return &icons[iconIdx];
+ int iconIdx = getIconIndex(key);
+ if (iconIdx == -1)
+ return nullptr;
+ return &icons[iconIdx];
}
bool IconList::deleteIcon(const QString &key)
{
- int iconIdx = getIconIndex(key);
- if (iconIdx == -1)
- return false;
- auto &iconEntry = icons[iconIdx];
- if (iconEntry.has(IconType::FileBased))
- {
- return QFile::remove(iconEntry.m_images[IconType::FileBased].filename);
- }
- return false;
+ int iconIdx = getIconIndex(key);
+ if (iconIdx == -1)
+ return false;
+ auto &iconEntry = icons[iconIdx];
+ if (iconEntry.has(IconType::FileBased))
+ {
+ return QFile::remove(iconEntry.m_images[IconType::FileBased].filename);
+ }
+ return false;
}
bool IconList::addThemeIcon(const QString& key)
{
- auto iter = name_index.find(key);
- if (iter != name_index.end())
- {
- auto &oldOne = icons[*iter];
- oldOne.replace(Builtin, key);
- dataChanged(index(*iter), index(*iter));
- return true;
- }
- else
- {
- // add a new icon
- beginInsertRows(QModelIndex(), icons.size(), icons.size());
- {
- MMCIcon mmc_icon;
- mmc_icon.m_name = key;
- mmc_icon.m_key = key;
- mmc_icon.replace(Builtin, key);
- icons.push_back(mmc_icon);
- name_index[key] = icons.size() - 1;
- }
- endInsertRows();
- return true;
- }
+ auto iter = name_index.find(key);
+ if (iter != name_index.end())
+ {
+ auto &oldOne = icons[*iter];
+ oldOne.replace(Builtin, key);
+ dataChanged(index(*iter), index(*iter));
+ return true;
+ }
+ else
+ {
+ // add a new icon
+ beginInsertRows(QModelIndex(), icons.size(), icons.size());
+ {
+ MMCIcon mmc_icon;
+ mmc_icon.m_name = key;
+ mmc_icon.m_key = key;
+ mmc_icon.replace(Builtin, key);
+ icons.push_back(mmc_icon);
+ name_index[key] = icons.size() - 1;
+ }
+ endInsertRows();
+ return true;
+ }
}
bool IconList::addIcon(const QString &key, const QString &name, const QString &path, const IconType type)
{
- // replace the icon even? is the input valid?
- QIcon icon(path);
- if (icon.isNull())
- return false;
- auto iter = name_index.find(key);
- if (iter != name_index.end())
- {
- auto &oldOne = icons[*iter];
- oldOne.replace(type, icon, path);
- dataChanged(index(*iter), index(*iter));
- return true;
- }
- else
- {
- // add a new icon
- beginInsertRows(QModelIndex(), icons.size(), icons.size());
- {
- MMCIcon mmc_icon;
- mmc_icon.m_name = name;
- mmc_icon.m_key = key;
- mmc_icon.replace(type, icon, path);
- icons.push_back(mmc_icon);
- name_index[key] = icons.size() - 1;
- }
- endInsertRows();
- return true;
- }
+ // replace the icon even? is the input valid?
+ QIcon icon(path);
+ if (icon.isNull())
+ return false;
+ auto iter = name_index.find(key);
+ if (iter != name_index.end())
+ {
+ auto &oldOne = icons[*iter];
+ oldOne.replace(type, icon, path);
+ dataChanged(index(*iter), index(*iter));
+ return true;
+ }
+ else
+ {
+ // add a new icon
+ beginInsertRows(QModelIndex(), icons.size(), icons.size());
+ {
+ MMCIcon mmc_icon;
+ mmc_icon.m_name = name;
+ mmc_icon.m_key = key;
+ mmc_icon.replace(type, icon, path);
+ icons.push_back(mmc_icon);
+ name_index[key] = icons.size() - 1;
+ }
+ endInsertRows();
+ return true;
+ }
}
void IconList::saveIcon(const QString &key, const QString &path, const char * format) const
{
- auto icon = getIcon(key);
- auto pixmap = icon.pixmap(128, 128);
- pixmap.save(path, format);
+ auto icon = getIcon(key);
+ auto pixmap = icon.pixmap(128, 128);
+ pixmap.save(path, format);
}
void IconList::reindex()
{
- name_index.clear();
- int i = 0;
- for (auto &iter : icons)
- {
- name_index[iter.m_key] = i;
- i++;
- }
+ name_index.clear();
+ int i = 0;
+ for (auto &iter : icons)
+ {
+ name_index[iter.m_key] = i;
+ i++;
+ }
}
QIcon IconList::getIcon(const QString &key) const
{
- int icon_index = getIconIndex(key);
+ int icon_index = getIconIndex(key);
- if (icon_index != -1)
- return icons[icon_index].icon();
+ if (icon_index != -1)
+ return icons[icon_index].icon();
- // Fallback for icons that don't exist.
- icon_index = getIconIndex("infinity");
+ // Fallback for icons that don't exist.
+ icon_index = getIconIndex("infinity");
- if (icon_index != -1)
- return icons[icon_index].icon();
- return QIcon();
+ if (icon_index != -1)
+ return icons[icon_index].icon();
+ return QIcon();
}
int IconList::getIconIndex(const QString &key) const
{
- auto iter = name_index.find(key == "default" ? "infinity" : key);
- if (iter != name_index.end())
- return *iter;
+ auto iter = name_index.find(key == "default" ? "infinity" : key);
+ if (iter != name_index.end())
+ return *iter;
- return -1;
+ return -1;
}
QString IconList::getDirectory() const
{
- return m_dir.absolutePath();
+ return m_dir.absolutePath();
}
//#include "IconList.moc"
diff --git a/api/gui/icons/IconList.h b/api/gui/icons/IconList.h
index fad3336f..97ed3956 100644
--- a/api/gui/icons/IconList.h
+++ b/api/gui/icons/IconList.h
@@ -32,57 +32,57 @@ class QFileSystemWatcher;
class MULTIMC_GUI_EXPORT IconList : public QAbstractListModel, public IIconList
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit IconList(const QStringList &builtinPaths, QString path, QObject *parent = 0);
- virtual ~IconList() {};
+ explicit IconList(const QStringList &builtinPaths, QString path, QObject *parent = 0);
+ virtual ~IconList() {};
- QIcon getIcon(const QString &key) const;
- int getIconIndex(const QString &key) const;
- QString getDirectory() const;
+ QIcon getIcon(const QString &key) const;
+ int getIconIndex(const QString &key) const;
+ QString getDirectory() const;
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- bool addThemeIcon(const QString &key);
- bool addIcon(const QString &key, const QString &name, const QString &path, const IconType type) override;
- void saveIcon(const QString &key, const QString &path, const char * format) const override;
- bool deleteIcon(const QString &key) override;
- bool iconFileExists(const QString &key) const override;
+ bool addThemeIcon(const QString &key);
+ bool addIcon(const QString &key, const QString &name, const QString &path, const IconType type) override;
+ void saveIcon(const QString &key, const QString &path, const char * format) const override;
+ bool deleteIcon(const QString &key) override;
+ bool iconFileExists(const QString &key) const override;
- virtual QStringList mimeTypes() const override;
- virtual Qt::DropActions supportedDropActions() const override;
- virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
- virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
+ virtual QStringList mimeTypes() const override;
+ virtual Qt::DropActions supportedDropActions() const override;
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
- void installIcons(const QStringList &iconFiles) override;
- void installIcon(const QString &file, const QString &name) override;
+ void installIcons(const QStringList &iconFiles) override;
+ void installIcon(const QString &file, const QString &name) override;
- const MMCIcon * icon(const QString &key) const;
+ const MMCIcon * icon(const QString &key) const;
- void startWatching();
- void stopWatching();
+ void startWatching();
+ void stopWatching();
signals:
- void iconUpdated(QString key);
+ void iconUpdated(QString key);
private:
- // hide copy constructor
- IconList(const IconList &) = delete;
- // hide assign op
- IconList &operator=(const IconList &) = delete;
- void reindex();
+ // hide copy constructor
+ IconList(const IconList &) = delete;
+ // hide assign op
+ IconList &operator=(const IconList &) = delete;
+ void reindex();
public slots:
- void directoryChanged(const QString &path);
+ void directoryChanged(const QString &path);
protected slots:
- void fileChanged(const QString &path);
- void SettingChanged(const Setting & setting, QVariant value);
+ void fileChanged(const QString &path);
+ void SettingChanged(const Setting & setting, QVariant value);
private:
- std::shared_ptr<QFileSystemWatcher> m_watcher;
- bool is_watching;
- QMap<QString, int> name_index;
- QVector<MMCIcon> icons;
- QDir m_dir;
+ std::shared_ptr<QFileSystemWatcher> m_watcher;
+ bool is_watching;
+ QMap<QString, int> name_index;
+ QVector<MMCIcon> icons;
+ QDir m_dir;
};
diff --git a/api/gui/icons/MMCIcon.cpp b/api/gui/icons/MMCIcon.cpp
index 92518e01..a5ab548e 100644
--- a/api/gui/icons/MMCIcon.cpp
+++ b/api/gui/icons/MMCIcon.cpp
@@ -19,86 +19,86 @@
IconType operator--(IconType &t, int)
{
- IconType temp = t;
- switch (t)
- {
- case IconType::Builtin:
- t = IconType::ToBeDeleted;
- break;
- case IconType::Transient:
- t = IconType::Builtin;
- break;
- case IconType::FileBased:
- t = IconType::Transient;
- break;
- default:
- {
- }
- }
- return temp;
+ IconType temp = t;
+ switch (t)
+ {
+ case IconType::Builtin:
+ t = IconType::ToBeDeleted;
+ break;
+ case IconType::Transient:
+ t = IconType::Builtin;
+ break;
+ case IconType::FileBased:
+ t = IconType::Transient;
+ break;
+ default:
+ {
+ }
+ }
+ return temp;
}
IconType MMCIcon::type() const
{
- return m_current_type;
+ return m_current_type;
}
QString MMCIcon::name() const
{
- if (m_name.size())
- return m_name;
- return m_key;
+ if (m_name.size())
+ return m_name;
+ return m_key;
}
bool MMCIcon::has(IconType _type) const
{
- return m_images[_type].present();
+ return m_images[_type].present();
}
QIcon MMCIcon::icon() const
{
- if (m_current_type == IconType::ToBeDeleted)
- return QIcon();
- auto & icon = m_images[m_current_type].icon;
- if(!icon.isNull())
- return icon;
- // FIXME: inject this.
- return XdgIcon::fromTheme(m_images[m_current_type].key);
+ if (m_current_type == IconType::ToBeDeleted)
+ return QIcon();
+ auto & icon = m_images[m_current_type].icon;
+ if(!icon.isNull())
+ return icon;
+ // FIXME: inject this.
+ return XdgIcon::fromTheme(m_images[m_current_type].key);
}
void MMCIcon::remove(IconType rm_type)
{
- m_images[rm_type].filename = QString();
- m_images[rm_type].icon = QIcon();
- for (auto iter = rm_type; iter != IconType::ToBeDeleted; iter--)
- {
- if (m_images[iter].present())
- {
- m_current_type = iter;
- return;
- }
- }
- m_current_type = IconType::ToBeDeleted;
+ m_images[rm_type].filename = QString();
+ m_images[rm_type].icon = QIcon();
+ for (auto iter = rm_type; iter != IconType::ToBeDeleted; iter--)
+ {
+ if (m_images[iter].present())
+ {
+ m_current_type = iter;
+ return;
+ }
+ }
+ m_current_type = IconType::ToBeDeleted;
}
void MMCIcon::replace(IconType new_type, QIcon icon, QString path)
{
- if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted)
- {
- m_current_type = new_type;
- }
- m_images[new_type].icon = icon;
- m_images[new_type].filename = path;
- m_images[new_type].key = QString();
+ if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted)
+ {
+ m_current_type = new_type;
+ }
+ m_images[new_type].icon = icon;
+ m_images[new_type].filename = path;
+ m_images[new_type].key = QString();
}
void MMCIcon::replace(IconType new_type, const QString& key)
{
- if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted)
- {
- m_current_type = new_type;
- }
- m_images[new_type].icon = QIcon();
- m_images[new_type].filename = QString();
- m_images[new_type].key = key;
+ if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted)
+ {
+ m_current_type = new_type;
+ }
+ m_images[new_type].icon = QIcon();
+ m_images[new_type].filename = QString();
+ m_images[new_type].key = key;
}
diff --git a/api/gui/icons/MMCIcon.h b/api/gui/icons/MMCIcon.h
index 8c6752ea..d7618bee 100644
--- a/api/gui/icons/MMCIcon.h
+++ b/api/gui/icons/MMCIcon.h
@@ -23,27 +23,27 @@
struct MULTIMC_GUI_EXPORT MMCImage
{
- QIcon icon;
- QString key;
- QString filename;
- bool present() const
- {
- return !icon.isNull() || !key.isEmpty();
- }
+ QIcon icon;
+ QString key;
+ QString filename;
+ bool present() const
+ {
+ return !icon.isNull() || !key.isEmpty();
+ }
};
struct MULTIMC_GUI_EXPORT MMCIcon
{
- QString m_key;
- QString m_name;
- MMCImage m_images[ICONS_TOTAL];
- IconType m_current_type = ToBeDeleted;
+ QString m_key;
+ QString m_name;
+ MMCImage m_images[ICONS_TOTAL];
+ IconType m_current_type = ToBeDeleted;
- IconType type() const;
- QString name() const;
- bool has(IconType _type) const;
- QIcon icon() const;
- void remove(IconType rm_type);
- void replace(IconType new_type, QIcon icon, QString path = QString());
- void replace(IconType new_type, const QString &key);
+ IconType type() const;
+ QString name() const;
+ bool has(IconType _type) const;
+ QIcon icon() const;
+ void remove(IconType rm_type);
+ void replace(IconType new_type, QIcon icon, QString path = QString());
+ void replace(IconType new_type, const QString &key);
};
diff --git a/api/logic/BaseInstaller.cpp b/api/logic/BaseInstaller.cpp
index 51f66293..e25683a9 100644
--- a/api/logic/BaseInstaller.cpp
+++ b/api/logic/BaseInstaller.cpp
@@ -25,37 +25,37 @@ BaseInstaller::BaseInstaller()
bool BaseInstaller::isApplied(MinecraftInstance *on)
{
- return QFile::exists(filename(on->instanceRoot()));
+ return QFile::exists(filename(on->instanceRoot()));
}
bool BaseInstaller::add(MinecraftInstance *to)
{
- if (!patchesDir(to->instanceRoot()).exists())
- {
- QDir(to->instanceRoot()).mkdir("patches");
- }
-
- if (isApplied(to))
- {
- if (!remove(to))
- {
- return false;
- }
- }
-
- return true;
+ if (!patchesDir(to->instanceRoot()).exists())
+ {
+ QDir(to->instanceRoot()).mkdir("patches");
+ }
+
+ if (isApplied(to))
+ {
+ if (!remove(to))
+ {
+ return false;
+ }
+ }
+
+ return true;
}
bool BaseInstaller::remove(MinecraftInstance *from)
{
- return QFile::remove(filename(from->instanceRoot()));
+ return QFile::remove(filename(from->instanceRoot()));
}
QString BaseInstaller::filename(const QString &root) const
{
- return patchesDir(root).absoluteFilePath(id() + ".json");
+ return patchesDir(root).absoluteFilePath(id() + ".json");
}
QDir BaseInstaller::patchesDir(const QString &root) const
{
- return QDir(root + "/patches/");
+ return QDir(root + "/patches/");
}
diff --git a/api/logic/BaseInstaller.h b/api/logic/BaseInstaller.h
index afe11d55..121d35ef 100644
--- a/api/logic/BaseInstaller.h
+++ b/api/logic/BaseInstaller.h
@@ -30,17 +30,17 @@ typedef std::shared_ptr<BaseVersion> BaseVersionPtr;
class MULTIMC_LOGIC_EXPORT BaseInstaller
{
public:
- BaseInstaller();
- virtual ~BaseInstaller(){};
- bool isApplied(MinecraftInstance *on);
+ BaseInstaller();
+ virtual ~BaseInstaller(){};
+ bool isApplied(MinecraftInstance *on);
- virtual bool add(MinecraftInstance *to);
- virtual bool remove(MinecraftInstance *from);
+ virtual bool add(MinecraftInstance *to);
+ virtual bool remove(MinecraftInstance *from);
- virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersionPtr version, QObject *parent) = 0;
+ virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersionPtr version, QObject *parent) = 0;
protected:
- virtual QString id() const = 0;
- QString filename(const QString &root) const;
- QDir patchesDir(const QString &root) const;
+ virtual QString id() const = 0;
+ QString filename(const QString &root) const;
+ QDir patchesDir(const QString &root) const;
};
diff --git a/api/logic/BaseInstance.cpp b/api/logic/BaseInstance.cpp
index 7e652e0d..c81b70c6 100644
--- a/api/logic/BaseInstance.cpp
+++ b/api/logic/BaseInstance.cpp
@@ -27,281 +27,281 @@
#include "Commandline.h"
BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : QObject()
+ : QObject()
{
- m_settings = settings;
- m_rootDir = rootDir;
+ m_settings = settings;
+ m_rootDir = rootDir;
- m_settings->registerSetting("name", "Unnamed Instance");
- m_settings->registerSetting("iconKey", "default");
- m_settings->registerSetting("notes", "");
- m_settings->registerSetting("lastLaunchTime", 0);
- m_settings->registerSetting("totalTimePlayed", 0);
+ m_settings->registerSetting("name", "Unnamed Instance");
+ m_settings->registerSetting("iconKey", "default");
+ m_settings->registerSetting("notes", "");
+ m_settings->registerSetting("lastLaunchTime", 0);
+ m_settings->registerSetting("totalTimePlayed", 0);
- // Custom Commands
- auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false);
- m_settings->registerOverride(globalSettings->getSetting("PreLaunchCommand"), commandSetting);
- m_settings->registerOverride(globalSettings->getSetting("WrapperCommand"), commandSetting);
- m_settings->registerOverride(globalSettings->getSetting("PostExitCommand"), commandSetting);
+ // Custom Commands
+ auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false);
+ m_settings->registerOverride(globalSettings->getSetting("PreLaunchCommand"), commandSetting);
+ m_settings->registerOverride(globalSettings->getSetting("WrapperCommand"), commandSetting);
+ m_settings->registerOverride(globalSettings->getSetting("PostExitCommand"), commandSetting);
- // Console
- auto consoleSetting = m_settings->registerSetting("OverrideConsole", false);
- m_settings->registerOverride(globalSettings->getSetting("ShowConsole"), consoleSetting);
- m_settings->registerOverride(globalSettings->getSetting("AutoCloseConsole"), consoleSetting);
- m_settings->registerOverride(globalSettings->getSetting("ShowConsoleOnError"), consoleSetting);
- m_settings->registerOverride(globalSettings->getSetting("LogPrePostOutput"), consoleSetting);
+ // Console
+ auto consoleSetting = m_settings->registerSetting("OverrideConsole", false);
+ m_settings->registerOverride(globalSettings->getSetting("ShowConsole"), consoleSetting);
+ m_settings->registerOverride(globalSettings->getSetting("AutoCloseConsole"), consoleSetting);
+ m_settings->registerOverride(globalSettings->getSetting("ShowConsoleOnError"), consoleSetting);
+ m_settings->registerOverride(globalSettings->getSetting("LogPrePostOutput"), consoleSetting);
- m_settings->registerPassthrough(globalSettings->getSetting("ConsoleMaxLines"), nullptr);
- m_settings->registerPassthrough(globalSettings->getSetting("ConsoleOverflowStop"), nullptr);
+ m_settings->registerPassthrough(globalSettings->getSetting("ConsoleMaxLines"), nullptr);
+ m_settings->registerPassthrough(globalSettings->getSetting("ConsoleOverflowStop"), nullptr);
}
QString BaseInstance::getPreLaunchCommand()
{
- return settings()->get("PreLaunchCommand").toString();
+ return settings()->get("PreLaunchCommand").toString();
}
QString BaseInstance::getWrapperCommand()
{
- return settings()->get("WrapperCommand").toString();
+ return settings()->get("WrapperCommand").toString();
}
QString BaseInstance::getPostExitCommand()
{
- return settings()->get("PostExitCommand").toString();
+ return settings()->get("PostExitCommand").toString();
}
int BaseInstance::getConsoleMaxLines() const
{
- auto lineSetting = settings()->getSetting("ConsoleMaxLines");
- bool conversionOk = false;
- int maxLines = lineSetting->get().toInt(&conversionOk);
- if(!conversionOk)
- {
- maxLines = lineSetting->defValue().toInt();
- qWarning() << "ConsoleMaxLines has nonsensical value, defaulting to" << maxLines;
- }
- return maxLines;
+ auto lineSetting = settings()->getSetting("ConsoleMaxLines");
+ bool conversionOk = false;
+ int maxLines = lineSetting->get().toInt(&conversionOk);
+ if(!conversionOk)
+ {
+ maxLines = lineSetting->defValue().toInt();
+ qWarning() << "ConsoleMaxLines has nonsensical value, defaulting to" << maxLines;
+ }
+ return maxLines;
}
bool BaseInstance::shouldStopOnConsoleOverflow() const
{
- return settings()->get("ConsoleOverflowStop").toBool();
+ return settings()->get("ConsoleOverflowStop").toBool();
}
void BaseInstance::iconUpdated(QString key)
{
- if(iconKey() == key)
- {
- emit propertiesChanged(this);
- }
+ if(iconKey() == key)
+ {
+ emit propertiesChanged(this);
+ }
}
void BaseInstance::invalidate()
{
- changeStatus(Status::Gone);
- qDebug() << "Instance" << id() << "has been invalidated.";
+ changeStatus(Status::Gone);
+ qDebug() << "Instance" << id() << "has been invalidated.";
}
void BaseInstance::nuke()
{
- changeStatus(Status::Gone);
- qDebug() << "Instance" << id() << "has been deleted by MultiMC.";
- FS::deletePath(instanceRoot());
+ changeStatus(Status::Gone);
+ qDebug() << "Instance" << id() << "has been deleted by MultiMC.";
+ FS::deletePath(instanceRoot());
}
void BaseInstance::changeStatus(BaseInstance::Status newStatus)
{
- Status status = currentStatus();
- if(status != newStatus)
- {
- m_status = newStatus;
- emit statusChanged(status, newStatus);
- }
+ Status status = currentStatus();
+ if(status != newStatus)
+ {
+ m_status = newStatus;
+ emit statusChanged(status, newStatus);
+ }
}
BaseInstance::Status BaseInstance::currentStatus() const
{
- return m_status;
+ return m_status;
}
QString BaseInstance::id() const
{
- return QFileInfo(instanceRoot()).fileName();
+ return QFileInfo(instanceRoot()).fileName();
}
bool BaseInstance::isRunning() const
{
- return m_isRunning;
+ return m_isRunning;
}
void BaseInstance::setRunning(bool running)
{
- if(running == m_isRunning)
- return;
+ if(running == m_isRunning)
+ return;
- m_isRunning = running;
+ m_isRunning = running;
- if(running)
- {
- m_timeStarted = QDateTime::currentDateTime();
- }
- else
- {
- qint64 current = settings()->get("totalTimePlayed").toLongLong();
- QDateTime timeEnded = QDateTime::currentDateTime();
- settings()->set("totalTimePlayed", current + m_timeStarted.secsTo(timeEnded));
- emit propertiesChanged(this);
- }
+ if(running)
+ {
+ m_timeStarted = QDateTime::currentDateTime();
+ }
+ else
+ {
+ qint64 current = settings()->get("totalTimePlayed").toLongLong();
+ QDateTime timeEnded = QDateTime::currentDateTime();
+ settings()->set("totalTimePlayed", current + m_timeStarted.secsTo(timeEnded));
+ emit propertiesChanged(this);
+ }
- emit runningStatusChanged(running);
+ emit runningStatusChanged(running);
}
int64_t BaseInstance::totalTimePlayed() const
{
- qint64 current = settings()->get("totalTimePlayed").toLongLong();
- if(m_isRunning)
- {
- QDateTime timeNow = QDateTime::currentDateTime();
- return current + m_timeStarted.secsTo(timeNow);
- }
- return current;
+ qint64 current = settings()->get("totalTimePlayed").toLongLong();
+ if(m_isRunning)
+ {
+ QDateTime timeNow = QDateTime::currentDateTime();
+ return current + m_timeStarted.secsTo(timeNow);
+ }
+ return current;
}
void BaseInstance::resetTimePlayed()
{
- settings()->reset("totalTimePlayed");
+ settings()->reset("totalTimePlayed");
}
QString BaseInstance::instanceType() const
{
- return m_settings->get("InstanceType").toString();
+ return m_settings->get("InstanceType").toString();
}
QString BaseInstance::instanceRoot() const
{
- return m_rootDir;
+ return m_rootDir;
}
InstancePtr BaseInstance::getSharedPtr()
{
- return shared_from_this();
+ return shared_from_this();
}
SettingsObjectPtr BaseInstance::settings() const
{
- return m_settings;
+ return m_settings;
}
bool BaseInstance::canLaunch() const
{
- return (!hasVersionBroken() && !isRunning());
+ return (!hasVersionBroken() && !isRunning());
}
bool BaseInstance::reloadSettings()
{
- return m_settings->reload();
+ return m_settings->reload();
}
qint64 BaseInstance::lastLaunch() const
{
- return m_settings->get("lastLaunchTime").value<qint64>();
+ return m_settings->get("lastLaunchTime").value<qint64>();
}
void BaseInstance::setLastLaunch(qint64 val)
{
- //FIXME: if no change, do not set. setting involves saving a file.
- m_settings->set("lastLaunchTime", val);
- emit propertiesChanged(this);
+ //FIXME: if no change, do not set. setting involves saving a file.
+ m_settings->set("lastLaunchTime", val);
+ emit propertiesChanged(this);
}
void BaseInstance::setGroupInitial(QString val)
{
- if(m_group == val)
- {
- return;
- }
- m_group = val;
- emit propertiesChanged(this);
+ if(m_group == val)
+ {
+ return;
+ }
+ m_group = val;
+ emit propertiesChanged(this);
}
void BaseInstance::setGroupPost(QString val)
{
- if(m_group == val)
- {
- return;
- }
- setGroupInitial(val);
- emit groupChanged();
+ if(m_group == val)
+ {
+ return;
+ }
+ setGroupInitial(val);
+ emit groupChanged();
}
QString BaseInstance::group() const
{
- return m_group;
+ return m_group;
}
void BaseInstance::setNotes(QString val)
{
- //FIXME: if no change, do not set. setting involves saving a file.
- m_settings->set("notes", val);
+ //FIXME: if no change, do not set. setting involves saving a file.
+ m_settings->set("notes", val);
}
QString BaseInstance::notes() const
{
- return m_settings->get("notes").toString();
+ return m_settings->get("notes").toString();
}
void BaseInstance::setIconKey(QString val)
{
- //FIXME: if no change, do not set. setting involves saving a file.
- m_settings->set("iconKey", val);
- emit propertiesChanged(this);
+ //FIXME: if no change, do not set. setting involves saving a file.
+ m_settings->set("iconKey", val);
+ emit propertiesChanged(this);
}
QString BaseInstance::iconKey() const
{
- return m_settings->get("iconKey").toString();
+ return m_settings->get("iconKey").toString();
}
void BaseInstance::setName(QString val)
{
- //FIXME: if no change, do not set. setting involves saving a file.
- m_settings->set("name", val);
- emit propertiesChanged(this);
+ //FIXME: if no change, do not set. setting involves saving a file.
+ m_settings->set("name", val);
+ emit propertiesChanged(this);
}
QString BaseInstance::name() const
{
- return m_settings->get("name").toString();
+ return m_settings->get("name").toString();
}
QString BaseInstance::windowTitle() const
{
- return "MultiMC: " + name();
+ return "MultiMC: " + name();
}
// FIXME: why is this here? move it to MinecraftInstance!!!
QStringList BaseInstance::extraArguments() const
{
- return Commandline::splitArgs(settings()->get("JvmArgs").toString());
+ return Commandline::splitArgs(settings()->get("JvmArgs").toString());
}
std::shared_ptr<LaunchTask> BaseInstance::getLaunchTask()
{
- return m_launchProcess;
+ return m_launchProcess;
}
void BaseInstance::setProvider(BaseInstanceProvider* provider)
{
- // only once.
- assert(!m_provider);
- if(m_provider)
- {
- qWarning() << "Provider set more than once for instance" << id();
- }
- m_provider = provider;
+ // only once.
+ assert(!m_provider);
+ if(m_provider)
+ {
+ qWarning() << "Provider set more than once for instance" << id();
+ }
+ m_provider = provider;
}
BaseInstanceProvider* BaseInstance::provider() const
{
- return m_provider;
+ return m_provider;
}
diff --git a/api/logic/BaseInstance.h b/api/logic/BaseInstance.h
index 282bfb70..f3b15a20 100644
--- a/api/logic/BaseInstance.h
+++ b/api/logic/BaseInstance.h
@@ -53,229 +53,229 @@ typedef std::shared_ptr<BaseInstance> InstancePtr;
*/
class MULTIMC_LOGIC_EXPORT BaseInstance : public QObject, public std::enable_shared_from_this<BaseInstance>
{
- Q_OBJECT
+ Q_OBJECT
protected:
- /// no-touchy!
- BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
+ /// no-touchy!
+ BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
public: /* types */
- enum class Status
- {
- Present,
- Gone // either nuked or invalidated
- };
+ enum class Status
+ {
+ Present,
+ Gone // either nuked or invalidated
+ };
public:
- /// virtual destructor to make sure the destruction is COMPLETE
- virtual ~BaseInstance() {};
+ /// virtual destructor to make sure the destruction is COMPLETE
+ virtual ~BaseInstance() {};
- virtual void init() = 0;
- virtual void saveNow() = 0;
+ virtual void init() = 0;
+ virtual void saveNow() = 0;
- /// nuke thoroughly - deletes the instance contents, notifies the list/model which is
- /// responsible of cleaning up the husk
- void nuke();
+ /// nuke thoroughly - deletes the instance contents, notifies the list/model which is
+ /// responsible of cleaning up the husk
+ void nuke();
- /***
- * the instance has been invalidated - it is no longer tracked by MultiMC for some reason,
- * but it has not necessarily been deleted.
- *
- * Happens when the instance folder changes to some other location, or the instance is removed by external means.
- */
- void invalidate();
+ /***
+ * the instance has been invalidated - it is no longer tracked by MultiMC for some reason,
+ * but it has not necessarily been deleted.
+ *
+ * Happens when the instance folder changes to some other location, or the instance is removed by external means.
+ */
+ void invalidate();
- /// The instance's ID. The ID SHALL be determined by MMC internally. The ID IS guaranteed to
- /// be unique.
- virtual QString id() const;
+ /// The instance's ID. The ID SHALL be determined by MMC internally. The ID IS guaranteed to
+ /// be unique.
+ virtual QString id() const;
- void setRunning(bool running);
- bool isRunning() const;
- int64_t totalTimePlayed() const;
- void resetTimePlayed();
+ void setRunning(bool running);
+ bool isRunning() const;
+ int64_t totalTimePlayed() const;
+ void resetTimePlayed();
- void setProvider(BaseInstanceProvider * provider);
- BaseInstanceProvider * provider() const;
-
- /// get the type of this instance
- QString instanceType() const;
-
- /// Path to the instance's root directory.
- QString instanceRoot() const;
-
- QString name() const;
- void setName(QString val);
-
- /// Value used for instance window titles
- QString windowTitle() const;
-
- QString iconKey() const;
- void setIconKey(QString val);
-
- QString notes() const;
- void setNotes(QString val);
-
- QString group() const;
- void setGroupInitial(QString val);
- void setGroupPost(QString val);
-
- QString getPreLaunchCommand();
- QString getPostExitCommand();
- QString getWrapperCommand();
-
- /// guess log level from a line of game log
- virtual MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level)
- {
- return level;
- };
-
- virtual QStringList extraArguments() const;
-
- /// Traits. Normally inside the version, depends on instance implementation.
- virtual QSet <QString> traits() const = 0;
-
- /**
- * Gets the time that the instance was last launched.
- * Stored in milliseconds since epoch.
- */
- qint64 lastLaunch() const;
- /// Sets the last launched time to 'val' milliseconds since epoch
- void setLastLaunch(qint64 val = QDateTime::currentMSecsSinceEpoch());
-
- InstancePtr getSharedPtr();
-
- /*!
- * \brief Gets this instance's settings object.
- * This settings object stores instance-specific settings.
- * \return A pointer to this instance's settings object.
- */
- virtual SettingsObjectPtr settings() const;
-
- /// returns a valid update task
- virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) = 0;
-
- /// returns a valid launcher (task container)
- virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) = 0;
-
- /// returns the current launch task (if any)
- std::shared_ptr<LaunchTask> getLaunchTask();
-
- /*!
- * Create envrironment variables for running the instance
- */
- virtual QProcessEnvironment createEnvironment() = 0;
-
- /*!
- * Returns a matcher that can maps relative paths within the instance to whether they are 'log files'
- */
- virtual IPathMatcher::Ptr getLogFileMatcher() = 0;
-
- /*!
- * Returns the root folder to use for looking up log files
- */
- virtual QString getLogFileRoot() = 0;
-
- virtual QString getStatusbarDescription() = 0;
-
- /// FIXME: this really should be elsewhere...
- virtual QString instanceConfigFolder() const = 0;
-
- /// get variables this instance exports
- virtual QMap<QString, QString> getVariables() const = 0;
-
- virtual QString typeName() const = 0;
-
- bool hasVersionBroken() const
- {
- return m_hasBrokenVersion;
- }
- void setVersionBroken(bool value)
- {
- if(m_hasBrokenVersion != value)
- {
- m_hasBrokenVersion = value;
- emit propertiesChanged(this);
- }
- }
-
- bool hasUpdateAvailable() const
- {
- return m_hasUpdate;
- }
- void setUpdateAvailable(bool value)
- {
- if(m_hasUpdate != value)
- {
- m_hasUpdate = value;
- emit propertiesChanged(this);
- }
- }
-
- bool hasCrashed() const
- {
- return m_crashed;
- }
- void setCrashed(bool value)
- {
- if(m_crashed != value)
- {
- m_crashed = value;
- emit propertiesChanged(this);
- }
- }
-
- virtual bool canLaunch() const;
- virtual bool canEdit() const = 0;
- virtual bool canExport() const = 0;
-
- bool reloadSettings();
-
- /**
- * 'print' a verbose desription of the instance into a QStringList
- */
- virtual QStringList verboseDescription(AuthSessionPtr session) = 0;
-
- Status currentStatus() const;
-
- int getConsoleMaxLines() const;
- bool shouldStopOnConsoleOverflow() const;
+ void setProvider(BaseInstanceProvider * provider);
+ BaseInstanceProvider * provider() const;
+
+ /// get the type of this instance
+ QString instanceType() const;
+
+ /// Path to the instance's root directory.
+ QString instanceRoot() const;
+
+ QString name() const;
+ void setName(QString val);
+
+ /// Value used for instance window titles
+ QString windowTitle() const;
+
+ QString iconKey() const;
+ void setIconKey(QString val);
+
+ QString notes() const;
+ void setNotes(QString val);
+
+ QString group() const;
+ void setGroupInitial(QString val);
+ void setGroupPost(QString val);
+
+ QString getPreLaunchCommand();
+ QString getPostExitCommand();
+ QString getWrapperCommand();
+
+ /// guess log level from a line of game log
+ virtual MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level)
+ {
+ return level;
+ };
+
+ virtual QStringList extraArguments() const;
+
+ /// Traits. Normally inside the version, depends on instance implementation.
+ virtual QSet <QString> traits() const = 0;
+
+ /**
+ * Gets the time that the instance was last launched.
+ * Stored in milliseconds since epoch.
+ */
+ qint64 lastLaunch() const;
+ /// Sets the last launched time to 'val' milliseconds since epoch
+ void setLastLaunch(qint64 val = QDateTime::currentMSecsSinceEpoch());
+
+ InstancePtr getSharedPtr();
+
+ /*!
+ * \brief Gets this instance's settings object.
+ * This settings object stores instance-specific settings.
+ * \return A pointer to this instance's settings object.
+ */
+ virtual SettingsObjectPtr settings() const;
+
+ /// returns a valid update task
+ virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) = 0;
+
+ /// returns a valid launcher (task container)
+ virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) = 0;
+
+ /// returns the current launch task (if any)
+ std::shared_ptr<LaunchTask> getLaunchTask();
+
+ /*!
+ * Create envrironment variables for running the instance
+ */
+ virtual QProcessEnvironment createEnvironment() = 0;
+
+ /*!
+ * Returns a matcher that can maps relative paths within the instance to whether they are 'log files'
+ */
+ virtual IPathMatcher::Ptr getLogFileMatcher() = 0;
+
+ /*!
+ * Returns the root folder to use for looking up log files
+ */
+ virtual QString getLogFileRoot() = 0;
+
+ virtual QString getStatusbarDescription() = 0;
+
+ /// FIXME: this really should be elsewhere...
+ virtual QString instanceConfigFolder() const = 0;
+
+ /// get variables this instance exports
+ virtual QMap<QString, QString> getVariables() const = 0;
+
+ virtual QString typeName() const = 0;
+
+ bool hasVersionBroken() const
+ {
+ return m_hasBrokenVersion;
+ }
+ void setVersionBroken(bool value)
+ {
+ if(m_hasBrokenVersion != value)
+ {
+ m_hasBrokenVersion = value;
+ emit propertiesChanged(this);
+ }
+ }
+
+ bool hasUpdateAvailable() const
+ {
+ return m_hasUpdate;
+ }
+ void setUpdateAvailable(bool value)
+ {
+ if(m_hasUpdate != value)
+ {
+ m_hasUpdate = value;
+ emit propertiesChanged(this);
+ }
+ }
+
+ bool hasCrashed() const
+ {
+ return m_crashed;
+ }
+ void setCrashed(bool value)
+ {
+ if(m_crashed != value)
+ {
+ m_crashed = value;
+ emit propertiesChanged(this);
+ }
+ }
+
+ virtual bool canLaunch() const;
+ virtual bool canEdit() const = 0;
+ virtual bool canExport() const = 0;
+
+ bool reloadSettings();
+
+ /**
+ * 'print' a verbose desription of the instance into a QStringList
+ */
+ virtual QStringList verboseDescription(AuthSessionPtr session) = 0;
+
+ Status currentStatus() const;
+
+ int getConsoleMaxLines() const;
+ bool shouldStopOnConsoleOverflow() const;
protected:
- void changeStatus(Status newStatus);
+ void changeStatus(Status newStatus);
signals:
- /*!
- * \brief Signal emitted when properties relevant to the instance view change
- */
- void propertiesChanged(BaseInstance *inst);
- /*!
- * \brief Signal emitted when groups are affected in any way
- */
- void groupChanged();
+ /*!
+ * \brief Signal emitted when properties relevant to the instance view change
+ */
+ void propertiesChanged(BaseInstance *inst);
+ /*!
+ * \brief Signal emitted when groups are affected in any way
+ */
+ void groupChanged();
- void launchTaskChanged(std::shared_ptr<LaunchTask>);
+ void launchTaskChanged(std::shared_ptr<LaunchTask>);
- void runningStatusChanged(bool running);
+ void runningStatusChanged(bool running);
- void statusChanged(Status from, Status to);
+ void statusChanged(Status from, Status to);
protected slots:
- void iconUpdated(QString key);
+ void iconUpdated(QString key);
protected: /* data */
- QString m_rootDir;
- QString m_group;
- SettingsObjectPtr m_settings;
- // InstanceFlags m_flags;
- bool m_isRunning = false;
- std::shared_ptr<LaunchTask> m_launchProcess;
- QDateTime m_timeStarted;
- BaseInstanceProvider * m_provider = nullptr;
+ QString m_rootDir;
+ QString m_group;
+ SettingsObjectPtr m_settings;
+ // InstanceFlags m_flags;
+ bool m_isRunning = false;
+ std::shared_ptr<LaunchTask> m_launchProcess;
+ QDateTime m_timeStarted;
+ BaseInstanceProvider * m_provider = nullptr;
private: /* data */
- Status m_status = Status::Present;
- bool m_crashed = false;
- bool m_hasUpdate = false;
- bool m_hasBrokenVersion = false;
+ Status m_status = Status::Present;
+ bool m_crashed = false;
+ bool m_hasUpdate = false;
+ bool m_hasBrokenVersion = false;
};
Q_DECLARE_METATYPE(std::shared_ptr<BaseInstance>)
diff --git a/api/logic/BaseInstanceProvider.h b/api/logic/BaseInstanceProvider.h
index 34489c5d..1eee0e4f 100644
--- a/api/logic/BaseInstanceProvider.h
+++ b/api/logic/BaseInstanceProvider.h
@@ -12,46 +12,46 @@ using InstanceLocator = std::pair<InstancePtr, int>;
enum class InstCreateError
{
- NoCreateError = 0,
- NoSuchVersion,
- UnknownCreateError,
- InstExists,
- CantCreateDir
+ NoCreateError = 0,
+ NoSuchVersion,
+ UnknownCreateError,
+ InstExists,
+ CantCreateDir
};
class MULTIMC_LOGIC_EXPORT BaseInstanceProvider : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- BaseInstanceProvider(SettingsObjectPtr settings) : m_globalSettings(settings)
- {
- // nil
- }
+ BaseInstanceProvider(SettingsObjectPtr settings) : m_globalSettings(settings)
+ {
+ // nil
+ }
public:
- virtual QList<InstanceId> discoverInstances() = 0;
- virtual InstancePtr loadInstance(const InstanceId &id) = 0;
- virtual void loadGroupList() = 0;
- virtual void saveGroupList() = 0;
-
- virtual QString getStagedInstancePath()
- {
- return QString();
- }
- virtual bool commitStagedInstance(const QString & path, const QString& instanceName, const QString & groupName)
- {
- return false;
- }
- virtual bool destroyStagingPath(const QString & path)
- {
- return true;
- }
+ virtual QList<InstanceId> discoverInstances() = 0;
+ virtual InstancePtr loadInstance(const InstanceId &id) = 0;
+ virtual void loadGroupList() = 0;
+ virtual void saveGroupList() = 0;
+
+ virtual QString getStagedInstancePath()
+ {
+ return QString();
+ }
+ virtual bool commitStagedInstance(const QString & path, const QString& instanceName, const QString & groupName)
+ {
+ return false;
+ }
+ virtual bool destroyStagingPath(const QString & path)
+ {
+ return true;
+ }
signals:
- // Emit this when the list of provided instances changed
- void instancesChanged();
- // Emit when the set of groups your provider supplies changes.
- void groupsChanged(QSet<QString> groups);
+ // Emit this when the list of provided instances changed
+ void instancesChanged();
+ // Emit when the set of groups your provider supplies changes.
+ void groupsChanged(QSet<QString> groups);
protected:
- SettingsObjectPtr m_globalSettings;
+ SettingsObjectPtr m_globalSettings;
};
diff --git a/api/logic/BaseVersion.h b/api/logic/BaseVersion.h
index e49d6277..4f06c3bc 100644
--- a/api/logic/BaseVersion.h
+++ b/api/logic/BaseVersion.h
@@ -25,33 +25,33 @@
class BaseVersion
{
public:
- virtual ~BaseVersion() {}
- /*!
- * A string used to identify this version in config files.
- * This should be unique within the version list or shenanigans will occur.
- */
- virtual QString descriptor() = 0;
-
- /*!
- * The name of this version as it is displayed to the user.
- * For example: "1.5.1"
- */
- virtual QString name() = 0;
-
- /*!
- * This should return a string that describes
- * the kind of version this is (Stable, Beta, Snapshot, whatever)
- */
- virtual QString typeString() const = 0;
-
- virtual bool operator<(BaseVersion &a)
- {
- return name() < a.name();
- };
- virtual bool operator>(BaseVersion &a)
- {
- return name() > a.name();
- };
+ virtual ~BaseVersion() {}
+ /*!
+ * A string used to identify this version in config files.
+ * This should be unique within the version list or shenanigans will occur.
+ */
+ virtual QString descriptor() = 0;
+
+ /*!
+ * The name of this version as it is displayed to the user.
+ * For example: "1.5.1"
+ */
+ virtual QString name() = 0;
+
+ /*!
+ * This should return a string that describes
+ * the kind of version this is (Stable, Beta, Snapshot, whatever)
+ */
+ virtual QString typeString() const = 0;
+
+ virtual bool operator<(BaseVersion &a)
+ {
+ return name() < a.name();
+ };
+ virtual bool operator>(BaseVersion &a)
+ {
+ return name() > a.name();
+ };
};
typedef std::shared_ptr<BaseVersion> BaseVersionPtr;
diff --git a/api/logic/BaseVersionList.cpp b/api/logic/BaseVersionList.cpp
index 31a635d7..b1f73529 100644
--- a/api/logic/BaseVersionList.cpp
+++ b/api/logic/BaseVersionList.cpp
@@ -22,78 +22,78 @@ BaseVersionList::BaseVersionList(QObject *parent) : QAbstractListModel(parent)
BaseVersionPtr BaseVersionList::findVersion(const QString &descriptor)
{
- for (int i = 0; i < count(); i++)
- {
- if (at(i)->descriptor() == descriptor)
- return at(i);
- }
- return BaseVersionPtr();
+ for (int i = 0; i < count(); i++)
+ {
+ if (at(i)->descriptor() == descriptor)
+ return at(i);
+ }
+ return BaseVersionPtr();
}
BaseVersionPtr BaseVersionList::getRecommended() const
{
- if (count() <= 0)
- return BaseVersionPtr();
- else
- return at(0);
+ if (count() <= 0)
+ return BaseVersionPtr();
+ else
+ return at(0);
}
QVariant BaseVersionList::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
- return QVariant();
+ if (!index.isValid())
+ return QVariant();
- if (index.row() > count())
- return QVariant();
+ if (index.row() > count())
+ return QVariant();
- BaseVersionPtr version = at(index.row());
+ BaseVersionPtr version = at(index.row());
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(version);
+ switch (role)
+ {
+ case VersionPointerRole:
+ return qVariantFromValue(version);
- case VersionRole:
- return version->name();
+ case VersionRole:
+ return version->name();
- case VersionIdRole:
- return version->descriptor();
+ case VersionIdRole:
+ return version->descriptor();
- case TypeRole:
- return version->typeString();
+ case TypeRole:
+ return version->typeString();
- default:
- return QVariant();
- }
+ default:
+ return QVariant();
+ }
}
BaseVersionList::RoleList BaseVersionList::providesRoles() const
{
- return {VersionPointerRole, VersionRole, VersionIdRole, TypeRole};
+ return {VersionPointerRole, VersionRole, VersionIdRole, TypeRole};
}
int BaseVersionList::rowCount(const QModelIndex &parent) const
{
- // Return count
- return count();
+ // Return count
+ return count();
}
int BaseVersionList::columnCount(const QModelIndex &parent) const
{
- return 1;
+ return 1;
}
QHash<int, QByteArray> BaseVersionList::roleNames() const
{
- QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
- roles.insert(VersionRole, "version");
- roles.insert(VersionIdRole, "versionId");
- roles.insert(ParentVersionRole, "parentGameVersion");
- roles.insert(RecommendedRole, "recommended");
- roles.insert(LatestRole, "latest");
- roles.insert(TypeRole, "type");
- roles.insert(BranchRole, "branch");
- roles.insert(PathRole, "path");
- roles.insert(ArchitectureRole, "architecture");
- return roles;
+ QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
+ roles.insert(VersionRole, "version");
+ roles.insert(VersionIdRole, "versionId");
+ roles.insert(ParentVersionRole, "parentGameVersion");
+ roles.insert(RecommendedRole, "recommended");
+ roles.insert(LatestRole, "latest");
+ roles.insert(TypeRole, "type");
+ roles.insert(BranchRole, "branch");
+ roles.insert(PathRole, "path");
+ roles.insert(ArchitectureRole, "architecture");
+ return roles;
}
diff --git a/api/logic/BaseVersionList.h b/api/logic/BaseVersionList.h
index b609e039..a70a414c 100644
--- a/api/logic/BaseVersionList.h
+++ b/api/logic/BaseVersionList.h
@@ -38,85 +38,85 @@
*/
class MULTIMC_LOGIC_EXPORT BaseVersionList : public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum ModelRoles
- {
- VersionPointerRole = Qt::UserRole,
- VersionRole,
- VersionIdRole,
- ParentVersionRole,
- RecommendedRole,
- LatestRole,
- TypeRole,
- BranchRole,
- PathRole,
- ArchitectureRole,
- SortRole
- };
- typedef QList<int> RoleList;
+ enum ModelRoles
+ {
+ VersionPointerRole = Qt::UserRole,
+ VersionRole,
+ VersionIdRole,
+ ParentVersionRole,
+ RecommendedRole,
+ LatestRole,
+ TypeRole,
+ BranchRole,
+ PathRole,
+ ArchitectureRole,
+ SortRole
+ };
+ typedef QList<int> RoleList;
- explicit BaseVersionList(QObject *parent = 0);
+ explicit BaseVersionList(QObject *parent = 0);
- /*!
- * \brief Gets a task that will reload the version list.
- * Simply execute the task to load the list.
- * The task returned by this function should reset the model when it's done.
- * \return A pointer to a task that reloads the version list.
- */
- virtual shared_qobject_ptr<Task> getLoadTask() = 0;
+ /*!
+ * \brief Gets a task that will reload the version list.
+ * Simply execute the task to load the list.
+ * The task returned by this function should reset the model when it's done.
+ * \return A pointer to a task that reloads the version list.
+ */
+ virtual shared_qobject_ptr<Task> getLoadTask() = 0;
- //! Checks whether or not the list is loaded. If this returns false, the list should be
- //loaded.
- virtual bool isLoaded() = 0;
+ //! Checks whether or not the list is loaded. If this returns false, the list should be
+ //loaded.
+ virtual bool isLoaded() = 0;
- //! Gets the version at the given index.
- virtual const BaseVersionPtr at(int i) const = 0;
+ //! Gets the version at the given index.
+ virtual const BaseVersionPtr at(int i) const = 0;
- //! Returns the number of versions in the list.
- virtual int count() const = 0;
+ //! Returns the number of versions in the list.
+ virtual int count() const = 0;
- //////// List Model Functions ////////
- QVariant data(const QModelIndex &index, int role) const override;
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QHash<int, QByteArray> roleNames() const override;
+ //////// List Model Functions ////////
+ QVariant data(const QModelIndex &index, int role) const override;
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ QHash<int, QByteArray> roleNames() const override;
- //! which roles are provided by this version list?
- virtual RoleList providesRoles() const;
+ //! which roles are provided by this version list?
+ virtual RoleList providesRoles() const;
- /*!
- * \brief Finds a version by its descriptor.
- * \param descriptor The descriptor of the version to find.
- * \return A const pointer to the version with the given descriptor. NULL if
- * one doesn't exist.
- */
- virtual BaseVersionPtr findVersion(const QString &descriptor);
+ /*!
+ * \brief Finds a version by its descriptor.
+ * \param descriptor The descriptor of the version to find.
+ * \return A const pointer to the version with the given descriptor. NULL if
+ * one doesn't exist.
+ */
+ virtual BaseVersionPtr findVersion(const QString &descriptor);
- /*!
- * \brief Gets the recommended version from this list
- * If the list doesn't support recommended versions, this works exactly as getLatestStable
- */
- virtual BaseVersionPtr getRecommended() const;
+ /*!
+ * \brief Gets the recommended version from this list
+ * If the list doesn't support recommended versions, this works exactly as getLatestStable
+ */
+ virtual BaseVersionPtr getRecommended() const;
- /*!
- * Sorts the version list.
- */
- virtual void sortVersions() = 0;
+ /*!
+ * Sorts the version list.
+ */
+ virtual void sortVersions() = 0;
protected
slots:
- /*!
- * Updates this list with the given list of versions.
- * This is done by copying each version in the given list and inserting it
- * into this one.
- * We need to do this so that we can set the parents of the versions are set to this
- * version list. This can't be done in the load task, because the versions the load
- * task creates are on the load task's thread and Qt won't allow their parents
- * to be set to something created on another thread.
- * To get around that problem, we invoke this method on the GUI thread, which
- * then copies the versions and sets their parents correctly.
- * \param versions List of versions whose parents should be set.
- */
- virtual void updateListData(QList<BaseVersionPtr> versions) = 0;
+ /*!
+ * Updates this list with the given list of versions.
+ * This is done by copying each version in the given list and inserting it
+ * into this one.
+ * We need to do this so that we can set the parents of the versions are set to this
+ * version list. This can't be done in the load task, because the versions the load
+ * task creates are on the load task's thread and Qt won't allow their parents
+ * to be set to something created on another thread.
+ * To get around that problem, we invoke this method on the GUI thread, which
+ * then copies the versions and sets their parents correctly.
+ * \param versions List of versions whose parents should be set.
+ */
+ virtual void updateListData(QList<BaseVersionPtr> versions) = 0;
};
diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt
index 769f112e..4c2445f0 100644
--- a/api/logic/CMakeLists.txt
+++ b/api/logic/CMakeLists.txt
@@ -3,446 +3,446 @@ project(MultiMC_logic)
include (UnitTest)
set(CORE_SOURCES
- # LOGIC - Base classes and infrastructure
- BaseInstaller.h
- BaseInstaller.cpp
- BaseVersionList.h
- BaseVersionList.cpp
- InstanceList.h
- InstanceList.cpp
- InstanceTask.h
- InstanceTask.cpp
- LoggedProcess.h
- LoggedProcess.cpp
- MessageLevel.cpp
- MessageLevel.h
- BaseInstanceProvider.h
- FolderInstanceProvider.h
- FolderInstanceProvider.cpp
- BaseVersion.h
- BaseInstance.h
- BaseInstance.cpp
- NullInstance.h
- MMCZip.h
- MMCZip.cpp
- MMCStrings.h
- MMCStrings.cpp
-
- # Basic instance manipulation tasks (derived from InstanceTask)
- InstanceCreationTask.h
- InstanceCreationTask.cpp
- InstanceCopyTask.h
- InstanceCopyTask.cpp
- InstanceImportTask.h
- InstanceImportTask.cpp
-
- # Use tracking separate from memory management
- Usable.h
-
- # Prefix tree where node names are strings between separators
- SeparatorPrefixTree.h
-
- # WARNING: globals live here
- Env.h
- Env.cpp
-
- # String filters
- Filter.h
- Filter.cpp
-
- # JSON parsing helpers
- Json.h
- Json.cpp
-
- FileSystem.h
- FileSystem.cpp
-
- Exception.h
-
- # RW lock protected map
- RWStorage.h
-
- # A variable that has an implicit default value and keeps track of changes
- DefaultVariable.h
-
- # a smart pointer wrapper intended for safer use with Qt signal/slot mechanisms
- QObjectPtr.h
-
- # Compression support
- GZip.h
- GZip.cpp
-
- # Command line parameter parsing
- Commandline.h
- Commandline.cpp
-
- # Version number string support
- Version.h
- Version.cpp
-
- # A Recursive file system watcher
- RecursiveFileSystemWatcher.h
- RecursiveFileSystemWatcher.cpp
+ # LOGIC - Base classes and infrastructure
+ BaseInstaller.h
+ BaseInstaller.cpp
+ BaseVersionList.h
+ BaseVersionList.cpp
+ InstanceList.h
+ InstanceList.cpp
+ InstanceTask.h
+ InstanceTask.cpp
+ LoggedProcess.h
+ LoggedProcess.cpp
+ MessageLevel.cpp
+ MessageLevel.h
+ BaseInstanceProvider.h
+ FolderInstanceProvider.h
+ FolderInstanceProvider.cpp
+ BaseVersion.h
+ BaseInstance.h
+ BaseInstance.cpp
+ NullInstance.h
+ MMCZip.h
+ MMCZip.cpp
+ MMCStrings.h
+ MMCStrings.cpp
+
+ # Basic instance manipulation tasks (derived from InstanceTask)
+ InstanceCreationTask.h
+ InstanceCreationTask.cpp
+ InstanceCopyTask.h
+ InstanceCopyTask.cpp
+ InstanceImportTask.h
+ InstanceImportTask.cpp
+
+ # Use tracking separate from memory management
+ Usable.h
+
+ # Prefix tree where node names are strings between separators
+ SeparatorPrefixTree.h
+
+ # WARNING: globals live here
+ Env.h
+ Env.cpp
+
+ # String filters
+ Filter.h
+ Filter.cpp
+
+ # JSON parsing helpers
+ Json.h
+ Json.cpp
+
+ FileSystem.h
+ FileSystem.cpp
+
+ Exception.h
+
+ # RW lock protected map
+ RWStorage.h
+
+ # A variable that has an implicit default value and keeps track of changes
+ DefaultVariable.h
+
+ # a smart pointer wrapper intended for safer use with Qt signal/slot mechanisms
+ QObjectPtr.h
+
+ # Compression support
+ GZip.h
+ GZip.cpp
+
+ # Command line parameter parsing
+ Commandline.h
+ Commandline.cpp
+
+ # Version number string support
+ Version.h
+ Version.cpp
+
+ # A Recursive file system watcher
+ RecursiveFileSystemWatcher.h
+ RecursiveFileSystemWatcher.cpp
)
add_unit_test(FileSystem
- SOURCES FileSystem_test.cpp
- LIBS MultiMC_logic
- DATA testdata
- )
+ SOURCES FileSystem_test.cpp
+ LIBS MultiMC_logic
+ DATA testdata
+ )
add_unit_test(GZip
- SOURCES GZip_test.cpp
- LIBS MultiMC_logic
- )
+ SOURCES GZip_test.cpp
+ LIBS MultiMC_logic
+ )
set(PATHMATCHER_SOURCES
- # Path matchers
- pathmatcher/FSTreeMatcher.h
- pathmatcher/IPathMatcher.h
- pathmatcher/MultiMatcher.h
- pathmatcher/RegexpMatcher.h
+ # Path matchers
+ pathmatcher/FSTreeMatcher.h
+ pathmatcher/IPathMatcher.h
+ pathmatcher/MultiMatcher.h
+ pathmatcher/RegexpMatcher.h
)
set(NET_SOURCES
- # network stuffs
- net/ByteArraySink.h
- net/ChecksumValidator.h
- net/Download.cpp
- net/Download.h
- net/FileSink.cpp
- net/FileSink.h
- net/HttpMetaCache.cpp
- net/HttpMetaCache.h
- net/MetaCacheSink.cpp
- net/MetaCacheSink.h
- net/NetAction.h
- net/NetJob.cpp
- net/NetJob.h
- net/PasteUpload.cpp
- net/PasteUpload.h
- net/Sink.h
- net/URLConstants.cpp
- net/URLConstants.h
- net/Validator.h
+ # network stuffs
+ net/ByteArraySink.h
+ net/ChecksumValidator.h
+ net/Download.cpp
+ net/Download.h
+ net/FileSink.cpp
+ net/FileSink.h
+ net/HttpMetaCache.cpp
+ net/HttpMetaCache.h
+ net/MetaCacheSink.cpp
+ net/MetaCacheSink.h
+ net/NetAction.h
+ net/NetJob.cpp
+ net/NetJob.h
+ net/PasteUpload.cpp
+ net/PasteUpload.h
+ net/Sink.h
+ net/URLConstants.cpp
+ net/URLConstants.h
+ net/Validator.h
)
# Game launch logic
set(LAUNCH_SOURCES
- launch/steps/PostLaunchCommand.cpp
- launch/steps/PostLaunchCommand.h
- launch/steps/PreLaunchCommand.cpp
- launch/steps/PreLaunchCommand.h
- launch/steps/TextPrint.cpp
- launch/steps/TextPrint.h
- launch/steps/Update.cpp
- launch/steps/Update.h
- launch/LaunchStep.cpp
- launch/LaunchStep.h
- launch/LaunchTask.cpp
- launch/LaunchTask.h
- launch/LogModel.cpp
- launch/LogModel.h
+ launch/steps/PostLaunchCommand.cpp
+ launch/steps/PostLaunchCommand.h
+ launch/steps/PreLaunchCommand.cpp
+ launch/steps/PreLaunchCommand.h
+ launch/steps/TextPrint.cpp
+ launch/steps/TextPrint.h
+ launch/steps/Update.cpp
+ launch/steps/Update.h
+ launch/LaunchStep.cpp
+ launch/LaunchStep.h
+ launch/LaunchTask.cpp
+ launch/LaunchTask.h
+ launch/LogModel.cpp
+ launch/LogModel.h
)
# Old update system
set(UPDATE_SOURCES
- updater/GoUpdate.h
- updater/GoUpdate.cpp
- updater/UpdateChecker.h
- updater/UpdateChecker.cpp
- updater/DownloadTask.h
- updater/DownloadTask.cpp
+ updater/GoUpdate.h
+ updater/GoUpdate.cpp
+ updater/UpdateChecker.h
+ updater/UpdateChecker.cpp
+ updater/DownloadTask.h
+ updater/DownloadTask.cpp
)
add_unit_test(UpdateChecker
- SOURCES updater/UpdateChecker_test.cpp
- LIBS MultiMC_logic
- DATA updater/testdata
- )
+ SOURCES updater/UpdateChecker_test.cpp
+ LIBS MultiMC_logic
+ DATA updater/testdata
+ )
add_unit_test(DownloadTask
- SOURCES updater/DownloadTask_test.cpp
- LIBS MultiMC_logic
- DATA updater/testdata
- )
+ SOURCES updater/DownloadTask_test.cpp
+ LIBS MultiMC_logic
+ DATA updater/testdata
+ )
# Rarely used notifications
set(NOTIFICATIONS_SOURCES
- # Notifications - short warning messages
- notifications/NotificationChecker.h
- notifications/NotificationChecker.cpp
+ # Notifications - short warning messages
+ notifications/NotificationChecker.h
+ notifications/NotificationChecker.cpp
)
# Backend for the news bar... there's usually no news.
set(NEWS_SOURCES
- # News System
- news/NewsChecker.h
- news/NewsChecker.cpp
- news/NewsEntry.h
- news/NewsEntry.cpp
+ # News System
+ news/NewsChecker.h
+ news/NewsChecker.cpp
+ news/NewsEntry.h
+ news/NewsEntry.cpp
)
# Icon interface
set(ICONS_SOURCES
- # News System
- icons/IIconList.h
- icons/IIconList.cpp
+ # News System
+ icons/IIconList.h
+ icons/IIconList.cpp
)
# Minecraft services status checker
set(STATUS_SOURCES
- # Status system
- status/StatusChecker.h
- status/StatusChecker.cpp
+ # Status system
+ status/StatusChecker.h
+ status/StatusChecker.cpp
)
# Support for Minecraft instances and launch
set(MINECRAFT_SOURCES
- # Minecraft support
- minecraft/auth/AuthSession.h
- minecraft/auth/AuthSession.cpp
- minecraft/auth/MojangAccountList.h
- minecraft/auth/MojangAccountList.cpp
- minecraft/auth/MojangAccount.h
- minecraft/auth/MojangAccount.cpp
- minecraft/auth/YggdrasilTask.h
- minecraft/auth/YggdrasilTask.cpp
- minecraft/auth/flows/AuthenticateTask.h
- minecraft/auth/flows/AuthenticateTask.cpp
- minecraft/auth/flows/RefreshTask.cpp
- minecraft/auth/flows/RefreshTask.cpp
- minecraft/auth/flows/ValidateTask.h
- minecraft/auth/flows/ValidateTask.cpp
- minecraft/update/AssetUpdateTask.h
- minecraft/update/AssetUpdateTask.cpp
- minecraft/update/FMLLibrariesTask.cpp
- minecraft/update/FMLLibrariesTask.h
- minecraft/update/FoldersTask.cpp
- minecraft/update/FoldersTask.h
- minecraft/update/LibrariesTask.cpp
- minecraft/update/LibrariesTask.h
- minecraft/launch/ClaimAccount.cpp
- minecraft/launch/ClaimAccount.h
- minecraft/launch/CreateServerResourcePacksFolder.cpp
- minecraft/launch/CreateServerResourcePacksFolder.h
- minecraft/launch/ModMinecraftJar.cpp
- minecraft/launch/ModMinecraftJar.h
- minecraft/launch/DirectJavaLaunch.cpp
- minecraft/launch/DirectJavaLaunch.h
- minecraft/launch/ExtractNatives.cpp
- minecraft/launch/ExtractNatives.h
- minecraft/launch/LauncherPartLaunch.cpp
- minecraft/launch/LauncherPartLaunch.h
- minecraft/launch/PrintInstanceInfo.cpp
- minecraft/launch/PrintInstanceInfo.h
- minecraft/legacy/LegacyModList.h
- minecraft/legacy/LegacyModList.cpp
- minecraft/legacy/LegacyInstance.h
- minecraft/legacy/LegacyInstance.cpp
- minecraft/legacy/LegacyUpgradeTask.h
- minecraft/legacy/LegacyUpgradeTask.cpp
- minecraft/GradleSpecifier.h
- minecraft/MinecraftInstance.cpp
- minecraft/MinecraftInstance.h
- minecraft/LaunchProfile.cpp
- minecraft/LaunchProfile.h
- minecraft/Component.cpp
- minecraft/Component.h
- minecraft/ComponentList.cpp
- minecraft/ComponentList.h
- minecraft/ComponentUpdateTask.cpp
- minecraft/ComponentUpdateTask.h
- minecraft/MinecraftLoadAndCheck.h
- minecraft/MinecraftLoadAndCheck.cpp
- minecraft/MinecraftUpdate.h
- minecraft/MinecraftUpdate.cpp
- minecraft/MojangVersionFormat.cpp
- minecraft/MojangVersionFormat.h
- minecraft/Rule.cpp
- minecraft/Rule.h
- minecraft/OneSixVersionFormat.cpp
- minecraft/OneSixVersionFormat.h
- minecraft/OpSys.cpp
- minecraft/OpSys.h
- minecraft/ParseUtils.cpp
- minecraft/ParseUtils.h
- minecraft/ProfileUtils.cpp
- minecraft/ProfileUtils.h
- minecraft/Library.cpp
- minecraft/Library.h
- minecraft/MojangDownloadInfo.h
- minecraft/VersionFile.cpp
- minecraft/VersionFile.h
- minecraft/VersionFilterData.h
- minecraft/VersionFilterData.cpp
- minecraft/Mod.h
- minecraft/Mod.cpp
- minecraft/ModsModel.h
- minecraft/ModsModel.cpp
- minecraft/SimpleModList.h
- minecraft/SimpleModList.cpp
- minecraft/World.h
- minecraft/World.cpp
- minecraft/WorldList.h
- minecraft/WorldList.cpp
-
- # Assets
- minecraft/AssetsUtils.h
- minecraft/AssetsUtils.cpp
-
- # Forge and all things forge related
- minecraft/forge/ForgeXzDownload.h
- minecraft/forge/ForgeXzDownload.cpp
-
- # Skin upload utilities
- minecraft/SkinUpload.cpp
- minecraft/SkinUpload.h
- )
+ # Minecraft support
+ minecraft/auth/AuthSession.h
+ minecraft/auth/AuthSession.cpp
+ minecraft/auth/MojangAccountList.h
+ minecraft/auth/MojangAccountList.cpp
+ minecraft/auth/MojangAccount.h
+ minecraft/auth/MojangAccount.cpp
+ minecraft/auth/YggdrasilTask.h
+ minecraft/auth/YggdrasilTask.cpp
+ minecraft/auth/flows/AuthenticateTask.h
+ minecraft/auth/flows/AuthenticateTask.cpp
+ minecraft/auth/flows/RefreshTask.cpp
+ minecraft/auth/flows/RefreshTask.cpp
+ minecraft/auth/flows/ValidateTask.h
+ minecraft/auth/flows/ValidateTask.cpp
+ minecraft/update/AssetUpdateTask.h
+ minecraft/update/AssetUpdateTask.cpp
+ minecraft/update/FMLLibrariesTask.cpp
+ minecraft/update/FMLLibrariesTask.h
+ minecraft/update/FoldersTask.cpp
+ minecraft/update/FoldersTask.h
+ minecraft/update/LibrariesTask.cpp
+ minecraft/update/LibrariesTask.h
+ minecraft/launch/ClaimAccount.cpp
+ minecraft/launch/ClaimAccount.h
+ minecraft/launch/CreateServerResourcePacksFolder.cpp
+ minecraft/launch/CreateServerResourcePacksFolder.h
+ minecraft/launch/ModMinecraftJar.cpp
+ minecraft/launch/ModMinecraftJar.h
+ minecraft/launch/DirectJavaLaunch.cpp
+ minecraft/launch/DirectJavaLaunch.h
+ minecraft/launch/ExtractNatives.cpp
+ minecraft/launch/ExtractNatives.h
+ minecraft/launch/LauncherPartLaunch.cpp
+ minecraft/launch/LauncherPartLaunch.h
+ minecraft/launch/PrintInstanceInfo.cpp
+ minecraft/launch/PrintInstanceInfo.h
+ minecraft/legacy/LegacyModList.h
+ minecraft/legacy/LegacyModList.cpp
+ minecraft/legacy/LegacyInstance.h
+ minecraft/legacy/LegacyInstance.cpp
+ minecraft/legacy/LegacyUpgradeTask.h
+ minecraft/legacy/LegacyUpgradeTask.cpp
+ minecraft/GradleSpecifier.h
+ minecraft/MinecraftInstance.cpp
+ minecraft/MinecraftInstance.h
+ minecraft/LaunchProfile.cpp
+ minecraft/LaunchProfile.h
+ minecraft/Component.cpp
+ minecraft/Component.h
+ minecraft/ComponentList.cpp
+ minecraft/ComponentList.h
+ minecraft/ComponentUpdateTask.cpp
+ minecraft/ComponentUpdateTask.h
+ minecraft/MinecraftLoadAndCheck.h
+ minecraft/MinecraftLoadAndCheck.cpp
+ minecraft/MinecraftUpdate.h
+ minecraft/MinecraftUpdate.cpp
+ minecraft/MojangVersionFormat.cpp
+ minecraft/MojangVersionFormat.h
+ minecraft/Rule.cpp
+ minecraft/Rule.h
+ minecraft/OneSixVersionFormat.cpp
+ minecraft/OneSixVersionFormat.h
+ minecraft/OpSys.cpp
+ minecraft/OpSys.h
+ minecraft/ParseUtils.cpp
+ minecraft/ParseUtils.h
+ minecraft/ProfileUtils.cpp
+ minecraft/ProfileUtils.h
+ minecraft/Library.cpp
+ minecraft/Library.h
+ minecraft/MojangDownloadInfo.h
+ minecraft/VersionFile.cpp
+ minecraft/VersionFile.h
+ minecraft/VersionFilterData.h
+ minecraft/VersionFilterData.cpp
+ minecraft/Mod.h
+ minecraft/Mod.cpp
+ minecraft/ModsModel.h
+ minecraft/ModsModel.cpp
+ minecraft/SimpleModList.h
+ minecraft/SimpleModList.cpp
+ minecraft/World.h
+ minecraft/World.cpp
+ minecraft/WorldList.h
+ minecraft/WorldList.cpp
+
+ # Assets
+ minecraft/AssetsUtils.h
+ minecraft/AssetsUtils.cpp
+
+ # Forge and all things forge related
+ minecraft/forge/ForgeXzDownload.h
+ minecraft/forge/ForgeXzDownload.cpp
+
+ # Skin upload utilities
+ minecraft/SkinUpload.cpp
+ minecraft/SkinUpload.h
+ )
add_unit_test(GradleSpecifier
- SOURCES minecraft/GradleSpecifier_test.cpp
- LIBS MultiMC_logic
- )
+ SOURCES minecraft/GradleSpecifier_test.cpp
+ LIBS MultiMC_logic
+ )
add_unit_test(MojangVersionFormat
- SOURCES minecraft/MojangVersionFormat_test.cpp
- LIBS MultiMC_logic
- DATA minecraft/testdata
- )
+ SOURCES minecraft/MojangVersionFormat_test.cpp
+ LIBS MultiMC_logic
+ DATA minecraft/testdata
+ )
add_unit_test(Library
- SOURCES minecraft/Library_test.cpp
- LIBS MultiMC_logic
- )
+ SOURCES minecraft/Library_test.cpp
+ LIBS MultiMC_logic
+ )
# FIXME: shares data with FileSystem test
add_unit_test(SimpleModList
- SOURCES minecraft/SimpleModList_test.cpp
- DATA testdata
- LIBS MultiMC_logic
- )
+ SOURCES minecraft/SimpleModList_test.cpp
+ DATA testdata
+ LIBS MultiMC_logic
+ )
add_unit_test(ParseUtils
- SOURCES minecraft/ParseUtils_test.cpp
- LIBS MultiMC_logic
- )
+ SOURCES minecraft/ParseUtils_test.cpp
+ LIBS MultiMC_logic
+ )
# the screenshots feature
set(SCREENSHOTS_SOURCES
- screenshots/Screenshot.h
- screenshots/ImgurUpload.h
- screenshots/ImgurUpload.cpp
- screenshots/ImgurAlbumCreation.h
- screenshots/ImgurAlbumCreation.cpp
+ screenshots/Screenshot.h
+ screenshots/ImgurUpload.h
+ screenshots/ImgurUpload.cpp
+ screenshots/ImgurAlbumCreation.h
+ screenshots/ImgurAlbumCreation.cpp
)
set(TASKS_SOURCES
- # Tasks
- tasks/Task.h
- tasks/Task.cpp
- tasks/SequentialTask.h
- tasks/SequentialTask.cpp
+ # Tasks
+ tasks/Task.h
+ tasks/Task.cpp
+ tasks/SequentialTask.h
+ tasks/SequentialTask.cpp
)
set(SETTINGS_SOURCES
- # Settings
- settings/INIFile.cpp
- settings/INIFile.h
- settings/INISettingsObject.cpp
- settings/INISettingsObject.h
- settings/OverrideSetting.cpp
- settings/OverrideSetting.h
- settings/PassthroughSetting.cpp
- settings/PassthroughSetting.h
- settings/Setting.cpp
- settings/Setting.h
- settings/SettingsObject.cpp
- settings/SettingsObject.h
+ # Settings
+ settings/INIFile.cpp
+ settings/INIFile.h
+ settings/INISettingsObject.cpp
+ settings/INISettingsObject.h
+ settings/OverrideSetting.cpp
+ settings/OverrideSetting.h
+ settings/PassthroughSetting.cpp
+ settings/PassthroughSetting.h
+ settings/Setting.cpp
+ settings/Setting.h
+ settings/SettingsObject.cpp
+ settings/SettingsObject.h
)
add_unit_test(INIFile
- SOURCES settings/INIFile_test.cpp
- LIBS MultiMC_logic
- )
+ SOURCES settings/INIFile_test.cpp
+ LIBS MultiMC_logic
+ )
set(JAVA_SOURCES
- # Java related code
- java/launch/CheckJava.cpp
- java/launch/CheckJava.h
- java/JavaChecker.h
- java/JavaChecker.cpp
- java/JavaCheckerJob.h
- java/JavaCheckerJob.cpp
- java/JavaInstall.h
- java/JavaInstall.cpp
- java/JavaInstallList.h
- java/JavaInstallList.cpp
- java/JavaUtils.h
- java/JavaUtils.cpp
- java/JavaVersion.h
- java/JavaVersion.cpp
+ # Java related code
+ java/launch/CheckJava.cpp
+ java/launch/CheckJava.h
+ java/JavaChecker.h
+ java/JavaChecker.cpp
+ java/JavaCheckerJob.h
+ java/JavaCheckerJob.cpp
+ java/JavaInstall.h
+ java/JavaInstall.cpp
+ java/JavaInstallList.h
+ java/JavaInstallList.cpp
+ java/JavaUtils.h
+ java/JavaUtils.cpp
+ java/JavaVersion.h
+ java/JavaVersion.cpp
)
add_unit_test(JavaVersion
- SOURCES java/JavaVersion_test.cpp
- LIBS MultiMC_logic
- )
+ SOURCES java/JavaVersion_test.cpp
+ LIBS MultiMC_logic
+ )
set(TRANSLATIONS_SOURCES
- translations/TranslationsModel.h
- translations/TranslationsModel.cpp
+ translations/TranslationsModel.h
+ translations/TranslationsModel.cpp
)
set(TOOLS_SOURCES
- # Tools
- tools/BaseExternalTool.cpp
- tools/BaseExternalTool.h
- tools/BaseProfiler.cpp
- tools/BaseProfiler.h
- tools/JProfiler.cpp
- tools/JProfiler.h
- tools/JVisualVM.cpp
- tools/JVisualVM.h
- tools/MCEditTool.cpp
- tools/MCEditTool.h
+ # Tools
+ tools/BaseExternalTool.cpp
+ tools/BaseExternalTool.h
+ tools/BaseProfiler.cpp
+ tools/BaseProfiler.h
+ tools/JProfiler.cpp
+ tools/JProfiler.h
+ tools/JVisualVM.cpp
+ tools/JVisualVM.h
+ tools/MCEditTool.cpp
+ tools/MCEditTool.h
)
set(META_SOURCES
- # Metadata sources
- meta/JsonFormat.cpp
- meta/JsonFormat.h
- meta/BaseEntity.cpp
- meta/BaseEntity.h
- meta/VersionList.cpp
- meta/VersionList.h
- meta/Version.cpp
- meta/Version.h
- meta/Index.cpp
- meta/Index.h
+ # Metadata sources
+ meta/JsonFormat.cpp
+ meta/JsonFormat.h
+ meta/BaseEntity.cpp
+ meta/BaseEntity.h
+ meta/VersionList.cpp
+ meta/VersionList.h
+ meta/Version.cpp
+ meta/Version.h
+ meta/Index.cpp
+ meta/Index.h
)
set(FTB_SOURCES
- modplatform/ftb/FtbPackFetchTask.h
- modplatform/ftb/FtbPackFetchTask.cpp
- modplatform/ftb/FtbPackInstallTask.h
- modplatform/ftb/FtbPackInstallTask.cpp
+ modplatform/ftb/FtbPackFetchTask.h
+ modplatform/ftb/FtbPackFetchTask.cpp
+ modplatform/ftb/FtbPackInstallTask.h
+ modplatform/ftb/FtbPackInstallTask.cpp
- modplatform/ftb/PackHelpers.h
+ modplatform/ftb/PackHelpers.h
)
set(FLAME_SOURCES
- # Flame
- modplatform/flame/PackManifest.h
- modplatform/flame/PackManifest.cpp
- modplatform/flame/FileResolvingTask.h
- modplatform/flame/FileResolvingTask.cpp
+ # Flame
+ modplatform/flame/PackManifest.h
+ modplatform/flame/PackManifest.cpp
+ modplatform/flame/FileResolvingTask.h
+ modplatform/flame/FileResolvingTask.cpp
)
add_unit_test(Index
- SOURCES meta/Index_test.cpp
- LIBS MultiMC_logic
- )
+ SOURCES meta/Index_test.cpp
+ LIBS MultiMC_logic
+ )
################################ COMPILE ################################
@@ -450,25 +450,25 @@ add_unit_test(Index
find_package(ZLIB REQUIRED)
set(LOGIC_SOURCES
- ${CORE_SOURCES}
- ${PATHMATCHER_SOURCES}
- ${NET_SOURCES}
- ${LAUNCH_SOURCES}
- ${UPDATE_SOURCES}
- ${NOTIFICATIONS_SOURCES}
- ${NEWS_SOURCES}
- ${STATUS_SOURCES}
- ${MINECRAFT_SOURCES}
- ${SCREENSHOTS_SOURCES}
- ${TASKS_SOURCES}
- ${SETTINGS_SOURCES}
- ${JAVA_SOURCES}
- ${TRANSLATIONS_SOURCES}
- ${TOOLS_SOURCES}
- ${META_SOURCES}
- ${ICONS_SOURCES}
- ${FTB_SOURCES}
- ${FLAME_SOURCES}
+ ${CORE_SOURCES}
+ ${PATHMATCHER_SOURCES}
+ ${NET_SOURCES}
+ ${LAUNCH_SOURCES}
+ ${UPDATE_SOURCES}
+ ${NOTIFICATIONS_SOURCES}
+ ${NEWS_SOURCES}
+ ${STATUS_SOURCES}
+ ${MINECRAFT_SOURCES}
+ ${SCREENSHOTS_SOURCES}
+ ${TASKS_SOURCES}
+ ${SETTINGS_SOURCES}
+ ${JAVA_SOURCES}
+ ${TRANSLATIONS_SOURCES}
+ ${TOOLS_SOURCES}
+ ${META_SOURCES}
+ ${ICONS_SOURCES}
+ ${FTB_SOURCES}
+ ${FLAME_SOURCES}
)
add_library(MultiMC_logic SHARED ${LOGIC_SOURCES})
@@ -485,7 +485,7 @@ target_include_directories(MultiMC_logic PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" "$
# Install it
install(
- TARGETS MultiMC_logic
- RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
- LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
+ TARGETS MultiMC_logic
+ RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
+ LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
)
diff --git a/api/logic/Commandline.cpp b/api/logic/Commandline.cpp
index eac9db09..81ae7d0b 100644
--- a/api/logic/Commandline.cpp
+++ b/api/logic/Commandline.cpp
@@ -27,453 +27,453 @@ namespace Commandline
// commandline splitter
QStringList splitArgs(QString args)
{
- QStringList argv;
- QString current;
- bool escape = false;
- QChar inquotes;
- for (int i = 0; i < args.length(); i++)
- {
- QChar cchar = args.at(i);
-
- // \ escaped
- if (escape)
- {
- current += cchar;
- escape = false;
- // in "quotes"
- }
- else if (!inquotes.isNull())
- {
- if (cchar == '\\')
- escape = true;
- else if (cchar == inquotes)
- inquotes = 0;
- else
- current += cchar;
- // otherwise
- }
- else
- {
- if (cchar == ' ')
- {
- if (!current.isEmpty())
- {
- argv << current;
- current.clear();
- }
- }
- else if (cchar == '"' || cchar == '\'')
- inquotes = cchar;
- else
- current += cchar;
- }
- }
- if (!current.isEmpty())
- argv << current;
- return argv;
+ QStringList argv;
+ QString current;
+ bool escape = false;
+ QChar inquotes;
+ for (int i = 0; i < args.length(); i++)
+ {
+ QChar cchar = args.at(i);
+
+ // \ escaped
+ if (escape)
+ {
+ current += cchar;
+ escape = false;
+ // in "quotes"
+ }
+ else if (!inquotes.isNull())
+ {
+ if (cchar == '\\')
+ escape = true;
+ else if (cchar == inquotes)
+ inquotes = 0;
+ else
+ current += cchar;
+ // otherwise
+ }
+ else
+ {
+ if (cchar == ' ')
+ {
+ if (!current.isEmpty())
+ {
+ argv << current;
+ current.clear();
+ }
+ }
+ else if (cchar == '"' || cchar == '\'')
+ inquotes = cchar;
+ else
+ current += cchar;
+ }
+ }
+ if (!current.isEmpty())
+ argv << current;
+ return argv;
}
Parser::Parser(FlagStyle::Enum flagStyle, ArgumentStyle::Enum argStyle)
{
- m_flagStyle = flagStyle;
- m_argStyle = argStyle;
+ m_flagStyle = flagStyle;
+ m_argStyle = argStyle;
}
// styles setter/getter
void Parser::setArgumentStyle(ArgumentStyle::Enum style)
{
- m_argStyle = style;
+ m_argStyle = style;
}
ArgumentStyle::Enum Parser::argumentStyle()
{
- return m_argStyle;
+ return m_argStyle;
}
void Parser::setFlagStyle(FlagStyle::Enum style)
{
- m_flagStyle = style;
+ m_flagStyle = style;
}
FlagStyle::Enum Parser::flagStyle()
{
- return m_flagStyle;
+ return m_flagStyle;
}
// setup methods
void Parser::addSwitch(QString name, bool def)
{
- if (m_params.contains(name))
- throw "Name not unique";
-
- OptionDef *param = new OptionDef;
- param->type = otSwitch;
- param->name = name;
- param->metavar = QString("<%1>").arg(name);
- param->def = def;
-
- m_options[name] = param;
- m_params[name] = (CommonDef *)param;
- m_optionList.append(param);
+ if (m_params.contains(name))
+ throw "Name not unique";
+
+ OptionDef *param = new OptionDef;
+ param->type = otSwitch;
+ param->name = name;
+ param->metavar = QString("<%1>").arg(name);
+ param->def = def;
+
+ m_options[name] = param;
+ m_params[name] = (CommonDef *)param;
+ m_optionList.append(param);
}
void Parser::addOption(QString name, QVariant def)
{
- if (m_params.contains(name))
- throw "Name not unique";
-
- OptionDef *param = new OptionDef;
- param->type = otOption;
- param->name = name;
- param->metavar = QString("<%1>").arg(name);
- param->def = def;
-
- m_options[name] = param;
- m_params[name] = (CommonDef *)param;
- m_optionList.append(param);
+ if (m_params.contains(name))
+ throw "Name not unique";
+
+ OptionDef *param = new OptionDef;
+ param->type = otOption;
+ param->name = name;
+ param->metavar = QString("<%1>").arg(name);
+ param->def = def;
+
+ m_options[name] = param;
+ m_params[name] = (CommonDef *)param;
+ m_optionList.append(param);
}
void Parser::addArgument(QString name, bool required, QVariant def)
{
- if (m_params.contains(name))
- throw "Name not unique";
+ if (m_params.contains(name))
+ throw "Name not unique";
- PositionalDef *param = new PositionalDef;
- param->name = name;
- param->def = def;
- param->required = required;
- param->metavar = name;
+ PositionalDef *param = new PositionalDef;
+ param->name = name;
+ param->def = def;
+ param->required = required;
+ param->metavar = name;
- m_positionals.append(param);
- m_params[name] = (CommonDef *)param;
+ m_positionals.append(param);
+ m_params[name] = (CommonDef *)param;
}
void Parser::addDocumentation(QString name, QString doc, QString metavar)
{
- if (!m_params.contains(name))
- throw "Name does not exist";
+ if (!m_params.contains(name))
+ throw "Name does not exist";
- CommonDef *param = m_params[name];
- param->doc = doc;
- if (!metavar.isNull())
- param->metavar = metavar;
+ CommonDef *param = m_params[name];
+ param->doc = doc;
+ if (!metavar.isNull())
+ param->metavar = metavar;
}
void Parser::addShortOpt(QString name, QChar flag)
{
- if (!m_params.contains(name))
- throw "Name does not exist";
- if (!m_options.contains(name))
- throw "Name is not an Option or Swtich";
-
- OptionDef *param = m_options[name];
- m_flags[flag] = param;
- param->flag = flag;
+ if (!m_params.contains(name))
+ throw "Name does not exist";
+ if (!m_options.contains(name))
+ throw "Name is not an Option or Swtich";
+
+ OptionDef *param = m_options[name];
+ m_flags[flag] = param;
+ param->flag = flag;
}
// help methods
QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags)
{
- QStringList help;
- help << compileUsage(progName, useFlags) << "\r\n";
-
- // positionals
- if (!m_positionals.isEmpty())
- {
- help << "\r\n";
- help << "Positional arguments:\r\n";
- QListIterator<PositionalDef *> it2(m_positionals);
- while (it2.hasNext())
- {
- PositionalDef *param = it2.next();
- help << " " << param->metavar;
- help << " " << QString(helpIndent - param->metavar.length() - 1, ' ');
- help << param->doc << "\r\n";
- }
- }
-
- // Options
- if (!m_optionList.isEmpty())
- {
- help << "\r\n";
- QString optPrefix, flagPrefix;
- getPrefix(optPrefix, flagPrefix);
-
- help << "Options & Switches:\r\n";
- QListIterator<OptionDef *> it(m_optionList);
- while (it.hasNext())
- {
- OptionDef *option = it.next();
- help << " ";
- int nameLength = optPrefix.length() + option->name.length();
- if (!option->flag.isNull())
- {
- nameLength += 3 + flagPrefix.length();
- help << flagPrefix << option->flag << ", ";
- }
- help << optPrefix << option->name;
- if (option->type == otOption)
- {
- QString arg = QString("%1%2").arg(
- ((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar);
- nameLength += arg.length();
- help << arg;
- }
- help << " " << QString(helpIndent - nameLength - 1, ' ');
- help << option->doc << "\r\n";
- }
- }
-
- return help.join("");
+ QStringList help;
+ help << compileUsage(progName, useFlags) << "\r\n";
+
+ // positionals
+ if (!m_positionals.isEmpty())
+ {
+ help << "\r\n";
+ help << "Positional arguments:\r\n";
+ QListIterator<PositionalDef *> it2(m_positionals);
+ while (it2.hasNext())
+ {
+ PositionalDef *param = it2.next();
+ help << " " << param->metavar;
+ help << " " << QString(helpIndent - param->metavar.length() - 1, ' ');
+ help << param->doc << "\r\n";
+ }
+ }
+
+ // Options
+ if (!m_optionList.isEmpty())
+ {
+ help << "\r\n";
+ QString optPrefix, flagPrefix;
+ getPrefix(optPrefix, flagPrefix);
+
+ help << "Options & Switches:\r\n";
+ QListIterator<OptionDef *> it(m_optionList);
+ while (it.hasNext())
+ {
+ OptionDef *option = it.next();
+ help << " ";
+ int nameLength = optPrefix.length() + option->name.length();
+ if (!option->flag.isNull())
+ {
+ nameLength += 3 + flagPrefix.length();
+ help << flagPrefix << option->flag << ", ";
+ }
+ help << optPrefix << option->name;
+ if (option->type == otOption)
+ {
+ QString arg = QString("%1%2").arg(
+ ((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar);
+ nameLength += arg.length();
+ help << arg;
+ }
+ help << " " << QString(helpIndent - nameLength - 1, ' ');
+ help << option->doc << "\r\n";
+ }
+ }
+
+ return help.join("");
}
QString Parser::compileUsage(QString progName, bool useFlags)
{
- QStringList usage;
- usage << "Usage: " << progName;
-
- QString optPrefix, flagPrefix;
- getPrefix(optPrefix, flagPrefix);
-
- // options
- QListIterator<OptionDef *> it(m_optionList);
- while (it.hasNext())
- {
- OptionDef *option = it.next();
- usage << " [";
- if (!option->flag.isNull() && useFlags)
- usage << flagPrefix << option->flag;
- else
- usage << optPrefix << option->name;
- if (option->type == otOption)
- usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") << option->metavar;
- usage << "]";
- }
-
- // arguments
- QListIterator<PositionalDef *> it2(m_positionals);
- while (it2.hasNext())
- {
- PositionalDef *param = it2.next();
- usage << " " << (param->required ? "<" : "[");
- usage << param->metavar;
- usage << (param->required ? ">" : "]");
- }
-
- return usage.join("");
+ QStringList usage;
+ usage << "Usage: " << progName;
+
+ QString optPrefix, flagPrefix;
+ getPrefix(optPrefix, flagPrefix);
+
+ // options
+ QListIterator<OptionDef *> it(m_optionList);
+ while (it.hasNext())
+ {
+ OptionDef *option = it.next();
+ usage << " [";
+ if (!option->flag.isNull() && useFlags)
+ usage << flagPrefix << option->flag;
+ else
+ usage << optPrefix << option->name;
+ if (option->type == otOption)
+ usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") << option->metavar;
+ usage << "]";
+ }
+
+ // arguments
+ QListIterator<PositionalDef *> it2(m_positionals);
+ while (it2.hasNext())
+ {
+ PositionalDef *param = it2.next();
+ usage << " " << (param->required ? "<" : "[");
+ usage << param->metavar;
+ usage << (param->required ? ">" : "]");
+ }
+
+ return usage.join("");
}
// parsing
QHash<QString, QVariant> Parser::parse(QStringList argv)
{
- QHash<QString, QVariant> map;
+ QHash<QString, QVariant> map;
- QStringListIterator it(argv);
- QString programName = it.next();
+ QStringListIterator it(argv);
+ QString programName = it.next();
- QString optionPrefix;
- QString flagPrefix;
- QListIterator<PositionalDef *> positionals(m_positionals);
- QStringList expecting;
+ QString optionPrefix;
+ QString flagPrefix;
+ QListIterator<PositionalDef *> positionals(m_positionals);
+ QStringList expecting;
- getPrefix(optionPrefix, flagPrefix);
+ getPrefix(optionPrefix, flagPrefix);
- while (it.hasNext())
- {
- QString arg = it.next();
+ while (it.hasNext())
+ {
+ QString arg = it.next();
- if (!expecting.isEmpty())
- // we were expecting an argument
- {
- QString name = expecting.first();
+ if (!expecting.isEmpty())
+ // we were expecting an argument
+ {
+ QString name = expecting.first();
/*
- if (map.contains(name))
- throw ParsingError(
- QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
+ if (map.contains(name))
+ throw ParsingError(
+ QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
*/
- map[name] = QVariant(arg);
-
- expecting.removeFirst();
- continue;
- }
-
- if (arg.startsWith(optionPrefix))
- // we have an option
- {
- // qDebug("Found option %s", qPrintable(arg));
-
- QString name = arg.mid(optionPrefix.length());
- QString equals;
-
- if ((m_argStyle == ArgumentStyle::Equals ||
- m_argStyle == ArgumentStyle::SpaceAndEquals) &&
- name.contains("="))
- {
- int i = name.indexOf("=");
- equals = name.mid(i + 1);
- name = name.left(i);
- }
-
- if (m_options.contains(name))
- {
- /*
- if (map.contains(name))
- throw ParsingError(QString("Option %2%1 was given multiple times")
- .arg(name, optionPrefix));
+ map[name] = QVariant(arg);
+
+ expecting.removeFirst();
+ continue;
+ }
+
+ if (arg.startsWith(optionPrefix))
+ // we have an option
+ {
+ // qDebug("Found option %s", qPrintable(arg));
+
+ QString name = arg.mid(optionPrefix.length());
+ QString equals;
+
+ if ((m_argStyle == ArgumentStyle::Equals ||
+ m_argStyle == ArgumentStyle::SpaceAndEquals) &&
+ name.contains("="))
+ {
+ int i = name.indexOf("=");
+ equals = name.mid(i + 1);
+ name = name.left(i);
+ }
+
+ if (m_options.contains(name))
+ {
+ /*
+ if (map.contains(name))
+ throw ParsingError(QString("Option %2%1 was given multiple times")
+ .arg(name, optionPrefix));
*/
- OptionDef *option = m_options[name];
- if (option->type == otSwitch)
- map[name] = true;
- else // if (option->type == otOption)
- {
- if (m_argStyle == ArgumentStyle::Space)
- expecting.append(name);
- else if (!equals.isNull())
- map[name] = equals;
- else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
- expecting.append(name);
- else
- throw ParsingError(QString("Option %2%1 reqires an argument.")
- .arg(name, optionPrefix));
- }
-
- continue;
- }
-
- throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix));
- }
-
- if (arg.startsWith(flagPrefix))
- // we have (a) flag(s)
- {
- // qDebug("Found flags %s", qPrintable(arg));
-
- QString flags = arg.mid(flagPrefix.length());
- QString equals;
-
- if ((m_argStyle == ArgumentStyle::Equals ||
- m_argStyle == ArgumentStyle::SpaceAndEquals) &&
- flags.contains("="))
- {
- int i = flags.indexOf("=");
- equals = flags.mid(i + 1);
- flags = flags.left(i);
- }
-
- for (int i = 0; i < flags.length(); i++)
- {
- QChar flag = flags.at(i);
-
- if (!m_flags.contains(flag))
- throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix));
-
- OptionDef *option = m_flags[flag];
+ OptionDef *option = m_options[name];
+ if (option->type == otSwitch)
+ map[name] = true;
+ else // if (option->type == otOption)
+ {
+ if (m_argStyle == ArgumentStyle::Space)
+ expecting.append(name);
+ else if (!equals.isNull())
+ map[name] = equals;
+ else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
+ expecting.append(name);
+ else
+ throw ParsingError(QString("Option %2%1 reqires an argument.")
+ .arg(name, optionPrefix));
+ }
+
+ continue;
+ }
+
+ throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix));
+ }
+
+ if (arg.startsWith(flagPrefix))
+ // we have (a) flag(s)
+ {
+ // qDebug("Found flags %s", qPrintable(arg));
+
+ QString flags = arg.mid(flagPrefix.length());
+ QString equals;
+
+ if ((m_argStyle == ArgumentStyle::Equals ||
+ m_argStyle == ArgumentStyle::SpaceAndEquals) &&
+ flags.contains("="))
+ {
+ int i = flags.indexOf("=");
+ equals = flags.mid(i + 1);
+ flags = flags.left(i);
+ }
+
+ for (int i = 0; i < flags.length(); i++)
+ {
+ QChar flag = flags.at(i);
+
+ if (!m_flags.contains(flag))
+ throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix));
+
+ OptionDef *option = m_flags[flag];
/*
- if (map.contains(option->name))
- throw ParsingError(QString("Option %2%1 was given multiple times")
- .arg(option->name, optionPrefix));
+ if (map.contains(option->name))
+ throw ParsingError(QString("Option %2%1 was given multiple times")
+ .arg(option->name, optionPrefix));
*/
- if (option->type == otSwitch)
- map[option->name] = true;
- else // if (option->type == otOption)
- {
- if (m_argStyle == ArgumentStyle::Space)
- expecting.append(option->name);
- else if (!equals.isNull())
- if (i == flags.length() - 1)
- map[option->name] = equals;
- else
- throw ParsingError(QString("Flag %4%2 of Argument-requiring Option "
- "%1 not last flag in %4%3")
- .arg(option->name, flag, flags, flagPrefix));
- else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
- expecting.append(option->name);
- else
- throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)")
- .arg(option->name, flag, flagPrefix));
- }
- }
-
- continue;
- }
-
- // must be a positional argument
- if (!positionals.hasNext())
- throw ParsingError(QString("Don't know what to do with '%1'").arg(arg));
-
- PositionalDef *param = positionals.next();
-
- map[param->name] = arg;
- }
-
- // check if we're missing something
- if (!expecting.isEmpty())
- throw ParsingError(QString("Was still expecting arguments for %2%1").arg(
- expecting.join(QString(", ") + optionPrefix), optionPrefix));
-
- while (positionals.hasNext())
- {
- PositionalDef *param = positionals.next();
- if (param->required)
- throw ParsingError(
- QString("Missing required positional argument '%1'").arg(param->name));
- else
- map[param->name] = param->def;
- }
-
- // fill out gaps
- QListIterator<OptionDef *> iter(m_optionList);
- while (iter.hasNext())
- {
- OptionDef *option = iter.next();
- if (!map.contains(option->name))
- map[option->name] = option->def;
- }
-
- return map;
+ if (option->type == otSwitch)
+ map[option->name] = true;
+ else // if (option->type == otOption)
+ {
+ if (m_argStyle == ArgumentStyle::Space)
+ expecting.append(option->name);
+ else if (!equals.isNull())
+ if (i == flags.length() - 1)
+ map[option->name] = equals;
+ else
+ throw ParsingError(QString("Flag %4%2 of Argument-requiring Option "
+ "%1 not last flag in %4%3")
+ .arg(option->name, flag, flags, flagPrefix));
+ else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
+ expecting.append(option->name);
+ else
+ throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)")
+ .arg(option->name, flag, flagPrefix));
+ }
+ }
+
+ continue;
+ }
+
+ // must be a positional argument
+ if (!positionals.hasNext())
+ throw ParsingError(QString("Don't know what to do with '%1'").arg(arg));
+
+ PositionalDef *param = positionals.next();
+
+ map[param->name] = arg;
+ }
+
+ // check if we're missing something
+ if (!expecting.isEmpty())
+ throw ParsingError(QString("Was still expecting arguments for %2%1").arg(
+ expecting.join(QString(", ") + optionPrefix), optionPrefix));
+
+ while (positionals.hasNext())
+ {
+ PositionalDef *param = positionals.next();
+ if (param->required)
+ throw ParsingError(
+ QString("Missing required positional argument '%1'").arg(param->name));
+ else
+ map[param->name] = param->def;
+ }
+
+ // fill out gaps
+ QListIterator<OptionDef *> iter(m_optionList);
+ while (iter.hasNext())
+ {
+ OptionDef *option = iter.next();
+ if (!map.contains(option->name))
+ map[option->name] = option->def;
+ }
+
+ return map;
}
// clear defs
void Parser::clear()
{
- m_flags.clear();
- m_params.clear();
- m_options.clear();
-
- QMutableListIterator<OptionDef *> it(m_optionList);
- while (it.hasNext())
- {
- OptionDef *option = it.next();
- it.remove();
- delete option;
- }
-
- QMutableListIterator<PositionalDef *> it2(m_positionals);
- while (it2.hasNext())
- {
- PositionalDef *arg = it2.next();
- it2.remove();
- delete arg;
- }
+ m_flags.clear();
+ m_params.clear();
+ m_options.clear();
+
+ QMutableListIterator<OptionDef *> it(m_optionList);
+ while (it.hasNext())
+ {
+ OptionDef *option = it.next();
+ it.remove();
+ delete option;
+ }
+
+ QMutableListIterator<PositionalDef *> it2(m_positionals);
+ while (it2.hasNext())
+ {
+ PositionalDef *arg = it2.next();
+ it2.remove();
+ delete arg;
+ }
}
// Destructor
Parser::~Parser()
{
- clear();
+ clear();
}
// getPrefix
void Parser::getPrefix(QString &opt, QString &flag)
{
- if (m_flagStyle == FlagStyle::Windows)
- opt = flag = "/";
- else if (m_flagStyle == FlagStyle::Unix)
- opt = flag = "-";
- // else if (m_flagStyle == FlagStyle::GNU)
- else
- {
- opt = "--";
- flag = "-";
- }
+ if (m_flagStyle == FlagStyle::Windows)
+ opt = flag = "/";
+ else if (m_flagStyle == FlagStyle::Unix)
+ opt = flag = "-";
+ // else if (m_flagStyle == FlagStyle::GNU)
+ else
+ {
+ opt = "--";
+ flag = "-";
+ }
}
// ParsingError
diff --git a/api/logic/Commandline.h b/api/logic/Commandline.h
index c8c8be29..586d644f 100644
--- a/api/logic/Commandline.h
+++ b/api/logic/Commandline.h
@@ -51,13 +51,13 @@ namespace FlagStyle
{
enum Enum
{
- GNU, /**< --option and -o (GNU Style) */
- Unix, /**< -option and -o (Unix Style) */
- Windows, /**< /option and /o (Windows Style) */
+ GNU, /**< --option and -o (GNU Style) */
+ Unix, /**< -option and -o (Unix Style) */
+ Windows, /**< /option and /o (Windows Style) */
#ifdef Q_OS_WIN32
- Default = Windows
+ Default = Windows
#else
- Default = GNU
+ Default = GNU
#endif
};
}
@@ -69,13 +69,13 @@ namespace ArgumentStyle
{
enum Enum
{
- Space, /**< --option=value */
- Equals, /**< --option value */
- SpaceAndEquals, /**< --option[= ]value */
+ Space, /**< --option=value */
+ Equals, /**< --option value */
+ SpaceAndEquals, /**< --option[= ]value */
#ifdef Q_OS_WIN32
- Default = Equals
+ Default = Equals
#else
- Default = SpaceAndEquals
+ Default = SpaceAndEquals
#endif
};
}
@@ -86,7 +86,7 @@ enum Enum
class MULTIMC_LOGIC_EXPORT ParsingError : public std::runtime_error
{
public:
- ParsingError(const QString &what);
+ ParsingError(const QString &what);
};
/**
@@ -95,158 +95,158 @@ public:
class MULTIMC_LOGIC_EXPORT Parser
{
public:
- /**
- * @brief Parser constructor
- * @param flagStyle the FlagStyle to use in this Parser
- * @param argStyle the ArgumentStyle to use in this Parser
- */
- Parser(FlagStyle::Enum flagStyle = FlagStyle::Default,
- ArgumentStyle::Enum argStyle = ArgumentStyle::Default);
-
- /**
- * @brief set the flag style
- * @param style
- */
- void setFlagStyle(FlagStyle::Enum style);
-
- /**
- * @brief get the flag style
- * @return
- */
- FlagStyle::Enum flagStyle();
-
- /**
- * @brief set the argument style
- * @param style
- */
- void setArgumentStyle(ArgumentStyle::Enum style);
-
- /**
- * @brief get the argument style
- * @return
- */
- ArgumentStyle::Enum argumentStyle();
-
- /**
- * @brief define a boolean switch
- * @param name the parameter name
- * @param def the default value
- */
- void addSwitch(QString name, bool def = false);
-
- /**
- * @brief define an option that takes an additional argument
- * @param name the parameter name
- * @param def the default value
- */
- void addOption(QString name, QVariant def = QVariant());
-
- /**
- * @brief define a positional argument
- * @param name the parameter name
- * @param required wether this argument is required
- * @param def the default value
- */
- void addArgument(QString name, bool required = true, QVariant def = QVariant());
-
- /**
- * @brief adds a flag to an existing parameter
- * @param name the (existing) parameter name
- * @param flag the flag character
- * @see addSwitch addArgument addOption
- * Note: any one parameter can only have one flag
- */
- void addShortOpt(QString name, QChar flag);
-
- /**
- * @brief adds documentation to a Parameter
- * @param name the parameter name
- * @param metavar a string to be displayed as placeholder for the value
- * @param doc a QString containing the documentation
- * Note: on positional arguments, metavar replaces the name as displayed.
- * on options , metavar replaces the value placeholder
- */
- void addDocumentation(QString name, QString doc, QString metavar = QString());
-
- /**
- * @brief generate a help message
- * @param progName the program name to use in the help message
- * @param helpIndent how much the parameter documentation should be indented
- * @param flagsInUsage whether we should use flags instead of options in the usage
- * @return a help message
- */
- QString compileHelp(QString progName, int helpIndent = 22, bool flagsInUsage = true);
-
- /**
- * @brief generate a short usage message
- * @param progName the program name to use in the usage message
- * @param useFlags whether we should use flags instead of options
- * @return a usage message
- */
- QString compileUsage(QString progName, bool useFlags = true);
-
- /**
- * @brief parse
- * @param argv a QStringList containing the program ARGV
- * @return a QHash mapping argument names to their values
- */
- QHash<QString, QVariant> parse(QStringList argv);
-
- /**
- * @brief clear all definitions
- */
- void clear();
-
- ~Parser();
+ /**
+ * @brief Parser constructor
+ * @param flagStyle the FlagStyle to use in this Parser
+ * @param argStyle the ArgumentStyle to use in this Parser
+ */
+ Parser(FlagStyle::Enum flagStyle = FlagStyle::Default,
+ ArgumentStyle::Enum argStyle = ArgumentStyle::Default);
+
+ /**
+ * @brief set the flag style
+ * @param style
+ */
+ void setFlagStyle(FlagStyle::Enum style);
+
+ /**
+ * @brief get the flag style
+ * @return
+ */
+ FlagStyle::Enum flagStyle();
+
+ /**
+ * @brief set the argument style
+ * @param style
+ */
+ void setArgumentStyle(ArgumentStyle::Enum style);
+
+ /**
+ * @brief get the argument style
+ * @return
+ */
+ ArgumentStyle::Enum argumentStyle();
+
+ /**
+ * @brief define a boolean switch
+ * @param name the parameter name
+ * @param def the default value
+ */
+ void addSwitch(QString name, bool def = false);
+
+ /**
+ * @brief define an option that takes an additional argument
+ * @param name the parameter name
+ * @param def the default value
+ */
+ void addOption(QString name, QVariant def = QVariant());
+
+ /**
+ * @brief define a positional argument
+ * @param name the parameter name
+ * @param required wether this argument is required
+ * @param def the default value
+ */
+ void addArgument(QString name, bool required = true, QVariant def = QVariant());
+
+ /**
+ * @brief adds a flag to an existing parameter
+ * @param name the (existing) parameter name
+ * @param flag the flag character
+ * @see addSwitch addArgument addOption
+ * Note: any one parameter can only have one flag
+ */
+ void addShortOpt(QString name, QChar flag);
+
+ /**
+ * @brief adds documentation to a Parameter
+ * @param name the parameter name
+ * @param metavar a string to be displayed as placeholder for the value
+ * @param doc a QString containing the documentation
+ * Note: on positional arguments, metavar replaces the name as displayed.
+ * on options , metavar replaces the value placeholder
+ */
+ void addDocumentation(QString name, QString doc, QString metavar = QString());
+
+ /**
+ * @brief generate a help message
+ * @param progName the program name to use in the help message
+ * @param helpIndent how much the parameter documentation should be indented
+ * @param flagsInUsage whether we should use flags instead of options in the usage
+ * @return a help message
+ */
+ QString compileHelp(QString progName, int helpIndent = 22, bool flagsInUsage = true);
+
+ /**
+ * @brief generate a short usage message
+ * @param progName the program name to use in the usage message
+ * @param useFlags whether we should use flags instead of options
+ * @return a usage message
+ */
+ QString compileUsage(QString progName, bool useFlags = true);
+
+ /**
+ * @brief parse
+ * @param argv a QStringList containing the program ARGV
+ * @return a QHash mapping argument names to their values
+ */
+ QHash<QString, QVariant> parse(QStringList argv);
+
+ /**
+ * @brief clear all definitions
+ */
+ void clear();
+
+ ~Parser();
private:
- FlagStyle::Enum m_flagStyle;
- ArgumentStyle::Enum m_argStyle;
-
- enum OptionType
- {
- otSwitch,
- otOption
- };
-
- // Important: the common part MUST BE COMMON ON ALL THREE structs
- struct CommonDef
- {
- QString name;
- QString doc;
- QString metavar;
- QVariant def;
- };
-
- struct OptionDef
- {
- // common
- QString name;
- QString doc;
- QString metavar;
- QVariant def;
- // option
- OptionType type;
- QChar flag;
- };
-
- struct PositionalDef
- {
- // common
- QString name;
- QString doc;
- QString metavar;
- QVariant def;
- // positional
- bool required;
- };
-
- QHash<QString, OptionDef *> m_options;
- QHash<QChar, OptionDef *> m_flags;
- QHash<QString, CommonDef *> m_params;
- QList<PositionalDef *> m_positionals;
- QList<OptionDef *> m_optionList;
-
- void getPrefix(QString &opt, QString &flag);
+ FlagStyle::Enum m_flagStyle;
+ ArgumentStyle::Enum m_argStyle;
+
+ enum OptionType
+ {
+ otSwitch,
+ otOption
+ };
+
+ // Important: the common part MUST BE COMMON ON ALL THREE structs
+ struct CommonDef
+ {
+ QString name;
+ QString doc;
+ QString metavar;
+ QVariant def;
+ };
+
+ struct OptionDef
+ {
+ // common
+ QString name;
+ QString doc;
+ QString metavar;
+ QVariant def;
+ // option
+ OptionType type;
+ QChar flag;
+ };
+
+ struct PositionalDef
+ {
+ // common
+ QString name;
+ QString doc;
+ QString metavar;
+ QVariant def;
+ // positional
+ bool required;
+ };
+
+ QHash<QString, OptionDef *> m_options;
+ QHash<QChar, OptionDef *> m_flags;
+ QHash<QString, CommonDef *> m_params;
+ QList<PositionalDef *> m_positionals;
+ QList<OptionDef *> m_optionList;
+
+ void getPrefix(QString &opt, QString &flag);
};
}
diff --git a/api/logic/DefaultVariable.h b/api/logic/DefaultVariable.h
index 38d7ecc2..5c069bd3 100644
--- a/api/logic/DefaultVariable.h
+++ b/api/logic/DefaultVariable.h
@@ -4,32 +4,32 @@ template <typename T>
class DefaultVariable
{
public:
- DefaultVariable(const T & value)
- {
- defaultValue = value;
- }
- DefaultVariable<T> & operator =(const T & value)
- {
- currentValue = value;
- is_default = currentValue == defaultValue;
- is_explicit = true;
- return *this;
- }
- operator const T &() const
- {
- return is_default ? defaultValue : currentValue;
- }
- bool isDefault() const
- {
- return is_default;
- }
- bool isExplicit() const
- {
- return is_explicit;
- }
+ DefaultVariable(const T & value)
+ {
+ defaultValue = value;
+ }
+ DefaultVariable<T> & operator =(const T & value)
+ {
+ currentValue = value;
+ is_default = currentValue == defaultValue;
+ is_explicit = true;
+ return *this;
+ }
+ operator const T &() const
+ {
+ return is_default ? defaultValue : currentValue;
+ }
+ bool isDefault() const
+ {
+ return is_default;
+ }
+ bool isExplicit() const
+ {
+ return is_explicit;
+ }
private:
- T currentValue;
- T defaultValue;
- bool is_default = true;
- bool is_explicit = false;
+ T currentValue;
+ T defaultValue;
+ bool is_default = true;
+ bool is_explicit = false;
};
diff --git a/api/logic/Env.cpp b/api/logic/Env.cpp
index 04a5ab23..73cad2e9 100644
--- a/api/logic/Env.cpp
+++ b/api/logic/Env.cpp
@@ -15,11 +15,11 @@
struct Env::Private
{
- QNetworkAccessManager m_qnam;
- shared_qobject_ptr<HttpMetaCache> m_metacache;
- std::shared_ptr<IIconList> m_iconlist;
- shared_qobject_ptr<Meta::Index> m_metadataIndex;
- QString m_jarsPath;
+ QNetworkAccessManager m_qnam;
+ shared_qobject_ptr<HttpMetaCache> m_metacache;
+ std::shared_ptr<IIconList> m_iconlist;
+ shared_qobject_ptr<Meta::Index> m_metadataIndex;
+ QString m_jarsPath;
};
static Env * instance;
@@ -30,152 +30,152 @@ static Env * instance;
Env::Env()
{
- d = new Private();
+ d = new Private();
}
Env::~Env()
{
- delete d;
+ delete d;
}
Env& Env::Env::getInstance()
{
- if(!instance)
- {
- instance = new Env();
- }
- return *instance;
+ if(!instance)
+ {
+ instance = new Env();
+ }
+ return *instance;
}
void Env::dispose()
{
- delete instance;
- instance = nullptr;
+ delete instance;
+ instance = nullptr;
}
shared_qobject_ptr< HttpMetaCache > Env::metacache()
{
- return d->m_metacache;
+ return d->m_metacache;
}
QNetworkAccessManager& Env::qnam() const
{
- return d->m_qnam;
+ return d->m_qnam;
}
std::shared_ptr<IIconList> Env::icons()
{
- return d->m_iconlist;
+ return d->m_iconlist;
}
void Env::registerIconList(std::shared_ptr<IIconList> iconlist)
{
- d->m_iconlist = iconlist;
+ d->m_iconlist = iconlist;
}
shared_qobject_ptr<Meta::Index> Env::metadataIndex()
{
- if (!d->m_metadataIndex)
- {
- d->m_metadataIndex.reset(new Meta::Index());
- }
- return d->m_metadataIndex;
+ if (!d->m_metadataIndex)
+ {
+ d->m_metadataIndex.reset(new Meta::Index());
+ }
+ return d->m_metadataIndex;
}
void Env::initHttpMetaCache()
{
- auto &m_metacache = d->m_metacache;
- m_metacache.reset(new HttpMetaCache("metacache"));
- m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath());
- m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath());
- m_metacache->addBase("versions", QDir("versions").absolutePath());
- m_metacache->addBase("libraries", QDir("libraries").absolutePath());
- m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
- m_metacache->addBase("fmllibs", QDir("mods/minecraftforge/libs").absolutePath());
- m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath());
- m_metacache->addBase("general", QDir("cache").absolutePath());
- m_metacache->addBase("FTBPacks", QDir("cache/FTBPacks").absolutePath());
- m_metacache->addBase("skins", QDir("accounts/skins").absolutePath());
- m_metacache->addBase("root", QDir::currentPath());
- m_metacache->addBase("translations", QDir("translations").absolutePath());
- m_metacache->addBase("icons", QDir("cache/icons").absolutePath());
- m_metacache->addBase("meta", QDir("meta").absolutePath());
- m_metacache->Load();
+ auto &m_metacache = d->m_metacache;
+ m_metacache.reset(new HttpMetaCache("metacache"));
+ m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath());
+ m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath());
+ m_metacache->addBase("versions", QDir("versions").absolutePath());
+ m_metacache->addBase("libraries", QDir("libraries").absolutePath());
+ m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
+ m_metacache->addBase("fmllibs", QDir("mods/minecraftforge/libs").absolutePath());
+ m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath());
+ m_metacache->addBase("general", QDir("cache").absolutePath());
+ m_metacache->addBase("FTBPacks", QDir("cache/FTBPacks").absolutePath());
+ m_metacache->addBase("skins", QDir("accounts/skins").absolutePath());
+ m_metacache->addBase("root", QDir::currentPath());
+ m_metacache->addBase("translations", QDir("translations").absolutePath());
+ m_metacache->addBase("icons", QDir("cache/icons").absolutePath());
+ m_metacache->addBase("meta", QDir("meta").absolutePath());
+ m_metacache->Load();
}
void Env::updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password)
{
- // Set the application proxy settings.
- if (proxyTypeStr == "SOCKS5")
- {
- QNetworkProxy::setApplicationProxy(
- QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password));
- }
- else if (proxyTypeStr == "HTTP")
- {
- QNetworkProxy::setApplicationProxy(
- QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password));
- }
- else if (proxyTypeStr == "None")
- {
- // If we have no proxy set, set no proxy and return.
- QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy));
- }
- else
- {
- // If we have "Default" selected, set Qt to use the system proxy settings.
- QNetworkProxyFactory::setUseSystemConfiguration(true);
- }
-
- qDebug() << "Detecting proxy settings...";
- QNetworkProxy proxy = QNetworkProxy::applicationProxy();
- d->m_qnam.setProxy(proxy);
- QString proxyDesc;
- if (proxy.type() == QNetworkProxy::NoProxy)
- {
- qDebug() << "Using no proxy is an option!";
- return;
- }
- switch (proxy.type())
- {
- case QNetworkProxy::DefaultProxy:
- proxyDesc = "Default proxy: ";
- break;
- case QNetworkProxy::Socks5Proxy:
- proxyDesc = "Socks5 proxy: ";
- break;
- case QNetworkProxy::HttpProxy:
- proxyDesc = "HTTP proxy: ";
- break;
- case QNetworkProxy::HttpCachingProxy:
- proxyDesc = "HTTP caching: ";
- break;
- case QNetworkProxy::FtpCachingProxy:
- proxyDesc = "FTP caching: ";
- break;
- default:
- proxyDesc = "DERP proxy: ";
- break;
- }
- proxyDesc += QString("%3@%1:%2 pass %4")
- .arg(proxy.hostName())
- .arg(proxy.port())
- .arg(proxy.user())
- .arg(proxy.password());
- qDebug() << proxyDesc;
+ // Set the application proxy settings.
+ if (proxyTypeStr == "SOCKS5")
+ {
+ QNetworkProxy::setApplicationProxy(
+ QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password));
+ }
+ else if (proxyTypeStr == "HTTP")
+ {
+ QNetworkProxy::setApplicationProxy(
+ QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password));
+ }
+ else if (proxyTypeStr == "None")
+ {
+ // If we have no proxy set, set no proxy and return.
+ QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy));
+ }
+ else
+ {
+ // If we have "Default" selected, set Qt to use the system proxy settings.
+ QNetworkProxyFactory::setUseSystemConfiguration(true);
+ }
+
+ qDebug() << "Detecting proxy settings...";
+ QNetworkProxy proxy = QNetworkProxy::applicationProxy();
+ d->m_qnam.setProxy(proxy);
+ QString proxyDesc;
+ if (proxy.type() == QNetworkProxy::NoProxy)
+ {
+ qDebug() << "Using no proxy is an option!";
+ return;
+ }
+ switch (proxy.type())
+ {
+ case QNetworkProxy::DefaultProxy:
+ proxyDesc = "Default proxy: ";
+ break;
+ case QNetworkProxy::Socks5Proxy:
+ proxyDesc = "Socks5 proxy: ";
+ break;
+ case QNetworkProxy::HttpProxy:
+ proxyDesc = "HTTP proxy: ";
+ break;
+ case QNetworkProxy::HttpCachingProxy:
+ proxyDesc = "HTTP caching: ";
+ break;
+ case QNetworkProxy::FtpCachingProxy:
+ proxyDesc = "FTP caching: ";
+ break;
+ default:
+ proxyDesc = "DERP proxy: ";
+ break;
+ }
+ proxyDesc += QString("%3@%1:%2 pass %4")
+ .arg(proxy.hostName())
+ .arg(proxy.port())
+ .arg(proxy.user())
+ .arg(proxy.password());
+ qDebug() << proxyDesc;
}
QString Env::getJarsPath()
{
- if(d->m_jarsPath.isEmpty())
- {
- return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars");
- }
- return d->m_jarsPath;
+ if(d->m_jarsPath.isEmpty())
+ {
+ return FS::PathCombine(QCoreApplication::applicationDirPath(), "jars");
+ }
+ return d->m_jarsPath;
}
void Env::setJarsPath(const QString& path)
{
- d->m_jarsPath = path;
+ d->m_jarsPath = path;
}
diff --git a/api/logic/Env.h b/api/logic/Env.h
index 276d762d..4d9ec139 100644
--- a/api/logic/Env.h
+++ b/api/logic/Env.h
@@ -20,40 +20,40 @@ class Index;
}
#if defined(ENV)
- #undef ENV
+ #undef ENV
#endif
#define ENV (Env::getInstance())
class MULTIMC_LOGIC_EXPORT Env
{
- friend class MultiMC;
+ friend class MultiMC;
private:
- struct Private;
- Env();
- ~Env();
- static void dispose();
+ struct Private;
+ Env();
+ ~Env();
+ static void dispose();
public:
- static Env& getInstance();
+ static Env& getInstance();
- QNetworkAccessManager &qnam() const;
+ QNetworkAccessManager &qnam() const;
- shared_qobject_ptr<HttpMetaCache> metacache();
+ shared_qobject_ptr<HttpMetaCache> metacache();
- std::shared_ptr<IIconList> icons();
+ std::shared_ptr<IIconList> icons();
- /// init the cache. FIXME: possible future hook point
- void initHttpMetaCache();
+ /// init the cache. FIXME: possible future hook point
+ void initHttpMetaCache();
- /// Updates the application proxy settings from the settings object.
- void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password);
+ /// Updates the application proxy settings from the settings object.
+ void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password);
- void registerIconList(std::shared_ptr<IIconList> iconlist);
+ void registerIconList(std::shared_ptr<IIconList> iconlist);
- shared_qobject_ptr<Meta::Index> metadataIndex();
+ shared_qobject_ptr<Meta::Index> metadataIndex();
- QString getJarsPath();
- void setJarsPath(const QString & path);
+ QString getJarsPath();
+ void setJarsPath(const QString & path);
protected:
- Private * d;
+ Private * d;
};
diff --git a/api/logic/Exception.h b/api/logic/Exception.h
index 30c7aa45..9400b3f8 100644
--- a/api/logic/Exception.h
+++ b/api/logic/Exception.h
@@ -11,24 +11,24 @@
class MULTIMC_LOGIC_EXPORT Exception : public std::exception
{
public:
- Exception(const QString &message) : std::exception(), m_message(message)
- {
- qCritical() << "Exception:" << message;
- }
- Exception(const Exception &other)
- : std::exception(), m_message(other.cause())
- {
- }
- virtual ~Exception() noexcept {}
- const char *what() const noexcept
- {
- return m_message.toLatin1().constData();
- }
- QString cause() const
- {
- return m_message;
- }
+ Exception(const QString &message) : std::exception(), m_message(message)
+ {
+ qCritical() << "Exception:" << message;
+ }
+ Exception(const Exception &other)
+ : std::exception(), m_message(other.cause())
+ {
+ }
+ virtual ~Exception() noexcept {}
+ const char *what() const noexcept
+ {
+ return m_message.toLatin1().constData();
+ }
+ QString cause() const
+ {
+ return m_message;
+ }
private:
- QString m_message;
+ QString m_message;
};
diff --git a/api/logic/FileSystem.cpp b/api/logic/FileSystem.cpp
index aef35375..1d8b290d 100644
--- a/api/logic/FileSystem.cpp
+++ b/api/logic/FileSystem.cpp
@@ -12,262 +12,262 @@
#include <QTextStream>
#if defined Q_OS_WIN32
- #include <windows.h>
- #include <string>
- #include <sys/utime.h>
- #include <winnls.h>
- #include <shobjidl.h>
- #include <objbase.h>
- #include <objidl.h>
- #include <shlguid.h>
- #include <shlobj.h>
+ #include <windows.h>
+ #include <string>
+ #include <sys/utime.h>
+ #include <winnls.h>
+ #include <shobjidl.h>
+ #include <objbase.h>
+ #include <objidl.h>
+ #include <shlguid.h>
+ #include <shlobj.h>
#else
- #include <utime.h>
+ #include <utime.h>
#endif
namespace FS {
void ensureExists(const QDir &dir)
{
- if (!QDir().mkpath(dir.absolutePath()))
- {
- throw FileSystemException("Unable to create folder " + dir.dirName() + " (" +
- dir.absolutePath() + ")");
- }
+ if (!QDir().mkpath(dir.absolutePath()))
+ {
+ throw FileSystemException("Unable to create folder " + dir.dirName() + " (" +
+ dir.absolutePath() + ")");
+ }
}
void write(const QString &filename, const QByteArray &data)
{
- ensureExists(QFileInfo(filename).dir());
- QSaveFile file(filename);
- if (!file.open(QSaveFile::WriteOnly))
- {
- throw FileSystemException("Couldn't open " + filename + " for writing: " +
- file.errorString());
- }
- if (data.size() != file.write(data))
- {
- throw FileSystemException("Error writing data to " + filename + ": " +
- file.errorString());
- }
- if (!file.commit())
- {
- throw FileSystemException("Error while committing data to " + filename + ": " +
- file.errorString());
- }
+ ensureExists(QFileInfo(filename).dir());
+ QSaveFile file(filename);
+ if (!file.open(QSaveFile::WriteOnly))
+ {
+ throw FileSystemException("Couldn't open " + filename + " for writing: " +
+ file.errorString());
+ }
+ if (data.size() != file.write(data))
+ {
+ throw FileSystemException("Error writing data to " + filename + ": " +
+ file.errorString());
+ }
+ if (!file.commit())
+ {
+ throw FileSystemException("Error while committing data to " + filename + ": " +
+ file.errorString());
+ }
}
QByteArray read(const QString &filename)
{
- QFile file(filename);
- if (!file.open(QFile::ReadOnly))
- {
- throw FileSystemException("Unable to open " + filename + " for reading: " +
- file.errorString());
- }
- const qint64 size = file.size();
- QByteArray data(int(size), 0);
- const qint64 ret = file.read(data.data(), size);
- if (ret == -1 || ret != size)
- {
- throw FileSystemException("Error reading data from " + filename + ": " +
- file.errorString());
- }
- return data;
+ QFile file(filename);
+ if (!file.open(QFile::ReadOnly))
+ {
+ throw FileSystemException("Unable to open " + filename + " for reading: " +
+ file.errorString());
+ }
+ const qint64 size = file.size();
+ QByteArray data(int(size), 0);
+ const qint64 ret = file.read(data.data(), size);
+ if (ret == -1 || ret != size)
+ {
+ throw FileSystemException("Error reading data from " + filename + ": " +
+ file.errorString());
+ }
+ return data;
}
bool updateTimestamp(const QString& filename)
{
#ifdef Q_OS_WIN32
- std::wstring filename_utf_16 = filename.toStdWString();
- return (_wutime64(filename_utf_16.c_str(), nullptr) == 0);
+ std::wstring filename_utf_16 = filename.toStdWString();
+ return (_wutime64(filename_utf_16.c_str(), nullptr) == 0);
#else
- QByteArray filenameBA = QFile::encodeName(filename);
- return (utime(filenameBA.data(), nullptr) == 0);
+ QByteArray filenameBA = QFile::encodeName(filename);
+ return (utime(filenameBA.data(), nullptr) == 0);
#endif
}
bool ensureFilePathExists(QString filenamepath)
{
- QFileInfo a(filenamepath);
- QDir dir;
- QString ensuredPath = a.path();
- bool success = dir.mkpath(ensuredPath);
- return success;
+ QFileInfo a(filenamepath);
+ QDir dir;
+ QString ensuredPath = a.path();
+ bool success = dir.mkpath(ensuredPath);
+ return success;
}
bool ensureFolderPathExists(QString foldernamepath)
{
- QFileInfo a(foldernamepath);
- QDir dir;
- QString ensuredPath = a.filePath();
- bool success = dir.mkpath(ensuredPath);
- return success;
+ QFileInfo a(foldernamepath);
+ QDir dir;
+ QString ensuredPath = a.filePath();
+ bool success = dir.mkpath(ensuredPath);
+ return success;
}
bool copy::operator()(const QString &offset)
{
- //NOTE always deep copy on windows. the alternatives are too messy.
- #if defined Q_OS_WIN32
- m_followSymlinks = true;
- #endif
-
- auto src = PathCombine(m_src.absolutePath(), offset);
- auto dst = PathCombine(m_dst.absolutePath(), offset);
-
- QFileInfo currentSrc(src);
- if (!currentSrc.exists())
- return false;
-
- if(!m_followSymlinks && currentSrc.isSymLink())
- {
- qDebug() << "creating symlink" << src << " - " << dst;
- if (!ensureFilePathExists(dst))
- {
- qWarning() << "Cannot create path!";
- return false;
- }
- return QFile::link(currentSrc.symLinkTarget(), dst);
- }
- else if(currentSrc.isFile())
- {
- qDebug() << "copying file" << src << " - " << dst;
- if (!ensureFilePathExists(dst))
- {
- qWarning() << "Cannot create path!";
- return false;
- }
- return QFile::copy(src, dst);
- }
- else if(currentSrc.isDir())
- {
- qDebug() << "recursing" << offset;
- if (!ensureFolderPathExists(dst))
- {
- qWarning() << "Cannot create path!";
- return false;
- }
- QDir currentDir(src);
- for(auto & f : currentDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System))
- {
- auto inner_offset = PathCombine(offset, f);
- // ignore and skip stuff that matches the blacklist.
- if(m_blacklist && m_blacklist->matches(inner_offset))
- {
- continue;
- }
- if(!operator()(inner_offset))
- {
- qWarning() << "Failed to copy" << inner_offset;
- return false;
- }
- }
- }
- else
- {
- qCritical() << "Copy ERROR: Unknown filesystem object:" << src;
- return false;
- }
- return true;
+ //NOTE always deep copy on windows. the alternatives are too messy.
+ #if defined Q_OS_WIN32
+ m_followSymlinks = true;
+ #endif
+
+ auto src = PathCombine(m_src.absolutePath(), offset);
+ auto dst = PathCombine(m_dst.absolutePath(), offset);
+
+ QFileInfo currentSrc(src);
+ if (!currentSrc.exists())
+ return false;
+
+ if(!m_followSymlinks && currentSrc.isSymLink())
+ {
+ qDebug() << "creating symlink" << src << " - " << dst;
+ if (!ensureFilePathExists(dst))
+ {
+ qWarning() << "Cannot create path!";
+ return false;
+ }
+ return QFile::link(currentSrc.symLinkTarget(), dst);
+ }
+ else if(currentSrc.isFile())
+ {
+ qDebug() << "copying file" << src << " - " << dst;
+ if (!ensureFilePathExists(dst))
+ {
+ qWarning() << "Cannot create path!";
+ return false;
+ }
+ return QFile::copy(src, dst);
+ }
+ else if(currentSrc.isDir())
+ {
+ qDebug() << "recursing" << offset;
+ if (!ensureFolderPathExists(dst))
+ {
+ qWarning() << "Cannot create path!";
+ return false;
+ }
+ QDir currentDir(src);
+ for(auto & f : currentDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System))
+ {
+ auto inner_offset = PathCombine(offset, f);
+ // ignore and skip stuff that matches the blacklist.
+ if(m_blacklist && m_blacklist->matches(inner_offset))
+ {
+ continue;
+ }
+ if(!operator()(inner_offset))
+ {
+ qWarning() << "Failed to copy" << inner_offset;
+ return false;
+ }
+ }
+ }
+ else
+ {
+ qCritical() << "Copy ERROR: Unknown filesystem object:" << src;
+ return false;
+ }
+ return true;
}
bool deletePath(QString path)
{
- bool OK = true;
- QDir dir(path);
-
- if (!dir.exists())
- {
- return OK;
- }
- auto allEntries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden |
- QDir::AllDirs | QDir::Files,
- QDir::DirsFirst);
-
- for(auto & info: allEntries)
- {
+ bool OK = true;
+ QDir dir(path);
+
+ if (!dir.exists())
+ {
+ return OK;
+ }
+ auto allEntries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden |
+ QDir::AllDirs | QDir::Files,
+ QDir::DirsFirst);
+
+ for(auto & info: allEntries)
+ {
#if defined Q_OS_WIN32
- QString nativePath = QDir::toNativeSeparators(info.absoluteFilePath());
- auto wString = nativePath.toStdWString();
- DWORD dwAttrs = GetFileAttributesW(wString.c_str());
- // Windows: check for junctions, reparse points and other nasty things of that sort
- if(dwAttrs & FILE_ATTRIBUTE_REPARSE_POINT)
- {
- if (info.isFile())
- {
- OK &= QFile::remove(info.absoluteFilePath());
- }
- else if (info.isDir())
- {
- OK &= dir.rmdir(info.absoluteFilePath());
- }
- }
+ QString nativePath = QDir::toNativeSeparators(info.absoluteFilePath());
+ auto wString = nativePath.toStdWString();
+ DWORD dwAttrs = GetFileAttributesW(wString.c_str());
+ // Windows: check for junctions, reparse points and other nasty things of that sort
+ if(dwAttrs & FILE_ATTRIBUTE_REPARSE_POINT)
+ {
+ if (info.isFile())
+ {
+ OK &= QFile::remove(info.absoluteFilePath());
+ }
+ else if (info.isDir())
+ {
+ OK &= dir.rmdir(info.absoluteFilePath());
+ }
+ }
#else
- // We do not trust Qt with reparse points, but do trust it with unix symlinks.
- if(info.isSymLink())
- {
- OK &= QFile::remove(info.absoluteFilePath());
- }
+ // We do not trust Qt with reparse points, but do trust it with unix symlinks.
+ if(info.isSymLink())
+ {
+ OK &= QFile::remove(info.absoluteFilePath());
+ }
#endif
- else if (info.isDir())
- {
- OK &= deletePath(info.absoluteFilePath());
- }
- else if (info.isFile())
- {
- OK &= QFile::remove(info.absoluteFilePath());
- }
- else
- {
- OK = false;
- qCritical() << "Delete ERROR: Unknown filesystem object:" << info.absoluteFilePath();
- }
- }
- OK &= dir.rmdir(dir.absolutePath());
- return OK;
+ else if (info.isDir())
+ {
+ OK &= deletePath(info.absoluteFilePath());
+ }
+ else if (info.isFile())
+ {
+ OK &= QFile::remove(info.absoluteFilePath());
+ }
+ else
+ {
+ OK = false;
+ qCritical() << "Delete ERROR: Unknown filesystem object:" << info.absoluteFilePath();
+ }
+ }
+ OK &= dir.rmdir(dir.absolutePath());
+ return OK;
}
QString PathCombine(const QString & path1, const QString & path2)
{
- if(!path1.size())
- return path2;
- if(!path2.size())
- return path1;
+ if(!path1.size())
+ return path2;
+ if(!path2.size())
+ return path1;
return QDir::cleanPath(path1 + QDir::separator() + path2);
}
QString PathCombine(const QString & path1, const QString & path2, const QString & path3)
{
- return PathCombine(PathCombine(path1, path2), path3);
+ return PathCombine(PathCombine(path1, path2), path3);
}
QString PathCombine(const QString & path1, const QString & path2, const QString & path3, const QString & path4)
{
- return PathCombine(PathCombine(path1, path2, path3), path4);
+ return PathCombine(PathCombine(path1, path2, path3), path4);
}
QString AbsolutePath(QString path)
{
- return QFileInfo(path).absolutePath();
+ return QFileInfo(path).absolutePath();
}
QString ResolveExecutable(QString path)
{
- if (path.isEmpty())
- {
- return QString();
- }
- if(!path.contains('/'))
- {
- path = QStandardPaths::findExecutable(path);
- }
- QFileInfo pathInfo(path);
- if(!pathInfo.exists() || !pathInfo.isExecutable())
- {
- return QString();
- }
- return pathInfo.absoluteFilePath();
+ if (path.isEmpty())
+ {
+ return QString();
+ }
+ if(!path.contains('/'))
+ {
+ path = QStandardPaths::findExecutable(path);
+ }
+ QFileInfo pathInfo(path);
+ if(!pathInfo.exists() || !pathInfo.isExecutable())
+ {
+ return QString();
+ }
+ return pathInfo.absoluteFilePath();
}
/**
@@ -278,66 +278,66 @@ QString ResolveExecutable(QString path)
*/
QString NormalizePath(QString path)
{
- QDir a = QDir::currentPath();
- QString currentAbsolute = a.absolutePath();
-
- QDir b(path);
- QString newAbsolute = b.absolutePath();
-
- if (newAbsolute.startsWith(currentAbsolute))
- {
- return a.relativeFilePath(newAbsolute);
- }
- else
- {
- return newAbsolute;
- }
+ QDir a = QDir::currentPath();
+ QString currentAbsolute = a.absolutePath();
+
+ QDir b(path);
+ QString newAbsolute = b.absolutePath();
+
+ if (newAbsolute.startsWith(currentAbsolute))
+ {
+ return a.relativeFilePath(newAbsolute);
+ }
+ else
+ {
+ return newAbsolute;
+ }
}
QString badFilenameChars = "\"\\/?<>:*|!";
QString RemoveInvalidFilenameChars(QString string, QChar replaceWith)
{
- for (int i = 0; i < string.length(); i++)
- {
- if (badFilenameChars.contains(string[i]))
- {
- string[i] = replaceWith;
- }
- }
- return string;
+ for (int i = 0; i < string.length(); i++)
+ {
+ if (badFilenameChars.contains(string[i]))
+ {
+ string[i] = replaceWith;
+ }
+ }
+ return string;
}
QString DirNameFromString(QString string, QString inDir)
{
- int num = 0;
- QString baseName = RemoveInvalidFilenameChars(string, '-');
- QString dirName;
- do
- {
- if(num == 0)
- {
- dirName = baseName;
- }
- else
- {
- dirName = baseName + QString::number(num);;
- }
-
- // If it's over 9000
- if (num > 9000)
- return "";
- num++;
- } while (QFileInfo(PathCombine(inDir, dirName)).exists());
- return dirName;
+ int num = 0;
+ QString baseName = RemoveInvalidFilenameChars(string, '-');
+ QString dirName;
+ do
+ {
+ if(num == 0)
+ {
+ dirName = baseName;
+ }
+ else
+ {
+ dirName = baseName + QString::number(num);;
+ }
+
+ // If it's over 9000
+ if (num > 9000)
+ return "";
+ num++;
+ } while (QFileInfo(PathCombine(inDir, dirName)).exists());
+ return dirName;
}
// Does the folder path contain any '!'? If yes, return true, otherwise false.
// (This is a problem for Java)
bool checkProblemticPathJava(QDir folder)
{
- QString pathfoldername = folder.absolutePath();
- return pathfoldername.contains("!", Qt::CaseInsensitive);
+ QString pathfoldername = folder.absolutePath();
+ return pathfoldername.contains("!", Qt::CaseInsensitive);
}
// Win32 crap
@@ -347,106 +347,106 @@ bool called_coinit = false;
HRESULT CreateLink(LPCSTR linkPath, LPCSTR targetPath, LPCSTR args)
{
- HRESULT hres;
-
- if (!called_coinit)
- {
- hres = CoInitialize(NULL);
- called_coinit = true;
-
- if (!SUCCEEDED(hres))
- {
- qWarning("Failed to initialize COM. Error 0x%08lX", hres);
- return hres;
- }
- }
-
- IShellLink *link;
- hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink,
- (LPVOID *)&link);
-
- if (SUCCEEDED(hres))
- {
- IPersistFile *persistFile;
-
- link->SetPath(targetPath);
- link->SetArguments(args);
-
- hres = link->QueryInterface(IID_IPersistFile, (LPVOID *)&persistFile);
- if (SUCCEEDED(hres))
- {
- WCHAR wstr[MAX_PATH];
-
- MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
-
- hres = persistFile->Save(wstr, TRUE);
- persistFile->Release();
- }
- link->Release();
- }
- return hres;
+ HRESULT hres;
+
+ if (!called_coinit)
+ {
+ hres = CoInitialize(NULL);
+ called_coinit = true;
+
+ if (!SUCCEEDED(hres))
+ {
+ qWarning("Failed to initialize COM. Error 0x%08lX", hres);
+ return hres;
+ }
+ }
+
+ IShellLink *link;
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink,
+ (LPVOID *)&link);
+
+ if (SUCCEEDED(hres))
+ {
+ IPersistFile *persistFile;
+
+ link->SetPath(targetPath);
+ link->SetArguments(args);
+
+ hres = link->QueryInterface(IID_IPersistFile, (LPVOID *)&persistFile);
+ if (SUCCEEDED(hres))
+ {
+ WCHAR wstr[MAX_PATH];
+
+ MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
+
+ hres = persistFile->Save(wstr, TRUE);
+ persistFile->Release();
+ }
+ link->Release();
+ }
+ return hres;
}
#endif
QString getDesktopDir()
{
- return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
+ return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
}
// Cross-platform Shortcut creation
bool createShortCut(QString location, QString dest, QStringList args, QString name,
- QString icon)
+ QString icon)
{
#if defined Q_OS_LINUX
- location = PathCombine(location, name + ".desktop");
+ location = PathCombine(location, name + ".desktop");
- QFile f(location);
- f.open(QIODevice::WriteOnly | QIODevice::Text);
- QTextStream stream(&f);
+ QFile f(location);
+ f.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream stream(&f);
- QString argstring;
- if (!args.empty())
- argstring = " '" + args.join("' '") + "'";
+ QString argstring;
+ if (!args.empty())
+ argstring = " '" + args.join("' '") + "'";
- stream << "[Desktop Entry]"
- << "\n";
- stream << "Type=Application"
- << "\n";
- stream << "TryExec=" << dest.toLocal8Bit() << "\n";
- stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
- stream << "Name=" << name.toLocal8Bit() << "\n";
- stream << "Icon=" << icon.toLocal8Bit() << "\n";
+ stream << "[Desktop Entry]"
+ << "\n";
+ stream << "Type=Application"
+ << "\n";
+ stream << "TryExec=" << dest.toLocal8Bit() << "\n";
+ stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
+ stream << "Name=" << name.toLocal8Bit() << "\n";
+ stream << "Icon=" << icon.toLocal8Bit() << "\n";
- stream.flush();
- f.close();
+ stream.flush();
+ f.close();
- f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup |
- QFileDevice::ExeOther);
+ f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup |
+ QFileDevice::ExeOther);
- return true;
+ return true;
#elif defined Q_OS_WIN
- // TODO: Fix
- // QFile file(PathCombine(location, name + ".lnk"));
- // WCHAR *file_w;
- // WCHAR *dest_w;
- // WCHAR *args_w;
- // file.fileName().toWCharArray(file_w);
- // dest.toWCharArray(dest_w);
-
- // QString argStr;
- // for (int i = 0; i < args.count(); i++)
- // {
- // argStr.append(args[i]);
- // argStr.append(" ");
- // }
- // argStr.toWCharArray(args_w);
-
- // return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
- return false;
+ // TODO: Fix
+ // QFile file(PathCombine(location, name + ".lnk"));
+ // WCHAR *file_w;
+ // WCHAR *dest_w;
+ // WCHAR *args_w;
+ // file.fileName().toWCharArray(file_w);
+ // dest.toWCharArray(dest_w);
+
+ // QString argStr;
+ // for (int i = 0; i < args.count(); i++)
+ // {
+ // argStr.append(args[i]);
+ // argStr.append(" ");
+ // }
+ // argStr.toWCharArray(args_w);
+
+ // return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
+ return false;
#else
- qWarning("Desktop Shortcuts not supported on your platform!");
- return false;
+ qWarning("Desktop Shortcuts not supported on your platform!");
+ return false;
#endif
}
}
diff --git a/api/logic/FileSystem.h b/api/logic/FileSystem.h
index de8774ff..55ec6a58 100644
--- a/api/logic/FileSystem.h
+++ b/api/logic/FileSystem.h
@@ -15,7 +15,7 @@ namespace FS
class MULTIMC_LOGIC_EXPORT FileSystemException : public ::Exception
{
public:
- FileSystemException(const QString &message) : Exception(message) {}
+ FileSystemException(const QString &message) : Exception(message) {}
};
/**
@@ -48,34 +48,34 @@ MULTIMC_LOGIC_EXPORT bool ensureFolderPathExists(QString filenamepath);
class MULTIMC_LOGIC_EXPORT copy
{
public:
- copy(const QString & src, const QString & dst)
- {
- m_src = src;
- m_dst = dst;
- }
- copy & followSymlinks(const bool follow)
- {
- m_followSymlinks = follow;
- return *this;
- }
- copy & blacklist(const IPathMatcher * filter)
- {
- m_blacklist = filter;
- return *this;
- }
- bool operator()()
- {
- return operator()(QString());
- }
+ copy(const QString & src, const QString & dst)
+ {
+ m_src = src;
+ m_dst = dst;
+ }
+ copy & followSymlinks(const bool follow)
+ {
+ m_followSymlinks = follow;
+ return *this;
+ }
+ copy & blacklist(const IPathMatcher * filter)
+ {
+ m_blacklist = filter;
+ return *this;
+ }
+ bool operator()()
+ {
+ return operator()(QString());
+ }
private:
- bool operator()(const QString &offset);
+ bool operator()(const QString &offset);
private:
- bool m_followSymlinks = true;
- const IPathMatcher * m_blacklist = nullptr;
- QDir m_src;
- QDir m_dst;
+ bool m_followSymlinks = true;
+ const IPathMatcher * m_blacklist = nullptr;
+ QDir m_src;
+ QDir m_dst;
};
/**
diff --git a/api/logic/FileSystem_test.cpp b/api/logic/FileSystem_test.cpp
index d5e1eedb..df653ea1 100644
--- a/api/logic/FileSystem_test.cpp
+++ b/api/logic/FileSystem_test.cpp
@@ -7,155 +7,155 @@
class FileSystemTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
- const QString bothSlash = "/foo/";
- const QString trailingSlash = "foo/";
- const QString leadingSlash = "/foo";
+ const QString bothSlash = "/foo/";
+ const QString trailingSlash = "foo/";
+ const QString leadingSlash = "/foo";
private
slots:
- void test_pathCombine()
- {
- QCOMPARE(QString("/foo/foo"), FS::PathCombine(bothSlash, bothSlash));
- QCOMPARE(QString("foo/foo"), FS::PathCombine(trailingSlash, trailingSlash));
- QCOMPARE(QString("/foo/foo"), FS::PathCombine(leadingSlash, leadingSlash));
-
- QCOMPARE(QString("/foo/foo/foo"), FS::PathCombine(bothSlash, bothSlash, bothSlash));
- QCOMPARE(QString("foo/foo/foo"), FS::PathCombine(trailingSlash, trailingSlash, trailingSlash));
- QCOMPARE(QString("/foo/foo/foo"), FS::PathCombine(leadingSlash, leadingSlash, leadingSlash));
- }
-
- void test_PathCombine1_data()
- {
- QTest::addColumn<QString>("result");
- QTest::addColumn<QString>("path1");
- QTest::addColumn<QString>("path2");
-
- QTest::newRow("qt 1") << "/abc/def/ghi/jkl" << "/abc/def" << "ghi/jkl";
- QTest::newRow("qt 2") << "/abc/def/ghi/jkl" << "/abc/def/" << "ghi/jkl";
+ void test_pathCombine()
+ {
+ QCOMPARE(QString("/foo/foo"), FS::PathCombine(bothSlash, bothSlash));
+ QCOMPARE(QString("foo/foo"), FS::PathCombine(trailingSlash, trailingSlash));
+ QCOMPARE(QString("/foo/foo"), FS::PathCombine(leadingSlash, leadingSlash));
+
+ QCOMPARE(QString("/foo/foo/foo"), FS::PathCombine(bothSlash, bothSlash, bothSlash));
+ QCOMPARE(QString("foo/foo/foo"), FS::PathCombine(trailingSlash, trailingSlash, trailingSlash));
+ QCOMPARE(QString("/foo/foo/foo"), FS::PathCombine(leadingSlash, leadingSlash, leadingSlash));
+ }
+
+ void test_PathCombine1_data()
+ {
+ QTest::addColumn<QString>("result");
+ QTest::addColumn<QString>("path1");
+ QTest::addColumn<QString>("path2");
+
+ QTest::newRow("qt 1") << "/abc/def/ghi/jkl" << "/abc/def" << "ghi/jkl";
+ QTest::newRow("qt 2") << "/abc/def/ghi/jkl" << "/abc/def/" << "ghi/jkl";
#if defined(Q_OS_WIN)
- QTest::newRow("win native, from C:") << "C:/abc" << "C:" << "abc";
- QTest::newRow("win native 1") << "C:/abc/def/ghi/jkl" << "C:\\abc\\def" << "ghi\\jkl";
- QTest::newRow("win native 2") << "C:/abc/def/ghi/jkl" << "C:\\abc\\def\\" << "ghi\\jkl";
+ QTest::newRow("win native, from C:") << "C:/abc" << "C:" << "abc";
+ QTest::newRow("win native 1") << "C:/abc/def/ghi/jkl" << "C:\\abc\\def" << "ghi\\jkl";
+ QTest::newRow("win native 2") << "C:/abc/def/ghi/jkl" << "C:\\abc\\def\\" << "ghi\\jkl";
#endif
- }
-
- void test_PathCombine1()
- {
- QFETCH(QString, result);
- QFETCH(QString, path1);
- QFETCH(QString, path2);
-
- QCOMPARE(FS::PathCombine(path1, path2), result);
- }
-
- void test_PathCombine2_data()
- {
- QTest::addColumn<QString>("result");
- QTest::addColumn<QString>("path1");
- QTest::addColumn<QString>("path2");
- QTest::addColumn<QString>("path3");
-
- QTest::newRow("qt 1") << "/abc/def/ghi/jkl" << "/abc" << "def" << "ghi/jkl";
- QTest::newRow("qt 2") << "/abc/def/ghi/jkl" << "/abc/" << "def" << "ghi/jkl";
- QTest::newRow("qt 3") << "/abc/def/ghi/jkl" << "/abc" << "def/" << "ghi/jkl";
- QTest::newRow("qt 4") << "/abc/def/ghi/jkl" << "/abc/" << "def/" << "ghi/jkl";
+ }
+
+ void test_PathCombine1()
+ {
+ QFETCH(QString, result);
+ QFETCH(QString, path1);
+ QFETCH(QString, path2);
+
+ QCOMPARE(FS::PathCombine(path1, path2), result);
+ }
+
+ void test_PathCombine2_data()
+ {
+ QTest::addColumn<QString>("result");
+ QTest::addColumn<QString>("path1");
+ QTest::addColumn<QString>("path2");
+ QTest::addColumn<QString>("path3");
+
+ QTest::newRow("qt 1") << "/abc/def/ghi/jkl" << "/abc" << "def" << "ghi/jkl";
+ QTest::newRow("qt 2") << "/abc/def/ghi/jkl" << "/abc/" << "def" << "ghi/jkl";
+ QTest::newRow("qt 3") << "/abc/def/ghi/jkl" << "/abc" << "def/" << "ghi/jkl";
+ QTest::newRow("qt 4") << "/abc/def/ghi/jkl" << "/abc/" << "def/" << "ghi/jkl";
#if defined(Q_OS_WIN)
- QTest::newRow("win 1") << "C:/abc/def/ghi/jkl" << "C:\\abc" << "def" << "ghi\\jkl";
- QTest::newRow("win 2") << "C:/abc/def/ghi/jkl" << "C:\\abc\\" << "def" << "ghi\\jkl";
- QTest::newRow("win 3") << "C:/abc/def/ghi/jkl" << "C:\\abc" << "def\\" << "ghi\\jkl";
- QTest::newRow("win 4") << "C:/abc/def/ghi/jkl" << "C:\\abc\\" << "def" << "ghi\\jkl";
+ QTest::newRow("win 1") << "C:/abc/def/ghi/jkl" << "C:\\abc" << "def" << "ghi\\jkl";
+ QTest::newRow("win 2") << "C:/abc/def/ghi/jkl" << "C:\\abc\\" << "def" << "ghi\\jkl";
+ QTest::newRow("win 3") << "C:/abc/def/ghi/jkl" << "C:\\abc" << "def\\" << "ghi\\jkl";
+ QTest::newRow("win 4") << "C:/abc/def/ghi/jkl" << "C:\\abc\\" << "def" << "ghi\\jkl";
#endif
- }
-
- void test_PathCombine2()
- {
- QFETCH(QString, result);
- QFETCH(QString, path1);
- QFETCH(QString, path2);
- QFETCH(QString, path3);
-
- QCOMPARE(FS::PathCombine(path1, path2, path3), result);
- }
-
- void test_copy()
- {
- QString folder = QFINDTESTDATA("data/test_folder");
- auto f = [&folder]()
- {
- QTemporaryDir tempDir;
- tempDir.setAutoRemove(true);
- qDebug() << "From:" << folder << "To:" << tempDir.path();
-
- QDir target_dir(FS::PathCombine(tempDir.path(), "test_folder"));
- qDebug() << tempDir.path();
- qDebug() << target_dir.path();
- FS::copy c(folder, target_dir.path());
- c();
-
- for(auto entry: target_dir.entryList())
- {
- qDebug() << entry;
- }
- QVERIFY(target_dir.entryList().contains("pack.mcmeta"));
- QVERIFY(target_dir.entryList().contains("assets"));
- };
-
- // first try variant without trailing /
- QVERIFY(!folder.endsWith('/'));
- f();
-
- // then variant with trailing /
- folder.append('/');
- QVERIFY(folder.endsWith('/'));
- f();
- }
-
- void test_getDesktop()
- {
- QCOMPARE(FS::getDesktopDir(), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
- }
+ }
+
+ void test_PathCombine2()
+ {
+ QFETCH(QString, result);
+ QFETCH(QString, path1);
+ QFETCH(QString, path2);
+ QFETCH(QString, path3);
+
+ QCOMPARE(FS::PathCombine(path1, path2, path3), result);
+ }
+
+ void test_copy()
+ {
+ QString folder = QFINDTESTDATA("data/test_folder");
+ auto f = [&folder]()
+ {
+ QTemporaryDir tempDir;
+ tempDir.setAutoRemove(true);
+ qDebug() << "From:" << folder << "To:" << tempDir.path();
+
+ QDir target_dir(FS::PathCombine(tempDir.path(), "test_folder"));
+ qDebug() << tempDir.path();
+ qDebug() << target_dir.path();
+ FS::copy c(folder, target_dir.path());
+ c();
+
+ for(auto entry: target_dir.entryList())
+ {
+ qDebug() << entry;
+ }
+ QVERIFY(target_dir.entryList().contains("pack.mcmeta"));
+ QVERIFY(target_dir.entryList().contains("assets"));
+ };
+
+ // first try variant without trailing /
+ QVERIFY(!folder.endsWith('/'));
+ f();
+
+ // then variant with trailing /
+ folder.append('/');
+ QVERIFY(folder.endsWith('/'));
+ f();
+ }
+
+ void test_getDesktop()
+ {
+ QCOMPARE(FS::getDesktopDir(), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
+ }
// this is only valid on linux
// FIXME: implement on windows, OSX, then test.
#if defined(Q_OS_LINUX)
- void test_createShortcut_data()
- {
- QTest::addColumn<QString>("location");
- QTest::addColumn<QString>("dest");
- QTest::addColumn<QStringList>("args");
- QTest::addColumn<QString>("name");
- QTest::addColumn<QString>("iconLocation");
- QTest::addColumn<QByteArray>("result");
-
- QTest::newRow("unix") << QDir::currentPath()
- << "asdfDest"
- << (QStringList() << "arg1" << "arg2")
- << "asdf"
- << QString()
- #if defined(Q_OS_LINUX)
- << MULTIMC_GET_TEST_FILE("data/FileSystem-test_createShortcut-unix")
- #elif defined(Q_OS_WIN)
- << QByteArray()
- #endif
- ;
- }
-
- void test_createShortcut()
- {
- QFETCH(QString, location);
- QFETCH(QString, dest);
- QFETCH(QStringList, args);
- QFETCH(QString, name);
- QFETCH(QString, iconLocation);
- QFETCH(QByteArray, result);
-
- QVERIFY(FS::createShortCut(location, dest, args, name, iconLocation));
- QCOMPARE(QString::fromLocal8Bit(TestsInternal::readFile(location + QDir::separator() + name + ".desktop")), QString::fromLocal8Bit(result));
-
- //QDir().remove(location);
- }
+ void test_createShortcut_data()
+ {
+ QTest::addColumn<QString>("location");
+ QTest::addColumn<QString>("dest");
+ QTest::addColumn<QStringList>("args");
+ QTest::addColumn<QString>("name");
+ QTest::addColumn<QString>("iconLocation");
+ QTest::addColumn<QByteArray>("result");
+
+ QTest::newRow("unix") << QDir::currentPath()
+ << "asdfDest"
+ << (QStringList() << "arg1" << "arg2")
+ << "asdf"
+ << QString()
+ #if defined(Q_OS_LINUX)
+ << MULTIMC_GET_TEST_FILE("data/FileSystem-test_createShortcut-unix")
+ #elif defined(Q_OS_WIN)
+ << QByteArray()
+ #endif
+ ;
+ }
+
+ void test_createShortcut()
+ {
+ QFETCH(QString, location);
+ QFETCH(QString, dest);
+ QFETCH(QStringList, args);
+ QFETCH(QString, name);
+ QFETCH(QString, iconLocation);
+ QFETCH(QByteArray, result);
+
+ QVERIFY(FS::createShortCut(location, dest, args, name, iconLocation));
+ QCOMPARE(QString::fromLocal8Bit(TestsInternal::readFile(location + QDir::separator() + name + ".desktop")), QString::fromLocal8Bit(result));
+
+ //QDir().remove(location);
+ }
#endif
};
diff --git a/api/logic/Filter.cpp b/api/logic/Filter.cpp
index 7f6667ae..6ec26bcb 100644
--- a/api/logic/Filter.cpp
+++ b/api/logic/Filter.cpp
@@ -6,26 +6,26 @@ ContainsFilter::ContainsFilter(const QString& pattern) : pattern(pattern){}
ContainsFilter::~ContainsFilter(){}
bool ContainsFilter::accepts(const QString& value)
{
- return value.contains(pattern);
+ return value.contains(pattern);
}
ExactFilter::ExactFilter(const QString& pattern) : pattern(pattern){}
ExactFilter::~ExactFilter(){}
bool ExactFilter::accepts(const QString& value)
{
- return value.contains(pattern);
+ return value.contains(pattern);
}
RegexpFilter::RegexpFilter(const QString& regexp, bool invert)
- :invert(invert)
+ :invert(invert)
{
- pattern.setPattern(regexp);
- pattern.optimize();
+ pattern.setPattern(regexp);
+ pattern.optimize();
}
RegexpFilter::~RegexpFilter(){}
bool RegexpFilter::accepts(const QString& value)
{
- auto match = pattern.match(value);
- bool matched = match.hasMatch();
- return invert ? (!matched) : (matched);
+ auto match = pattern.match(value);
+ bool matched = match.hasMatch();
+ return invert ? (!matched) : (matched);
}
diff --git a/api/logic/Filter.h b/api/logic/Filter.h
index 8de7d8f9..1ba48e48 100644
--- a/api/logic/Filter.h
+++ b/api/logic/Filter.h
@@ -8,37 +8,37 @@
class MULTIMC_LOGIC_EXPORT Filter
{
public:
- virtual ~Filter();
- virtual bool accepts(const QString & value) = 0;
+ virtual ~Filter();
+ virtual bool accepts(const QString & value) = 0;
};
class MULTIMC_LOGIC_EXPORT ContainsFilter: public Filter
{
public:
- ContainsFilter(const QString &pattern);
- virtual ~ContainsFilter();
- bool accepts(const QString & value) override;
+ ContainsFilter(const QString &pattern);
+ virtual ~ContainsFilter();
+ bool accepts(const QString & value) override;
private:
- QString pattern;
+ QString pattern;
};
class MULTIMC_LOGIC_EXPORT ExactFilter: public Filter
{
public:
- ExactFilter(const QString &pattern);
- virtual ~ExactFilter();
- bool accepts(const QString & value) override;
+ ExactFilter(const QString &pattern);
+ virtual ~ExactFilter();
+ bool accepts(const QString & value) override;
private:
- QString pattern;
+ QString pattern;
};
class MULTIMC_LOGIC_EXPORT RegexpFilter: public Filter
{
public:
- RegexpFilter(const QString &regexp, bool invert);
- virtual ~RegexpFilter();
- bool accepts(const QString & value) override;
+ RegexpFilter(const QString &regexp, bool invert);
+ virtual ~RegexpFilter();
+ bool accepts(const QString & value) override;
private:
- QRegularExpression pattern;
- bool invert = false;
+ QRegularExpression pattern;
+ bool invert = false;
};
diff --git a/api/logic/FolderInstanceProvider.cpp b/api/logic/FolderInstanceProvider.cpp
index cedba408..4f89e5b7 100644
--- a/api/logic/FolderInstanceProvider.cpp
+++ b/api/logic/FolderInstanceProvider.cpp
@@ -18,322 +18,322 @@ const static int GROUP_FILE_FORMAT_VERSION = 1;
struct WatchLock
{
- WatchLock(QFileSystemWatcher * watcher, const QString& instDir)
- : m_watcher(watcher), m_instDir(instDir)
- {
- m_watcher->removePath(m_instDir);
- }
- ~WatchLock()
- {
- m_watcher->addPath(m_instDir);
- }
- QFileSystemWatcher * m_watcher;
- QString m_instDir;
+ WatchLock(QFileSystemWatcher * watcher, const QString& instDir)
+ : m_watcher(watcher), m_instDir(instDir)
+ {
+ m_watcher->removePath(m_instDir);
+ }
+ ~WatchLock()
+ {
+ m_watcher->addPath(m_instDir);
+ }
+ QFileSystemWatcher * m_watcher;
+ QString m_instDir;
};
FolderInstanceProvider::FolderInstanceProvider(SettingsObjectPtr settings, const QString& instDir)
- : BaseInstanceProvider(settings)
+ : BaseInstanceProvider(settings)
{
- // Create aand normalize path
- if (!QDir::current().exists(instDir))
- {
- QDir::current().mkpath(instDir);
- }
- // NOTE: canonicalPath requires the path to exist. Do not move this above the creation block!
- m_instDir = QDir(instDir).canonicalPath();
- m_watcher = new QFileSystemWatcher(this);
- connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &FolderInstanceProvider::instanceDirContentsChanged);
- m_watcher->addPath(m_instDir);
+ // Create aand normalize path
+ if (!QDir::current().exists(instDir))
+ {
+ QDir::current().mkpath(instDir);
+ }
+ // NOTE: canonicalPath requires the path to exist. Do not move this above the creation block!
+ m_instDir = QDir(instDir).canonicalPath();
+ m_watcher = new QFileSystemWatcher(this);
+ connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &FolderInstanceProvider::instanceDirContentsChanged);
+ m_watcher->addPath(m_instDir);
}
QList< InstanceId > FolderInstanceProvider::discoverInstances()
{
- QList<InstanceId> out;
- QDirIterator iter(m_instDir, QDir::Dirs | QDir::NoDot | QDir::NoDotDot | QDir::Readable | QDir::Hidden, QDirIterator::FollowSymlinks);
- while (iter.hasNext())
- {
- QString subDir = iter.next();
- QFileInfo dirInfo(subDir);
- if (!QFileInfo(FS::PathCombine(subDir, "instance.cfg")).exists())
- continue;
- // if it is a symlink, ignore it if it goes to the instance folder
- if(dirInfo.isSymLink())
- {
- QFileInfo targetInfo(dirInfo.symLinkTarget());
- QFileInfo instDirInfo(m_instDir);
- if(targetInfo.canonicalPath() == instDirInfo.canonicalFilePath())
- {
- qDebug() << "Ignoring symlink" << subDir << "that leads into the instances folder";
- continue;
- }
- }
- auto id = dirInfo.fileName();
- out.append(id);
- qDebug() << "Found instance ID" << id;
- }
- return out;
+ QList<InstanceId> out;
+ QDirIterator iter(m_instDir, QDir::Dirs | QDir::NoDot | QDir::NoDotDot | QDir::Readable | QDir::Hidden, QDirIterator::FollowSymlinks);
+ while (iter.hasNext())
+ {
+ QString subDir = iter.next();
+ QFileInfo dirInfo(subDir);
+ if (!QFileInfo(FS::PathCombine(subDir, "instance.cfg")).exists())
+ continue;
+ // if it is a symlink, ignore it if it goes to the instance folder
+ if(dirInfo.isSymLink())
+ {
+ QFileInfo targetInfo(dirInfo.symLinkTarget());
+ QFileInfo instDirInfo(m_instDir);
+ if(targetInfo.canonicalPath() == instDirInfo.canonicalFilePath())
+ {
+ qDebug() << "Ignoring symlink" << subDir << "that leads into the instances folder";
+ continue;
+ }
+ }
+ auto id = dirInfo.fileName();
+ out.append(id);
+ qDebug() << "Found instance ID" << id;
+ }
+ return out;
}
InstancePtr FolderInstanceProvider::loadInstance(const InstanceId& id)
{
- if(!m_groupsLoaded)
- {
- loadGroupList();
- }
-
- auto instanceRoot = FS::PathCombine(m_instDir, id);
- auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instanceRoot, "instance.cfg"));
- InstancePtr inst;
-
- instanceSettings->registerSetting("InstanceType", "Legacy");
-
- QString inst_type = instanceSettings->get("InstanceType").toString();
-
- if (inst_type == "OneSix" || inst_type == "Nostalgia")
- {
- inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
- }
- else if (inst_type == "Legacy")
- {
- inst.reset(new LegacyInstance(m_globalSettings, instanceSettings, instanceRoot));
- }
- else
- {
- inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot));
- }
- inst->init();
- inst->setProvider(this);
- auto iter = groupMap.find(id);
- if (iter != groupMap.end())
- {
- inst->setGroupInitial((*iter));
- }
- connect(inst.get(), &BaseInstance::groupChanged, this, &FolderInstanceProvider::groupChanged);
- qDebug() << "Loaded instance " << inst->name() << " from " << inst->instanceRoot();
- return inst;
+ if(!m_groupsLoaded)
+ {
+ loadGroupList();
+ }
+
+ auto instanceRoot = FS::PathCombine(m_instDir, id);
+ auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instanceRoot, "instance.cfg"));
+ InstancePtr inst;
+
+ instanceSettings->registerSetting("InstanceType", "Legacy");
+
+ QString inst_type = instanceSettings->get("InstanceType").toString();
+
+ if (inst_type == "OneSix" || inst_type == "Nostalgia")
+ {
+ inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
+ }
+ else if (inst_type == "Legacy")
+ {
+ inst.reset(new LegacyInstance(m_globalSettings, instanceSettings, instanceRoot));
+ }
+ else
+ {
+ inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot));
+ }
+ inst->init();
+ inst->setProvider(this);
+ auto iter = groupMap.find(id);
+ if (iter != groupMap.end())
+ {
+ inst->setGroupInitial((*iter));
+ }
+ connect(inst.get(), &BaseInstance::groupChanged, this, &FolderInstanceProvider::groupChanged);
+ qDebug() << "Loaded instance " << inst->name() << " from " << inst->instanceRoot();
+ return inst;
}
void FolderInstanceProvider::saveGroupList()
{
- WatchLock foo(m_watcher, m_instDir);
- QString groupFileName = m_instDir + "/instgroups.json";
- QMap<QString, QSet<QString>> reverseGroupMap;
- for (auto iter = groupMap.begin(); iter != groupMap.end(); iter++)
- {
- QString id = iter.key();
- QString group = iter.value();
- if (group.isEmpty())
- continue;
-
- if (!reverseGroupMap.count(group))
- {
- QSet<QString> set;
- set.insert(id);
- reverseGroupMap[group] = set;
- }
- else
- {
- QSet<QString> &set = reverseGroupMap[group];
- set.insert(id);
- }
- }
- QJsonObject toplevel;
- toplevel.insert("formatVersion", QJsonValue(QString("1")));
- QJsonObject groupsArr;
- for (auto iter = reverseGroupMap.begin(); iter != reverseGroupMap.end(); iter++)
- {
- auto list = iter.value();
- auto name = iter.key();
- QJsonObject groupObj;
- QJsonArray instanceArr;
- groupObj.insert("hidden", QJsonValue(QString("false")));
- for (auto item : list)
- {
- instanceArr.append(QJsonValue(item));
- }
- groupObj.insert("instances", instanceArr);
- groupsArr.insert(name, groupObj);
- }
- toplevel.insert("groups", groupsArr);
- QJsonDocument doc(toplevel);
- try
- {
- FS::write(groupFileName, doc.toJson());
- }
- catch (const FS::FileSystemException &e)
- {
- qCritical() << "Failed to write instance group file :" << e.cause();
- }
+ WatchLock foo(m_watcher, m_instDir);
+ QString groupFileName = m_instDir + "/instgroups.json";
+ QMap<QString, QSet<QString>> reverseGroupMap;
+ for (auto iter = groupMap.begin(); iter != groupMap.end(); iter++)
+ {
+ QString id = iter.key();
+ QString group = iter.value();
+ if (group.isEmpty())
+ continue;
+
+ if (!reverseGroupMap.count(group))
+ {
+ QSet<QString> set;
+ set.insert(id);
+ reverseGroupMap[group] = set;
+ }
+ else
+ {
+ QSet<QString> &set = reverseGroupMap[group];
+ set.insert(id);
+ }
+ }
+ QJsonObject toplevel;
+ toplevel.insert("formatVersion", QJsonValue(QString("1")));
+ QJsonObject groupsArr;
+ for (auto iter = reverseGroupMap.begin(); iter != reverseGroupMap.end(); iter++)
+ {
+ auto list = iter.value();
+ auto name = iter.key();
+ QJsonObject groupObj;
+ QJsonArray instanceArr;
+ groupObj.insert("hidden", QJsonValue(QString("false")));
+ for (auto item : list)
+ {
+ instanceArr.append(QJsonValue(item));
+ }
+ groupObj.insert("instances", instanceArr);
+ groupsArr.insert(name, groupObj);
+ }
+ toplevel.insert("groups", groupsArr);
+ QJsonDocument doc(toplevel);
+ try
+ {
+ FS::write(groupFileName, doc.toJson());
+ }
+ catch (const FS::FileSystemException &e)
+ {
+ qCritical() << "Failed to write instance group file :" << e.cause();
+ }
}
void FolderInstanceProvider::loadGroupList()
{
- QSet<QString> groupSet;
-
- QString groupFileName = m_instDir + "/instgroups.json";
-
- // if there's no group file, fail
- if (!QFileInfo(groupFileName).exists())
- return;
-
- QByteArray jsonData;
- try
- {
- jsonData = FS::read(groupFileName);
- }
- catch (const FS::FileSystemException &e)
- {
- qCritical() << "Failed to read instance group file :" << e.cause();
- return;
- }
-
- QJsonParseError error;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &error);
-
- // if the json was bad, fail
- if (error.error != QJsonParseError::NoError)
- {
- qCritical() << QString("Failed to parse instance group file: %1 at offset %2")
- .arg(error.errorString(), QString::number(error.offset))
- .toUtf8();
- return;
- }
-
- // if the root of the json wasn't an object, fail
- if (!jsonDoc.isObject())
- {
- qWarning() << "Invalid group file. Root entry should be an object.";
- return;
- }
-
- QJsonObject rootObj = jsonDoc.object();
-
- // Make sure the format version matches, otherwise fail.
- if (rootObj.value("formatVersion").toVariant().toInt() != GROUP_FILE_FORMAT_VERSION)
- return;
-
- // Get the groups. if it's not an object, fail
- if (!rootObj.value("groups").isObject())
- {
- qWarning() << "Invalid group list JSON: 'groups' should be an object.";
- return;
- }
-
- groupMap.clear();
-
- // Iterate through all the groups.
- QJsonObject groupMapping = rootObj.value("groups").toObject();
- for (QJsonObject::iterator iter = groupMapping.begin(); iter != groupMapping.end(); iter++)
- {
- QString groupName = iter.key();
-
- // If not an object, complain and skip to the next one.
- if (!iter.value().isObject())
- {
- qWarning() << QString("Group '%1' in the group list should "
- "be an object.")
- .arg(groupName)
- .toUtf8();
- continue;
- }
-
- QJsonObject groupObj = iter.value().toObject();
- if (!groupObj.value("instances").isArray())
- {
- qWarning() << QString("Group '%1' in the group list is invalid. "
- "It should contain an array "
- "called 'instances'.")
- .arg(groupName)
- .toUtf8();
- continue;
- }
-
- // keep a list/set of groups for choosing
- groupSet.insert(groupName);
-
- // Iterate through the list of instances in the group.
- QJsonArray instancesArray = groupObj.value("instances").toArray();
-
- for (QJsonArray::iterator iter2 = instancesArray.begin(); iter2 != instancesArray.end();
- iter2++)
- {
- groupMap[(*iter2).toString()] = groupName;
- }
- }
- m_groupsLoaded = true;
- emit groupsChanged(groupSet);
+ QSet<QString> groupSet;
+
+ QString groupFileName = m_instDir + "/instgroups.json";
+
+ // if there's no group file, fail
+ if (!QFileInfo(groupFileName).exists())
+ return;
+
+ QByteArray jsonData;
+ try
+ {
+ jsonData = FS::read(groupFileName);
+ }
+ catch (const FS::FileSystemException &e)
+ {
+ qCritical() << "Failed to read instance group file :" << e.cause();
+ return;
+ }
+
+ QJsonParseError error;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &error);
+
+ // if the json was bad, fail
+ if (error.error != QJsonParseError::NoError)
+ {
+ qCritical() << QString("Failed to parse instance group file: %1 at offset %2")
+ .arg(error.errorString(), QString::number(error.offset))
+ .toUtf8();
+ return;
+ }
+
+ // if the root of the json wasn't an object, fail
+ if (!jsonDoc.isObject())
+ {
+ qWarning() << "Invalid group file. Root entry should be an object.";
+ return;
+ }
+
+ QJsonObject rootObj = jsonDoc.object();
+
+ // Make sure the format version matches, otherwise fail.
+ if (rootObj.value("formatVersion").toVariant().toInt() != GROUP_FILE_FORMAT_VERSION)
+ return;
+
+ // Get the groups. if it's not an object, fail
+ if (!rootObj.value("groups").isObject())
+ {
+ qWarning() << "Invalid group list JSON: 'groups' should be an object.";
+ return;
+ }
+
+ groupMap.clear();
+
+ // Iterate through all the groups.
+ QJsonObject groupMapping = rootObj.value("groups").toObject();
+ for (QJsonObject::iterator iter = groupMapping.begin(); iter != groupMapping.end(); iter++)
+ {
+ QString groupName = iter.key();
+
+ // If not an object, complain and skip to the next one.
+ if (!iter.value().isObject())
+ {
+ qWarning() << QString("Group '%1' in the group list should "
+ "be an object.")
+ .arg(groupName)
+ .toUtf8();
+ continue;
+ }
+
+ QJsonObject groupObj = iter.value().toObject();
+ if (!groupObj.value("instances").isArray())
+ {
+ qWarning() << QString("Group '%1' in the group list is invalid. "
+ "It should contain an array "
+ "called 'instances'.")
+ .arg(groupName)
+ .toUtf8();
+ continue;
+ }
+
+ // keep a list/set of groups for choosing
+ groupSet.insert(groupName);
+
+ // Iterate through the list of instances in the group.
+ QJsonArray instancesArray = groupObj.value("instances").toArray();
+
+ for (QJsonArray::iterator iter2 = instancesArray.begin(); iter2 != instancesArray.end();
+ iter2++)
+ {
+ groupMap[(*iter2).toString()] = groupName;
+ }
+ }
+ m_groupsLoaded = true;
+ emit groupsChanged(groupSet);
}
void FolderInstanceProvider::groupChanged()
{
- // save the groups. save all of them.
- auto instance = (BaseInstance *) QObject::sender();
- auto id = instance->id();
- groupMap[id] = instance->group();
- emit groupsChanged({instance->group()});
- saveGroupList();
+ // save the groups. save all of them.
+ auto instance = (BaseInstance *) QObject::sender();
+ auto id = instance->id();
+ groupMap[id] = instance->group();
+ emit groupsChanged({instance->group()});
+ saveGroupList();
}
void FolderInstanceProvider::instanceDirContentsChanged(const QString& path)
{
- Q_UNUSED(path);
- emit instancesChanged();
+ Q_UNUSED(path);
+ emit instancesChanged();
}
void FolderInstanceProvider::on_InstFolderChanged(const Setting &setting, QVariant value)
{
- QString newInstDir = QDir(value.toString()).canonicalPath();
- if(newInstDir != m_instDir)
- {
- if(m_groupsLoaded)
- {
- saveGroupList();
- }
- m_instDir = newInstDir;
- m_groupsLoaded = false;
- emit instancesChanged();
- }
+ QString newInstDir = QDir(value.toString()).canonicalPath();
+ if(newInstDir != m_instDir)
+ {
+ if(m_groupsLoaded)
+ {
+ saveGroupList();
+ }
+ m_instDir = newInstDir;
+ m_groupsLoaded = false;
+ emit instancesChanged();
+ }
}
template <typename T>
static void clamp(T& current, T min, T max)
{
- if (current < min)
- {
- current = min;
- }
- else if(current > max)
- {
- current = max;
- }
+ if (current < min)
+ {
+ current = min;
+ }
+ else if(current > max)
+ {
+ current = max;
+ }
}
// List of numbers from min to max. Next is exponent times bigger than previous.
class ExponentialSeries
{
public:
- ExponentialSeries(unsigned min, unsigned max, unsigned exponent = 2)
- {
- m_current = m_min = min;
- m_max = max;
- m_exponent = exponent;
- }
- void reset()
- {
- m_current = m_min;
- }
- unsigned operator()()
- {
- unsigned retval = m_current;
- m_current *= m_exponent;
- clamp(m_current, m_min, m_max);
- return retval;
- }
- unsigned m_current;
- unsigned m_min;
- unsigned m_max;
- unsigned m_exponent;
+ ExponentialSeries(unsigned min, unsigned max, unsigned exponent = 2)
+ {
+ m_current = m_min = min;
+ m_max = max;
+ m_exponent = exponent;
+ }
+ void reset()
+ {
+ m_current = m_min;
+ }
+ unsigned operator()()
+ {
+ unsigned retval = m_current;
+ m_current *= m_exponent;
+ clamp(m_current, m_min, m_max);
+ return retval;
+ }
+ unsigned m_current;
+ unsigned m_min;
+ unsigned m_max;
+ unsigned m_exponent;
};
/*
@@ -344,121 +344,121 @@ public:
class FolderInstanceStaging : public Task
{
Q_OBJECT
- const unsigned minBackoff = 1;
- const unsigned maxBackoff = 16;
+ const unsigned minBackoff = 1;
+ const unsigned maxBackoff = 16;
public:
- FolderInstanceStaging (
- FolderInstanceProvider * parent,
- Task * child,
- const QString & stagingPath,
- const QString& instanceName,
- const QString& groupName )
- : backoff(minBackoff, maxBackoff)
- {
- m_parent = parent;
- m_child.reset(child);
- connect(child, &Task::succeeded, this, &FolderInstanceStaging::childSucceded);
- connect(child, &Task::failed, this, &FolderInstanceStaging::childFailed);
- connect(child, &Task::status, this, &FolderInstanceStaging::setStatus);
- connect(child, &Task::progress, this, &FolderInstanceStaging::setProgress);
- m_instanceName = instanceName;
- m_groupName = groupName;
- m_stagingPath = stagingPath;
- m_backoffTimer.setSingleShot(true);
- connect(&m_backoffTimer, &QTimer::timeout, this, &FolderInstanceStaging::childSucceded);
- }
-
- virtual ~FolderInstanceStaging() {};
+ FolderInstanceStaging (
+ FolderInstanceProvider * parent,
+ Task * child,
+ const QString & stagingPath,
+ const QString& instanceName,
+ const QString& groupName )
+ : backoff(minBackoff, maxBackoff)
+ {
+ m_parent = parent;
+ m_child.reset(child);
+ connect(child, &Task::succeeded, this, &FolderInstanceStaging::childSucceded);
+ connect(child, &Task::failed, this, &FolderInstanceStaging::childFailed);
+ connect(child, &Task::status, this, &FolderInstanceStaging::setStatus);
+ connect(child, &Task::progress, this, &FolderInstanceStaging::setProgress);
+ m_instanceName = instanceName;
+ m_groupName = groupName;
+ m_stagingPath = stagingPath;
+ m_backoffTimer.setSingleShot(true);
+ connect(&m_backoffTimer, &QTimer::timeout, this, &FolderInstanceStaging::childSucceded);
+ }
+
+ virtual ~FolderInstanceStaging() {};
protected:
- virtual void executeTask() override
- {
- m_child->start();
- }
- QStringList warnings() const override
- {
- return m_child->warnings();
- }
+ virtual void executeTask() override
+ {
+ m_child->start();
+ }
+ QStringList warnings() const override
+ {
+ return m_child->warnings();
+ }
private slots:
- void childSucceded()
- {
- unsigned sleepTime = backoff();
- if(m_parent->commitStagedInstance(m_stagingPath, m_instanceName, m_groupName))
- {
- emitSucceeded();
- return;
- }
- // we actually failed, retry?
- if(sleepTime == maxBackoff)
- {
- emitFailed(tr("Failed to commit instance, even after multiple retries. It is being blocked by something."));
- return;
- }
- qDebug() << "Failed to commit instance" << m_instanceName << "Initiating backoff:" << sleepTime;
- m_backoffTimer.start(sleepTime * 500);
- }
- void childFailed(const QString & reason)
- {
- m_parent->destroyStagingPath(m_stagingPath);
- emitFailed(reason);
- }
+ void childSucceded()
+ {
+ unsigned sleepTime = backoff();
+ if(m_parent->commitStagedInstance(m_stagingPath, m_instanceName, m_groupName))
+ {
+ emitSucceeded();
+ return;
+ }
+ // we actually failed, retry?
+ if(sleepTime == maxBackoff)
+ {
+ emitFailed(tr("Failed to commit instance, even after multiple retries. It is being blocked by something."));
+ return;
+ }
+ qDebug() << "Failed to commit instance" << m_instanceName << "Initiating backoff:" << sleepTime;
+ m_backoffTimer.start(sleepTime * 500);
+ }
+ void childFailed(const QString & reason)
+ {
+ m_parent->destroyStagingPath(m_stagingPath);
+ emitFailed(reason);
+ }
private:
- ExponentialSeries backoff;
- QString m_stagingPath;
- FolderInstanceProvider * m_parent;
- unique_qobject_ptr<Task> m_child;
- QString m_instanceName;
- QString m_groupName;
- QTimer m_backoffTimer;
+ ExponentialSeries backoff;
+ QString m_stagingPath;
+ FolderInstanceProvider * m_parent;
+ unique_qobject_ptr<Task> m_child;
+ QString m_instanceName;
+ QString m_groupName;
+ QTimer m_backoffTimer;
};
#include "InstanceTask.h"
Task * FolderInstanceProvider::wrapInstanceTask(InstanceTask * task)
{
- auto stagingPath = getStagedInstancePath();
- task->setStagingPath(stagingPath);
- task->setParentSettings(m_globalSettings);
- return new FolderInstanceStaging(this, task, stagingPath, task->name(), task->group());
+ auto stagingPath = getStagedInstancePath();
+ task->setStagingPath(stagingPath);
+ task->setParentSettings(m_globalSettings);
+ return new FolderInstanceStaging(this, task, stagingPath, task->name(), task->group());
}
QString FolderInstanceProvider::getStagedInstancePath()
{
- QString key = QUuid::createUuid().toString();
- QString relPath = FS::PathCombine("_MMC_TEMP/" , key);
- QDir rootPath(m_instDir);
- auto path = FS::PathCombine(m_instDir, relPath);
- if(!rootPath.mkpath(relPath))
- {
- return QString();
- }
- return path;
+ QString key = QUuid::createUuid().toString();
+ QString relPath = FS::PathCombine("_MMC_TEMP/" , key);
+ QDir rootPath(m_instDir);
+ auto path = FS::PathCombine(m_instDir, relPath);
+ if(!rootPath.mkpath(relPath))
+ {
+ return QString();
+ }
+ return path;
}
bool FolderInstanceProvider::commitStagedInstance(const QString& path, const QString& instanceName, const QString& groupName)
{
- QDir dir;
- QString instID = FS::DirNameFromString(instanceName, m_instDir);
- {
- WatchLock lock(m_watcher, m_instDir);
- QString destination = FS::PathCombine(m_instDir, instID);
- if(!dir.rename(path, destination))
- {
- qWarning() << "Failed to move" << path << "to" << destination;
- return false;
- }
- groupMap[instID] = groupName;
- emit groupsChanged({groupName});
- emit instancesChanged();
- }
- saveGroupList();
- return true;
+ QDir dir;
+ QString instID = FS::DirNameFromString(instanceName, m_instDir);
+ {
+ WatchLock lock(m_watcher, m_instDir);
+ QString destination = FS::PathCombine(m_instDir, instID);
+ if(!dir.rename(path, destination))
+ {
+ qWarning() << "Failed to move" << path << "to" << destination;
+ return false;
+ }
+ groupMap[instID] = groupName;
+ emit groupsChanged({groupName});
+ emit instancesChanged();
+ }
+ saveGroupList();
+ return true;
}
bool FolderInstanceProvider::destroyStagingPath(const QString& keyPath)
{
- return FS::deletePath(keyPath);
+ return FS::deletePath(keyPath);
}
#include "FolderInstanceProvider.moc"
diff --git a/api/logic/FolderInstanceProvider.h b/api/logic/FolderInstanceProvider.h
index e13dcfe9..fc14ba7a 100644
--- a/api/logic/FolderInstanceProvider.h
+++ b/api/logic/FolderInstanceProvider.h
@@ -8,68 +8,68 @@ class InstanceTask;
class MULTIMC_LOGIC_EXPORT FolderInstanceProvider : public BaseInstanceProvider
{
- Q_OBJECT
+ Q_OBJECT
public:
- FolderInstanceProvider(SettingsObjectPtr settings, const QString & instDir);
+ FolderInstanceProvider(SettingsObjectPtr settings, const QString & instDir);
public:
- /// used by InstanceList to @return a list of plausible IDs to probe for
- QList<InstanceId> discoverInstances() override;
+ /// used by InstanceList to @return a list of plausible IDs to probe for
+ QList<InstanceId> discoverInstances() override;
- /// used by InstanceList to (re)load an instance with the given @id.
- InstancePtr loadInstance(const InstanceId& id) override;
+ /// used by InstanceList to (re)load an instance with the given @id.
+ InstancePtr loadInstance(const InstanceId& id) override;
- /*
- // create instance in this provider
- Task * creationTask(BaseVersionPtr version, const QString &instName, const QString &instGroup, const QString &instIcon);
+ /*
+ // create instance in this provider
+ Task * creationTask(BaseVersionPtr version, const QString &instName, const QString &instGroup, const QString &instIcon);
- // copy instance to this provider
- Task * copyTask(const InstancePtr &oldInstance, const QString& instName, const QString& instGroup, const QString& instIcon, bool copySaves);
+ // copy instance to this provider
+ Task * copyTask(const InstancePtr &oldInstance, const QString& instName, const QString& instGroup, const QString& instIcon, bool copySaves);
- // import zipped instance into this provider
- Task * zipImportTask(const QUrl sourceUrl, const QString &instName, const QString &instGroup, const QString &instIcon);
+ // import zipped instance into this provider
+ Task * zipImportTask(const QUrl sourceUrl, const QString &instName, const QString &instGroup, const QString &instIcon);
- //create FtbInstance
- Task * ftbCreationTask(FtbPackDownloader *downloader, const QString &instName, const QString &instGroup, const QString &instIcon);
+ //create FtbInstance
+ Task * ftbCreationTask(FtbPackDownloader *downloader, const QString &instName, const QString &instGroup, const QString &instIcon);
- // migrate an instance to the current format
- Task * legacyUpgradeTask(const InstancePtr& oldInstance);
+ // migrate an instance to the current format
+ Task * legacyUpgradeTask(const InstancePtr& oldInstance);
*/
- // Wrap an instance creation task in some more task machinery and make it ready to be used
- Task * wrapInstanceTask(InstanceTask * task);
-
- /**
- * Create a new empty staging area for instance creation and @return a path/key top commit it later.
- * Used by instance manipulation tasks.
- */
- QString getStagedInstancePath() override;
- /**
- * Commit the staging area given by @keyPath to the provider - used when creation succeeds.
- * Used by instance manipulation tasks.
- */
- bool commitStagedInstance(const QString & keyPath, const QString& instanceName, const QString & groupName) override;
- /**
- * Destroy a previously created staging area given by @keyPath - used when creation fails.
- * Used by instance manipulation tasks.
- */
- bool destroyStagingPath(const QString & keyPath) override;
+ // Wrap an instance creation task in some more task machinery and make it ready to be used
+ Task * wrapInstanceTask(InstanceTask * task);
+
+ /**
+ * Create a new empty staging area for instance creation and @return a path/key top commit it later.
+ * Used by instance manipulation tasks.
+ */
+ QString getStagedInstancePath() override;
+ /**
+ * Commit the staging area given by @keyPath to the provider - used when creation succeeds.
+ * Used by instance manipulation tasks.
+ */
+ bool commitStagedInstance(const QString & keyPath, const QString& instanceName, const QString & groupName) override;
+ /**
+ * Destroy a previously created staging area given by @keyPath - used when creation fails.
+ * Used by instance manipulation tasks.
+ */
+ bool destroyStagingPath(const QString & keyPath) override;
public slots:
- void on_InstFolderChanged(const Setting &setting, QVariant value);
+ void on_InstFolderChanged(const Setting &setting, QVariant value);
private slots:
- void instanceDirContentsChanged(const QString &path);
- void groupChanged();
+ void instanceDirContentsChanged(const QString &path);
+ void groupChanged();
private: /* methods */
- void loadGroupList() override;
- void saveGroupList() override;
+ void loadGroupList() override;
+ void saveGroupList() override;
private: /* data */
- QString m_instDir;
- QFileSystemWatcher * m_watcher;
- QMap<QString, QString> groupMap;
- bool m_groupsLoaded = false;
+ QString m_instDir;
+ QFileSystemWatcher * m_watcher;
+ QMap<QString, QString> groupMap;
+ bool m_groupsLoaded = false;
};
diff --git a/api/logic/GZip.cpp b/api/logic/GZip.cpp
index 38605df6..0368c32d 100644
--- a/api/logic/GZip.cpp
+++ b/api/logic/GZip.cpp
@@ -4,112 +4,112 @@
bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedBytes)
{
- if (compressedBytes.size() == 0)
- {
- uncompressedBytes = compressedBytes;
- return true;
- }
-
- unsigned uncompLength = compressedBytes.size();
- uncompressedBytes.clear();
- uncompressedBytes.resize(uncompLength);
-
- z_stream strm;
- memset(&strm, 0, sizeof(strm));
- strm.next_in = (Bytef *)compressedBytes.data();
- strm.avail_in = compressedBytes.size();
-
- bool done = false;
-
- if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK)
- {
- return false;
- }
-
- int err = Z_OK;
-
- while (!done)
- {
- // If our output buffer is too small
- if (strm.total_out >= uncompLength)
- {
- uncompressedBytes.resize(uncompLength * 2);
- uncompLength *= 2;
- }
-
- strm.next_out = (Bytef *)(uncompressedBytes.data() + strm.total_out);
- strm.avail_out = uncompLength - strm.total_out;
-
- // Inflate another chunk.
- err = inflate(&strm, Z_SYNC_FLUSH);
- if (err == Z_STREAM_END)
- done = true;
- else if (err != Z_OK)
- {
- break;
- }
- }
-
- if (inflateEnd(&strm) != Z_OK || !done)
- {
- return false;
- }
-
- uncompressedBytes.resize(strm.total_out);
- return true;
+ if (compressedBytes.size() == 0)
+ {
+ uncompressedBytes = compressedBytes;
+ return true;
+ }
+
+ unsigned uncompLength = compressedBytes.size();
+ uncompressedBytes.clear();
+ uncompressedBytes.resize(uncompLength);
+
+ z_stream strm;
+ memset(&strm, 0, sizeof(strm));
+ strm.next_in = (Bytef *)compressedBytes.data();
+ strm.avail_in = compressedBytes.size();
+
+ bool done = false;
+
+ if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK)
+ {
+ return false;
+ }
+
+ int err = Z_OK;
+
+ while (!done)
+ {
+ // If our output buffer is too small
+ if (strm.total_out >= uncompLength)
+ {
+ uncompressedBytes.resize(uncompLength * 2);
+ uncompLength *= 2;
+ }
+
+ strm.next_out = (Bytef *)(uncompressedBytes.data() + strm.total_out);
+ strm.avail_out = uncompLength - strm.total_out;
+
+ // Inflate another chunk.
+ err = inflate(&strm, Z_SYNC_FLUSH);
+ if (err == Z_STREAM_END)
+ done = true;
+ else if (err != Z_OK)
+ {
+ break;
+ }
+ }
+
+ if (inflateEnd(&strm) != Z_OK || !done)
+ {
+ return false;
+ }
+
+ uncompressedBytes.resize(strm.total_out);
+ return true;
}
bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
{
- if (uncompressedBytes.size() == 0)
- {
- compressedBytes = uncompressedBytes;
- return true;
- }
-
- unsigned compLength = std::min(uncompressedBytes.size(), 16);
- compressedBytes.clear();
- compressedBytes.resize(compLength);
-
- z_stream zs;
- memset(&zs, 0, sizeof(zs));
-
- if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK)
- {
- return false;
- }
-
- zs.next_in = (Bytef*)uncompressedBytes.data();
- zs.avail_in = uncompressedBytes.size();
-
- int ret;
- compressedBytes.resize(uncompressedBytes.size());
-
- unsigned offset = 0;
- unsigned temp = 0;
- do
- {
- auto remaining = compressedBytes.size() - offset;
- if(remaining < 1)
- {
- compressedBytes.resize(compressedBytes.size() * 2);
- }
- zs.next_out = (Bytef *) (compressedBytes.data() + offset);
- temp = zs.avail_out = compressedBytes.size() - offset;
- ret = deflate(&zs, Z_FINISH);
- offset += temp - zs.avail_out;
- } while (ret == Z_OK);
-
- compressedBytes.resize(offset);
-
- if (deflateEnd(&zs) != Z_OK)
- {
- return false;
- }
-
- if (ret != Z_STREAM_END)
- {
- return false;
- }
- return true;
+ if (uncompressedBytes.size() == 0)
+ {
+ compressedBytes = uncompressedBytes;
+ return true;
+ }
+
+ unsigned compLength = std::min(uncompressedBytes.size(), 16);
+ compressedBytes.clear();
+ compressedBytes.resize(compLength);
+
+ z_stream zs;
+ memset(&zs, 0, sizeof(zs));
+
+ if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ return false;
+ }
+
+ zs.next_in = (Bytef*)uncompressedBytes.data();
+ zs.avail_in = uncompressedBytes.size();
+
+ int ret;
+ compressedBytes.resize(uncompressedBytes.size());
+
+ unsigned offset = 0;
+ unsigned temp = 0;
+ do
+ {
+ auto remaining = compressedBytes.size() - offset;
+ if(remaining < 1)
+ {
+ compressedBytes.resize(compressedBytes.size() * 2);
+ }
+ zs.next_out = (Bytef *) (compressedBytes.data() + offset);
+ temp = zs.avail_out = compressedBytes.size() - offset;
+ ret = deflate(&zs, Z_FINISH);
+ offset += temp - zs.avail_out;
+ } while (ret == Z_OK);
+
+ compressedBytes.resize(offset);
+
+ if (deflateEnd(&zs) != Z_OK)
+ {
+ return false;
+ }
+
+ if (ret != Z_STREAM_END)
+ {
+ return false;
+ }
+ return true;
} \ No newline at end of file
diff --git a/api/logic/GZip.h b/api/logic/GZip.h
index 6993a222..c7eddbb3 100644
--- a/api/logic/GZip.h
+++ b/api/logic/GZip.h
@@ -6,7 +6,7 @@
class MULTIMC_LOGIC_EXPORT GZip
{
public:
- static bool unzip(const QByteArray &compressedBytes, QByteArray &uncompressedBytes);
- static bool zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes);
+ static bool unzip(const QByteArray &compressedBytes, QByteArray &uncompressedBytes);
+ static bool zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes);
};
diff --git a/api/logic/GZip_test.cpp b/api/logic/GZip_test.cpp
index f4c9214c..3f4d181c 100644
--- a/api/logic/GZip_test.cpp
+++ b/api/logic/GZip_test.cpp
@@ -6,50 +6,50 @@
void fib(int &prev, int &cur)
{
- auto ret = prev + cur;
- prev = cur;
- cur = ret;
+ auto ret = prev + cur;
+ prev = cur;
+ cur = ret;
}
class GZipTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- void test_Through()
- {
- // test up to 10 MB
- static const int size = 10 * 1024 * 1024;
- QByteArray random;
- QByteArray compressed;
- QByteArray decompressed;
- std::default_random_engine eng((std::random_device())());
- std::uniform_int_distribution<uint8_t> idis(0, std::numeric_limits<uint8_t>::max());
-
- // initialize random buffer
- for(int i = 0; i < size; i++)
- {
- random.append((char)idis(eng));
- }
-
- // initialize fibonacci
- int prev = 1;
- int cur = 1;
-
- // test if fibonacci long random buffers pass through GZip
- do
- {
- QByteArray copy = random;
- copy.resize(cur);
- compressed.clear();
- decompressed.clear();
- QVERIFY(GZip::zip(copy, compressed));
- QVERIFY(GZip::unzip(compressed, decompressed));
- QCOMPARE(decompressed, copy);
- fib(prev, cur);
- } while (cur < size);
- }
+ void test_Through()
+ {
+ // test up to 10 MB
+ static const int size = 10 * 1024 * 1024;
+ QByteArray random;
+ QByteArray compressed;
+ QByteArray decompressed;
+ std::default_random_engine eng((std::random_device())());
+ std::uniform_int_distribution<uint8_t> idis(0, std::numeric_limits<uint8_t>::max());
+
+ // initialize random buffer
+ for(int i = 0; i < size; i++)
+ {
+ random.append((char)idis(eng));
+ }
+
+ // initialize fibonacci
+ int prev = 1;
+ int cur = 1;
+
+ // test if fibonacci long random buffers pass through GZip
+ do
+ {
+ QByteArray copy = random;
+ copy.resize(cur);
+ compressed.clear();
+ decompressed.clear();
+ QVERIFY(GZip::zip(copy, compressed));
+ QVERIFY(GZip::unzip(compressed, decompressed));
+ QCOMPARE(decompressed, copy);
+ fib(prev, cur);
+ } while (cur < size);
+ }
};
QTEST_GUILESS_MAIN(GZipTest)
diff --git a/api/logic/InstanceCopyTask.cpp b/api/logic/InstanceCopyTask.cpp
index 62c22362..cb2deb29 100644
--- a/api/logic/InstanceCopyTask.cpp
+++ b/api/logic/InstanceCopyTask.cpp
@@ -8,50 +8,50 @@
InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, bool copySaves)
{
- m_origInstance = origInstance;
-
- if(!copySaves)
- {
- // FIXME: get this from the original instance type...
- auto matcherReal = new RegexpMatcher("[.]?minecraft/saves");
- matcherReal->caseSensitive(false);
- m_matcher.reset(matcherReal);
- }
+ m_origInstance = origInstance;
+
+ if(!copySaves)
+ {
+ // FIXME: get this from the original instance type...
+ auto matcherReal = new RegexpMatcher("[.]?minecraft/saves");
+ matcherReal->caseSensitive(false);
+ m_matcher.reset(matcherReal);
+ }
}
void InstanceCopyTask::executeTask()
{
- setStatus(tr("Copying instance %1").arg(m_origInstance->name()));
+ setStatus(tr("Copying instance %1").arg(m_origInstance->name()));
- FS::copy folderCopy(m_origInstance->instanceRoot(), m_stagingPath);
- folderCopy.followSymlinks(false).blacklist(m_matcher.get());
+ FS::copy folderCopy(m_origInstance->instanceRoot(), m_stagingPath);
+ folderCopy.followSymlinks(false).blacklist(m_matcher.get());
- m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), folderCopy);
- connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &InstanceCopyTask::copyFinished);
- connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &InstanceCopyTask::copyAborted);
- m_copyFutureWatcher.setFuture(m_copyFuture);
+ m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), folderCopy);
+ connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &InstanceCopyTask::copyFinished);
+ connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &InstanceCopyTask::copyAborted);
+ m_copyFutureWatcher.setFuture(m_copyFuture);
}
void InstanceCopyTask::copyFinished()
{
- auto successful = m_copyFuture.result();
- if(!successful)
- {
- emitFailed(tr("Instance folder copy failed."));
- return;
- }
- // FIXME: shouldn't this be able to report errors?
- auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg"));
- instanceSettings->registerSetting("InstanceType", "Legacy");
-
- InstancePtr inst(new NullInstance(m_globalSettings, instanceSettings, m_stagingPath));
- inst->setName(m_instName);
- inst->setIconKey(m_instIcon);
- emitSucceeded();
+ auto successful = m_copyFuture.result();
+ if(!successful)
+ {
+ emitFailed(tr("Instance folder copy failed."));
+ return;
+ }
+ // FIXME: shouldn't this be able to report errors?
+ auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg"));
+ instanceSettings->registerSetting("InstanceType", "Legacy");
+
+ InstancePtr inst(new NullInstance(m_globalSettings, instanceSettings, m_stagingPath));
+ inst->setName(m_instName);
+ inst->setIconKey(m_instIcon);
+ emitSucceeded();
}
void InstanceCopyTask::copyAborted()
{
- emitFailed(tr("Instance folder copy has been aborted."));
- return;
+ emitFailed(tr("Instance folder copy has been aborted."));
+ return;
}
diff --git a/api/logic/InstanceCopyTask.h b/api/logic/InstanceCopyTask.h
index a8dc9783..0a338f2f 100644
--- a/api/logic/InstanceCopyTask.h
+++ b/api/logic/InstanceCopyTask.h
@@ -15,19 +15,19 @@ class BaseInstanceProvider;
class MULTIMC_LOGIC_EXPORT InstanceCopyTask : public InstanceTask
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit InstanceCopyTask(InstancePtr origInstance, bool copySaves);
+ explicit InstanceCopyTask(InstancePtr origInstance, bool copySaves);
protected:
- //! Entry point for tasks.
- virtual void executeTask() override;
- void copyFinished();
- void copyAborted();
+ //! Entry point for tasks.
+ virtual void executeTask() override;
+ void copyFinished();
+ void copyAborted();
private: /* data */
- InstancePtr m_origInstance;
- QFuture<bool> m_copyFuture;
- QFutureWatcher<bool> m_copyFutureWatcher;
- std::unique_ptr<IPathMatcher> m_matcher;
+ InstancePtr m_origInstance;
+ QFuture<bool> m_copyFuture;
+ QFutureWatcher<bool> m_copyFutureWatcher;
+ std::unique_ptr<IPathMatcher> m_matcher;
};
diff --git a/api/logic/InstanceCreationTask.cpp b/api/logic/InstanceCreationTask.cpp
index 6dc2496c..7ac474ec 100644
--- a/api/logic/InstanceCreationTask.cpp
+++ b/api/logic/InstanceCreationTask.cpp
@@ -9,25 +9,25 @@
InstanceCreationTask::InstanceCreationTask(BaseVersionPtr version)
{
- m_version = version;
+ m_version = version;
}
void InstanceCreationTask::executeTask()
{
- setStatus(tr("Creating instance from version %1").arg(m_version->name()));
- {
- auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg"));
- instanceSettings->suspendSave();
- instanceSettings->registerSetting("InstanceType", "Legacy");
- instanceSettings->set("InstanceType", "OneSix");
- MinecraftInstance inst(m_globalSettings, instanceSettings, m_stagingPath);
- auto components = inst.getComponentList();
- components->buildingFromScratch();
- components->setComponentVersion("net.minecraft", m_version->descriptor(), true);
- inst.setName(m_instName);
- inst.setIconKey(m_instIcon);
- inst.init();
- instanceSettings->resumeSave();
- }
- emitSucceeded();
+ setStatus(tr("Creating instance from version %1").arg(m_version->name()));
+ {
+ auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg"));
+ instanceSettings->suspendSave();
+ instanceSettings->registerSetting("InstanceType", "Legacy");
+ instanceSettings->set("InstanceType", "OneSix");
+ MinecraftInstance inst(m_globalSettings, instanceSettings, m_stagingPath);
+ auto components = inst.getComponentList();
+ components->buildingFromScratch();
+ components->setComponentVersion("net.minecraft", m_version->descriptor(), true);
+ inst.setName(m_instName);
+ inst.setIconKey(m_instIcon);
+ inst.init();
+ instanceSettings->resumeSave();
+ }
+ emitSucceeded();
}
diff --git a/api/logic/InstanceCreationTask.h b/api/logic/InstanceCreationTask.h
index e06eacbb..154a854f 100644
--- a/api/logic/InstanceCreationTask.h
+++ b/api/logic/InstanceCreationTask.h
@@ -10,14 +10,14 @@
class MULTIMC_LOGIC_EXPORT InstanceCreationTask : public InstanceTask
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit InstanceCreationTask(BaseVersionPtr version);
+ explicit InstanceCreationTask(BaseVersionPtr version);
protected:
- //! Entry point for tasks.
- virtual void executeTask() override;
+ //! Entry point for tasks.
+ virtual void executeTask() override;
private: /* data */
- BaseVersionPtr m_version;
+ BaseVersionPtr m_version;
};
diff --git a/api/logic/InstanceImportTask.cpp b/api/logic/InstanceImportTask.cpp
index 45037908..f3e0858d 100644
--- a/api/logic/InstanceImportTask.cpp
+++ b/api/logic/InstanceImportTask.cpp
@@ -18,394 +18,394 @@
InstanceImportTask::InstanceImportTask(const QUrl sourceUrl)
{
- m_sourceUrl = sourceUrl;
+ m_sourceUrl = sourceUrl;
}
void InstanceImportTask::executeTask()
{
- InstancePtr newInstance;
+ InstancePtr newInstance;
- if (m_sourceUrl.isLocalFile())
- {
- m_archivePath = m_sourceUrl.toLocalFile();
- processZipPack();
- }
- else
- {
- setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString()));
- m_downloadRequired = true;
+ if (m_sourceUrl.isLocalFile())
+ {
+ m_archivePath = m_sourceUrl.toLocalFile();
+ processZipPack();
+ }
+ else
+ {
+ setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString()));
+ m_downloadRequired = true;
- const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path();
- auto entry = ENV.metacache()->resolveEntry("general", path);
- entry->setStale(true);
- m_filesNetJob.reset(new NetJob(tr("Modpack download")));
- m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry));
- m_archivePath = entry->getFullPath();
- auto job = m_filesNetJob.get();
- connect(job, &NetJob::succeeded, this, &InstanceImportTask::downloadSucceeded);
- connect(job, &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged);
- connect(job, &NetJob::failed, this, &InstanceImportTask::downloadFailed);
- m_filesNetJob->start();
- }
+ const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path();
+ auto entry = ENV.metacache()->resolveEntry("general", path);
+ entry->setStale(true);
+ m_filesNetJob.reset(new NetJob(tr("Modpack download")));
+ m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry));
+ m_archivePath = entry->getFullPath();
+ auto job = m_filesNetJob.get();
+ connect(job, &NetJob::succeeded, this, &InstanceImportTask::downloadSucceeded);
+ connect(job, &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged);
+ connect(job, &NetJob::failed, this, &InstanceImportTask::downloadFailed);
+ m_filesNetJob->start();
+ }
}
void InstanceImportTask::downloadSucceeded()
{
- processZipPack();
- m_filesNetJob.reset();
+ processZipPack();
+ m_filesNetJob.reset();
}
void InstanceImportTask::downloadFailed(QString reason)
{
- emitFailed(reason);
- m_filesNetJob.reset();
+ emitFailed(reason);
+ m_filesNetJob.reset();
}
void InstanceImportTask::downloadProgressChanged(qint64 current, qint64 total)
{
- setProgress(current / 2, total);
+ setProgress(current / 2, total);
}
void InstanceImportTask::processZipPack()
{
- setStatus(tr("Extracting modpack"));
- QDir extractDir(m_stagingPath);
- qDebug() << "Attempting to create instance from" << m_archivePath;
+ setStatus(tr("Extracting modpack"));
+ QDir extractDir(m_stagingPath);
+ qDebug() << "Attempting to create instance from" << m_archivePath;
- // open the zip and find relevant files in it
- m_packZip.reset(new QuaZip(m_archivePath));
- if (!m_packZip->open(QuaZip::mdUnzip))
- {
- emitFailed(tr("Unable to open supplied modpack zip file."));
- return;
- }
+ // open the zip and find relevant files in it
+ m_packZip.reset(new QuaZip(m_archivePath));
+ if (!m_packZip->open(QuaZip::mdUnzip))
+ {
+ emitFailed(tr("Unable to open supplied modpack zip file."));
+ return;
+ }
- QStringList blacklist = {"instance.cfg", "manifest.json"};
- QString mmcFound = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg");
- QString flameFound = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json");
- QString root;
- if(!mmcFound.isNull())
- {
- // process as MultiMC instance/pack
- qDebug() << "MultiMC:" << mmcFound;
- root = mmcFound;
- m_modpackType = ModpackType::MultiMC;
- }
- else if(!flameFound.isNull())
- {
- // process as Flame pack
- qDebug() << "Flame:" << flameFound;
- root = flameFound;
- m_modpackType = ModpackType::Flame;
- }
+ QStringList blacklist = {"instance.cfg", "manifest.json"};
+ QString mmcFound = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg");
+ QString flameFound = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json");
+ QString root;
+ if(!mmcFound.isNull())
+ {
+ // process as MultiMC instance/pack
+ qDebug() << "MultiMC:" << mmcFound;
+ root = mmcFound;
+ m_modpackType = ModpackType::MultiMC;
+ }
+ else if(!flameFound.isNull())
+ {
+ // process as Flame pack
+ qDebug() << "Flame:" << flameFound;
+ root = flameFound;
+ m_modpackType = ModpackType::Flame;
+ }
- if(m_modpackType == ModpackType::Unknown)
- {
- emitFailed(tr("Archive does not contain a recognized modpack type."));
- return;
- }
+ if(m_modpackType == ModpackType::Unknown)
+ {
+ emitFailed(tr("Archive does not contain a recognized modpack type."));
+ return;
+ }
- // make sure we extract just the pack
- m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), root, extractDir.absolutePath());
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &InstanceImportTask::extractFinished);
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &InstanceImportTask::extractAborted);
- m_extractFutureWatcher.setFuture(m_extractFuture);
+ // make sure we extract just the pack
+ m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), root, extractDir.absolutePath());
+ connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &InstanceImportTask::extractFinished);
+ connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &InstanceImportTask::extractAborted);
+ m_extractFutureWatcher.setFuture(m_extractFuture);
}
void InstanceImportTask::extractFinished()
{
- m_packZip.reset();
- if (m_extractFuture.result().isEmpty())
- {
- emitFailed(tr("Failed to extract modpack"));
- return;
- }
- QDir extractDir(m_stagingPath);
+ m_packZip.reset();
+ if (m_extractFuture.result().isEmpty())
+ {
+ emitFailed(tr("Failed to extract modpack"));
+ return;
+ }
+ QDir extractDir(m_stagingPath);
- qDebug() << "Fixing permissions for extracted pack files...";
- QDirIterator it(extractDir, QDirIterator::Subdirectories);
- while (it.hasNext())
- {
- auto filepath = it.next();
- QFileInfo file(filepath);
- auto permissions = QFile::permissions(filepath);
- auto origPermissions = permissions;
- if(file.isDir())
- {
- // Folder +rwx for current user
- permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser;
- }
- else
- {
- // File +rw for current user
- permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser;
- }
- if(origPermissions != permissions)
- {
- if(!QFile::setPermissions(filepath, permissions))
- {
- logWarning(tr("Could not fix permissions for %1").arg(filepath));
- }
- else
- {
- qDebug() << "Fixed" << filepath;
- }
- }
- }
+ qDebug() << "Fixing permissions for extracted pack files...";
+ QDirIterator it(extractDir, QDirIterator::Subdirectories);
+ while (it.hasNext())
+ {
+ auto filepath = it.next();
+ QFileInfo file(filepath);
+ auto permissions = QFile::permissions(filepath);
+ auto origPermissions = permissions;
+ if(file.isDir())
+ {
+ // Folder +rwx for current user
+ permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser;
+ }
+ else
+ {
+ // File +rw for current user
+ permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser;
+ }
+ if(origPermissions != permissions)
+ {
+ if(!QFile::setPermissions(filepath, permissions))
+ {
+ logWarning(tr("Could not fix permissions for %1").arg(filepath));
+ }
+ else
+ {
+ qDebug() << "Fixed" << filepath;
+ }
+ }
+ }
- switch(m_modpackType)
- {
- case ModpackType::Flame:
- processFlame();
- return;
- case ModpackType::MultiMC:
- processMultiMC();
- return;
- case ModpackType::Unknown:
- emitFailed(tr("Archive does not contain a recognized modpack type."));
- return;
- }
+ switch(m_modpackType)
+ {
+ case ModpackType::Flame:
+ processFlame();
+ return;
+ case ModpackType::MultiMC:
+ processMultiMC();
+ return;
+ case ModpackType::Unknown:
+ emitFailed(tr("Archive does not contain a recognized modpack type."));
+ return;
+ }
}
void InstanceImportTask::extractAborted()
{
- emitFailed(tr("Instance import has been aborted."));
- return;
+ emitFailed(tr("Instance import has been aborted."));
+ return;
}
void InstanceImportTask::processFlame()
{
- const static QMap<QString,QString> forgemap = {
- {"1.2.5", "3.4.9.171"},
- {"1.4.2", "6.0.1.355"},
- {"1.4.7", "6.6.2.534"},
- {"1.5.2", "7.8.1.737"}
- };
- Flame::Manifest pack;
- try
- {
- QString configPath = FS::PathCombine(m_stagingPath, "manifest.json");
- Flame::loadManifest(pack, configPath);
- QFile::remove(configPath);
- }
- catch (const JSONValidationError &e)
- {
- emitFailed(tr("Could not understand pack manifest:\n") + e.cause());
- return;
- }
- if(!pack.overrides.isEmpty())
- {
- QString overridePath = FS::PathCombine(m_stagingPath, pack.overrides);
- if (QFile::exists(overridePath))
- {
- QString mcPath = FS::PathCombine(m_stagingPath, "minecraft");
- if (!QFile::rename(overridePath, mcPath))
- {
- emitFailed(tr("Could not rename the overrides folder:\n") + pack.overrides);
- return;
- }
- }
- else
- {
- logWarning(tr("The specified overrides folder (%1) is missing. Maybe the modpack was already used before?").arg(pack.overrides));
- }
- }
+ const static QMap<QString,QString> forgemap = {
+ {"1.2.5", "3.4.9.171"},
+ {"1.4.2", "6.0.1.355"},
+ {"1.4.7", "6.6.2.534"},
+ {"1.5.2", "7.8.1.737"}
+ };
+ Flame::Manifest pack;
+ try
+ {
+ QString configPath = FS::PathCombine(m_stagingPath, "manifest.json");
+ Flame::loadManifest(pack, configPath);
+ QFile::remove(configPath);
+ }
+ catch (const JSONValidationError &e)
+ {
+ emitFailed(tr("Could not understand pack manifest:\n") + e.cause());
+ return;
+ }
+ if(!pack.overrides.isEmpty())
+ {
+ QString overridePath = FS::PathCombine(m_stagingPath, pack.overrides);
+ if (QFile::exists(overridePath))
+ {
+ QString mcPath = FS::PathCombine(m_stagingPath, "minecraft");
+ if (!QFile::rename(overridePath, mcPath))
+ {
+ emitFailed(tr("Could not rename the overrides folder:\n") + pack.overrides);
+ return;
+ }
+ }
+ else
+ {
+ logWarning(tr("The specified overrides folder (%1) is missing. Maybe the modpack was already used before?").arg(pack.overrides));
+ }
+ }
- QString forgeVersion;
- for(auto &loader: pack.minecraft.modLoaders)
- {
- auto id = loader.id;
- if(id.startsWith("forge-"))
- {
- id.remove("forge-");
- forgeVersion = id;
- continue;
- }
- logWarning(tr("Unknown mod loader in manifest: %1").arg(id));
- }
+ QString forgeVersion;
+ for(auto &loader: pack.minecraft.modLoaders)
+ {
+ auto id = loader.id;
+ if(id.startsWith("forge-"))
+ {
+ id.remove("forge-");
+ forgeVersion = id;
+ continue;
+ }
+ logWarning(tr("Unknown mod loader in manifest: %1").arg(id));
+ }
- QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg");
- auto instanceSettings = std::make_shared<INISettingsObject>(configPath);
- instanceSettings->registerSetting("InstanceType", "Legacy");
- instanceSettings->set("InstanceType", "OneSix");
- MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
- auto mcVersion = pack.minecraft.version;
- // Hack to correct some 'special sauce'...
- if(mcVersion.endsWith('.'))
- {
- mcVersion.remove(QRegExp("[.]+$"));
- logWarning(tr("Mysterious trailing dots removed from Minecraft version while importing pack."));
- }
- auto components = instance.getComponentList();
- components->buildingFromScratch();
- components->setComponentVersion("net.minecraft", mcVersion, true);
- if(!forgeVersion.isEmpty())
- {
- // FIXME: dirty, nasty, hack. Proper solution requires dependency resolution and knowledge of the metadata.
- if(forgeVersion == "recommended")
- {
- if(forgemap.contains(mcVersion))
- {
- forgeVersion = forgemap[mcVersion];
- }
- else
- {
- logWarning(tr("Could not map recommended forge version for Minecraft %1").arg(mcVersion));
- }
- }
- components->setComponentVersion("net.minecraftforge", forgeVersion);
- }
- if (m_instIcon != "default")
- {
- instance.setIconKey(m_instIcon);
- }
- else
- {
- if(pack.name.contains("Direwolf20"))
- {
- instance.setIconKey("steve");
- }
- else if(pack.name.contains("FTB") || pack.name.contains("Feed The Beast"))
- {
- instance.setIconKey("ftb_logo");
- }
- else
- {
- // default to something other than the MultiMC default to distinguish these
- instance.setIconKey("flame");
- }
- }
- instance.init();
- QString jarmodsPath = FS::PathCombine(m_stagingPath, "minecraft", "jarmods");
- QFileInfo jarmodsInfo(jarmodsPath);
- if(jarmodsInfo.isDir())
- {
- // install all the jar mods
- qDebug() << "Found jarmods:";
- QDir jarmodsDir(jarmodsPath);
- QStringList jarMods;
- for (auto info: jarmodsDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files))
- {
- qDebug() << info.fileName();
- jarMods.push_back(info.absoluteFilePath());
- }
- auto profile = instance.getComponentList();
- profile->installJarMods(jarMods);
- // nuke the original files
- FS::deletePath(jarmodsPath);
- }
- instance.setName(m_instName);
- m_modIdResolver.reset(new Flame::FileResolvingTask(pack));
- connect(m_modIdResolver.get(), &Flame::FileResolvingTask::succeeded, [&]()
- {
- auto results = m_modIdResolver->getResults();
- m_filesNetJob.reset(new NetJob(tr("Mod download")));
- for(auto result: results.files)
- {
- QString filename = result.fileName;
- if(!result.required)
- {
- filename += ".disabled";
- }
+ QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg");
+ auto instanceSettings = std::make_shared<INISettingsObject>(configPath);
+ instanceSettings->registerSetting("InstanceType", "Legacy");
+ instanceSettings->set("InstanceType", "OneSix");
+ MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
+ auto mcVersion = pack.minecraft.version;
+ // Hack to correct some 'special sauce'...
+ if(mcVersion.endsWith('.'))
+ {
+ mcVersion.remove(QRegExp("[.]+$"));
+ logWarning(tr("Mysterious trailing dots removed from Minecraft version while importing pack."));
+ }
+ auto components = instance.getComponentList();
+ components->buildingFromScratch();
+ components->setComponentVersion("net.minecraft", mcVersion, true);
+ if(!forgeVersion.isEmpty())
+ {
+ // FIXME: dirty, nasty, hack. Proper solution requires dependency resolution and knowledge of the metadata.
+ if(forgeVersion == "recommended")
+ {
+ if(forgemap.contains(mcVersion))
+ {
+ forgeVersion = forgemap[mcVersion];
+ }
+ else
+ {
+ logWarning(tr("Could not map recommended forge version for Minecraft %1").arg(mcVersion));
+ }
+ }
+ components->setComponentVersion("net.minecraftforge", forgeVersion);
+ }
+ if (m_instIcon != "default")
+ {
+ instance.setIconKey(m_instIcon);
+ }
+ else
+ {
+ if(pack.name.contains("Direwolf20"))
+ {
+ instance.setIconKey("steve");
+ }
+ else if(pack.name.contains("FTB") || pack.name.contains("Feed The Beast"))
+ {
+ instance.setIconKey("ftb_logo");
+ }
+ else
+ {
+ // default to something other than the MultiMC default to distinguish these
+ instance.setIconKey("flame");
+ }
+ }
+ instance.init();
+ QString jarmodsPath = FS::PathCombine(m_stagingPath, "minecraft", "jarmods");
+ QFileInfo jarmodsInfo(jarmodsPath);
+ if(jarmodsInfo.isDir())
+ {
+ // install all the jar mods
+ qDebug() << "Found jarmods:";
+ QDir jarmodsDir(jarmodsPath);
+ QStringList jarMods;
+ for (auto info: jarmodsDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files))
+ {
+ qDebug() << info.fileName();
+ jarMods.push_back(info.absoluteFilePath());
+ }
+ auto profile = instance.getComponentList();
+ profile->installJarMods(jarMods);
+ // nuke the original files
+ FS::deletePath(jarmodsPath);
+ }
+ instance.setName(m_instName);
+ m_modIdResolver.reset(new Flame::FileResolvingTask(pack));
+ connect(m_modIdResolver.get(), &Flame::FileResolvingTask::succeeded, [&]()
+ {
+ auto results = m_modIdResolver->getResults();
+ m_filesNetJob.reset(new NetJob(tr("Mod download")));
+ for(auto result: results.files)
+ {
+ QString filename = result.fileName;
+ if(!result.required)
+ {
+ filename += ".disabled";
+ }
- auto relpath = FS::PathCombine("minecraft", result.targetFolder, filename);
- auto path = FS::PathCombine(m_stagingPath , relpath);
+ auto relpath = FS::PathCombine("minecraft", result.targetFolder, filename);
+ auto path = FS::PathCombine(m_stagingPath , relpath);
- switch(result.type)
- {
- case Flame::File::Type::Folder:
- {
- logWarning(tr("This 'Folder' may need extracting: %1").arg(relpath));
- // fall-through intentional, we treat these as plain old mods and dump them wherever.
- }
- case Flame::File::Type::SingleFile:
- case Flame::File::Type::Mod:
- {
- qDebug() << "Will download" << result.url << "to" << path;
- auto dl = Net::Download::makeFile(result.url, path);
- m_filesNetJob->addNetAction(dl);
- break;
- }
- case Flame::File::Type::Modpack:
- logWarning(tr("Nesting modpacks in modpacks is not implemented, nothing was downloaded: %1").arg(relpath));
- break;
- case Flame::File::Type::Cmod2:
- case Flame::File::Type::Ctoc:
- case Flame::File::Type::Unknown:
- logWarning(tr("Unrecognized/unhandled PackageType for: %1").arg(relpath));
- break;
- }
- }
- m_modIdResolver.reset();
- connect(m_filesNetJob.get(), &NetJob::succeeded, this, [&]()
- {
- m_filesNetJob.reset();
- emitSucceeded();
- }
- );
- connect(m_filesNetJob.get(), &NetJob::failed, [&](QString reason)
- {
- m_filesNetJob.reset();
- emitFailed(reason);
- });
- connect(m_filesNetJob.get(), &NetJob::progress, [&](qint64 current, qint64 total)
- {
- setProgress(current, total);
- });
- setStatus(tr("Downloading mods..."));
- m_filesNetJob->start();
- }
- );
- connect(m_modIdResolver.get(), &Flame::FileResolvingTask::failed, [&](QString reason)
- {
- m_modIdResolver.reset();
- emitFailed(tr("Unable to resolve mod IDs:\n") + reason);
- });
- connect(m_modIdResolver.get(), &Flame::FileResolvingTask::progress, [&](qint64 current, qint64 total)
- {
- setProgress(current, total);
- });
- connect(m_modIdResolver.get(), &Flame::FileResolvingTask::status, [&](QString status)
- {
- setStatus(status);
- });
- m_modIdResolver->start();
+ switch(result.type)
+ {
+ case Flame::File::Type::Folder:
+ {
+ logWarning(tr("This 'Folder' may need extracting: %1").arg(relpath));
+ // fall-through intentional, we treat these as plain old mods and dump them wherever.
+ }
+ case Flame::File::Type::SingleFile:
+ case Flame::File::Type::Mod:
+ {
+ qDebug() << "Will download" << result.url << "to" << path;
+ auto dl = Net::Download::makeFile(result.url, path);
+ m_filesNetJob->addNetAction(dl);
+ break;
+ }
+ case Flame::File::Type::Modpack:
+ logWarning(tr("Nesting modpacks in modpacks is not implemented, nothing was downloaded: %1").arg(relpath));
+ break;
+ case Flame::File::Type::Cmod2:
+ case Flame::File::Type::Ctoc:
+ case Flame::File::Type::Unknown:
+ logWarning(tr("Unrecognized/unhandled PackageType for: %1").arg(relpath));
+ break;
+ }
+ }
+ m_modIdResolver.reset();
+ connect(m_filesNetJob.get(), &NetJob::succeeded, this, [&]()
+ {
+ m_filesNetJob.reset();
+ emitSucceeded();
+ }
+ );
+ connect(m_filesNetJob.get(), &NetJob::failed, [&](QString reason)
+ {
+ m_filesNetJob.reset();
+ emitFailed(reason);
+ });
+ connect(m_filesNetJob.get(), &NetJob::progress, [&](qint64 current, qint64 total)
+ {
+ setProgress(current, total);
+ });
+ setStatus(tr("Downloading mods..."));
+ m_filesNetJob->start();
+ }
+ );
+ connect(m_modIdResolver.get(), &Flame::FileResolvingTask::failed, [&](QString reason)
+ {
+ m_modIdResolver.reset();
+ emitFailed(tr("Unable to resolve mod IDs:\n") + reason);
+ });
+ connect(m_modIdResolver.get(), &Flame::FileResolvingTask::progress, [&](qint64 current, qint64 total)
+ {
+ setProgress(current, total);
+ });
+ connect(m_modIdResolver.get(), &Flame::FileResolvingTask::status, [&](QString status)
+ {
+ setStatus(status);
+ });
+ m_modIdResolver->start();
}
void InstanceImportTask::processMultiMC()
{
- // FIXME: copy from FolderInstanceProvider!!! FIX IT!!!
- QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg");
- auto instanceSettings = std::make_shared<INISettingsObject>(configPath);
- instanceSettings->registerSetting("InstanceType", "Legacy");
+ // FIXME: copy from FolderInstanceProvider!!! FIX IT!!!
+ QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg");
+ auto instanceSettings = std::make_shared<INISettingsObject>(configPath);
+ instanceSettings->registerSetting("InstanceType", "Legacy");
- NullInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
+ NullInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
- // reset time played on import... because packs.
- instance.resetTimePlayed();
+ // reset time played on import... because packs.
+ instance.resetTimePlayed();
- // set a new nice name
- instance.setName(m_instName);
+ // set a new nice name
+ instance.setName(m_instName);
- // if the icon was specified by user, use that. otherwise pull icon from the pack
- if (m_instIcon != "default")
- {
- instance.setIconKey(m_instIcon);
- }
- else
- {
- m_instIcon = instance.iconKey();
- auto importIconPath = FS::PathCombine(instance.instanceRoot(), m_instIcon + ".png");
- if (QFile::exists(importIconPath))
- {
- // import icon
- auto iconList = ENV.icons();
- if (iconList->iconFileExists(m_instIcon))
- {
- iconList->deleteIcon(m_instIcon);
- }
- iconList->installIcons({importIconPath});
- }
- }
- emitSucceeded();
+ // if the icon was specified by user, use that. otherwise pull icon from the pack
+ if (m_instIcon != "default")
+ {
+ instance.setIconKey(m_instIcon);
+ }
+ else
+ {
+ m_instIcon = instance.iconKey();
+ auto importIconPath = FS::PathCombine(instance.instanceRoot(), m_instIcon + ".png");
+ if (QFile::exists(importIconPath))
+ {
+ // import icon
+ auto iconList = ENV.icons();
+ if (iconList->iconFileExists(m_instIcon))
+ {
+ iconList->deleteIcon(m_instIcon);
+ }
+ iconList->installIcons({importIconPath});
+ }
+ }
+ emitSucceeded();
}
diff --git a/api/logic/InstanceImportTask.h b/api/logic/InstanceImportTask.h
index 06778dfe..4156aa48 100644
--- a/api/logic/InstanceImportTask.h
+++ b/api/logic/InstanceImportTask.h
@@ -13,43 +13,43 @@ class QuaZip;
class BaseInstanceProvider;
namespace Flame
{
- class FileResolvingTask;
+ class FileResolvingTask;
}
class MULTIMC_LOGIC_EXPORT InstanceImportTask : public InstanceTask
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit InstanceImportTask(const QUrl sourceUrl);
+ explicit InstanceImportTask(const QUrl sourceUrl);
protected:
- //! Entry point for tasks.
- virtual void executeTask() override;
+ //! Entry point for tasks.
+ virtual void executeTask() override;
private:
- void processZipPack();
- void processMultiMC();
- void processFlame();
+ void processZipPack();
+ void processMultiMC();
+ void processFlame();
private slots:
- void downloadSucceeded();
- void downloadFailed(QString reason);
- void downloadProgressChanged(qint64 current, qint64 total);
- void extractFinished();
- void extractAborted();
+ void downloadSucceeded();
+ void downloadFailed(QString reason);
+ void downloadProgressChanged(qint64 current, qint64 total);
+ void extractFinished();
+ void extractAborted();
private: /* data */
- NetJobPtr m_filesNetJob;
- shared_qobject_ptr<Flame::FileResolvingTask> m_modIdResolver;
- QUrl m_sourceUrl;
- QString m_archivePath;
- bool m_downloadRequired = false;
- std::unique_ptr<QuaZip> m_packZip;
- QFuture<QStringList> m_extractFuture;
- QFutureWatcher<QStringList> m_extractFutureWatcher;
- enum class ModpackType{
- Unknown,
- MultiMC,
- Flame
- } m_modpackType = ModpackType::Unknown;
+ NetJobPtr m_filesNetJob;
+ shared_qobject_ptr<Flame::FileResolvingTask> m_modIdResolver;
+ QUrl m_sourceUrl;
+ QString m_archivePath;
+ bool m_downloadRequired = false;
+ std::unique_ptr<QuaZip> m_packZip;
+ QFuture<QStringList> m_extractFuture;
+ QFutureWatcher<QStringList> m_extractFutureWatcher;
+ enum class ModpackType{
+ Unknown,
+ MultiMC,
+ Flame
+ } m_modpackType = ModpackType::Unknown;
};
diff --git a/api/logic/InstanceList.cpp b/api/logic/InstanceList.cpp
index 75b523e4..c7a22b08 100644
--- a/api/logic/InstanceList.cpp
+++ b/api/logic/InstanceList.cpp
@@ -27,9 +27,9 @@
#include "FolderInstanceProvider.h"
InstanceList::InstanceList(QObject *parent)
- : QAbstractListModel(parent)
+ : QAbstractListModel(parent)
{
- resumeWatch();
+ resumeWatch();
}
InstanceList::~InstanceList()
@@ -38,310 +38,310 @@ InstanceList::~InstanceList()
int InstanceList::rowCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
- return m_instances.count();
+ Q_UNUSED(parent);
+ return m_instances.count();
}
QModelIndex InstanceList::index(int row, int column, const QModelIndex &parent) const
{
- Q_UNUSED(parent);
- if (row < 0 || row >= m_instances.size())
- return QModelIndex();
- return createIndex(row, column, (void *)m_instances.at(row).get());
+ Q_UNUSED(parent);
+ if (row < 0 || row >= m_instances.size())
+ return QModelIndex();
+ return createIndex(row, column, (void *)m_instances.at(row).get());
}
QVariant InstanceList::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
- {
- return QVariant();
- }
- BaseInstance *pdata = static_cast<BaseInstance *>(index.internalPointer());
- switch (role)
- {
- case InstancePointerRole:
- {
- QVariant v = qVariantFromValue((void *)pdata);
- return v;
- }
- case InstanceIDRole:
+ if (!index.isValid())
+ {
+ return QVariant();
+ }
+ BaseInstance *pdata = static_cast<BaseInstance *>(index.internalPointer());
+ switch (role)
+ {
+ case InstancePointerRole:
+ {
+ QVariant v = qVariantFromValue((void *)pdata);
+ return v;
+ }
+ case InstanceIDRole:
{
return pdata->id();
}
- case Qt::DisplayRole:
- {
- return pdata->name();
- }
- case Qt::ToolTipRole:
- {
- return pdata->instanceRoot();
- }
- case Qt::DecorationRole:
- {
- return pdata->iconKey();
- }
- // HACK: see GroupView.h in gui!
- case GroupRole:
- {
- return pdata->group();
- }
- default:
- break;
- }
- return QVariant();
+ case Qt::DisplayRole:
+ {
+ return pdata->name();
+ }
+ case Qt::ToolTipRole:
+ {
+ return pdata->instanceRoot();
+ }
+ case Qt::DecorationRole:
+ {
+ return pdata->iconKey();
+ }
+ // HACK: see GroupView.h in gui!
+ case GroupRole:
+ {
+ return pdata->group();
+ }
+ default:
+ break;
+ }
+ return QVariant();
}
Qt::ItemFlags InstanceList::flags(const QModelIndex &index) const
{
- Qt::ItemFlags f;
- if (index.isValid())
- {
- f |= (Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- }
- return f;
+ Qt::ItemFlags f;
+ if (index.isValid())
+ {
+ f |= (Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+ }
+ return f;
}
QStringList InstanceList::getGroups()
{
- return m_groups.toList();
+ return m_groups.toList();
}
void InstanceList::deleteGroup(const QString& name)
{
- for(auto & instance: m_instances)
- {
- auto instGroupName = instance->group();
- if(instGroupName == name)
- {
- instance->setGroupPost(QString());
- }
- }
+ for(auto & instance: m_instances)
+ {
+ auto instGroupName = instance->group();
+ if(instGroupName == name)
+ {
+ instance->setGroupPost(QString());
+ }
+ }
}
static QMap<InstanceId, InstanceLocator> getIdMapping(const QList<InstancePtr> &list)
{
- QMap<InstanceId, InstanceLocator> out;
- int i = 0;
- for(auto & item: list)
- {
- auto id = item->id();
- if(out.contains(id))
- {
- qWarning() << "Duplicate ID" << id << "in instance list";
- }
- out[id] = std::make_pair(item, i);
- i++;
- }
- return out;
+ QMap<InstanceId, InstanceLocator> out;
+ int i = 0;
+ for(auto & item: list)
+ {
+ auto id = item->id();
+ if(out.contains(id))
+ {
+ qWarning() << "Duplicate ID" << id << "in instance list";
+ }
+ out[id] = std::make_pair(item, i);
+ i++;
+ }
+ return out;
}
InstanceList::InstListError InstanceList::loadList(bool complete)
{
- auto existingIds = getIdMapping(m_instances);
+ auto existingIds = getIdMapping(m_instances);
- QList<InstancePtr> newList;
+ QList<InstancePtr> newList;
- auto processIds = [&](BaseInstanceProvider * provider, QList<InstanceId> ids)
- {
- for(auto & id: ids)
- {
- if(existingIds.contains(id))
- {
- auto instPair = existingIds[id];
- /*
- auto & instPtr = instPair.first;
- auto & instIdx = instPair.second;
- */
- existingIds.remove(id);
- qDebug() << "Should keep and soft-reload" << id;
- }
- else
- {
- InstancePtr instPtr = provider->loadInstance(id);
- if(instPtr)
- {
- newList.append(instPtr);
- }
- }
- }
- };
- if(complete)
- {
- for(auto & item: m_providers)
- {
- processIds(item.get(), item->discoverInstances());
- }
- }
- else
- {
- for (auto & item: m_updatedProviders)
- {
- processIds(item, item->discoverInstances());
- }
- }
+ auto processIds = [&](BaseInstanceProvider * provider, QList<InstanceId> ids)
+ {
+ for(auto & id: ids)
+ {
+ if(existingIds.contains(id))
+ {
+ auto instPair = existingIds[id];
+ /*
+ auto & instPtr = instPair.first;
+ auto & instIdx = instPair.second;
+ */
+ existingIds.remove(id);
+ qDebug() << "Should keep and soft-reload" << id;
+ }
+ else
+ {
+ InstancePtr instPtr = provider->loadInstance(id);
+ if(instPtr)
+ {
+ newList.append(instPtr);
+ }
+ }
+ }
+ };
+ if(complete)
+ {
+ for(auto & item: m_providers)
+ {
+ processIds(item.get(), item->discoverInstances());
+ }
+ }
+ else
+ {
+ for (auto & item: m_updatedProviders)
+ {
+ processIds(item, item->discoverInstances());
+ }
+ }
- // TODO: looks like a general algorithm with a few specifics inserted. Do something about it.
- if(!existingIds.isEmpty())
- {
- // get the list of removed instances and sort it by their original index, from last to first
- auto deadList = existingIds.values();
- auto orderSortPredicate = [](const InstanceLocator & a, const InstanceLocator & b) -> bool
- {
- return a.second > b.second;
- };
- std::sort(deadList.begin(), deadList.end(), orderSortPredicate);
- // remove the contiguous ranges of rows
- int front_bookmark = -1;
- int back_bookmark = -1;
- int currentItem = -1;
- auto removeNow = [&]()
- {
- beginRemoveRows(QModelIndex(), front_bookmark, back_bookmark);
- m_instances.erase(m_instances.begin() + front_bookmark, m_instances.begin() + back_bookmark + 1);
- endRemoveRows();
- front_bookmark = -1;
- back_bookmark = currentItem;
- };
- for(auto & removedItem: deadList)
- {
- auto instPtr = removedItem.first;
- if(!complete && !m_updatedProviders.contains(instPtr->provider()))
- {
- continue;
- }
- instPtr->invalidate();
- currentItem = removedItem.second;
- if(back_bookmark == -1)
- {
- // no bookmark yet
- back_bookmark = currentItem;
- }
- else if(currentItem == front_bookmark - 1)
- {
- // part of contiguous sequence, continue
- }
- else
- {
- // seam between previous and current item
- removeNow();
- }
- front_bookmark = currentItem;
- }
- if(back_bookmark != -1)
- {
- removeNow();
- }
- }
- if(newList.size())
- {
- add(newList);
- }
- m_updatedProviders.clear();
- return NoError;
+ // TODO: looks like a general algorithm with a few specifics inserted. Do something about it.
+ if(!existingIds.isEmpty())
+ {
+ // get the list of removed instances and sort it by their original index, from last to first
+ auto deadList = existingIds.values();
+ auto orderSortPredicate = [](const InstanceLocator & a, const InstanceLocator & b) -> bool
+ {
+ return a.second > b.second;
+ };
+ std::sort(deadList.begin(), deadList.end(), orderSortPredicate);
+ // remove the contiguous ranges of rows
+ int front_bookmark = -1;
+ int back_bookmark = -1;
+ int currentItem = -1;
+ auto removeNow = [&]()
+ {
+ beginRemoveRows(QModelIndex(), front_bookmark, back_bookmark);
+ m_instances.erase(m_instances.begin() + front_bookmark, m_instances.begin() + back_bookmark + 1);
+ endRemoveRows();
+ front_bookmark = -1;
+ back_bookmark = currentItem;
+ };
+ for(auto & removedItem: deadList)
+ {
+ auto instPtr = removedItem.first;
+ if(!complete && !m_updatedProviders.contains(instPtr->provider()))
+ {
+ continue;
+ }
+ instPtr->invalidate();
+ currentItem = removedItem.second;
+ if(back_bookmark == -1)
+ {
+ // no bookmark yet
+ back_bookmark = currentItem;
+ }
+ else if(currentItem == front_bookmark - 1)
+ {
+ // part of contiguous sequence, continue
+ }
+ else
+ {
+ // seam between previous and current item
+ removeNow();
+ }
+ front_bookmark = currentItem;
+ }
+ if(back_bookmark != -1)
+ {
+ removeNow();
+ }
+ }
+ if(newList.size())
+ {
+ add(newList);
+ }
+ m_updatedProviders.clear();
+ return NoError;
}
void InstanceList::saveNow()
{
- for(auto & item: m_instances)
- {
- item->saveNow();
- }
+ for(auto & item: m_instances)
+ {
+ item->saveNow();
+ }
}
void InstanceList::add(const QList<InstancePtr> &t)
{
- beginInsertRows(QModelIndex(), m_instances.count(), m_instances.count() + t.size() - 1);
- m_instances.append(t);
- for(auto & ptr : t)
- {
- connect(ptr.get(), &BaseInstance::propertiesChanged, this, &InstanceList::propertiesChanged);
- }
- endInsertRows();
+ beginInsertRows(QModelIndex(), m_instances.count(), m_instances.count() + t.size() - 1);
+ m_instances.append(t);
+ for(auto & ptr : t)
+ {
+ connect(ptr.get(), &BaseInstance::propertiesChanged, this, &InstanceList::propertiesChanged);
+ }
+ endInsertRows();
}
void InstanceList::resumeWatch()
{
- if(m_watchLevel > 0)
- {
- qWarning() << "Bad suspend level resume in instance list";
- return;
- }
- m_watchLevel++;
- if(m_watchLevel > 0 && !m_updatedProviders.isEmpty())
- {
- loadList();
- }
+ if(m_watchLevel > 0)
+ {
+ qWarning() << "Bad suspend level resume in instance list";
+ return;
+ }
+ m_watchLevel++;
+ if(m_watchLevel > 0 && !m_updatedProviders.isEmpty())
+ {
+ loadList();
+ }
}
void InstanceList::suspendWatch()
{
- m_watchLevel --;
+ m_watchLevel --;
}
void InstanceList::providerUpdated()
{
- auto provider = dynamic_cast<BaseInstanceProvider *>(QObject::sender());
- if(!provider)
- {
- qWarning() << "InstanceList::providerUpdated triggered by a non-provider";
- return;
- }
- m_updatedProviders.insert(provider);
- if(m_watchLevel == 1)
- {
- loadList();
- }
+ auto provider = dynamic_cast<BaseInstanceProvider *>(QObject::sender());
+ if(!provider)
+ {
+ qWarning() << "InstanceList::providerUpdated triggered by a non-provider";
+ return;
+ }
+ m_updatedProviders.insert(provider);
+ if(m_watchLevel == 1)
+ {
+ loadList();
+ }
}
void InstanceList::groupsPublished(QSet<QString> newGroups)
{
- m_groups.unite(newGroups);
+ m_groups.unite(newGroups);
}
void InstanceList::addInstanceProvider(BaseInstanceProvider* provider)
{
- connect(provider, &BaseInstanceProvider::instancesChanged, this, &InstanceList::providerUpdated);
- connect(provider, &BaseInstanceProvider::groupsChanged, this, &InstanceList::groupsPublished);
- m_providers.append(provider);
+ connect(provider, &BaseInstanceProvider::instancesChanged, this, &InstanceList::providerUpdated);
+ connect(provider, &BaseInstanceProvider::groupsChanged, this, &InstanceList::groupsPublished);
+ m_providers.append(provider);
}
InstancePtr InstanceList::getInstanceById(QString instId) const
{
- if(instId.isEmpty())
- return InstancePtr();
- for(auto & inst: m_instances)
- {
- if (inst->id() == instId)
- {
- return inst;
- }
- }
- return InstancePtr();
+ if(instId.isEmpty())
+ return InstancePtr();
+ for(auto & inst: m_instances)
+ {
+ if (inst->id() == instId)
+ {
+ return inst;
+ }
+ }
+ return InstancePtr();
}
QModelIndex InstanceList::getInstanceIndexById(const QString &id) const
{
- return index(getInstIndex(getInstanceById(id).get()));
+ return index(getInstIndex(getInstanceById(id).get()));
}
int InstanceList::getInstIndex(BaseInstance *inst) const
{
- int count = m_instances.count();
- for (int i = 0; i < count; i++)
- {
- if (inst == m_instances[i].get())
- {
- return i;
- }
- }
- return -1;
+ int count = m_instances.count();
+ for (int i = 0; i < count; i++)
+ {
+ if (inst == m_instances[i].get())
+ {
+ return i;
+ }
+ }
+ return -1;
}
void InstanceList::propertiesChanged(BaseInstance *inst)
{
- int i = getInstIndex(inst);
- if (i != -1)
- {
- emit dataChanged(index(i), index(i));
- }
+ int i = getInstIndex(inst);
+ if (i != -1)
+ {
+ emit dataChanged(index(i), index(i));
+ }
}
diff --git a/api/logic/InstanceList.h b/api/logic/InstanceList.h
index bb879c83..7fe5ea34 100644
--- a/api/logic/InstanceList.h
+++ b/api/logic/InstanceList.h
@@ -31,75 +31,75 @@ class BaseInstance;
class MULTIMC_LOGIC_EXPORT InstanceList : public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit InstanceList(QObject *parent = 0);
- virtual ~InstanceList();
+ explicit InstanceList(QObject *parent = 0);
+ virtual ~InstanceList();
public:
- QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role) const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- enum AdditionalRoles
- {
- GroupRole = Qt::UserRole,
- InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance
- InstanceIDRole = 0x34B1CB49 ///< Return id if the instance
- };
- /*!
- * \brief Error codes returned by functions in the InstanceList class.
- * NoError Indicates that no error occurred.
- * UnknownError indicates that an unspecified error occurred.
- */
- enum InstListError
- {
- NoError = 0,
- UnknownError
- };
-
- InstancePtr at(int i) const
- {
- return m_instances.at(i);
- }
-
- int count() const
- {
- return m_instances.count();
- }
-
- InstListError loadList(bool complete = false);
- void saveNow();
-
- /// Add an instance provider. Takes ownership of it. Should only be done before the first load.
- void addInstanceProvider(BaseInstanceProvider * provider);
-
- InstancePtr getInstanceById(QString id) const;
- QModelIndex getInstanceIndexById(const QString &id) const;
- QStringList getGroups();
-
- void deleteGroup(const QString & name);
+ QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ enum AdditionalRoles
+ {
+ GroupRole = Qt::UserRole,
+ InstancePointerRole = 0x34B1CB48, ///< Return pointer to real instance
+ InstanceIDRole = 0x34B1CB49 ///< Return id if the instance
+ };
+ /*!
+ * \brief Error codes returned by functions in the InstanceList class.
+ * NoError Indicates that no error occurred.
+ * UnknownError indicates that an unspecified error occurred.
+ */
+ enum InstListError
+ {
+ NoError = 0,
+ UnknownError
+ };
+
+ InstancePtr at(int i) const
+ {
+ return m_instances.at(i);
+ }
+
+ int count() const
+ {
+ return m_instances.count();
+ }
+
+ InstListError loadList(bool complete = false);
+ void saveNow();
+
+ /// Add an instance provider. Takes ownership of it. Should only be done before the first load.
+ void addInstanceProvider(BaseInstanceProvider * provider);
+
+ InstancePtr getInstanceById(QString id) const;
+ QModelIndex getInstanceIndexById(const QString &id) const;
+ QStringList getGroups();
+
+ void deleteGroup(const QString & name);
signals:
- void dataIsInvalid();
+ void dataIsInvalid();
private slots:
- void propertiesChanged(BaseInstance *inst);
- void groupsPublished(QSet<QString>);
- void providerUpdated();
+ void propertiesChanged(BaseInstance *inst);
+ void groupsPublished(QSet<QString>);
+ void providerUpdated();
private:
- int getInstIndex(BaseInstance *inst) const;
- void suspendWatch();
- void resumeWatch();
- void add(const QList<InstancePtr> &list);
+ int getInstIndex(BaseInstance *inst) const;
+ void suspendWatch();
+ void resumeWatch();
+ void add(const QList<InstancePtr> &list);
protected:
- int m_watchLevel = 0;
- QSet<BaseInstanceProvider *> m_updatedProviders;
- QList<InstancePtr> m_instances;
- QSet<QString> m_groups;
- QVector<shared_qobject_ptr<BaseInstanceProvider>> m_providers;
+ int m_watchLevel = 0;
+ QSet<BaseInstanceProvider *> m_updatedProviders;
+ QList<InstancePtr> m_instances;
+ QSet<QString> m_groups;
+ QVector<shared_qobject_ptr<BaseInstanceProvider>> m_providers;
};
diff --git a/api/logic/InstanceTask.h b/api/logic/InstanceTask.h
index 8fc98eb7..5face5fc 100644
--- a/api/logic/InstanceTask.h
+++ b/api/logic/InstanceTask.h
@@ -8,48 +8,48 @@ class BaseInstanceProvider;
class MULTIMC_LOGIC_EXPORT InstanceTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit InstanceTask();
- virtual ~InstanceTask();
-
- void setParentSettings(SettingsObjectPtr settings)
- {
- m_globalSettings = settings;
- }
-
- void setStagingPath(const QString &stagingPath)
- {
- m_stagingPath = stagingPath;
- }
-
- void setName(const QString &name)
- {
- m_instName = name;
- }
- QString name() const
- {
- return m_instName;
- }
-
- void setIcon(const QString &icon)
- {
- m_instIcon = icon;
- }
-
- void setGroup(const QString &group)
- {
- m_instGroup = group;
- }
- QString group() const
- {
- return m_instGroup;
- }
+ explicit InstanceTask();
+ virtual ~InstanceTask();
+
+ void setParentSettings(SettingsObjectPtr settings)
+ {
+ m_globalSettings = settings;
+ }
+
+ void setStagingPath(const QString &stagingPath)
+ {
+ m_stagingPath = stagingPath;
+ }
+
+ void setName(const QString &name)
+ {
+ m_instName = name;
+ }
+ QString name() const
+ {
+ return m_instName;
+ }
+
+ void setIcon(const QString &icon)
+ {
+ m_instIcon = icon;
+ }
+
+ void setGroup(const QString &group)
+ {
+ m_instGroup = group;
+ }
+ QString group() const
+ {
+ return m_instGroup;
+ }
protected: /* data */
- SettingsObjectPtr m_globalSettings;
- QString m_instName;
- QString m_instIcon;
- QString m_instGroup;
- QString m_stagingPath;
+ SettingsObjectPtr m_globalSettings;
+ QString m_instName;
+ QString m_instIcon;
+ QString m_instGroup;
+ QString m_stagingPath;
};
diff --git a/api/logic/Json.cpp b/api/logic/Json.cpp
index f2cbc8a3..37ada1aa 100644
--- a/api/logic/Json.cpp
+++ b/api/logic/Json.cpp
@@ -11,262 +11,262 @@ namespace Json
{
void write(const QJsonDocument &doc, const QString &filename)
{
- FS::write(filename, doc.toJson());
+ FS::write(filename, doc.toJson());
}
void write(const QJsonObject &object, const QString &filename)
{
- write(QJsonDocument(object), filename);
+ write(QJsonDocument(object), filename);
}
void write(const QJsonArray &array, const QString &filename)
{
- write(QJsonDocument(array), filename);
+ write(QJsonDocument(array), filename);
}
QByteArray toBinary(const QJsonObject &obj)
{
- return QJsonDocument(obj).toBinaryData();
+ return QJsonDocument(obj).toBinaryData();
}
QByteArray toBinary(const QJsonArray &array)
{
- return QJsonDocument(array).toBinaryData();
+ return QJsonDocument(array).toBinaryData();
}
QByteArray toText(const QJsonObject &obj)
{
- return QJsonDocument(obj).toJson(QJsonDocument::Compact);
+ return QJsonDocument(obj).toJson(QJsonDocument::Compact);
}
QByteArray toText(const QJsonArray &array)
{
- return QJsonDocument(array).toJson(QJsonDocument::Compact);
+ return QJsonDocument(array).toJson(QJsonDocument::Compact);
}
static bool isBinaryJson(const QByteArray &data)
{
- decltype(QJsonDocument::BinaryFormatTag) tag = QJsonDocument::BinaryFormatTag;
- return memcmp(data.constData(), &tag, sizeof(QJsonDocument::BinaryFormatTag)) == 0;
+ decltype(QJsonDocument::BinaryFormatTag) tag = QJsonDocument::BinaryFormatTag;
+ return memcmp(data.constData(), &tag, sizeof(QJsonDocument::BinaryFormatTag)) == 0;
}
QJsonDocument requireDocument(const QByteArray &data, const QString &what)
{
- if (isBinaryJson(data))
- {
- QJsonDocument doc = QJsonDocument::fromBinaryData(data);
- if (doc.isNull())
- {
- throw JsonException(what + ": Invalid JSON (binary JSON detected)");
- }
- return doc;
- }
- else
- {
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(data, &error);
- if (error.error != QJsonParseError::NoError)
- {
- throw JsonException(what + ": Error parsing JSON: " + error.errorString());
- }
- return doc;
- }
+ if (isBinaryJson(data))
+ {
+ QJsonDocument doc = QJsonDocument::fromBinaryData(data);
+ if (doc.isNull())
+ {
+ throw JsonException(what + ": Invalid JSON (binary JSON detected)");
+ }
+ return doc;
+ }
+ else
+ {
+ QJsonParseError error;
+ QJsonDocument doc = QJsonDocument::fromJson(data, &error);
+ if (error.error != QJsonParseError::NoError)
+ {
+ throw JsonException(what + ": Error parsing JSON: " + error.errorString());
+ }
+ return doc;
+ }
}
QJsonDocument requireDocument(const QString &filename, const QString &what)
{
- return requireDocument(FS::read(filename), what);
+ return requireDocument(FS::read(filename), what);
}
QJsonObject requireObject(const QJsonDocument &doc, const QString &what)
{
- if (!doc.isObject())
- {
- throw JsonException(what + " is not an object");
- }
- return doc.object();
+ if (!doc.isObject())
+ {
+ throw JsonException(what + " is not an object");
+ }
+ return doc.object();
}
QJsonArray requireArray(const QJsonDocument &doc, const QString &what)
{
- if (!doc.isArray())
- {
- throw JsonException(what + " is not an array");
- }
- return doc.array();
+ if (!doc.isArray())
+ {
+ throw JsonException(what + " is not an array");
+ }
+ return doc.array();
}
void writeString(QJsonObject &to, const QString &key, const QString &value)
{
- if (!value.isEmpty())
- {
- to.insert(key, value);
- }
+ if (!value.isEmpty())
+ {
+ to.insert(key, value);
+ }
}
void writeStringList(QJsonObject &to, const QString &key, const QStringList &values)
{
- if (!values.isEmpty())
- {
- QJsonArray array;
- for(auto value: values)
- {
- array.append(value);
- }
- to.insert(key, array);
- }
+ if (!values.isEmpty())
+ {
+ QJsonArray array;
+ for(auto value: values)
+ {
+ array.append(value);
+ }
+ to.insert(key, array);
+ }
}
template<>
QJsonValue toJson<QUrl>(const QUrl &url)
{
- return QJsonValue(url.toString(QUrl::FullyEncoded));
+ return QJsonValue(url.toString(QUrl::FullyEncoded));
}
template<>
QJsonValue toJson<QByteArray>(const QByteArray &data)
{
- return QJsonValue(QString::fromLatin1(data.toHex()));
+ return QJsonValue(QString::fromLatin1(data.toHex()));
}
template<>
QJsonValue toJson<QDateTime>(const QDateTime &datetime)
{
- return QJsonValue(datetime.toString(Qt::ISODate));
+ return QJsonValue(datetime.toString(Qt::ISODate));
}
template<>
QJsonValue toJson<QDir>(const QDir &dir)
{
- return QDir::current().relativeFilePath(dir.absolutePath());
+ return QDir::current().relativeFilePath(dir.absolutePath());
}
template<>
QJsonValue toJson<QUuid>(const QUuid &uuid)
{
- return uuid.toString();
+ return uuid.toString();
}
template<>
QJsonValue toJson<QVariant>(const QVariant &variant)
{
- return QJsonValue::fromVariant(variant);
+ return QJsonValue::fromVariant(variant);
}
template<> QByteArray requireIsType<QByteArray>(const QJsonValue &value, const QString &what)
{
- const QString string = ensureIsType<QString>(value, what);
- // ensure that the string can be safely cast to Latin1
- if (string != QString::fromLatin1(string.toLatin1()))
- {
- throw JsonException(what + " is not encodable as Latin1");
- }
- return QByteArray::fromHex(string.toLatin1());
+ const QString string = ensureIsType<QString>(value, what);
+ // ensure that the string can be safely cast to Latin1
+ if (string != QString::fromLatin1(string.toLatin1()))
+ {
+ throw JsonException(what + " is not encodable as Latin1");
+ }
+ return QByteArray::fromHex(string.toLatin1());
}
template<> QJsonArray requireIsType<QJsonArray>(const QJsonValue &value, const QString &what)
{
- if (!value.isArray())
- {
- throw JsonException(what + " is not an array");
- }
- return value.toArray();
+ if (!value.isArray())
+ {
+ throw JsonException(what + " is not an array");
+ }
+ return value.toArray();
}
template<> QString requireIsType<QString>(const QJsonValue &value, const QString &what)
{
- if (!value.isString())
- {
- throw JsonException(what + " is not a string");
- }
- return value.toString();
+ if (!value.isString())
+ {
+ throw JsonException(what + " is not a string");
+ }
+ return value.toString();
}
template<> bool requireIsType<bool>(const QJsonValue &value, const QString &what)
{
- if (!value.isBool())
- {
- throw JsonException(what + " is not a bool");
- }
- return value.toBool();
+ if (!value.isBool())
+ {
+ throw JsonException(what + " is not a bool");
+ }
+ return value.toBool();
}
template<> double requireIsType<double>(const QJsonValue &value, const QString &what)
{
- if (!value.isDouble())
- {
- throw JsonException(what + " is not a double");
- }
- return value.toDouble();
+ if (!value.isDouble())
+ {
+ throw JsonException(what + " is not a double");
+ }
+ return value.toDouble();
}
template<> int requireIsType<int>(const QJsonValue &value, const QString &what)
{
- const double doubl = requireIsType<double>(value, what);
- if (fmod(doubl, 1) != 0)
- {
- throw JsonException(what + " is not an integer");
- }
- return int(doubl);
+ const double doubl = requireIsType<double>(value, what);
+ if (fmod(doubl, 1) != 0)
+ {
+ throw JsonException(what + " is not an integer");
+ }
+ return int(doubl);
}
template<> QDateTime requireIsType<QDateTime>(const QJsonValue &value, const QString &what)
{
- const QString string = requireIsType<QString>(value, what);
- const QDateTime datetime = QDateTime::fromString(string, Qt::ISODate);
- if (!datetime.isValid())
- {
- throw JsonException(what + " is not a ISO formatted date/time value");
- }
- return datetime;
+ const QString string = requireIsType<QString>(value, what);
+ const QDateTime datetime = QDateTime::fromString(string, Qt::ISODate);
+ if (!datetime.isValid())
+ {
+ throw JsonException(what + " is not a ISO formatted date/time value");
+ }
+ return datetime;
}
template<> QUrl requireIsType<QUrl>(const QJsonValue &value, const QString &what)
{
- const QString string = ensureIsType<QString>(value, what);
- if (string.isEmpty())
- {
- return QUrl();
- }
- const QUrl url = QUrl(string, QUrl::StrictMode);
- if (!url.isValid())
- {
- throw JsonException(what + " is not a correctly formatted URL");
- }
- return url;
+ const QString string = ensureIsType<QString>(value, what);
+ if (string.isEmpty())
+ {
+ return QUrl();
+ }
+ const QUrl url = QUrl(string, QUrl::StrictMode);
+ if (!url.isValid())
+ {
+ throw JsonException(what + " is not a correctly formatted URL");
+ }
+ return url;
}
template<> QDir requireIsType<QDir>(const QJsonValue &value, const QString &what)
{
- const QString string = requireIsType<QString>(value, what);
- // FIXME: does not handle invalid characters!
- return QDir::current().absoluteFilePath(string);
+ const QString string = requireIsType<QString>(value, what);
+ // FIXME: does not handle invalid characters!
+ return QDir::current().absoluteFilePath(string);
}
template<> QUuid requireIsType<QUuid>(const QJsonValue &value, const QString &what)
{
- const QString string = requireIsType<QString>(value, what);
- const QUuid uuid = QUuid(string);
- if (uuid.toString() != string) // converts back => valid
- {
- throw JsonException(what + " is not a valid UUID");
- }
- return uuid;
+ const QString string = requireIsType<QString>(value, what);
+ const QUuid uuid = QUuid(string);
+ if (uuid.toString() != string) // converts back => valid
+ {
+ throw JsonException(what + " is not a valid UUID");
+ }
+ return uuid;
}
template<> QJsonObject requireIsType<QJsonObject>(const QJsonValue &value, const QString &what)
{
- if (!value.isObject())
- {
- throw JsonException(what + " is not an object");
- }
- return value.toObject();
+ if (!value.isObject())
+ {
+ throw JsonException(what + " is not an object");
+ }
+ return value.toObject();
}
template<> QVariant requireIsType<QVariant>(const QJsonValue &value, const QString &what)
{
- if (value.isNull() || value.isUndefined())
- {
- throw JsonException(what + " is null or undefined");
- }
- return value.toVariant();
+ if (value.isNull() || value.isUndefined())
+ {
+ throw JsonException(what + " is null or undefined");
+ }
+ return value.toVariant();
}
template<> QJsonValue requireIsType<QJsonValue>(const QJsonValue &value, const QString &what)
{
- if (value.isNull() || value.isUndefined())
- {
- throw JsonException(what + " is null or undefined");
- }
- return value;
+ if (value.isNull() || value.isUndefined())
+ {
+ throw JsonException(what + " is null or undefined");
+ }
+ return value;
}
}
diff --git a/api/logic/Json.h b/api/logic/Json.h
index a84d204a..34ff6fe2 100644
--- a/api/logic/Json.h
+++ b/api/logic/Json.h
@@ -19,7 +19,7 @@ namespace Json
class MULTIMC_LOGIC_EXPORT JsonException : public ::Exception
{
public:
- JsonException(const QString &message) : Exception(message) {}
+ JsonException(const QString &message) : Exception(message) {}
};
/// @throw FileSystemException
@@ -51,7 +51,7 @@ void writeStringList(QJsonObject & to, const QString &key, const QStringList &va
template<typename T>
QJsonValue toJson(const T &t)
{
- return QJsonValue(t);
+ return QJsonValue(t);
}
template<>
QJsonValue toJson<QUrl>(const QUrl &url);
@@ -69,12 +69,12 @@ QJsonValue toJson<QVariant>(const QVariant &variant);
template<typename T>
QJsonArray toJsonArray(const QList<T> &container)
{
- QJsonArray array;
- for (const T item : container)
- {
- array.append(toJson<T>(item));
- }
- return array;
+ QJsonArray array;
+ for (const T item : container)
+ {
+ array.append(toJson<T>(item));
+ }
+ return array;
}
////////////////// READING ////////////////////
@@ -115,119 +115,119 @@ template<> MULTIMC_LOGIC_EXPORT QUrl requireIsType<QUrl>(const QJsonValue &value
template <typename T>
T ensureIsType(const QJsonValue &value, const T default_ = T(), const QString &what = "Value")
{
- if (value.isUndefined() || value.isNull())
- {
- return default_;
- }
- try
- {
- return requireIsType<T>(value, what);
- }
- catch (const JsonException &)
- {
- return default_;
- }
+ if (value.isUndefined() || value.isNull())
+ {
+ return default_;
+ }
+ try
+ {
+ return requireIsType<T>(value, what);
+ }
+ catch (const JsonException &)
+ {
+ return default_;
+ }
}
/// @throw JsonException
template <typename T>
T requireIsType(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__")
{
- const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
- if (!parent.contains(key))
- {
- throw JsonException(localWhat + "s parent does not contain " + localWhat);
- }
- return requireIsType<T>(parent.value(key), localWhat);
+ const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
+ if (!parent.contains(key))
+ {
+ throw JsonException(localWhat + "s parent does not contain " + localWhat);
+ }
+ return requireIsType<T>(parent.value(key), localWhat);
}
template <typename T>
T ensureIsType(const QJsonObject &parent, const QString &key, const T default_ = T(), const QString &what = "__placeholder__")
{
- const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
- if (!parent.contains(key))
- {
- return default_;
- }
- return ensureIsType<T>(parent.value(key), default_, localWhat);
+ const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
+ if (!parent.contains(key))
+ {
+ return default_;
+ }
+ return ensureIsType<T>(parent.value(key), default_, localWhat);
}
template <typename T>
QVector<T> requireIsArrayOf(const QJsonDocument &doc)
{
- const QJsonArray array = requireArray(doc);
- QVector<T> out;
- for (const QJsonValue val : array)
- {
- out.append(requireIsType<T>(val, "Document"));
- }
- return out;
+ const QJsonArray array = requireArray(doc);
+ QVector<T> out;
+ for (const QJsonValue val : array)
+ {
+ out.append(requireIsType<T>(val, "Document"));
+ }
+ return out;
}
template <typename T>
QVector<T> ensureIsArrayOf(const QJsonValue &value, const QString &what = "Value")
{
- const QJsonArray array = ensureIsType<QJsonArray>(value, QJsonArray(), what);
- QVector<T> out;
- for (const QJsonValue val : array)
- {
- out.append(requireIsType<T>(val, what));
- }
- return out;
+ const QJsonArray array = ensureIsType<QJsonArray>(value, QJsonArray(), what);
+ QVector<T> out;
+ for (const QJsonValue val : array)
+ {
+ out.append(requireIsType<T>(val, what));
+ }
+ return out;
}
template <typename T>
QVector<T> ensureIsArrayOf(const QJsonValue &value, const QVector<T> default_, const QString &what = "Value")
{
- if (value.isUndefined())
- {
- return default_;
- }
- return ensureIsArrayOf<T>(value, what);
+ if (value.isUndefined())
+ {
+ return default_;
+ }
+ return ensureIsArrayOf<T>(value, what);
}
/// @throw JsonException
template <typename T>
QVector<T> requireIsArrayOf(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__")
{
- const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
- if (!parent.contains(key))
- {
- throw JsonException(localWhat + "s parent does not contain " + localWhat);
- }
- return ensureIsArrayOf<T>(parent.value(key), localWhat);
+ const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
+ if (!parent.contains(key))
+ {
+ throw JsonException(localWhat + "s parent does not contain " + localWhat);
+ }
+ return ensureIsArrayOf<T>(parent.value(key), localWhat);
}
template <typename T>
QVector<T> ensureIsArrayOf(const QJsonObject &parent, const QString &key,
- const QVector<T> &default_ = QVector<T>(), const QString &what = "__placeholder__")
+ const QVector<T> &default_ = QVector<T>(), const QString &what = "__placeholder__")
{
- const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
- if (!parent.contains(key))
- {
- return default_;
- }
- return ensureIsArrayOf<T>(parent.value(key), default_, localWhat);
+ const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\'');
+ if (!parent.contains(key))
+ {
+ return default_;
+ }
+ return ensureIsArrayOf<T>(parent.value(key), default_, localWhat);
}
// this macro part could be replaced by variadic functions that just pass on their arguments, but that wouldn't work well with IDE helpers
#define JSON_HELPERFUNCTIONS(NAME, TYPE) \
- inline TYPE require##NAME(const QJsonValue &value, const QString &what = "Value") \
- { \
- return requireIsType<TYPE>(value, what); \
- } \
- inline TYPE ensure##NAME(const QJsonValue &value, const TYPE default_ = TYPE(), const QString &what = "Value") \
- { \
- return ensureIsType<TYPE>(value, default_, what); \
- } \
- inline TYPE require##NAME(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") \
- { \
- return requireIsType<TYPE>(parent, key, what); \
- } \
- inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const TYPE default_ = TYPE(), const QString &what = "__placeholder") \
- { \
- return ensureIsType<TYPE>(parent, key, default_, what); \
- }
+ inline TYPE require##NAME(const QJsonValue &value, const QString &what = "Value") \
+ { \
+ return requireIsType<TYPE>(value, what); \
+ } \
+ inline TYPE ensure##NAME(const QJsonValue &value, const TYPE default_ = TYPE(), const QString &what = "Value") \
+ { \
+ return ensureIsType<TYPE>(value, default_, what); \
+ } \
+ inline TYPE require##NAME(const QJsonObject &parent, const QString &key, const QString &what = "__placeholder__") \
+ { \
+ return requireIsType<TYPE>(parent, key, what); \
+ } \
+ inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const TYPE default_ = TYPE(), const QString &what = "__placeholder") \
+ { \
+ return ensureIsType<TYPE>(parent, key, default_, what); \
+ }
JSON_HELPERFUNCTIONS(Array, QJsonArray)
JSON_HELPERFUNCTIONS(Object, QJsonObject)
diff --git a/api/logic/LoggedProcess.cpp b/api/logic/LoggedProcess.cpp
index f89b4acc..822c0f04 100644
--- a/api/logic/LoggedProcess.cpp
+++ b/api/logic/LoggedProcess.cpp
@@ -4,157 +4,157 @@
LoggedProcess::LoggedProcess(QObject *parent) : QProcess(parent)
{
- // QProcess has a strange interface... let's map a lot of those into a few.
- connect(this, &QProcess::readyReadStandardOutput, this, &LoggedProcess::on_stdOut);
- connect(this, &QProcess::readyReadStandardError, this, &LoggedProcess::on_stdErr);
- connect(this, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(on_exit(int,QProcess::ExitStatus)));
- connect(this, SIGNAL(error(QProcess::ProcessError)), this, SLOT(on_error(QProcess::ProcessError)));
- connect(this, &QProcess::stateChanged, this, &LoggedProcess::on_stateChange);
+ // QProcess has a strange interface... let's map a lot of those into a few.
+ connect(this, &QProcess::readyReadStandardOutput, this, &LoggedProcess::on_stdOut);
+ connect(this, &QProcess::readyReadStandardError, this, &LoggedProcess::on_stdErr);
+ connect(this, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(on_exit(int,QProcess::ExitStatus)));
+ connect(this, SIGNAL(error(QProcess::ProcessError)), this, SLOT(on_error(QProcess::ProcessError)));
+ connect(this, &QProcess::stateChanged, this, &LoggedProcess::on_stateChange);
}
LoggedProcess::~LoggedProcess()
{
- if(m_is_detachable)
- {
- setProcessState(QProcess::NotRunning);
- }
+ if(m_is_detachable)
+ {
+ setProcessState(QProcess::NotRunning);
+ }
}
QStringList reprocess(const QByteArray & data, QString & leftover)
{
- QString str = leftover + QString::fromLocal8Bit(data);
+ QString str = leftover + QString::fromLocal8Bit(data);
- str.remove('\r');
- QStringList lines = str.split("\n");
- leftover = lines.takeLast();
- return lines;
+ str.remove('\r');
+ QStringList lines = str.split("\n");
+ leftover = lines.takeLast();
+ return lines;
}
void LoggedProcess::on_stdErr()
{
- auto lines = reprocess(readAllStandardError(), m_err_leftover);
- emit log(lines, MessageLevel::StdErr);
+ auto lines = reprocess(readAllStandardError(), m_err_leftover);
+ emit log(lines, MessageLevel::StdErr);
}
void LoggedProcess::on_stdOut()
{
- auto lines = reprocess(readAllStandardOutput(), m_out_leftover);
- emit log(lines, MessageLevel::StdOut);
+ auto lines = reprocess(readAllStandardOutput(), m_out_leftover);
+ emit log(lines, MessageLevel::StdOut);
}
void LoggedProcess::on_exit(int exit_code, QProcess::ExitStatus status)
{
- // save the exit code
- m_exit_code = exit_code;
-
- // Flush console window
- if (!m_err_leftover.isEmpty())
- {
- emit log({m_err_leftover}, MessageLevel::StdErr);
- m_err_leftover.clear();
- }
- if (!m_out_leftover.isEmpty())
- {
- emit log({m_err_leftover}, MessageLevel::StdOut);
- m_out_leftover.clear();
- }
-
- // based on state, send signals
- if (!m_is_aborting)
- {
- if (status == QProcess::NormalExit)
- {
- //: Message displayed on instance exit
- emit log({tr("Process exited with code %1.").arg(exit_code)}, MessageLevel::MultiMC);
- changeState(LoggedProcess::Finished);
- }
- else
- {
- //: Message displayed on instance crashed
- if(exit_code == -1)
- emit log({tr("Process crashed.")}, MessageLevel::MultiMC);
- else
- emit log({tr("Process crashed with exitcode %1.").arg(exit_code)}, MessageLevel::MultiMC);
- changeState(LoggedProcess::Crashed);
- }
- }
- else
- {
- //: Message displayed after the instance exits due to kill request
- emit log({tr("Process was killed by user.")}, MessageLevel::Error);
- changeState(LoggedProcess::Aborted);
- }
+ // save the exit code
+ m_exit_code = exit_code;
+
+ // Flush console window
+ if (!m_err_leftover.isEmpty())
+ {
+ emit log({m_err_leftover}, MessageLevel::StdErr);
+ m_err_leftover.clear();
+ }
+ if (!m_out_leftover.isEmpty())
+ {
+ emit log({m_err_leftover}, MessageLevel::StdOut);
+ m_out_leftover.clear();
+ }
+
+ // based on state, send signals
+ if (!m_is_aborting)
+ {
+ if (status == QProcess::NormalExit)
+ {
+ //: Message displayed on instance exit
+ emit log({tr("Process exited with code %1.").arg(exit_code)}, MessageLevel::MultiMC);
+ changeState(LoggedProcess::Finished);
+ }
+ else
+ {
+ //: Message displayed on instance crashed
+ if(exit_code == -1)
+ emit log({tr("Process crashed.")}, MessageLevel::MultiMC);
+ else
+ emit log({tr("Process crashed with exitcode %1.").arg(exit_code)}, MessageLevel::MultiMC);
+ changeState(LoggedProcess::Crashed);
+ }
+ }
+ else
+ {
+ //: Message displayed after the instance exits due to kill request
+ emit log({tr("Process was killed by user.")}, MessageLevel::Error);
+ changeState(LoggedProcess::Aborted);
+ }
}
void LoggedProcess::on_error(QProcess::ProcessError error)
{
- switch(error)
- {
- case QProcess::FailedToStart:
- {
- emit log({tr("The process failed to start.")}, MessageLevel::Fatal);
- changeState(LoggedProcess::FailedToStart);
- break;
- }
- // we'll just ignore those... never needed them
- case QProcess::Crashed:
- case QProcess::ReadError:
- case QProcess::Timedout:
- case QProcess::UnknownError:
- case QProcess::WriteError:
- break;
- }
+ switch(error)
+ {
+ case QProcess::FailedToStart:
+ {
+ emit log({tr("The process failed to start.")}, MessageLevel::Fatal);
+ changeState(LoggedProcess::FailedToStart);
+ break;
+ }
+ // we'll just ignore those... never needed them
+ case QProcess::Crashed:
+ case QProcess::ReadError:
+ case QProcess::Timedout:
+ case QProcess::UnknownError:
+ case QProcess::WriteError:
+ break;
+ }
}
void LoggedProcess::kill()
{
- m_is_aborting = true;
- QProcess::kill();
+ m_is_aborting = true;
+ QProcess::kill();
}
int LoggedProcess::exitCode() const
{
- return m_exit_code;
+ return m_exit_code;
}
void LoggedProcess::changeState(LoggedProcess::State state)
{
- if(state == m_state)
- return;
- m_state = state;
- emit stateChanged(m_state);
+ if(state == m_state)
+ return;
+ m_state = state;
+ emit stateChanged(m_state);
}
LoggedProcess::State LoggedProcess::state() const
{
- return m_state;
+ return m_state;
}
void LoggedProcess::on_stateChange(QProcess::ProcessState state)
{
- switch(state)
- {
- case QProcess::NotRunning:
- break; // let's not - there are too many that handle this already.
- case QProcess::Starting:
- {
- if(m_state != LoggedProcess::NotRunning)
- {
- qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Starting;
- }
- changeState(LoggedProcess::Starting);
- return;
- }
- case QProcess::Running:
- {
- if(m_state != LoggedProcess::Starting)
- {
- qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Running;
- }
- changeState(LoggedProcess::Running);
- return;
- }
- }
+ switch(state)
+ {
+ case QProcess::NotRunning:
+ break; // let's not - there are too many that handle this already.
+ case QProcess::Starting:
+ {
+ if(m_state != LoggedProcess::NotRunning)
+ {
+ qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Starting;
+ }
+ changeState(LoggedProcess::Starting);
+ return;
+ }
+ case QProcess::Running:
+ {
+ if(m_state != LoggedProcess::Starting)
+ {
+ qWarning() << "Wrong state change for process from state" << m_state << "to" << (int) LoggedProcess::Running;
+ }
+ changeState(LoggedProcess::Running);
+ return;
+ }
+ }
}
#if defined Q_OS_WIN32
@@ -172,5 +172,5 @@ qint64 LoggedProcess::processId() const
void LoggedProcess::setDetachable(bool detachable)
{
- m_is_detachable = detachable;
+ m_is_detachable = detachable;
}
diff --git a/api/logic/LoggedProcess.h b/api/logic/LoggedProcess.h
index 6a80365f..2cbc28bc 100644
--- a/api/logic/LoggedProcess.h
+++ b/api/logic/LoggedProcess.h
@@ -27,54 +27,54 @@ class MULTIMC_LOGIC_EXPORT LoggedProcess : public QProcess
{
Q_OBJECT
public:
- enum State
- {
- NotRunning,
- Starting,
- FailedToStart,
- Running,
- Finished,
- Crashed,
- Aborted
- };
+ enum State
+ {
+ NotRunning,
+ Starting,
+ FailedToStart,
+ Running,
+ Finished,
+ Crashed,
+ Aborted
+ };
public:
- explicit LoggedProcess(QObject* parent = 0);
- virtual ~LoggedProcess();
+ explicit LoggedProcess(QObject* parent = 0);
+ virtual ~LoggedProcess();
- State state() const;
- int exitCode() const;
- qint64 processId() const;
+ State state() const;
+ int exitCode() const;
+ qint64 processId() const;
- void setDetachable(bool detachable);
+ void setDetachable(bool detachable);
signals:
- void log(QStringList lines, MessageLevel::Enum level);
- void stateChanged(LoggedProcess::State state);
+ void log(QStringList lines, MessageLevel::Enum level);
+ void stateChanged(LoggedProcess::State state);
public slots:
- /**
- * @brief kill the process - equivalent to kill -9
- */
- void kill();
+ /**
+ * @brief kill the process - equivalent to kill -9
+ */
+ void kill();
private slots:
- void on_stdErr();
- void on_stdOut();
- void on_exit(int exit_code, QProcess::ExitStatus status);
- void on_error(QProcess::ProcessError error);
- void on_stateChange(QProcess::ProcessState);
+ void on_stdErr();
+ void on_stdOut();
+ void on_exit(int exit_code, QProcess::ExitStatus status);
+ void on_error(QProcess::ProcessError error);
+ void on_stateChange(QProcess::ProcessState);
private:
- void changeState(LoggedProcess::State state);
+ void changeState(LoggedProcess::State state);
private:
- QString m_err_leftover;
- QString m_out_leftover;
- bool m_killed = false;
- State m_state = NotRunning;
- int m_exit_code = 0;
- bool m_is_aborting = false;
- bool m_is_detachable = false;
+ QString m_err_leftover;
+ QString m_out_leftover;
+ bool m_killed = false;
+ State m_state = NotRunning;
+ int m_exit_code = 0;
+ bool m_is_aborting = false;
+ bool m_is_detachable = false;
};
diff --git a/api/logic/MMCStrings.cpp b/api/logic/MMCStrings.cpp
index c50d596e..dc91c8d6 100644
--- a/api/logic/MMCStrings.cpp
+++ b/api/logic/MMCStrings.cpp
@@ -3,74 +3,74 @@
/// TAKEN FROM Qt, because it doesn't expose it intelligently
static inline QChar getNextChar(const QString &s, int location)
{
- return (location < s.length()) ? s.at(location) : QChar();
+ return (location < s.length()) ? s.at(location) : QChar();
}
/// TAKEN FROM Qt, because it doesn't expose it intelligently
int Strings::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs)
{
- for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2)
- {
- // skip spaces, tabs and 0's
- QChar c1 = getNextChar(s1, l1);
- while (c1.isSpace())
- c1 = getNextChar(s1, ++l1);
- QChar c2 = getNextChar(s2, l2);
- while (c2.isSpace())
- c2 = getNextChar(s2, ++l2);
+ for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2)
+ {
+ // skip spaces, tabs and 0's
+ QChar c1 = getNextChar(s1, l1);
+ while (c1.isSpace())
+ c1 = getNextChar(s1, ++l1);
+ QChar c2 = getNextChar(s2, l2);
+ while (c2.isSpace())
+ c2 = getNextChar(s2, ++l2);
- if (c1.isDigit() && c2.isDigit())
- {
- while (c1.digitValue() == 0)
- c1 = getNextChar(s1, ++l1);
- while (c2.digitValue() == 0)
- c2 = getNextChar(s2, ++l2);
+ if (c1.isDigit() && c2.isDigit())
+ {
+ while (c1.digitValue() == 0)
+ c1 = getNextChar(s1, ++l1);
+ while (c2.digitValue() == 0)
+ c2 = getNextChar(s2, ++l2);
- int lookAheadLocation1 = l1;
- int lookAheadLocation2 = l2;
- int currentReturnValue = 0;
- // find the last digit, setting currentReturnValue as we go if it isn't equal
- for (QChar lookAhead1 = c1, lookAhead2 = c2;
- (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length());
- lookAhead1 = getNextChar(s1, ++lookAheadLocation1),
- lookAhead2 = getNextChar(s2, ++lookAheadLocation2))
- {
- bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit();
- bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit();
- if (!is1ADigit && !is2ADigit)
- break;
- if (!is1ADigit)
- return -1;
- if (!is2ADigit)
- return 1;
- if (currentReturnValue == 0)
- {
- if (lookAhead1 < lookAhead2)
- {
- currentReturnValue = -1;
- }
- else if (lookAhead1 > lookAhead2)
- {
- currentReturnValue = 1;
- }
- }
- }
- if (currentReturnValue != 0)
- return currentReturnValue;
- }
- if (cs == Qt::CaseInsensitive)
- {
- if (!c1.isLower())
- c1 = c1.toLower();
- if (!c2.isLower())
- c2 = c2.toLower();
- }
- int r = QString::localeAwareCompare(c1, c2);
- if (r < 0)
- return -1;
- if (r > 0)
- return 1;
- }
- // The two strings are the same (02 == 2) so fall back to the normal sort
- return QString::compare(s1, s2, cs);
+ int lookAheadLocation1 = l1;
+ int lookAheadLocation2 = l2;
+ int currentReturnValue = 0;
+ // find the last digit, setting currentReturnValue as we go if it isn't equal
+ for (QChar lookAhead1 = c1, lookAhead2 = c2;
+ (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length());
+ lookAhead1 = getNextChar(s1, ++lookAheadLocation1),
+ lookAhead2 = getNextChar(s2, ++lookAheadLocation2))
+ {
+ bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit();
+ bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit();
+ if (!is1ADigit && !is2ADigit)
+ break;
+ if (!is1ADigit)
+ return -1;
+ if (!is2ADigit)
+ return 1;
+ if (currentReturnValue == 0)
+ {
+ if (lookAhead1 < lookAhead2)
+ {
+ currentReturnValue = -1;
+ }
+ else if (lookAhead1 > lookAhead2)
+ {
+ currentReturnValue = 1;
+ }
+ }
+ }
+ if (currentReturnValue != 0)
+ return currentReturnValue;
+ }
+ if (cs == Qt::CaseInsensitive)
+ {
+ if (!c1.isLower())
+ c1 = c1.toLower();
+ if (!c2.isLower())
+ c2 = c2.toLower();
+ }
+ int r = QString::localeAwareCompare(c1, c2);
+ if (r < 0)
+ return -1;
+ if (r > 0)
+ return 1;
+ }
+ // The two strings are the same (02 == 2) so fall back to the normal sort
+ return QString::compare(s1, s2, cs);
}
diff --git a/api/logic/MMCStrings.h b/api/logic/MMCStrings.h
index 5606b909..493ba3d2 100644
--- a/api/logic/MMCStrings.h
+++ b/api/logic/MMCStrings.h
@@ -6,5 +6,5 @@
namespace Strings
{
- int MULTIMC_LOGIC_EXPORT naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs);
+ int MULTIMC_LOGIC_EXPORT naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs);
}
diff --git a/api/logic/MMCZip.cpp b/api/logic/MMCZip.cpp
index 1e7ad51d..21a55493 100644
--- a/api/logic/MMCZip.cpp
+++ b/api/logic/MMCZip.cpp
@@ -25,231 +25,231 @@
// ours
bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained, const JlCompress::FilterFunction filter)
{
- QuaZip modZip(from.filePath());
- modZip.open(QuaZip::mdUnzip);
-
- QuaZipFile fileInsideMod(&modZip);
- QuaZipFile zipOutFile(into);
- for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile())
- {
- QString filename = modZip.getCurrentFileName();
- if (filter && !filter(filename))
- {
- qDebug() << "Skipping file " << filename << " from "
- << from.fileName() << " - filtered";
- continue;
- }
- if (contained.contains(filename))
- {
- qDebug() << "Skipping already contained file " << filename << " from "
- << from.fileName();
- continue;
- }
- contained.insert(filename);
-
- if (!fileInsideMod.open(QIODevice::ReadOnly))
- {
- qCritical() << "Failed to open " << filename << " from " << from.fileName();
- return false;
- }
-
- QuaZipNewInfo info_out(fileInsideMod.getActualFileName());
-
- if (!zipOutFile.open(QIODevice::WriteOnly, info_out))
- {
- qCritical() << "Failed to open " << filename << " in the jar";
- fileInsideMod.close();
- return false;
- }
- if (!JlCompress::copyData(fileInsideMod, zipOutFile))
- {
- zipOutFile.close();
- fileInsideMod.close();
- qCritical() << "Failed to copy data of " << filename << " into the jar";
- return false;
- }
- zipOutFile.close();
- fileInsideMod.close();
- }
- return true;
+ QuaZip modZip(from.filePath());
+ modZip.open(QuaZip::mdUnzip);
+
+ QuaZipFile fileInsideMod(&modZip);
+ QuaZipFile zipOutFile(into);
+ for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile())
+ {
+ QString filename = modZip.getCurrentFileName();
+ if (filter && !filter(filename))
+ {
+ qDebug() << "Skipping file " << filename << " from "
+ << from.fileName() << " - filtered";
+ continue;
+ }
+ if (contained.contains(filename))
+ {
+ qDebug() << "Skipping already contained file " << filename << " from "
+ << from.fileName();
+ continue;
+ }
+ contained.insert(filename);
+
+ if (!fileInsideMod.open(QIODevice::ReadOnly))
+ {
+ qCritical() << "Failed to open " << filename << " from " << from.fileName();
+ return false;
+ }
+
+ QuaZipNewInfo info_out(fileInsideMod.getActualFileName());
+
+ if (!zipOutFile.open(QIODevice::WriteOnly, info_out))
+ {
+ qCritical() << "Failed to open " << filename << " in the jar";
+ fileInsideMod.close();
+ return false;
+ }
+ if (!JlCompress::copyData(fileInsideMod, zipOutFile))
+ {
+ zipOutFile.close();
+ fileInsideMod.close();
+ qCritical() << "Failed to copy data of " << filename << " into the jar";
+ return false;
+ }
+ zipOutFile.close();
+ fileInsideMod.close();
+ }
+ return true;
}
// ours
bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods)
{
- QuaZip zipOut(targetJarPath);
- if (!zipOut.open(QuaZip::mdCreate))
- {
- QFile::remove(targetJarPath);
- qCritical() << "Failed to open the minecraft.jar for modding";
- return false;
- }
- // Files already added to the jar.
- // These files will be skipped.
- QSet<QString> addedFiles;
-
- // Modify the jar
- QListIterator<Mod> i(mods);
+ QuaZip zipOut(targetJarPath);
+ if (!zipOut.open(QuaZip::mdCreate))
+ {
+ QFile::remove(targetJarPath);
+ qCritical() << "Failed to open the minecraft.jar for modding";
+ return false;
+ }
+ // Files already added to the jar.
+ // These files will be skipped.
+ QSet<QString> addedFiles;
+
+ // Modify the jar
+ QListIterator<Mod> i(mods);
i.toBack();
while (i.hasPrevious())
- {
- const Mod &mod = i.previous();
- // do not merge disabled mods.
- if (!mod.enabled())
- continue;
- if (mod.type() == Mod::MOD_ZIPFILE)
- {
- if (!mergeZipFiles(&zipOut, mod.filename(), addedFiles))
- {
- zipOut.close();
- QFile::remove(targetJarPath);
- qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
- return false;
- }
- }
- else if (mod.type() == Mod::MOD_SINGLEFILE)
- {
- // FIXME: buggy - does not work with addedFiles
- auto filename = mod.filename();
- if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName()))
- {
- zipOut.close();
- QFile::remove(targetJarPath);
- qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
- return false;
- }
- addedFiles.insert(filename.fileName());
- }
- else if (mod.type() == Mod::MOD_FOLDER)
- {
- // FIXME: buggy - does not work with addedFiles
- auto filename = mod.filename();
- QString what_to_zip = filename.absoluteFilePath();
- QDir dir(what_to_zip);
- dir.cdUp();
- QString parent_dir = dir.absolutePath();
- if (!JlCompress::compressSubDir(&zipOut, what_to_zip, parent_dir, addedFiles))
- {
- zipOut.close();
- QFile::remove(targetJarPath);
- qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
- return false;
- }
- qDebug() << "Adding folder " << filename.fileName() << " from "
- << filename.absoluteFilePath();
- }
- else
- {
- // Make sure we do not continue launching when something is missing or undefined...
- zipOut.close();
- QFile::remove(targetJarPath);
- qCritical() << "Failed to add unknown mod type" << mod.filename().fileName() << "to the jar.";
- return false;
- }
- }
-
- if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, [](const QString key){return !key.contains("META-INF");}))
- {
- zipOut.close();
- QFile::remove(targetJarPath);
- qCritical() << "Failed to insert minecraft.jar contents.";
- return false;
- }
-
- // Recompress the jar
- zipOut.close();
- if (zipOut.getZipError() != 0)
- {
- QFile::remove(targetJarPath);
- qCritical() << "Failed to finalize minecraft.jar!";
- return false;
- }
- return true;
+ {
+ const Mod &mod = i.previous();
+ // do not merge disabled mods.
+ if (!mod.enabled())
+ continue;
+ if (mod.type() == Mod::MOD_ZIPFILE)
+ {
+ if (!mergeZipFiles(&zipOut, mod.filename(), addedFiles))
+ {
+ zipOut.close();
+ QFile::remove(targetJarPath);
+ qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
+ return false;
+ }
+ }
+ else if (mod.type() == Mod::MOD_SINGLEFILE)
+ {
+ // FIXME: buggy - does not work with addedFiles
+ auto filename = mod.filename();
+ if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName()))
+ {
+ zipOut.close();
+ QFile::remove(targetJarPath);
+ qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
+ return false;
+ }
+ addedFiles.insert(filename.fileName());
+ }
+ else if (mod.type() == Mod::MOD_FOLDER)
+ {
+ // FIXME: buggy - does not work with addedFiles
+ auto filename = mod.filename();
+ QString what_to_zip = filename.absoluteFilePath();
+ QDir dir(what_to_zip);
+ dir.cdUp();
+ QString parent_dir = dir.absolutePath();
+ if (!JlCompress::compressSubDir(&zipOut, what_to_zip, parent_dir, addedFiles))
+ {
+ zipOut.close();
+ QFile::remove(targetJarPath);
+ qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
+ return false;
+ }
+ qDebug() << "Adding folder " << filename.fileName() << " from "
+ << filename.absoluteFilePath();
+ }
+ else
+ {
+ // Make sure we do not continue launching when something is missing or undefined...
+ zipOut.close();
+ QFile::remove(targetJarPath);
+ qCritical() << "Failed to add unknown mod type" << mod.filename().fileName() << "to the jar.";
+ return false;
+ }
+ }
+
+ if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, [](const QString key){return !key.contains("META-INF");}))
+ {
+ zipOut.close();
+ QFile::remove(targetJarPath);
+ qCritical() << "Failed to insert minecraft.jar contents.";
+ return false;
+ }
+
+ // Recompress the jar
+ zipOut.close();
+ if (zipOut.getZipError() != 0)
+ {
+ QFile::remove(targetJarPath);
+ qCritical() << "Failed to finalize minecraft.jar!";
+ return false;
+ }
+ return true;
}
// ours
QString MMCZip::findFolderOfFileInZip(QuaZip * zip, const QString & what, const QString &root)
{
- QuaZipDir rootDir(zip, root);
- for(auto fileName: rootDir.entryList(QDir::Files))
- {
- if(fileName == what)
- return root;
- }
- for(auto fileName: rootDir.entryList(QDir::Dirs))
- {
- QString result = findFolderOfFileInZip(zip, what, root + fileName);
- if(!result.isEmpty())
- {
- return result;
- }
- }
- return QString();
+ QuaZipDir rootDir(zip, root);
+ for(auto fileName: rootDir.entryList(QDir::Files))
+ {
+ if(fileName == what)
+ return root;
+ }
+ for(auto fileName: rootDir.entryList(QDir::Dirs))
+ {
+ QString result = findFolderOfFileInZip(zip, what, root + fileName);
+ if(!result.isEmpty())
+ {
+ return result;
+ }
+ }
+ return QString();
}
// ours
bool MMCZip::findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root)
{
- QuaZipDir rootDir(zip, root);
- for(auto fileName: rootDir.entryList(QDir::Files))
- {
- if(fileName == what)
- {
- result.append(root);
- return true;
- }
- }
- for(auto fileName: rootDir.entryList(QDir::Dirs))
- {
- findFilesInZip(zip, what, result, root + fileName);
- }
- return !result.isEmpty();
+ QuaZipDir rootDir(zip, root);
+ for(auto fileName: rootDir.entryList(QDir::Files))
+ {
+ if(fileName == what)
+ {
+ result.append(root);
+ return true;
+ }
+ }
+ for(auto fileName: rootDir.entryList(QDir::Dirs))
+ {
+ findFilesInZip(zip, what, result, root + fileName);
+ }
+ return !result.isEmpty();
}
// ours
QStringList MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target)
{
- QDir directory(target);
- QStringList extracted;
- qDebug() << "Extracting subdir" << subdir << "from" << zip->getZipName() << "to" << target;
- if (!zip->goToFirstFile())
- {
- qWarning() << "Failed to seek to first file in zip";
- return QStringList();
- }
- do
- {
- QString name = zip->getCurrentFileName();
- if(!name.startsWith(subdir))
- {
- continue;
- }
- name.remove(0, subdir.size());
- QString absFilePath = directory.absoluteFilePath(name);
- if(name.isEmpty())
- {
- absFilePath += "/";
- }
- if (!JlCompress::extractFile(zip, "", absFilePath))
- {
- qWarning() << "Failed to extract file" << name << "to" << absFilePath;
- JlCompress::removeFile(extracted);
- return QStringList();
- }
- extracted.append(absFilePath);
- qDebug() << "Extracted file" << name;
- } while (zip->goToNextFile());
- return extracted;
+ QDir directory(target);
+ QStringList extracted;
+ qDebug() << "Extracting subdir" << subdir << "from" << zip->getZipName() << "to" << target;
+ if (!zip->goToFirstFile())
+ {
+ qWarning() << "Failed to seek to first file in zip";
+ return QStringList();
+ }
+ do
+ {
+ QString name = zip->getCurrentFileName();
+ if(!name.startsWith(subdir))
+ {
+ continue;
+ }
+ name.remove(0, subdir.size());
+ QString absFilePath = directory.absoluteFilePath(name);
+ if(name.isEmpty())
+ {
+ absFilePath += "/";
+ }
+ if (!JlCompress::extractFile(zip, "", absFilePath))
+ {
+ qWarning() << "Failed to extract file" << name << "to" << absFilePath;
+ JlCompress::removeFile(extracted);
+ return QStringList();
+ }
+ extracted.append(absFilePath);
+ qDebug() << "Extracted file" << name;
+ } while (zip->goToNextFile());
+ return extracted;
}
// ours
QStringList MMCZip::extractDir(QString fileCompressed, QString dir)
{
- QuaZip zip(fileCompressed);
- if (!zip.open(QuaZip::mdUnzip))
- {
- return {};
- }
- return MMCZip::extractSubDir(&zip, "", dir);
+ QuaZip zip(fileCompressed);
+ if (!zip.open(QuaZip::mdUnzip))
+ {
+ return {};
+ }
+ return MMCZip::extractSubDir(&zip, "", dir);
}
diff --git a/api/logic/MMCZip.h b/api/logic/MMCZip.h
index 68094b2c..4eb86361 100644
--- a/api/logic/MMCZip.h
+++ b/api/logic/MMCZip.h
@@ -28,44 +28,44 @@
namespace MMCZip
{
- /**
- * Merge two zip files, using a filter function
- */
- bool MULTIMC_LOGIC_EXPORT mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
- const JlCompress::FilterFunction filter = nullptr);
+ /**
+ * Merge two zip files, using a filter function
+ */
+ bool MULTIMC_LOGIC_EXPORT mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
+ const JlCompress::FilterFunction filter = nullptr);
- /**
- * take a source jar, add mods to it, resulting in target jar
- */
- bool MULTIMC_LOGIC_EXPORT createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods);
+ /**
+ * take a source jar, add mods to it, resulting in target jar
+ */
+ bool MULTIMC_LOGIC_EXPORT createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods);
- /**
- * Find a single file in archive by file name (not path)
- *
- * \return the path prefix where the file is
- */
- QString MULTIMC_LOGIC_EXPORT findFolderOfFileInZip(QuaZip * zip, const QString & what, const QString &root = QString(""));
+ /**
+ * Find a single file in archive by file name (not path)
+ *
+ * \return the path prefix where the file is
+ */
+ QString MULTIMC_LOGIC_EXPORT findFolderOfFileInZip(QuaZip * zip, const QString & what, const QString &root = QString(""));
- /**
- * Find a multiple files of the same name in archive by file name
- * If a file is found in a path, no deeper paths are searched
- *
- * \return true if anything was found
- */
- bool MULTIMC_LOGIC_EXPORT findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root = QString());
+ /**
+ * Find a multiple files of the same name in archive by file name
+ * If a file is found in a path, no deeper paths are searched
+ *
+ * \return true if anything was found
+ */
+ bool MULTIMC_LOGIC_EXPORT findFilesInZip(QuaZip * zip, const QString & what, QStringList & result, const QString &root = QString());
- /**
- * Extract a subdirectory from an archive
- */
- QStringList MULTIMC_LOGIC_EXPORT extractSubDir(QuaZip *zip, const QString & subdir, const QString &target);
+ /**
+ * Extract a subdirectory from an archive
+ */
+ QStringList MULTIMC_LOGIC_EXPORT extractSubDir(QuaZip *zip, const QString & subdir, const QString &target);
- /**
- * Extract a whole archive.
- *
- * \param fileCompressed The name of the archive.
- * \param dir The directory to extract to, the current directory if left empty.
- * \return The list of the full paths of the files extracted, empty on failure.
- */
- QStringList MULTIMC_LOGIC_EXPORT extractDir(QString fileCompressed, QString dir);
+ /**
+ * Extract a whole archive.
+ *
+ * \param fileCompressed The name of the archive.
+ * \param dir The directory to extract to, the current directory if left empty.
+ * \return The list of the full paths of the files extracted, empty on failure.
+ */
+ QStringList MULTIMC_LOGIC_EXPORT extractDir(QString fileCompressed, QString dir);
}
diff --git a/api/logic/MessageLevel.cpp b/api/logic/MessageLevel.cpp
index a5191290..0a2cd23d 100644
--- a/api/logic/MessageLevel.cpp
+++ b/api/logic/MessageLevel.cpp
@@ -2,35 +2,35 @@
MessageLevel::Enum MessageLevel::getLevel(const QString& levelName)
{
- if (levelName == "MultiMC")
- return MessageLevel::MultiMC;
- else if (levelName == "Debug")
- return MessageLevel::Debug;
- else if (levelName == "Info")
- return MessageLevel::Info;
- else if (levelName == "Message")
- return MessageLevel::Message;
- else if (levelName == "Warning")
- return MessageLevel::Warning;
- else if (levelName == "Error")
- return MessageLevel::Error;
- else if (levelName == "Fatal")
- return MessageLevel::Fatal;
- // Skip PrePost, it's not exposed to !![]!
- // Also skip StdErr and StdOut
- else
- return MessageLevel::Unknown;
+ if (levelName == "MultiMC")
+ return MessageLevel::MultiMC;
+ else if (levelName == "Debug")
+ return MessageLevel::Debug;
+ else if (levelName == "Info")
+ return MessageLevel::Info;
+ else if (levelName == "Message")
+ return MessageLevel::Message;
+ else if (levelName == "Warning")
+ return MessageLevel::Warning;
+ else if (levelName == "Error")
+ return MessageLevel::Error;
+ else if (levelName == "Fatal")
+ return MessageLevel::Fatal;
+ // Skip PrePost, it's not exposed to !![]!
+ // Also skip StdErr and StdOut
+ else
+ return MessageLevel::Unknown;
}
MessageLevel::Enum MessageLevel::fromLine(QString &line)
{
- // Level prefix
- int endmark = line.indexOf("]!");
- if (line.startsWith("!![") && endmark != -1)
- {
- auto level = MessageLevel::getLevel(line.left(endmark).mid(3));
- line = line.mid(endmark + 2);
- return level;
- }
- return MessageLevel::Unknown;
+ // Level prefix
+ int endmark = line.indexOf("]!");
+ if (line.startsWith("!![") && endmark != -1)
+ {
+ auto level = MessageLevel::getLevel(line.left(endmark).mid(3));
+ line = line.mid(endmark + 2);
+ return level;
+ }
+ return MessageLevel::Unknown;
}
diff --git a/api/logic/MessageLevel.h b/api/logic/MessageLevel.h
index 0128148d..f19048e3 100644
--- a/api/logic/MessageLevel.h
+++ b/api/logic/MessageLevel.h
@@ -10,16 +10,16 @@ namespace MessageLevel
{
enum Enum
{
- Unknown, /**< No idea what this is or where it came from */
- StdOut, /**< Undetermined stderr messages */
- StdErr, /**< Undetermined stdout messages */
- MultiMC, /**< MultiMC Messages */
- Debug, /**< Debug Messages */
- Info, /**< Info Messages */
- Message, /**< Standard Messages */
- Warning, /**< Warnings */
- Error, /**< Errors */
- Fatal, /**< Fatal Errors */
+ Unknown, /**< No idea what this is or where it came from */
+ StdOut, /**< Undetermined stderr messages */
+ StdErr, /**< Undetermined stdout messages */
+ MultiMC, /**< MultiMC Messages */
+ Debug, /**< Debug Messages */
+ Info, /**< Info Messages */
+ Message, /**< Standard Messages */
+ Warning, /**< Warnings */
+ Error, /**< Errors */
+ Fatal, /**< Fatal Errors */
};
MessageLevel::Enum getLevel(const QString &levelName);
diff --git a/api/logic/NullInstance.h b/api/logic/NullInstance.h
index 64965277..861a2f57 100644
--- a/api/logic/NullInstance.h
+++ b/api/logic/NullInstance.h
@@ -4,74 +4,74 @@
class NullInstance: public BaseInstance
{
public:
- NullInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir)
- :BaseInstance(globalSettings, settings, rootDir)
- {
- setVersionBroken(true);
- }
- virtual ~NullInstance() {};
- virtual void init() override
- {
- }
- virtual void saveNow() override
- {
- }
- virtual QString getStatusbarDescription() override
- {
- return tr("Unknown instance type");
- };
- virtual QSet< QString > traits() const override
- {
- return {};
- };
- virtual QString instanceConfigFolder() const override
- {
- return instanceRoot();
- };
- virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr) override
- {
- return nullptr;
- }
- virtual shared_qobject_ptr< Task > createUpdateTask(Net::Mode mode) override
- {
- return nullptr;
- }
- virtual QProcessEnvironment createEnvironment() override
- {
- return QProcessEnvironment();
- }
- virtual QMap<QString, QString> getVariables() const override
- {
- return QMap<QString, QString>();
- }
- virtual IPathMatcher::Ptr getLogFileMatcher() override
- {
- return nullptr;
- }
- virtual QString getLogFileRoot() override
- {
- return instanceRoot();
- }
- virtual QString typeName() const override
- {
- return "Null";
- }
- bool canExport() const override
- {
- return false;
- }
- bool canEdit() const override
- {
- return false;
- }
- bool canLaunch() const override
- {
- return false;
- }
- QStringList verboseDescription(AuthSessionPtr session) override
- {
- QStringList out;
- out << "Null instance - placeholder.";
- return out;
- }
+ NullInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir)
+ :BaseInstance(globalSettings, settings, rootDir)
+ {
+ setVersionBroken(true);
+ }
+ virtual ~NullInstance() {};
+ virtual void init() override
+ {
+ }
+ virtual void saveNow() override
+ {
+ }
+ virtual QString getStatusbarDescription() override
+ {
+ return tr("Unknown instance type");
+ };
+ virtual QSet< QString > traits() const override
+ {
+ return {};
+ };
+ virtual QString instanceConfigFolder() const override
+ {
+ return instanceRoot();
+ };
+ virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr) override
+ {
+ return nullptr;
+ }
+ virtual shared_qobject_ptr< Task > createUpdateTask(Net::Mode mode) override
+ {
+ return nullptr;
+ }
+ virtual QProcessEnvironment createEnvironment() override
+ {
+ return QProcessEnvironment();
+ }
+ virtual QMap<QString, QString> getVariables() const override
+ {
+ return QMap<QString, QString>();
+ }
+ virtual IPathMatcher::Ptr getLogFileMatcher() override
+ {
+ return nullptr;
+ }
+ virtual QString getLogFileRoot() override
+ {
+ return instanceRoot();
+ }
+ virtual QString typeName() const override
+ {
+ return "Null";
+ }
+ bool canExport() const override
+ {
+ return false;
+ }
+ bool canEdit() const override
+ {
+ return false;
+ }
+ bool canLaunch() const override
+ {
+ return false;
+ }
+ QStringList verboseDescription(AuthSessionPtr session) override
+ {
+ QStringList out;
+ out << "Null instance - placeholder.";
+ return out;
+ }
};
diff --git a/api/logic/ProblemProvider.h b/api/logic/ProblemProvider.h
index 978710f0..33c9d364 100644
--- a/api/logic/ProblemProvider.h
+++ b/api/logic/ProblemProvider.h
@@ -4,46 +4,46 @@
enum class ProblemSeverity
{
- None,
- Warning,
- Error
+ None,
+ Warning,
+ Error
};
struct PatchProblem
{
- ProblemSeverity m_severity;
- QString m_description;
+ ProblemSeverity m_severity;
+ QString m_description;
};
class MULTIMC_LOGIC_EXPORT ProblemProvider
{
public:
- virtual ~ProblemProvider() {};
- virtual const QList<PatchProblem> getProblems() const = 0;
- virtual ProblemSeverity getProblemSeverity() const = 0;
+ virtual ~ProblemProvider() {};
+ virtual const QList<PatchProblem> getProblems() const = 0;
+ virtual ProblemSeverity getProblemSeverity() const = 0;
};
class MULTIMC_LOGIC_EXPORT ProblemContainer : public ProblemProvider
{
public:
- const QList<PatchProblem> getProblems() const override
- {
- return m_problems;
- }
- ProblemSeverity getProblemSeverity() const override
- {
- return m_problemSeverity;
- }
- virtual void addProblem(ProblemSeverity severity, const QString &description)
- {
- if(severity > m_problemSeverity)
- {
- m_problemSeverity = severity;
- }
- m_problems.append({severity, description});
- }
+ const QList<PatchProblem> getProblems() const override
+ {
+ return m_problems;
+ }
+ ProblemSeverity getProblemSeverity() const override
+ {
+ return m_problemSeverity;
+ }
+ virtual void addProblem(ProblemSeverity severity, const QString &description)
+ {
+ if(severity > m_problemSeverity)
+ {
+ m_problemSeverity = severity;
+ }
+ m_problems.append({severity, description});
+ }
private:
- QList<PatchProblem> m_problems;
- ProblemSeverity m_problemSeverity = ProblemSeverity::None;
+ QList<PatchProblem> m_problems;
+ ProblemSeverity m_problemSeverity = ProblemSeverity::None;
};
diff --git a/api/logic/QObjectPtr.h b/api/logic/QObjectPtr.h
index 4a42f728..0ff51136 100644
--- a/api/logic/QObjectPtr.h
+++ b/api/logic/QObjectPtr.h
@@ -8,10 +8,10 @@ namespace details
{
struct DeleteQObjectLater
{
- void operator()(QObject *obj) const
- {
- obj->deleteLater();
- }
+ void operator()(QObject *obj) const
+ {
+ obj->deleteLater();
+ }
};
}
/**
@@ -28,56 +28,56 @@ template <typename T>
class shared_qobject_ptr
{
public:
- shared_qobject_ptr(){}
- shared_qobject_ptr(T * wrap)
- {
- reset(wrap);
- }
- shared_qobject_ptr(const shared_qobject_ptr<T>& other)
- {
- m_ptr = other.m_ptr;
- }
- template<typename Derived>
- shared_qobject_ptr(const shared_qobject_ptr<Derived> &other)
- {
- m_ptr = other.unwrap();
- }
+ shared_qobject_ptr(){}
+ shared_qobject_ptr(T * wrap)
+ {
+ reset(wrap);
+ }
+ shared_qobject_ptr(const shared_qobject_ptr<T>& other)
+ {
+ m_ptr = other.m_ptr;
+ }
+ template<typename Derived>
+ shared_qobject_ptr(const shared_qobject_ptr<Derived> &other)
+ {
+ m_ptr = other.unwrap();
+ }
public:
- void reset(T * wrap)
- {
- using namespace std::placeholders;
- m_ptr.reset(wrap, std::bind(&QObject::deleteLater, _1));
- }
- void reset(const shared_qobject_ptr<T> &other)
- {
- m_ptr = other.m_ptr;
- }
- void reset()
- {
- m_ptr.reset();
- }
- T * get() const
- {
- return m_ptr.get();
- }
- T * operator->() const
- {
- return m_ptr.get();
- }
- T & operator*() const
- {
- return *m_ptr.get();
- }
- operator bool() const
- {
- return m_ptr.get() != nullptr;
- }
- const std::shared_ptr <T> unwrap() const
- {
- return m_ptr;
- }
+ void reset(T * wrap)
+ {
+ using namespace std::placeholders;
+ m_ptr.reset(wrap, std::bind(&QObject::deleteLater, _1));
+ }
+ void reset(const shared_qobject_ptr<T> &other)
+ {
+ m_ptr = other.m_ptr;
+ }
+ void reset()
+ {
+ m_ptr.reset();
+ }
+ T * get() const
+ {
+ return m_ptr.get();
+ }
+ T * operator->() const
+ {
+ return m_ptr.get();
+ }
+ T & operator*() const
+ {
+ return *m_ptr.get();
+ }
+ operator bool() const
+ {
+ return m_ptr.get() != nullptr;
+ }
+ const std::shared_ptr <T> unwrap() const
+ {
+ return m_ptr;
+ }
private:
- std::shared_ptr <T> m_ptr;
+ std::shared_ptr <T> m_ptr;
};
diff --git a/api/logic/RWStorage.h b/api/logic/RWStorage.h
index 4afbd96c..5d792367 100644
--- a/api/logic/RWStorage.h
+++ b/api/logic/RWStorage.h
@@ -5,59 +5,59 @@ template <typename K, typename V>
class RWStorage
{
public:
- void add(K key, V value)
- {
- QWriteLocker l(&lock);
- cache[key] = value;
- stale_entries.remove(key);
- }
- V get(K key)
- {
- QReadLocker l(&lock);
- if(cache.contains(key))
- {
- return cache[key];
- }
- else return V();
- }
- bool get(K key, V& value)
- {
- QReadLocker l(&lock);
- if(cache.contains(key))
- {
- value = cache[key];
- return true;
- }
- else return false;
- }
- bool has(K key)
- {
- QReadLocker l(&lock);
- return cache.contains(key);
- }
- bool stale(K key)
- {
- QReadLocker l(&lock);
- if(!cache.contains(key))
- return true;
- return stale_entries.contains(key);
- }
- void setStale(K key)
- {
- QWriteLocker l(&lock);
- if(cache.contains(key))
- {
- stale_entries.insert(key);
- }
- }
- void clear()
- {
- QWriteLocker l(&lock);
- cache.clear();
- stale_entries.clear();
- }
+ void add(K key, V value)
+ {
+ QWriteLocker l(&lock);
+ cache[key] = value;
+ stale_entries.remove(key);
+ }
+ V get(K key)
+ {
+ QReadLocker l(&lock);
+ if(cache.contains(key))
+ {
+ return cache[key];
+ }
+ else return V();
+ }
+ bool get(K key, V& value)
+ {
+ QReadLocker l(&lock);
+ if(cache.contains(key))
+ {
+ value = cache[key];
+ return true;
+ }
+ else return false;
+ }
+ bool has(K key)
+ {
+ QReadLocker l(&lock);
+ return cache.contains(key);
+ }
+ bool stale(K key)
+ {
+ QReadLocker l(&lock);
+ if(!cache.contains(key))
+ return true;
+ return stale_entries.contains(key);
+ }
+ void setStale(K key)
+ {
+ QWriteLocker l(&lock);
+ if(cache.contains(key))
+ {
+ stale_entries.insert(key);
+ }
+ }
+ void clear()
+ {
+ QWriteLocker l(&lock);
+ cache.clear();
+ stale_entries.clear();
+ }
private:
- QReadWriteLock lock;
- QMap<K, V> cache;
- QSet<K> stale_entries;
+ QReadWriteLock lock;
+ QMap<K, V> cache;
+ QSet<K> stale_entries;
};
diff --git a/api/logic/RecursiveFileSystemWatcher.cpp b/api/logic/RecursiveFileSystemWatcher.cpp
index 59c3f0f0..b7417cdf 100644
--- a/api/logic/RecursiveFileSystemWatcher.cpp
+++ b/api/logic/RecursiveFileSystemWatcher.cpp
@@ -4,108 +4,108 @@
#include <QDebug>
RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject *parent)
- : QObject(parent), m_watcher(new QFileSystemWatcher(this))
+ : QObject(parent), m_watcher(new QFileSystemWatcher(this))
{
- connect(m_watcher, &QFileSystemWatcher::fileChanged, this,
- &RecursiveFileSystemWatcher::fileChange);
- connect(m_watcher, &QFileSystemWatcher::directoryChanged, this,
- &RecursiveFileSystemWatcher::directoryChange);
+ connect(m_watcher, &QFileSystemWatcher::fileChanged, this,
+ &RecursiveFileSystemWatcher::fileChange);
+ connect(m_watcher, &QFileSystemWatcher::directoryChanged, this,
+ &RecursiveFileSystemWatcher::directoryChange);
}
void RecursiveFileSystemWatcher::setRootDir(const QDir &root)
{
- bool wasEnabled = m_isEnabled;
- disable();
- m_root = root;
- setFiles(scanRecursive(m_root));
- if (wasEnabled)
- {
- enable();
- }
+ bool wasEnabled = m_isEnabled;
+ disable();
+ m_root = root;
+ setFiles(scanRecursive(m_root));
+ if (wasEnabled)
+ {
+ enable();
+ }
}
void RecursiveFileSystemWatcher::setWatchFiles(const bool watchFiles)
{
- bool wasEnabled = m_isEnabled;
- disable();
- m_watchFiles = watchFiles;
- if (wasEnabled)
- {
- enable();
- }
+ bool wasEnabled = m_isEnabled;
+ disable();
+ m_watchFiles = watchFiles;
+ if (wasEnabled)
+ {
+ enable();
+ }
}
void RecursiveFileSystemWatcher::enable()
{
- if (m_isEnabled)
- {
- return;
- }
- Q_ASSERT(m_root != QDir::root());
- addFilesToWatcherRecursive(m_root);
- m_isEnabled = true;
+ if (m_isEnabled)
+ {
+ return;
+ }
+ Q_ASSERT(m_root != QDir::root());
+ addFilesToWatcherRecursive(m_root);
+ m_isEnabled = true;
}
void RecursiveFileSystemWatcher::disable()
{
- if (!m_isEnabled)
- {
- return;
- }
- m_isEnabled = false;
- m_watcher->removePaths(m_watcher->files());
- m_watcher->removePaths(m_watcher->directories());
+ if (!m_isEnabled)
+ {
+ return;
+ }
+ m_isEnabled = false;
+ m_watcher->removePaths(m_watcher->files());
+ m_watcher->removePaths(m_watcher->directories());
}
void RecursiveFileSystemWatcher::setFiles(const QStringList &files)
{
- if (files != m_files)
- {
- m_files = files;
- emit filesChanged();
- }
+ if (files != m_files)
+ {
+ m_files = files;
+ emit filesChanged();
+ }
}
void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir &dir)
{
- m_watcher->addPath(dir.absolutePath());
- for (const QString &directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
- {
- addFilesToWatcherRecursive(dir.absoluteFilePath(directory));
- }
- if (m_watchFiles)
- {
- for (const QFileInfo &info : dir.entryInfoList(QDir::Files))
- {
- m_watcher->addPath(info.absoluteFilePath());
- }
- }
+ m_watcher->addPath(dir.absolutePath());
+ for (const QString &directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
+ {
+ addFilesToWatcherRecursive(dir.absoluteFilePath(directory));
+ }
+ if (m_watchFiles)
+ {
+ for (const QFileInfo &info : dir.entryInfoList(QDir::Files))
+ {
+ m_watcher->addPath(info.absoluteFilePath());
+ }
+ }
}
QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir &directory)
{
- QStringList ret;
- if(!m_matcher)
- {
- return {};
- }
- for (const QString &dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden))
- {
- ret.append(scanRecursive(directory.absoluteFilePath(dir)));
- }
- for (const QString &file : directory.entryList(QDir::Files | QDir::Hidden))
- {
- auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file));
- if (m_matcher->matches(relPath))
- {
- ret.append(relPath);
- }
- }
- return ret;
+ QStringList ret;
+ if(!m_matcher)
+ {
+ return {};
+ }
+ for (const QString &dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden))
+ {
+ ret.append(scanRecursive(directory.absoluteFilePath(dir)));
+ }
+ for (const QString &file : directory.entryList(QDir::Files | QDir::Hidden))
+ {
+ auto relPath = m_root.relativeFilePath(directory.absoluteFilePath(file));
+ if (m_matcher->matches(relPath))
+ {
+ ret.append(relPath);
+ }
+ }
+ return ret;
}
void RecursiveFileSystemWatcher::fileChange(const QString &path)
{
- emit fileChanged(path);
+ emit fileChanged(path);
}
void RecursiveFileSystemWatcher::directoryChange(const QString &path)
{
- setFiles(scanRecursive(m_root));
+ setFiles(scanRecursive(m_root));
}
diff --git a/api/logic/RecursiveFileSystemWatcher.h b/api/logic/RecursiveFileSystemWatcher.h
index 07bce0b9..c9c39f49 100644
--- a/api/logic/RecursiveFileSystemWatcher.h
+++ b/api/logic/RecursiveFileSystemWatcher.h
@@ -8,56 +8,56 @@
class MULTIMC_LOGIC_EXPORT RecursiveFileSystemWatcher : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- RecursiveFileSystemWatcher(QObject *parent);
-
- void setRootDir(const QDir &root);
- QDir rootDir() const
- {
- return m_root;
- }
-
- // WARNING: setting this to true may be bad for performance
- void setWatchFiles(const bool watchFiles);
- bool watchFiles() const
- {
- return m_watchFiles;
- }
-
- void setMatcher(IPathMatcher::Ptr matcher)
- {
- m_matcher = matcher;
- }
-
- QStringList files() const
- {
- return m_files;
- }
+ RecursiveFileSystemWatcher(QObject *parent);
+
+ void setRootDir(const QDir &root);
+ QDir rootDir() const
+ {
+ return m_root;
+ }
+
+ // WARNING: setting this to true may be bad for performance
+ void setWatchFiles(const bool watchFiles);
+ bool watchFiles() const
+ {
+ return m_watchFiles;
+ }
+
+ void setMatcher(IPathMatcher::Ptr matcher)
+ {
+ m_matcher = matcher;
+ }
+
+ QStringList files() const
+ {
+ return m_files;
+ }
signals:
- void filesChanged();
- void fileChanged(const QString &path);
+ void filesChanged();
+ void fileChanged(const QString &path);
public slots:
- void enable();
- void disable();
+ void enable();
+ void disable();
private:
- QDir m_root;
- bool m_watchFiles = false;
- bool m_isEnabled = false;
- IPathMatcher::Ptr m_matcher;
+ QDir m_root;
+ bool m_watchFiles = false;
+ bool m_isEnabled = false;
+ IPathMatcher::Ptr m_matcher;
- QFileSystemWatcher *m_watcher;
+ QFileSystemWatcher *m_watcher;
- QStringList m_files;
- void setFiles(const QStringList &files);
+ QStringList m_files;
+ void setFiles(const QStringList &files);
- void addFilesToWatcherRecursive(const QDir &dir);
- QStringList scanRecursive(const QDir &dir);
+ void addFilesToWatcherRecursive(const QDir &dir);
+ QStringList scanRecursive(const QDir &dir);
private slots:
- void fileChange(const QString &path);
- void directoryChange(const QString &path);
+ void fileChange(const QString &path);
+ void directoryChange(const QString &path);
};
diff --git a/api/logic/SeparatorPrefixTree.h b/api/logic/SeparatorPrefixTree.h
index fd149af0..7a841cb7 100644
--- a/api/logic/SeparatorPrefixTree.h
+++ b/api/logic/SeparatorPrefixTree.h
@@ -7,292 +7,292 @@ template <char Tseparator>
class SeparatorPrefixTree
{
public:
- SeparatorPrefixTree(QStringList paths)
- {
- insert(paths);
- }
+ SeparatorPrefixTree(QStringList paths)
+ {
+ insert(paths);
+ }
- SeparatorPrefixTree(bool contained = false)
- {
- m_contained = contained;
- }
+ SeparatorPrefixTree(bool contained = false)
+ {
+ m_contained = contained;
+ }
- void insert(QStringList paths)
- {
- for(auto &path: paths)
- {
- insert(path);
- }
- }
+ void insert(QStringList paths)
+ {
+ for(auto &path: paths)
+ {
+ insert(path);
+ }
+ }
- /// insert an exact path into the tree
- SeparatorPrefixTree & insert(QString path)
- {
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- children[path] = SeparatorPrefixTree(true);
- return children[path];
- }
- else
- {
- auto prefix = path.left(sepIndex);
- if(!children.contains(prefix))
- {
- children[prefix] = SeparatorPrefixTree(false);
- }
- return children[prefix].insert(path.mid(sepIndex + 1));
- }
- }
+ /// insert an exact path into the tree
+ SeparatorPrefixTree & insert(QString path)
+ {
+ auto sepIndex = path.indexOf(Tseparator);
+ if(sepIndex == -1)
+ {
+ children[path] = SeparatorPrefixTree(true);
+ return children[path];
+ }
+ else
+ {
+ auto prefix = path.left(sepIndex);
+ if(!children.contains(prefix))
+ {
+ children[prefix] = SeparatorPrefixTree(false);
+ }
+ return children[prefix].insert(path.mid(sepIndex + 1));
+ }
+ }
- /// is the path fully contained in the tree?
- bool contains(QString path) const
- {
- auto node = find(path);
- return node != nullptr;
- }
+ /// is the path fully contained in the tree?
+ bool contains(QString path) const
+ {
+ auto node = find(path);
+ return node != nullptr;
+ }
- /// does the tree cover a path? That means the prefix of the path is contained in the tree
- bool covers(QString path) const
- {
- // if we found some valid node, it's good enough. the tree covers the path
- if(m_contained)
- {
- return true;
- }
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- auto found = children.find(path);
- if(found == children.end())
- {
- return false;
- }
- return (*found).covers(QString());
- }
- else
- {
- auto prefix = path.left(sepIndex);
- auto found = children.find(prefix);
- if(found == children.end())
- {
- return false;
- }
- return (*found).covers(path.mid(sepIndex + 1));
- }
- }
+ /// does the tree cover a path? That means the prefix of the path is contained in the tree
+ bool covers(QString path) const
+ {
+ // if we found some valid node, it's good enough. the tree covers the path
+ if(m_contained)
+ {
+ return true;
+ }
+ auto sepIndex = path.indexOf(Tseparator);
+ if(sepIndex == -1)
+ {
+ auto found = children.find(path);
+ if(found == children.end())
+ {
+ return false;
+ }
+ return (*found).covers(QString());
+ }
+ else
+ {
+ auto prefix = path.left(sepIndex);
+ auto found = children.find(prefix);
+ if(found == children.end())
+ {
+ return false;
+ }
+ return (*found).covers(path.mid(sepIndex + 1));
+ }
+ }
- /// return the contained path that covers the path specified
- QString cover(QString path) const
- {
- // if we found some valid node, it's good enough. the tree covers the path
- if(m_contained)
- {
- return QString("");
- }
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- auto found = children.find(path);
- if(found == children.end())
- {
- return QString();
- }
- auto nested = (*found).cover(QString());
- if(nested.isNull())
- {
- return nested;
- }
- if(nested.isEmpty())
- return path;
- return path + Tseparator + nested;
- }
- else
- {
- auto prefix = path.left(sepIndex);
- auto found = children.find(prefix);
- if(found == children.end())
- {
- return QString();
- }
- auto nested = (*found).cover(path.mid(sepIndex + 1));
- if(nested.isNull())
- {
- return nested;
- }
- if(nested.isEmpty())
- return prefix;
- return prefix + Tseparator + nested;
- }
- }
+ /// return the contained path that covers the path specified
+ QString cover(QString path) const
+ {
+ // if we found some valid node, it's good enough. the tree covers the path
+ if(m_contained)
+ {
+ return QString("");
+ }
+ auto sepIndex = path.indexOf(Tseparator);
+ if(sepIndex == -1)
+ {
+ auto found = children.find(path);
+ if(found == children.end())
+ {
+ return QString();
+ }
+ auto nested = (*found).cover(QString());
+ if(nested.isNull())
+ {
+ return nested;
+ }
+ if(nested.isEmpty())
+ return path;
+ return path + Tseparator + nested;
+ }
+ else
+ {
+ auto prefix = path.left(sepIndex);
+ auto found = children.find(prefix);
+ if(found == children.end())
+ {
+ return QString();
+ }
+ auto nested = (*found).cover(path.mid(sepIndex + 1));
+ if(nested.isNull())
+ {
+ return nested;
+ }
+ if(nested.isEmpty())
+ return prefix;
+ return prefix + Tseparator + nested;
+ }
+ }
- /// Does the path-specified node exist in the tree? It does not have to be contained.
- bool exists(QString path) const
- {
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- auto found = children.find(path);
- if(found == children.end())
- {
- return false;
- }
- return true;
- }
- else
- {
- auto prefix = path.left(sepIndex);
- auto found = children.find(prefix);
- if(found == children.end())
- {
- return false;
- }
- return (*found).exists(path.mid(sepIndex + 1));
- }
- }
+ /// Does the path-specified node exist in the tree? It does not have to be contained.
+ bool exists(QString path) const
+ {
+ auto sepIndex = path.indexOf(Tseparator);
+ if(sepIndex == -1)
+ {
+ auto found = children.find(path);
+ if(found == children.end())
+ {
+ return false;
+ }
+ return true;
+ }
+ else
+ {
+ auto prefix = path.left(sepIndex);
+ auto found = children.find(prefix);
+ if(found == children.end())
+ {
+ return false;
+ }
+ return (*found).exists(path.mid(sepIndex + 1));
+ }
+ }
- /// find a node in the tree by name
- const SeparatorPrefixTree * find(QString path) const
- {
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- auto found = children.find(path);
- if(found == children.end())
- {
- return nullptr;
- }
- return &(*found);
- }
- else
- {
- auto prefix = path.left(sepIndex);
- auto found = children.find(prefix);
- if(found == children.end())
- {
- return nullptr;
- }
- return (*found).find(path.mid(sepIndex + 1));
- }
- }
+ /// find a node in the tree by name
+ const SeparatorPrefixTree * find(QString path) const
+ {
+ auto sepIndex = path.indexOf(Tseparator);
+ if(sepIndex == -1)
+ {
+ auto found = children.find(path);
+ if(found == children.end())
+ {
+ return nullptr;
+ }
+ return &(*found);
+ }
+ else
+ {
+ auto prefix = path.left(sepIndex);
+ auto found = children.find(prefix);
+ if(found == children.end())
+ {
+ return nullptr;
+ }
+ return (*found).find(path.mid(sepIndex + 1));
+ }
+ }
- /// is this a leaf node?
- bool leaf() const
- {
- return children.isEmpty();
- }
+ /// is this a leaf node?
+ bool leaf() const
+ {
+ return children.isEmpty();
+ }
- /// is this node actually contained in the tree, or is it purely structural?
- bool contained() const
- {
- return m_contained;
- }
+ /// is this node actually contained in the tree, or is it purely structural?
+ bool contained() const
+ {
+ return m_contained;
+ }
- /// Remove a path from the tree
- bool remove(QString path)
- {
- return removeInternal(path) != Failed;
- }
+ /// Remove a path from the tree
+ bool remove(QString path)
+ {
+ return removeInternal(path) != Failed;
+ }
- /// Clear all children of this node tree node
- void clear()
- {
- children.clear();
- }
+ /// Clear all children of this node tree node
+ void clear()
+ {
+ children.clear();
+ }
- QStringList toStringList() const
- {
- QStringList collected;
- // collecting these is more expensive.
- auto iter = children.begin();
- while(iter != children.end())
- {
- QStringList list = iter.value().toStringList();
- for(int i = 0; i < list.size(); i++)
- {
- list[i] = iter.key() + Tseparator + list[i];
- }
- collected.append(list);
- if((*iter).m_contained)
- {
- collected.append(iter.key());
- }
- iter++;
- }
- return collected;
- }
+ QStringList toStringList() const
+ {
+ QStringList collected;
+ // collecting these is more expensive.
+ auto iter = children.begin();
+ while(iter != children.end())
+ {
+ QStringList list = iter.value().toStringList();
+ for(int i = 0; i < list.size(); i++)
+ {
+ list[i] = iter.key() + Tseparator + list[i];
+ }
+ collected.append(list);
+ if((*iter).m_contained)
+ {
+ collected.append(iter.key());
+ }
+ iter++;
+ }
+ return collected;
+ }
private:
- enum Removal
- {
- Failed,
- Succeeded,
- HasChildren
- };
- Removal removeInternal(QString path = QString())
- {
- if(path.isEmpty())
- {
- if(!m_contained)
- {
- // remove all children - we are removing a prefix
- clear();
- return Succeeded;
- }
- m_contained = false;
- if(children.size())
- {
- return HasChildren;
- }
- return Succeeded;
- }
- Removal remStatus = Failed;
- QString childToRemove;
- auto sepIndex = path.indexOf(Tseparator);
- if(sepIndex == -1)
- {
- childToRemove = path;
- auto found = children.find(childToRemove);
- if(found == children.end())
- {
- return Failed;
- }
- remStatus = (*found).removeInternal();
- }
- else
- {
- childToRemove = path.left(sepIndex);
- auto found = children.find(childToRemove);
- if(found == children.end())
- {
- return Failed;
- }
- remStatus = (*found).removeInternal(path.mid(sepIndex + 1));
- }
- switch (remStatus)
- {
- case Failed:
- case HasChildren:
- {
- return remStatus;
- }
- case Succeeded:
- {
- children.remove(childToRemove);
- if(m_contained)
- {
- return HasChildren;
- }
- if(children.size())
- {
- return HasChildren;
- }
- return Succeeded;
- }
- }
- return Failed;
- }
+ enum Removal
+ {
+ Failed,
+ Succeeded,
+ HasChildren
+ };
+ Removal removeInternal(QString path = QString())
+ {
+ if(path.isEmpty())
+ {
+ if(!m_contained)
+ {
+ // remove all children - we are removing a prefix
+ clear();
+ return Succeeded;
+ }
+ m_contained = false;
+ if(children.size())
+ {
+ return HasChildren;
+ }
+ return Succeeded;
+ }
+ Removal remStatus = Failed;
+ QString childToRemove;
+ auto sepIndex = path.indexOf(Tseparator);
+ if(sepIndex == -1)
+ {
+ childToRemove = path;
+ auto found = children.find(childToRemove);
+ if(found == children.end())
+ {
+ return Failed;
+ }
+ remStatus = (*found).removeInternal();
+ }
+ else
+ {
+ childToRemove = path.left(sepIndex);
+ auto found = children.find(childToRemove);
+ if(found == children.end())
+ {
+ return Failed;
+ }
+ remStatus = (*found).removeInternal(path.mid(sepIndex + 1));
+ }
+ switch (remStatus)
+ {
+ case Failed:
+ case HasChildren:
+ {
+ return remStatus;
+ }
+ case Succeeded:
+ {
+ children.remove(childToRemove);
+ if(m_contained)
+ {
+ return HasChildren;
+ }
+ if(children.size())
+ {
+ return HasChildren;
+ }
+ return Succeeded;
+ }
+ }
+ return Failed;
+ }
private:
- QMap<QString,SeparatorPrefixTree<Tseparator>> children;
- bool m_contained = false;
+ QMap<QString,SeparatorPrefixTree<Tseparator>> children;
+ bool m_contained = false;
};
diff --git a/api/logic/Usable.h b/api/logic/Usable.h
index 1168be4d..83dd083d 100644
--- a/api/logic/Usable.h
+++ b/api/logic/Usable.h
@@ -12,27 +12,27 @@ class Usable;
*/
class Usable
{
- friend class UseLock;
+ friend class UseLock;
public:
- std::size_t useCount()
- {
- return m_useCount;
- }
- bool isInUse()
- {
- return m_useCount > 0;
- }
+ std::size_t useCount()
+ {
+ return m_useCount;
+ }
+ bool isInUse()
+ {
+ return m_useCount > 0;
+ }
protected:
- virtual void decrementUses()
- {
- m_useCount--;
- }
- virtual void incrementUses()
- {
- m_useCount++;
- }
+ virtual void decrementUses()
+ {
+ m_useCount--;
+ }
+ virtual void incrementUses()
+ {
+ m_useCount++;
+ }
private:
- std::size_t m_useCount = 0;
+ std::size_t m_useCount = 0;
};
/**
@@ -43,16 +43,16 @@ private:
class UseLock
{
public:
- UseLock(std::shared_ptr<Usable> usable)
- : m_usable(usable)
- {
- // this doesn't use shared pointer use count, because that wouldn't be correct. this count is separate.
- m_usable->incrementUses();
- }
- ~UseLock()
- {
- m_usable->decrementUses();
- }
+ UseLock(std::shared_ptr<Usable> usable)
+ : m_usable(usable)
+ {
+ // this doesn't use shared pointer use count, because that wouldn't be correct. this count is separate.
+ m_usable->incrementUses();
+ }
+ ~UseLock()
+ {
+ m_usable->decrementUses();
+ }
private:
- std::shared_ptr<Usable> m_usable;
+ std::shared_ptr<Usable> m_usable;
};
diff --git a/api/logic/Version.cpp b/api/logic/Version.cpp
index 2c83374f..42eac669 100644
--- a/api/logic/Version.cpp
+++ b/api/logic/Version.cpp
@@ -7,79 +7,79 @@
Version::Version(const QString &str) : m_string(str)
{
- parse();
+ parse();
}
bool Version::operator<(const Version &other) const
{
- const int size = qMax(m_sections.size(), other.m_sections.size());
- for (int i = 0; i < size; ++i)
- {
- const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
- const Section sec2 =
- (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
- if (sec1 != sec2)
- {
- return sec1 < sec2;
- }
- }
+ const int size = qMax(m_sections.size(), other.m_sections.size());
+ for (int i = 0; i < size; ++i)
+ {
+ const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
+ const Section sec2 =
+ (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
+ if (sec1 != sec2)
+ {
+ return sec1 < sec2;
+ }
+ }
- return false;
+ return false;
}
bool Version::operator<=(const Version &other) const
{
- return *this < other || *this == other;
+ return *this < other || *this == other;
}
bool Version::operator>(const Version &other) const
{
- const int size = qMax(m_sections.size(), other.m_sections.size());
- for (int i = 0; i < size; ++i)
- {
- const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
- const Section sec2 =
- (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
- if (sec1 != sec2)
- {
- return sec1 > sec2;
- }
- }
+ const int size = qMax(m_sections.size(), other.m_sections.size());
+ for (int i = 0; i < size; ++i)
+ {
+ const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
+ const Section sec2 =
+ (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
+ if (sec1 != sec2)
+ {
+ return sec1 > sec2;
+ }
+ }
- return false;
+ return false;
}
bool Version::operator>=(const Version &other) const
{
- return *this > other || *this == other;
+ return *this > other || *this == other;
}
bool Version::operator==(const Version &other) const
{
- const int size = qMax(m_sections.size(), other.m_sections.size());
- for (int i = 0; i < size; ++i)
- {
- const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
- const Section sec2 =
- (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
- if (sec1 != sec2)
- {
- return false;
- }
- }
+ const int size = qMax(m_sections.size(), other.m_sections.size());
+ for (int i = 0; i < size; ++i)
+ {
+ const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
+ const Section sec2 =
+ (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
+ if (sec1 != sec2)
+ {
+ return false;
+ }
+ }
- return true;
+ return true;
}
bool Version::operator!=(const Version &other) const
{
- return !operator==(other);
+ return !operator==(other);
}
void Version::parse()
{
- m_sections.clear();
+ m_sections.clear();
- // FIXME: this is bad. versions can contain a lot more separators...
- QStringList parts = m_string.split('.');
+ // FIXME: this is bad. versions can contain a lot more separators...
+ QStringList parts = m_string.split('.');
- for (const auto part : parts)
- {
- m_sections.append(Section(part));
- }
+ for (const auto part : parts)
+ {
+ m_sections.append(Section(part));
+ }
}
diff --git a/api/logic/Version.h b/api/logic/Version.h
index 7aa2ebe8..c5d93081 100644
--- a/api/logic/Version.h
+++ b/api/logic/Version.h
@@ -10,98 +10,98 @@ class QUrl;
class MULTIMC_LOGIC_EXPORT Version
{
public:
- Version(const QString &str);
- Version() {}
+ Version(const QString &str);
+ Version() {}
- bool operator<(const Version &other) const;
- bool operator<=(const Version &other) const;
- bool operator>(const Version &other) const;
- bool operator>=(const Version &other) const;
- bool operator==(const Version &other) const;
- bool operator!=(const Version &other) const;
+ bool operator<(const Version &other) const;
+ bool operator<=(const Version &other) const;
+ bool operator>(const Version &other) const;
+ bool operator>=(const Version &other) const;
+ bool operator==(const Version &other) const;
+ bool operator!=(const Version &other) const;
- QString toString() const
- {
- return m_string;
- }
+ QString toString() const
+ {
+ return m_string;
+ }
private:
- QString m_string;
- struct Section
- {
- explicit Section(const QString &fullString)
- {
- m_fullString = fullString;
- int cutoff = m_fullString.size();
- for(int i = 0; i < m_fullString.size(); i++)
- {
- if(!m_fullString[i].isDigit())
- {
- cutoff = i;
- break;
- }
- }
- auto numPart = m_fullString.leftRef(cutoff);
- if(numPart.size())
- {
- numValid = true;
- m_numPart = numPart.toInt();
- }
- auto stringPart = m_fullString.midRef(cutoff);
- if(stringPart.size())
- {
- m_stringPart = stringPart.toString();
- }
- }
- explicit Section() {}
- bool numValid = false;
- int m_numPart = 0;
- QString m_stringPart;
- QString m_fullString;
+ QString m_string;
+ struct Section
+ {
+ explicit Section(const QString &fullString)
+ {
+ m_fullString = fullString;
+ int cutoff = m_fullString.size();
+ for(int i = 0; i < m_fullString.size(); i++)
+ {
+ if(!m_fullString[i].isDigit())
+ {
+ cutoff = i;
+ break;
+ }
+ }
+ auto numPart = m_fullString.leftRef(cutoff);
+ if(numPart.size())
+ {
+ numValid = true;
+ m_numPart = numPart.toInt();
+ }
+ auto stringPart = m_fullString.midRef(cutoff);
+ if(stringPart.size())
+ {
+ m_stringPart = stringPart.toString();
+ }
+ }
+ explicit Section() {}
+ bool numValid = false;
+ int m_numPart = 0;
+ QString m_stringPart;
+ QString m_fullString;
- inline bool operator!=(const Section &other) const
- {
- if(numValid && other.numValid)
- {
- return m_numPart != other.m_numPart || m_stringPart != other.m_stringPart;
- }
- else
- {
- return m_fullString != other.m_fullString;
- }
- }
- inline bool operator<(const Section &other) const
- {
- if(numValid && other.numValid)
- {
- if(m_numPart < other.m_numPart)
- return true;
- if(m_numPart == other.m_numPart && m_stringPart < other.m_stringPart)
- return true;
- return false;
- }
- else
- {
- return m_fullString < other.m_fullString;
- }
- }
- inline bool operator>(const Section &other) const
- {
- if(numValid && other.numValid)
- {
- if(m_numPart > other.m_numPart)
- return true;
- if(m_numPart == other.m_numPart && m_stringPart > other.m_stringPart)
- return true;
- return false;
- }
- else
- {
- return m_fullString > other.m_fullString;
- }
- }
- };
- QList<Section> m_sections;
+ inline bool operator!=(const Section &other) const
+ {
+ if(numValid && other.numValid)
+ {
+ return m_numPart != other.m_numPart || m_stringPart != other.m_stringPart;
+ }
+ else
+ {
+ return m_fullString != other.m_fullString;
+ }
+ }
+ inline bool operator<(const Section &other) const
+ {
+ if(numValid && other.numValid)
+ {
+ if(m_numPart < other.m_numPart)
+ return true;
+ if(m_numPart == other.m_numPart && m_stringPart < other.m_stringPart)
+ return true;
+ return false;
+ }
+ else
+ {
+ return m_fullString < other.m_fullString;
+ }
+ }
+ inline bool operator>(const Section &other) const
+ {
+ if(numValid && other.numValid)
+ {
+ if(m_numPart > other.m_numPart)
+ return true;
+ if(m_numPart == other.m_numPart && m_stringPart > other.m_stringPart)
+ return true;
+ return false;
+ }
+ else
+ {
+ return m_fullString > other.m_fullString;
+ }
+ }
+ };
+ QList<Section> m_sections;
- void parse();
+ void parse();
};
diff --git a/api/logic/Version_test.cpp b/api/logic/Version_test.cpp
index b8e05768..bfbec12d 100644
--- a/api/logic/Version_test.cpp
+++ b/api/logic/Version_test.cpp
@@ -20,64 +20,64 @@
class ModUtilsTest : public QObject
{
- Q_OBJECT
- void setupVersions()
- {
- QTest::addColumn<QString>("first");
- QTest::addColumn<QString>("second");
- QTest::addColumn<bool>("lessThan");
- QTest::addColumn<bool>("equal");
+ Q_OBJECT
+ void setupVersions()
+ {
+ QTest::addColumn<QString>("first");
+ QTest::addColumn<QString>("second");
+ QTest::addColumn<bool>("lessThan");
+ QTest::addColumn<bool>("equal");
- QTest::newRow("equal, explicit") << "1.2.0" << "1.2.0" << false << true;
- QTest::newRow("equal, implicit 1") << "1.2" << "1.2.0" << false << true;
- QTest::newRow("equal, implicit 2") << "1.2.0" << "1.2" << false << true;
- QTest::newRow("equal, two-digit") << "1.42" << "1.42" << false << true;
+ QTest::newRow("equal, explicit") << "1.2.0" << "1.2.0" << false << true;
+ QTest::newRow("equal, implicit 1") << "1.2" << "1.2.0" << false << true;
+ QTest::newRow("equal, implicit 2") << "1.2.0" << "1.2" << false << true;
+ QTest::newRow("equal, two-digit") << "1.42" << "1.42" << false << true;
- QTest::newRow("lessThan, explicit 1") << "1.2.0" << "1.2.1" << true << false;
- QTest::newRow("lessThan, explicit 2") << "1.2.0" << "1.3.0" << true << false;
- QTest::newRow("lessThan, explicit 3") << "1.2.0" << "2.2.0" << true << false;
- QTest::newRow("lessThan, implicit 1") << "1.2" << "1.2.1" << true << false;
- QTest::newRow("lessThan, implicit 2") << "1.2" << "1.3.0" << true << false;
- QTest::newRow("lessThan, implicit 3") << "1.2" << "2.2.0" << true << false;
- QTest::newRow("lessThan, two-digit") << "1.41" << "1.42" << true << false;
+ QTest::newRow("lessThan, explicit 1") << "1.2.0" << "1.2.1" << true << false;
+ QTest::newRow("lessThan, explicit 2") << "1.2.0" << "1.3.0" << true << false;
+ QTest::newRow("lessThan, explicit 3") << "1.2.0" << "2.2.0" << true << false;
+ QTest::newRow("lessThan, implicit 1") << "1.2" << "1.2.1" << true << false;
+ QTest::newRow("lessThan, implicit 2") << "1.2" << "1.3.0" << true << false;
+ QTest::newRow("lessThan, implicit 3") << "1.2" << "2.2.0" << true << false;
+ QTest::newRow("lessThan, two-digit") << "1.41" << "1.42" << true << false;
- QTest::newRow("greaterThan, explicit 1") << "1.2.1" << "1.2.0" << false << false;
- QTest::newRow("greaterThan, explicit 2") << "1.3.0" << "1.2.0" << false << false;
- QTest::newRow("greaterThan, explicit 3") << "2.2.0" << "1.2.0" << false << false;
- QTest::newRow("greaterThan, implicit 1") << "1.2.1" << "1.2" << false << false;
- QTest::newRow("greaterThan, implicit 2") << "1.3.0" << "1.2" << false << false;
- QTest::newRow("greaterThan, implicit 3") << "2.2.0" << "1.2" << false << false;
- QTest::newRow("greaterThan, two-digit") << "1.42" << "1.41" << false << false;
- }
+ QTest::newRow("greaterThan, explicit 1") << "1.2.1" << "1.2.0" << false << false;
+ QTest::newRow("greaterThan, explicit 2") << "1.3.0" << "1.2.0" << false << false;
+ QTest::newRow("greaterThan, explicit 3") << "2.2.0" << "1.2.0" << false << false;
+ QTest::newRow("greaterThan, implicit 1") << "1.2.1" << "1.2" << false << false;
+ QTest::newRow("greaterThan, implicit 2") << "1.3.0" << "1.2" << false << false;
+ QTest::newRow("greaterThan, implicit 3") << "2.2.0" << "1.2" << false << false;
+ QTest::newRow("greaterThan, two-digit") << "1.42" << "1.41" << false << false;
+ }
private slots:
- void initTestCase()
- {
+ void initTestCase()
+ {
- }
- void cleanupTestCase()
- {
+ }
+ void cleanupTestCase()
+ {
- }
+ }
- void test_versionCompare_data()
- {
- setupVersions();
- }
- void test_versionCompare()
- {
- QFETCH(QString, first);
- QFETCH(QString, second);
- QFETCH(bool, lessThan);
- QFETCH(bool, equal);
+ void test_versionCompare_data()
+ {
+ setupVersions();
+ }
+ void test_versionCompare()
+ {
+ QFETCH(QString, first);
+ QFETCH(QString, second);
+ QFETCH(bool, lessThan);
+ QFETCH(bool, equal);
- const auto v1 = Version(first);
- const auto v2 = Version(second);
+ const auto v1 = Version(first);
+ const auto v2 = Version(second);
- QCOMPARE(v1 < v2, lessThan);
- QCOMPARE(v1 > v2, !lessThan && !equal);
- QCOMPARE(v1 == v2, equal);
- }
+ QCOMPARE(v1 < v2, lessThan);
+ QCOMPARE(v1 > v2, !lessThan && !equal);
+ QCOMPARE(v1 == v2, equal);
+ }
};
QTEST_GUILESS_MAIN(ModUtilsTest)
diff --git a/api/logic/icons/IIconList.h b/api/logic/icons/IIconList.h
index e6c16d50..9a3fe022 100644
--- a/api/logic/icons/IIconList.h
+++ b/api/logic/icons/IIconList.h
@@ -6,21 +6,21 @@
enum IconType : unsigned
{
- Builtin,
- Transient,
- FileBased,
- ICONS_TOTAL,
- ToBeDeleted
+ Builtin,
+ Transient,
+ FileBased,
+ ICONS_TOTAL,
+ ToBeDeleted
};
class MULTIMC_LOGIC_EXPORT IIconList
{
public:
- virtual ~IIconList();
- virtual bool addIcon(const QString &key, const QString &name, const QString &path, const IconType type) = 0;
- virtual bool deleteIcon(const QString &key) = 0;
- virtual void saveIcon(const QString &key, const QString &path, const char * format) const = 0;
- virtual bool iconFileExists(const QString &key) const = 0;
- virtual void installIcons(const QStringList &iconFiles) = 0;
- virtual void installIcon(const QString &file, const QString &name) = 0;
+ virtual ~IIconList();
+ virtual bool addIcon(const QString &key, const QString &name, const QString &path, const IconType type) = 0;
+ virtual bool deleteIcon(const QString &key) = 0;
+ virtual void saveIcon(const QString &key, const QString &path, const char * format) const = 0;
+ virtual bool iconFileExists(const QString &key) const = 0;
+ virtual void installIcons(const QStringList &iconFiles) = 0;
+ virtual void installIcon(const QString &file, const QString &name) = 0;
};
diff --git a/api/logic/java/JavaChecker.cpp b/api/logic/java/JavaChecker.cpp
index f0b71e48..9ba3933f 100644
--- a/api/logic/java/JavaChecker.cpp
+++ b/api/logic/java/JavaChecker.cpp
@@ -16,149 +16,149 @@ JavaChecker::JavaChecker(QObject *parent) : QObject(parent)
void JavaChecker::performCheck()
{
- QString checkerJar = FS::PathCombine(ENV.getJarsPath(), "JavaCheck.jar");
-
- QStringList args;
-
- process.reset(new QProcess());
- if(m_args.size())
- {
- auto extraArgs = Commandline::splitArgs(m_args);
- args.append(extraArgs);
- }
- if(m_minMem != 0)
- {
- args << QString("-Xms%1m").arg(m_minMem);
- }
- if(m_maxMem != 0)
- {
- args << QString("-Xmx%1m").arg(m_maxMem);
- }
- if(m_permGen != 64)
- {
- args << QString("-XX:PermSize=%1m").arg(m_permGen);
- }
-
- args.append({"-jar", checkerJar});
- process->setArguments(args);
- process->setProgram(m_path);
- process->setProcessChannelMode(QProcess::SeparateChannels);
- process->setProcessEnvironment(CleanEnviroment());
- qDebug() << "Running java checker: " + m_path + args.join(" ");;
-
- connect(process.get(), SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
- connect(process.get(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
- connect(process.get(), SIGNAL(readyReadStandardOutput()), this, SLOT(stdoutReady()));
- connect(process.get(), SIGNAL(readyReadStandardError()), this, SLOT(stderrReady()));
- connect(&killTimer, SIGNAL(timeout()), SLOT(timeout()));
- killTimer.setSingleShot(true);
- killTimer.start(15000);
- process->start();
+ QString checkerJar = FS::PathCombine(ENV.getJarsPath(), "JavaCheck.jar");
+
+ QStringList args;
+
+ process.reset(new QProcess());
+ if(m_args.size())
+ {
+ auto extraArgs = Commandline::splitArgs(m_args);
+ args.append(extraArgs);
+ }
+ if(m_minMem != 0)
+ {
+ args << QString("-Xms%1m").arg(m_minMem);
+ }
+ if(m_maxMem != 0)
+ {
+ args << QString("-Xmx%1m").arg(m_maxMem);
+ }
+ if(m_permGen != 64)
+ {
+ args << QString("-XX:PermSize=%1m").arg(m_permGen);
+ }
+
+ args.append({"-jar", checkerJar});
+ process->setArguments(args);
+ process->setProgram(m_path);
+ process->setProcessChannelMode(QProcess::SeparateChannels);
+ process->setProcessEnvironment(CleanEnviroment());
+ qDebug() << "Running java checker: " + m_path + args.join(" ");;
+
+ connect(process.get(), SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
+ connect(process.get(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
+ connect(process.get(), SIGNAL(readyReadStandardOutput()), this, SLOT(stdoutReady()));
+ connect(process.get(), SIGNAL(readyReadStandardError()), this, SLOT(stderrReady()));
+ connect(&killTimer, SIGNAL(timeout()), SLOT(timeout()));
+ killTimer.setSingleShot(true);
+ killTimer.start(15000);
+ process->start();
}
void JavaChecker::stdoutReady()
{
- QByteArray data = process->readAllStandardOutput();
- QString added = QString::fromLocal8Bit(data);
- added.remove('\r');
- m_stdout += added;
+ QByteArray data = process->readAllStandardOutput();
+ QString added = QString::fromLocal8Bit(data);
+ added.remove('\r');
+ m_stdout += added;
}
void JavaChecker::stderrReady()
{
- QByteArray data = process->readAllStandardError();
- QString added = QString::fromLocal8Bit(data);
- added.remove('\r');
- m_stderr += added;
+ QByteArray data = process->readAllStandardError();
+ QString added = QString::fromLocal8Bit(data);
+ added.remove('\r');
+ m_stderr += added;
}
void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
{
- killTimer.stop();
- QProcessPtr _process;
- _process.swap(process);
-
- JavaCheckResult result;
- {
- result.path = m_path;
- result.id = m_id;
- }
- result.errorLog = m_stderr;
- result.outLog = m_stdout;
- qDebug() << "STDOUT" << m_stdout;
- qWarning() << "STDERR" << m_stderr;
- qDebug() << "Java checker finished with status " << status << " exit code " << exitcode;
-
- if (status == QProcess::CrashExit || exitcode == 1)
- {
- result.validity = JavaCheckResult::Validity::Errored;
- emit checkFinished(result);
- return;
- }
-
- bool success = true;
-
- QMap<QString, QString> results;
- QStringList lines = m_stdout.split("\n", QString::SkipEmptyParts);
- for(QString line : lines)
- {
- line = line.trimmed();
-
- auto parts = line.split('=', QString::SkipEmptyParts);
- if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty())
- {
- success = false;
- }
- else
- {
- results.insert(parts[0], parts[1]);
- }
- }
-
- if(!results.contains("os.arch") || !results.contains("java.version") || !success)
- {
- result.validity = JavaCheckResult::Validity::ReturnedInvalidData;
- emit checkFinished(result);
- return;
- }
-
- auto os_arch = results["os.arch"];
- auto java_version = results["java.version"];
- bool is_64 = os_arch == "x86_64" || os_arch == "amd64";
-
-
- result.validity = JavaCheckResult::Validity::Valid;
- result.is_64bit = is_64;
- result.mojangPlatform = is_64 ? "64" : "32";
- result.realPlatform = os_arch;
- result.javaVersion = java_version;
- qDebug() << "Java checker succeeded.";
- emit checkFinished(result);
+ killTimer.stop();
+ QProcessPtr _process;
+ _process.swap(process);
+
+ JavaCheckResult result;
+ {
+ result.path = m_path;
+ result.id = m_id;
+ }
+ result.errorLog = m_stderr;
+ result.outLog = m_stdout;
+ qDebug() << "STDOUT" << m_stdout;
+ qWarning() << "STDERR" << m_stderr;
+ qDebug() << "Java checker finished with status " << status << " exit code " << exitcode;
+
+ if (status == QProcess::CrashExit || exitcode == 1)
+ {
+ result.validity = JavaCheckResult::Validity::Errored;
+ emit checkFinished(result);
+ return;
+ }
+
+ bool success = true;
+
+ QMap<QString, QString> results;
+ QStringList lines = m_stdout.split("\n", QString::SkipEmptyParts);
+ for(QString line : lines)
+ {
+ line = line.trimmed();
+
+ auto parts = line.split('=', QString::SkipEmptyParts);
+ if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty())
+ {
+ success = false;
+ }
+ else
+ {
+ results.insert(parts[0], parts[1]);
+ }
+ }
+
+ if(!results.contains("os.arch") || !results.contains("java.version") || !success)
+ {
+ result.validity = JavaCheckResult::Validity::ReturnedInvalidData;
+ emit checkFinished(result);
+ return;
+ }
+
+ auto os_arch = results["os.arch"];
+ auto java_version = results["java.version"];
+ bool is_64 = os_arch == "x86_64" || os_arch == "amd64";
+
+
+ result.validity = JavaCheckResult::Validity::Valid;
+ result.is_64bit = is_64;
+ result.mojangPlatform = is_64 ? "64" : "32";
+ result.realPlatform = os_arch;
+ result.javaVersion = java_version;
+ qDebug() << "Java checker succeeded.";
+ emit checkFinished(result);
}
void JavaChecker::error(QProcess::ProcessError err)
{
- if(err == QProcess::FailedToStart)
- {
- killTimer.stop();
- qDebug() << "Java checker has failed to start.";
- JavaCheckResult result;
- {
- result.path = m_path;
- result.id = m_id;
- }
-
- emit checkFinished(result);
- return;
- }
+ if(err == QProcess::FailedToStart)
+ {
+ killTimer.stop();
+ qDebug() << "Java checker has failed to start.";
+ JavaCheckResult result;
+ {
+ result.path = m_path;
+ result.id = m_id;
+ }
+
+ emit checkFinished(result);
+ return;
+ }
}
void JavaChecker::timeout()
{
- // NO MERCY. NO ABUSE.
- if(process)
- {
- qDebug() << "Java checker has been killed by timeout.";
- process->kill();
- }
+ // NO MERCY. NO ABUSE.
+ if(process)
+ {
+ qDebug() << "Java checker has been killed by timeout.";
+ process->kill();
+ }
}
diff --git a/api/logic/java/JavaChecker.h b/api/logic/java/JavaChecker.h
index c6bd697c..d5d4b0de 100644
--- a/api/logic/java/JavaChecker.h
+++ b/api/logic/java/JavaChecker.h
@@ -11,50 +11,50 @@ class JavaChecker;
struct MULTIMC_LOGIC_EXPORT JavaCheckResult
{
- QString path;
- QString mojangPlatform;
- QString realPlatform;
- JavaVersion javaVersion;
- QString outLog;
- QString errorLog;
- bool is_64bit = false;
- int id;
- enum class Validity
- {
- Errored,
- ReturnedInvalidData,
- Valid
- } validity = Validity::Errored;
+ QString path;
+ QString mojangPlatform;
+ QString realPlatform;
+ JavaVersion javaVersion;
+ QString outLog;
+ QString errorLog;
+ bool is_64bit = false;
+ int id;
+ enum class Validity
+ {
+ Errored,
+ ReturnedInvalidData,
+ Valid
+ } validity = Validity::Errored;
};
typedef std::shared_ptr<QProcess> QProcessPtr;
typedef std::shared_ptr<JavaChecker> JavaCheckerPtr;
class MULTIMC_LOGIC_EXPORT JavaChecker : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit JavaChecker(QObject *parent = 0);
- void performCheck();
+ explicit JavaChecker(QObject *parent = 0);
+ void performCheck();
- QString m_path;
- QString m_args;
- int m_id = 0;
- int m_minMem = 0;
- int m_maxMem = 0;
- int m_permGen = 64;
+ QString m_path;
+ QString m_args;
+ int m_id = 0;
+ int m_minMem = 0;
+ int m_maxMem = 0;
+ int m_permGen = 64;
signals:
- void checkFinished(JavaCheckResult result);
+ void checkFinished(JavaCheckResult result);
private:
- QProcessPtr process;
- QTimer killTimer;
- QString m_stdout;
- QString m_stderr;
+ QProcessPtr process;
+ QTimer killTimer;
+ QString m_stdout;
+ QString m_stderr;
public
slots:
- void timeout();
- void finished(int exitcode, QProcess::ExitStatus);
- void error(QProcess::ProcessError);
- void stdoutReady();
- void stderrReady();
+ void timeout();
+ void finished(int exitcode, QProcess::ExitStatus);
+ void error(QProcess::ProcessError);
+ void stdoutReady();
+ void stderrReady();
};
diff --git a/api/logic/java/JavaCheckerJob.cpp b/api/logic/java/JavaCheckerJob.cpp
index fabb5aaa..a26846f2 100644
--- a/api/logic/java/JavaCheckerJob.cpp
+++ b/api/logic/java/JavaCheckerJob.cpp
@@ -19,26 +19,26 @@
void JavaCheckerJob::partFinished(JavaCheckResult result)
{
- num_finished++;
- qDebug() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/"
- << javacheckers.size();
- setProgress(num_finished, javacheckers.size());
+ num_finished++;
+ qDebug() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/"
+ << javacheckers.size();
+ setProgress(num_finished, javacheckers.size());
- javaresults.replace(result.id, result);
+ javaresults.replace(result.id, result);
- if (num_finished == javacheckers.size())
- {
- emitSucceeded();
- }
+ if (num_finished == javacheckers.size())
+ {
+ emitSucceeded();
+ }
}
void JavaCheckerJob::executeTask()
{
- qDebug() << m_job_name.toLocal8Bit() << " started.";
- for (auto iter : javacheckers)
- {
- javaresults.append(JavaCheckResult());
- connect(iter.get(), SIGNAL(checkFinished(JavaCheckResult)), SLOT(partFinished(JavaCheckResult)));
- iter->performCheck();
- }
+ qDebug() << m_job_name.toLocal8Bit() << " started.";
+ for (auto iter : javacheckers)
+ {
+ javaresults.append(JavaCheckResult());
+ connect(iter.get(), SIGNAL(checkFinished(JavaCheckResult)), SLOT(partFinished(JavaCheckResult)));
+ iter->performCheck();
+ }
}
diff --git a/api/logic/java/JavaCheckerJob.h b/api/logic/java/JavaCheckerJob.h
index 64ac58a1..e52970c1 100644
--- a/api/logic/java/JavaCheckerJob.h
+++ b/api/logic/java/JavaCheckerJob.h
@@ -25,37 +25,37 @@ typedef std::shared_ptr<JavaCheckerJob> JavaCheckerJobPtr;
// FIXME: this just seems horribly redundant
class JavaCheckerJob : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name) {};
- virtual ~JavaCheckerJob() {};
-
- bool addJavaCheckerAction(JavaCheckerPtr base)
- {
- javacheckers.append(base);
- // if this is already running, the action needs to be started right away!
- if (isRunning())
- {
- setProgress(num_finished, javacheckers.size());
- connect(base.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished);
- base->performCheck();
- }
- return true;
- }
- QList<JavaCheckResult> getResults()
- {
- return javaresults;
- }
+ explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name) {};
+ virtual ~JavaCheckerJob() {};
+
+ bool addJavaCheckerAction(JavaCheckerPtr base)
+ {
+ javacheckers.append(base);
+ // if this is already running, the action needs to be started right away!
+ if (isRunning())
+ {
+ setProgress(num_finished, javacheckers.size());
+ connect(base.get(), &JavaChecker::checkFinished, this, &JavaCheckerJob::partFinished);
+ base->performCheck();
+ }
+ return true;
+ }
+ QList<JavaCheckResult> getResults()
+ {
+ return javaresults;
+ }
private slots:
- void partFinished(JavaCheckResult result);
+ void partFinished(JavaCheckResult result);
protected:
- virtual void executeTask() override;
+ virtual void executeTask() override;
private:
- QString m_job_name;
- QList<JavaCheckerPtr> javacheckers;
- QList<JavaCheckResult> javaresults;
- int num_finished = 0;
+ QString m_job_name;
+ QList<JavaCheckerPtr> javacheckers;
+ QList<JavaCheckResult> javaresults;
+ int num_finished = 0;
};
diff --git a/api/logic/java/JavaInstall.cpp b/api/logic/java/JavaInstall.cpp
index bb262b6e..5bcf7bcb 100644
--- a/api/logic/java/JavaInstall.cpp
+++ b/api/logic/java/JavaInstall.cpp
@@ -3,26 +3,26 @@
bool JavaInstall::operator<(const JavaInstall &rhs)
{
- auto archCompare = Strings::naturalCompare(arch, rhs.arch, Qt::CaseInsensitive);
- if(archCompare != 0)
- return archCompare < 0;
- if(id < rhs.id)
- {
- return true;
- }
- if(id > rhs.id)
- {
- return false;
- }
- return Strings::naturalCompare(path, rhs.path, Qt::CaseInsensitive) < 0;
+ auto archCompare = Strings::naturalCompare(arch, rhs.arch, Qt::CaseInsensitive);
+ if(archCompare != 0)
+ return archCompare < 0;
+ if(id < rhs.id)
+ {
+ return true;
+ }
+ if(id > rhs.id)
+ {
+ return false;
+ }
+ return Strings::naturalCompare(path, rhs.path, Qt::CaseInsensitive) < 0;
}
bool JavaInstall::operator==(const JavaInstall &rhs)
{
- return arch == rhs.arch && id == rhs.id && path == rhs.path;
+ return arch == rhs.arch && id == rhs.id && path == rhs.path;
}
bool JavaInstall::operator>(const JavaInstall &rhs)
{
- return (!operator<(rhs)) && (!operator==(rhs));
+ return (!operator<(rhs)) && (!operator==(rhs));
}
diff --git a/api/logic/java/JavaInstall.h b/api/logic/java/JavaInstall.h
index 882c7386..64be40d1 100644
--- a/api/logic/java/JavaInstall.h
+++ b/api/logic/java/JavaInstall.h
@@ -5,34 +5,34 @@
struct JavaInstall : public BaseVersion
{
- JavaInstall(){}
- JavaInstall(QString id, QString arch, QString path)
- : id(id), arch(arch), path(path)
- {
- }
- virtual QString descriptor()
- {
- return id.toString();
- }
+ JavaInstall(){}
+ JavaInstall(QString id, QString arch, QString path)
+ : id(id), arch(arch), path(path)
+ {
+ }
+ virtual QString descriptor()
+ {
+ return id.toString();
+ }
- virtual QString name()
- {
- return id.toString();
- }
+ virtual QString name()
+ {
+ return id.toString();
+ }
- virtual QString typeString() const
- {
- return arch;
- }
+ virtual QString typeString() const
+ {
+ return arch;
+ }
- bool operator<(const JavaInstall & rhs);
- bool operator==(const JavaInstall & rhs);
- bool operator>(const JavaInstall & rhs);
+ bool operator<(const JavaInstall & rhs);
+ bool operator==(const JavaInstall & rhs);
+ bool operator>(const JavaInstall & rhs);
- JavaVersion id;
- QString arch;
- QString path;
- bool recommended = false;
+ JavaVersion id;
+ QString arch;
+ QString path;
+ bool recommended = false;
};
typedef std::shared_ptr<JavaInstall> JavaInstallPtr;
diff --git a/api/logic/java/JavaInstallList.cpp b/api/logic/java/JavaInstallList.cpp
index 9d2e2f8b..605d4c0c 100644
--- a/api/logic/java/JavaInstallList.cpp
+++ b/api/logic/java/JavaInstallList.cpp
@@ -31,111 +31,111 @@ JavaInstallList::JavaInstallList(QObject *parent) : BaseVersionList(parent)
shared_qobject_ptr<Task> JavaInstallList::getLoadTask()
{
- load();
- return getCurrentTask();
+ load();
+ return getCurrentTask();
}
shared_qobject_ptr<Task> JavaInstallList::getCurrentTask()
{
- if(m_status == Status::InProgress)
- {
- return m_loadTask;
- }
- return nullptr;
+ if(m_status == Status::InProgress)
+ {
+ return m_loadTask;
+ }
+ return nullptr;
}
void JavaInstallList::load()
{
- if(m_status != Status::InProgress)
- {
- m_status = Status::InProgress;
- m_loadTask = new JavaListLoadTask(this);
- m_loadTask->start();
- }
+ if(m_status != Status::InProgress)
+ {
+ m_status = Status::InProgress;
+ m_loadTask = new JavaListLoadTask(this);
+ m_loadTask->start();
+ }
}
const BaseVersionPtr JavaInstallList::at(int i) const
{
- return m_vlist.at(i);
+ return m_vlist.at(i);
}
bool JavaInstallList::isLoaded()
{
- return m_status == JavaInstallList::Status::Done;
+ return m_status == JavaInstallList::Status::Done;
}
int JavaInstallList::count() const
{
- return m_vlist.count();
+ return m_vlist.count();
}
QVariant JavaInstallList::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- auto version = std::dynamic_pointer_cast<JavaInstall>(m_vlist[index.row()]);
- switch (role)
- {
- case VersionPointerRole:
- return qVariantFromValue(m_vlist[index.row()]);
- case VersionIdRole:
- return version->descriptor();
- case VersionRole:
- return version->id.toString();
- case RecommendedRole:
- return version->recommended;
- case PathRole:
- return version->path;
- case ArchitectureRole:
- return version->arch;
- default:
- return QVariant();
- }
+ if (!index.isValid())
+ return QVariant();
+
+ if (index.row() > count())
+ return QVariant();
+
+ auto version = std::dynamic_pointer_cast<JavaInstall>(m_vlist[index.row()]);
+ switch (role)
+ {
+ case VersionPointerRole:
+ return qVariantFromValue(m_vlist[index.row()]);
+ case VersionIdRole:
+ return version->descriptor();
+ case VersionRole:
+ return version->id.toString();
+ case RecommendedRole:
+ return version->recommended;
+ case PathRole:
+ return version->path;
+ case ArchitectureRole:
+ return version->arch;
+ default:
+ return QVariant();
+ }
}
BaseVersionList::RoleList JavaInstallList::providesRoles() const
{
- return {VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole};
+ return {VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole};
}
void JavaInstallList::updateListData(QList<BaseVersionPtr> versions)
{
- beginResetModel();
- m_vlist = versions;
- sortVersions();
- if(m_vlist.size())
- {
- auto best = std::dynamic_pointer_cast<JavaInstall>(m_vlist[0]);
- best->recommended = true;
- }
- endResetModel();
- m_status = Status::Done;
- m_loadTask.reset();
+ beginResetModel();
+ m_vlist = versions;
+ sortVersions();
+ if(m_vlist.size())
+ {
+ auto best = std::dynamic_pointer_cast<JavaInstall>(m_vlist[0]);
+ best->recommended = true;
+ }
+ endResetModel();
+ m_status = Status::Done;
+ m_loadTask.reset();
}
bool sortJavas(BaseVersionPtr left, BaseVersionPtr right)
{
- auto rleft = std::dynamic_pointer_cast<JavaInstall>(left);
- auto rright = std::dynamic_pointer_cast<JavaInstall>(right);
- return (*rleft) > (*rright);
+ auto rleft = std::dynamic_pointer_cast<JavaInstall>(left);
+ auto rright = std::dynamic_pointer_cast<JavaInstall>(right);
+ return (*rleft) > (*rright);
}
void JavaInstallList::sortVersions()
{
- beginResetModel();
- std::sort(m_vlist.begin(), m_vlist.end(), sortJavas);
- endResetModel();
+ beginResetModel();
+ std::sort(m_vlist.begin(), m_vlist.end(), sortJavas);
+ endResetModel();
}
JavaListLoadTask::JavaListLoadTask(JavaInstallList *vlist) : Task()
{
- m_list = vlist;
- m_currentRecommended = NULL;
+ m_list = vlist;
+ m_currentRecommended = NULL;
}
JavaListLoadTask::~JavaListLoadTask()
@@ -144,65 +144,65 @@ JavaListLoadTask::~JavaListLoadTask()
void JavaListLoadTask::executeTask()
{
- setStatus(tr("Detecting Java installations..."));
+ setStatus(tr("Detecting Java installations..."));
- JavaUtils ju;
- QList<QString> candidate_paths = ju.FindJavaPaths();
+ JavaUtils ju;
+ QList<QString> candidate_paths = ju.FindJavaPaths();
- m_job = std::shared_ptr<JavaCheckerJob>(new JavaCheckerJob("Java detection"));
- connect(m_job.get(), &Task::finished, this, &JavaListLoadTask::javaCheckerFinished);
- connect(m_job.get(), &Task::progress, this, &Task::setProgress);
+ m_job = std::shared_ptr<JavaCheckerJob>(new JavaCheckerJob("Java detection"));
+ connect(m_job.get(), &Task::finished, this, &JavaListLoadTask::javaCheckerFinished);
+ connect(m_job.get(), &Task::progress, this, &Task::setProgress);
- qDebug() << "Probing the following Java paths: ";
- int id = 0;
- for(QString candidate : candidate_paths)
- {
- qDebug() << " " << candidate;
+ qDebug() << "Probing the following Java paths: ";
+ int id = 0;
+ for(QString candidate : candidate_paths)
+ {
+ qDebug() << " " << candidate;
- auto candidate_checker = new JavaChecker();
- candidate_checker->m_path = candidate;
- candidate_checker->m_id = id;
- m_job->addJavaCheckerAction(JavaCheckerPtr(candidate_checker));
+ auto candidate_checker = new JavaChecker();
+ candidate_checker->m_path = candidate;
+ candidate_checker->m_id = id;
+ m_job->addJavaCheckerAction(JavaCheckerPtr(candidate_checker));
- id++;
- }
+ id++;
+ }
- m_job->start();
+ m_job->start();
}
void JavaListLoadTask::javaCheckerFinished()
{
- QList<JavaInstallPtr> candidates;
- auto results = m_job->getResults();
-
- qDebug() << "Found the following valid Java installations:";
- for(JavaCheckResult result : results)
- {
- if(result.validity == JavaCheckResult::Validity::Valid)
- {
- JavaInstallPtr javaVersion(new JavaInstall());
-
- javaVersion->id = result.javaVersion;
- javaVersion->arch = result.mojangPlatform;
- javaVersion->path = result.path;
- candidates.append(javaVersion);
-
- qDebug() << " " << javaVersion->id.toString() << javaVersion->arch << javaVersion->path;
- }
- }
-
- QList<BaseVersionPtr> javas_bvp;
- for (auto java : candidates)
- {
- //qDebug() << java->id << java->arch << " at " << java->path;
- BaseVersionPtr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
-
- if (bp_java)
- {
- javas_bvp.append(java);
- }
- }
-
- m_list->updateListData(javas_bvp);
- emitSucceeded();
+ QList<JavaInstallPtr> candidates;
+ auto results = m_job->getResults();
+
+ qDebug() << "Found the following valid Java installations:";
+ for(JavaCheckResult result : results)
+ {
+ if(result.validity == JavaCheckResult::Validity::Valid)
+ {
+ JavaInstallPtr javaVersion(new JavaInstall());
+
+ javaVersion->id = result.javaVersion;
+ javaVersion->arch = result.mojangPlatform;
+ javaVersion->path = result.path;
+ candidates.append(javaVersion);
+
+ qDebug() << " " << javaVersion->id.toString() << javaVersion->arch << javaVersion->path;
+ }
+ }
+
+ QList<BaseVersionPtr> javas_bvp;
+ for (auto java : candidates)
+ {
+ //qDebug() << java->id << java->arch << " at " << java->path;
+ BaseVersionPtr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
+
+ if (bp_java)
+ {
+ javas_bvp.append(java);
+ }
+ }
+
+ m_list->updateListData(javas_bvp);
+ emitSucceeded();
}
diff --git a/api/logic/java/JavaInstallList.h b/api/logic/java/JavaInstallList.h
index 9ec12f87..7e72b5ef 100644
--- a/api/logic/java/JavaInstallList.h
+++ b/api/logic/java/JavaInstallList.h
@@ -30,52 +30,52 @@ class JavaListLoadTask;
class MULTIMC_LOGIC_EXPORT JavaInstallList : public BaseVersionList
{
- Q_OBJECT
- enum class Status
- {
- NotDone,
- InProgress,
- Done
- };
+ Q_OBJECT
+ enum class Status
+ {
+ NotDone,
+ InProgress,
+ Done
+ };
public:
- explicit JavaInstallList(QObject *parent = 0);
+ explicit JavaInstallList(QObject *parent = 0);
- shared_qobject_ptr<Task> getLoadTask() override;
- bool isLoaded() override;
- const BaseVersionPtr at(int i) const override;
- int count() const override;
- void sortVersions() override;
+ shared_qobject_ptr<Task> getLoadTask() override;
+ bool isLoaded() override;
+ const BaseVersionPtr at(int i) const override;
+ int count() const override;
+ void sortVersions() override;
- QVariant data(const QModelIndex &index, int role) const override;
- RoleList providesRoles() const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ RoleList providesRoles() const override;
public slots:
- void updateListData(QList<BaseVersionPtr> versions) override;
+ void updateListData(QList<BaseVersionPtr> versions) override;
protected:
- void load();
- shared_qobject_ptr<Task> getCurrentTask();
+ void load();
+ shared_qobject_ptr<Task> getCurrentTask();
protected:
- Status m_status = Status::NotDone;
- shared_qobject_ptr<JavaListLoadTask> m_loadTask;
- QList<BaseVersionPtr> m_vlist;
+ Status m_status = Status::NotDone;
+ shared_qobject_ptr<JavaListLoadTask> m_loadTask;
+ QList<BaseVersionPtr> m_vlist;
};
class JavaListLoadTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit JavaListLoadTask(JavaInstallList *vlist);
- virtual ~JavaListLoadTask();
+ explicit JavaListLoadTask(JavaInstallList *vlist);
+ virtual ~JavaListLoadTask();
- void executeTask() override;
+ void executeTask() override;
public slots:
- void javaCheckerFinished();
+ void javaCheckerFinished();
protected:
- std::shared_ptr<JavaCheckerJob> m_job;
- JavaInstallList *m_list;
- JavaInstall *m_currentRecommended;
+ std::shared_ptr<JavaCheckerJob> m_job;
+ JavaInstallList *m_list;
+ JavaInstall *m_currentRecommended;
};
diff --git a/api/logic/java/JavaUtils.cpp b/api/logic/java/JavaUtils.cpp
index 798c80e8..9f7fdcb0 100644
--- a/api/logic/java/JavaUtils.cpp
+++ b/api/logic/java/JavaUtils.cpp
@@ -34,312 +34,312 @@ JavaUtils::JavaUtils()
#ifdef Q_OS_LINUX
static QString processLD_LIBRARY_PATH(const QString & LD_LIBRARY_PATH)
{
- QDir mmcBin(QCoreApplication::applicationDirPath());
- auto items = LD_LIBRARY_PATH.split(':');
- QStringList final;
- for(auto & item: items)
- {
- QDir test(item);
- if(test == mmcBin)
- {
- qDebug() << "Env:LD_LIBRARY_PATH ignoring path" << item;
- continue;
- }
- final.append(item);
- }
- return final.join(':');
+ QDir mmcBin(QCoreApplication::applicationDirPath());
+ auto items = LD_LIBRARY_PATH.split(':');
+ QStringList final;
+ for(auto & item: items)
+ {
+ QDir test(item);
+ if(test == mmcBin)
+ {
+ qDebug() << "Env:LD_LIBRARY_PATH ignoring path" << item;
+ continue;
+ }
+ final.append(item);
+ }
+ return final.join(':');
}
#endif
QProcessEnvironment CleanEnviroment()
{
- // prepare the process environment
- QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment();
- QProcessEnvironment env;
-
- QStringList ignored =
- {
- "JAVA_ARGS",
- "CLASSPATH",
- "CONFIGPATH",
- "JAVA_HOME",
- "JRE_HOME",
- "_JAVA_OPTIONS",
- "JAVA_OPTIONS",
- "JAVA_TOOL_OPTIONS"
- };
- for(auto key: rawenv.keys())
- {
- auto value = rawenv.value(key);
- // filter out dangerous java crap
- if(ignored.contains(key))
- {
- qDebug() << "Env: ignoring" << key << value;
- continue;
- }
- // filter MultiMC-related things
- if(key.startsWith("QT_"))
- {
- qDebug() << "Env: ignoring" << key << value;
- continue;
- }
+ // prepare the process environment
+ QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment();
+ QProcessEnvironment env;
+
+ QStringList ignored =
+ {
+ "JAVA_ARGS",
+ "CLASSPATH",
+ "CONFIGPATH",
+ "JAVA_HOME",
+ "JRE_HOME",
+ "_JAVA_OPTIONS",
+ "JAVA_OPTIONS",
+ "JAVA_TOOL_OPTIONS"
+ };
+ for(auto key: rawenv.keys())
+ {
+ auto value = rawenv.value(key);
+ // filter out dangerous java crap
+ if(ignored.contains(key))
+ {
+ qDebug() << "Env: ignoring" << key << value;
+ continue;
+ }
+ // filter MultiMC-related things
+ if(key.startsWith("QT_"))
+ {
+ qDebug() << "Env: ignoring" << key << value;
+ continue;
+ }
#ifdef Q_OS_LINUX
- // Do not pass LD_* variables to java. They were intended for MultiMC
- if(key.startsWith("LD_"))
- {
- qDebug() << "Env: ignoring" << key << value;
- continue;
- }
- // Strip IBus
- // IBus is a Linux IME framework. For some reason, it breaks MC?
- if (key == "XMODIFIERS" && value.contains(IBUS))
- {
- QString save = value;
- value.replace(IBUS, "");
- qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value;
- }
- if(key == "GAME_PRELOAD")
- {
- env.insert("LD_PRELOAD", value);
- continue;
- }
- if(key == "GAME_LIBRARY_PATH")
- {
- env.insert("LD_LIBRARY_PATH", processLD_LIBRARY_PATH(value));
- continue;
- }
+ // Do not pass LD_* variables to java. They were intended for MultiMC
+ if(key.startsWith("LD_"))
+ {
+ qDebug() << "Env: ignoring" << key << value;
+ continue;
+ }
+ // Strip IBus
+ // IBus is a Linux IME framework. For some reason, it breaks MC?
+ if (key == "XMODIFIERS" && value.contains(IBUS))
+ {
+ QString save = value;
+ value.replace(IBUS, "");
+ qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value;
+ }
+ if(key == "GAME_PRELOAD")
+ {
+ env.insert("LD_PRELOAD", value);
+ continue;
+ }
+ if(key == "GAME_LIBRARY_PATH")
+ {
+ env.insert("LD_LIBRARY_PATH", processLD_LIBRARY_PATH(value));
+ continue;
+ }
#endif
- // qDebug() << "Env: " << key << value;
- env.insert(key, value);
- }
+ // qDebug() << "Env: " << key << value;
+ env.insert(key, value);
+ }
#ifdef Q_OS_LINUX
- // HACK: Workaround for QTBUG42500
- if(!env.contains("LD_LIBRARY_PATH"))
- {
- env.insert("LD_LIBRARY_PATH", "");
- }
+ // HACK: Workaround for QTBUG42500
+ if(!env.contains("LD_LIBRARY_PATH"))
+ {
+ env.insert("LD_LIBRARY_PATH", "");
+ }
#endif
- return env;
+ return env;
}
JavaInstallPtr JavaUtils::MakeJavaPtr(QString path, QString id, QString arch)
{
- JavaInstallPtr javaVersion(new JavaInstall());
+ JavaInstallPtr javaVersion(new JavaInstall());
- javaVersion->id = id;
- javaVersion->arch = arch;
- javaVersion->path = path;
+ javaVersion->id = id;
+ javaVersion->arch = arch;
+ javaVersion->path = path;
- return javaVersion;
+ return javaVersion;
}
JavaInstallPtr JavaUtils::GetDefaultJava()
{
- JavaInstallPtr javaVersion(new JavaInstall());
+ JavaInstallPtr javaVersion(new JavaInstall());
- javaVersion->id = "java";
- javaVersion->arch = "unknown";
+ javaVersion->id = "java";
+ javaVersion->arch = "unknown";
#if defined(Q_OS_WIN32)
- javaVersion->path = "javaw";
+ javaVersion->path = "javaw";
#else
- javaVersion->path = "java";
+ javaVersion->path = "java";
#endif
- return javaVersion;
+ return javaVersion;
}
#if defined(Q_OS_WIN32)
QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName)
{
- QList<JavaInstallPtr> javas;
-
- QString archType = "unknown";
- if (keyType == KEY_WOW64_64KEY)
- archType = "64";
- else if (keyType == KEY_WOW64_32KEY)
- archType = "32";
-
- HKEY jreKey;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName.toStdString().c_str(), 0,
- KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) == ERROR_SUCCESS)
- {
- // Read the current type version from the registry.
- // This will be used to find any key that contains the JavaHome value.
- char *value = new char[0];
- DWORD valueSz = 0;
- if (RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz) ==
- ERROR_MORE_DATA)
- {
- value = new char[valueSz];
- RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz);
- }
-
- QString recommended = value;
-
- TCHAR subKeyName[255];
- DWORD subKeyNameSize, numSubKeys, retCode;
-
- // Get the number of subkeys
- RegQueryInfoKey(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL);
-
- // Iterate until RegEnumKeyEx fails
- if (numSubKeys > 0)
- {
- for (DWORD i = 0; i < numSubKeys; i++)
- {
- subKeyNameSize = 255;
- retCode = RegEnumKeyEx(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL,
- NULL);
- if (retCode == ERROR_SUCCESS)
- {
- // Now open the registry key for the version that we just got.
- QString newKeyName = keyName + "\\" + subKeyName;
-
- HKEY newKey;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, newKeyName.toStdString().c_str(), 0,
- KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS)
- {
- // Read the JavaHome value to find where Java is installed.
- value = new char[0];
- valueSz = 0;
- if (RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value,
- &valueSz) == ERROR_MORE_DATA)
- {
- value = new char[valueSz];
- RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value,
- &valueSz);
-
- // Now, we construct the version object and add it to the list.
- JavaInstallPtr javaVersion(new JavaInstall());
-
- javaVersion->id = subKeyName;
- javaVersion->arch = archType;
- javaVersion->path =
- QDir(FS::PathCombine(value, "bin")).absoluteFilePath("javaw.exe");
- javas.append(javaVersion);
- }
-
- RegCloseKey(newKey);
- }
- }
- }
- }
-
- RegCloseKey(jreKey);
- }
-
- return javas;
+ QList<JavaInstallPtr> javas;
+
+ QString archType = "unknown";
+ if (keyType == KEY_WOW64_64KEY)
+ archType = "64";
+ else if (keyType == KEY_WOW64_32KEY)
+ archType = "32";
+
+ HKEY jreKey;
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName.toStdString().c_str(), 0,
+ KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) == ERROR_SUCCESS)
+ {
+ // Read the current type version from the registry.
+ // This will be used to find any key that contains the JavaHome value.
+ char *value = new char[0];
+ DWORD valueSz = 0;
+ if (RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz) ==
+ ERROR_MORE_DATA)
+ {
+ value = new char[valueSz];
+ RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz);
+ }
+
+ QString recommended = value;
+
+ TCHAR subKeyName[255];
+ DWORD subKeyNameSize, numSubKeys, retCode;
+
+ // Get the number of subkeys
+ RegQueryInfoKey(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL);
+
+ // Iterate until RegEnumKeyEx fails
+ if (numSubKeys > 0)
+ {
+ for (DWORD i = 0; i < numSubKeys; i++)
+ {
+ subKeyNameSize = 255;
+ retCode = RegEnumKeyEx(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL,
+ NULL);
+ if (retCode == ERROR_SUCCESS)
+ {
+ // Now open the registry key for the version that we just got.
+ QString newKeyName = keyName + "\\" + subKeyName;
+
+ HKEY newKey;
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, newKeyName.toStdString().c_str(), 0,
+ KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS)
+ {
+ // Read the JavaHome value to find where Java is installed.
+ value = new char[0];
+ valueSz = 0;
+ if (RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value,
+ &valueSz) == ERROR_MORE_DATA)
+ {
+ value = new char[valueSz];
+ RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value,
+ &valueSz);
+
+ // Now, we construct the version object and add it to the list.
+ JavaInstallPtr javaVersion(new JavaInstall());
+
+ javaVersion->id = subKeyName;
+ javaVersion->arch = archType;
+ javaVersion->path =
+ QDir(FS::PathCombine(value, "bin")).absoluteFilePath("javaw.exe");
+ javas.append(javaVersion);
+ }
+
+ RegCloseKey(newKey);
+ }
+ }
+ }
+ }
+
+ RegCloseKey(jreKey);
+ }
+
+ return javas;
}
QList<QString> JavaUtils::FindJavaPaths()
{
- QList<JavaInstallPtr> java_candidates;
-
- QList<JavaInstallPtr> JRE64s = this->FindJavaFromRegistryKey(
- KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment");
- QList<JavaInstallPtr> JDK64s = this->FindJavaFromRegistryKey(
- KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit");
- QList<JavaInstallPtr> JRE32s = this->FindJavaFromRegistryKey(
- KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment");
- QList<JavaInstallPtr> JDK32s = this->FindJavaFromRegistryKey(
- KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit");
-
- java_candidates.append(JRE64s);
- java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre8/bin/javaw.exe"));
- java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre7/bin/javaw.exe"));
- java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre6/bin/javaw.exe"));
- java_candidates.append(JDK64s);
- java_candidates.append(JRE32s);
- java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre8/bin/javaw.exe"));
- java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre7/bin/javaw.exe"));
- java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre6/bin/javaw.exe"));
- java_candidates.append(JDK32s);
- java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path));
-
- QList<QString> candidates;
- for(JavaInstallPtr java_candidate : java_candidates)
- {
- if(!candidates.contains(java_candidate->path))
- {
- candidates.append(java_candidate->path);
- }
- }
-
- return candidates;
+ QList<JavaInstallPtr> java_candidates;
+
+ QList<JavaInstallPtr> JRE64s = this->FindJavaFromRegistryKey(
+ KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment");
+ QList<JavaInstallPtr> JDK64s = this->FindJavaFromRegistryKey(
+ KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit");
+ QList<JavaInstallPtr> JRE32s = this->FindJavaFromRegistryKey(
+ KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment");
+ QList<JavaInstallPtr> JDK32s = this->FindJavaFromRegistryKey(
+ KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit");
+
+ java_candidates.append(JRE64s);
+ java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre8/bin/javaw.exe"));
+ java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre7/bin/javaw.exe"));
+ java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre6/bin/javaw.exe"));
+ java_candidates.append(JDK64s);
+ java_candidates.append(JRE32s);
+ java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre8/bin/javaw.exe"));
+ java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre7/bin/javaw.exe"));
+ java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre6/bin/javaw.exe"));
+ java_candidates.append(JDK32s);
+ java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path));
+
+ QList<QString> candidates;
+ for(JavaInstallPtr java_candidate : java_candidates)
+ {
+ if(!candidates.contains(java_candidate->path))
+ {
+ candidates.append(java_candidate->path);
+ }
+ }
+
+ return candidates;
}
#elif defined(Q_OS_MAC)
QList<QString> JavaUtils::FindJavaPaths()
{
- QList<QString> javas;
- javas.append(this->GetDefaultJava()->path);
- javas.append("/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/bin/java");
- javas.append("/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java");
- javas.append("/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java");
- QDir libraryJVMDir("/Library/Java/JavaVirtualMachines/");
- QStringList libraryJVMJavas = libraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
- foreach (const QString &java, libraryJVMJavas) {
- javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
- javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/jre/bin/java");
- }
- QDir systemLibraryJVMDir("/System/Library/Java/JavaVirtualMachines/");
- QStringList systemLibraryJVMJavas = systemLibraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
- foreach (const QString &java, systemLibraryJVMJavas) {
- javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
- javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
- }
- return javas;
+ QList<QString> javas;
+ javas.append(this->GetDefaultJava()->path);
+ javas.append("/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/bin/java");
+ javas.append("/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java");
+ javas.append("/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java");
+ QDir libraryJVMDir("/Library/Java/JavaVirtualMachines/");
+ QStringList libraryJVMJavas = libraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+ foreach (const QString &java, libraryJVMJavas) {
+ javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
+ javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/jre/bin/java");
+ }
+ QDir systemLibraryJVMDir("/System/Library/Java/JavaVirtualMachines/");
+ QStringList systemLibraryJVMJavas = systemLibraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+ foreach (const QString &java, systemLibraryJVMJavas) {
+ javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
+ javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
+ }
+ return javas;
}
#elif defined(Q_OS_LINUX)
QList<QString> JavaUtils::FindJavaPaths()
{
- qDebug() << "Linux Java detection incomplete - defaulting to \"java\"";
-
- QList<QString> javas;
- javas.append(this->GetDefaultJava()->path);
- auto scanJavaDir = [&](const QString & dirPath)
- {
- QDir dir(dirPath);
- if(!dir.exists())
- return;
- auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
- for(auto & entry: entries)
- {
-
- QString prefix;
- if(entry.isAbsolute())
- {
- prefix = entry.absoluteFilePath();
- }
- else
- {
- prefix = entry.filePath();
- }
-
- javas.append(FS::PathCombine(prefix, "jre/bin/java"));
- javas.append(FS::PathCombine(prefix, "bin/java"));
- }
- };
- // oracle RPMs
- scanJavaDir("/usr/java");
- // general locations used by distro packaging
- scanJavaDir("/usr/lib/jvm");
- scanJavaDir("/usr/lib32/jvm");
- // javas stored in MultiMC's folder
- scanJavaDir("java");
- return javas;
+ qDebug() << "Linux Java detection incomplete - defaulting to \"java\"";
+
+ QList<QString> javas;
+ javas.append(this->GetDefaultJava()->path);
+ auto scanJavaDir = [&](const QString & dirPath)
+ {
+ QDir dir(dirPath);
+ if(!dir.exists())
+ return;
+ auto entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
+ for(auto & entry: entries)
+ {
+
+ QString prefix;
+ if(entry.isAbsolute())
+ {
+ prefix = entry.absoluteFilePath();
+ }
+ else
+ {
+ prefix = entry.filePath();
+ }
+
+ javas.append(FS::PathCombine(prefix, "jre/bin/java"));
+ javas.append(FS::PathCombine(prefix, "bin/java"));
+ }
+ };
+ // oracle RPMs
+ scanJavaDir("/usr/java");
+ // general locations used by distro packaging
+ scanJavaDir("/usr/lib/jvm");
+ scanJavaDir("/usr/lib32/jvm");
+ // javas stored in MultiMC's folder
+ scanJavaDir("java");
+ return javas;
}
#else
QList<QString> JavaUtils::FindJavaPaths()
{
- qDebug() << "Unknown operating system build - defaulting to \"java\"";
+ qDebug() << "Unknown operating system build - defaulting to \"java\"";
- QList<QString> javas;
- javas.append(this->GetDefaultJava()->path);
+ QList<QString> javas;
+ javas.append(this->GetDefaultJava()->path);
- return javas;
+ return javas;
}
#endif
diff --git a/api/logic/java/JavaUtils.h b/api/logic/java/JavaUtils.h
index b43e93cf..40745ad6 100644
--- a/api/logic/java/JavaUtils.h
+++ b/api/logic/java/JavaUtils.h
@@ -30,15 +30,15 @@ QProcessEnvironment CleanEnviroment();
class MULTIMC_LOGIC_EXPORT JavaUtils : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- JavaUtils();
+ JavaUtils();
- JavaInstallPtr MakeJavaPtr(QString path, QString id = "unknown", QString arch = "unknown");
- QList<QString> FindJavaPaths();
- JavaInstallPtr GetDefaultJava();
+ JavaInstallPtr MakeJavaPtr(QString path, QString id = "unknown", QString arch = "unknown");
+ QList<QString> FindJavaPaths();
+ JavaInstallPtr GetDefaultJava();
#ifdef Q_OS_WIN
- QList<JavaInstallPtr> FindJavaFromRegistryKey(DWORD keyType, QString keyName);
+ QList<JavaInstallPtr> FindJavaFromRegistryKey(DWORD keyType, QString keyName);
#endif
};
diff --git a/api/logic/java/JavaVersion.cpp b/api/logic/java/JavaVersion.cpp
index 27050da3..179ccd8d 100644
--- a/api/logic/java/JavaVersion.cpp
+++ b/api/logic/java/JavaVersion.cpp
@@ -6,116 +6,116 @@
JavaVersion & JavaVersion::operator=(const QString & javaVersionString)
{
- m_string = javaVersionString;
+ m_string = javaVersionString;
- auto getCapturedInteger = [](const QRegularExpressionMatch & match, const QString &what) -> int
- {
- auto str = match.captured(what);
- if(str.isEmpty())
- {
- return 0;
- }
- return str.toInt();
- };
+ auto getCapturedInteger = [](const QRegularExpressionMatch & match, const QString &what) -> int
+ {
+ auto str = match.captured(what);
+ if(str.isEmpty())
+ {
+ return 0;
+ }
+ return str.toInt();
+ };
- QRegularExpression pattern;
- if(javaVersionString.startsWith("1."))
- {
- pattern = QRegularExpression ("1[.](?<major>[0-9]+)([.](?<minor>[0-9]+))?(_(?<security>[0-9]+)?)?(-(?<prerelease>[a-zA-Z0-9]+))?");
- }
- else
- {
- pattern = QRegularExpression("(?<major>[0-9]+)([.](?<minor>[0-9]+))?([.](?<security>[0-9]+))?(-(?<prerelease>[a-zA-Z0-9]+))?");
- }
+ QRegularExpression pattern;
+ if(javaVersionString.startsWith("1."))
+ {
+ pattern = QRegularExpression ("1[.](?<major>[0-9]+)([.](?<minor>[0-9]+))?(_(?<security>[0-9]+)?)?(-(?<prerelease>[a-zA-Z0-9]+))?");
+ }
+ else
+ {
+ pattern = QRegularExpression("(?<major>[0-9]+)([.](?<minor>[0-9]+))?([.](?<security>[0-9]+))?(-(?<prerelease>[a-zA-Z0-9]+))?");
+ }
- auto match = pattern.match(m_string);
- m_parseable = match.hasMatch();
- m_major = getCapturedInteger(match, "major");
- m_minor = getCapturedInteger(match, "minor");
- m_security = getCapturedInteger(match, "security");
- m_prerelease = match.captured("prerelease");
- return *this;
+ auto match = pattern.match(m_string);
+ m_parseable = match.hasMatch();
+ m_major = getCapturedInteger(match, "major");
+ m_minor = getCapturedInteger(match, "minor");
+ m_security = getCapturedInteger(match, "security");
+ m_prerelease = match.captured("prerelease");
+ return *this;
}
JavaVersion::JavaVersion(const QString &rhs)
{
- operator=(rhs);
+ operator=(rhs);
}
QString JavaVersion::toString()
{
- return m_string;
+ return m_string;
}
bool JavaVersion::requiresPermGen()
{
- if(m_parseable)
- {
- return m_major < 8;
- }
- return true;
+ if(m_parseable)
+ {
+ return m_major < 8;
+ }
+ return true;
}
bool JavaVersion::operator<(const JavaVersion &rhs)
{
- if(m_parseable && rhs.m_parseable)
- {
- auto major = m_major;
- auto rmajor = rhs.m_major;
+ if(m_parseable && rhs.m_parseable)
+ {
+ auto major = m_major;
+ auto rmajor = rhs.m_major;
- // HACK: discourage using java 9
- if(major > 8)
- major = -major;
- if(rmajor > 8)
- rmajor = -rmajor;
+ // HACK: discourage using java 9
+ if(major > 8)
+ major = -major;
+ if(rmajor > 8)
+ rmajor = -rmajor;
- if(major < rmajor)
- return true;
- if(major > rmajor)
- return false;
- if(m_minor < rhs.m_minor)
- return true;
- if(m_minor > rhs.m_minor)
- return false;
- if(m_security < rhs.m_security)
- return true;
- if(m_security > rhs.m_security)
- return false;
+ if(major < rmajor)
+ return true;
+ if(major > rmajor)
+ return false;
+ if(m_minor < rhs.m_minor)
+ return true;
+ if(m_minor > rhs.m_minor)
+ return false;
+ if(m_security < rhs.m_security)
+ return true;
+ if(m_security > rhs.m_security)
+ return false;
- // everything else being equal, consider prerelease status
- bool thisPre = !m_prerelease.isEmpty();
- bool rhsPre = !rhs.m_prerelease.isEmpty();
- if(thisPre && !rhsPre)
- {
- // this is a prerelease and the other one isn't -> lesser
- return true;
- }
- else if(!thisPre && rhsPre)
- {
- // this isn't a prerelease and the other one is -> greater
- return false;
- }
- else if(thisPre && rhsPre)
- {
- // both are prereleases - use natural compare...
- return Strings::naturalCompare(m_prerelease, rhs.m_prerelease, Qt::CaseSensitive) < 0;
- }
- // neither is prerelease, so they are the same -> this cannot be less than rhs
- return false;
- }
- else return Strings::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0;
+ // everything else being equal, consider prerelease status
+ bool thisPre = !m_prerelease.isEmpty();
+ bool rhsPre = !rhs.m_prerelease.isEmpty();
+ if(thisPre && !rhsPre)
+ {
+ // this is a prerelease and the other one isn't -> lesser
+ return true;
+ }
+ else if(!thisPre && rhsPre)
+ {
+ // this isn't a prerelease and the other one is -> greater
+ return false;
+ }
+ else if(thisPre && rhsPre)
+ {
+ // both are prereleases - use natural compare...
+ return Strings::naturalCompare(m_prerelease, rhs.m_prerelease, Qt::CaseSensitive) < 0;
+ }
+ // neither is prerelease, so they are the same -> this cannot be less than rhs
+ return false;
+ }
+ else return Strings::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0;
}
bool JavaVersion::operator==(const JavaVersion &rhs)
{
- if(m_parseable && rhs.m_parseable)
- {
- return m_major == rhs.m_major && m_minor == rhs.m_minor && m_security == rhs.m_security && m_prerelease == rhs.m_prerelease;
- }
- return m_string == rhs.m_string;
+ if(m_parseable && rhs.m_parseable)
+ {
+ return m_major == rhs.m_major && m_minor == rhs.m_minor && m_security == rhs.m_security && m_prerelease == rhs.m_prerelease;
+ }
+ return m_string == rhs.m_string;
}
bool JavaVersion::operator>(const JavaVersion &rhs)
{
- return (!operator<(rhs)) && (!operator==(rhs));
+ return (!operator<(rhs)) && (!operator==(rhs));
}
diff --git a/api/logic/java/JavaVersion.h b/api/logic/java/JavaVersion.h
index de13998c..8589c21a 100644
--- a/api/logic/java/JavaVersion.h
+++ b/api/logic/java/JavaVersion.h
@@ -5,46 +5,46 @@
// NOTE: apparently the GNU C library pollutes the global namespace with these... undef them.
#ifdef major
- #undef major
+ #undef major
#endif
#ifdef minor
- #undef minor
+ #undef minor
#endif
class MULTIMC_LOGIC_EXPORT JavaVersion
{
- friend class JavaVersionTest;
+ friend class JavaVersionTest;
public:
- JavaVersion() {};
- JavaVersion(const QString & rhs);
-
- JavaVersion & operator=(const QString & rhs);
-
- bool operator<(const JavaVersion & rhs);
- bool operator==(const JavaVersion & rhs);
- bool operator>(const JavaVersion & rhs);
-
- bool requiresPermGen();
-
- QString toString();
-
- int major()
- {
- return m_major;
- }
- int minor()
- {
- return m_minor;
- }
- int security()
- {
- return m_security;
- }
+ JavaVersion() {};
+ JavaVersion(const QString & rhs);
+
+ JavaVersion & operator=(const QString & rhs);
+
+ bool operator<(const JavaVersion & rhs);
+ bool operator==(const JavaVersion & rhs);
+ bool operator>(const JavaVersion & rhs);
+
+ bool requiresPermGen();
+
+ QString toString();
+
+ int major()
+ {
+ return m_major;
+ }
+ int minor()
+ {
+ return m_minor;
+ }
+ int security()
+ {
+ return m_security;
+ }
private:
- QString m_string;
- int m_major = 0;
- int m_minor = 0;
- int m_security = 0;
- bool m_parseable = false;
- QString m_prerelease;
+ QString m_string;
+ int m_major = 0;
+ int m_minor = 0;
+ int m_security = 0;
+ bool m_parseable = false;
+ QString m_prerelease;
};
diff --git a/api/logic/java/JavaVersion_test.cpp b/api/logic/java/JavaVersion_test.cpp
index e719ffc8..10ae13a7 100644
--- a/api/logic/java/JavaVersion_test.cpp
+++ b/api/logic/java/JavaVersion_test.cpp
@@ -5,110 +5,110 @@
class JavaVersionTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- void test_Parse_data()
- {
- QTest::addColumn<QString>("string");
- QTest::addColumn<int>("major");
- QTest::addColumn<int>("minor");
- QTest::addColumn<int>("security");
- QTest::addColumn<QString>("prerelease");
+ void test_Parse_data()
+ {
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<int>("major");
+ QTest::addColumn<int>("minor");
+ QTest::addColumn<int>("security");
+ QTest::addColumn<QString>("prerelease");
- QTest::newRow("old format") << "1.6.0_33" << 6 << 0 << 33 << QString();
- QTest::newRow("old format prerelease") << "1.9.0_1-ea" << 9 << 0 << 1 << "ea";
+ QTest::newRow("old format") << "1.6.0_33" << 6 << 0 << 33 << QString();
+ QTest::newRow("old format prerelease") << "1.9.0_1-ea" << 9 << 0 << 1 << "ea";
- QTest::newRow("new format major") << "9" << 9 << 0 << 0 << QString();
- QTest::newRow("new format minor") << "9.1" << 9 << 1 << 0 << QString();
- QTest::newRow("new format security") << "9.0.1" << 9 << 0 << 1 << QString();
- QTest::newRow("new format prerelease") << "9-ea" << 9 << 0 << 0 << "ea";
- QTest::newRow("new format long prerelease") << "9.0.1-ea" << 9 << 0 << 1 << "ea";
- }
- void test_Parse()
- {
- QFETCH(QString, string);
- QFETCH(int, major);
- QFETCH(int, minor);
- QFETCH(int, security);
- QFETCH(QString, prerelease);
+ QTest::newRow("new format major") << "9" << 9 << 0 << 0 << QString();
+ QTest::newRow("new format minor") << "9.1" << 9 << 1 << 0 << QString();
+ QTest::newRow("new format security") << "9.0.1" << 9 << 0 << 1 << QString();
+ QTest::newRow("new format prerelease") << "9-ea" << 9 << 0 << 0 << "ea";
+ QTest::newRow("new format long prerelease") << "9.0.1-ea" << 9 << 0 << 1 << "ea";
+ }
+ void test_Parse()
+ {
+ QFETCH(QString, string);
+ QFETCH(int, major);
+ QFETCH(int, minor);
+ QFETCH(int, security);
+ QFETCH(QString, prerelease);
- JavaVersion test(string);
- QCOMPARE(test.m_string, string);
- QCOMPARE(test.toString(), string);
- QCOMPARE(test.m_major, major);
- QCOMPARE(test.m_minor, minor);
- QCOMPARE(test.m_security, security);
- QCOMPARE(test.m_prerelease, prerelease);
- }
+ JavaVersion test(string);
+ QCOMPARE(test.m_string, string);
+ QCOMPARE(test.toString(), string);
+ QCOMPARE(test.m_major, major);
+ QCOMPARE(test.m_minor, minor);
+ QCOMPARE(test.m_security, security);
+ QCOMPARE(test.m_prerelease, prerelease);
+ }
- void test_Sort_data()
- {
- QTest::addColumn<QString>("lhs");
- QTest::addColumn<QString>("rhs");
- QTest::addColumn<bool>("smaller");
- QTest::addColumn<bool>("equal");
- QTest::addColumn<bool>("bigger");
+ void test_Sort_data()
+ {
+ QTest::addColumn<QString>("lhs");
+ QTest::addColumn<QString>("rhs");
+ QTest::addColumn<bool>("smaller");
+ QTest::addColumn<bool>("equal");
+ QTest::addColumn<bool>("bigger");
- // old format and new format equivalence
- QTest::newRow("1.6.0_33 == 6.0.33") << "1.6.0_33" << "6.0.33" << false << true << false;
- // old format major version
- QTest::newRow("1.5.0_33 < 1.6.0_33") << "1.5.0_33" << "1.6.0_33" << true << false << false;
- // new format - first release vs first security patch
- QTest::newRow("9 < 9.0.1") << "9" << "9.0.1" << true << false << false;
- QTest::newRow("9.0.1 > 9") << "9.0.1" << "9" << false << false << true;
- // new format - first minor vs first release/security patch
- QTest::newRow("9.1 > 9.0.1") << "9.1" << "9.0.1" << false << false << true;
- QTest::newRow("9.0.1 < 9.1") << "9.0.1" << "9.1" << true << false << false;
- QTest::newRow("9.1 > 9") << "9.1" << "9" << false << false << true;
- QTest::newRow("9 > 9.1") << "9" << "9.1" << true << false << false;
- // new format - omitted numbers
- QTest::newRow("9 == 9.0") << "9" << "9.0" << false << true << false;
- QTest::newRow("9 == 9.0.0") << "9" << "9.0.0" << false << true << false;
- QTest::newRow("9.0 == 9.0.0") << "9.0" << "9.0.0" << false << true << false;
- // early access and prereleases compared to final release
- QTest::newRow("9-ea < 9") << "9-ea" << "9" << true << false << false;
- QTest::newRow("9 < 9.0.1-ea") << "9" << "9.0.1-ea" << true << false << false;
- QTest::newRow("9.0.1-ea > 9") << "9.0.1-ea" << "9" << false << false << true;
- // prerelease difference only testing
- QTest::newRow("9-1 == 9-1") << "9-1" << "9-1" << false << true << false;
- QTest::newRow("9-1 < 9-2") << "9-1" << "9-2" << true << false << false;
- QTest::newRow("9-5 < 9-20") << "9-5" << "9-20" << true << false << false;
- QTest::newRow("9-rc1 < 9-rc2") << "9-rc1" << "9-rc2" << true << false << false;
- QTest::newRow("9-rc5 < 9-rc20") << "9-rc5" << "9-rc20" << true << false << false;
- QTest::newRow("9-rc < 9-rc2") << "9-rc" << "9-rc2" << true << false << false;
- QTest::newRow("9-ea < 9-rc") << "9-ea" << "9-rc" << true << false << false;
- }
- void test_Sort()
- {
- QFETCH(QString, lhs);
- QFETCH(QString, rhs);
- QFETCH(bool, smaller);
- QFETCH(bool, equal);
- QFETCH(bool, bigger);
- JavaVersion lver(lhs);
- JavaVersion rver(rhs);
- QCOMPARE(lver < rver, smaller);
- QCOMPARE(lver == rver, equal);
- QCOMPARE(lver > rver, bigger);
- }
- void test_PermGen_data()
- {
- QTest::addColumn<QString>("version");
- QTest::addColumn<bool>("needs_permgen");
- QTest::newRow("1.6.0_33") << "1.6.0_33" << true;
- QTest::newRow("1.7.0_60") << "1.7.0_60" << true;
- QTest::newRow("1.8.0_22") << "1.8.0_22" << false;
- QTest::newRow("9-ea") << "9-ea" << false;
- QTest::newRow("9.2.4") << "9.2.4" << false;
- }
- void test_PermGen()
- {
- QFETCH(QString, version);
- QFETCH(bool, needs_permgen);
- JavaVersion v(version);
- QCOMPARE(needs_permgen, v.requiresPermGen());
- }
+ // old format and new format equivalence
+ QTest::newRow("1.6.0_33 == 6.0.33") << "1.6.0_33" << "6.0.33" << false << true << false;
+ // old format major version
+ QTest::newRow("1.5.0_33 < 1.6.0_33") << "1.5.0_33" << "1.6.0_33" << true << false << false;
+ // new format - first release vs first security patch
+ QTest::newRow("9 < 9.0.1") << "9" << "9.0.1" << true << false << false;
+ QTest::newRow("9.0.1 > 9") << "9.0.1" << "9" << false << false << true;
+ // new format - first minor vs first release/security patch
+ QTest::newRow("9.1 > 9.0.1") << "9.1" << "9.0.1" << false << false << true;
+ QTest::newRow("9.0.1 < 9.1") << "9.0.1" << "9.1" << true << false << false;
+ QTest::newRow("9.1 > 9") << "9.1" << "9" << false << false << true;
+ QTest::newRow("9 > 9.1") << "9" << "9.1" << true << false << false;
+ // new format - omitted numbers
+ QTest::newRow("9 == 9.0") << "9" << "9.0" << false << true << false;
+ QTest::newRow("9 == 9.0.0") << "9" << "9.0.0" << false << true << false;
+ QTest::newRow("9.0 == 9.0.0") << "9.0" << "9.0.0" << false << true << false;
+ // early access and prereleases compared to final release
+ QTest::newRow("9-ea < 9") << "9-ea" << "9" << true << false << false;
+ QTest::newRow("9 < 9.0.1-ea") << "9" << "9.0.1-ea" << true << false << false;
+ QTest::newRow("9.0.1-ea > 9") << "9.0.1-ea" << "9" << false << false << true;
+ // prerelease difference only testing
+ QTest::newRow("9-1 == 9-1") << "9-1" << "9-1" << false << true << false;
+ QTest::newRow("9-1 < 9-2") << "9-1" << "9-2" << true << false << false;
+ QTest::newRow("9-5 < 9-20") << "9-5" << "9-20" << true << false << false;
+ QTest::newRow("9-rc1 < 9-rc2") << "9-rc1" << "9-rc2" << true << false << false;
+ QTest::newRow("9-rc5 < 9-rc20") << "9-rc5" << "9-rc20" << true << false << false;
+ QTest::newRow("9-rc < 9-rc2") << "9-rc" << "9-rc2" << true << false << false;
+ QTest::newRow("9-ea < 9-rc") << "9-ea" << "9-rc" << true << false << false;
+ }
+ void test_Sort()
+ {
+ QFETCH(QString, lhs);
+ QFETCH(QString, rhs);
+ QFETCH(bool, smaller);
+ QFETCH(bool, equal);
+ QFETCH(bool, bigger);
+ JavaVersion lver(lhs);
+ JavaVersion rver(rhs);
+ QCOMPARE(lver < rver, smaller);
+ QCOMPARE(lver == rver, equal);
+ QCOMPARE(lver > rver, bigger);
+ }
+ void test_PermGen_data()
+ {
+ QTest::addColumn<QString>("version");
+ QTest::addColumn<bool>("needs_permgen");
+ QTest::newRow("1.6.0_33") << "1.6.0_33" << true;
+ QTest::newRow("1.7.0_60") << "1.7.0_60" << true;
+ QTest::newRow("1.8.0_22") << "1.8.0_22" << false;
+ QTest::newRow("9-ea") << "9-ea" << false;
+ QTest::newRow("9.2.4") << "9.2.4" << false;
+ }
+ void test_PermGen()
+ {
+ QFETCH(QString, version);
+ QFETCH(bool, needs_permgen);
+ JavaVersion v(version);
+ QCOMPARE(needs_permgen, v.requiresPermGen());
+ }
};
QTEST_GUILESS_MAIN(JavaVersionTest)
diff --git a/api/logic/java/launch/CheckJava.cpp b/api/logic/java/launch/CheckJava.cpp
index 24f26682..4ea40084 100644
--- a/api/logic/java/launch/CheckJava.cpp
+++ b/api/logic/java/launch/CheckJava.cpp
@@ -22,115 +22,115 @@
void CheckJava::executeTask()
{
- auto instance = m_parent->instance();
- auto settings = instance->settings();
- m_javaPath = FS::ResolveExecutable(settings->get("JavaPath").toString());
- bool perInstance = settings->get("OverrideJava").toBool() || settings->get("OverrideJavaLocation").toBool();
+ auto instance = m_parent->instance();
+ auto settings = instance->settings();
+ m_javaPath = FS::ResolveExecutable(settings->get("JavaPath").toString());
+ bool perInstance = settings->get("OverrideJava").toBool() || settings->get("OverrideJavaLocation").toBool();
- auto realJavaPath = QStandardPaths::findExecutable(m_javaPath);
- if (realJavaPath.isEmpty())
- {
- if (perInstance)
- {
- emit logLine(
- tr("The java binary \"%1\" couldn't be found. Please fix the java path "
- "override in the instance's settings or disable it.").arg(m_javaPath),
- MessageLevel::Warning);
- }
- else
- {
- emit logLine(tr("The java binary \"%1\" couldn't be found. Please set up java in "
- "the settings.").arg(m_javaPath),
- MessageLevel::Warning);
- }
- emitFailed(tr("Java path is not valid."));
- return;
- }
- else
- {
- emit logLine("Java path is:\n" + m_javaPath + "\n\n", MessageLevel::MultiMC);
- }
+ auto realJavaPath = QStandardPaths::findExecutable(m_javaPath);
+ if (realJavaPath.isEmpty())
+ {
+ if (perInstance)
+ {
+ emit logLine(
+ tr("The java binary \"%1\" couldn't be found. Please fix the java path "
+ "override in the instance's settings or disable it.").arg(m_javaPath),
+ MessageLevel::Warning);
+ }
+ else
+ {
+ emit logLine(tr("The java binary \"%1\" couldn't be found. Please set up java in "
+ "the settings.").arg(m_javaPath),
+ MessageLevel::Warning);
+ }
+ emitFailed(tr("Java path is not valid."));
+ return;
+ }
+ else
+ {
+ emit logLine("Java path is:\n" + m_javaPath + "\n\n", MessageLevel::MultiMC);
+ }
- QFileInfo javaInfo(realJavaPath);
- qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch();
- auto storedUnixTime = settings->get("JavaTimestamp").toLongLong();
- auto storedArchitecture = settings->get("JavaArchitecture").toString();
- auto storedVersion = settings->get("JavaVersion").toString();
- m_javaUnixTime = javaUnixTime;
- // if timestamps are not the same, or something is missing, check!
- if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 || storedArchitecture.size() == 0)
- {
- m_JavaChecker = std::make_shared<JavaChecker>();
- emit logLine(tr("Checking Java version..."), MessageLevel::MultiMC);
- connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished);
- m_JavaChecker->m_path = realJavaPath;
- m_JavaChecker->performCheck();
- return;
- }
- else
- {
- auto verString = instance->settings()->get("JavaVersion").toString();
- auto archString = instance->settings()->get("JavaArchitecture").toString();
- printJavaInfo(verString, archString);
- }
- emitSucceeded();
+ QFileInfo javaInfo(realJavaPath);
+ qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch();
+ auto storedUnixTime = settings->get("JavaTimestamp").toLongLong();
+ auto storedArchitecture = settings->get("JavaArchitecture").toString();
+ auto storedVersion = settings->get("JavaVersion").toString();
+ m_javaUnixTime = javaUnixTime;
+ // if timestamps are not the same, or something is missing, check!
+ if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 || storedArchitecture.size() == 0)
+ {
+ m_JavaChecker = std::make_shared<JavaChecker>();
+ emit logLine(tr("Checking Java version..."), MessageLevel::MultiMC);
+ connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished);
+ m_JavaChecker->m_path = realJavaPath;
+ m_JavaChecker->performCheck();
+ return;
+ }
+ else
+ {
+ auto verString = instance->settings()->get("JavaVersion").toString();
+ auto archString = instance->settings()->get("JavaArchitecture").toString();
+ printJavaInfo(verString, archString);
+ }
+ emitSucceeded();
}
void CheckJava::checkJavaFinished(JavaCheckResult result)
{
- switch (result.validity)
- {
- case JavaCheckResult::Validity::Errored:
- {
- // Error message displayed if java can't start
- emit logLine(tr("Could not start java:"), MessageLevel::Error);
- emit logLines(result.errorLog.split('\n'), MessageLevel::Error);
- emit logLine("\nCheck your MultiMC Java settings.", MessageLevel::MultiMC);
- printSystemInfo(false, false);
- emitFailed(tr("Could not start java!"));
- return;
- }
- case JavaCheckResult::Validity::ReturnedInvalidData:
- {
- emit logLine(tr("Java checker returned some invalid data MultiMC doesn't understand:"), MessageLevel::Error);
- emit logLines(result.outLog.split('\n'), MessageLevel::Warning);
- emit logLine("\nMinecraft might not start properly.", MessageLevel::MultiMC);
- printSystemInfo(false, false);
- emitSucceeded();
- return;
- }
- case JavaCheckResult::Validity::Valid:
- {
- auto instance = m_parent->instance();
- printJavaInfo(result.javaVersion.toString(), result.mojangPlatform);
- instance->settings()->set("JavaVersion", result.javaVersion.toString());
- instance->settings()->set("JavaArchitecture", result.mojangPlatform);
- instance->settings()->set("JavaTimestamp", m_javaUnixTime);
- emitSucceeded();
- return;
- }
- }
+ switch (result.validity)
+ {
+ case JavaCheckResult::Validity::Errored:
+ {
+ // Error message displayed if java can't start
+ emit logLine(tr("Could not start java:"), MessageLevel::Error);
+ emit logLines(result.errorLog.split('\n'), MessageLevel::Error);
+ emit logLine("\nCheck your MultiMC Java settings.", MessageLevel::MultiMC);
+ printSystemInfo(false, false);
+ emitFailed(tr("Could not start java!"));
+ return;
+ }
+ case JavaCheckResult::Validity::ReturnedInvalidData:
+ {
+ emit logLine(tr("Java checker returned some invalid data MultiMC doesn't understand:"), MessageLevel::Error);
+ emit logLines(result.outLog.split('\n'), MessageLevel::Warning);
+ emit logLine("\nMinecraft might not start properly.", MessageLevel::MultiMC);
+ printSystemInfo(false, false);
+ emitSucceeded();
+ return;
+ }
+ case JavaCheckResult::Validity::Valid:
+ {
+ auto instance = m_parent->instance();
+ printJavaInfo(result.javaVersion.toString(), result.mojangPlatform);
+ instance->settings()->set("JavaVersion", result.javaVersion.toString());
+ instance->settings()->set("JavaArchitecture", result.mojangPlatform);
+ instance->settings()->set("JavaTimestamp", m_javaUnixTime);
+ emitSucceeded();
+ return;
+ }
+ }
}
void CheckJava::printJavaInfo(const QString& version, const QString& architecture)
{
- emit logLine(tr("Java is version %1, using %2-bit architecture.\n\n").arg(version, architecture), MessageLevel::MultiMC);
- printSystemInfo(true, architecture == "64");
+ emit logLine(tr("Java is version %1, using %2-bit architecture.\n\n").arg(version, architecture), MessageLevel::MultiMC);
+ printSystemInfo(true, architecture == "64");
}
void CheckJava::printSystemInfo(bool javaIsKnown, bool javaIs64bit)
{
- auto cpu64 = Sys::isCPU64bit();
- auto system64 = Sys::isSystem64bit();
- if(cpu64 != system64)
- {
- emit logLine(tr("Your CPU architecture is not matching your system architecture. You might want to install a 64bit Operating System.\n\n"), MessageLevel::Error);
- }
- if(javaIsKnown)
- {
- if(javaIs64bit != system64)
- {
- emit logLine(tr("Your Java architecture is not matching your system architecture. You might want to install a 64bit Java version.\n\n"), MessageLevel::Error);
- }
- }
+ auto cpu64 = Sys::isCPU64bit();
+ auto system64 = Sys::isSystem64bit();
+ if(cpu64 != system64)
+ {
+ emit logLine(tr("Your CPU architecture is not matching your system architecture. You might want to install a 64bit Operating System.\n\n"), MessageLevel::Error);
+ }
+ if(javaIsKnown)
+ {
+ if(javaIs64bit != system64)
+ {
+ emit logLine(tr("Your Java architecture is not matching your system architecture. You might want to install a 64bit Java version.\n\n"), MessageLevel::Error);
+ }
+ }
}
diff --git a/api/logic/java/launch/CheckJava.h b/api/logic/java/launch/CheckJava.h
index 82508cd4..be247a1b 100644
--- a/api/logic/java/launch/CheckJava.h
+++ b/api/logic/java/launch/CheckJava.h
@@ -21,25 +21,25 @@
class CheckJava: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit CheckJava(LaunchTask *parent) :LaunchStep(parent){};
- virtual ~CheckJava() {};
+ explicit CheckJava(LaunchTask *parent) :LaunchStep(parent){};
+ virtual ~CheckJava() {};
- virtual void executeTask();
- virtual bool canAbort() const
- {
- return false;
- }
+ virtual void executeTask();
+ virtual bool canAbort() const
+ {
+ return false;
+ }
private slots:
- void checkJavaFinished(JavaCheckResult result);
+ void checkJavaFinished(JavaCheckResult result);
private:
- void printJavaInfo(const QString & version, const QString & architecture);
- void printSystemInfo(bool javaIsKnown, bool javaIs64bit);
+ void printJavaInfo(const QString & version, const QString & architecture);
+ void printSystemInfo(bool javaIsKnown, bool javaIs64bit);
private:
- QString m_javaPath;
- qlonglong m_javaUnixTime;
- JavaCheckerPtr m_JavaChecker;
+ QString m_javaPath;
+ qlonglong m_javaUnixTime;
+ JavaCheckerPtr m_JavaChecker;
};
diff --git a/api/logic/launch/LaunchStep.cpp b/api/logic/launch/LaunchStep.cpp
index 01f72a0a..e2327712 100644
--- a/api/logic/launch/LaunchStep.cpp
+++ b/api/logic/launch/LaunchStep.cpp
@@ -18,10 +18,10 @@
void LaunchStep::bind(LaunchTask *parent)
{
- m_parent = parent;
- connect(this, &LaunchStep::readyForLaunch, parent, &LaunchTask::onReadyForLaunch);
- connect(this, &LaunchStep::logLine, parent, &LaunchTask::onLogLine);
- connect(this, &LaunchStep::logLines, parent, &LaunchTask::onLogLines);
- connect(this, &LaunchStep::finished, parent, &LaunchTask::onStepFinished);
- connect(this, &LaunchStep::progressReportingRequest, parent, &LaunchTask::onProgressReportingRequested);
+ m_parent = parent;
+ connect(this, &LaunchStep::readyForLaunch, parent, &LaunchTask::onReadyForLaunch);
+ connect(this, &LaunchStep::logLine, parent, &LaunchTask::onLogLine);
+ connect(this, &LaunchStep::logLines, parent, &LaunchTask::onLogLines);
+ connect(this, &LaunchStep::finished, parent, &LaunchTask::onStepFinished);
+ connect(this, &LaunchStep::progressReportingRequest, parent, &LaunchTask::onProgressReportingRequested);
}
diff --git a/api/logic/launch/LaunchStep.h b/api/logic/launch/LaunchStep.h
index 80778e34..0abe456a 100644
--- a/api/logic/launch/LaunchStep.h
+++ b/api/logic/launch/LaunchStep.h
@@ -23,28 +23,28 @@
class LaunchTask;
class LaunchStep: public Task
{
- Q_OBJECT
+ Q_OBJECT
public: /* methods */
- explicit LaunchStep(LaunchTask *parent):Task(nullptr), m_parent(parent)
- {
- bind(parent);
- };
- virtual ~LaunchStep() {};
+ explicit LaunchStep(LaunchTask *parent):Task(nullptr), m_parent(parent)
+ {
+ bind(parent);
+ };
+ virtual ~LaunchStep() {};
protected: /* methods */
- virtual void bind(LaunchTask *parent);
+ virtual void bind(LaunchTask *parent);
signals:
- void logLines(QStringList lines, MessageLevel::Enum level);
- void logLine(QString line, MessageLevel::Enum level);
- void readyForLaunch();
- void progressReportingRequest();
+ void logLines(QStringList lines, MessageLevel::Enum level);
+ void logLine(QString line, MessageLevel::Enum level);
+ void readyForLaunch();
+ void progressReportingRequest();
public slots:
- virtual void proceed() {};
- // called in the opposite order than the Task launch(), used to clean up or otherwise undo things after the launch ends
- virtual void finalize() {};
+ virtual void proceed() {};
+ // called in the opposite order than the Task launch(), used to clean up or otherwise undo things after the launch ends
+ virtual void finalize() {};
protected: /* data */
- LaunchTask *m_parent;
+ LaunchTask *m_parent;
}; \ No newline at end of file
diff --git a/api/logic/launch/LaunchTask.cpp b/api/logic/launch/LaunchTask.cpp
index 99c16721..c00fa32a 100644
--- a/api/logic/launch/LaunchTask.cpp
+++ b/api/logic/launch/LaunchTask.cpp
@@ -30,14 +30,14 @@
void LaunchTask::init()
{
- m_instance->setRunning(true);
+ m_instance->setRunning(true);
}
std::shared_ptr<LaunchTask> LaunchTask::create(InstancePtr inst)
{
- std::shared_ptr<LaunchTask> proc(new LaunchTask(inst));
- proc->init();
- return proc;
+ std::shared_ptr<LaunchTask> proc(new LaunchTask(inst));
+ proc->init();
+ return proc;
}
LaunchTask::LaunchTask(InstancePtr instance): m_instance(instance)
@@ -46,235 +46,235 @@ LaunchTask::LaunchTask(InstancePtr instance): m_instance(instance)
void LaunchTask::appendStep(std::shared_ptr<LaunchStep> step)
{
- m_steps.append(step);
+ m_steps.append(step);
}
void LaunchTask::prependStep(std::shared_ptr<LaunchStep> step)
{
- m_steps.prepend(step);
+ m_steps.prepend(step);
}
void LaunchTask::executeTask()
{
- m_instance->setCrashed(false);
- if(!m_steps.size())
- {
- state = LaunchTask::Finished;
- emitSucceeded();
- }
- state = LaunchTask::Running;
- onStepFinished();
+ m_instance->setCrashed(false);
+ if(!m_steps.size())
+ {
+ state = LaunchTask::Finished;
+ emitSucceeded();
+ }
+ state = LaunchTask::Running;
+ onStepFinished();
}
void LaunchTask::onReadyForLaunch()
{
- state = LaunchTask::Waiting;
- emit readyForLaunch();
+ state = LaunchTask::Waiting;
+ emit readyForLaunch();
}
void LaunchTask::onStepFinished()
{
- // initial -> just start the first step
- if(currentStep == -1)
- {
- currentStep ++;
- m_steps[currentStep]->start();
- return;
- }
+ // initial -> just start the first step
+ if(currentStep == -1)
+ {
+ currentStep ++;
+ m_steps[currentStep]->start();
+ return;
+ }
- auto step = m_steps[currentStep];
- if(step->wasSuccessful())
- {
- // end?
- if(currentStep == m_steps.size() - 1)
- {
- finalizeSteps(true, QString());
- }
- else
- {
- currentStep ++;
- step = m_steps[currentStep];
- step->start();
- }
- }
- else
- {
- finalizeSteps(false, step->failReason());
- }
+ auto step = m_steps[currentStep];
+ if(step->wasSuccessful())
+ {
+ // end?
+ if(currentStep == m_steps.size() - 1)
+ {
+ finalizeSteps(true, QString());
+ }
+ else
+ {
+ currentStep ++;
+ step = m_steps[currentStep];
+ step->start();
+ }
+ }
+ else
+ {
+ finalizeSteps(false, step->failReason());
+ }
}
void LaunchTask::finalizeSteps(bool successful, const QString& error)
{
- for(auto step = currentStep; step >= 0; step--)
- {
- m_steps[step]->finalize();
- }
- if(successful)
- {
- emitSucceeded();
- }
- else
- {
- emitFailed(error);
- }
+ for(auto step = currentStep; step >= 0; step--)
+ {
+ m_steps[step]->finalize();
+ }
+ if(successful)
+ {
+ emitSucceeded();
+ }
+ else
+ {
+ emitFailed(error);
+ }
}
void LaunchTask::onProgressReportingRequested()
{
- state = LaunchTask::Waiting;
- emit requestProgress(m_steps[currentStep].get());
+ state = LaunchTask::Waiting;
+ emit requestProgress(m_steps[currentStep].get());
}
void LaunchTask::setCensorFilter(QMap<QString, QString> filter)
{
- m_censorFilter = filter;
+ m_censorFilter = filter;
}
QString LaunchTask::censorPrivateInfo(QString in)
{
- auto iter = m_censorFilter.begin();
- while (iter != m_censorFilter.end())
- {
- in.replace(iter.key(), iter.value());
- iter++;
- }
- return in;
+ auto iter = m_censorFilter.begin();
+ while (iter != m_censorFilter.end())
+ {
+ in.replace(iter.key(), iter.value());
+ iter++;
+ }
+ return in;
}
void LaunchTask::proceed()
{
- if(state != LaunchTask::Waiting)
- {
- return;
- }
- m_steps[currentStep]->proceed();
+ if(state != LaunchTask::Waiting)
+ {
+ return;
+ }
+ m_steps[currentStep]->proceed();
}
bool LaunchTask::canAbort() const
{
- switch(state)
- {
- case LaunchTask::Aborted:
- case LaunchTask::Failed:
- case LaunchTask::Finished:
- return false;
- case LaunchTask::NotStarted:
- return true;
- case LaunchTask::Running:
- case LaunchTask::Waiting:
- {
- auto step = m_steps[currentStep];
- return step->canAbort();
- }
- }
- return false;
+ switch(state)
+ {
+ case LaunchTask::Aborted:
+ case LaunchTask::Failed:
+ case LaunchTask::Finished:
+ return false;
+ case LaunchTask::NotStarted:
+ return true;
+ case LaunchTask::Running:
+ case LaunchTask::Waiting:
+ {
+ auto step = m_steps[currentStep];
+ return step->canAbort();
+ }
+ }
+ return false;
}
bool LaunchTask::abort()
{
- switch(state)
- {
- case LaunchTask::Aborted:
- case LaunchTask::Failed:
- case LaunchTask::Finished:
- return true;
- case LaunchTask::NotStarted:
- {
- state = LaunchTask::Aborted;
- emitFailed("Aborted");
- return true;
- }
- case LaunchTask::Running:
- case LaunchTask::Waiting:
- {
- auto step = m_steps[currentStep];
- if(!step->canAbort())
- {
- return false;
- }
- if(step->abort())
- {
- state = LaunchTask::Aborted;
- return true;
- }
- }
- default:
- break;
- }
- return false;
+ switch(state)
+ {
+ case LaunchTask::Aborted:
+ case LaunchTask::Failed:
+ case LaunchTask::Finished:
+ return true;
+ case LaunchTask::NotStarted:
+ {
+ state = LaunchTask::Aborted;
+ emitFailed("Aborted");
+ return true;
+ }
+ case LaunchTask::Running:
+ case LaunchTask::Waiting:
+ {
+ auto step = m_steps[currentStep];
+ if(!step->canAbort())
+ {
+ return false;
+ }
+ if(step->abort())
+ {
+ state = LaunchTask::Aborted;
+ return true;
+ }
+ }
+ default:
+ break;
+ }
+ return false;
}
shared_qobject_ptr<LogModel> LaunchTask::getLogModel()
{
- if(!m_logModel)
- {
- m_logModel.reset(new LogModel());
- m_logModel->setMaxLines(m_instance->getConsoleMaxLines());
- m_logModel->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow());
- // FIXME: should this really be here?
- m_logModel->setOverflowMessage(tr("MultiMC stopped watching the game log because the log length surpassed %1 lines.\n"
- "You may have to fix your mods because the game is still logging to files and"
- " likely wasting harddrive space at an alarming rate!").arg(m_logModel->getMaxLines()));
- }
- return m_logModel;
+ if(!m_logModel)
+ {
+ m_logModel.reset(new LogModel());
+ m_logModel->setMaxLines(m_instance->getConsoleMaxLines());
+ m_logModel->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow());
+ // FIXME: should this really be here?
+ m_logModel->setOverflowMessage(tr("MultiMC stopped watching the game log because the log length surpassed %1 lines.\n"
+ "You may have to fix your mods because the game is still logging to files and"
+ " likely wasting harddrive space at an alarming rate!").arg(m_logModel->getMaxLines()));
+ }
+ return m_logModel;
}
void LaunchTask::onLogLines(const QStringList &lines, MessageLevel::Enum defaultLevel)
{
- for (auto & line: lines)
- {
- onLogLine(line, defaultLevel);
- }
+ for (auto & line: lines)
+ {
+ onLogLine(line, defaultLevel);
+ }
}
void LaunchTask::onLogLine(QString line, MessageLevel::Enum level)
{
- // if the launcher part set a log level, use it
- auto innerLevel = MessageLevel::fromLine(line);
- if(innerLevel != MessageLevel::Unknown)
- {
- level = innerLevel;
- }
+ // if the launcher part set a log level, use it
+ auto innerLevel = MessageLevel::fromLine(line);
+ if(innerLevel != MessageLevel::Unknown)
+ {
+ level = innerLevel;
+ }
- // If the level is still undetermined, guess level
- if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown)
- {
- level = m_instance->guessLevel(line, level);
- }
+ // If the level is still undetermined, guess level
+ if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown)
+ {
+ level = m_instance->guessLevel(line, level);
+ }
- // censor private user info
- line = censorPrivateInfo(line);
+ // censor private user info
+ line = censorPrivateInfo(line);
- auto &model = *getLogModel();
- model.append(level, line);
+ auto &model = *getLogModel();
+ model.append(level, line);
}
void LaunchTask::emitSucceeded()
{
- m_instance->setRunning(false);
- Task::emitSucceeded();
+ m_instance->setRunning(false);
+ Task::emitSucceeded();
}
void LaunchTask::emitFailed(QString reason)
{
- m_instance->setRunning(false);
- m_instance->setCrashed(true);
- Task::emitFailed(reason);
+ m_instance->setRunning(false);
+ m_instance->setCrashed(true);
+ Task::emitFailed(reason);
}
QString LaunchTask::substituteVariables(const QString &cmd) const
{
- QString out = cmd;
- auto variables = m_instance->getVariables();
- for (auto it = variables.begin(); it != variables.end(); ++it)
- {
- out.replace("$" + it.key(), it.value());
- }
- auto env = QProcessEnvironment::systemEnvironment();
- for (auto var : env.keys())
- {
- out.replace("$" + var, env.value(var));
- }
- return out;
+ QString out = cmd;
+ auto variables = m_instance->getVariables();
+ for (auto it = variables.begin(); it != variables.end(); ++it)
+ {
+ out.replace("$" + it.key(), it.value());
+ }
+ auto env = QProcessEnvironment::systemEnvironment();
+ for (auto var : env.keys())
+ {
+ out.replace("$" + var, env.value(var));
+ }
+ return out;
}
diff --git a/api/logic/launch/LaunchTask.h b/api/logic/launch/LaunchTask.h
index 746d6d19..f5e226b5 100644
--- a/api/logic/launch/LaunchTask.h
+++ b/api/logic/launch/LaunchTask.h
@@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -28,98 +28,98 @@
class MULTIMC_LOGIC_EXPORT LaunchTask: public Task
{
- Q_OBJECT
+ Q_OBJECT
protected:
- explicit LaunchTask(InstancePtr instance);
- void init();
+ explicit LaunchTask(InstancePtr instance);
+ void init();
public:
- enum State
- {
- NotStarted,
- Running,
- Waiting,
- Failed,
- Aborted,
- Finished
- };
+ enum State
+ {
+ NotStarted,
+ Running,
+ Waiting,
+ Failed,
+ Aborted,
+ Finished
+ };
public: /* methods */
- static std::shared_ptr<LaunchTask> create(InstancePtr inst);
- virtual ~LaunchTask() {};
+ static std::shared_ptr<LaunchTask> create(InstancePtr inst);
+ virtual ~LaunchTask() {};
- void appendStep(std::shared_ptr<LaunchStep> step);
- void prependStep(std::shared_ptr<LaunchStep> step);
- void setCensorFilter(QMap<QString, QString> filter);
+ void appendStep(std::shared_ptr<LaunchStep> step);
+ void prependStep(std::shared_ptr<LaunchStep> step);
+ void setCensorFilter(QMap<QString, QString> filter);
- InstancePtr instance()
- {
- return m_instance;
- }
+ InstancePtr instance()
+ {
+ return m_instance;
+ }
- void setPid(qint64 pid)
- {
- m_pid = pid;
- }
+ void setPid(qint64 pid)
+ {
+ m_pid = pid;
+ }
- qint64 pid()
- {
- return m_pid;
- }
+ qint64 pid()
+ {
+ return m_pid;
+ }
- /**
- * @brief prepare the process for launch (for multi-stage launch)
- */
- virtual void executeTask() override;
+ /**
+ * @brief prepare the process for launch (for multi-stage launch)
+ */
+ virtual void executeTask() override;
- /**
- * @brief launch the armed instance
- */
- void proceed();
+ /**
+ * @brief launch the armed instance
+ */
+ void proceed();
- /**
- * @brief abort launch
- */
- bool abort() override;
+ /**
+ * @brief abort launch
+ */
+ bool abort() override;
- bool canAbort() const override;
+ bool canAbort() const override;
- shared_qobject_ptr<LogModel> getLogModel();
+ shared_qobject_ptr<LogModel> getLogModel();
public:
- QString substituteVariables(const QString &cmd) const;
- QString censorPrivateInfo(QString in);
+ QString substituteVariables(const QString &cmd) const;
+ QString censorPrivateInfo(QString in);
protected: /* methods */
- virtual void emitFailed(QString reason) override;
- virtual void emitSucceeded() override;
+ virtual void emitFailed(QString reason) override;
+ virtual void emitSucceeded() override;
signals:
- /**
- * @brief emitted when the launch preparations are done
- */
- void readyForLaunch();
+ /**
+ * @brief emitted when the launch preparations are done
+ */
+ void readyForLaunch();
- void requestProgress(Task *task);
+ void requestProgress(Task *task);
- void requestLogging();
+ void requestLogging();
public slots:
- void onLogLines(const QStringList& lines, MessageLevel::Enum defaultLevel = MessageLevel::MultiMC);
- void onLogLine(QString line, MessageLevel::Enum defaultLevel = MessageLevel::MultiMC);
- void onReadyForLaunch();
- void onStepFinished();
- void onProgressReportingRequested();
+ void onLogLines(const QStringList& lines, MessageLevel::Enum defaultLevel = MessageLevel::MultiMC);
+ void onLogLine(QString line, MessageLevel::Enum defaultLevel = MessageLevel::MultiMC);
+ void onReadyForLaunch();
+ void onStepFinished();
+ void onProgressReportingRequested();
private: /*methods */
- void finalizeSteps(bool successful, const QString & error);
+ void finalizeSteps(bool successful, const QString & error);
protected: /* data */
- InstancePtr m_instance;
- shared_qobject_ptr<LogModel> m_logModel;
- QList <std::shared_ptr<LaunchStep>> m_steps;
- QMap<QString, QString> m_censorFilter;
- int currentStep = -1;
- State state = NotStarted;
- qint64 m_pid = -1;
+ InstancePtr m_instance;
+ shared_qobject_ptr<LogModel> m_logModel;
+ QList <std::shared_ptr<LaunchStep>> m_steps;
+ QMap<QString, QString> m_censorFilter;
+ int currentStep = -1;
+ State state = NotStarted;
+ qint64 m_pid = -1;
};
diff --git a/api/logic/launch/LogModel.cpp b/api/logic/launch/LogModel.cpp
index 72b076e9..92f9487a 100644
--- a/api/logic/launch/LogModel.cpp
+++ b/api/logic/launch/LogModel.cpp
@@ -2,166 +2,166 @@
LogModel::LogModel(QObject *parent):QAbstractListModel(parent)
{
- m_content.resize(m_maxLines);
+ m_content.resize(m_maxLines);
}
int LogModel::rowCount(const QModelIndex &parent) const
{
- if (parent.isValid())
- return 0;
+ if (parent.isValid())
+ return 0;
- return m_numLines;
+ return m_numLines;
}
QVariant LogModel::data(const QModelIndex &index, int role) const
{
- if (index.row() < 0 || index.row() >= m_numLines)
- return QVariant();
-
- auto row = index.row();
- auto realRow = (row + m_firstLine) % m_maxLines;
- if (role == Qt::DisplayRole || role == Qt::EditRole)
- {
- return m_content[realRow].line;
- }
- if(role == LevelRole)
- {
- return m_content[realRow].level;
- }
-
- return QVariant();
+ if (index.row() < 0 || index.row() >= m_numLines)
+ return QVariant();
+
+ auto row = index.row();
+ auto realRow = (row + m_firstLine) % m_maxLines;
+ if (role == Qt::DisplayRole || role == Qt::EditRole)
+ {
+ return m_content[realRow].line;
+ }
+ if(role == LevelRole)
+ {
+ return m_content[realRow].level;
+ }
+
+ return QVariant();
}
void LogModel::append(MessageLevel::Enum level, QString line)
{
- if(m_suspended)
- {
- return;
- }
- int lineNum = (m_firstLine + m_numLines) % m_maxLines;
- // overflow
- if(m_numLines == m_maxLines)
- {
- if(m_stopOnOverflow)
- {
- // nothing more to do, the buffer is full
- return;
- }
- beginRemoveRows(QModelIndex(), 0, 0);
- m_firstLine = (m_firstLine + 1) % m_maxLines;
- m_numLines --;
- endRemoveRows();
- }
- else if (m_numLines == m_maxLines - 1 && m_stopOnOverflow)
- {
- level = MessageLevel::Fatal;
- line = m_overflowMessage;
- }
- beginInsertRows(QModelIndex(), m_numLines, m_numLines);
- m_numLines ++;
- m_content[lineNum].level = level;
- m_content[lineNum].line = line;
- endInsertRows();
+ if(m_suspended)
+ {
+ return;
+ }
+ int lineNum = (m_firstLine + m_numLines) % m_maxLines;
+ // overflow
+ if(m_numLines == m_maxLines)
+ {
+ if(m_stopOnOverflow)
+ {
+ // nothing more to do, the buffer is full
+ return;
+ }
+ beginRemoveRows(QModelIndex(), 0, 0);
+ m_firstLine = (m_firstLine + 1) % m_maxLines;
+ m_numLines --;
+ endRemoveRows();
+ }
+ else if (m_numLines == m_maxLines - 1 && m_stopOnOverflow)
+ {
+ level = MessageLevel::Fatal;
+ line = m_overflowMessage;
+ }
+ beginInsertRows(QModelIndex(), m_numLines, m_numLines);
+ m_numLines ++;
+ m_content[lineNum].level = level;
+ m_content[lineNum].line = line;
+ endInsertRows();
}
void LogModel::suspend(bool suspend)
{
- m_suspended = suspend;
+ m_suspended = suspend;
}
bool LogModel::suspended()
{
- return m_suspended;
+ return m_suspended;
}
void LogModel::clear()
{
- beginResetModel();
- m_firstLine = 0;
- m_numLines = 0;
- endResetModel();
+ beginResetModel();
+ m_firstLine = 0;
+ m_numLines = 0;
+ endResetModel();
}
QString LogModel::toPlainText()
{
- QString out;
- out.reserve(m_numLines * 80);
- for(int i = 0; i < m_numLines; i++)
- {
- QString & line = m_content[(m_firstLine + i) % m_maxLines].line;
- out.append(line + '\n');
- }
- out.squeeze();
- return out;
+ QString out;
+ out.reserve(m_numLines * 80);
+ for(int i = 0; i < m_numLines; i++)
+ {
+ QString & line = m_content[(m_firstLine + i) % m_maxLines].line;
+ out.append(line + '\n');
+ }
+ out.squeeze();
+ return out;
}
void LogModel::setMaxLines(int maxLines)
{
- // no-op
- if(maxLines == m_maxLines)
- {
- return;
- }
- // if it all still fits in the buffer, just resize it
- if(m_firstLine + m_numLines < m_maxLines)
- {
- m_maxLines = maxLines;
- m_content.resize(maxLines);
- return;
- }
- // otherwise, we need to reorganize the data because it crosses the wrap boundary
- QVector<entry> newContent;
- newContent.resize(maxLines);
- if(m_numLines <= maxLines)
- {
- // if it all fits in the new buffer, just copy it over
- for(int i = 0; i < m_numLines; i++)
- {
- newContent[i] = m_content[(m_firstLine + i) % m_maxLines];
- }
- m_content.swap(newContent);
- }
- else
- {
- // if it doesn't fit, part of the data needs to be thrown away (the oldest log messages)
- int lead = m_numLines - maxLines;
- beginRemoveRows(QModelIndex(), 0, lead - 1);
- for(int i = 0; i < maxLines; i++)
- {
- newContent[i] = m_content[(m_firstLine + lead + i) % m_maxLines];
- }
- m_numLines = m_maxLines;
- m_content.swap(newContent);
- endRemoveRows();
- }
- m_firstLine = 0;
- m_maxLines = maxLines;
+ // no-op
+ if(maxLines == m_maxLines)
+ {
+ return;
+ }
+ // if it all still fits in the buffer, just resize it
+ if(m_firstLine + m_numLines < m_maxLines)
+ {
+ m_maxLines = maxLines;
+ m_content.resize(maxLines);
+ return;
+ }
+ // otherwise, we need to reorganize the data because it crosses the wrap boundary
+ QVector<entry> newContent;
+ newContent.resize(maxLines);
+ if(m_numLines <= maxLines)
+ {
+ // if it all fits in the new buffer, just copy it over
+ for(int i = 0; i < m_numLines; i++)
+ {
+ newContent[i] = m_content[(m_firstLine + i) % m_maxLines];
+ }
+ m_content.swap(newContent);
+ }
+ else
+ {
+ // if it doesn't fit, part of the data needs to be thrown away (the oldest log messages)
+ int lead = m_numLines - maxLines;
+ beginRemoveRows(QModelIndex(), 0, lead - 1);
+ for(int i = 0; i < maxLines; i++)
+ {
+ newContent[i] = m_content[(m_firstLine + lead + i) % m_maxLines];
+ }
+ m_numLines = m_maxLines;
+ m_content.swap(newContent);
+ endRemoveRows();
+ }
+ m_firstLine = 0;
+ m_maxLines = maxLines;
}
int LogModel::getMaxLines()
{
- return m_maxLines;
+ return m_maxLines;
}
void LogModel::setStopOnOverflow(bool stop)
{
- m_stopOnOverflow = stop;
+ m_stopOnOverflow = stop;
}
void LogModel::setOverflowMessage(const QString& overflowMessage)
{
- m_overflowMessage = overflowMessage;
+ m_overflowMessage = overflowMessage;
}
void LogModel::setLineWrap(bool state)
{
- if(m_lineWrap != state)
- {
- m_lineWrap = state;
- }
+ if(m_lineWrap != state)
+ {
+ m_lineWrap = state;
+ }
}
bool LogModel::wrapLines() const
{
- return m_lineWrap;
+ return m_lineWrap;
}
diff --git a/api/logic/launch/LogModel.h b/api/logic/launch/LogModel.h
index e6deac89..bccceaef 100644
--- a/api/logic/launch/LogModel.h
+++ b/api/logic/launch/LogModel.h
@@ -8,53 +8,53 @@
class MULTIMC_LOGIC_EXPORT LogModel : public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit LogModel(QObject *parent = 0);
+ explicit LogModel(QObject *parent = 0);
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role) const;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role) const;
- void append(MessageLevel::Enum, QString line);
- void clear();
+ void append(MessageLevel::Enum, QString line);
+ void clear();
- void suspend(bool suspend);
- bool suspended();
+ void suspend(bool suspend);
+ bool suspended();
- QString toPlainText();
+ QString toPlainText();
- int getMaxLines();
- void setMaxLines(int maxLines);
- void setStopOnOverflow(bool stop);
- void setOverflowMessage(const QString & overflowMessage);
+ int getMaxLines();
+ void setMaxLines(int maxLines);
+ void setStopOnOverflow(bool stop);
+ void setOverflowMessage(const QString & overflowMessage);
- void setLineWrap(bool state);
- bool wrapLines() const;
+ void setLineWrap(bool state);
+ bool wrapLines() const;
- enum Roles
- {
- LevelRole = Qt::UserRole
- };
+ enum Roles
+ {
+ LevelRole = Qt::UserRole
+ };
private /* types */:
- struct entry
- {
- MessageLevel::Enum level;
- QString line;
- };
+ struct entry
+ {
+ MessageLevel::Enum level;
+ QString line;
+ };
private: /* data */
- QVector <entry> m_content;
- int m_maxLines = 1000;
- // first line in the circular buffer
- int m_firstLine = 0;
- // number of lines occupied in the circular buffer
- int m_numLines = 0;
- bool m_stopOnOverflow = false;
- QString m_overflowMessage = "OVERFLOW";
- bool m_suspended = false;
- bool m_lineWrap = true;
+ QVector <entry> m_content;
+ int m_maxLines = 1000;
+ // first line in the circular buffer
+ int m_firstLine = 0;
+ // number of lines occupied in the circular buffer
+ int m_numLines = 0;
+ bool m_stopOnOverflow = false;
+ QString m_overflowMessage = "OVERFLOW";
+ bool m_suspended = false;
+ bool m_lineWrap = true;
private:
- Q_DISABLE_COPY(LogModel)
+ Q_DISABLE_COPY(LogModel)
};
diff --git a/api/logic/launch/steps/PostLaunchCommand.cpp b/api/logic/launch/steps/PostLaunchCommand.cpp
index bc3b3ffe..3730f71c 100644
--- a/api/logic/launch/steps/PostLaunchCommand.cpp
+++ b/api/logic/launch/steps/PostLaunchCommand.cpp
@@ -18,67 +18,67 @@
PostLaunchCommand::PostLaunchCommand(LaunchTask *parent) : LaunchStep(parent)
{
- auto instance = m_parent->instance();
- m_command = instance->getPostExitCommand();
- m_process.setProcessEnvironment(instance->createEnvironment());
- connect(&m_process, &LoggedProcess::log, this, &PostLaunchCommand::logLines);
- connect(&m_process, &LoggedProcess::stateChanged, this, &PostLaunchCommand::on_state);
+ auto instance = m_parent->instance();
+ m_command = instance->getPostExitCommand();
+ m_process.setProcessEnvironment(instance->createEnvironment());
+ connect(&m_process, &LoggedProcess::log, this, &PostLaunchCommand::logLines);
+ connect(&m_process, &LoggedProcess::stateChanged, this, &PostLaunchCommand::on_state);
}
void PostLaunchCommand::executeTask()
{
- QString postlaunch_cmd = m_parent->substituteVariables(m_command);
- emit logLine(tr("Running Post-Launch command: %1").arg(postlaunch_cmd), MessageLevel::MultiMC);
- m_process.start(postlaunch_cmd);
+ QString postlaunch_cmd = m_parent->substituteVariables(m_command);
+ emit logLine(tr("Running Post-Launch command: %1").arg(postlaunch_cmd), MessageLevel::MultiMC);
+ m_process.start(postlaunch_cmd);
}
void PostLaunchCommand::on_state(LoggedProcess::State state)
{
- auto getError = [&]()
- {
- return tr("Post-Launch command failed with code %1.\n\n").arg(m_process.exitCode());
- };
- switch(state)
- {
- case LoggedProcess::Aborted:
- case LoggedProcess::Crashed:
- case LoggedProcess::FailedToStart:
- {
- auto error = getError();
- emit logLine(error, MessageLevel::Fatal);
- emitFailed(error);
- return;
- }
- case LoggedProcess::Finished:
- {
- if(m_process.exitCode() != 0)
- {
- auto error = getError();
- emit logLine(error, MessageLevel::Fatal);
- emitFailed(error);
- }
- else
- {
- emit logLine(tr("Post-Launch command ran successfully.\n\n"), MessageLevel::MultiMC);
- emitSucceeded();
- }
- }
- default:
- break;
- }
+ auto getError = [&]()
+ {
+ return tr("Post-Launch command failed with code %1.\n\n").arg(m_process.exitCode());
+ };
+ switch(state)
+ {
+ case LoggedProcess::Aborted:
+ case LoggedProcess::Crashed:
+ case LoggedProcess::FailedToStart:
+ {
+ auto error = getError();
+ emit logLine(error, MessageLevel::Fatal);
+ emitFailed(error);
+ return;
+ }
+ case LoggedProcess::Finished:
+ {
+ if(m_process.exitCode() != 0)
+ {
+ auto error = getError();
+ emit logLine(error, MessageLevel::Fatal);
+ emitFailed(error);
+ }
+ else
+ {
+ emit logLine(tr("Post-Launch command ran successfully.\n\n"), MessageLevel::MultiMC);
+ emitSucceeded();
+ }
+ }
+ default:
+ break;
+ }
}
void PostLaunchCommand::setWorkingDirectory(const QString &wd)
{
- m_process.setWorkingDirectory(wd);
+ m_process.setWorkingDirectory(wd);
}
bool PostLaunchCommand::abort()
{
- auto state = m_process.state();
- if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
- {
- m_process.kill();
- }
- return true;
+ auto state = m_process.state();
+ if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
+ {
+ m_process.kill();
+ }
+ return true;
}
diff --git a/api/logic/launch/steps/PostLaunchCommand.h b/api/logic/launch/steps/PostLaunchCommand.h
index 88681cbc..efba62d9 100644
--- a/api/logic/launch/steps/PostLaunchCommand.h
+++ b/api/logic/launch/steps/PostLaunchCommand.h
@@ -20,22 +20,22 @@
class PostLaunchCommand: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit PostLaunchCommand(LaunchTask *parent);
- virtual ~PostLaunchCommand() {};
+ explicit PostLaunchCommand(LaunchTask *parent);
+ virtual ~PostLaunchCommand() {};
- virtual void executeTask();
- virtual bool abort();
- virtual bool canAbort() const
- {
- return true;
- }
- void setWorkingDirectory(const QString &wd);
+ virtual void executeTask();
+ virtual bool abort();
+ virtual bool canAbort() const
+ {
+ return true;
+ }
+ void setWorkingDirectory(const QString &wd);
private slots:
- void on_state(LoggedProcess::State state);
+ void on_state(LoggedProcess::State state);
private:
- LoggedProcess m_process;
- QString m_command;
+ LoggedProcess m_process;
+ QString m_command;
};
diff --git a/api/logic/launch/steps/PreLaunchCommand.cpp b/api/logic/launch/steps/PreLaunchCommand.cpp
index 7c37d5cb..c5e1e373 100644
--- a/api/logic/launch/steps/PreLaunchCommand.cpp
+++ b/api/logic/launch/steps/PreLaunchCommand.cpp
@@ -18,68 +18,68 @@
PreLaunchCommand::PreLaunchCommand(LaunchTask *parent) : LaunchStep(parent)
{
- auto instance = m_parent->instance();
- m_command = instance->getPreLaunchCommand();
- m_process.setProcessEnvironment(instance->createEnvironment());
- connect(&m_process, &LoggedProcess::log, this, &PreLaunchCommand::logLines);
- connect(&m_process, &LoggedProcess::stateChanged, this, &PreLaunchCommand::on_state);
+ auto instance = m_parent->instance();
+ m_command = instance->getPreLaunchCommand();
+ m_process.setProcessEnvironment(instance->createEnvironment());
+ connect(&m_process, &LoggedProcess::log, this, &PreLaunchCommand::logLines);
+ connect(&m_process, &LoggedProcess::stateChanged, this, &PreLaunchCommand::on_state);
}
void PreLaunchCommand::executeTask()
{
- //FIXME: where to put this?
- QString prelaunch_cmd = m_parent->substituteVariables(m_command);
- emit logLine(tr("Running Pre-Launch command: %1").arg(prelaunch_cmd), MessageLevel::MultiMC);
- m_process.start(prelaunch_cmd);
+ //FIXME: where to put this?
+ QString prelaunch_cmd = m_parent->substituteVariables(m_command);
+ emit logLine(tr("Running Pre-Launch command: %1").arg(prelaunch_cmd), MessageLevel::MultiMC);
+ m_process.start(prelaunch_cmd);
}
void PreLaunchCommand::on_state(LoggedProcess::State state)
{
- auto getError = [&]()
- {
- return tr("Pre-Launch command failed with code %1.\n\n").arg(m_process.exitCode());
- };
- switch(state)
- {
- case LoggedProcess::Aborted:
- case LoggedProcess::Crashed:
- case LoggedProcess::FailedToStart:
- {
- auto error = getError();
- emit logLine(error, MessageLevel::Fatal);
- emitFailed(error);
- return;
- }
- case LoggedProcess::Finished:
- {
- if(m_process.exitCode() != 0)
- {
- auto error = getError();
- emit logLine(error, MessageLevel::Fatal);
- emitFailed(error);
- }
- else
- {
- emit logLine(tr("Pre-Launch command ran successfully.\n\n"), MessageLevel::MultiMC);
- emitSucceeded();
- }
- }
- default:
- break;
- }
+ auto getError = [&]()
+ {
+ return tr("Pre-Launch command failed with code %1.\n\n").arg(m_process.exitCode());
+ };
+ switch(state)
+ {
+ case LoggedProcess::Aborted:
+ case LoggedProcess::Crashed:
+ case LoggedProcess::FailedToStart:
+ {
+ auto error = getError();
+ emit logLine(error, MessageLevel::Fatal);
+ emitFailed(error);
+ return;
+ }
+ case LoggedProcess::Finished:
+ {
+ if(m_process.exitCode() != 0)
+ {
+ auto error = getError();
+ emit logLine(error, MessageLevel::Fatal);
+ emitFailed(error);
+ }
+ else
+ {
+ emit logLine(tr("Pre-Launch command ran successfully.\n\n"), MessageLevel::MultiMC);
+ emitSucceeded();
+ }
+ }
+ default:
+ break;
+ }
}
void PreLaunchCommand::setWorkingDirectory(const QString &wd)
{
- m_process.setWorkingDirectory(wd);
+ m_process.setWorkingDirectory(wd);
}
bool PreLaunchCommand::abort()
{
- auto state = m_process.state();
- if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
- {
- m_process.kill();
- }
- return true;
+ auto state = m_process.state();
+ if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
+ {
+ m_process.kill();
+ }
+ return true;
}
diff --git a/api/logic/launch/steps/PreLaunchCommand.h b/api/logic/launch/steps/PreLaunchCommand.h
index 5c955923..861e5be7 100644
--- a/api/logic/launch/steps/PreLaunchCommand.h
+++ b/api/logic/launch/steps/PreLaunchCommand.h
@@ -20,22 +20,22 @@
class PreLaunchCommand: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit PreLaunchCommand(LaunchTask *parent);
- virtual ~PreLaunchCommand() {};
+ explicit PreLaunchCommand(LaunchTask *parent);
+ virtual ~PreLaunchCommand() {};
- virtual void executeTask();
- virtual bool abort();
- virtual bool canAbort() const
- {
- return true;
- }
- void setWorkingDirectory(const QString &wd);
+ virtual void executeTask();
+ virtual bool abort();
+ virtual bool canAbort() const
+ {
+ return true;
+ }
+ void setWorkingDirectory(const QString &wd);
private slots:
- void on_state(LoggedProcess::State state);
+ void on_state(LoggedProcess::State state);
private:
- LoggedProcess m_process;
- QString m_command;
+ LoggedProcess m_process;
+ QString m_command;
};
diff --git a/api/logic/launch/steps/TextPrint.cpp b/api/logic/launch/steps/TextPrint.cpp
index f307b1fd..0c1f320c 100644
--- a/api/logic/launch/steps/TextPrint.cpp
+++ b/api/logic/launch/steps/TextPrint.cpp
@@ -2,28 +2,28 @@
TextPrint::TextPrint(LaunchTask * parent, const QStringList &lines, MessageLevel::Enum level) : LaunchStep(parent)
{
- m_lines = lines;
- m_level = level;
+ m_lines = lines;
+ m_level = level;
}
TextPrint::TextPrint(LaunchTask *parent, const QString &line, MessageLevel::Enum level) : LaunchStep(parent)
{
- m_lines.append(line);
- m_level = level;
+ m_lines.append(line);
+ m_level = level;
}
void TextPrint::executeTask()
{
- emit logLines(m_lines, m_level);
- emitSucceeded();
+ emit logLines(m_lines, m_level);
+ emitSucceeded();
}
bool TextPrint::canAbort() const
{
- return true;
+ return true;
}
bool TextPrint::abort()
{
- emitFailed("Aborted.");
- return true;
+ emitFailed("Aborted.");
+ return true;
}
diff --git a/api/logic/launch/steps/TextPrint.h b/api/logic/launch/steps/TextPrint.h
index 3e3e06cb..48b8cf6f 100644
--- a/api/logic/launch/steps/TextPrint.h
+++ b/api/logic/launch/steps/TextPrint.h
@@ -27,17 +27,17 @@
class MULTIMC_LOGIC_EXPORT TextPrint: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit TextPrint(LaunchTask *parent, const QStringList &lines, MessageLevel::Enum level);
- explicit TextPrint(LaunchTask *parent, const QString &line, MessageLevel::Enum level);
- virtual ~TextPrint(){};
+ explicit TextPrint(LaunchTask *parent, const QStringList &lines, MessageLevel::Enum level);
+ explicit TextPrint(LaunchTask *parent, const QString &line, MessageLevel::Enum level);
+ virtual ~TextPrint(){};
- virtual void executeTask();
- virtual bool canAbort() const;
- virtual bool abort();
+ virtual void executeTask();
+ virtual bool canAbort() const;
+ virtual bool abort();
private:
- QStringList m_lines;
- MessageLevel::Enum m_level;
+ QStringList m_lines;
+ MessageLevel::Enum m_level;
};
diff --git a/api/logic/launch/steps/Update.cpp b/api/logic/launch/steps/Update.cpp
index d057febb..65f24391 100644
--- a/api/logic/launch/steps/Update.cpp
+++ b/api/logic/launch/steps/Update.cpp
@@ -18,63 +18,63 @@
void Update::executeTask()
{
- if(m_aborted)
- {
- emitFailed(tr("Task aborted."));
- return;
- }
- m_updateTask.reset(m_parent->instance()->createUpdateTask(m_mode));
- if(m_updateTask)
- {
- connect(m_updateTask.get(), SIGNAL(finished()), this, SLOT(updateFinished()));
- connect(m_updateTask.get(), &Task::progress, this, &Task::setProgress);
- connect(m_updateTask.get(), &Task::status, this, &Task::setStatus);
- emit progressReportingRequest();
- return;
- }
- emitSucceeded();
+ if(m_aborted)
+ {
+ emitFailed(tr("Task aborted."));
+ return;
+ }
+ m_updateTask.reset(m_parent->instance()->createUpdateTask(m_mode));
+ if(m_updateTask)
+ {
+ connect(m_updateTask.get(), SIGNAL(finished()), this, SLOT(updateFinished()));
+ connect(m_updateTask.get(), &Task::progress, this, &Task::setProgress);
+ connect(m_updateTask.get(), &Task::status, this, &Task::setStatus);
+ emit progressReportingRequest();
+ return;
+ }
+ emitSucceeded();
}
void Update::proceed()
{
- m_updateTask->start();
+ m_updateTask->start();
}
void Update::updateFinished()
{
- if(m_updateTask->wasSuccessful())
- {
- m_updateTask.reset();
- emitSucceeded();
- }
- else
- {
- QString reason = tr("Instance update failed because: %1.\n\n").arg(m_updateTask->failReason());
- m_updateTask.reset();
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- }
+ if(m_updateTask->wasSuccessful())
+ {
+ m_updateTask.reset();
+ emitSucceeded();
+ }
+ else
+ {
+ QString reason = tr("Instance update failed because: %1.\n\n").arg(m_updateTask->failReason());
+ m_updateTask.reset();
+ emit logLine(reason, MessageLevel::Fatal);
+ emitFailed(reason);
+ }
}
bool Update::canAbort() const
{
- if(m_updateTask)
- {
- return m_updateTask->canAbort();
- }
- return true;
+ if(m_updateTask)
+ {
+ return m_updateTask->canAbort();
+ }
+ return true;
}
bool Update::abort()
{
- m_aborted = true;
- if(m_updateTask)
- {
- if(m_updateTask->canAbort())
- {
- return m_updateTask->abort();
- }
- }
- return true;
+ m_aborted = true;
+ if(m_updateTask)
+ {
+ if(m_updateTask->canAbort())
+ {
+ return m_updateTask->abort();
+ }
+ }
+ return true;
}
diff --git a/api/logic/launch/steps/Update.h b/api/logic/launch/steps/Update.h
index 7a14011a..baa0b80e 100644
--- a/api/logic/launch/steps/Update.h
+++ b/api/logic/launch/steps/Update.h
@@ -24,22 +24,22 @@
// FIXME: stupid. should be defined by the instance type? or even completely abstracted away...
class Update: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit Update(LaunchTask *parent, Net::Mode mode):LaunchStep(parent), m_mode(mode) {};
- virtual ~Update() {};
+ explicit Update(LaunchTask *parent, Net::Mode mode):LaunchStep(parent), m_mode(mode) {};
+ virtual ~Update() {};
- void executeTask() override;
- bool canAbort() const override;
- void proceed() override;
+ void executeTask() override;
+ bool canAbort() const override;
+ void proceed() override;
public slots:
- bool abort() override;
+ bool abort() override;
private slots:
- void updateFinished();
+ void updateFinished();
private:
- shared_qobject_ptr<Task> m_updateTask;
- bool m_aborted = false;
- Net::Mode m_mode = Net::Mode::Offline;
+ shared_qobject_ptr<Task> m_updateTask;
+ bool m_aborted = false;
+ Net::Mode m_mode = Net::Mode::Offline;
};
diff --git a/api/logic/meta/BaseEntity.cpp b/api/logic/meta/BaseEntity.cpp
index 342f676c..9ea712fa 100644
--- a/api/logic/meta/BaseEntity.cpp
+++ b/api/logic/meta/BaseEntity.cpp
@@ -27,45 +27,45 @@
class ParsingValidator : public Net::Validator
{
public: /* con/des */
- ParsingValidator(Meta::BaseEntity *entity) : m_entity(entity)
- {
- };
- virtual ~ParsingValidator()
- {
- };
+ ParsingValidator(Meta::BaseEntity *entity) : m_entity(entity)
+ {
+ };
+ virtual ~ParsingValidator()
+ {
+ };
public: /* methods */
- bool init(QNetworkRequest &) override
- {
- return true;
- }
- bool write(QByteArray & data) override
- {
- this->data.append(data);
- return true;
- }
- bool abort() override
- {
- return true;
- }
- bool validate(QNetworkReply &) override
- {
- auto fname = m_entity->localFilename();
- try
- {
- m_entity->parse(Json::requireObject(Json::requireDocument(data, fname), fname));
- return true;
- }
- catch (const Exception &e)
- {
- qWarning() << "Unable to parse response:" << e.cause();
- return false;
- }
- }
+ bool init(QNetworkRequest &) override
+ {
+ return true;
+ }
+ bool write(QByteArray & data) override
+ {
+ this->data.append(data);
+ return true;
+ }
+ bool abort() override
+ {
+ return true;
+ }
+ bool validate(QNetworkReply &) override
+ {
+ auto fname = m_entity->localFilename();
+ try
+ {
+ m_entity->parse(Json::requireObject(Json::requireDocument(data, fname), fname));
+ return true;
+ }
+ catch (const Exception &e)
+ {
+ qWarning() << "Unable to parse response:" << e.cause();
+ return false;
+ }
+ }
private: /* data */
- QByteArray data;
- Meta::BaseEntity *m_entity;
+ QByteArray data;
+ Meta::BaseEntity *m_entity;
};
Meta::BaseEntity::~BaseEntity()
@@ -74,89 +74,89 @@ Meta::BaseEntity::~BaseEntity()
QUrl Meta::BaseEntity::url() const
{
- return QUrl("https://v1.meta.multimc.org").resolved(localFilename());
+ return QUrl("https://v1.meta.multimc.org").resolved(localFilename());
}
bool Meta::BaseEntity::loadLocalFile()
{
- const QString fname = QDir("meta").absoluteFilePath(localFilename());
- if (!QFile::exists(fname))
- {
- return false;
- }
- // TODO: check if the file has the expected checksum
- try
- {
- parse(Json::requireObject(Json::requireDocument(fname, fname), fname));
- return true;
- }
- catch (const Exception &e)
- {
- qDebug() << QString("Unable to parse file %1: %2").arg(fname, e.cause());
- // just make sure it's gone and we never consider it again.
- QFile::remove(fname);
- return false;
- }
+ const QString fname = QDir("meta").absoluteFilePath(localFilename());
+ if (!QFile::exists(fname))
+ {
+ return false;
+ }
+ // TODO: check if the file has the expected checksum
+ try
+ {
+ parse(Json::requireObject(Json::requireDocument(fname, fname), fname));
+ return true;
+ }
+ catch (const Exception &e)
+ {
+ qDebug() << QString("Unable to parse file %1: %2").arg(fname, e.cause());
+ // just make sure it's gone and we never consider it again.
+ QFile::remove(fname);
+ return false;
+ }
}
void Meta::BaseEntity::load(Net::Mode loadType)
{
- // load local file if nothing is loaded yet
- if(!isLoaded())
- {
- if(loadLocalFile())
- {
- m_loadStatus = LoadStatus::Local;
- }
- }
- // if we need remote update, run the update task
- if(loadType == Net::Mode::Offline || !shouldStartRemoteUpdate())
- {
- return;
- }
- NetJob *job = new NetJob(QObject::tr("Download of meta file %1").arg(localFilename()));
- auto url = this->url();
- auto entry = ENV.metacache()->resolveEntry("meta", localFilename());
- entry->setStale(true);
- auto dl = Net::Download::makeCached(url, entry);
- /*
- * The validator parses the file and loads it into the object.
- * If that fails, the file is not written to storage.
- */
- dl->addValidator(new ParsingValidator(this));
- job->addNetAction(dl);
- m_updateStatus = UpdateStatus::InProgress;
- m_updateTask.reset(job);
- QObject::connect(job, &NetJob::succeeded, [&]()
- {
- m_loadStatus = LoadStatus::Remote;
- m_updateStatus = UpdateStatus::Succeeded;
- m_updateTask.reset();
- });
- QObject::connect(job, &NetJob::failed, [&]()
- {
- m_updateStatus = UpdateStatus::Failed;
- m_updateTask.reset();
- });
- m_updateTask->start();
+ // load local file if nothing is loaded yet
+ if(!isLoaded())
+ {
+ if(loadLocalFile())
+ {
+ m_loadStatus = LoadStatus::Local;
+ }
+ }
+ // if we need remote update, run the update task
+ if(loadType == Net::Mode::Offline || !shouldStartRemoteUpdate())
+ {
+ return;
+ }
+ NetJob *job = new NetJob(QObject::tr("Download of meta file %1").arg(localFilename()));
+ auto url = this->url();
+ auto entry = ENV.metacache()->resolveEntry("meta", localFilename());
+ entry->setStale(true);
+ auto dl = Net::Download::makeCached(url, entry);
+ /*
+ * The validator parses the file and loads it into the object.
+ * If that fails, the file is not written to storage.
+ */
+ dl->addValidator(new ParsingValidator(this));
+ job->addNetAction(dl);
+ m_updateStatus = UpdateStatus::InProgress;
+ m_updateTask.reset(job);
+ QObject::connect(job, &NetJob::succeeded, [&]()
+ {
+ m_loadStatus = LoadStatus::Remote;
+ m_updateStatus = UpdateStatus::Succeeded;
+ m_updateTask.reset();
+ });
+ QObject::connect(job, &NetJob::failed, [&]()
+ {
+ m_updateStatus = UpdateStatus::Failed;
+ m_updateTask.reset();
+ });
+ m_updateTask->start();
}
bool Meta::BaseEntity::isLoaded() const
{
- return m_loadStatus > LoadStatus::NotLoaded;
+ return m_loadStatus > LoadStatus::NotLoaded;
}
bool Meta::BaseEntity::shouldStartRemoteUpdate() const
{
- // TODO: version-locks and offline mode?
- return m_updateStatus != UpdateStatus::InProgress;
+ // TODO: version-locks and offline mode?
+ return m_updateStatus != UpdateStatus::InProgress;
}
shared_qobject_ptr<Task> Meta::BaseEntity::getCurrentTask()
{
- if(m_updateStatus == UpdateStatus::InProgress)
- {
- return m_updateTask;
- }
- return nullptr;
+ if(m_updateStatus == UpdateStatus::InProgress)
+ {
+ return m_updateTask;
+ }
+ return nullptr;
}
diff --git a/api/logic/meta/BaseEntity.h b/api/logic/meta/BaseEntity.h
index 418c979f..19dd2c18 100644
--- a/api/logic/meta/BaseEntity.h
+++ b/api/logic/meta/BaseEntity.h
@@ -28,41 +28,41 @@ namespace Meta
class MULTIMC_LOGIC_EXPORT BaseEntity
{
public: /* types */
- using Ptr = std::shared_ptr<BaseEntity>;
- enum class LoadStatus
- {
- NotLoaded,
- Local,
- Remote
- };
- enum class UpdateStatus
- {
- NotDone,
- InProgress,
- Failed,
- Succeeded
- };
+ using Ptr = std::shared_ptr<BaseEntity>;
+ enum class LoadStatus
+ {
+ NotLoaded,
+ Local,
+ Remote
+ };
+ enum class UpdateStatus
+ {
+ NotDone,
+ InProgress,
+ Failed,
+ Succeeded
+ };
public:
- virtual ~BaseEntity();
+ virtual ~BaseEntity();
- virtual void parse(const QJsonObject &obj) = 0;
+ virtual void parse(const QJsonObject &obj) = 0;
- virtual QString localFilename() const = 0;
- virtual QUrl url() const;
+ virtual QString localFilename() const = 0;
+ virtual QUrl url() const;
- bool isLoaded() const;
- bool shouldStartRemoteUpdate() const;
+ bool isLoaded() const;
+ bool shouldStartRemoteUpdate() const;
- void load(Net::Mode loadType);
- shared_qobject_ptr<Task> getCurrentTask();
+ void load(Net::Mode loadType);
+ shared_qobject_ptr<Task> getCurrentTask();
protected: /* methods */
- bool loadLocalFile();
+ bool loadLocalFile();
private:
- LoadStatus m_loadStatus = LoadStatus::NotLoaded;
- UpdateStatus m_updateStatus = UpdateStatus::NotDone;
- shared_qobject_ptr<Task> m_updateTask;
+ LoadStatus m_loadStatus = LoadStatus::NotLoaded;
+ UpdateStatus m_updateStatus = UpdateStatus::NotDone;
+ shared_qobject_ptr<Task> m_updateTask;
};
}
diff --git a/api/logic/meta/Index.cpp b/api/logic/meta/Index.cpp
index 6e1e34cd..4dbc0a86 100644
--- a/api/logic/meta/Index.cpp
+++ b/api/logic/meta/Index.cpp
@@ -21,128 +21,128 @@
namespace Meta
{
Index::Index(QObject *parent)
- : QAbstractListModel(parent)
+ : QAbstractListModel(parent)
{
}
Index::Index(const QVector<VersionListPtr> &lists, QObject *parent)
- : QAbstractListModel(parent), m_lists(lists)
+ : QAbstractListModel(parent), m_lists(lists)
{
- for (int i = 0; i < m_lists.size(); ++i)
- {
- m_uids.insert(m_lists.at(i)->uid(), m_lists.at(i));
- connectVersionList(i, m_lists.at(i));
- }
+ for (int i = 0; i < m_lists.size(); ++i)
+ {
+ m_uids.insert(m_lists.at(i)->uid(), m_lists.at(i));
+ connectVersionList(i, m_lists.at(i));
+ }
}
QVariant Index::data(const QModelIndex &index, int role) const
{
- if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size())
- {
- return QVariant();
- }
+ if (index.parent().isValid() || index.row() < 0 || index.row() >= m_lists.size())
+ {
+ return QVariant();
+ }
- VersionListPtr list = m_lists.at(index.row());
- switch (role)
- {
- case Qt::DisplayRole:
- switch (index.column())
- {
- case 0: return list->humanReadable();
- default: break;
- }
- case UidRole: return list->uid();
- case NameRole: return list->name();
- case ListPtrRole: return QVariant::fromValue(list);
- }
- return QVariant();
+ VersionListPtr list = m_lists.at(index.row());
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (index.column())
+ {
+ case 0: return list->humanReadable();
+ default: break;
+ }
+ case UidRole: return list->uid();
+ case NameRole: return list->name();
+ case ListPtrRole: return QVariant::fromValue(list);
+ }
+ return QVariant();
}
int Index::rowCount(const QModelIndex &parent) const
{
- return m_lists.size();
+ return m_lists.size();
}
int Index::columnCount(const QModelIndex &parent) const
{
- return 1;
+ return 1;
}
QVariant Index::headerData(int section, Qt::Orientation orientation, int role) const
{
- if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0)
- {
- return tr("Name");
- }
- else
- {
- return QVariant();
- }
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0)
+ {
+ return tr("Name");
+ }
+ else
+ {
+ return QVariant();
+ }
}
bool Index::hasUid(const QString &uid) const
{
- return m_uids.contains(uid);
+ return m_uids.contains(uid);
}
VersionListPtr Index::get(const QString &uid)
{
- VersionListPtr out = m_uids.value(uid, nullptr);
- if(!out)
- {
- out = std::make_shared<VersionList>(uid);
- m_uids[uid] = out;
- }
- return out;
+ VersionListPtr out = m_uids.value(uid, nullptr);
+ if(!out)
+ {
+ out = std::make_shared<VersionList>(uid);
+ m_uids[uid] = out;
+ }
+ return out;
}
VersionPtr Index::get(const QString &uid, const QString &version)
{
- auto list = get(uid);
- return list->getVersion(version);
+ auto list = get(uid);
+ return list->getVersion(version);
}
void Index::parse(const QJsonObject& obj)
{
- parseIndex(obj, this);
+ parseIndex(obj, this);
}
void Index::merge(const std::shared_ptr<Index> &other)
{
- const QVector<VersionListPtr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists;
- // initial load, no need to merge
- if (m_lists.isEmpty())
- {
- beginResetModel();
- m_lists = lists;
- for (int i = 0; i < lists.size(); ++i)
- {
- m_uids.insert(lists.at(i)->uid(), lists.at(i));
- connectVersionList(i, lists.at(i));
- }
- endResetModel();
- }
- else
- {
- for (const VersionListPtr &list : lists)
- {
- if (m_uids.contains(list->uid()))
- {
- m_uids[list->uid()]->mergeFromIndex(list);
- }
- else
- {
- beginInsertRows(QModelIndex(), m_lists.size(), m_lists.size());
- connectVersionList(m_lists.size(), list);
- m_lists.append(list);
- m_uids.insert(list->uid(), list);
- endInsertRows();
- }
- }
- }
+ const QVector<VersionListPtr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists;
+ // initial load, no need to merge
+ if (m_lists.isEmpty())
+ {
+ beginResetModel();
+ m_lists = lists;
+ for (int i = 0; i < lists.size(); ++i)
+ {
+ m_uids.insert(lists.at(i)->uid(), lists.at(i));
+ connectVersionList(i, lists.at(i));
+ }
+ endResetModel();
+ }
+ else
+ {
+ for (const VersionListPtr &list : lists)
+ {
+ if (m_uids.contains(list->uid()))
+ {
+ m_uids[list->uid()]->mergeFromIndex(list);
+ }
+ else
+ {
+ beginInsertRows(QModelIndex(), m_lists.size(), m_lists.size());
+ connectVersionList(m_lists.size(), list);
+ m_lists.append(list);
+ m_uids.insert(list->uid(), list);
+ endInsertRows();
+ }
+ }
+ }
}
void Index::connectVersionList(const int row, const VersionListPtr &list)
{
- connect(list.get(), &VersionList::nameChanged, this, [this, row]()
- {
- emit dataChanged(index(row), index(row), QVector<int>() << Qt::DisplayRole);
- });
+ connect(list.get(), &VersionList::nameChanged, this, [this, row]()
+ {
+ emit dataChanged(index(row), index(row), QVector<int>() << Qt::DisplayRole);
+ });
}
}
diff --git a/api/logic/meta/Index.h b/api/logic/meta/Index.h
index 0ec43f96..c81b4c54 100644
--- a/api/logic/meta/Index.h
+++ b/api/logic/meta/Index.h
@@ -31,41 +31,41 @@ using VersionPtr = std::shared_ptr<class Version>;
class MULTIMC_LOGIC_EXPORT Index : public QAbstractListModel, public BaseEntity
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit Index(QObject *parent = nullptr);
- explicit Index(const QVector<VersionListPtr> &lists, QObject *parent = nullptr);
+ explicit Index(QObject *parent = nullptr);
+ explicit Index(const QVector<VersionListPtr> &lists, QObject *parent = nullptr);
- enum
- {
- UidRole = Qt::UserRole,
- NameRole,
- ListPtrRole
- };
+ enum
+ {
+ UidRole = Qt::UserRole,
+ NameRole,
+ ListPtrRole
+ };
- QVariant data(const QModelIndex &index, int role) const override;
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
- QString localFilename() const override { return "index.json"; }
+ QString localFilename() const override { return "index.json"; }
- // queries
- VersionListPtr get(const QString &uid);
- VersionPtr get(const QString &uid, const QString &version);
- bool hasUid(const QString &uid) const;
+ // queries
+ VersionListPtr get(const QString &uid);
+ VersionPtr get(const QString &uid, const QString &version);
+ bool hasUid(const QString &uid) const;
- QVector<VersionListPtr> lists() const { return m_lists; }
+ QVector<VersionListPtr> lists() const { return m_lists; }
public: // for usage by parsers only
- void merge(const std::shared_ptr<Index> &other);
- void parse(const QJsonObject &obj) override;
+ void merge(const std::shared_ptr<Index> &other);
+ void parse(const QJsonObject &obj) override;
private:
- QVector<VersionListPtr> m_lists;
- QHash<QString, VersionListPtr> m_uids;
+ QVector<VersionListPtr> m_lists;
+ QHash<QString, VersionListPtr> m_uids;
- void connectVersionList(const int row, const VersionListPtr &list);
+ void connectVersionList(const int row, const VersionListPtr &list);
};
}
diff --git a/api/logic/meta/Index_test.cpp b/api/logic/meta/Index_test.cpp
index 1c5face2..b0892070 100644
--- a/api/logic/meta/Index_test.cpp
+++ b/api/logic/meta/Index_test.cpp
@@ -7,36 +7,36 @@
class IndexTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- void test_isProvidedByEnv()
- {
- QVERIFY(ENV.metadataIndex());
- QCOMPARE(ENV.metadataIndex(), ENV.metadataIndex());
- }
+ void test_isProvidedByEnv()
+ {
+ QVERIFY(ENV.metadataIndex());
+ QCOMPARE(ENV.metadataIndex(), ENV.metadataIndex());
+ }
- void test_hasUid_and_getList()
- {
- Meta::Index windex({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")});
- QVERIFY(windex.hasUid("list1"));
- QVERIFY(!windex.hasUid("asdf"));
- QVERIFY(windex.get("list2") != nullptr);
- QCOMPARE(windex.get("list2")->uid(), QString("list2"));
- QVERIFY(windex.get("adsf") != nullptr);
- }
+ void test_hasUid_and_getList()
+ {
+ Meta::Index windex({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")});
+ QVERIFY(windex.hasUid("list1"));
+ QVERIFY(!windex.hasUid("asdf"));
+ QVERIFY(windex.get("list2") != nullptr);
+ QCOMPARE(windex.get("list2")->uid(), QString("list2"));
+ QVERIFY(windex.get("adsf") != nullptr);
+ }
- void test_merge()
- {
- Meta::Index windex({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")});
- QCOMPARE(windex.lists().size(), 3);
- windex.merge(std::shared_ptr<Meta::Index>(new Meta::Index({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")})));
- QCOMPARE(windex.lists().size(), 3);
- windex.merge(std::shared_ptr<Meta::Index>(new Meta::Index({std::make_shared<Meta::VersionList>("list4"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list5")})));
- QCOMPARE(windex.lists().size(), 5);
- windex.merge(std::shared_ptr<Meta::Index>(new Meta::Index({std::make_shared<Meta::VersionList>("list6")})));
- QCOMPARE(windex.lists().size(), 6);
- }
+ void test_merge()
+ {
+ Meta::Index windex({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")});
+ QCOMPARE(windex.lists().size(), 3);
+ windex.merge(std::shared_ptr<Meta::Index>(new Meta::Index({std::make_shared<Meta::VersionList>("list1"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list3")})));
+ QCOMPARE(windex.lists().size(), 3);
+ windex.merge(std::shared_ptr<Meta::Index>(new Meta::Index({std::make_shared<Meta::VersionList>("list4"), std::make_shared<Meta::VersionList>("list2"), std::make_shared<Meta::VersionList>("list5")})));
+ QCOMPARE(windex.lists().size(), 5);
+ windex.merge(std::shared_ptr<Meta::Index>(new Meta::Index({std::make_shared<Meta::VersionList>("list6")})));
+ QCOMPARE(windex.lists().size(), 6);
+ }
};
QTEST_GUILESS_MAIN(IndexTest)
diff --git a/api/logic/meta/JsonFormat.cpp b/api/logic/meta/JsonFormat.cpp
index 2183e579..12da266f 100644
--- a/api/logic/meta/JsonFormat.cpp
+++ b/api/logic/meta/JsonFormat.cpp
@@ -30,141 +30,141 @@ namespace Meta
MetadataVersion currentFormatVersion()
{
- return MetadataVersion::InitialRelease;
+ return MetadataVersion::InitialRelease;
}
// Index
static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj)
{
- const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages");
- QVector<VersionListPtr> lists;
- lists.reserve(objects.size());
- std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj)
- {
- VersionListPtr list = std::make_shared<VersionList>(requireString(obj, "uid"));
- list->setName(ensureString(obj, "name", QString()));
- return list;
- });
- return std::make_shared<Index>(lists);
+ const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages");
+ QVector<VersionListPtr> lists;
+ lists.reserve(objects.size());
+ std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj)
+ {
+ VersionListPtr list = std::make_shared<VersionList>(requireString(obj, "uid"));
+ list->setName(ensureString(obj, "name", QString()));
+ return list;
+ });
+ return std::make_shared<Index>(lists);
}
// Version
static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj)
{
- VersionPtr version = std::make_shared<Version>(uid, requireString(obj, "version"));
- version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000);
- version->setType(ensureString(obj, "type", QString()));
- version->setRecommended(ensureBoolean(obj, QString("recommended"), false));
- version->setVolatile(ensureBoolean(obj, QString("volatile"), false));
- RequireSet requires, conflicts;
- parseRequires(obj, &requires, "requires");
- parseRequires(obj, &conflicts, "conflicts");
- version->setRequires(requires, conflicts);
- return version;
+ VersionPtr version = std::make_shared<Version>(uid, requireString(obj, "version"));
+ version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000);
+ version->setType(ensureString(obj, "type", QString()));
+ version->setRecommended(ensureBoolean(obj, QString("recommended"), false));
+ version->setVolatile(ensureBoolean(obj, QString("volatile"), false));
+ RequireSet requires, conflicts;
+ parseRequires(obj, &requires, "requires");
+ parseRequires(obj, &conflicts, "conflicts");
+ version->setRequires(requires, conflicts);
+ return version;
}
static std::shared_ptr<Version> parseVersionInternal(const QJsonObject &obj)
{
- VersionPtr version = parseCommonVersion(requireString(obj, "uid"), obj);
+ VersionPtr version = parseCommonVersion(requireString(obj, "uid"), obj);
- version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
- QString("%1/%2.json").arg(version->uid(), version->version()),
- obj.contains("order")));
- return version;
+ version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
+ QString("%1/%2.json").arg(version->uid(), version->version()),
+ obj.contains("order")));
+ return version;
}
// Version list / package
static std::shared_ptr<VersionList> parseVersionListInternal(const QJsonObject &obj)
{
- const QString uid = requireString(obj, "uid");
-
- const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
- QVector<VersionPtr> versions;
- versions.reserve(versionsRaw.size());
- std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj)
- {
- auto version = parseCommonVersion(uid, vObj);
- version->setProvidesRecommendations();
- return version;
- });
-
- VersionListPtr list = std::make_shared<VersionList>(uid);
- list->setName(ensureString(obj, "name", QString()));
- list->setVersions(versions);
- return list;
+ const QString uid = requireString(obj, "uid");
+
+ const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
+ QVector<VersionPtr> versions;
+ versions.reserve(versionsRaw.size());
+ std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj)
+ {
+ auto version = parseCommonVersion(uid, vObj);
+ version->setProvidesRecommendations();
+ return version;
+ });
+
+ VersionListPtr list = std::make_shared<VersionList>(uid);
+ list->setName(ensureString(obj, "name", QString()));
+ list->setVersions(versions);
+ return list;
}
MetadataVersion parseFormatVersion(const QJsonObject &obj, bool required)
{
- if (!obj.contains("formatVersion"))
- {
- if(required)
- {
- return MetadataVersion::Invalid;
- }
- return MetadataVersion::InitialRelease;
- }
- if (!obj.value("formatVersion").isDouble())
- {
- return MetadataVersion::Invalid;
- }
- switch(obj.value("formatVersion").toInt())
- {
- case 0:
- case 1:
- return MetadataVersion::InitialRelease;
- default:
- return MetadataVersion::Invalid;
- }
+ if (!obj.contains("formatVersion"))
+ {
+ if(required)
+ {
+ return MetadataVersion::Invalid;
+ }
+ return MetadataVersion::InitialRelease;
+ }
+ if (!obj.value("formatVersion").isDouble())
+ {
+ return MetadataVersion::Invalid;
+ }
+ switch(obj.value("formatVersion").toInt())
+ {
+ case 0:
+ case 1:
+ return MetadataVersion::InitialRelease;
+ default:
+ return MetadataVersion::Invalid;
+ }
}
void serializeFormatVersion(QJsonObject& obj, Meta::MetadataVersion version)
{
- if(version == MetadataVersion::Invalid)
- {
- return;
- }
- obj.insert("formatVersion", int(version));
+ if(version == MetadataVersion::Invalid)
+ {
+ return;
+ }
+ obj.insert("formatVersion", int(version));
}
void parseIndex(const QJsonObject &obj, Index *ptr)
{
- const MetadataVersion version = parseFormatVersion(obj);
- switch (version)
- {
- case MetadataVersion::InitialRelease:
- ptr->merge(parseIndexInternal(obj));
- break;
- case MetadataVersion::Invalid:
- throw ParseException(QObject::tr("Unknown format version!"));
- }
+ const MetadataVersion version = parseFormatVersion(obj);
+ switch (version)
+ {
+ case MetadataVersion::InitialRelease:
+ ptr->merge(parseIndexInternal(obj));
+ break;
+ case MetadataVersion::Invalid:
+ throw ParseException(QObject::tr("Unknown format version!"));
+ }
}
void parseVersionList(const QJsonObject &obj, VersionList *ptr)
{
- const MetadataVersion version = parseFormatVersion(obj);
- switch (version)
- {
- case MetadataVersion::InitialRelease:
- ptr->merge(parseVersionListInternal(obj));
- break;
- case MetadataVersion::Invalid:
- throw ParseException(QObject::tr("Unknown format version!"));
- }
+ const MetadataVersion version = parseFormatVersion(obj);
+ switch (version)
+ {
+ case MetadataVersion::InitialRelease:
+ ptr->merge(parseVersionListInternal(obj));
+ break;
+ case MetadataVersion::Invalid:
+ throw ParseException(QObject::tr("Unknown format version!"));
+ }
}
void parseVersion(const QJsonObject &obj, Version *ptr)
{
- const MetadataVersion version = parseFormatVersion(obj);
- switch (version)
- {
- case MetadataVersion::InitialRelease:
- ptr->merge(parseVersionInternal(obj));
- break;
- case MetadataVersion::Invalid:
- throw ParseException(QObject::tr("Unknown format version!"));
- }
+ const MetadataVersion version = parseFormatVersion(obj);
+ switch (version)
+ {
+ case MetadataVersion::InitialRelease:
+ ptr->merge(parseVersionInternal(obj));
+ break;
+ case MetadataVersion::Invalid:
+ throw ParseException(QObject::tr("Unknown format version!"));
+ }
}
/*
@@ -174,44 +174,44 @@ void parseVersion(const QJsonObject &obj, Version *ptr)
*/
void parseRequires(const QJsonObject& obj, RequireSet* ptr, const char * keyName)
{
- if(obj.contains(keyName))
- {
- QSet<QString> requires;
- auto reqArray = requireArray(obj, keyName);
- auto iter = reqArray.begin();
- while(iter != reqArray.end())
- {
- auto reqObject = requireObject(*iter);
- auto uid = requireString(reqObject, "uid");
- auto equals = ensureString(reqObject, "equals", QString());
- auto suggests = ensureString(reqObject, "suggests", QString());
- ptr->insert({uid, equals, suggests});
- iter++;
- }
- }
+ if(obj.contains(keyName))
+ {
+ QSet<QString> requires;
+ auto reqArray = requireArray(obj, keyName);
+ auto iter = reqArray.begin();
+ while(iter != reqArray.end())
+ {
+ auto reqObject = requireObject(*iter);
+ auto uid = requireString(reqObject, "uid");
+ auto equals = ensureString(reqObject, "equals", QString());
+ auto suggests = ensureString(reqObject, "suggests", QString());
+ ptr->insert({uid, equals, suggests});
+ iter++;
+ }
+ }
}
void serializeRequires(QJsonObject& obj, RequireSet* ptr, const char * keyName)
{
- if(!ptr || ptr->empty())
- {
- return;
- }
- QJsonArray arrOut;
- for(auto &iter: *ptr)
- {
- QJsonObject reqOut;
- reqOut.insert("uid", iter.uid);
- if(!iter.equalsVersion.isEmpty())
- {
- reqOut.insert("equals", iter.equalsVersion);
- }
- if(!iter.suggests.isEmpty())
- {
- reqOut.insert("suggests", iter.suggests);
- }
- arrOut.append(reqOut);
- }
- obj.insert(keyName, arrOut);
+ if(!ptr || ptr->empty())
+ {
+ return;
+ }
+ QJsonArray arrOut;
+ for(auto &iter: *ptr)
+ {
+ QJsonObject reqOut;
+ reqOut.insert("uid", iter.uid);
+ if(!iter.equalsVersion.isEmpty())
+ {
+ reqOut.insert("equals", iter.equalsVersion);
+ }
+ if(!iter.suggests.isEmpty())
+ {
+ reqOut.insert("suggests", iter.suggests);
+ }
+ arrOut.append(reqOut);
+ }
+ obj.insert(keyName, arrOut);
}
}
diff --git a/api/logic/meta/JsonFormat.h b/api/logic/meta/JsonFormat.h
index cc2c8f83..62351ad6 100644
--- a/api/logic/meta/JsonFormat.h
+++ b/api/logic/meta/JsonFormat.h
@@ -30,39 +30,39 @@ class VersionList;
enum class MetadataVersion
{
- Invalid = -1,
- InitialRelease = 1
+ Invalid = -1,
+ InitialRelease = 1
};
class ParseException : public Exception
{
public:
- using Exception::Exception;
+ using Exception::Exception;
};
struct Require
{
- bool operator==(const Require & rhs) const
- {
- return uid == rhs.uid;
- }
- bool operator<(const Require & rhs) const
- {
- return uid < rhs.uid;
- }
- bool deepEquals(const Require & rhs) const
- {
- return uid == rhs.uid
- && equalsVersion == rhs.equalsVersion
- && suggests == rhs.suggests;
- }
- QString uid;
- QString equalsVersion;
- QString suggests;
+ bool operator==(const Require & rhs) const
+ {
+ return uid == rhs.uid;
+ }
+ bool operator<(const Require & rhs) const
+ {
+ return uid < rhs.uid;
+ }
+ bool deepEquals(const Require & rhs) const
+ {
+ return uid == rhs.uid
+ && equalsVersion == rhs.equalsVersion
+ && suggests == rhs.suggests;
+ }
+ QString uid;
+ QString equalsVersion;
+ QString suggests;
};
inline Q_DECL_PURE_FUNCTION uint qHash(const Require &key, uint seed = 0) Q_DECL_NOTHROW
{
- return qHash(key.uid, seed);
+ return qHash(key.uid, seed);
}
using RequireSet = std::set<Require>;
diff --git a/api/logic/meta/Version.cpp b/api/logic/meta/Version.cpp
index edc70f33..05a76b41 100644
--- a/api/logic/meta/Version.cpp
+++ b/api/logic/meta/Version.cpp
@@ -21,7 +21,7 @@
#include "minecraft/ComponentList.h"
Meta::Version::Version(const QString &uid, const QString &version)
- : BaseVersion(), m_uid(uid), m_version(version)
+ : BaseVersion(), m_uid(uid), m_version(version)
{
}
@@ -31,110 +31,110 @@ Meta::Version::~Version()
QString Meta::Version::descriptor()
{
- return m_version;
+ return m_version;
}
QString Meta::Version::name()
{
- if(m_data)
- return m_data->name;
- return m_uid;
+ if(m_data)
+ return m_data->name;
+ return m_uid;
}
QString Meta::Version::typeString() const
{
- return m_type;
+ return m_type;
}
QDateTime Meta::Version::time() const
{
- return QDateTime::fromMSecsSinceEpoch(m_time * 1000, Qt::UTC);
+ return QDateTime::fromMSecsSinceEpoch(m_time * 1000, Qt::UTC);
}
void Meta::Version::parse(const QJsonObject& obj)
{
- parseVersion(obj, this);
+ parseVersion(obj, this);
}
void Meta::Version::mergeFromList(const Meta::VersionPtr& other)
{
- if(other->m_providesRecommendations)
- {
- if(m_recommended != other->m_recommended)
- {
- setRecommended(other->m_recommended);
- }
- }
- if (m_type != other->m_type)
- {
- setType(other->m_type);
- }
- if (m_time != other->m_time)
- {
- setTime(other->m_time);
- }
- if (m_requires != other->m_requires)
- {
- m_requires = other->m_requires;
- }
- if (m_conflicts != other->m_conflicts)
- {
- m_conflicts = other->m_conflicts;
- }
- if(m_volatile != other->m_volatile)
- {
- setVolatile(other->m_volatile);
- }
+ if(other->m_providesRecommendations)
+ {
+ if(m_recommended != other->m_recommended)
+ {
+ setRecommended(other->m_recommended);
+ }
+ }
+ if (m_type != other->m_type)
+ {
+ setType(other->m_type);
+ }
+ if (m_time != other->m_time)
+ {
+ setTime(other->m_time);
+ }
+ if (m_requires != other->m_requires)
+ {
+ m_requires = other->m_requires;
+ }
+ if (m_conflicts != other->m_conflicts)
+ {
+ m_conflicts = other->m_conflicts;
+ }
+ if(m_volatile != other->m_volatile)
+ {
+ setVolatile(other->m_volatile);
+ }
}
void Meta::Version::merge(const VersionPtr &other)
{
- mergeFromList(other);
- if(other->m_data)
- {
- setData(other->m_data);
- }
+ mergeFromList(other);
+ if(other->m_data)
+ {
+ setData(other->m_data);
+ }
}
QString Meta::Version::localFilename() const
{
- return m_uid + '/' + m_version + ".json";
+ return m_uid + '/' + m_version + ".json";
}
void Meta::Version::setType(const QString &type)
{
- m_type = type;
- emit typeChanged();
+ m_type = type;
+ emit typeChanged();
}
void Meta::Version::setTime(const qint64 time)
{
- m_time = time;
- emit timeChanged();
+ m_time = time;
+ emit timeChanged();
}
void Meta::Version::setRequires(const Meta::RequireSet &requires, const Meta::RequireSet &conflicts)
{
- m_requires = requires;
- m_conflicts = conflicts;
- emit requiresChanged();
+ m_requires = requires;
+ m_conflicts = conflicts;
+ emit requiresChanged();
}
void Meta::Version::setVolatile(bool volatile_)
{
- m_volatile = volatile_;
+ m_volatile = volatile_;
}
void Meta::Version::setData(const VersionFilePtr &data)
{
- m_data = data;
+ m_data = data;
}
void Meta::Version::setProvidesRecommendations()
{
- m_providesRecommendations = true;
+ m_providesRecommendations = true;
}
void Meta::Version::setRecommended(bool recommended)
{
- m_recommended = recommended;
+ m_recommended = recommended;
}
diff --git a/api/logic/meta/Version.h b/api/logic/meta/Version.h
index 33bd5b35..6506d486 100644
--- a/api/logic/meta/Version.h
+++ b/api/logic/meta/Version.h
@@ -36,82 +36,82 @@ using VersionPtr = std::shared_ptr<class Version>;
class MULTIMC_LOGIC_EXPORT Version : public QObject, public BaseVersion, public BaseEntity
{
- Q_OBJECT
+ Q_OBJECT
public: /* con/des */
- explicit Version(const QString &uid, const QString &version);
- virtual ~Version();
-
- QString descriptor() override;
- QString name() override;
- QString typeString() const override;
-
- QString uid() const
- {
- return m_uid;
- }
- QString version() const
- {
- return m_version;
- }
- QString type() const
- {
- return m_type;
- }
- QDateTime time() const;
- qint64 rawTime() const
- {
- return m_time;
- }
- const Meta::RequireSet &requires() const
- {
- return m_requires;
- }
- VersionFilePtr data() const
- {
- return m_data;
- }
- bool isRecommended() const
- {
- return m_recommended;
- }
- bool isLoaded() const
- {
- return m_data != nullptr;
- }
-
- void merge(const VersionPtr &other);
- void mergeFromList(const VersionPtr &other);
- void parse(const QJsonObject &obj) override;
-
- QString localFilename() const override;
+ explicit Version(const QString &uid, const QString &version);
+ virtual ~Version();
+
+ QString descriptor() override;
+ QString name() override;
+ QString typeString() const override;
+
+ QString uid() const
+ {
+ return m_uid;
+ }
+ QString version() const
+ {
+ return m_version;
+ }
+ QString type() const
+ {
+ return m_type;
+ }
+ QDateTime time() const;
+ qint64 rawTime() const
+ {
+ return m_time;
+ }
+ const Meta::RequireSet &requires() const
+ {
+ return m_requires;
+ }
+ VersionFilePtr data() const
+ {
+ return m_data;
+ }
+ bool isRecommended() const
+ {
+ return m_recommended;
+ }
+ bool isLoaded() const
+ {
+ return m_data != nullptr;
+ }
+
+ void merge(const VersionPtr &other);
+ void mergeFromList(const VersionPtr &other);
+ void parse(const QJsonObject &obj) override;
+
+ QString localFilename() const override;
public: // for usage by format parsers only
- void setType(const QString &type);
- void setTime(const qint64 time);
- void setRequires(const Meta::RequireSet &requires, const Meta::RequireSet &conflicts);
- void setVolatile(bool volatile_);
- void setRecommended(bool recommended);
- void setProvidesRecommendations();
- void setData(const VersionFilePtr &data);
+ void setType(const QString &type);
+ void setTime(const qint64 time);
+ void setRequires(const Meta::RequireSet &requires, const Meta::RequireSet &conflicts);
+ void setVolatile(bool volatile_);
+ void setRecommended(bool recommended);
+ void setProvidesRecommendations();
+ void setData(const VersionFilePtr &data);
signals:
- void typeChanged();
- void timeChanged();
- void requiresChanged();
+ void typeChanged();
+ void timeChanged();
+ void requiresChanged();
private:
- bool m_providesRecommendations = false;
- bool m_recommended = false;
- QString m_name;
- QString m_uid;
- QString m_version;
- QString m_type;
- qint64 m_time = 0;
- Meta::RequireSet m_requires;
- Meta::RequireSet m_conflicts;
- bool m_volatile = false;
- VersionFilePtr m_data;
+ bool m_providesRecommendations = false;
+ bool m_recommended = false;
+ QString m_name;
+ QString m_uid;
+ QString m_version;
+ QString m_type;
+ qint64 m_time = 0;
+ Meta::RequireSet m_requires;
+ Meta::RequireSet m_conflicts;
+ bool m_volatile = false;
+ VersionFilePtr m_data;
};
}
diff --git a/api/logic/meta/VersionList.cpp b/api/logic/meta/VersionList.cpp
index 9ae02301..526fe165 100644
--- a/api/logic/meta/VersionList.cpp
+++ b/api/logic/meta/VersionList.cpp
@@ -24,222 +24,222 @@
namespace Meta
{
VersionList::VersionList(const QString &uid, QObject *parent)
- : BaseVersionList(parent), m_uid(uid)
+ : BaseVersionList(parent), m_uid(uid)
{
- setObjectName("Version list: " + uid);
+ setObjectName("Version list: " + uid);
}
shared_qobject_ptr<Task> VersionList::getLoadTask()
{
- load(Net::Mode::Online);
- return getCurrentTask();
+ load(Net::Mode::Online);
+ return getCurrentTask();
}
bool VersionList::isLoaded()
{
- return BaseEntity::isLoaded();
+ return BaseEntity::isLoaded();
}
const BaseVersionPtr VersionList::at(int i) const
{
- return m_versions.at(i);
+ return m_versions.at(i);
}
int VersionList::count() const
{
- return m_versions.size();
+ return m_versions.size();
}
void VersionList::sortVersions()
{
- beginResetModel();
- std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b)
- {
- return *a.get() < *b.get();
- });
- endResetModel();
+ beginResetModel();
+ std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b)
+ {
+ return *a.get() < *b.get();
+ });
+ endResetModel();
}
QVariant VersionList::data(const QModelIndex &index, int role) const
{
- if (!index.isValid() || index.row() < 0 || index.row() >= m_versions.size() || index.parent().isValid())
- {
- return QVariant();
- }
-
- VersionPtr version = m_versions.at(index.row());
-
- switch (role)
- {
- case VersionPointerRole: return QVariant::fromValue(std::dynamic_pointer_cast<BaseVersion>(version));
- case VersionRole:
- case VersionIdRole:
- return version->version();
- case ParentVersionRole:
- {
- // FIXME: HACK: this should be generic and be replaced by something else. Anything that is a hard 'equals' dep is a 'parent uid'.
- auto & reqs = version->requires();
- auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Require & req)
- {
- return req.uid == "net.minecraft";
- });
- if (iter != reqs.end())
- {
- return (*iter).equalsVersion;
- }
- return QVariant();
- }
- case TypeRole: return version->type();
-
- case UidRole: return version->uid();
- case TimeRole: return version->time();
- case RequiresRole: return QVariant::fromValue(version->requires());
- case SortRole: return version->rawTime();
- case VersionPtrRole: return QVariant::fromValue(version);
- case RecommendedRole: return version->isRecommended();
- // FIXME: this should be determined in whatever view/proxy is used...
- // case LatestRole: return version == getLatestStable();
- default: return QVariant();
- }
+ if (!index.isValid() || index.row() < 0 || index.row() >= m_versions.size() || index.parent().isValid())
+ {
+ return QVariant();
+ }
+
+ VersionPtr version = m_versions.at(index.row());
+
+ switch (role)
+ {
+ case VersionPointerRole: return QVariant::fromValue(std::dynamic_pointer_cast<BaseVersion>(version));
+ case VersionRole:
+ case VersionIdRole:
+ return version->version();
+ case ParentVersionRole:
+ {
+ // FIXME: HACK: this should be generic and be replaced by something else. Anything that is a hard 'equals' dep is a 'parent uid'.
+ auto & reqs = version->requires();
+ auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Require & req)
+ {
+ return req.uid == "net.minecraft";
+ });
+ if (iter != reqs.end())
+ {
+ return (*iter).equalsVersion;
+ }
+ return QVariant();
+ }
+ case TypeRole: return version->type();
+
+ case UidRole: return version->uid();
+ case TimeRole: return version->time();
+ case RequiresRole: return QVariant::fromValue(version->requires());
+ case SortRole: return version->rawTime();
+ case VersionPtrRole: return QVariant::fromValue(version);
+ case RecommendedRole: return version->isRecommended();
+ // FIXME: this should be determined in whatever view/proxy is used...
+ // case LatestRole: return version == getLatestStable();
+ default: return QVariant();
+ }
}
BaseVersionList::RoleList VersionList::providesRoles() const
{
- return {VersionPointerRole, VersionRole, VersionIdRole, ParentVersionRole,
- TypeRole, UidRole, TimeRole, RequiresRole, SortRole,
- RecommendedRole, LatestRole, VersionPtrRole};
+ return {VersionPointerRole, VersionRole, VersionIdRole, ParentVersionRole,
+ TypeRole, UidRole, TimeRole, RequiresRole, SortRole,
+ RecommendedRole, LatestRole, VersionPtrRole};
}
QHash<int, QByteArray> VersionList::roleNames() const
{
- QHash<int, QByteArray> roles = BaseVersionList::roleNames();
- roles.insert(UidRole, "uid");
- roles.insert(TimeRole, "time");
- roles.insert(SortRole, "sort");
- roles.insert(RequiresRole, "requires");
- return roles;
+ QHash<int, QByteArray> roles = BaseVersionList::roleNames();
+ roles.insert(UidRole, "uid");
+ roles.insert(TimeRole, "time");
+ roles.insert(SortRole, "sort");
+ roles.insert(RequiresRole, "requires");
+ return roles;
}
QString VersionList::localFilename() const
{
- return m_uid + "/index.json";
+ return m_uid + "/index.json";
}
QString VersionList::humanReadable() const
{
- return m_name.isEmpty() ? m_uid : m_name;
+ return m_name.isEmpty() ? m_uid : m_name;
}
VersionPtr VersionList::getVersion(const QString &version)
{
- VersionPtr out = m_lookup.value(version, nullptr);
- if(!out)
- {
- out = std::make_shared<Version>(m_uid, version);
- m_lookup[version] = out;
- }
- return out;
+ VersionPtr out = m_lookup.value(version, nullptr);
+ if(!out)
+ {
+ out = std::make_shared<Version>(m_uid, version);
+ m_lookup[version] = out;
+ }
+ return out;
}
void VersionList::setName(const QString &name)
{
- m_name = name;
- emit nameChanged(name);
+ m_name = name;
+ emit nameChanged(name);
}
void VersionList::setVersions(const QVector<VersionPtr> &versions)
{
- beginResetModel();
- m_versions = versions;
- std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b)
- {
- return a->rawTime() > b->rawTime();
- });
- for (int i = 0; i < m_versions.size(); ++i)
- {
- m_lookup.insert(m_versions.at(i)->version(), m_versions.at(i));
- setupAddedVersion(i, m_versions.at(i));
- }
+ beginResetModel();
+ m_versions = versions;
+ std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b)
+ {
+ return a->rawTime() > b->rawTime();
+ });
+ for (int i = 0; i < m_versions.size(); ++i)
+ {
+ m_lookup.insert(m_versions.at(i)->version(), m_versions.at(i));
+ setupAddedVersion(i, m_versions.at(i));
+ }
- // FIXME: this is dumb, we have 'recommended' as part of the metadata already...
- auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const VersionPtr &ptr) { return ptr->type() == "release"; });
- m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt;
- endResetModel();
+ // FIXME: this is dumb, we have 'recommended' as part of the metadata already...
+ auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const VersionPtr &ptr) { return ptr->type() == "release"; });
+ m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt;
+ endResetModel();
}
void VersionList::parse(const QJsonObject& obj)
{
- parseVersionList(obj, this);
+ parseVersionList(obj, this);
}
// FIXME: this is dumb, we have 'recommended' as part of the metadata already...
static const Meta::VersionPtr &getBetterVersion(const Meta::VersionPtr &a, const Meta::VersionPtr &b)
{
- if(!a)
- return b;
- if(!b)
- return a;
- if(a->type() == b->type())
- {
- // newer of same type wins
- return (a->rawTime() > b->rawTime() ? a : b);
- }
- // 'release' type wins
- return (a->type() == "release" ? a : b);
+ if(!a)
+ return b;
+ if(!b)
+ return a;
+ if(a->type() == b->type())
+ {
+ // newer of same type wins
+ return (a->rawTime() > b->rawTime() ? a : b);
+ }
+ // 'release' type wins
+ return (a->type() == "release" ? a : b);
}
void VersionList::mergeFromIndex(const VersionListPtr &other)
{
- if (m_name != other->m_name)
- {
- setName(other->m_name);
- }
+ if (m_name != other->m_name)
+ {
+ setName(other->m_name);
+ }
}
void VersionList::merge(const VersionListPtr &other)
{
- if (m_name != other->m_name)
- {
- setName(other->m_name);
- }
-
- // TODO: do not reset the whole model. maybe?
- beginResetModel();
- m_versions.clear();
- if(other->m_versions.isEmpty())
- {
- qWarning() << "Empty list loaded ...";
- }
- for (const VersionPtr &version : other->m_versions)
- {
- // we already have the version. merge the contents
- if (m_lookup.contains(version->version()))
- {
- m_lookup.value(version->version())->mergeFromList(version);
- }
- else
- {
- m_lookup.insert(version->uid(), version);
- }
- // connect it.
- setupAddedVersion(m_versions.size(), version);
- m_versions.append(version);
- m_recommended = getBetterVersion(m_recommended, version);
- }
- endResetModel();
+ if (m_name != other->m_name)
+ {
+ setName(other->m_name);
+ }
+
+ // TODO: do not reset the whole model. maybe?
+ beginResetModel();
+ m_versions.clear();
+ if(other->m_versions.isEmpty())
+ {
+ qWarning() << "Empty list loaded ...";
+ }
+ for (const VersionPtr &version : other->m_versions)
+ {
+ // we already have the version. merge the contents
+ if (m_lookup.contains(version->version()))
+ {
+ m_lookup.value(version->version())->mergeFromList(version);
+ }
+ else
+ {
+ m_lookup.insert(version->uid(), version);
+ }
+ // connect it.
+ setupAddedVersion(m_versions.size(), version);
+ m_versions.append(version);
+ m_recommended = getBetterVersion(m_recommended, version);
+ }
+ endResetModel();
}
void VersionList::setupAddedVersion(const int row, const VersionPtr &version)
{
- // FIXME: do not disconnect from everythin, disconnect only the lambdas here
- version->disconnect();
- connect(version.get(), &Version::requiresChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << RequiresRole); });
- connect(version.get(), &Version::timeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TimeRole << SortRole); });
- connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TypeRole); });
+ // FIXME: do not disconnect from everythin, disconnect only the lambdas here
+ version->disconnect();
+ connect(version.get(), &Version::requiresChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << RequiresRole); });
+ connect(version.get(), &Version::timeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TimeRole << SortRole); });
+ connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TypeRole); });
}
BaseVersionPtr VersionList::getRecommended() const
{
- return m_recommended;
+ return m_recommended;
}
}
diff --git a/api/logic/meta/VersionList.h b/api/logic/meta/VersionList.h
index ad8733cc..0be074dd 100644
--- a/api/logic/meta/VersionList.h
+++ b/api/logic/meta/VersionList.h
@@ -27,75 +27,75 @@ using VersionListPtr = std::shared_ptr<class VersionList>;
class MULTIMC_LOGIC_EXPORT VersionList : public BaseVersionList, public BaseEntity
{
- Q_OBJECT
- Q_PROPERTY(QString uid READ uid CONSTANT)
- Q_PROPERTY(QString name READ name NOTIFY nameChanged)
+ Q_OBJECT
+ Q_PROPERTY(QString uid READ uid CONSTANT)
+ Q_PROPERTY(QString name READ name NOTIFY nameChanged)
public:
- explicit VersionList(const QString &uid, QObject *parent = nullptr);
-
- enum Roles
- {
- UidRole = Qt::UserRole + 100,
- TimeRole,
- RequiresRole,
- VersionPtrRole
- };
-
- shared_qobject_ptr<Task> getLoadTask() override;
- bool isLoaded() override;
- const BaseVersionPtr at(int i) const override;
- int count() const override;
- void sortVersions() override;
-
- BaseVersionPtr getRecommended() const override;
-
- QVariant data(const QModelIndex &index, int role) const override;
- RoleList providesRoles() const override;
- QHash<int, QByteArray> roleNames() const override;
-
- QString localFilename() const override;
-
- QString uid() const
- {
- return m_uid;
- }
- QString name() const
- {
- return m_name;
- }
- QString humanReadable() const;
-
- VersionPtr getVersion(const QString &version);
-
- QVector<VersionPtr> versions() const
- {
- return m_versions;
- }
+ explicit VersionList(const QString &uid, QObject *parent = nullptr);
+
+ enum Roles
+ {
+ UidRole = Qt::UserRole + 100,
+ TimeRole,
+ RequiresRole,
+ VersionPtrRole
+ };
+
+ shared_qobject_ptr<Task> getLoadTask() override;
+ bool isLoaded() override;
+ const BaseVersionPtr at(int i) const override;
+ int count() const override;
+ void sortVersions() override;
+
+ BaseVersionPtr getRecommended() const override;
+
+ QVariant data(const QModelIndex &index, int role) const override;
+ RoleList providesRoles() const override;
+ QHash<int, QByteArray> roleNames() const override;
+
+ QString localFilename() const override;
+
+ QString uid() const
+ {
+ return m_uid;
+ }
+ QString name() const
+ {
+ return m_name;
+ }
+ QString humanReadable() const;
+
+ VersionPtr getVersion(const QString &version);
+
+ QVector<VersionPtr> versions() const
+ {
+ return m_versions;
+ }
public: // for usage only by parsers
- void setName(const QString &name);
- void setVersions(const QVector<VersionPtr> &versions);
- void merge(const VersionListPtr &other);
- void mergeFromIndex(const VersionListPtr &other);
- void parse(const QJsonObject &obj) override;
+ void setName(const QString &name);
+ void setVersions(const QVector<VersionPtr> &versions);
+ void merge(const VersionListPtr &other);
+ void mergeFromIndex(const VersionListPtr &other);
+ void parse(const QJsonObject &obj) override;
signals:
- void nameChanged(const QString &name);
+ void nameChanged(const QString &name);
protected slots:
- void updateListData(QList<BaseVersionPtr>) override
- {
- }
+ void updateListData(QList<BaseVersionPtr>) override
+ {
+ }
private:
- QVector<VersionPtr> m_versions;
- QHash<QString, VersionPtr> m_lookup;
- QString m_uid;
- QString m_name;
+ QVector<VersionPtr> m_versions;
+ QHash<QString, VersionPtr> m_lookup;
+ QString m_uid;
+ QString m_name;
- VersionPtr m_recommended;
+ VersionPtr m_recommended;
- void setupAddedVersion(const int row, const VersionPtr &version);
+ void setupAddedVersion(const int row, const VersionPtr &version);
};
}
Q_DECLARE_METATYPE(Meta::VersionListPtr)
diff --git a/api/logic/minecraft/AssetsUtils.cpp b/api/logic/minecraft/AssetsUtils.cpp
index 5b25bede..a2274492 100644
--- a/api/logic/minecraft/AssetsUtils.cpp
+++ b/api/logic/minecraft/AssetsUtils.cpp
@@ -38,200 +38,200 @@ namespace AssetsUtils
*/
bool loadAssetsIndexJson(QString assetsId, QString path, AssetsIndex *index)
{
- /*
- {
- "objects": {
- "icons/icon_16x16.png": {
- "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
- "size": 3665
- },
- ...
- }
- }
- }
- */
-
- QFile file(path);
-
- // Try to open the file and fail if we can't.
- // TODO: We should probably report this error to the user.
- if (!file.open(QIODevice::ReadOnly))
- {
- qCritical() << "Failed to read assets index file" << path;
- return false;
- }
- index->id = assetsId;
-
- // Read the file and close it.
- QByteArray jsonData = file.readAll();
- file.close();
-
- QJsonParseError parseError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
-
- // Fail if the JSON is invalid.
- if (parseError.error != QJsonParseError::NoError)
- {
- qCritical() << "Failed to parse assets index file:" << parseError.errorString()
- << "at offset " << QString::number(parseError.offset);
- return false;
- }
-
- // Make sure the root is an object.
- if (!jsonDoc.isObject())
- {
- qCritical() << "Invalid assets index JSON: Root should be an array.";
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- QJsonValue isVirtual = root.value("virtual");
- if (!isVirtual.isUndefined())
- {
- index->isVirtual = isVirtual.toBool(false);
- }
-
- QJsonValue objects = root.value("objects");
- QVariantMap map = objects.toVariant().toMap();
-
- for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
- {
- // qDebug() << iter.key();
-
- QVariant variant = iter.value();
- QVariantMap nested_objects = variant.toMap();
-
- AssetObject object;
-
- for (QVariantMap::const_iterator nested_iter = nested_objects.begin();
- nested_iter != nested_objects.end(); ++nested_iter)
- {
- // qDebug() << nested_iter.key() << nested_iter.value().toString();
- QString key = nested_iter.key();
- QVariant value = nested_iter.value();
-
- if (key == "hash")
- {
- object.hash = value.toString();
- }
- else if (key == "size")
- {
- object.size = value.toDouble();
- }
- }
-
- index->objects.insert(iter.key(), object);
- }
-
- return true;
+ /*
+ {
+ "objects": {
+ "icons/icon_16x16.png": {
+ "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
+ "size": 3665
+ },
+ ...
+ }
+ }
+ }
+ */
+
+ QFile file(path);
+
+ // Try to open the file and fail if we can't.
+ // TODO: We should probably report this error to the user.
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ qCritical() << "Failed to read assets index file" << path;
+ return false;
+ }
+ index->id = assetsId;
+
+ // Read the file and close it.
+ QByteArray jsonData = file.readAll();
+ file.close();
+
+ QJsonParseError parseError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
+
+ // Fail if the JSON is invalid.
+ if (parseError.error != QJsonParseError::NoError)
+ {
+ qCritical() << "Failed to parse assets index file:" << parseError.errorString()
+ << "at offset " << QString::number(parseError.offset);
+ return false;
+ }
+
+ // Make sure the root is an object.
+ if (!jsonDoc.isObject())
+ {
+ qCritical() << "Invalid assets index JSON: Root should be an array.";
+ return false;
+ }
+
+ QJsonObject root = jsonDoc.object();
+
+ QJsonValue isVirtual = root.value("virtual");
+ if (!isVirtual.isUndefined())
+ {
+ index->isVirtual = isVirtual.toBool(false);
+ }
+
+ QJsonValue objects = root.value("objects");
+ QVariantMap map = objects.toVariant().toMap();
+
+ for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
+ {
+ // qDebug() << iter.key();
+
+ QVariant variant = iter.value();
+ QVariantMap nested_objects = variant.toMap();
+
+ AssetObject object;
+
+ for (QVariantMap::const_iterator nested_iter = nested_objects.begin();
+ nested_iter != nested_objects.end(); ++nested_iter)
+ {
+ // qDebug() << nested_iter.key() << nested_iter.value().toString();
+ QString key = nested_iter.key();
+ QVariant value = nested_iter.value();
+
+ if (key == "hash")
+ {
+ object.hash = value.toString();
+ }
+ else if (key == "size")
+ {
+ object.size = value.toDouble();
+ }
+ }
+
+ index->objects.insert(iter.key(), object);
+ }
+
+ return true;
}
QDir reconstructAssets(QString assetsId)
{
- QDir assetsDir = QDir("assets/");
- QDir indexDir = QDir(FS::PathCombine(assetsDir.path(), "indexes"));
- QDir objectDir = QDir(FS::PathCombine(assetsDir.path(), "objects"));
- QDir virtualDir = QDir(FS::PathCombine(assetsDir.path(), "virtual"));
-
- QString indexPath = FS::PathCombine(indexDir.path(), assetsId + ".json");
- QFile indexFile(indexPath);
- QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId));
-
- if (!indexFile.exists())
- {
- qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets";
- return virtualRoot;
- }
-
- qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path()
- << objectDir.path() << virtualDir.path() << virtualRoot.path();
-
- AssetsIndex index;
- bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, &index);
-
- if (loadAssetsIndex && index.isVirtual)
- {
- qDebug() << "Reconstructing virtual assets folder at" << virtualRoot.path();
-
- for (QString map : index.objects.keys())
- {
- AssetObject asset_object = index.objects.value(map);
- QString target_path = FS::PathCombine(virtualRoot.path(), map);
- QFile target(target_path);
-
- QString tlk = asset_object.hash.left(2);
-
- QString original_path = FS::PathCombine(objectDir.path(), tlk, asset_object.hash);
- QFile original(original_path);
- if (!original.exists())
- continue;
- if (!target.exists())
- {
- QFileInfo info(target_path);
- QDir target_dir = info.dir();
- // qDebug() << target_dir;
- if (!target_dir.exists())
- QDir("").mkpath(target_dir.path());
-
- bool couldCopy = original.copy(target_path);
- qDebug() << " Copying" << original_path << "to" << target_path
- << QString::number(couldCopy); // << original.errorString();
- }
- }
-
- // TODO: Write last used time to virtualRoot/.lastused
- }
-
- return virtualRoot;
+ QDir assetsDir = QDir("assets/");
+ QDir indexDir = QDir(FS::PathCombine(assetsDir.path(), "indexes"));
+ QDir objectDir = QDir(FS::PathCombine(assetsDir.path(), "objects"));
+ QDir virtualDir = QDir(FS::PathCombine(assetsDir.path(), "virtual"));
+
+ QString indexPath = FS::PathCombine(indexDir.path(), assetsId + ".json");
+ QFile indexFile(indexPath);
+ QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId));
+
+ if (!indexFile.exists())
+ {
+ qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets";
+ return virtualRoot;
+ }
+
+ qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path()
+ << objectDir.path() << virtualDir.path() << virtualRoot.path();
+
+ AssetsIndex index;
+ bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, &index);
+
+ if (loadAssetsIndex && index.isVirtual)
+ {
+ qDebug() << "Reconstructing virtual assets folder at" << virtualRoot.path();
+
+ for (QString map : index.objects.keys())
+ {
+ AssetObject asset_object = index.objects.value(map);
+ QString target_path = FS::PathCombine(virtualRoot.path(), map);
+ QFile target(target_path);
+
+ QString tlk = asset_object.hash.left(2);
+
+ QString original_path = FS::PathCombine(objectDir.path(), tlk, asset_object.hash);
+ QFile original(original_path);
+ if (!original.exists())
+ continue;
+ if (!target.exists())
+ {
+ QFileInfo info(target_path);
+ QDir target_dir = info.dir();
+ // qDebug() << target_dir;
+ if (!target_dir.exists())
+ QDir("").mkpath(target_dir.path());
+
+ bool couldCopy = original.copy(target_path);
+ qDebug() << " Copying" << original_path << "to" << target_path
+ << QString::number(couldCopy); // << original.errorString();
+ }
+ }
+
+ // TODO: Write last used time to virtualRoot/.lastused
+ }
+
+ return virtualRoot;
}
}
NetActionPtr AssetObject::getDownloadAction()
{
- QFileInfo objectFile(getLocalPath());
- if ((!objectFile.isFile()) || (objectFile.size() != size))
- {
- auto objectDL = Net::Download::makeFile(getUrl(), objectFile.filePath());
- if(hash.size())
- {
- auto rawHash = QByteArray::fromHex(hash.toLatin1());
- objectDL->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawHash));
- }
- objectDL->m_total_progress = size;
- return objectDL;
- }
- return nullptr;
+ QFileInfo objectFile(getLocalPath());
+ if ((!objectFile.isFile()) || (objectFile.size() != size))
+ {
+ auto objectDL = Net::Download::makeFile(getUrl(), objectFile.filePath());
+ if(hash.size())
+ {
+ auto rawHash = QByteArray::fromHex(hash.toLatin1());
+ objectDL->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawHash));
+ }
+ objectDL->m_total_progress = size;
+ return objectDL;
+ }
+ return nullptr;
}
QString AssetObject::getLocalPath()
{
- return "assets/objects/" + getRelPath();
+ return "assets/objects/" + getRelPath();
}
QUrl AssetObject::getUrl()
{
- return QUrl("http://resources.download.minecraft.net/" + getRelPath());
+ return QUrl("http://resources.download.minecraft.net/" + getRelPath());
}
QString AssetObject::getRelPath()
{
- return hash.left(2) + "/" + hash;
+ return hash.left(2) + "/" + hash;
}
NetJobPtr AssetsIndex::getDownloadJob()
{
- auto job = new NetJob(QObject::tr("Assets for %1").arg(id));
- for (auto &object : objects.values())
- {
- auto dl = object.getDownloadAction();
- if(dl)
- {
- job->addNetAction(dl);
- }
- }
- if(job->size())
- return job;
- return nullptr;
+ auto job = new NetJob(QObject::tr("Assets for %1").arg(id));
+ for (auto &object : objects.values())
+ {
+ auto dl = object.getDownloadAction();
+ if(dl)
+ {
+ job->addNetAction(dl);
+ }
+ }
+ if(job->size())
+ return job;
+ return nullptr;
}
diff --git a/api/logic/minecraft/AssetsUtils.h b/api/logic/minecraft/AssetsUtils.h
index b7ea9cc1..063c1237 100644
--- a/api/logic/minecraft/AssetsUtils.h
+++ b/api/logic/minecraft/AssetsUtils.h
@@ -22,22 +22,22 @@
struct AssetObject
{
- QString getRelPath();
- QUrl getUrl();
- QString getLocalPath();
- NetActionPtr getDownloadAction();
+ QString getRelPath();
+ QUrl getUrl();
+ QString getLocalPath();
+ NetActionPtr getDownloadAction();
- QString hash;
- qint64 size;
+ QString hash;
+ qint64 size;
};
struct AssetsIndex
{
- NetJobPtr getDownloadJob();
+ NetJobPtr getDownloadJob();
- QString id;
- QMap<QString, AssetObject> objects;
- bool isVirtual = false;
+ QString id;
+ QMap<QString, AssetObject> objects;
+ bool isVirtual = false;
};
namespace AssetsUtils
diff --git a/api/logic/minecraft/Component.cpp b/api/logic/minecraft/Component.cpp
index 7c52271e..51957d17 100644
--- a/api/logic/minecraft/Component.cpp
+++ b/api/logic/minecraft/Component.cpp
@@ -13,356 +13,356 @@
Component::Component(ComponentList * parent, const QString& uid)
{
- assert(parent);
- m_parent = parent;
+ assert(parent);
+ m_parent = parent;
- m_uid = uid;
+ m_uid = uid;
}
Component::Component(ComponentList * parent, std::shared_ptr<Meta::Version> version)
{
- assert(parent);
- m_parent = parent;
+ assert(parent);
+ m_parent = parent;
- m_metaVersion = version;
- m_uid = version->uid();
- m_version = m_cachedVersion = version->version();
- m_cachedName = version->name();
- m_loaded = version->isLoaded();
+ m_metaVersion = version;
+ m_uid = version->uid();
+ m_version = m_cachedVersion = version->version();
+ m_cachedName = version->name();
+ m_loaded = version->isLoaded();
}
Component::Component(ComponentList * parent, const QString& uid, std::shared_ptr<VersionFile> file)
{
- assert(parent);
- m_parent = parent;
+ assert(parent);
+ m_parent = parent;
- m_file = file;
- m_uid = uid;
- m_cachedVersion = m_file->version;
- m_cachedName = m_file->name;
- m_loaded = true;
+ m_file = file;
+ m_uid = uid;
+ m_cachedVersion = m_file->version;
+ m_cachedName = m_file->name;
+ m_loaded = true;
}
std::shared_ptr<Meta::Version> Component::getMeta()
{
- return m_metaVersion;
+ return m_metaVersion;
}
void Component::applyTo(LaunchProfile* profile)
{
- // do not apply disabled components
- if(!isEnabled())
- {
- return;
- }
- auto vfile = getVersionFile();
- if(vfile)
- {
- vfile->applyTo(profile);
- }
- else
- {
- profile->applyProblemSeverity(getProblemSeverity());
- }
+ // do not apply disabled components
+ if(!isEnabled())
+ {
+ return;
+ }
+ auto vfile = getVersionFile();
+ if(vfile)
+ {
+ vfile->applyTo(profile);
+ }
+ else
+ {
+ profile->applyProblemSeverity(getProblemSeverity());
+ }
}
std::shared_ptr<class VersionFile> Component::getVersionFile() const
{
- if(m_metaVersion)
- {
- if(!m_metaVersion->isLoaded())
- {
- m_metaVersion->load(Net::Mode::Online);
- }
- return m_metaVersion->data();
- }
- else
- {
- return m_file;
- }
+ if(m_metaVersion)
+ {
+ if(!m_metaVersion->isLoaded())
+ {
+ m_metaVersion->load(Net::Mode::Online);
+ }
+ return m_metaVersion->data();
+ }
+ else
+ {
+ return m_file;
+ }
}
std::shared_ptr<class Meta::VersionList> Component::getVersionList() const
{
- // FIXME: what if the metadata index isn't loaded yet?
- if(ENV.metadataIndex()->hasUid(m_uid))
- {
- return ENV.metadataIndex()->get(m_uid);
- }
- return nullptr;
+ // FIXME: what if the metadata index isn't loaded yet?
+ if(ENV.metadataIndex()->hasUid(m_uid))
+ {
+ return ENV.metadataIndex()->get(m_uid);
+ }
+ return nullptr;
}
int Component::getOrder()
{
- if(m_orderOverride)
- return m_order;
+ if(m_orderOverride)
+ return m_order;
- auto vfile = getVersionFile();
- if(vfile)
- {
- return vfile->order;
- }
- return 0;
+ auto vfile = getVersionFile();
+ if(vfile)
+ {
+ return vfile->order;
+ }
+ return 0;
}
void Component::setOrder(int order)
{
- m_orderOverride = true;
- m_order = order;
+ m_orderOverride = true;
+ m_order = order;
}
QString Component::getID()
{
- return m_uid;
+ return m_uid;
}
QString Component::getName()
{
- if (!m_cachedName.isEmpty())
- return m_cachedName;
- return m_uid;
+ if (!m_cachedName.isEmpty())
+ return m_cachedName;
+ return m_uid;
}
QString Component::getVersion()
{
- return m_cachedVersion;
+ return m_cachedVersion;
}
QString Component::getFilename()
{
- return m_parent->patchFilePathForUid(m_uid);
+ return m_parent->patchFilePathForUid(m_uid);
}
QDateTime Component::getReleaseDateTime()
{
- if(m_metaVersion)
- {
- return m_metaVersion->time();
- }
- auto vfile = getVersionFile();
- if(vfile)
- {
- return vfile->releaseTime;
- }
- // FIXME: fake
- return QDateTime::currentDateTime();
+ if(m_metaVersion)
+ {
+ return m_metaVersion->time();
+ }
+ auto vfile = getVersionFile();
+ if(vfile)
+ {
+ return vfile->releaseTime;
+ }
+ // FIXME: fake
+ return QDateTime::currentDateTime();
}
bool Component::isEnabled()
{
- return !canBeDisabled() || !m_disabled;
+ return !canBeDisabled() || !m_disabled;
}
bool Component::canBeDisabled()
{
- return isRemovable() && !m_dependencyOnly;
+ return isRemovable() && !m_dependencyOnly;
}
bool Component::setEnabled(bool state)
{
- bool intendedDisabled = !state;
- if (!canBeDisabled())
- {
- intendedDisabled = false;
- }
- if(intendedDisabled != m_disabled)
- {
- m_disabled = intendedDisabled;
- emit dataChanged();
- return true;
- }
- return false;
+ bool intendedDisabled = !state;
+ if (!canBeDisabled())
+ {
+ intendedDisabled = false;
+ }
+ if(intendedDisabled != m_disabled)
+ {
+ m_disabled = intendedDisabled;
+ emit dataChanged();
+ return true;
+ }
+ return false;
}
bool Component::isCustom()
{
- return m_file != nullptr;
+ return m_file != nullptr;
}
bool Component::isCustomizable()
{
- if(m_metaVersion)
- {
- if(getVersionFile())
- {
- return true;
- }
- }
- return false;
+ if(m_metaVersion)
+ {
+ if(getVersionFile())
+ {
+ return true;
+ }
+ }
+ return false;
}
bool Component::isRemovable()
{
- return !m_important;
+ return !m_important;
}
bool Component::isRevertible()
{
- if (isCustom())
- {
- if(ENV.metadataIndex()->hasUid(m_uid))
- {
- return true;
- }
- }
- return false;
+ if (isCustom())
+ {
+ if(ENV.metadataIndex()->hasUid(m_uid))
+ {
+ return true;
+ }
+ }
+ return false;
}
bool Component::isMoveable()
{
- // HACK, FIXME: this was too dumb and wouldn't follow dependency constraints anyway. For now hardcoded to 'true'.
- return true;
+ // HACK, FIXME: this was too dumb and wouldn't follow dependency constraints anyway. For now hardcoded to 'true'.
+ return true;
}
bool Component::isVersionChangeable()
{
- auto list = getVersionList();
- if(list)
- {
- if(!list->isLoaded())
- {
- list->load(Net::Mode::Online);
- }
- return list->count() != 0;
- }
- return false;
+ auto list = getVersionList();
+ if(list)
+ {
+ if(!list->isLoaded())
+ {
+ list->load(Net::Mode::Online);
+ }
+ return list->count() != 0;
+ }
+ return false;
}
void Component::setImportant(bool state)
{
- if(m_important != state)
- {
- m_important = state;
- emit dataChanged();
- }
+ if(m_important != state)
+ {
+ m_important = state;
+ emit dataChanged();
+ }
}
ProblemSeverity Component::getProblemSeverity() const
{
- auto file = getVersionFile();
- if(file)
- {
- return file->getProblemSeverity();
- }
- return ProblemSeverity::Error;
+ auto file = getVersionFile();
+ if(file)
+ {
+ return file->getProblemSeverity();
+ }
+ return ProblemSeverity::Error;
}
const QList<PatchProblem> Component::getProblems() const
{
- auto file = getVersionFile();
- if(file)
- {
- return file->getProblems();
- }
- return {{ProblemSeverity::Error, QObject::tr("Patch is not loaded yet.")}};
+ auto file = getVersionFile();
+ if(file)
+ {
+ return file->getProblems();
+ }
+ return {{ProblemSeverity::Error, QObject::tr("Patch is not loaded yet.")}};
}
void Component::setVersion(const QString& version)
{
- if(version == m_version)
- {
- return;
- }
- m_version = version;
- if(m_loaded)
- {
- // we are loaded and potentially have state to invalidate
- if(m_file)
- {
- // we have a file... explicit version has been changed and there is nothing else to do.
- }
- else
- {
- // we don't have a file, therefore we are loaded with metadata
- m_cachedVersion = version;
- // see if the meta version is loaded
- auto metaVersion = ENV.metadataIndex()->get(m_uid, version);
- if(metaVersion->isLoaded())
- {
- // if yes, we can continue with that.
- m_metaVersion = metaVersion;
- }
- else
- {
- // if not, we need loading
- m_metaVersion.reset();
- m_loaded = false;
- }
- updateCachedData();
- }
- }
- else
- {
- // not loaded... assume it will be sorted out later by the update task
- }
- emit dataChanged();
+ if(version == m_version)
+ {
+ return;
+ }
+ m_version = version;
+ if(m_loaded)
+ {
+ // we are loaded and potentially have state to invalidate
+ if(m_file)
+ {
+ // we have a file... explicit version has been changed and there is nothing else to do.
+ }
+ else
+ {
+ // we don't have a file, therefore we are loaded with metadata
+ m_cachedVersion = version;
+ // see if the meta version is loaded
+ auto metaVersion = ENV.metadataIndex()->get(m_uid, version);
+ if(metaVersion->isLoaded())
+ {
+ // if yes, we can continue with that.
+ m_metaVersion = metaVersion;
+ }
+ else
+ {
+ // if not, we need loading
+ m_metaVersion.reset();
+ m_loaded = false;
+ }
+ updateCachedData();
+ }
+ }
+ else
+ {
+ // not loaded... assume it will be sorted out later by the update task
+ }
+ emit dataChanged();
}
bool Component::customize()
{
- if(isCustom())
- {
- return false;
- }
+ if(isCustom())
+ {
+ return false;
+ }
- auto filename = getFilename();
- if(!FS::ensureFilePathExists(filename))
- {
- return false;
- }
- // FIXME: get rid of this try-catch.
- try
- {
- QSaveFile jsonFile(filename);
- if(!jsonFile.open(QIODevice::WriteOnly))
- {
- return false;
- }
- auto vfile = getVersionFile();
- if(!vfile)
- {
- return false;
- }
- auto document = OneSixVersionFormat::versionFileToJson(vfile);
- jsonFile.write(document.toJson());
- if(!jsonFile.commit())
- {
- return false;
- }
- m_file = vfile;
- m_metaVersion.reset();
- emit dataChanged();
- }
- catch (const Exception &error)
- {
- qWarning() << "Version could not be loaded:" << error.cause();
- }
- return true;
+ auto filename = getFilename();
+ if(!FS::ensureFilePathExists(filename))
+ {
+ return false;
+ }
+ // FIXME: get rid of this try-catch.
+ try
+ {
+ QSaveFile jsonFile(filename);
+ if(!jsonFile.open(QIODevice::WriteOnly))
+ {
+ return false;
+ }
+ auto vfile = getVersionFile();
+ if(!vfile)
+ {
+ return false;
+ }
+ auto document = OneSixVersionFormat::versionFileToJson(vfile);
+ jsonFile.write(document.toJson());
+ if(!jsonFile.commit())
+ {
+ return false;
+ }
+ m_file = vfile;
+ m_metaVersion.reset();
+ emit dataChanged();
+ }
+ catch (const Exception &error)
+ {
+ qWarning() << "Version could not be loaded:" << error.cause();
+ }
+ return true;
}
bool Component::revert()
{
- if(!isCustom())
- {
- // already not custom
- return true;
- }
- auto filename = getFilename();
- bool result = true;
- // just kill the file and reload
- if(QFile::exists(filename))
- {
- result = QFile::remove(filename);
- }
- if(result)
- {
- // file gone...
- m_file.reset();
+ if(!isCustom())
+ {
+ // already not custom
+ return true;
+ }
+ auto filename = getFilename();
+ bool result = true;
+ // just kill the file and reload
+ if(QFile::exists(filename))
+ {
+ result = QFile::remove(filename);
+ }
+ if(result)
+ {
+ // file gone...
+ m_file.reset();
- // check local cache for metadata...
- auto version = ENV.metadataIndex()->get(m_uid, m_version);
- if(version->isLoaded())
- {
- m_metaVersion = version;
- }
- else
- {
- m_metaVersion.reset();
- m_loaded = false;
- }
- emit dataChanged();
- }
- return result;
+ // check local cache for metadata...
+ auto version = ENV.metadataIndex()->get(m_uid, m_version);
+ if(version->isLoaded())
+ {
+ m_metaVersion = version;
+ }
+ else
+ {
+ m_metaVersion.reset();
+ m_loaded = false;
+ }
+ emit dataChanged();
+ }
+ return result;
}
/**
@@ -372,68 +372,68 @@ bool Component::revert()
*/
static bool deepCompare(const std::set<Meta::Require> & a, const std::set<Meta::Require> & b)
{
- // NOTE: this needs to be rewritten if the type of Meta::RequireSet changes
- if(a.size() != b.size())
- {
- return false;
- }
- for(const auto & reqA :a)
- {
- const auto &iter2 = b.find(reqA);
- if(iter2 == b.cend())
- {
- return false;
- }
- const auto & reqB = *iter2;
- if(!reqA.deepEquals(reqB))
- {
- return false;
- }
- }
- return true;
+ // NOTE: this needs to be rewritten if the type of Meta::RequireSet changes
+ if(a.size() != b.size())
+ {
+ return false;
+ }
+ for(const auto & reqA :a)
+ {
+ const auto &iter2 = b.find(reqA);
+ if(iter2 == b.cend())
+ {
+ return false;
+ }
+ const auto & reqB = *iter2;
+ if(!reqA.deepEquals(reqB))
+ {
+ return false;
+ }
+ }
+ return true;
}
void Component::updateCachedData()
{
- auto file = getVersionFile();
- if(file)
- {
- bool changed = false;
- if(m_cachedName != file->name)
- {
- m_cachedName = file->name;
- changed = true;
- }
- if(m_cachedVersion != file->version)
- {
- m_cachedVersion = file->version;
- changed = true;
- }
- if(m_cachedVolatile != file->m_volatile)
- {
- m_cachedVolatile = file->m_volatile;
- changed = true;
- }
- if(!deepCompare(m_cachedRequires, file->requires))
- {
- m_cachedRequires = file->requires;
- changed = true;
- }
- if(!deepCompare(m_cachedConflicts, file->conflicts))
- {
- m_cachedConflicts = file->conflicts;
- changed = true;
- }
- if(changed)
- {
- emit dataChanged();
- }
- }
- else
- {
- // in case we removed all the metadata
- m_cachedRequires.clear();
- m_cachedConflicts.clear();
- emit dataChanged();
- }
+ auto file = getVersionFile();
+ if(file)
+ {
+ bool changed = false;
+ if(m_cachedName != file->name)
+ {
+ m_cachedName = file->name;
+ changed = true;
+ }
+ if(m_cachedVersion != file->version)
+ {
+ m_cachedVersion = file->version;
+ changed = true;
+ }
+ if(m_cachedVolatile != file->m_volatile)
+ {
+ m_cachedVolatile = file->m_volatile;
+ changed = true;
+ }
+ if(!deepCompare(m_cachedRequires, file->requires))
+ {
+ m_cachedRequires = file->requires;
+ changed = true;
+ }
+ if(!deepCompare(m_cachedConflicts, file->conflicts))
+ {
+ m_cachedConflicts = file->conflicts;
+ changed = true;
+ }
+ if(changed)
+ {
+ emit dataChanged();
+ }
+ }
+ else
+ {
+ // in case we removed all the metadata
+ m_cachedRequires.clear();
+ m_cachedConflicts.clear();
+ emit dataChanged();
+ }
}
diff --git a/api/logic/minecraft/Component.h b/api/logic/minecraft/Component.h
index 778fbb18..6a0f86c8 100644
--- a/api/logic/minecraft/Component.h
+++ b/api/logic/minecraft/Component.h
@@ -13,8 +13,8 @@ class ComponentList;
class LaunchProfile;
namespace Meta
{
- class Version;
- class VersionList;
+ class Version;
+ class VersionList;
}
class VersionFile;
@@ -22,90 +22,90 @@ class MULTIMC_LOGIC_EXPORT Component : public QObject, public ProblemProvider
{
Q_OBJECT
public:
- Component(ComponentList * parent, const QString &uid);
+ Component(ComponentList * parent, const QString &uid);
- // DEPRECATED: remove these constructors?
- Component(ComponentList * parent, std::shared_ptr<Meta::Version> version);
- Component(ComponentList * parent, const QString & uid, std::shared_ptr<VersionFile> file);
+ // DEPRECATED: remove these constructors?
+ Component(ComponentList * parent, std::shared_ptr<Meta::Version> version);
+ Component(ComponentList * parent, const QString & uid, std::shared_ptr<VersionFile> file);
- virtual ~Component(){};
- void applyTo(LaunchProfile *profile);
+ virtual ~Component(){};
+ void applyTo(LaunchProfile *profile);
- bool isEnabled();
- bool setEnabled (bool state);
- bool canBeDisabled();
+ bool isEnabled();
+ bool setEnabled (bool state);
+ bool canBeDisabled();
- bool isMoveable();
- bool isCustomizable();
- bool isRevertible();
- bool isRemovable();
- bool isCustom();
- bool isVersionChangeable();
+ bool isMoveable();
+ bool isCustomizable();
+ bool isRevertible();
+ bool isRemovable();
+ bool isCustom();
+ bool isVersionChangeable();
- // DEPRECATED: explicit numeric order values, used for loading old non-component config. TODO: refactor and move to migration code
- void setOrder(int order);
- int getOrder();
+ // DEPRECATED: explicit numeric order values, used for loading old non-component config. TODO: refactor and move to migration code
+ void setOrder(int order);
+ int getOrder();
- QString getID();
- QString getName();
- QString getVersion();
- std::shared_ptr<Meta::Version> getMeta();
- QDateTime getReleaseDateTime();
+ QString getID();
+ QString getName();
+ QString getVersion();
+ std::shared_ptr<Meta::Version> getMeta();
+ QDateTime getReleaseDateTime();
- QString getFilename();
+ QString getFilename();
- std::shared_ptr<class VersionFile> getVersionFile() const;
- std::shared_ptr<class Meta::VersionList> getVersionList() const;
+ std::shared_ptr<class VersionFile> getVersionFile() const;
+ std::shared_ptr<class Meta::VersionList> getVersionList() const;
- void setImportant (bool state);
+ void setImportant (bool state);
- const QList<PatchProblem> getProblems() const override;
- ProblemSeverity getProblemSeverity() const override;
+ const QList<PatchProblem> getProblems() const override;
+ ProblemSeverity getProblemSeverity() const override;
- void setVersion(const QString & version);
- bool customize();
- bool revert();
+ void setVersion(const QString & version);
+ bool customize();
+ bool revert();
- void updateCachedData();
+ void updateCachedData();
signals:
- void dataChanged();
+ void dataChanged();
public: /* data */
- ComponentList * m_parent;
-
- // BEGIN: persistent component list properties
- /// ID of the component
- QString m_uid;
- /// version of the component - when there's a custom json override, this is also the version the component reverts to
- QString m_version;
- /// if true, this has been added automatically to satisfy dependencies and may be automatically removed
- bool m_dependencyOnly = false;
- /// if true, the component is either the main component of the instance, or otherwise important and cannot be removed.
- bool m_important = false;
- /// if true, the component is disabled
- bool m_disabled = false;
-
- /// cached name for display purposes, taken from the version file (meta or local override)
- QString m_cachedName;
- /// cached version for display AND other purposes, taken from the version file (meta or local override)
- QString m_cachedVersion;
- /// cached set of requirements, taken from the version file (meta or local override)
- Meta::RequireSet m_cachedRequires;
- Meta::RequireSet m_cachedConflicts;
- /// if true, the component is volatile and may be automatically removed when no longer needed
- bool m_cachedVolatile = false;
- // END: persistent component list properties
-
- // DEPRECATED: explicit numeric order values, used for loading old non-component config. TODO: refactor and move to migration code
- bool m_orderOverride = false;
- int m_order = 0;
-
- // load state
- std::shared_ptr<Meta::Version> m_metaVersion;
- std::shared_ptr<VersionFile> m_file;
- bool m_loaded = false;
+ ComponentList * m_parent;
+
+ // BEGIN: persistent component list properties
+ /// ID of the component
+ QString m_uid;
+ /// version of the component - when there's a custom json override, this is also the version the component reverts to
+ QString m_version;
+ /// if true, this has been added automatically to satisfy dependencies and may be automatically removed
+ bool m_dependencyOnly = false;
+ /// if true, the component is either the main component of the instance, or otherwise important and cannot be removed.
+ bool m_important = false;
+ /// if true, the component is disabled
+ bool m_disabled = false;
+
+ /// cached name for display purposes, taken from the version file (meta or local override)
+ QString m_cachedName;
+ /// cached version for display AND other purposes, taken from the version file (meta or local override)
+ QString m_cachedVersion;
+ /// cached set of requirements, taken from the version file (meta or local override)
+ Meta::RequireSet m_cachedRequires;
+ Meta::RequireSet m_cachedConflicts;
+ /// if true, the component is volatile and may be automatically removed when no longer needed
+ bool m_cachedVolatile = false;
+ // END: persistent component list properties
+
+ // DEPRECATED: explicit numeric order values, used for loading old non-component config. TODO: refactor and move to migration code
+ bool m_orderOverride = false;
+ int m_order = 0;
+
+ // load state
+ std::shared_ptr<Meta::Version> m_metaVersion;
+ std::shared_ptr<VersionFile> m_file;
+ bool m_loaded = false;
};
typedef shared_qobject_ptr<Component> ComponentPtr;
diff --git a/api/logic/minecraft/ComponentList.cpp b/api/logic/minecraft/ComponentList.cpp
index e373d499..7a865c60 100644
--- a/api/logic/minecraft/ComponentList.cpp
+++ b/api/logic/minecraft/ComponentList.cpp
@@ -37,18 +37,18 @@
#include "ComponentUpdateTask.h"
ComponentList::ComponentList(MinecraftInstance * instance)
- : QAbstractListModel()
+ : QAbstractListModel()
{
- d.reset(new ComponentListData);
- d->m_instance = instance;
- d->m_saveTimer.setSingleShot(true);
- d->m_saveTimer.setInterval(5000);
- connect(&d->m_saveTimer, &QTimer::timeout, this, &ComponentList::save_internal);
+ d.reset(new ComponentListData);
+ d->m_instance = instance;
+ d->m_saveTimer.setSingleShot(true);
+ d->m_saveTimer.setInterval(5000);
+ connect(&d->m_saveTimer, &QTimer::timeout, this, &ComponentList::save_internal);
}
ComponentList::~ComponentList()
{
- saveNow();
+ saveNow();
}
// BEGIN: component file format
@@ -57,151 +57,151 @@ static const int currentComponentsFileVersion = 1;
static QJsonObject componentToJsonV1(ComponentPtr component)
{
- QJsonObject obj;
- // critical
- obj.insert("uid", component->m_uid);
- if(!component->m_version.isEmpty())
- {
- obj.insert("version", component->m_version);
- }
- if(component->m_dependencyOnly)
- {
- obj.insert("dependencyOnly", true);
- }
- if(component->m_important)
- {
- obj.insert("important", true);
- }
- if(component->m_disabled)
- {
- obj.insert("disabled", true);
- }
-
- // cached
- if(!component->m_cachedVersion.isEmpty())
- {
- obj.insert("cachedVersion", component->m_cachedVersion);
- }
- if(!component->m_cachedName.isEmpty())
- {
- obj.insert("cachedName", component->m_cachedName);
- }
- Meta::serializeRequires(obj, &component->m_cachedRequires, "cachedRequires");
- Meta::serializeRequires(obj, &component->m_cachedConflicts, "cachedConflicts");
- if(component->m_cachedVolatile)
- {
- obj.insert("cachedVolatile", true);
- }
- return obj;
+ QJsonObject obj;
+ // critical
+ obj.insert("uid", component->m_uid);
+ if(!component->m_version.isEmpty())
+ {
+ obj.insert("version", component->m_version);
+ }
+ if(component->m_dependencyOnly)
+ {
+ obj.insert("dependencyOnly", true);
+ }
+ if(component->m_important)
+ {
+ obj.insert("important", true);
+ }
+ if(component->m_disabled)
+ {
+ obj.insert("disabled", true);
+ }
+
+ // cached
+ if(!component->m_cachedVersion.isEmpty())
+ {
+ obj.insert("cachedVersion", component->m_cachedVersion);
+ }
+ if(!component->m_cachedName.isEmpty())
+ {
+ obj.insert("cachedName", component->m_cachedName);
+ }
+ Meta::serializeRequires(obj, &component->m_cachedRequires, "cachedRequires");
+ Meta::serializeRequires(obj, &component->m_cachedConflicts, "cachedConflicts");
+ if(component->m_cachedVolatile)
+ {
+ obj.insert("cachedVolatile", true);
+ }
+ return obj;
}
static ComponentPtr componentFromJsonV1(ComponentList * parent, const QString & componentJsonPattern, const QJsonObject &obj)
{
- // critical
- auto uid = Json::requireString(obj.value("uid"));
- auto filePath = componentJsonPattern.arg(uid);
- auto component = new Component(parent, uid);
- component->m_version = Json::ensureString(obj.value("version"));
- component->m_dependencyOnly = Json::ensureBoolean(obj.value("dependencyOnly"), false);
- component->m_important = Json::ensureBoolean(obj.value("important"), false);
-
- // cached
- // TODO @RESILIENCE: ignore invalid values/structure here?
- component->m_cachedVersion = Json::ensureString(obj.value("cachedVersion"));
- component->m_cachedName = Json::ensureString(obj.value("cachedName"));
- Meta::parseRequires(obj, &component->m_cachedRequires, "cachedRequires");
- Meta::parseRequires(obj, &component->m_cachedConflicts, "cachedConflicts");
- component->m_cachedVolatile = Json::ensureBoolean(obj.value("volatile"), false);
- bool disabled = Json::ensureBoolean(obj.value("disabled"), false);
- component->setEnabled(!disabled);
- return component;
+ // critical
+ auto uid = Json::requireString(obj.value("uid"));
+ auto filePath = componentJsonPattern.arg(uid);
+ auto component = new Component(parent, uid);
+ component->m_version = Json::ensureString(obj.value("version"));
+ component->m_dependencyOnly = Json::ensureBoolean(obj.value("dependencyOnly"), false);
+ component->m_important = Json::ensureBoolean(obj.value("important"), false);
+
+ // cached
+ // TODO @RESILIENCE: ignore invalid values/structure here?
+ component->m_cachedVersion = Json::ensureString(obj.value("cachedVersion"));
+ component->m_cachedName = Json::ensureString(obj.value("cachedName"));
+ Meta::parseRequires(obj, &component->m_cachedRequires, "cachedRequires");
+ Meta::parseRequires(obj, &component->m_cachedConflicts, "cachedConflicts");
+ component->m_cachedVolatile = Json::ensureBoolean(obj.value("volatile"), false);
+ bool disabled = Json::ensureBoolean(obj.value("disabled"), false);
+ component->setEnabled(!disabled);
+ return component;
}
// Save the given component container data to a file
static bool saveComponentList(const QString & filename, const ComponentContainer & container)
{
- QJsonObject obj;
- obj.insert("formatVersion", currentComponentsFileVersion);
- QJsonArray orderArray;
- for(auto component: container)
- {
- orderArray.append(componentToJsonV1(component));
- }
- obj.insert("components", orderArray);
- QSaveFile outFile(filename);
- if (!outFile.open(QFile::WriteOnly))
- {
- qCritical() << "Couldn't open" << outFile.fileName()
- << "for writing:" << outFile.errorString();
- return false;
- }
- auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented);
- if(outFile.write(data) != data.size())
- {
- qCritical() << "Couldn't write all the data into" << outFile.fileName()
- << "because:" << outFile.errorString();
- return false;
- }
- if(!outFile.commit())
- {
- qCritical() << "Couldn't save" << outFile.fileName()
- << "because:" << outFile.errorString();
- }
- return true;
+ QJsonObject obj;
+ obj.insert("formatVersion", currentComponentsFileVersion);
+ QJsonArray orderArray;
+ for(auto component: container)
+ {
+ orderArray.append(componentToJsonV1(component));
+ }
+ obj.insert("components", orderArray);
+ QSaveFile outFile(filename);
+ if (!outFile.open(QFile::WriteOnly))
+ {
+ qCritical() << "Couldn't open" << outFile.fileName()
+ << "for writing:" << outFile.errorString();
+ return false;
+ }
+ auto data = QJsonDocument(obj).toJson(QJsonDocument::Indented);
+ if(outFile.write(data) != data.size())
+ {
+ qCritical() << "Couldn't write all the data into" << outFile.fileName()
+ << "because:" << outFile.errorString();
+ return false;
+ }
+ if(!outFile.commit())
+ {
+ qCritical() << "Couldn't save" << outFile.fileName()
+ << "because:" << outFile.errorString();
+ }
+ return true;
}
// Read the given file into component containers
static bool loadComponentList(ComponentList * parent, const QString & filename, const QString & componentJsonPattern, ComponentContainer & container)
{
- QFile componentsFile(filename);
- if (!componentsFile.exists())
- {
- qWarning() << "Components file doesn't exist. This should never happen.";
- return false;
- }
- if (!componentsFile.open(QFile::ReadOnly))
- {
- qCritical() << "Couldn't open" << componentsFile.fileName()
- << " for reading:" << componentsFile.errorString();
- qWarning() << "Ignoring overriden order";
- return false;
- }
-
- // and it's valid JSON
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(componentsFile.readAll(), &error);
- if (error.error != QJsonParseError::NoError)
- {
- qCritical() << "Couldn't parse" << componentsFile.fileName() << ":" << error.errorString();
- qWarning() << "Ignoring overriden order";
- return false;
- }
-
- // and then read it and process it if all above is true.
- try
- {
- auto obj = Json::requireObject(doc);
- // check order file version.
- auto version = Json::requireInteger(obj.value("formatVersion"));
- if (version != currentComponentsFileVersion)
- {
- throw JSONValidationError(QObject::tr("Invalid component file version, expected %1")
- .arg(currentComponentsFileVersion));
- }
- auto orderArray = Json::requireArray(obj.value("components"));
- for(auto item: orderArray)
- {
- auto obj = Json::requireObject(item, "Component must be an object.");
- container.append(componentFromJsonV1(parent, componentJsonPattern, obj));
- }
- }
- catch (const JSONValidationError &err)
- {
- qCritical() << "Couldn't parse" << componentsFile.fileName() << ": bad file format";
- container.clear();
- return false;
- }
- return true;
+ QFile componentsFile(filename);
+ if (!componentsFile.exists())
+ {
+ qWarning() << "Components file doesn't exist. This should never happen.";
+ return false;
+ }
+ if (!componentsFile.open(QFile::ReadOnly))
+ {
+ qCritical() << "Couldn't open" << componentsFile.fileName()
+ << " for reading:" << componentsFile.errorString();
+ qWarning() << "Ignoring overriden order";
+ return false;
+ }
+
+ // and it's valid JSON
+ QJsonParseError error;
+ QJsonDocument doc = QJsonDocument::fromJson(componentsFile.readAll(), &error);
+ if (error.error != QJsonParseError::NoError)
+ {
+ qCritical() << "Couldn't parse" << componentsFile.fileName() << ":" << error.errorString();
+ qWarning() << "Ignoring overriden order";
+ return false;
+ }
+
+ // and then read it and process it if all above is true.
+ try
+ {
+ auto obj = Json::requireObject(doc);
+ // check order file version.
+ auto version = Json::requireInteger(obj.value("formatVersion"));
+ if (version != currentComponentsFileVersion)
+ {
+ throw JSONValidationError(QObject::tr("Invalid component file version, expected %1")
+ .arg(currentComponentsFileVersion));
+ }
+ auto orderArray = Json::requireArray(obj.value("components"));
+ for(auto item: orderArray)
+ {
+ auto obj = Json::requireObject(item, "Component must be an object.");
+ container.append(componentFromJsonV1(parent, componentJsonPattern, obj));
+ }
+ }
+ catch (const JSONValidationError &err)
+ {
+ qCritical() << "Couldn't parse" << componentsFile.fileName() << ": bad file format";
+ container.clear();
+ return false;
+ }
+ return true;
}
// END: component file format
@@ -210,217 +210,217 @@ static bool loadComponentList(ComponentList * parent, const QString & filename,
void ComponentList::saveNow()
{
- if(saveIsScheduled())
- {
- d->m_saveTimer.stop();
- save_internal();
- }
+ if(saveIsScheduled())
+ {
+ d->m_saveTimer.stop();
+ save_internal();
+ }
}
bool ComponentList::saveIsScheduled() const
{
- return d->dirty;
+ return d->dirty;
}
void ComponentList::buildingFromScratch()
{
- d->loaded = true;
- d->dirty = true;
+ d->loaded = true;
+ d->dirty = true;
}
void ComponentList::scheduleSave()
{
- if(!d->loaded)
- {
- qDebug() << "Component list should never save if it didn't successfully load, instance:" << d->m_instance->name();
- return;
- }
- if(!d->dirty)
- {
- d->dirty = true;
- qDebug() << "Component list save is scheduled for" << d->m_instance->name();
- }
- d->m_saveTimer.start();
+ if(!d->loaded)
+ {
+ qDebug() << "Component list should never save if it didn't successfully load, instance:" << d->m_instance->name();
+ return;
+ }
+ if(!d->dirty)
+ {
+ d->dirty = true;
+ qDebug() << "Component list save is scheduled for" << d->m_instance->name();
+ }
+ d->m_saveTimer.start();
}
QString ComponentList::componentsFilePath() const
{
- return FS::PathCombine(d->m_instance->instanceRoot(), "mmc-pack.json");
+ return FS::PathCombine(d->m_instance->instanceRoot(), "mmc-pack.json");
}
QString ComponentList::patchesPattern() const
{
- return FS::PathCombine(d->m_instance->instanceRoot(), "patches", "%1.json");
+ return FS::PathCombine(d->m_instance->instanceRoot(), "patches", "%1.json");
}
QString ComponentList::patchFilePathForUid(const QString& uid) const
{
- return patchesPattern().arg(uid);
+ return patchesPattern().arg(uid);
}
void ComponentList::save_internal()
{
- qDebug() << "Component list save performed now for" << d->m_instance->name();
- auto filename = componentsFilePath();
- saveComponentList(filename, d->components);
- d->dirty = false;
+ qDebug() << "Component list save performed now for" << d->m_instance->name();
+ auto filename = componentsFilePath();
+ saveComponentList(filename, d->components);
+ d->dirty = false;
}
bool ComponentList::load()
{
- auto filename = componentsFilePath();
- QFile componentsFile(filename);
-
- // migrate old config to new one, if needed
- if(!componentsFile.exists())
- {
- if(!migratePreComponentConfig())
- {
- // FIXME: the user should be notified...
- qCritical() << "Failed to convert old pre-component config for instance" << d->m_instance->name();
- return false;
- }
- }
-
- // load the new component list and swap it with the current one...
- ComponentContainer newComponents;
- if(!loadComponentList(this, filename, patchesPattern(), newComponents))
- {
- qCritical() << "Failed to load the component config for instance" << d->m_instance->name();
- return false;
- }
- else
- {
- // FIXME: actually use fine-grained updates, not this...
- beginResetModel();
- // disconnect all the old components
- for(auto component: d->components)
- {
- disconnect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged);
- }
- d->components.clear();
- d->componentIndex.clear();
- for(auto component: newComponents)
- {
- if(d->componentIndex.contains(component->m_uid))
- {
- qWarning() << "Ignoring duplicate component entry" << component->m_uid;
- continue;
- }
- connect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged);
- d->components.append(component);
- d->componentIndex[component->m_uid] = component;
- }
- endResetModel();
- d->loaded = true;
- return true;
- }
+ auto filename = componentsFilePath();
+ QFile componentsFile(filename);
+
+ // migrate old config to new one, if needed
+ if(!componentsFile.exists())
+ {
+ if(!migratePreComponentConfig())
+ {
+ // FIXME: the user should be notified...
+ qCritical() << "Failed to convert old pre-component config for instance" << d->m_instance->name();
+ return false;
+ }
+ }
+
+ // load the new component list and swap it with the current one...
+ ComponentContainer newComponents;
+ if(!loadComponentList(this, filename, patchesPattern(), newComponents))
+ {
+ qCritical() << "Failed to load the component config for instance" << d->m_instance->name();
+ return false;
+ }
+ else
+ {
+ // FIXME: actually use fine-grained updates, not this...
+ beginResetModel();
+ // disconnect all the old components
+ for(auto component: d->components)
+ {
+ disconnect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged);
+ }
+ d->components.clear();
+ d->componentIndex.clear();
+ for(auto component: newComponents)
+ {
+ if(d->componentIndex.contains(component->m_uid))
+ {
+ qWarning() << "Ignoring duplicate component entry" << component->m_uid;
+ continue;
+ }
+ connect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged);
+ d->components.append(component);
+ d->componentIndex[component->m_uid] = component;
+ }
+ endResetModel();
+ d->loaded = true;
+ return true;
+ }
}
void ComponentList::reload(Net::Mode netmode)
{
- // Do not reload when the update/resolve task is running. It is in control.
- if(d->m_updateTask)
- {
- return;
- }
-
- // flush any scheduled saves to not lose state
- saveNow();
-
- // FIXME: differentiate when a reapply is required by propagating state from components
- invalidateLaunchProfile();
-
- if(load())
- {
- resolve(netmode);
- }
+ // Do not reload when the update/resolve task is running. It is in control.
+ if(d->m_updateTask)
+ {
+ return;
+ }
+
+ // flush any scheduled saves to not lose state
+ saveNow();
+
+ // FIXME: differentiate when a reapply is required by propagating state from components
+ invalidateLaunchProfile();
+
+ if(load())
+ {
+ resolve(netmode);
+ }
}
shared_qobject_ptr<Task> ComponentList::getCurrentTask()
{
- return d->m_updateTask;
+ return d->m_updateTask;
}
void ComponentList::resolve(Net::Mode netmode)
{
- auto updateTask = new ComponentUpdateTask(ComponentUpdateTask::Mode::Resolution, netmode, this);
- d->m_updateTask.reset(updateTask);
- connect(updateTask, &ComponentUpdateTask::succeeded, this, &ComponentList::updateSucceeded);
- connect(updateTask, &ComponentUpdateTask::failed, this, &ComponentList::updateFailed);
- d->m_updateTask->start();
+ auto updateTask = new ComponentUpdateTask(ComponentUpdateTask::Mode::Resolution, netmode, this);
+ d->m_updateTask.reset(updateTask);
+ connect(updateTask, &ComponentUpdateTask::succeeded, this, &ComponentList::updateSucceeded);
+ connect(updateTask, &ComponentUpdateTask::failed, this, &ComponentList::updateFailed);
+ d->m_updateTask->start();
}
void ComponentList::updateSucceeded()
{
- qDebug() << "Component list update/resolve task succeeded for" << d->m_instance->name();
- d->m_updateTask.reset();
- invalidateLaunchProfile();
+ qDebug() << "Component list update/resolve task succeeded for" << d->m_instance->name();
+ d->m_updateTask.reset();
+ invalidateLaunchProfile();
}
void ComponentList::updateFailed(const QString& error)
{
- qDebug() << "Component list update/resolve task failed for" << d->m_instance->name() << "Reason:" << error;
- d->m_updateTask.reset();
- invalidateLaunchProfile();
+ qDebug() << "Component list update/resolve task failed for" << d->m_instance->name() << "Reason:" << error;
+ d->m_updateTask.reset();
+ invalidateLaunchProfile();
}
// NOTE this is really old stuff, and only needs to be used when loading the old hardcoded component-unaware format (loadPreComponentConfig).
static void upgradeDeprecatedFiles(QString root, QString instanceName)
{
- auto versionJsonPath = FS::PathCombine(root, "version.json");
- auto customJsonPath = FS::PathCombine(root, "custom.json");
- auto mcJson = FS::PathCombine(root, "patches" , "net.minecraft.json");
-
- QString sourceFile;
- QString renameFile;
-
- // convert old crap.
- if(QFile::exists(customJsonPath))
- {
- sourceFile = customJsonPath;
- renameFile = versionJsonPath;
- }
- else if(QFile::exists(versionJsonPath))
- {
- sourceFile = versionJsonPath;
- }
- if(!sourceFile.isEmpty() && !QFile::exists(mcJson))
- {
- if(!FS::ensureFilePathExists(mcJson))
- {
- qWarning() << "Couldn't create patches folder for" << instanceName;
- return;
- }
- if(!renameFile.isEmpty() && QFile::exists(renameFile))
- {
- if(!QFile::rename(renameFile, renameFile + ".old"))
- {
- qWarning() << "Couldn't rename" << renameFile << "to" << renameFile + ".old" << "in" << instanceName;
- return;
- }
- }
- auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false);
- ProfileUtils::removeLwjglFromPatch(file);
- file->uid = "net.minecraft";
- file->version = file->minecraftVersion;
- file->name = "Minecraft";
-
- Meta::Require needsLwjgl;
- needsLwjgl.uid = "org.lwjgl";
- file->requires.insert(needsLwjgl);
-
- if(!ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), mcJson))
- {
- return;
- }
- if(!QFile::rename(sourceFile, sourceFile + ".old"))
- {
- qWarning() << "Couldn't rename" << sourceFile << "to" << sourceFile + ".old" << "in" << instanceName;
- return;
- }
- }
+ auto versionJsonPath = FS::PathCombine(root, "version.json");
+ auto customJsonPath = FS::PathCombine(root, "custom.json");
+ auto mcJson = FS::PathCombine(root, "patches" , "net.minecraft.json");
+
+ QString sourceFile;
+ QString renameFile;
+
+ // convert old crap.
+ if(QFile::exists(customJsonPath))
+ {
+ sourceFile = customJsonPath;
+ renameFile = versionJsonPath;
+ }
+ else if(QFile::exists(versionJsonPath))
+ {
+ sourceFile = versionJsonPath;
+ }
+ if(!sourceFile.isEmpty() && !QFile::exists(mcJson))
+ {
+ if(!FS::ensureFilePathExists(mcJson))
+ {
+ qWarning() << "Couldn't create patches folder for" << instanceName;
+ return;
+ }
+ if(!renameFile.isEmpty() && QFile::exists(renameFile))
+ {
+ if(!QFile::rename(renameFile, renameFile + ".old"))
+ {
+ qWarning() << "Couldn't rename" << renameFile << "to" << renameFile + ".old" << "in" << instanceName;
+ return;
+ }
+ }
+ auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false);
+ ProfileUtils::removeLwjglFromPatch(file);
+ file->uid = "net.minecraft";
+ file->version = file->minecraftVersion;
+ file->name = "Minecraft";
+
+ Meta::Require needsLwjgl;
+ needsLwjgl.uid = "org.lwjgl";
+ file->requires.insert(needsLwjgl);
+
+ if(!ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), mcJson))
+ {
+ return;
+ }
+ if(!QFile::rename(sourceFile, sourceFile + ".old"))
+ {
+ qWarning() << "Couldn't rename" << sourceFile << "to" << sourceFile + ".old" << "in" << instanceName;
+ return;
+ }
+ }
}
/*
@@ -431,774 +431,774 @@ static void upgradeDeprecatedFiles(QString root, QString instanceName)
*/
bool ComponentList::migratePreComponentConfig()
{
- // upgrade the very old files from the beginnings of MultiMC 5
- upgradeDeprecatedFiles(d->m_instance->instanceRoot(), d->m_instance->name());
-
- QList<ComponentPtr> components;
- QSet<QString> loaded;
-
- auto addBuiltinPatch = [&](const QString &uid, bool asDependency, const QString & emptyVersion, const Meta::Require & req, const Meta::Require & conflict)
- {
- auto jsonFilePath = FS::PathCombine(d->m_instance->instanceRoot(), "patches" , uid + ".json");
- auto intendedVersion = d->getOldConfigVersion(uid);
- // load up the base minecraft patch
- ComponentPtr component;
- if(QFile::exists(jsonFilePath))
- {
- if(intendedVersion.isEmpty())
- {
- intendedVersion = emptyVersion;
- }
- auto file = ProfileUtils::parseJsonFile(QFileInfo(jsonFilePath), false);
- // fix uid
- file->uid = uid;
- // if version is missing, add it from the outside.
- if(file->version.isEmpty())
- {
- file->version = intendedVersion;
- }
- // if this is a dependency (LWJGL), mark it also as volatile
- if(asDependency)
- {
- file->m_volatile = true;
- }
- // insert requirements if needed
- if(!req.uid.isEmpty())
- {
- file->requires.insert(req);
- }
- // insert conflicts if needed
- if(!conflict.uid.isEmpty())
- {
- file->conflicts.insert(conflict);
- }
- // FIXME: @QUALITY do not ignore return value
- ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), jsonFilePath);
- component = new Component(this, uid, file);
- component->m_version = intendedVersion;
- }
- else if(!intendedVersion.isEmpty())
- {
- auto metaVersion = ENV.metadataIndex()->get(uid, intendedVersion);
- component = new Component(this, metaVersion);
- }
- else
- {
- return;
- }
- component->m_dependencyOnly = asDependency;
- component->m_important = !asDependency;
- components.append(component);
- };
- // TODO: insert depends and conflicts here if these are customized files...
- Meta::Require reqLwjgl;
- reqLwjgl.uid = "org.lwjgl";
- reqLwjgl.suggests = "2.9.1";
- Meta::Require conflictLwjgl3;
- conflictLwjgl3.uid = "org.lwjgl3";
- Meta::Require nullReq;
- addBuiltinPatch("org.lwjgl", true, "2.9.1", nullReq, conflictLwjgl3);
- addBuiltinPatch("net.minecraft", false, QString(), reqLwjgl, nullReq);
-
- // first, collect all other file-based patches and load them
- QMap<QString, ComponentPtr> loadedComponents;
- QDir patchesDir(FS::PathCombine(d->m_instance->instanceRoot(),"patches"));
- for (auto info : patchesDir.entryInfoList(QStringList() << "*.json", QDir::Files))
- {
- // parse the file
- qDebug() << "Reading" << info.fileName();
- auto file = ProfileUtils::parseJsonFile(info, true);
-
- // correct missing or wrong uid based on the file name
- QString uid = info.completeBaseName();
-
- // ignore builtins, they've been handled already
- if (uid == "net.minecraft")
- continue;
- if (uid == "org.lwjgl")
- continue;
-
- // handle horrible corner cases
- if(uid.isEmpty())
- {
- // if you have a file named '.json', make it just go away.
- // FIXME: @QUALITY do not ignore return value
- QFile::remove(info.absoluteFilePath());
- continue;
- }
- file->uid = uid;
- // FIXME: @QUALITY do not ignore return value
- ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), info.absoluteFilePath());
-
- auto component = new Component(this, file->uid, file);
- auto version = d->getOldConfigVersion(file->uid);
- if(!version.isEmpty())
- {
- component->m_version = version;
- }
- loadedComponents[file->uid] = component;
- }
- // try to load the other 'hardcoded' patches (forge, liteloader), if they weren't loaded from files
- auto loadSpecial = [&](const QString & uid, int order)
- {
- auto patchVersion = d->getOldConfigVersion(uid);
- if(!patchVersion.isEmpty() && !loadedComponents.contains(uid))
- {
- auto patch = new Component(this, ENV.metadataIndex()->get(uid, patchVersion));
- patch->setOrder(order);
- loadedComponents[uid] = patch;
- }
- };
- loadSpecial("net.minecraftforge", 5);
- loadSpecial("com.mumfrey.liteloader", 10);
-
- // load the old order.json file, if present
- ProfileUtils::PatchOrder userOrder;
- ProfileUtils::readOverrideOrders(FS::PathCombine(d->m_instance->instanceRoot(), "order.json"), userOrder);
-
- // now add all the patches by user sort order
- for (auto uid : userOrder)
- {
- // ignore builtins
- if (uid == "net.minecraft")
- continue;
- if (uid == "org.lwjgl")
- continue;
- // ordering has a patch that is gone?
- if(!loadedComponents.contains(uid))
- {
- continue;
- }
- components.append(loadedComponents.take(uid));
- }
-
- // is there anything left to sort? - this is used when there are leftover components that aren't part of the order.json
- if(!loadedComponents.isEmpty())
- {
- // inserting into multimap by order number as key sorts the patches and detects duplicates
- QMultiMap<int, ComponentPtr> files;
- auto iter = loadedComponents.begin();
- while(iter != loadedComponents.end())
- {
- files.insert((*iter)->getOrder(), *iter);
- iter++;
- }
-
- // then just extract the patches and put them in the list
- for (auto order : files.keys())
- {
- const auto &values = files.values(order);
- for(auto &value: values)
- {
- // TODO: put back the insertion of problem messages here, so the user knows about the id duplication
- components.append(value);
- }
- }
- }
- // new we have a complete list of components...
- return saveComponentList(componentsFilePath(), components);
+ // upgrade the very old files from the beginnings of MultiMC 5
+ upgradeDeprecatedFiles(d->m_instance->instanceRoot(), d->m_instance->name());
+
+ QList<ComponentPtr> components;
+ QSet<QString> loaded;
+
+ auto addBuiltinPatch = [&](const QString &uid, bool asDependency, const QString & emptyVersion, const Meta::Require & req, const Meta::Require & conflict)
+ {
+ auto jsonFilePath = FS::PathCombine(d->m_instance->instanceRoot(), "patches" , uid + ".json");
+ auto intendedVersion = d->getOldConfigVersion(uid);
+ // load up the base minecraft patch
+ ComponentPtr component;
+ if(QFile::exists(jsonFilePath))
+ {
+ if(intendedVersion.isEmpty())
+ {
+ intendedVersion = emptyVersion;
+ }
+ auto file = ProfileUtils::parseJsonFile(QFileInfo(jsonFilePath), false);
+ // fix uid
+ file->uid = uid;
+ // if version is missing, add it from the outside.
+ if(file->version.isEmpty())
+ {
+ file->version = intendedVersion;
+ }
+ // if this is a dependency (LWJGL), mark it also as volatile
+ if(asDependency)
+ {
+ file->m_volatile = true;
+ }
+ // insert requirements if needed
+ if(!req.uid.isEmpty())
+ {
+ file->requires.insert(req);
+ }
+ // insert conflicts if needed
+ if(!conflict.uid.isEmpty())
+ {
+ file->conflicts.insert(conflict);
+ }
+ // FIXME: @QUALITY do not ignore return value
+ ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), jsonFilePath);
+ component = new Component(this, uid, file);
+ component->m_version = intendedVersion;
+ }
+ else if(!intendedVersion.isEmpty())
+ {
+ auto metaVersion = ENV.metadataIndex()->get(uid, intendedVersion);
+ component = new Component(this, metaVersion);
+ }
+ else
+ {
+ return;
+ }
+ component->m_dependencyOnly = asDependency;
+ component->m_important = !asDependency;
+ components.append(component);
+ };
+ // TODO: insert depends and conflicts here if these are customized files...
+ Meta::Require reqLwjgl;
+ reqLwjgl.uid = "org.lwjgl";
+ reqLwjgl.suggests = "2.9.1";
+ Meta::Require conflictLwjgl3;
+ conflictLwjgl3.uid = "org.lwjgl3";
+ Meta::Require nullReq;
+ addBuiltinPatch("org.lwjgl", true, "2.9.1", nullReq, conflictLwjgl3);
+ addBuiltinPatch("net.minecraft", false, QString(), reqLwjgl, nullReq);
+
+ // first, collect all other file-based patches and load them
+ QMap<QString, ComponentPtr> loadedComponents;
+ QDir patchesDir(FS::PathCombine(d->m_instance->instanceRoot(),"patches"));
+ for (auto info : patchesDir.entryInfoList(QStringList() << "*.json", QDir::Files))
+ {
+ // parse the file
+ qDebug() << "Reading" << info.fileName();
+ auto file = ProfileUtils::parseJsonFile(info, true);
+
+ // correct missing or wrong uid based on the file name
+ QString uid = info.completeBaseName();
+
+ // ignore builtins, they've been handled already
+ if (uid == "net.minecraft")
+ continue;
+ if (uid == "org.lwjgl")
+ continue;
+
+ // handle horrible corner cases
+ if(uid.isEmpty())
+ {
+ // if you have a file named '.json', make it just go away.
+ // FIXME: @QUALITY do not ignore return value
+ QFile::remove(info.absoluteFilePath());
+ continue;
+ }
+ file->uid = uid;
+ // FIXME: @QUALITY do not ignore return value
+ ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), info.absoluteFilePath());
+
+ auto component = new Component(this, file->uid, file);
+ auto version = d->getOldConfigVersion(file->uid);
+ if(!version.isEmpty())
+ {
+ component->m_version = version;
+ }
+ loadedComponents[file->uid] = component;
+ }
+ // try to load the other 'hardcoded' patches (forge, liteloader), if they weren't loaded from files
+ auto loadSpecial = [&](const QString & uid, int order)
+ {
+ auto patchVersion = d->getOldConfigVersion(uid);
+ if(!patchVersion.isEmpty() && !loadedComponents.contains(uid))
+ {
+ auto patch = new Component(this, ENV.metadataIndex()->get(uid, patchVersion));
+ patch->setOrder(order);
+ loadedComponents[uid] = patch;
+ }
+ };
+ loadSpecial("net.minecraftforge", 5);
+ loadSpecial("com.mumfrey.liteloader", 10);
+
+ // load the old order.json file, if present
+ ProfileUtils::PatchOrder userOrder;
+ ProfileUtils::readOverrideOrders(FS::PathCombine(d->m_instance->instanceRoot(), "order.json"), userOrder);
+
+ // now add all the patches by user sort order
+ for (auto uid : userOrder)
+ {
+ // ignore builtins
+ if (uid == "net.minecraft")
+ continue;
+ if (uid == "org.lwjgl")
+ continue;
+ // ordering has a patch that is gone?
+ if(!loadedComponents.contains(uid))
+ {
+ continue;
+ }
+ components.append(loadedComponents.take(uid));
+ }
+
+ // is there anything left to sort? - this is used when there are leftover components that aren't part of the order.json
+ if(!loadedComponents.isEmpty())
+ {
+ // inserting into multimap by order number as key sorts the patches and detects duplicates
+ QMultiMap<int, ComponentPtr> files;
+ auto iter = loadedComponents.begin();
+ while(iter != loadedComponents.end())
+ {
+ files.insert((*iter)->getOrder(), *iter);
+ iter++;
+ }
+
+ // then just extract the patches and put them in the list
+ for (auto order : files.keys())
+ {
+ const auto &values = files.values(order);
+ for(auto &value: values)
+ {
+ // TODO: put back the insertion of problem messages here, so the user knows about the id duplication
+ components.append(value);
+ }
+ }
+ }
+ // new we have a complete list of components...
+ return saveComponentList(componentsFilePath(), components);
}
// END: save/load
void ComponentList::appendComponent(ComponentPtr component)
{
- insertComponent(d->components.size(), component);
+ insertComponent(d->components.size(), component);
}
void ComponentList::insertComponent(size_t index, ComponentPtr component)
{
- auto id = component->getID();
- if(id.isEmpty())
- {
- qWarning() << "Attempt to add a component with empty ID!";
- return;
- }
- if(d->componentIndex.contains(id))
- {
- qWarning() << "Attempt to add a component that is already present!";
- return;
- }
- beginInsertRows(QModelIndex(), index, index);
- d->components.insert(index, component);
- d->componentIndex[id] = component;
- endInsertRows();
- connect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged);
- scheduleSave();
+ auto id = component->getID();
+ if(id.isEmpty())
+ {
+ qWarning() << "Attempt to add a component with empty ID!";
+ return;
+ }
+ if(d->componentIndex.contains(id))
+ {
+ qWarning() << "Attempt to add a component that is already present!";
+ return;
+ }
+ beginInsertRows(QModelIndex(), index, index);
+ d->components.insert(index, component);
+ d->componentIndex[id] = component;
+ endInsertRows();
+ connect(component.get(), &Component::dataChanged, this, &ComponentList::componentDataChanged);
+ scheduleSave();
}
void ComponentList::componentDataChanged()
{
- auto objPtr = qobject_cast<Component *>(sender());
- if(!objPtr)
- {
- qWarning() << "ComponentList got dataChenged signal from a non-Component!";
- return;
- }
- // figure out which one is it... in a seriously dumb way.
- int index = 0;
- for (auto component: d->components)
- {
- if(component.get() == objPtr)
- {
- emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1));
- scheduleSave();
- return;
- }
- index++;
- }
- qWarning() << "ComponentList got dataChenged signal from a Component which does not belong to it!";
+ auto objPtr = qobject_cast<Component *>(sender());
+ if(!objPtr)
+ {
+ qWarning() << "ComponentList got dataChenged signal from a non-Component!";
+ return;
+ }
+ // figure out which one is it... in a seriously dumb way.
+ int index = 0;
+ for (auto component: d->components)
+ {
+ if(component.get() == objPtr)
+ {
+ emit dataChanged(createIndex(index, 0), createIndex(index, columnCount(QModelIndex()) - 1));
+ scheduleSave();
+ return;
+ }
+ index++;
+ }
+ qWarning() << "ComponentList got dataChenged signal from a Component which does not belong to it!";
}
bool ComponentList::remove(const int index)
{
- auto patch = getComponent(index);
- if (!patch->isRemovable())
- {
- qWarning() << "Patch" << patch->getID() << "is non-removable";
- return false;
- }
-
- if(!removeComponent_internal(patch))
- {
- qCritical() << "Patch" << patch->getID() << "could not be removed";
- return false;
- }
-
- beginRemoveRows(QModelIndex(), index, index);
- d->components.removeAt(index);
- d->componentIndex.remove(patch->getID());
- endRemoveRows();
- invalidateLaunchProfile();
- scheduleSave();
- return true;
+ auto patch = getComponent(index);
+ if (!patch->isRemovable())
+ {
+ qWarning() << "Patch" << patch->getID() << "is non-removable";
+ return false;
+ }
+
+ if(!removeComponent_internal(patch))
+ {
+ qCritical() << "Patch" << patch->getID() << "could not be removed";
+ return false;
+ }
+
+ beginRemoveRows(QModelIndex(), index, index);
+ d->components.removeAt(index);
+ d->componentIndex.remove(patch->getID());
+ endRemoveRows();
+ invalidateLaunchProfile();
+ scheduleSave();
+ return true;
}
bool ComponentList::remove(const QString id)
{
- int i = 0;
- for (auto patch : d->components)
- {
- if (patch->getID() == id)
- {
- return remove(i);
- }
- i++;
- }
- return false;
+ int i = 0;
+ for (auto patch : d->components)
+ {
+ if (patch->getID() == id)
+ {
+ return remove(i);
+ }
+ i++;
+ }
+ return false;
}
bool ComponentList::customize(int index)
{
- auto patch = getComponent(index);
- if (!patch->isCustomizable())
- {
- qDebug() << "Patch" << patch->getID() << "is not customizable";
- return false;
- }
- if(!patch->customize())
- {
- qCritical() << "Patch" << patch->getID() << "could not be customized";
- return false;
- }
- invalidateLaunchProfile();
- scheduleSave();
- return true;
+ auto patch = getComponent(index);
+ if (!patch->isCustomizable())
+ {
+ qDebug() << "Patch" << patch->getID() << "is not customizable";
+ return false;
+ }
+ if(!patch->customize())
+ {
+ qCritical() << "Patch" << patch->getID() << "could not be customized";
+ return false;
+ }
+ invalidateLaunchProfile();
+ scheduleSave();
+ return true;
}
bool ComponentList::revertToBase(int index)
{
- auto patch = getComponent(index);
- if (!patch->isRevertible())
- {
- qDebug() << "Patch" << patch->getID() << "is not revertible";
- return false;
- }
- if(!patch->revert())
- {
- qCritical() << "Patch" << patch->getID() << "could not be reverted";
- return false;
- }
- invalidateLaunchProfile();
- scheduleSave();
- return true;
+ auto patch = getComponent(index);
+ if (!patch->isRevertible())
+ {
+ qDebug() << "Patch" << patch->getID() << "is not revertible";
+ return false;
+ }
+ if(!patch->revert())
+ {
+ qCritical() << "Patch" << patch->getID() << "could not be reverted";
+ return false;
+ }
+ invalidateLaunchProfile();
+ scheduleSave();
+ return true;
}
Component * ComponentList::getComponent(const QString &id)
{
- auto iter = d->componentIndex.find(id);
- if (iter == d->componentIndex.end())
- {
- return nullptr;
- }
- return (*iter).get();
+ auto iter = d->componentIndex.find(id);
+ if (iter == d->componentIndex.end())
+ {
+ return nullptr;
+ }
+ return (*iter).get();
}
Component * ComponentList::getComponent(int index)
{
- if(index < 0 || index >= d->components.size())
- {
- return nullptr;
- }
- return d->components[index].get();
+ if(index < 0 || index >= d->components.size())
+ {
+ return nullptr;
+ }
+ return d->components[index].get();
}
QVariant ComponentList::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= d->components.size())
- return QVariant();
-
- auto patch = d->components.at(row);
-
- switch (role)
- {
- case Qt::CheckStateRole:
- {
- switch (column)
- {
- case NameColumn:
- return d->components.at(row)->isEnabled() ? Qt::Checked : Qt::Unchecked;
- default:
- return QVariant();
- }
- }
- case Qt::DisplayRole:
- {
- switch (column)
- {
- case NameColumn:
- return d->components.at(row)->getName();
- case VersionColumn:
- {
- if(patch->isCustom())
- {
- return QString("%1 (Custom)").arg(patch->getVersion());
- }
- else
- {
- return patch->getVersion();
- }
- }
- default:
- return QVariant();
- }
- }
- case Qt::DecorationRole:
- {
- switch(column)
- {
- case NameColumn:
- {
- auto severity = patch->getProblemSeverity();
- switch (severity)
- {
- case ProblemSeverity::Warning:
- return "warning";
- case ProblemSeverity::Error:
- return "error";
- default:
- return QVariant();
- }
- }
- default:
- {
- return QVariant();
- }
- }
- }
- }
- return QVariant();
+ if (!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+ int column = index.column();
+
+ if (row < 0 || row >= d->components.size())
+ return QVariant();
+
+ auto patch = d->components.at(row);
+
+ switch (role)
+ {
+ case Qt::CheckStateRole:
+ {
+ switch (column)
+ {
+ case NameColumn:
+ return d->components.at(row)->isEnabled() ? Qt::Checked : Qt::Unchecked;
+ default:
+ return QVariant();
+ }
+ }
+ case Qt::DisplayRole:
+ {
+ switch (column)
+ {
+ case NameColumn:
+ return d->components.at(row)->getName();
+ case VersionColumn:
+ {
+ if(patch->isCustom())
+ {
+ return QString("%1 (Custom)").arg(patch->getVersion());
+ }
+ else
+ {
+ return patch->getVersion();
+ }
+ }
+ default:
+ return QVariant();
+ }
+ }
+ case Qt::DecorationRole:
+ {
+ switch(column)
+ {
+ case NameColumn:
+ {
+ auto severity = patch->getProblemSeverity();
+ switch (severity)
+ {
+ case ProblemSeverity::Warning:
+ return "warning";
+ case ProblemSeverity::Error:
+ return "error";
+ default:
+ return QVariant();
+ }
+ }
+ default:
+ {
+ return QVariant();
+ }
+ }
+ }
+ }
+ return QVariant();
}
bool ComponentList::setData(const QModelIndex& index, const QVariant& value, int role)
{
- if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index))
- {
- return false;
- }
-
- if (role == Qt::CheckStateRole)
- {
- auto component = d->components[index.row()];
- if (component->setEnabled(!component->isEnabled()))
- {
- return true;
- }
- }
- return false;
+ if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index))
+ {
+ return false;
+ }
+
+ if (role == Qt::CheckStateRole)
+ {
+ auto component = d->components[index.row()];
+ if (component->setEnabled(!component->isEnabled()))
+ {
+ return true;
+ }
+ }
+ return false;
}
QVariant ComponentList::headerData(int section, Qt::Orientation orientation, int role) const
{
- if (orientation == Qt::Horizontal)
- {
- if (role == Qt::DisplayRole)
- {
- switch (section)
- {
- case NameColumn:
- return tr("Name");
- case VersionColumn:
- return tr("Version");
- default:
- return QVariant();
- }
- }
- }
- return QVariant();
+ if (orientation == Qt::Horizontal)
+ {
+ if (role == Qt::DisplayRole)
+ {
+ switch (section)
+ {
+ case NameColumn:
+ return tr("Name");
+ case VersionColumn:
+ return tr("Version");
+ default:
+ return QVariant();
+ }
+ }
+ }
+ return QVariant();
}
Qt::ItemFlags ComponentList::flags(const QModelIndex &index) const
{
- if (!index.isValid())
- return Qt::NoItemFlags;
+ if (!index.isValid())
+ return Qt::NoItemFlags;
- Qt::ItemFlags outFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+ Qt::ItemFlags outFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
- int row = index.row();
+ int row = index.row();
- if (row < 0 || row >= d->components.size())
- return Qt::NoItemFlags;
+ if (row < 0 || row >= d->components.size())
+ return Qt::NoItemFlags;
- auto patch = d->components.at(row);
- // TODO: this will need fine-tuning later...
- if(patch->canBeDisabled())
- {
- outFlags |= Qt::ItemIsUserCheckable;
- }
- return outFlags;
+ auto patch = d->components.at(row);
+ // TODO: this will need fine-tuning later...
+ if(patch->canBeDisabled())
+ {
+ outFlags |= Qt::ItemIsUserCheckable;
+ }
+ return outFlags;
}
int ComponentList::rowCount(const QModelIndex &parent) const
{
- return d->components.size();
+ return d->components.size();
}
int ComponentList::columnCount(const QModelIndex &parent) const
{
- return NUM_COLUMNS;
+ return NUM_COLUMNS;
}
void ComponentList::move(const int index, const MoveDirection direction)
{
- int theirIndex;
- if (direction == MoveUp)
- {
- theirIndex = index - 1;
- }
- else
- {
- theirIndex = index + 1;
- }
-
- if (index < 0 || index >= d->components.size())
- return;
- if (theirIndex >= rowCount())
- theirIndex = rowCount() - 1;
- if (theirIndex == -1)
- theirIndex = rowCount() - 1;
- if (index == theirIndex)
- return;
- int togap = theirIndex > index ? theirIndex + 1 : theirIndex;
-
- auto from = getComponent(index);
- auto to = getComponent(theirIndex);
-
- if (!from || !to || !to->isMoveable() || !from->isMoveable())
- {
- return;
- }
- beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap);
- d->components.swap(index, theirIndex);
- endMoveRows();
- invalidateLaunchProfile();
- scheduleSave();
+ int theirIndex;
+ if (direction == MoveUp)
+ {
+ theirIndex = index - 1;
+ }
+ else
+ {
+ theirIndex = index + 1;
+ }
+
+ if (index < 0 || index >= d->components.size())
+ return;
+ if (theirIndex >= rowCount())
+ theirIndex = rowCount() - 1;
+ if (theirIndex == -1)
+ theirIndex = rowCount() - 1;
+ if (index == theirIndex)
+ return;
+ int togap = theirIndex > index ? theirIndex + 1 : theirIndex;
+
+ auto from = getComponent(index);
+ auto to = getComponent(theirIndex);
+
+ if (!from || !to || !to->isMoveable() || !from->isMoveable())
+ {
+ return;
+ }
+ beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap);
+ d->components.swap(index, theirIndex);
+ endMoveRows();
+ invalidateLaunchProfile();
+ scheduleSave();
}
void ComponentList::invalidateLaunchProfile()
{
- d->m_profile.reset();
+ d->m_profile.reset();
}
void ComponentList::installJarMods(QStringList selectedFiles)
{
- installJarMods_internal(selectedFiles);
+ installJarMods_internal(selectedFiles);
}
void ComponentList::installCustomJar(QString selectedFile)
{
- installCustomJar_internal(selectedFile);
+ installCustomJar_internal(selectedFile);
}
bool ComponentList::installEmpty(const QString& uid, const QString& name)
{
- QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
- if(!FS::ensureFolderPathExists(patchDir))
- {
- return false;
- }
- auto f = std::make_shared<VersionFile>();
- f->name = name;
- f->uid = uid;
- f->version = "1";
- QString patchFileName = FS::PathCombine(patchDir, uid + ".json");
- QFile file(patchFileName);
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
- file.close();
-
- appendComponent(new Component(this, f->uid, f));
- scheduleSave();
- invalidateLaunchProfile();
- return true;
+ QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
+ if(!FS::ensureFolderPathExists(patchDir))
+ {
+ return false;
+ }
+ auto f = std::make_shared<VersionFile>();
+ f->name = name;
+ f->uid = uid;
+ f->version = "1";
+ QString patchFileName = FS::PathCombine(patchDir, uid + ".json");
+ QFile file(patchFileName);
+ if (!file.open(QFile::WriteOnly))
+ {
+ qCritical() << "Error opening" << file.fileName()
+ << "for reading:" << file.errorString();
+ return false;
+ }
+ file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
+ file.close();
+
+ appendComponent(new Component(this, f->uid, f));
+ scheduleSave();
+ invalidateLaunchProfile();
+ return true;
}
bool ComponentList::removeComponent_internal(ComponentPtr patch)
{
- bool ok = true;
- // first, remove the patch file. this ensures it's not used anymore
- auto fileName = patch->getFilename();
- if(fileName.size())
- {
- QFile patchFile(fileName);
- if(patchFile.exists() && !patchFile.remove())
- {
- qCritical() << "File" << fileName << "could not be removed because:" << patchFile.errorString();
- return false;
- }
- }
-
- // FIXME: we need a generic way of removing local resources, not just jar mods...
- auto preRemoveJarMod = [&](LibraryPtr jarMod) -> bool
- {
- if (!jarMod->isLocal())
- {
- return true;
- }
- QStringList jar, temp1, temp2, temp3;
- jarMod->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, d->m_instance->jarmodsPath().absolutePath());
- QFileInfo finfo (jar[0]);
- if(finfo.exists())
- {
- QFile jarModFile(jar[0]);
- if(!jarModFile.remove())
- {
- qCritical() << "File" << jar[0] << "could not be removed because:" << jarModFile.errorString();
- return false;
- }
- return true;
- }
- return true;
- };
-
- auto vFile = patch->getVersionFile();
- if(vFile)
- {
- auto &jarMods = vFile->jarMods;
- for(auto &jarmod: jarMods)
- {
- ok &= preRemoveJarMod(jarmod);
- }
- }
- return ok;
+ bool ok = true;
+ // first, remove the patch file. this ensures it's not used anymore
+ auto fileName = patch->getFilename();
+ if(fileName.size())
+ {
+ QFile patchFile(fileName);
+ if(patchFile.exists() && !patchFile.remove())
+ {
+ qCritical() << "File" << fileName << "could not be removed because:" << patchFile.errorString();
+ return false;
+ }
+ }
+
+ // FIXME: we need a generic way of removing local resources, not just jar mods...
+ auto preRemoveJarMod = [&](LibraryPtr jarMod) -> bool
+ {
+ if (!jarMod->isLocal())
+ {
+ return true;
+ }
+ QStringList jar, temp1, temp2, temp3;
+ jarMod->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, d->m_instance->jarmodsPath().absolutePath());
+ QFileInfo finfo (jar[0]);
+ if(finfo.exists())
+ {
+ QFile jarModFile(jar[0]);
+ if(!jarModFile.remove())
+ {
+ qCritical() << "File" << jar[0] << "could not be removed because:" << jarModFile.errorString();
+ return false;
+ }
+ return true;
+ }
+ return true;
+ };
+
+ auto vFile = patch->getVersionFile();
+ if(vFile)
+ {
+ auto &jarMods = vFile->jarMods;
+ for(auto &jarmod: jarMods)
+ {
+ ok &= preRemoveJarMod(jarmod);
+ }
+ }
+ return ok;
}
bool ComponentList::installJarMods_internal(QStringList filepaths)
{
- QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
- if(!FS::ensureFolderPathExists(patchDir))
- {
- return false;
- }
-
- if (!FS::ensureFolderPathExists(d->m_instance->jarModsDir()))
- {
- return false;
- }
-
- for(auto filepath:filepaths)
- {
- QFileInfo sourceInfo(filepath);
- auto uuid = QUuid::createUuid();
- QString id = uuid.toString().remove('{').remove('}');
- QString target_filename = id + ".jar";
- QString target_id = "org.multimc.jarmod." + id;
- QString target_name = sourceInfo.completeBaseName() + " (jar mod)";
- QString finalPath = FS::PathCombine(d->m_instance->jarModsDir(), target_filename);
-
- QFileInfo targetInfo(finalPath);
- if(targetInfo.exists())
- {
- return false;
- }
-
- if (!QFile::copy(sourceInfo.absoluteFilePath(),QFileInfo(finalPath).absoluteFilePath()))
- {
- return false;
- }
-
- auto f = std::make_shared<VersionFile>();
- auto jarMod = std::make_shared<Library>();
- jarMod->setRawName(GradleSpecifier("org.multimc.jarmods:" + id + ":1"));
- jarMod->setFilename(target_filename);
- jarMod->setDisplayName(sourceInfo.completeBaseName());
- jarMod->setHint("local");
- f->jarMods.append(jarMod);
- f->name = target_name;
- f->uid = target_id;
- QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
-
- QFile file(patchFileName);
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
- file.close();
-
- appendComponent(new Component(this, f->uid, f));
- }
- scheduleSave();
- invalidateLaunchProfile();
- return true;
+ QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
+ if(!FS::ensureFolderPathExists(patchDir))
+ {
+ return false;
+ }
+
+ if (!FS::ensureFolderPathExists(d->m_instance->jarModsDir()))
+ {
+ return false;
+ }
+
+ for(auto filepath:filepaths)
+ {
+ QFileInfo sourceInfo(filepath);
+ auto uuid = QUuid::createUuid();
+ QString id = uuid.toString().remove('{').remove('}');
+ QString target_filename = id + ".jar";
+ QString target_id = "org.multimc.jarmod." + id;
+ QString target_name = sourceInfo.completeBaseName() + " (jar mod)";
+ QString finalPath = FS::PathCombine(d->m_instance->jarModsDir(), target_filename);
+
+ QFileInfo targetInfo(finalPath);
+ if(targetInfo.exists())
+ {
+ return false;
+ }
+
+ if (!QFile::copy(sourceInfo.absoluteFilePath(),QFileInfo(finalPath).absoluteFilePath()))
+ {
+ return false;
+ }
+
+ auto f = std::make_shared<VersionFile>();
+ auto jarMod = std::make_shared<Library>();
+ jarMod->setRawName(GradleSpecifier("org.multimc.jarmods:" + id + ":1"));
+ jarMod->setFilename(target_filename);
+ jarMod->setDisplayName(sourceInfo.completeBaseName());
+ jarMod->setHint("local");
+ f->jarMods.append(jarMod);
+ f->name = target_name;
+ f->uid = target_id;
+ QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
+
+ QFile file(patchFileName);
+ if (!file.open(QFile::WriteOnly))
+ {
+ qCritical() << "Error opening" << file.fileName()
+ << "for reading:" << file.errorString();
+ return false;
+ }
+ file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
+ file.close();
+
+ appendComponent(new Component(this, f->uid, f));
+ }
+ scheduleSave();
+ invalidateLaunchProfile();
+ return true;
}
bool ComponentList::installCustomJar_internal(QString filepath)
{
- QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
- if(!FS::ensureFolderPathExists(patchDir))
- {
- return false;
- }
-
- QString libDir = d->m_instance->getLocalLibraryPath();
- if (!FS::ensureFolderPathExists(libDir))
- {
- return false;
- }
-
- auto specifier = GradleSpecifier("org.multimc:customjar:1");
- QFileInfo sourceInfo(filepath);
- QString target_filename = specifier.getFileName();
- QString target_id = specifier.artifactId();
- QString target_name = sourceInfo.completeBaseName() + " (custom jar)";
- QString finalPath = FS::PathCombine(libDir, target_filename);
-
- QFileInfo jarInfo(finalPath);
- if (jarInfo.exists())
- {
- if(!QFile::remove(finalPath))
- {
- return false;
- }
- }
- if (!QFile::copy(filepath, finalPath))
- {
- return false;
- }
-
- auto f = std::make_shared<VersionFile>();
- auto jarMod = std::make_shared<Library>();
- jarMod->setRawName(specifier);
- jarMod->setDisplayName(sourceInfo.completeBaseName());
- jarMod->setHint("local");
- f->mainJar = jarMod;
- f->name = target_name;
- f->uid = target_id;
- QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
-
- QFile file(patchFileName);
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
- file.close();
-
- appendComponent(new Component(this, f->uid, f));
-
- scheduleSave();
- invalidateLaunchProfile();
- return true;
+ QString patchDir = FS::PathCombine(d->m_instance->instanceRoot(), "patches");
+ if(!FS::ensureFolderPathExists(patchDir))
+ {
+ return false;
+ }
+
+ QString libDir = d->m_instance->getLocalLibraryPath();
+ if (!FS::ensureFolderPathExists(libDir))
+ {
+ return false;
+ }
+
+ auto specifier = GradleSpecifier("org.multimc:customjar:1");
+ QFileInfo sourceInfo(filepath);
+ QString target_filename = specifier.getFileName();
+ QString target_id = specifier.artifactId();
+ QString target_name = sourceInfo.completeBaseName() + " (custom jar)";
+ QString finalPath = FS::PathCombine(libDir, target_filename);
+
+ QFileInfo jarInfo(finalPath);
+ if (jarInfo.exists())
+ {
+ if(!QFile::remove(finalPath))
+ {
+ return false;
+ }
+ }
+ if (!QFile::copy(filepath, finalPath))
+ {
+ return false;
+ }
+
+ auto f = std::make_shared<VersionFile>();
+ auto jarMod = std::make_shared<Library>();
+ jarMod->setRawName(specifier);
+ jarMod->setDisplayName(sourceInfo.completeBaseName());
+ jarMod->setHint("local");
+ f->mainJar = jarMod;
+ f->name = target_name;
+ f->uid = target_id;
+ QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
+
+ QFile file(patchFileName);
+ if (!file.open(QFile::WriteOnly))
+ {
+ qCritical() << "Error opening" << file.fileName()
+ << "for reading:" << file.errorString();
+ return false;
+ }
+ file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
+ file.close();
+
+ appendComponent(new Component(this, f->uid, f));
+
+ scheduleSave();
+ invalidateLaunchProfile();
+ return true;
}
std::shared_ptr<LaunchProfile> ComponentList::getProfile() const
{
- if(!d->m_profile)
- {
- try
- {
- auto profile = std::make_shared<LaunchProfile>();
- for(auto file: d->components)
- {
- qDebug() << "Applying" << file->getID() << (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD");
- file->applyTo(profile.get());
- }
- d->m_profile = profile;
- }
- catch (const Exception &error)
- {
- qWarning() << "Couldn't apply profile patches because: " << error.cause();
- }
- }
- return d->m_profile;
+ if(!d->m_profile)
+ {
+ try
+ {
+ auto profile = std::make_shared<LaunchProfile>();
+ for(auto file: d->components)
+ {
+ qDebug() << "Applying" << file->getID() << (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD");
+ file->applyTo(profile.get());
+ }
+ d->m_profile = profile;
+ }
+ catch (const Exception &error)
+ {
+ qWarning() << "Couldn't apply profile patches because: " << error.cause();
+ }
+ }
+ return d->m_profile;
}
void ComponentList::setOldConfigVersion(const QString& uid, const QString& version)
{
- if(version.isEmpty())
- {
- return;
- }
- d->m_oldConfigVersions[uid] = version;
+ if(version.isEmpty())
+ {
+ return;
+ }
+ d->m_oldConfigVersions[uid] = version;
}
bool ComponentList::setComponentVersion(const QString& uid, const QString& version, bool important)
{
- auto iter = d->componentIndex.find(uid);
- if(iter != d->componentIndex.end())
- {
- ComponentPtr component = *iter;
- // set existing
- if(component->revert())
- {
- component->setVersion(version);
- component->setImportant(important);
- return true;
- }
- return false;
- }
- else
- {
- // add new
- auto component = new Component(this, uid);
- component->m_version = version;
- component->m_important = important;
- appendComponent(component);
- return true;
- }
+ auto iter = d->componentIndex.find(uid);
+ if(iter != d->componentIndex.end())
+ {
+ ComponentPtr component = *iter;
+ // set existing
+ if(component->revert())
+ {
+ component->setVersion(version);
+ component->setImportant(important);
+ return true;
+ }
+ return false;
+ }
+ else
+ {
+ // add new
+ auto component = new Component(this, uid);
+ component->m_version = version;
+ component->m_important = important;
+ appendComponent(component);
+ return true;
+ }
}
QString ComponentList::getComponentVersion(const QString& uid) const
{
- const auto iter = d->componentIndex.find(uid);
- if (iter != d->componentIndex.end())
- {
- return (*iter)->getVersion();
- }
- return QString();
+ const auto iter = d->componentIndex.find(uid);
+ if (iter != d->componentIndex.end())
+ {
+ return (*iter)->getVersion();
+ }
+ return QString();
}
diff --git a/api/logic/minecraft/ComponentList.h b/api/logic/minecraft/ComponentList.h
index cf4d9975..6ddc09eb 100644
--- a/api/logic/minecraft/ComponentList.h
+++ b/api/logic/minecraft/ComponentList.h
@@ -36,111 +36,111 @@ class ComponentUpdateTask;
class MULTIMC_LOGIC_EXPORT ComponentList : public QAbstractListModel
{
- Q_OBJECT
- friend ComponentUpdateTask;
+ Q_OBJECT
+ friend ComponentUpdateTask;
public:
- enum Columns
- {
- NameColumn = 0,
- VersionColumn,
- NUM_COLUMNS
- };
+ enum Columns
+ {
+ NameColumn = 0,
+ VersionColumn,
+ NUM_COLUMNS
+ };
- explicit ComponentList(MinecraftInstance * instance);
- virtual ~ComponentList();
+ explicit ComponentList(MinecraftInstance * instance);
+ virtual ~ComponentList();
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- virtual int columnCount(const QModelIndex &parent) const override;
- virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ virtual int columnCount(const QModelIndex &parent) const override;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
- /// call this to explicitly mark the component list as loaded - this is used to build a new component list from scratch.
- void buildingFromScratch();
+ /// call this to explicitly mark the component list as loaded - this is used to build a new component list from scratch.
+ void buildingFromScratch();
- /// install more jar mods
- void installJarMods(QStringList selectedFiles);
+ /// install more jar mods
+ void installJarMods(QStringList selectedFiles);
- /// install a jar/zip as a replacement for the main jar
- void installCustomJar(QString selectedFile);
+ /// install a jar/zip as a replacement for the main jar
+ void installCustomJar(QString selectedFile);
- enum MoveDirection { MoveUp, MoveDown };
- /// move component file # up or down the list
- void move(const int index, const MoveDirection direction);
+ enum MoveDirection { MoveUp, MoveDown };
+ /// move component file # up or down the list
+ void move(const int index, const MoveDirection direction);
- /// remove component file # - including files/records
- bool remove(const int index);
+ /// remove component file # - including files/records
+ bool remove(const int index);
- /// remove component file by id - including files/records
- bool remove(const QString id);
+ /// remove component file by id - including files/records
+ bool remove(const QString id);
- bool customize(int index);
+ bool customize(int index);
- bool revertToBase(int index);
+ bool revertToBase(int index);
- /// reload the list, reload all components, resolve dependencies
- void reload(Net::Mode netmode);
+ /// reload the list, reload all components, resolve dependencies
+ void reload(Net::Mode netmode);
- // reload all components, resolve dependencies
- void resolve(Net::Mode netmode);
+ // reload all components, resolve dependencies
+ void resolve(Net::Mode netmode);
- /// get current running task...
- shared_qobject_ptr<Task> getCurrentTask();
+ /// get current running task...
+ shared_qobject_ptr<Task> getCurrentTask();
- std::shared_ptr<LaunchProfile> getProfile() const;
+ std::shared_ptr<LaunchProfile> getProfile() const;
- // NOTE: used ONLY by MinecraftInstance to provide legacy version mappings from instance config
- void setOldConfigVersion(const QString &uid, const QString &version);
+ // NOTE: used ONLY by MinecraftInstance to provide legacy version mappings from instance config
+ void setOldConfigVersion(const QString &uid, const QString &version);
- QString getComponentVersion(const QString &uid) const;
+ QString getComponentVersion(const QString &uid) const;
- bool setComponentVersion(const QString &uid, const QString &version, bool important = false);
+ bool setComponentVersion(const QString &uid, const QString &version, bool important = false);
- bool installEmpty(const QString &uid, const QString &name);
+ bool installEmpty(const QString &uid, const QString &name);
- QString patchFilePathForUid(const QString &uid) const;
+ QString patchFilePathForUid(const QString &uid) const;
- /// if there is a save scheduled, do it now.
- void saveNow();
+ /// if there is a save scheduled, do it now.
+ void saveNow();
public:
- /// get the profile component by id
- Component * getComponent(const QString &id);
+ /// get the profile component by id
+ Component * getComponent(const QString &id);
- /// get the profile component by index
- Component * getComponent(int index);
+ /// get the profile component by index
+ Component * getComponent(int index);
private:
- void scheduleSave();
- bool saveIsScheduled() const;
+ void scheduleSave();
+ bool saveIsScheduled() const;
- /// apply the component patches. Catches all the errors and returns true/false for success/failure
- void invalidateLaunchProfile();
+ /// apply the component patches. Catches all the errors and returns true/false for success/failure
+ void invalidateLaunchProfile();
- /// Add the component to the internal list of patches
- void appendComponent(ComponentPtr component);
- /// insert component so that its index is ideally the specified one (returns real index)
- void insertComponent(size_t index, ComponentPtr component);
+ /// Add the component to the internal list of patches
+ void appendComponent(ComponentPtr component);
+ /// insert component so that its index is ideally the specified one (returns real index)
+ void insertComponent(size_t index, ComponentPtr component);
- QString componentsFilePath() const;
- QString patchesPattern() const;
+ QString componentsFilePath() const;
+ QString patchesPattern() const;
private slots:
- void save_internal();
- void updateSucceeded();
- void updateFailed(const QString & error);
- void componentDataChanged();
+ void save_internal();
+ void updateSucceeded();
+ void updateFailed(const QString & error);
+ void componentDataChanged();
private:
- bool load();
- bool installJarMods_internal(QStringList filepaths);
+ bool load();
+ bool installJarMods_internal(QStringList filepaths);
bool installCustomJar_internal(QString filepath);
- bool removeComponent_internal(ComponentPtr patch);
+ bool removeComponent_internal(ComponentPtr patch);
- bool migratePreComponentConfig();
+ bool migratePreComponentConfig();
private: /* data */
- std::unique_ptr<ComponentListData> d;
+ std::unique_ptr<ComponentListData> d;
};
diff --git a/api/logic/minecraft/ComponentList_p.h b/api/logic/minecraft/ComponentList_p.h
index 26ca5049..aed65337 100644
--- a/api/logic/minecraft/ComponentList_p.h
+++ b/api/logic/minecraft/ComponentList_p.h
@@ -13,30 +13,30 @@ using ConnectionList = QList<QMetaObject::Connection>;
struct ComponentListData
{
- // the instance this belongs to
- MinecraftInstance *m_instance;
+ // the instance this belongs to
+ MinecraftInstance *m_instance;
- // the launch profile (volatile, temporary thing created on demand)
- std::shared_ptr<LaunchProfile> m_profile;
+ // the launch profile (volatile, temporary thing created on demand)
+ std::shared_ptr<LaunchProfile> m_profile;
- // version information migrated from instance.cfg file. Single use on migration!
- std::map<QString, QString> m_oldConfigVersions;
- QString getOldConfigVersion(const QString& uid) const
- {
- const auto iter = m_oldConfigVersions.find(uid);
- if(iter != m_oldConfigVersions.cend())
- {
- return (*iter).second;
- }
- return QString();
- }
+ // version information migrated from instance.cfg file. Single use on migration!
+ std::map<QString, QString> m_oldConfigVersions;
+ QString getOldConfigVersion(const QString& uid) const
+ {
+ const auto iter = m_oldConfigVersions.find(uid);
+ if(iter != m_oldConfigVersions.cend())
+ {
+ return (*iter).second;
+ }
+ return QString();
+ }
- // persistent list of components and related machinery
- ComponentContainer components;
- ComponentIndex componentIndex;
- bool dirty = false;
- QTimer m_saveTimer;
- shared_qobject_ptr<Task> m_updateTask;
- bool loaded = false;
+ // persistent list of components and related machinery
+ ComponentContainer components;
+ ComponentIndex componentIndex;
+ bool dirty = false;
+ QTimer m_saveTimer;
+ shared_qobject_ptr<Task> m_updateTask;
+ bool loaded = false;
};
diff --git a/api/logic/minecraft/ComponentUpdateTask.cpp b/api/logic/minecraft/ComponentUpdateTask.cpp
index 2d6ceb91..37cc488d 100644
--- a/api/logic/minecraft/ComponentUpdateTask.cpp
+++ b/api/logic/minecraft/ComponentUpdateTask.cpp
@@ -32,12 +32,12 @@
*/
ComponentUpdateTask::ComponentUpdateTask(Mode mode, Net::Mode netmode, ComponentList* list, QObject* parent)
- : Task(parent)
+ : Task(parent)
{
- d.reset(new ComponentUpdateTaskData);
- d->m_list = list;
- d->mode = mode;
- d->netmode = netmode;
+ d.reset(new ComponentUpdateTaskData);
+ d->m_list = list;
+ d->mode = mode;
+ d->netmode = netmode;
}
ComponentUpdateTask::~ComponentUpdateTask()
@@ -46,356 +46,356 @@ ComponentUpdateTask::~ComponentUpdateTask()
void ComponentUpdateTask::executeTask()
{
- qDebug() << "Loading components";
- loadComponents();
+ qDebug() << "Loading components";
+ loadComponents();
}
namespace
{
enum class LoadResult
{
- LoadedLocal,
- RequiresRemote,
- Failed
+ LoadedLocal,
+ RequiresRemote,
+ Failed
};
LoadResult composeLoadResult(LoadResult a, LoadResult b)
{
- if (a < b)
- {
- return b;
- }
- return a;
+ if (a < b)
+ {
+ return b;
+ }
+ return a;
}
static LoadResult loadComponent(ComponentPtr component, shared_qobject_ptr<Task>& loadTask, Net::Mode netmode)
{
- if(component->m_loaded)
- {
- qDebug() << component->getName() << "is already loaded";
- return LoadResult::LoadedLocal;
- }
-
- LoadResult result = LoadResult::Failed;
- auto customPatchFilename = component->getFilename();
- if(QFile::exists(customPatchFilename))
- {
- // if local file exists...
-
- // check for uid problems inside...
- bool fileChanged = false;
- auto file = ProfileUtils::parseJsonFile(QFileInfo(customPatchFilename), false);
- if(file->uid != component->m_uid)
- {
- file->uid = component->m_uid;
- fileChanged = true;
- }
- if(fileChanged)
- {
- // FIXME: @QUALITY do not ignore return value
- ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), customPatchFilename);
- }
-
- component->m_file = file;
- component->m_loaded = true;
- result = LoadResult::LoadedLocal;
- }
- else
- {
- auto metaVersion = ENV.metadataIndex()->get(component->m_uid, component->m_version);
- component->m_metaVersion = metaVersion;
- if(metaVersion->isLoaded())
- {
- component->m_loaded = true;
- result = LoadResult::LoadedLocal;
- }
- else
- {
- metaVersion->load(netmode);
- loadTask = metaVersion->getCurrentTask();
- if(loadTask)
- result = LoadResult::RequiresRemote;
- else if (metaVersion->isLoaded())
- result = LoadResult::LoadedLocal;
- else
- result = LoadResult::Failed;
- }
- }
- return result;
+ if(component->m_loaded)
+ {
+ qDebug() << component->getName() << "is already loaded";
+ return LoadResult::LoadedLocal;
+ }
+
+ LoadResult result = LoadResult::Failed;
+ auto customPatchFilename = component->getFilename();
+ if(QFile::exists(customPatchFilename))
+ {
+ // if local file exists...
+
+ // check for uid problems inside...
+ bool fileChanged = false;
+ auto file = ProfileUtils::parseJsonFile(QFileInfo(customPatchFilename), false);
+ if(file->uid != component->m_uid)
+ {
+ file->uid = component->m_uid;
+ fileChanged = true;
+ }
+ if(fileChanged)
+ {
+ // FIXME: @QUALITY do not ignore return value
+ ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), customPatchFilename);
+ }
+
+ component->m_file = file;
+ component->m_loaded = true;
+ result = LoadResult::LoadedLocal;
+ }
+ else
+ {
+ auto metaVersion = ENV.metadataIndex()->get(component->m_uid, component->m_version);
+ component->m_metaVersion = metaVersion;
+ if(metaVersion->isLoaded())
+ {
+ component->m_loaded = true;
+ result = LoadResult::LoadedLocal;
+ }
+ else
+ {
+ metaVersion->load(netmode);
+ loadTask = metaVersion->getCurrentTask();
+ if(loadTask)
+ result = LoadResult::RequiresRemote;
+ else if (metaVersion->isLoaded())
+ result = LoadResult::LoadedLocal;
+ else
+ result = LoadResult::Failed;
+ }
+ }
+ return result;
}
// FIXME: dead code. determine if this can still be useful?
/*
static LoadResult loadComponentList(ComponentPtr component, shared_qobject_ptr<Task>& loadTask, Net::Mode netmode)
{
- if(component->m_loaded)
- {
- qDebug() << component->getName() << "is already loaded";
- return LoadResult::LoadedLocal;
- }
-
- LoadResult result = LoadResult::Failed;
- auto metaList = ENV.metadataIndex()->get(component->m_uid);
- if(metaList->isLoaded())
- {
- component->m_loaded = true;
- result = LoadResult::LoadedLocal;
- }
- else
- {
- metaList->load(netmode);
- loadTask = metaList->getCurrentTask();
- result = LoadResult::RequiresRemote;
- }
- return result;
+ if(component->m_loaded)
+ {
+ qDebug() << component->getName() << "is already loaded";
+ return LoadResult::LoadedLocal;
+ }
+
+ LoadResult result = LoadResult::Failed;
+ auto metaList = ENV.metadataIndex()->get(component->m_uid);
+ if(metaList->isLoaded())
+ {
+ component->m_loaded = true;
+ result = LoadResult::LoadedLocal;
+ }
+ else
+ {
+ metaList->load(netmode);
+ loadTask = metaList->getCurrentTask();
+ result = LoadResult::RequiresRemote;
+ }
+ return result;
}
*/
static LoadResult loadIndex(shared_qobject_ptr<Task>& loadTask, Net::Mode netmode)
{
- // FIXME: DECIDE. do we want to run the update task anyway?
- if(ENV.metadataIndex()->isLoaded())
- {
- qDebug() << "Index is already loaded";
- return LoadResult::LoadedLocal;
- }
- ENV.metadataIndex()->load(netmode);
- loadTask = ENV.metadataIndex()->getCurrentTask();
- if(loadTask)
- {
- return LoadResult::RequiresRemote;
- }
- // FIXME: this is assuming the load succeeded... did it really?
- return LoadResult::LoadedLocal;
+ // FIXME: DECIDE. do we want to run the update task anyway?
+ if(ENV.metadataIndex()->isLoaded())
+ {
+ qDebug() << "Index is already loaded";
+ return LoadResult::LoadedLocal;
+ }
+ ENV.metadataIndex()->load(netmode);
+ loadTask = ENV.metadataIndex()->getCurrentTask();
+ if(loadTask)
+ {
+ return LoadResult::RequiresRemote;
+ }
+ // FIXME: this is assuming the load succeeded... did it really?
+ return LoadResult::LoadedLocal;
}
}
void ComponentUpdateTask::loadComponents()
{
- LoadResult result = LoadResult::LoadedLocal;
- size_t taskIndex = 0;
- size_t componentIndex = 0;
- d->remoteLoadSuccessful = true;
- // load the main index (it is needed to determine if components can revert)
- {
- // FIXME: tear out as a method? or lambda?
- shared_qobject_ptr<Task> indexLoadTask;
- auto singleResult = loadIndex(indexLoadTask, d->netmode);
- result = composeLoadResult(result, singleResult);
- if(indexLoadTask)
- {
- qDebug() << "Remote loading is being run for metadata index";
- RemoteLoadStatus status;
- status.type = RemoteLoadStatus::Type::Index;
- d->remoteLoadStatusList.append(status);
- connect(indexLoadTask.get(), &Task::succeeded, [=]()
- {
- remoteLoadSucceeded(taskIndex);
- });
- connect(indexLoadTask.get(), &Task::failed, [=](const QString & error)
- {
- remoteLoadFailed(taskIndex, error);
- });
- taskIndex++;
- }
- }
- // load all the components OR their lists...
- for (auto component: d->m_list->d->components)
- {
- shared_qobject_ptr<Task> loadTask;
- LoadResult singleResult;
- RemoteLoadStatus::Type loadType;
- // FIXME: to do this right, we need to load the lists and decide on which versions to use during dependency resolution. For now, ignore all that...
+ LoadResult result = LoadResult::LoadedLocal;
+ size_t taskIndex = 0;
+ size_t componentIndex = 0;
+ d->remoteLoadSuccessful = true;
+ // load the main index (it is needed to determine if components can revert)
+ {
+ // FIXME: tear out as a method? or lambda?
+ shared_qobject_ptr<Task> indexLoadTask;
+ auto singleResult = loadIndex(indexLoadTask, d->netmode);
+ result = composeLoadResult(result, singleResult);
+ if(indexLoadTask)
+ {
+ qDebug() << "Remote loading is being run for metadata index";
+ RemoteLoadStatus status;
+ status.type = RemoteLoadStatus::Type::Index;
+ d->remoteLoadStatusList.append(status);
+ connect(indexLoadTask.get(), &Task::succeeded, [=]()
+ {
+ remoteLoadSucceeded(taskIndex);
+ });
+ connect(indexLoadTask.get(), &Task::failed, [=](const QString & error)
+ {
+ remoteLoadFailed(taskIndex, error);
+ });
+ taskIndex++;
+ }
+ }
+ // load all the components OR their lists...
+ for (auto component: d->m_list->d->components)
+ {
+ shared_qobject_ptr<Task> loadTask;
+ LoadResult singleResult;
+ RemoteLoadStatus::Type loadType;
+ // FIXME: to do this right, we need to load the lists and decide on which versions to use during dependency resolution. For now, ignore all that...
#if 0
- switch(d->mode)
- {
- case Mode::Launch:
- {
- singleResult = loadComponent(component, loadTask, d->netmode);
- loadType = RemoteLoadStatus::Type::Version;
- break;
- }
- case Mode::Resolution:
- {
- singleResult = loadComponentList(component, loadTask, d->netmode);
- loadType = RemoteLoadStatus::Type::List;
- break;
- }
- }
+ switch(d->mode)
+ {
+ case Mode::Launch:
+ {
+ singleResult = loadComponent(component, loadTask, d->netmode);
+ loadType = RemoteLoadStatus::Type::Version;
+ break;
+ }
+ case Mode::Resolution:
+ {
+ singleResult = loadComponentList(component, loadTask, d->netmode);
+ loadType = RemoteLoadStatus::Type::List;
+ break;
+ }
+ }
#else
- singleResult = loadComponent(component, loadTask, d->netmode);
- loadType = RemoteLoadStatus::Type::Version;
+ singleResult = loadComponent(component, loadTask, d->netmode);
+ loadType = RemoteLoadStatus::Type::Version;
#endif
- if(singleResult == LoadResult::LoadedLocal)
- {
- component->updateCachedData();
- }
- result = composeLoadResult(result, singleResult);
- if (loadTask)
- {
- qDebug() << "Remote loading is being run for" << component->getName();
- connect(loadTask.get(), &Task::succeeded, [=]()
- {
- remoteLoadSucceeded(taskIndex);
- });
- connect(loadTask.get(), &Task::failed, [=](const QString & error)
- {
- remoteLoadFailed(taskIndex, error);
- });
- RemoteLoadStatus status;
- status.type = loadType;
- status.componentListIndex = componentIndex;
- d->remoteLoadStatusList.append(status);
- taskIndex++;
- }
- componentIndex++;
- }
- d->remoteTasksInProgress = taskIndex;
- switch(result)
- {
- case LoadResult::LoadedLocal:
- {
- // Everything got loaded. Advance to dependency resolution.
- resolveDependencies(d->mode == Mode::Launch || d->netmode == Net::Mode::Offline);
- break;
- }
- case LoadResult::RequiresRemote:
- {
- // we wait for signals.
- break;
- }
- case LoadResult::Failed:
- {
- emitFailed(tr("Some component metadata load tasks failed."));
- break;
- }
- }
+ if(singleResult == LoadResult::LoadedLocal)
+ {
+ component->updateCachedData();
+ }
+ result = composeLoadResult(result, singleResult);
+ if (loadTask)
+ {
+ qDebug() << "Remote loading is being run for" << component->getName();
+ connect(loadTask.get(), &Task::succeeded, [=]()
+ {
+ remoteLoadSucceeded(taskIndex);
+ });
+ connect(loadTask.get(), &Task::failed, [=](const QString & error)
+ {
+ remoteLoadFailed(taskIndex, error);
+ });
+ RemoteLoadStatus status;
+ status.type = loadType;
+ status.componentListIndex = componentIndex;
+ d->remoteLoadStatusList.append(status);
+ taskIndex++;
+ }
+ componentIndex++;
+ }
+ d->remoteTasksInProgress = taskIndex;
+ switch(result)
+ {
+ case LoadResult::LoadedLocal:
+ {
+ // Everything got loaded. Advance to dependency resolution.
+ resolveDependencies(d->mode == Mode::Launch || d->netmode == Net::Mode::Offline);
+ break;
+ }
+ case LoadResult::RequiresRemote:
+ {
+ // we wait for signals.
+ break;
+ }
+ case LoadResult::Failed:
+ {
+ emitFailed(tr("Some component metadata load tasks failed."));
+ break;
+ }
+ }
}
namespace
{
- struct RequireEx : public Meta::Require
- {
- size_t indexOfFirstDependee = 0;
- };
- struct RequireCompositionResult
- {
- bool ok;
- RequireEx outcome;
- };
- using RequireExSet = std::set<RequireEx>;
+ struct RequireEx : public Meta::Require
+ {
+ size_t indexOfFirstDependee = 0;
+ };
+ struct RequireCompositionResult
+ {
+ bool ok;
+ RequireEx outcome;
+ };
+ using RequireExSet = std::set<RequireEx>;
}
static RequireCompositionResult composeRequirement(const RequireEx & a, const RequireEx & b)
{
- assert(a.uid == b.uid);
- RequireEx out;
- out.uid = a.uid;
- out.indexOfFirstDependee = std::min(a.indexOfFirstDependee, b.indexOfFirstDependee);
- if(a.equalsVersion.isEmpty())
- {
- out.equalsVersion = b.equalsVersion;
- }
- else if (b.equalsVersion.isEmpty())
- {
- out.equalsVersion = a.equalsVersion;
- }
- else if (a.equalsVersion == b.equalsVersion)
- {
- out.equalsVersion = a.equalsVersion;
- }
- else
- {
- // FIXME: mark error as explicit version conflict
- return {false, out};
- }
-
- if(a.suggests.isEmpty())
- {
- out.suggests = b.suggests;
- }
- else if (b.suggests.isEmpty())
- {
- out.suggests = a.suggests;
- }
- else
- {
- Version aVer(a.suggests);
- Version bVer(b.suggests);
- out.suggests = (aVer < bVer ? b.suggests : a.suggests);
- }
- return {true, out};
+ assert(a.uid == b.uid);
+ RequireEx out;
+ out.uid = a.uid;
+ out.indexOfFirstDependee = std::min(a.indexOfFirstDependee, b.indexOfFirstDependee);
+ if(a.equalsVersion.isEmpty())
+ {
+ out.equalsVersion = b.equalsVersion;
+ }
+ else if (b.equalsVersion.isEmpty())
+ {
+ out.equalsVersion = a.equalsVersion;
+ }
+ else if (a.equalsVersion == b.equalsVersion)
+ {
+ out.equalsVersion = a.equalsVersion;
+ }
+ else
+ {
+ // FIXME: mark error as explicit version conflict
+ return {false, out};
+ }
+
+ if(a.suggests.isEmpty())
+ {
+ out.suggests = b.suggests;
+ }
+ else if (b.suggests.isEmpty())
+ {
+ out.suggests = a.suggests;
+ }
+ else
+ {
+ Version aVer(a.suggests);
+ Version bVer(b.suggests);
+ out.suggests = (aVer < bVer ? b.suggests : a.suggests);
+ }
+ return {true, out};
}
// gather the requirements from all components, finding any obvious conflicts
static bool gatherRequirementsFromComponents(const ComponentContainer & input, RequireExSet & output)
{
- bool succeeded = true;
- size_t componentNum = 0;
- for(auto component: input)
- {
- auto &componentRequires = component->m_cachedRequires;
- for(const auto & componentRequire: componentRequires)
- {
- auto found = std::find_if(output.cbegin(), output.cend(), [componentRequire](const Meta::Require & req){
- return req.uid == componentRequire.uid;
- });
-
- RequireEx componenRequireEx;
- componenRequireEx.uid = componentRequire.uid;
- componenRequireEx.suggests = componentRequire.suggests;
- componenRequireEx.equalsVersion = componentRequire.equalsVersion;
- componenRequireEx.indexOfFirstDependee = componentNum;
-
- if(found != output.cend())
- {
- // found... process it further
- auto result = composeRequirement(componenRequireEx, *found);
- if(result.ok)
- {
- output.erase(componenRequireEx);
- output.insert(result.outcome);
- }
- else
- {
- qCritical()
- << "Conflicting requirements:"
- << componentRequire.uid
- << "versions:"
- << componentRequire.equalsVersion
- << ";"
- << (*found).equalsVersion;
- }
- succeeded &= result.ok;
- }
- else
- {
- // not found, accumulate
- output.insert(componenRequireEx);
- }
- }
- componentNum++;
- }
- return succeeded;
+ bool succeeded = true;
+ size_t componentNum = 0;
+ for(auto component: input)
+ {
+ auto &componentRequires = component->m_cachedRequires;
+ for(const auto & componentRequire: componentRequires)
+ {
+ auto found = std::find_if(output.cbegin(), output.cend(), [componentRequire](const Meta::Require & req){
+ return req.uid == componentRequire.uid;
+ });
+
+ RequireEx componenRequireEx;
+ componenRequireEx.uid = componentRequire.uid;
+ componenRequireEx.suggests = componentRequire.suggests;
+ componenRequireEx.equalsVersion = componentRequire.equalsVersion;
+ componenRequireEx.indexOfFirstDependee = componentNum;
+
+ if(found != output.cend())
+ {
+ // found... process it further
+ auto result = composeRequirement(componenRequireEx, *found);
+ if(result.ok)
+ {
+ output.erase(componenRequireEx);
+ output.insert(result.outcome);
+ }
+ else
+ {
+ qCritical()
+ << "Conflicting requirements:"
+ << componentRequire.uid
+ << "versions:"
+ << componentRequire.equalsVersion
+ << ";"
+ << (*found).equalsVersion;
+ }
+ succeeded &= result.ok;
+ }
+ else
+ {
+ // not found, accumulate
+ output.insert(componenRequireEx);
+ }
+ }
+ componentNum++;
+ }
+ return succeeded;
}
/// Get list of uids that can be trivially removed because nothing is depending on them anymore (and they are installed as deps)
static void getTrivialRemovals(const ComponentContainer & components, const RequireExSet & reqs, QStringList &toRemove)
{
- for(const auto & component: components)
- {
- if(!component->m_dependencyOnly)
- continue;
- if(!component->m_cachedVolatile)
- continue;
- RequireEx reqNeedle;
- reqNeedle.uid = component->m_uid;
- const auto iter = reqs.find(reqNeedle);
- if(iter == reqs.cend())
- {
- toRemove.append(component->m_uid);
- }
- }
+ for(const auto & component: components)
+ {
+ if(!component->m_dependencyOnly)
+ continue;
+ if(!component->m_cachedVolatile)
+ continue;
+ RequireEx reqNeedle;
+ reqNeedle.uid = component->m_uid;
+ const auto iter = reqs.find(reqNeedle);
+ if(iter == reqs.cend())
+ {
+ toRemove.append(component->m_uid);
+ }
+ }
}
/**
@@ -408,86 +408,86 @@ static void getTrivialRemovals(const ComponentContainer & components, const Requ
*/
static bool getTrivialComponentChanges(const ComponentIndex & index, const RequireExSet & input, RequireExSet & toAdd, RequireExSet & toChange)
{
- enum class Decision
- {
- Undetermined,
- Met,
- Missing,
- VersionNotSame,
- LockedVersionNotSame
- } decision = Decision::Undetermined;
-
- QString reqStr;
- bool succeeded = true;
- // list the composed requirements and say if they are met or unmet
- for(auto & req: input)
- {
- do
- {
- if(req.equalsVersion.isEmpty())
- {
- reqStr = QString("Req: %1").arg(req.uid);
- if(index.contains(req.uid))
- {
- decision = Decision::Met;
- }
- else
- {
- toAdd.insert(req);
- decision = Decision::Missing;
- }
- break;
- }
- else
- {
- reqStr = QString("Req: %1 == %2").arg(req.uid, req.equalsVersion);
- const auto & compIter = index.find(req.uid);
- if(compIter == index.cend())
- {
- toAdd.insert(req);
- decision = Decision::Missing;
- break;
- }
- auto & comp = (*compIter);
- if(comp->getVersion() != req.equalsVersion)
- {
- if(comp->m_dependencyOnly)
- {
- decision = Decision::VersionNotSame;
- }
- else
- {
- decision = Decision::LockedVersionNotSame;
- }
- break;
- }
- decision = Decision::Met;
- }
- } while(false);
- switch(decision)
- {
- case Decision::Undetermined:
- qCritical() << "No decision for" << reqStr;
- succeeded = false;
- break;
- case Decision::Met:
- qDebug() << reqStr << "Is met.";
- break;
- case Decision::Missing:
- qDebug() << reqStr << "Is missing and should be added at" << req.indexOfFirstDependee;
- toAdd.insert(req);
- break;
- case Decision::VersionNotSame:
- qDebug() << reqStr << "already has different version that can be changed.";
- toChange.insert(req);
- break;
- case Decision::LockedVersionNotSame:
- qDebug() << reqStr << "already has different version that cannot be changed.";
- succeeded = false;
- break;
- }
- }
- return succeeded;
+ enum class Decision
+ {
+ Undetermined,
+ Met,
+ Missing,
+ VersionNotSame,
+ LockedVersionNotSame
+ } decision = Decision::Undetermined;
+
+ QString reqStr;
+ bool succeeded = true;
+ // list the composed requirements and say if they are met or unmet
+ for(auto & req: input)
+ {
+ do
+ {
+ if(req.equalsVersion.isEmpty())
+ {
+ reqStr = QString("Req: %1").arg(req.uid);
+ if(index.contains(req.uid))
+ {
+ decision = Decision::Met;
+ }
+ else
+ {
+ toAdd.insert(req);
+ decision = Decision::Missing;
+ }
+ break;
+ }
+ else
+ {
+ reqStr = QString("Req: %1 == %2").arg(req.uid, req.equalsVersion);
+ const auto & compIter = index.find(req.uid);
+ if(compIter == index.cend())
+ {
+ toAdd.insert(req);
+ decision = Decision::Missing;
+ break;
+ }
+ auto & comp = (*compIter);
+ if(comp->getVersion() != req.equalsVersion)
+ {
+ if(comp->m_dependencyOnly)
+ {
+ decision = Decision::VersionNotSame;
+ }
+ else
+ {
+ decision = Decision::LockedVersionNotSame;
+ }
+ break;
+ }
+ decision = Decision::Met;
+ }
+ } while(false);
+ switch(decision)
+ {
+ case Decision::Undetermined:
+ qCritical() << "No decision for" << reqStr;
+ succeeded = false;
+ break;
+ case Decision::Met:
+ qDebug() << reqStr << "Is met.";
+ break;
+ case Decision::Missing:
+ qDebug() << reqStr << "Is missing and should be added at" << req.indexOfFirstDependee;
+ toAdd.insert(req);
+ break;
+ case Decision::VersionNotSame:
+ qDebug() << reqStr << "already has different version that can be changed.";
+ toChange.insert(req);
+ break;
+ case Decision::LockedVersionNotSame:
+ qDebug() << reqStr << "already has different version that cannot be changed.";
+ succeeded = false;
+ break;
+ }
+ }
+ return succeeded;
}
// FIXME, TODO: decouple dependency resolution from loading
@@ -495,197 +495,197 @@ static bool getTrivialComponentChanges(const ComponentIndex & index, const Requi
// FIXME: throw all this away and use a graph
void ComponentUpdateTask::resolveDependencies(bool checkOnly)
{
- qDebug() << "Resolving dependencies";
- /*
- * this is a naive dependency resolving algorithm. all it does is check for following conditions and react in simple ways:
- * 1. There are conflicting dependencies on the same uid with different exact version numbers
- * -> hard error
- * 2. A dependency has non-matching exact version number
- * -> hard error
- * 3. A dependency is entirely missing and needs to be injected before the dependee(s)
- * -> requirements are injected
- *
- * NOTE: this is a placeholder and should eventually be replaced with something 'serious'
- */
- auto & components = d->m_list->d->components;
- auto & componentIndex = d->m_list->d->componentIndex;
-
- RequireExSet allRequires;
- QStringList toRemove;
- do
- {
- allRequires.clear();
- toRemove.clear();
- if(!gatherRequirementsFromComponents(components, allRequires))
- {
- emitFailed(tr("Conflicting requirements detected during dependency checking!"));
- return;
- }
- getTrivialRemovals(components, allRequires, toRemove);
- if(!toRemove.isEmpty())
- {
- qDebug() << "Removing obsolete components...";
- for(auto & remove : toRemove)
- {
- qDebug() << "Removing" << remove;
- d->m_list->remove(remove);
- }
- }
- } while (!toRemove.isEmpty());
- RequireExSet toAdd;
- RequireExSet toChange;
- bool succeeded = getTrivialComponentChanges(componentIndex, allRequires, toAdd, toChange);
- if(!succeeded)
- {
- emitFailed(tr("Instance has conflicting dependencies."));
- return;
- }
- if(checkOnly)
- {
- if(toAdd.size() || toChange.size())
- {
- emitFailed(tr("Instance has unresolved dependencies while loading/checking for launch."));
- }
- else
- {
- emitSucceeded();
- }
- return;
- }
-
- bool recursionNeeded = false;
- if(toAdd.size())
- {
- // add stuff...
- for(auto &add: toAdd)
- {
- ComponentPtr component = new Component(d->m_list, add.uid);
- if(!add.equalsVersion.isEmpty())
- {
- // exact version
- qDebug() << "Adding" << add.uid << "version" << add.equalsVersion << "at position" << add.indexOfFirstDependee;
- component->m_version = add.equalsVersion;
- }
- else
- {
- // version needs to be decided
- qDebug() << "Adding" << add.uid << "at position" << add.indexOfFirstDependee;
+ qDebug() << "Resolving dependencies";
+ /*
+ * this is a naive dependency resolving algorithm. all it does is check for following conditions and react in simple ways:
+ * 1. There are conflicting dependencies on the same uid with different exact version numbers
+ * -> hard error
+ * 2. A dependency has non-matching exact version number
+ * -> hard error
+ * 3. A dependency is entirely missing and needs to be injected before the dependee(s)
+ * -> requirements are injected
+ *
+ * NOTE: this is a placeholder and should eventually be replaced with something 'serious'
+ */
+ auto & components = d->m_list->d->components;
+ auto & componentIndex = d->m_list->d->componentIndex;
+
+ RequireExSet allRequires;
+ QStringList toRemove;
+ do
+ {
+ allRequires.clear();
+ toRemove.clear();
+ if(!gatherRequirementsFromComponents(components, allRequires))
+ {
+ emitFailed(tr("Conflicting requirements detected during dependency checking!"));
+ return;
+ }
+ getTrivialRemovals(components, allRequires, toRemove);
+ if(!toRemove.isEmpty())
+ {
+ qDebug() << "Removing obsolete components...";
+ for(auto & remove : toRemove)
+ {
+ qDebug() << "Removing" << remove;
+ d->m_list->remove(remove);
+ }
+ }
+ } while (!toRemove.isEmpty());
+ RequireExSet toAdd;
+ RequireExSet toChange;
+ bool succeeded = getTrivialComponentChanges(componentIndex, allRequires, toAdd, toChange);
+ if(!succeeded)
+ {
+ emitFailed(tr("Instance has conflicting dependencies."));
+ return;
+ }
+ if(checkOnly)
+ {
+ if(toAdd.size() || toChange.size())
+ {
+ emitFailed(tr("Instance has unresolved dependencies while loading/checking for launch."));
+ }
+ else
+ {
+ emitSucceeded();
+ }
+ return;
+ }
+
+ bool recursionNeeded = false;
+ if(toAdd.size())
+ {
+ // add stuff...
+ for(auto &add: toAdd)
+ {
+ ComponentPtr component = new Component(d->m_list, add.uid);
+ if(!add.equalsVersion.isEmpty())
+ {
+ // exact version
+ qDebug() << "Adding" << add.uid << "version" << add.equalsVersion << "at position" << add.indexOfFirstDependee;
+ component->m_version = add.equalsVersion;
+ }
+ else
+ {
+ // version needs to be decided
+ qDebug() << "Adding" << add.uid << "at position" << add.indexOfFirstDependee;
// ############################################################################################################
// HACK HACK HACK HACK FIXME: this is a placeholder for deciding what version to use. For now, it is hardcoded.
- if(!add.suggests.isEmpty())
- {
- component->m_version = add.suggests;
- }
- else
- {
- if(add.uid == "org.lwjgl")
- {
- component->m_version = "2.9.1";
- }
- else if (add.uid == "org.lwjgl3")
- {
- component->m_version = "3.1.2";
- }
- }
+ if(!add.suggests.isEmpty())
+ {
+ component->m_version = add.suggests;
+ }
+ else
+ {
+ if(add.uid == "org.lwjgl")
+ {
+ component->m_version = "2.9.1";
+ }
+ else if (add.uid == "org.lwjgl3")
+ {
+ component->m_version = "3.1.2";
+ }
+ }
// HACK HACK HACK HACK FIXME: this is a placeholder for deciding what version to use. For now, it is hardcoded.
// ############################################################################################################
- }
- component->m_dependencyOnly = true;
- // FIXME: this should not work directly with the component list
- d->m_list->insertComponent(add.indexOfFirstDependee, component);
- componentIndex[add.uid] = component;
- }
- recursionNeeded = true;
- }
- if(toChange.size())
- {
- // change a version of something that exists
- for(auto &change: toChange)
- {
- // FIXME: this should not work directly with the component list
- qDebug() << "Setting version of " << change.uid << "to" << change.equalsVersion;
- auto component = componentIndex[change.uid];
- component->setVersion(change.equalsVersion);
- }
- recursionNeeded = true;
- }
-
- if(recursionNeeded)
- {
- loadComponents();
- }
- else
- {
- emitSucceeded();
- }
+ }
+ component->m_dependencyOnly = true;
+ // FIXME: this should not work directly with the component list
+ d->m_list->insertComponent(add.indexOfFirstDependee, component);
+ componentIndex[add.uid] = component;
+ }
+ recursionNeeded = true;
+ }
+ if(toChange.size())
+ {
+ // change a version of something that exists
+ for(auto &change: toChange)
+ {
+ // FIXME: this should not work directly with the component list
+ qDebug() << "Setting version of " << change.uid << "to" << change.equalsVersion;
+ auto component = componentIndex[change.uid];
+ component->setVersion(change.equalsVersion);
+ }
+ recursionNeeded = true;
+ }
+
+ if(recursionNeeded)
+ {
+ loadComponents();
+ }
+ else
+ {
+ emitSucceeded();
+ }
}
void ComponentUpdateTask::remoteLoadSucceeded(size_t taskIndex)
{
- auto &taskSlot = d->remoteLoadStatusList[taskIndex];
- if(taskSlot.finished)
- {
- qWarning() << "Got multiple results from remote load task" << taskIndex;
- return;
- }
- qDebug() << "Remote task" << taskIndex << "succeeded";
- taskSlot.succeeded = false;
- taskSlot.finished = true;
- d->remoteTasksInProgress --;
- // update the cached data of the component from the downloaded version file.
- if (taskSlot.type == RemoteLoadStatus::Type::Version)
- {
- auto component = d->m_list->getComponent(taskSlot.componentListIndex);
- component->m_loaded = true;
- component->updateCachedData();
- }
- checkIfAllFinished();
+ auto &taskSlot = d->remoteLoadStatusList[taskIndex];
+ if(taskSlot.finished)
+ {
+ qWarning() << "Got multiple results from remote load task" << taskIndex;
+ return;
+ }
+ qDebug() << "Remote task" << taskIndex << "succeeded";
+ taskSlot.succeeded = false;
+ taskSlot.finished = true;
+ d->remoteTasksInProgress --;
+ // update the cached data of the component from the downloaded version file.
+ if (taskSlot.type == RemoteLoadStatus::Type::Version)
+ {
+ auto component = d->m_list->getComponent(taskSlot.componentListIndex);
+ component->m_loaded = true;
+ component->updateCachedData();
+ }
+ checkIfAllFinished();
}
void ComponentUpdateTask::remoteLoadFailed(size_t taskIndex, const QString& msg)
{
- auto &taskSlot = d->remoteLoadStatusList[taskIndex];
- if(taskSlot.finished)
- {
- qWarning() << "Got multiple results from remote load task" << taskIndex;
- return;
- }
- qDebug() << "Remote task" << taskIndex << "failed: " << msg;
- d->remoteLoadSuccessful = false;
- taskSlot.succeeded = false;
- taskSlot.finished = true;
- taskSlot.error = msg;
- d->remoteTasksInProgress --;
- checkIfAllFinished();
+ auto &taskSlot = d->remoteLoadStatusList[taskIndex];
+ if(taskSlot.finished)
+ {
+ qWarning() << "Got multiple results from remote load task" << taskIndex;
+ return;
+ }
+ qDebug() << "Remote task" << taskIndex << "failed: " << msg;
+ d->remoteLoadSuccessful = false;
+ taskSlot.succeeded = false;
+ taskSlot.finished = true;
+ taskSlot.error = msg;
+ d->remoteTasksInProgress --;
+ checkIfAllFinished();
}
void ComponentUpdateTask::checkIfAllFinished()
{
- if(d->remoteTasksInProgress)
- {
- // not yet...
- return;
- }
- if(d->remoteLoadSuccessful)
- {
- // nothing bad happened... clear the temp load status and proceed with looking at dependencies
- d->remoteLoadStatusList.clear();
- resolveDependencies(d->mode == Mode::Launch);
- }
- else
- {
- // remote load failed... report error and bail
- QStringList allErrorsList;
- for(auto & item: d->remoteLoadStatusList)
- {
- if(!item.succeeded)
- {
- allErrorsList.append(item.error);
- }
- }
- auto allErrors = allErrorsList.join("\n");
- emitFailed(tr("Component metadata update task failed while downloading from remote server:\n%1").arg(allErrors));
- d->remoteLoadStatusList.clear();
- }
+ if(d->remoteTasksInProgress)
+ {
+ // not yet...
+ return;
+ }
+ if(d->remoteLoadSuccessful)
+ {
+ // nothing bad happened... clear the temp load status and proceed with looking at dependencies
+ d->remoteLoadStatusList.clear();
+ resolveDependencies(d->mode == Mode::Launch);
+ }
+ else
+ {
+ // remote load failed... report error and bail
+ QStringList allErrorsList;
+ for(auto & item: d->remoteLoadStatusList)
+ {
+ if(!item.succeeded)
+ {
+ allErrorsList.append(item.error);
+ }
+ }
+ auto allErrors = allErrorsList.join("\n");
+ emitFailed(tr("Component metadata update task failed while downloading from remote server:\n%1").arg(allErrors));
+ d->remoteLoadStatusList.clear();
+ }
}
diff --git a/api/logic/minecraft/ComponentUpdateTask.h b/api/logic/minecraft/ComponentUpdateTask.h
index 11d122b6..4cb29a89 100644
--- a/api/logic/minecraft/ComponentUpdateTask.h
+++ b/api/logic/minecraft/ComponentUpdateTask.h
@@ -9,29 +9,29 @@ struct ComponentUpdateTaskData;
class ComponentUpdateTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum class Mode
- {
- Launch,
- Resolution
- };
+ enum class Mode
+ {
+ Launch,
+ Resolution
+ };
public:
- explicit ComponentUpdateTask(Mode mode, Net::Mode netmode, ComponentList * list, QObject *parent = 0);
- virtual ~ComponentUpdateTask();
+ explicit ComponentUpdateTask(Mode mode, Net::Mode netmode, ComponentList * list, QObject *parent = 0);
+ virtual ~ComponentUpdateTask();
protected:
- void executeTask();
+ void executeTask();
private:
- void loadComponents();
- void resolveDependencies(bool checkOnly);
+ void loadComponents();
+ void resolveDependencies(bool checkOnly);
- void remoteLoadSucceeded(size_t index);
- void remoteLoadFailed(size_t index, const QString &msg);
- void checkIfAllFinished();
+ void remoteLoadSucceeded(size_t index);
+ void remoteLoadFailed(size_t index, const QString &msg);
+ void checkIfAllFinished();
private:
- std::unique_ptr<ComponentUpdateTaskData> d;
+ std::unique_ptr<ComponentUpdateTaskData> d;
};
diff --git a/api/logic/minecraft/ComponentUpdateTask_p.h b/api/logic/minecraft/ComponentUpdateTask_p.h
index a5216506..5989cf07 100644
--- a/api/logic/minecraft/ComponentUpdateTask_p.h
+++ b/api/logic/minecraft/ComponentUpdateTask_p.h
@@ -9,24 +9,24 @@ class ComponentList;
struct RemoteLoadStatus
{
- enum class Type
- {
- Index,
- List,
- Version
- } type = Type::Version;
- size_t componentListIndex = 0;
- bool finished = false;
- bool succeeded = false;
- QString error;
+ enum class Type
+ {
+ Index,
+ List,
+ Version
+ } type = Type::Version;
+ size_t componentListIndex = 0;
+ bool finished = false;
+ bool succeeded = false;
+ QString error;
};
struct ComponentUpdateTaskData
{
- ComponentList * m_list = nullptr;
- QList<RemoteLoadStatus> remoteLoadStatusList;
- bool remoteLoadSuccessful = true;
- size_t remoteTasksInProgress = 0;
- ComponentUpdateTask::Mode mode;
- Net::Mode netmode;
+ ComponentList * m_list = nullptr;
+ QList<RemoteLoadStatus> remoteLoadStatusList;
+ bool remoteLoadSuccessful = true;
+ size_t remoteTasksInProgress = 0;
+ ComponentUpdateTask::Mode mode;
+ Net::Mode netmode;
};
diff --git a/api/logic/minecraft/GradleSpecifier.h b/api/logic/minecraft/GradleSpecifier.h
index f842008c..959325c6 100644
--- a/api/logic/minecraft/GradleSpecifier.h
+++ b/api/logic/minecraft/GradleSpecifier.h
@@ -6,138 +6,138 @@
struct GradleSpecifier
{
- GradleSpecifier()
- {
- m_valid = false;
- }
- GradleSpecifier(QString value)
- {
- operator=(value);
- }
- GradleSpecifier & operator =(const QString & value)
- {
- /*
- org.gradle.test.classifiers : service : 1.0 : jdk15 @ jar
- DEBUG 0 "org.gradle.test.classifiers:service:1.0:jdk15@jar"
- DEBUG 1 "org.gradle.test.classifiers"
- DEBUG 2 "service"
- DEBUG 3 "1.0"
- DEBUG 4 ":jdk15"
- DEBUG 5 "jdk15"
- DEBUG 6 "@jar"
- DEBUG 7 "jar"
- */
- QRegExp matcher("([^:@]+):([^:@]+):([^:@]+)" "(:([^:@]+))?" "(@([^:@]+))?");
- m_valid = matcher.exactMatch(value);
- auto elements = matcher.capturedTexts();
- m_groupId = elements[1];
- m_artifactId = elements[2];
- m_version = elements[3];
- m_classifier = elements[5];
- if(!elements[7].isEmpty())
- {
- m_extension = elements[7];
- }
- return *this;
- }
- operator QString() const
- {
- if(!m_valid)
- return "INVALID";
- QString retval = m_groupId + ":" + m_artifactId + ":" + m_version;
- if(!m_classifier.isEmpty())
- {
- retval += ":" + m_classifier;
- }
- if(m_extension.isExplicit())
- {
- retval += "@" + m_extension;
- }
- return retval;
- }
- QString getFileName() const
- {
- QString filename = m_artifactId + '-' + m_version;
- if(!m_classifier.isEmpty())
- {
- filename += "-" + m_classifier;
- }
- filename += "." + m_extension;
- return filename;
- }
- QString toPath(const QString & filenameOverride = QString()) const
- {
- if(!m_valid)
- return "INVALID";
- QString filename;
- if(filenameOverride.isEmpty())
- {
- filename = getFileName();
- }
- else
- {
- filename = filenameOverride;
- }
- QString path = m_groupId;
- path.replace('.', '/');
- path += '/' + m_artifactId + '/' + m_version + '/' + filename;
- return path;
- }
- inline bool valid() const
- {
- return m_valid;
- }
- inline QString version() const
- {
- return m_version;
- }
- inline QString groupId() const
- {
- return m_groupId;
- }
- inline QString artifactId() const
- {
- return m_artifactId;
- }
- inline void setClassifier(const QString & classifier)
- {
- m_classifier = classifier;
- }
- inline QString classifier() const
- {
- return m_classifier;
- }
- inline QString extension() const
- {
- return m_extension;
- }
- inline QString artifactPrefix() const
- {
- return m_groupId + ":" + m_artifactId;
- }
- bool matchName(const GradleSpecifier & other) const
- {
- return other.artifactId() == artifactId() && other.groupId() == groupId();
- }
- bool operator==(const GradleSpecifier & other) const
- {
- if(m_groupId != other.m_groupId)
- return false;
- if(m_artifactId != other.m_artifactId)
- return false;
- if(m_version != other.m_version)
- return false;
- if(m_classifier != other.m_classifier)
- return false;
- if(m_extension != other.m_extension)
- return false;
- return true;
- }
+ GradleSpecifier()
+ {
+ m_valid = false;
+ }
+ GradleSpecifier(QString value)
+ {
+ operator=(value);
+ }
+ GradleSpecifier & operator =(const QString & value)
+ {
+ /*
+ org.gradle.test.classifiers : service : 1.0 : jdk15 @ jar
+ DEBUG 0 "org.gradle.test.classifiers:service:1.0:jdk15@jar"
+ DEBUG 1 "org.gradle.test.classifiers"
+ DEBUG 2 "service"
+ DEBUG 3 "1.0"
+ DEBUG 4 ":jdk15"
+ DEBUG 5 "jdk15"
+ DEBUG 6 "@jar"
+ DEBUG 7 "jar"
+ */
+ QRegExp matcher("([^:@]+):([^:@]+):([^:@]+)" "(:([^:@]+))?" "(@([^:@]+))?");
+ m_valid = matcher.exactMatch(value);
+ auto elements = matcher.capturedTexts();
+ m_groupId = elements[1];
+ m_artifactId = elements[2];
+ m_version = elements[3];
+ m_classifier = elements[5];
+ if(!elements[7].isEmpty())
+ {
+ m_extension = elements[7];
+ }
+ return *this;
+ }
+ operator QString() const
+ {
+ if(!m_valid)
+ return "INVALID";
+ QString retval = m_groupId + ":" + m_artifactId + ":" + m_version;
+ if(!m_classifier.isEmpty())
+ {
+ retval += ":" + m_classifier;
+ }
+ if(m_extension.isExplicit())
+ {
+ retval += "@" + m_extension;
+ }
+ return retval;
+ }
+ QString getFileName() const
+ {
+ QString filename = m_artifactId + '-' + m_version;
+ if(!m_classifier.isEmpty())
+ {
+ filename += "-" + m_classifier;
+ }
+ filename += "." + m_extension;
+ return filename;
+ }
+ QString toPath(const QString & filenameOverride = QString()) const
+ {
+ if(!m_valid)
+ return "INVALID";
+ QString filename;
+ if(filenameOverride.isEmpty())
+ {
+ filename = getFileName();
+ }
+ else
+ {
+ filename = filenameOverride;
+ }
+ QString path = m_groupId;
+ path.replace('.', '/');
+ path += '/' + m_artifactId + '/' + m_version + '/' + filename;
+ return path;
+ }
+ inline bool valid() const
+ {
+ return m_valid;
+ }
+ inline QString version() const
+ {
+ return m_version;
+ }
+ inline QString groupId() const
+ {
+ return m_groupId;
+ }
+ inline QString artifactId() const
+ {
+ return m_artifactId;
+ }
+ inline void setClassifier(const QString & classifier)
+ {
+ m_classifier = classifier;
+ }
+ inline QString classifier() const
+ {
+ return m_classifier;
+ }
+ inline QString extension() const
+ {
+ return m_extension;
+ }
+ inline QString artifactPrefix() const
+ {
+ return m_groupId + ":" + m_artifactId;
+ }
+ bool matchName(const GradleSpecifier & other) const
+ {
+ return other.artifactId() == artifactId() && other.groupId() == groupId();
+ }
+ bool operator==(const GradleSpecifier & other) const
+ {
+ if(m_groupId != other.m_groupId)
+ return false;
+ if(m_artifactId != other.m_artifactId)
+ return false;
+ if(m_version != other.m_version)
+ return false;
+ if(m_classifier != other.m_classifier)
+ return false;
+ if(m_extension != other.m_extension)
+ return false;
+ return true;
+ }
private:
- QString m_groupId;
- QString m_artifactId;
- QString m_version;
- QString m_classifier;
- DefaultVariable<QString> m_extension = DefaultVariable<QString>("jar");
- bool m_valid = false;
+ QString m_groupId;
+ QString m_artifactId;
+ QString m_version;
+ QString m_classifier;
+ DefaultVariable<QString> m_extension = DefaultVariable<QString>("jar");
+ bool m_valid = false;
};
diff --git a/api/logic/minecraft/GradleSpecifier_test.cpp b/api/logic/minecraft/GradleSpecifier_test.cpp
index 155522cd..f49ec718 100644
--- a/api/logic/minecraft/GradleSpecifier_test.cpp
+++ b/api/logic/minecraft/GradleSpecifier_test.cpp
@@ -5,71 +5,71 @@
class GradleSpecifierTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- void initTestCase()
- {
-
- }
- void cleanupTestCase()
- {
-
- }
-
- void test_Positive_data()
- {
- QTest::addColumn<QString>("through");
-
- QTest::newRow("3 parter") << "org.gradle.test.classifiers:service:1.0";
- QTest::newRow("classifier") << "org.gradle.test.classifiers:service:1.0:jdk15";
- QTest::newRow("jarextension") << "org.gradle.test.classifiers:service:1.0@jar";
- QTest::newRow("jarboth") << "org.gradle.test.classifiers:service:1.0:jdk15@jar";
- QTest::newRow("packxz") << "org.gradle.test.classifiers:service:1.0:jdk15@jar.pack.xz";
- }
- void test_Positive()
- {
- QFETCH(QString, through);
-
- QString converted = GradleSpecifier(through);
-
- QCOMPARE(converted, through);
- }
-
- void test_Path_data()
- {
- QTest::addColumn<QString>("spec");
- QTest::addColumn<QString>("expected");
-
- QTest::newRow("3 parter") << "group.id:artifact:1.0" << "group/id/artifact/1.0/artifact-1.0.jar";
- QTest::newRow("doom") << "id.software:doom:1.666:demons@wad" << "id/software/doom/1.666/doom-1.666-demons.wad";
- }
- void test_Path()
- {
- QFETCH(QString, spec);
- QFETCH(QString, expected);
-
- QString converted = GradleSpecifier(spec).toPath();
-
- QCOMPARE(converted, expected);
- }
- void test_Negative_data()
- {
- QTest::addColumn<QString>("input");
-
- QTest::newRow("too many :") << "org:gradle.test:class:::ifiers:service:1.0::";
- QTest::newRow("nonsense") << "I like turtles";
- QTest::newRow("empty string") << "";
- QTest::newRow("missing version") << "herp.derp:artifact";
- }
- void test_Negative()
- {
- QFETCH(QString, input);
-
- GradleSpecifier spec(input);
- QVERIFY(!spec.valid());
- QCOMPARE(spec.operator QString(), QString("INVALID"));
- }
+ void initTestCase()
+ {
+
+ }
+ void cleanupTestCase()
+ {
+
+ }
+
+ void test_Positive_data()
+ {
+ QTest::addColumn<QString>("through");
+
+ QTest::newRow("3 parter") << "org.gradle.test.classifiers:service:1.0";
+ QTest::newRow("classifier") << "org.gradle.test.classifiers:service:1.0:jdk15";
+ QTest::newRow("jarextension") << "org.gradle.test.classifiers:service:1.0@jar";
+ QTest::newRow("jarboth") << "org.gradle.test.classifiers:service:1.0:jdk15@jar";
+ QTest::newRow("packxz") << "org.gradle.test.classifiers:service:1.0:jdk15@jar.pack.xz";
+ }
+ void test_Positive()
+ {
+ QFETCH(QString, through);
+
+ QString converted = GradleSpecifier(through);
+
+ QCOMPARE(converted, through);
+ }
+
+ void test_Path_data()
+ {
+ QTest::addColumn<QString>("spec");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("3 parter") << "group.id:artifact:1.0" << "group/id/artifact/1.0/artifact-1.0.jar";
+ QTest::newRow("doom") << "id.software:doom:1.666:demons@wad" << "id/software/doom/1.666/doom-1.666-demons.wad";
+ }
+ void test_Path()
+ {
+ QFETCH(QString, spec);
+ QFETCH(QString, expected);
+
+ QString converted = GradleSpecifier(spec).toPath();
+
+ QCOMPARE(converted, expected);
+ }
+ void test_Negative_data()
+ {
+ QTest::addColumn<QString>("input");
+
+ QTest::newRow("too many :") << "org:gradle.test:class:::ifiers:service:1.0::";
+ QTest::newRow("nonsense") << "I like turtles";
+ QTest::newRow("empty string") << "";
+ QTest::newRow("missing version") << "herp.derp:artifact";
+ }
+ void test_Negative()
+ {
+ QFETCH(QString, input);
+
+ GradleSpecifier spec(input);
+ QVERIFY(!spec.valid());
+ QCOMPARE(spec.operator QString(), QString("INVALID"));
+ }
};
QTEST_GUILESS_MAIN(GradleSpecifierTest)
diff --git a/api/logic/minecraft/LaunchProfile.cpp b/api/logic/minecraft/LaunchProfile.cpp
index 436a39d9..c39bdf04 100644
--- a/api/logic/minecraft/LaunchProfile.cpp
+++ b/api/logic/minecraft/LaunchProfile.cpp
@@ -3,295 +3,295 @@
void LaunchProfile::clear()
{
- m_minecraftVersion.clear();
- m_minecraftVersionType.clear();
- m_minecraftAssets.reset();
- m_minecraftArguments.clear();
- m_tweakers.clear();
- m_mainClass.clear();
- m_appletClass.clear();
- m_libraries.clear();
- m_traits.clear();
- m_jarMods.clear();
- m_mainJar.reset();
- m_problemSeverity = ProblemSeverity::None;
+ m_minecraftVersion.clear();
+ m_minecraftVersionType.clear();
+ m_minecraftAssets.reset();
+ m_minecraftArguments.clear();
+ m_tweakers.clear();
+ m_mainClass.clear();
+ m_appletClass.clear();
+ m_libraries.clear();
+ m_traits.clear();
+ m_jarMods.clear();
+ m_mainJar.reset();
+ m_problemSeverity = ProblemSeverity::None;
}
static void applyString(const QString & from, QString & to)
{
- if(from.isEmpty())
- return;
- to = from;
+ if(from.isEmpty())
+ return;
+ to = from;
}
void LaunchProfile::applyMinecraftVersion(const QString& id)
{
- applyString(id, this->m_minecraftVersion);
+ applyString(id, this->m_minecraftVersion);
}
void LaunchProfile::applyAppletClass(const QString& appletClass)
{
- applyString(appletClass, this->m_appletClass);
+ applyString(appletClass, this->m_appletClass);
}
void LaunchProfile::applyMainClass(const QString& mainClass)
{
- applyString(mainClass, this->m_mainClass);
+ applyString(mainClass, this->m_mainClass);
}
void LaunchProfile::applyMinecraftArguments(const QString& minecraftArguments)
{
- applyString(minecraftArguments, this->m_minecraftArguments);
+ applyString(minecraftArguments, this->m_minecraftArguments);
}
void LaunchProfile::applyMinecraftVersionType(const QString& type)
{
- applyString(type, this->m_minecraftVersionType);
+ applyString(type, this->m_minecraftVersionType);
}
void LaunchProfile::applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets)
{
- if(assets)
- {
- m_minecraftAssets = assets;
- }
+ if(assets)
+ {
+ m_minecraftAssets = assets;
+ }
}
void LaunchProfile::applyTraits(const QSet<QString>& traits)
{
- this->m_traits.unite(traits);
+ this->m_traits.unite(traits);
}
void LaunchProfile::applyTweakers(const QStringList& tweakers)
{
- // if the applied tweakers override an existing one, skip it. this effectively moves it later in the sequence
- QStringList newTweakers;
- for(auto & tweaker: m_tweakers)
- {
- if (tweakers.contains(tweaker))
- {
- continue;
- }
- newTweakers.append(tweaker);
- }
- // then just append the new tweakers (or moved original ones)
- newTweakers += tweakers;
- m_tweakers = newTweakers;
+ // if the applied tweakers override an existing one, skip it. this effectively moves it later in the sequence
+ QStringList newTweakers;
+ for(auto & tweaker: m_tweakers)
+ {
+ if (tweakers.contains(tweaker))
+ {
+ continue;
+ }
+ newTweakers.append(tweaker);
+ }
+ // then just append the new tweakers (or moved original ones)
+ newTweakers += tweakers;
+ m_tweakers = newTweakers;
}
void LaunchProfile::applyJarMods(const QList<LibraryPtr>& jarMods)
{
- this->m_jarMods.append(jarMods);
+ this->m_jarMods.append(jarMods);
}
static int findLibraryByName(QList<LibraryPtr> *haystack, const GradleSpecifier &needle)
{
- int retval = -1;
- for (int i = 0; i < haystack->size(); ++i)
- {
- if (haystack->at(i)->rawName().matchName(needle))
- {
- // only one is allowed.
- if (retval != -1)
- return -1;
- retval = i;
- }
- }
- return retval;
+ int retval = -1;
+ for (int i = 0; i < haystack->size(); ++i)
+ {
+ if (haystack->at(i)->rawName().matchName(needle))
+ {
+ // only one is allowed.
+ if (retval != -1)
+ return -1;
+ retval = i;
+ }
+ }
+ return retval;
}
void LaunchProfile::applyMods(const QList<LibraryPtr>& mods)
{
- QList<LibraryPtr> * list = &m_mods;
- for(auto & mod: mods)
- {
- auto modCopy = Library::limitedCopy(mod);
-
- // find the mod by name.
- const int index = findLibraryByName(list, mod->rawName());
- // mod not found? just add it.
- if (index < 0)
- {
- list->append(modCopy);
- return;
- }
-
- auto existingLibrary = list->at(index);
- // if we are higher it means we should update
- if (Version(mod->version()) > Version(existingLibrary->version()))
- {
- list->replace(index, modCopy);
- }
- }
+ QList<LibraryPtr> * list = &m_mods;
+ for(auto & mod: mods)
+ {
+ auto modCopy = Library::limitedCopy(mod);
+
+ // find the mod by name.
+ const int index = findLibraryByName(list, mod->rawName());
+ // mod not found? just add it.
+ if (index < 0)
+ {
+ list->append(modCopy);
+ return;
+ }
+
+ auto existingLibrary = list->at(index);
+ // if we are higher it means we should update
+ if (Version(mod->version()) > Version(existingLibrary->version()))
+ {
+ list->replace(index, modCopy);
+ }
+ }
}
void LaunchProfile::applyLibrary(LibraryPtr library)
{
- if(!library->isActive())
- {
- return;
- }
+ if(!library->isActive())
+ {
+ return;
+ }
- QList<LibraryPtr> * list = &m_libraries;
- if(library->isNative())
- {
- list = &m_nativeLibraries;
- }
+ QList<LibraryPtr> * list = &m_libraries;
+ if(library->isNative())
+ {
+ list = &m_nativeLibraries;
+ }
- auto libraryCopy = Library::limitedCopy(library);
+ auto libraryCopy = Library::limitedCopy(library);
- // find the library by name.
- const int index = findLibraryByName(list, library->rawName());
- // library not found? just add it.
- if (index < 0)
- {
- list->append(libraryCopy);
- return;
- }
+ // find the library by name.
+ const int index = findLibraryByName(list, library->rawName());
+ // library not found? just add it.
+ if (index < 0)
+ {
+ list->append(libraryCopy);
+ return;
+ }
- auto existingLibrary = list->at(index);
- // if we are higher it means we should update
- if (Version(library->version()) > Version(existingLibrary->version()))
- {
- list->replace(index, libraryCopy);
- }
+ auto existingLibrary = list->at(index);
+ // if we are higher it means we should update
+ if (Version(library->version()) > Version(existingLibrary->version()))
+ {
+ list->replace(index, libraryCopy);
+ }
}
const LibraryPtr LaunchProfile::getMainJar() const
{
- return m_mainJar;
+ return m_mainJar;
}
void LaunchProfile::applyMainJar(LibraryPtr jar)
{
- if(jar)
- {
- m_mainJar = jar;
- }
+ if(jar)
+ {
+ m_mainJar = jar;
+ }
}
void LaunchProfile::applyProblemSeverity(ProblemSeverity severity)
{
- if (m_problemSeverity < severity)
- {
- m_problemSeverity = severity;
- }
+ if (m_problemSeverity < severity)
+ {
+ m_problemSeverity = severity;
+ }
}
const QList<PatchProblem> LaunchProfile::getProblems() const
{
- // FIXME: implement something that actually makes sense here
- return {};
+ // FIXME: implement something that actually makes sense here
+ return {};
}
QString LaunchProfile::getMinecraftVersion() const
{
- return m_minecraftVersion;
+ return m_minecraftVersion;
}
QString LaunchProfile::getAppletClass() const
{
- return m_appletClass;
+ return m_appletClass;
}
QString LaunchProfile::getMainClass() const
{
- return m_mainClass;
+ return m_mainClass;
}
const QSet<QString> &LaunchProfile::getTraits() const
{
- return m_traits;
+ return m_traits;
}
const QStringList & LaunchProfile::getTweakers() const
{
- return m_tweakers;
+ return m_tweakers;
}
bool LaunchProfile::hasTrait(const QString& trait) const
{
- return m_traits.contains(trait);
+ return m_traits.contains(trait);
}
ProblemSeverity LaunchProfile::getProblemSeverity() const
{
- return m_problemSeverity;
+ return m_problemSeverity;
}
QString LaunchProfile::getMinecraftVersionType() const
{
- return m_minecraftVersionType;
+ return m_minecraftVersionType;
}
std::shared_ptr<MojangAssetIndexInfo> LaunchProfile::getMinecraftAssets() const
{
- if(!m_minecraftAssets)
- {
- return std::make_shared<MojangAssetIndexInfo>("legacy");
- }
- return m_minecraftAssets;
+ if(!m_minecraftAssets)
+ {
+ return std::make_shared<MojangAssetIndexInfo>("legacy");
+ }
+ return m_minecraftAssets;
}
QString LaunchProfile::getMinecraftArguments() const
{
- return m_minecraftArguments;
+ return m_minecraftArguments;
}
const QList<LibraryPtr> & LaunchProfile::getJarMods() const
{
- return m_jarMods;
+ return m_jarMods;
}
const QList<LibraryPtr> & LaunchProfile::getLibraries() const
{
- return m_libraries;
+ return m_libraries;
}
const QList<LibraryPtr> & LaunchProfile::getNativeLibraries() const
{
- return m_nativeLibraries;
+ return m_nativeLibraries;
}
void LaunchProfile::getLibraryFiles(
- const QString& architecture,
- QStringList& jars,
- QStringList& nativeJars,
- const QString& overridePath,
- const QString& tempPath
+ const QString& architecture,
+ QStringList& jars,
+ QStringList& nativeJars,
+ const QString& overridePath,
+ const QString& tempPath
) const
{
- QStringList native32, native64;
- jars.clear();
- nativeJars.clear();
- for (auto lib : getLibraries())
- {
- lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
- }
- // NOTE: order is important here, add main jar last to the lists
- if(m_mainJar)
- {
- // FIXME: HACK!! jar modding is weird and unsystematic!
- if(m_jarMods.size())
- {
- QDir tempDir(tempPath);
- jars.append(tempDir.absoluteFilePath("minecraft.jar"));
- }
- else
- {
- m_mainJar->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
- }
- }
- for (auto lib : getNativeLibraries())
- {
- lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
- }
- if(architecture == "32")
- {
- nativeJars.append(native32);
- }
- else if(architecture == "64")
- {
- nativeJars.append(native64);
- }
+ QStringList native32, native64;
+ jars.clear();
+ nativeJars.clear();
+ for (auto lib : getLibraries())
+ {
+ lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
+ }
+ // NOTE: order is important here, add main jar last to the lists
+ if(m_mainJar)
+ {
+ // FIXME: HACK!! jar modding is weird and unsystematic!
+ if(m_jarMods.size())
+ {
+ QDir tempDir(tempPath);
+ jars.append(tempDir.absoluteFilePath("minecraft.jar"));
+ }
+ else
+ {
+ m_mainJar->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
+ }
+ }
+ for (auto lib : getNativeLibraries())
+ {
+ lib->getApplicableFiles(currentSystem, jars, nativeJars, native32, native64, overridePath);
+ }
+ if(architecture == "32")
+ {
+ nativeJars.append(native32);
+ }
+ else if(architecture == "64")
+ {
+ nativeJars.append(native64);
+ }
}
diff --git a/api/logic/minecraft/LaunchProfile.h b/api/logic/minecraft/LaunchProfile.h
index e7f5f4af..77174079 100644
--- a/api/logic/minecraft/LaunchProfile.h
+++ b/api/logic/minecraft/LaunchProfile.h
@@ -6,94 +6,94 @@
class LaunchProfile: public ProblemProvider
{
public:
- virtual ~LaunchProfile() {};
+ virtual ~LaunchProfile() {};
public: /* application of profile variables from patches */
- void applyMinecraftVersion(const QString& id);
- void applyMainClass(const QString& mainClass);
- void applyAppletClass(const QString& appletClass);
- void applyMinecraftArguments(const QString& minecraftArguments);
- void applyMinecraftVersionType(const QString& type);
- void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets);
- void applyTraits(const QSet<QString> &traits);
- void applyTweakers(const QStringList &tweakers);
- void applyJarMods(const QList<LibraryPtr> &jarMods);
- void applyMods(const QList<LibraryPtr> &jarMods);
- void applyLibrary(LibraryPtr library);
- void applyMainJar(LibraryPtr jar);
- void applyProblemSeverity(ProblemSeverity severity);
- /// clear the profile
- void clear();
+ void applyMinecraftVersion(const QString& id);
+ void applyMainClass(const QString& mainClass);
+ void applyAppletClass(const QString& appletClass);
+ void applyMinecraftArguments(const QString& minecraftArguments);
+ void applyMinecraftVersionType(const QString& type);
+ void applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets);
+ void applyTraits(const QSet<QString> &traits);
+ void applyTweakers(const QStringList &tweakers);
+ void applyJarMods(const QList<LibraryPtr> &jarMods);
+ void applyMods(const QList<LibraryPtr> &jarMods);
+ void applyLibrary(LibraryPtr library);
+ void applyMainJar(LibraryPtr jar);
+ void applyProblemSeverity(ProblemSeverity severity);
+ /// clear the profile
+ void clear();
public: /* getters for profile variables */
- QString getMinecraftVersion() const;
- QString getMainClass() const;
- QString getAppletClass() const;
- QString getMinecraftVersionType() const;
- MojangAssetIndexInfo::Ptr getMinecraftAssets() const;
- QString getMinecraftArguments() const;
- const QSet<QString> & getTraits() const;
- const QStringList & getTweakers() const;
- const QList<LibraryPtr> & getJarMods() const;
- const QList<LibraryPtr> & getLibraries() const;
- const QList<LibraryPtr> & getNativeLibraries() const;
- const LibraryPtr getMainJar() const;
- void getLibraryFiles(
- const QString & architecture,
- QStringList & jars,
- QStringList & nativeJars,
- const QString & overridePath,
- const QString & tempPath
- ) const;
- bool hasTrait(const QString & trait) const;
- ProblemSeverity getProblemSeverity() const override;
- const QList<PatchProblem> getProblems() const override;
+ QString getMinecraftVersion() const;
+ QString getMainClass() const;
+ QString getAppletClass() const;
+ QString getMinecraftVersionType() const;
+ MojangAssetIndexInfo::Ptr getMinecraftAssets() const;
+ QString getMinecraftArguments() const;
+ const QSet<QString> & getTraits() const;
+ const QStringList & getTweakers() const;
+ const QList<LibraryPtr> & getJarMods() const;
+ const QList<LibraryPtr> & getLibraries() const;
+ const QList<LibraryPtr> & getNativeLibraries() const;
+ const LibraryPtr getMainJar() const;
+ void getLibraryFiles(
+ const QString & architecture,
+ QStringList & jars,
+ QStringList & nativeJars,
+ const QString & overridePath,
+ const QString & tempPath
+ ) const;
+ bool hasTrait(const QString & trait) const;
+ ProblemSeverity getProblemSeverity() const override;
+ const QList<PatchProblem> getProblems() const override;
private:
- /// the version of Minecraft - jar to use
- QString m_minecraftVersion;
+ /// the version of Minecraft - jar to use
+ QString m_minecraftVersion;
- /// Release type - "release" or "snapshot"
- QString m_minecraftVersionType;
+ /// Release type - "release" or "snapshot"
+ QString m_minecraftVersionType;
- /// Assets type - "legacy" or a version ID
- MojangAssetIndexInfo::Ptr m_minecraftAssets;
+ /// Assets type - "legacy" or a version ID
+ MojangAssetIndexInfo::Ptr m_minecraftAssets;
- /**
- * arguments that should be used for launching minecraft
- *
- * ex: "--username ${auth_player_name} --session ${auth_session}
- * --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}"
- */
- QString m_minecraftArguments;
+ /**
+ * arguments that should be used for launching minecraft
+ *
+ * ex: "--username ${auth_player_name} --session ${auth_session}
+ * --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}"
+ */
+ QString m_minecraftArguments;
- /// A list of all tweaker classes
- QStringList m_tweakers;
+ /// A list of all tweaker classes
+ QStringList m_tweakers;
- /// The main class to load first
- QString m_mainClass;
+ /// The main class to load first
+ QString m_mainClass;
- /// The applet class, for some very old minecraft releases
- QString m_appletClass;
+ /// The applet class, for some very old minecraft releases
+ QString m_appletClass;
- /// the list of libraries
- QList<LibraryPtr> m_libraries;
+ /// the list of libraries
+ QList<LibraryPtr> m_libraries;
- /// the main jar
- LibraryPtr m_mainJar;
+ /// the main jar
+ LibraryPtr m_mainJar;
- /// the list of libraries
- QList<LibraryPtr> m_nativeLibraries;
+ /// the list of libraries
+ QList<LibraryPtr> m_nativeLibraries;
- /// traits, collected from all the version files (version files can only add)
- QSet<QString> m_traits;
+ /// traits, collected from all the version files (version files can only add)
+ QSet<QString> m_traits;
- /// A list of jar mods. version files can add those.
- QList<LibraryPtr> m_jarMods;
+ /// A list of jar mods. version files can add those.
+ QList<LibraryPtr> m_jarMods;
- /// the list of mods
- QList<LibraryPtr> m_mods;
+ /// the list of mods
+ QList<LibraryPtr> m_mods;
- ProblemSeverity m_problemSeverity = ProblemSeverity::None;
+ ProblemSeverity m_problemSeverity = ProblemSeverity::None;
};
diff --git a/api/logic/minecraft/Library.cpp b/api/logic/minecraft/Library.cpp
index 237edaf1..a6ec0301 100644
--- a/api/logic/minecraft/Library.cpp
+++ b/api/logic/minecraft/Library.cpp
@@ -9,316 +9,316 @@
void Library::getApplicableFiles(OpSys system, QStringList& jar, QStringList& native, QStringList& native32,
- QStringList& native64, const QString &overridePath) const
+ QStringList& native64, const QString &overridePath) const
{
- bool local = isLocal();
- auto actualPath = [&](QString relPath)
- {
- QFileInfo out(FS::PathCombine(storagePrefix(), relPath));
- if(local && !overridePath.isEmpty())
- {
- QString fileName = out.fileName();
- auto fullPath = FS::PathCombine(overridePath, fileName);
- qDebug() << fullPath;
- QFileInfo fileinfo(fullPath);
- if(fileinfo.exists())
- {
- return fileinfo.absoluteFilePath();
- }
- }
- return out.absoluteFilePath();
- };
- QString raw_storage = storageSuffix(system);
- if(isNative())
- {
- if (raw_storage.contains("${arch}"))
- {
- auto nat32Storage = raw_storage;
- nat32Storage.replace("${arch}", "32");
- auto nat64Storage = raw_storage;
- nat64Storage.replace("${arch}", "64");
- native32 += actualPath(nat32Storage);
- native64 += actualPath(nat64Storage);
- }
- else
- {
- native += actualPath(raw_storage);
- }
- }
- else
- {
- jar += actualPath(raw_storage);
- }
+ bool local = isLocal();
+ auto actualPath = [&](QString relPath)
+ {
+ QFileInfo out(FS::PathCombine(storagePrefix(), relPath));
+ if(local && !overridePath.isEmpty())
+ {
+ QString fileName = out.fileName();
+ auto fullPath = FS::PathCombine(overridePath, fileName);
+ qDebug() << fullPath;
+ QFileInfo fileinfo(fullPath);
+ if(fileinfo.exists())
+ {
+ return fileinfo.absoluteFilePath();
+ }
+ }
+ return out.absoluteFilePath();
+ };
+ QString raw_storage = storageSuffix(system);
+ if(isNative())
+ {
+ if (raw_storage.contains("${arch}"))
+ {
+ auto nat32Storage = raw_storage;
+ nat32Storage.replace("${arch}", "32");
+ auto nat64Storage = raw_storage;
+ nat64Storage.replace("${arch}", "64");
+ native32 += actualPath(nat32Storage);
+ native64 += actualPath(nat64Storage);
+ }
+ else
+ {
+ native += actualPath(raw_storage);
+ }
+ }
+ else
+ {
+ jar += actualPath(raw_storage);
+ }
}
QList< std::shared_ptr< NetAction > > Library::getDownloads(OpSys system, class HttpMetaCache* cache,
- QStringList& failedFiles, const QString & overridePath) const
+ QStringList& failedFiles, const QString & overridePath) const
{
- QList<NetActionPtr> out;
- bool isAlwaysStale = (hint() == "always-stale");
- bool local = isLocal();
- bool isForge = (hint() == "forge-pack-xz");
+ QList<NetActionPtr> out;
+ bool isAlwaysStale = (hint() == "always-stale");
+ bool local = isLocal();
+ bool isForge = (hint() == "forge-pack-xz");
- auto add_download = [&](QString storage, QString url, QString sha1)
- {
- auto entry = cache->resolveEntry("libraries", storage);
- if(isAlwaysStale)
- {
- entry->setStale(true);
- }
- if (!entry->isStale())
- return true;
- if(local)
- {
- if(!overridePath.isEmpty())
- {
- QString fileName;
- int position = storage.lastIndexOf('/');
- if(position == -1)
- {
- fileName = storage;
- }
- else
- {
- fileName = storage.mid(position);
- }
- auto fullPath = FS::PathCombine(overridePath, fileName);
- QFileInfo fileinfo(fullPath);
- if(fileinfo.exists())
- {
- return true;
- }
- }
- QFileInfo fileinfo(entry->getFullPath());
- if(!fileinfo.exists())
- {
- failedFiles.append(entry->getFullPath());
- return false;
- }
- return true;
- }
- Net::Download::Options options;
- if(isAlwaysStale)
- {
- options |= Net::Download::Option::AcceptLocalFiles;
- }
- if (isForge)
- {
- qDebug() << "XzDownload for:" << rawName() << "storage:" << storage << "url:" << url;
- out.append(ForgeXzDownload::make(storage, entry));
- }
- else
- {
- if(sha1.size())
- {
- auto rawSha1 = QByteArray::fromHex(sha1.toLatin1());
- auto dl = Net::Download::makeCached(url, entry, options);
- dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
- qDebug() << "Checksummed Download for:" << rawName() << "storage:" << storage << "url:" << url;
- out.append(dl);
- }
- else
- {
- out.append(Net::Download::makeCached(url, entry, options));
- qDebug() << "Download for:" << rawName() << "storage:" << storage << "url:" << url;
- }
- }
- return true;
- };
+ auto add_download = [&](QString storage, QString url, QString sha1)
+ {
+ auto entry = cache->resolveEntry("libraries", storage);
+ if(isAlwaysStale)
+ {
+ entry->setStale(true);
+ }
+ if (!entry->isStale())
+ return true;
+ if(local)
+ {
+ if(!overridePath.isEmpty())
+ {
+ QString fileName;
+ int position = storage.lastIndexOf('/');
+ if(position == -1)
+ {
+ fileName = storage;
+ }
+ else
+ {
+ fileName = storage.mid(position);
+ }
+ auto fullPath = FS::PathCombine(overridePath, fileName);
+ QFileInfo fileinfo(fullPath);
+ if(fileinfo.exists())
+ {
+ return true;
+ }
+ }
+ QFileInfo fileinfo(entry->getFullPath());
+ if(!fileinfo.exists())
+ {
+ failedFiles.append(entry->getFullPath());
+ return false;
+ }
+ return true;
+ }
+ Net::Download::Options options;
+ if(isAlwaysStale)
+ {
+ options |= Net::Download::Option::AcceptLocalFiles;
+ }
+ if (isForge)
+ {
+ qDebug() << "XzDownload for:" << rawName() << "storage:" << storage << "url:" << url;
+ out.append(ForgeXzDownload::make(storage, entry));
+ }
+ else
+ {
+ if(sha1.size())
+ {
+ auto rawSha1 = QByteArray::fromHex(sha1.toLatin1());
+ auto dl = Net::Download::makeCached(url, entry, options);
+ dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
+ qDebug() << "Checksummed Download for:" << rawName() << "storage:" << storage << "url:" << url;
+ out.append(dl);
+ }
+ else
+ {
+ out.append(Net::Download::makeCached(url, entry, options));
+ qDebug() << "Download for:" << rawName() << "storage:" << storage << "url:" << url;
+ }
+ }
+ return true;
+ };
- QString raw_storage = storageSuffix(system);
- if(m_mojangDownloads)
- {
- if(isNative())
- {
- if(m_nativeClassifiers.contains(system))
- {
- auto nativeClassifier = m_nativeClassifiers[system];
- if(nativeClassifier.contains("${arch}"))
- {
- auto nat32Classifier = nativeClassifier;
- nat32Classifier.replace("${arch}", "32");
- auto nat64Classifier = nativeClassifier;
- nat64Classifier.replace("${arch}", "64");
- auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier);
- if(nat32info)
- {
- auto cooked_storage = raw_storage;
- cooked_storage.replace("${arch}", "32");
- add_download(cooked_storage, nat32info->url, nat32info->sha1);
- }
- auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier);
- if(nat64info)
- {
- auto cooked_storage = raw_storage;
- cooked_storage.replace("${arch}", "64");
- add_download(cooked_storage, nat64info->url, nat64info->sha1);
- }
- }
- else
- {
- auto info = m_mojangDownloads->getDownloadInfo(nativeClassifier);
- if(info)
- {
- add_download(raw_storage, info->url, info->sha1);
- }
- }
- }
- else
- {
- qDebug() << "Ignoring native library" << m_name << "because it has no classifier for current OS";
- }
- }
- else
- {
- if(m_mojangDownloads->artifact)
- {
- auto artifact = m_mojangDownloads->artifact;
- add_download(raw_storage, artifact->url, artifact->sha1);
- }
- else
- {
- qDebug() << "Ignoring java library" << m_name << "because it has no artifact";
- }
- }
- }
- else
- {
- auto raw_dl = [&](){
- if (!m_absoluteURL.isEmpty())
- {
- return m_absoluteURL;
- }
+ QString raw_storage = storageSuffix(system);
+ if(m_mojangDownloads)
+ {
+ if(isNative())
+ {
+ if(m_nativeClassifiers.contains(system))
+ {
+ auto nativeClassifier = m_nativeClassifiers[system];
+ if(nativeClassifier.contains("${arch}"))
+ {
+ auto nat32Classifier = nativeClassifier;
+ nat32Classifier.replace("${arch}", "32");
+ auto nat64Classifier = nativeClassifier;
+ nat64Classifier.replace("${arch}", "64");
+ auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier);
+ if(nat32info)
+ {
+ auto cooked_storage = raw_storage;
+ cooked_storage.replace("${arch}", "32");
+ add_download(cooked_storage, nat32info->url, nat32info->sha1);
+ }
+ auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier);
+ if(nat64info)
+ {
+ auto cooked_storage = raw_storage;
+ cooked_storage.replace("${arch}", "64");
+ add_download(cooked_storage, nat64info->url, nat64info->sha1);
+ }
+ }
+ else
+ {
+ auto info = m_mojangDownloads->getDownloadInfo(nativeClassifier);
+ if(info)
+ {
+ add_download(raw_storage, info->url, info->sha1);
+ }
+ }
+ }
+ else
+ {
+ qDebug() << "Ignoring native library" << m_name << "because it has no classifier for current OS";
+ }
+ }
+ else
+ {
+ if(m_mojangDownloads->artifact)
+ {
+ auto artifact = m_mojangDownloads->artifact;
+ add_download(raw_storage, artifact->url, artifact->sha1);
+ }
+ else
+ {
+ qDebug() << "Ignoring java library" << m_name << "because it has no artifact";
+ }
+ }
+ }
+ else
+ {
+ auto raw_dl = [&](){
+ if (!m_absoluteURL.isEmpty())
+ {
+ return m_absoluteURL;
+ }
- if (m_repositoryURL.isEmpty())
- {
- return QString("https://" + URLConstants::LIBRARY_BASE) + raw_storage;
- }
+ if (m_repositoryURL.isEmpty())
+ {
+ return QString("https://" + URLConstants::LIBRARY_BASE) + raw_storage;
+ }
- if(m_repositoryURL.endsWith('/'))
- {
- return m_repositoryURL + raw_storage;
- }
- else
- {
- return m_repositoryURL + QChar('/') + raw_storage;
- }
- }();
- if (raw_storage.contains("${arch}"))
- {
- QString cooked_storage = raw_storage;
- QString cooked_dl = raw_dl;
- add_download(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32"), QString());
- cooked_storage = raw_storage;
- cooked_dl = raw_dl;
- add_download(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64"), QString());
- }
- else
- {
- add_download(raw_storage, raw_dl, QString());
- }
- }
- return out;
+ if(m_repositoryURL.endsWith('/'))
+ {
+ return m_repositoryURL + raw_storage;
+ }
+ else
+ {
+ return m_repositoryURL + QChar('/') + raw_storage;
+ }
+ }();
+ if (raw_storage.contains("${arch}"))
+ {
+ QString cooked_storage = raw_storage;
+ QString cooked_dl = raw_dl;
+ add_download(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32"), QString());
+ cooked_storage = raw_storage;
+ cooked_dl = raw_dl;
+ add_download(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64"), QString());
+ }
+ else
+ {
+ add_download(raw_storage, raw_dl, QString());
+ }
+ }
+ return out;
}
bool Library::isActive() const
{
- bool result = true;
- if (m_rules.empty())
- {
- result = true;
- }
- else
- {
- RuleAction ruleResult = Disallow;
- for (auto rule : m_rules)
- {
- RuleAction temp = rule->apply(this);
- if (temp != Defer)
- ruleResult = temp;
- }
- result = result && (ruleResult == Allow);
- }
- if (isNative())
- {
- result = result && m_nativeClassifiers.contains(currentSystem);
- }
- return result;
+ bool result = true;
+ if (m_rules.empty())
+ {
+ result = true;
+ }
+ else
+ {
+ RuleAction ruleResult = Disallow;
+ for (auto rule : m_rules)
+ {
+ RuleAction temp = rule->apply(this);
+ if (temp != Defer)
+ ruleResult = temp;
+ }
+ result = result && (ruleResult == Allow);
+ }
+ if (isNative())
+ {
+ result = result && m_nativeClassifiers.contains(currentSystem);
+ }
+ return result;
}
bool Library::isLocal() const
{
- return m_hint == "local";
+ return m_hint == "local";
}
void Library::setStoragePrefix(QString prefix)
{
- m_storagePrefix = prefix;
+ m_storagePrefix = prefix;
}
QString Library::defaultStoragePrefix()
{
- return "libraries/";
+ return "libraries/";
}
QString Library::storagePrefix() const
{
- if(m_storagePrefix.isEmpty())
- {
- return defaultStoragePrefix();
- }
- return m_storagePrefix;
+ if(m_storagePrefix.isEmpty())
+ {
+ return defaultStoragePrefix();
+ }
+ return m_storagePrefix;
}
QString Library::filename(OpSys system) const
{
- if(!m_filename.isEmpty())
- {
- return m_filename;
- }
- // non-native? use only the gradle specifier
- if (!isNative())
- {
- return m_name.getFileName();
- }
+ if(!m_filename.isEmpty())
+ {
+ return m_filename;
+ }
+ // non-native? use only the gradle specifier
+ if (!isNative())
+ {
+ return m_name.getFileName();
+ }
- // otherwise native, override classifiers. Mojang HACK!
- GradleSpecifier nativeSpec = m_name;
- if (m_nativeClassifiers.contains(system))
- {
- nativeSpec.setClassifier(m_nativeClassifiers[system]);
- }
- else
- {
- nativeSpec.setClassifier("INVALID");
- }
- return nativeSpec.getFileName();
+ // otherwise native, override classifiers. Mojang HACK!
+ GradleSpecifier nativeSpec = m_name;
+ if (m_nativeClassifiers.contains(system))
+ {
+ nativeSpec.setClassifier(m_nativeClassifiers[system]);
+ }
+ else
+ {
+ nativeSpec.setClassifier("INVALID");
+ }
+ return nativeSpec.getFileName();
}
QString Library::displayName(OpSys system) const
{
- if(!m_displayname.isEmpty())
- return m_displayname;
- return filename(system);
+ if(!m_displayname.isEmpty())
+ return m_displayname;
+ return filename(system);
}
QString Library::storageSuffix(OpSys system) const
{
- // non-native? use only the gradle specifier
- if (!isNative())
- {
- return m_name.toPath(m_filename);
- }
+ // non-native? use only the gradle specifier
+ if (!isNative())
+ {
+ return m_name.toPath(m_filename);
+ }
- // otherwise native, override classifiers. Mojang HACK!
- GradleSpecifier nativeSpec = m_name;
- if (m_nativeClassifiers.contains(system))
- {
- nativeSpec.setClassifier(m_nativeClassifiers[system]);
- }
- else
- {
- nativeSpec.setClassifier("INVALID");
- }
- return nativeSpec.toPath(m_filename);
+ // otherwise native, override classifiers. Mojang HACK!
+ GradleSpecifier nativeSpec = m_name;
+ if (m_nativeClassifiers.contains(system))
+ {
+ nativeSpec.setClassifier(m_nativeClassifiers[system]);
+ }
+ else
+ {
+ nativeSpec.setClassifier("INVALID");
+ }
+ return nativeSpec.toPath(m_filename);
}
diff --git a/api/logic/minecraft/Library.h b/api/logic/minecraft/Library.h
index 9577de33..5fcff316 100644
--- a/api/logic/minecraft/Library.h
+++ b/api/logic/minecraft/Library.h
@@ -24,191 +24,191 @@ typedef std::shared_ptr<Library> LibraryPtr;
class MULTIMC_LOGIC_EXPORT Library
{
- friend class OneSixVersionFormat;
- friend class MojangVersionFormat;
- friend class LibraryTest;
+ friend class OneSixVersionFormat;
+ friend class MojangVersionFormat;
+ friend class LibraryTest;
public:
- Library()
- {
- }
- Library(const QString &name)
- {
- m_name = name;
- }
- /// limited copy without some data. TODO: why?
- static LibraryPtr limitedCopy(LibraryPtr base)
- {
- auto newlib = std::make_shared<Library>();
- newlib->m_name = base->m_name;
- newlib->m_repositoryURL = base->m_repositoryURL;
- newlib->m_hint = base->m_hint;
- newlib->m_absoluteURL = base->m_absoluteURL;
- newlib->m_extractExcludes = base->m_extractExcludes;
- newlib->m_nativeClassifiers = base->m_nativeClassifiers;
- newlib->m_rules = base->m_rules;
- newlib->m_storagePrefix = base->m_storagePrefix;
- newlib->m_mojangDownloads = base->m_mojangDownloads;
- newlib->m_filename = base->m_filename;
- return newlib;
- }
+ Library()
+ {
+ }
+ Library(const QString &name)
+ {
+ m_name = name;
+ }
+ /// limited copy without some data. TODO: why?
+ static LibraryPtr limitedCopy(LibraryPtr base)
+ {
+ auto newlib = std::make_shared<Library>();
+ newlib->m_name = base->m_name;
+ newlib->m_repositoryURL = base->m_repositoryURL;
+ newlib->m_hint = base->m_hint;
+ newlib->m_absoluteURL = base->m_absoluteURL;
+ newlib->m_extractExcludes = base->m_extractExcludes;
+ newlib->m_nativeClassifiers = base->m_nativeClassifiers;
+ newlib->m_rules = base->m_rules;
+ newlib->m_storagePrefix = base->m_storagePrefix;
+ newlib->m_mojangDownloads = base->m_mojangDownloads;
+ newlib->m_filename = base->m_filename;
+ return newlib;
+ }
public: /* methods */
- /// Returns the raw name field
- const GradleSpecifier & rawName() const
- {
- return m_name;
- }
-
- void setRawName(const GradleSpecifier & spec)
- {
- m_name = spec;
- }
-
- void setClassifier(const QString & spec)
- {
- m_name.setClassifier(spec);
- }
-
- /// returns the full group and artifact prefix
- QString artifactPrefix() const
- {
- return m_name.artifactPrefix();
- }
-
- /// get the artifact ID
- QString artifactId() const
- {
- return m_name.artifactId();
- }
-
- /// get the artifact version
- QString version() const
- {
- return m_name.version();
- }
-
- /// Returns true if the library is native
- bool isNative() const
- {
- return m_nativeClassifiers.size() != 0;
- }
-
- void setStoragePrefix(QString prefix = QString());
-
- /// Set the url base for downloads
- void setRepositoryURL(const QString &base_url)
- {
- m_repositoryURL = base_url;
- }
-
- void getApplicableFiles(OpSys system, QStringList & jar, QStringList & native,
- QStringList & native32, QStringList & native64, const QString & overridePath) const;
-
- void setAbsoluteUrl(const QString &absolute_url)
- {
- m_absoluteURL = absolute_url;
- }
-
- void setFilename(const QString &filename)
- {
- m_filename = filename;
- }
-
- /// Get the file name of the library
- QString filename(OpSys system) const;
-
- // DEPRECATED: set a display name, used by jar mods only
- void setDisplayName(const QString & displayName)
- {
- m_displayname = displayName;
- }
-
- /// Get the file name of the library
- QString displayName(OpSys system) const;
-
- void setMojangDownloadInfo(MojangLibraryDownloadInfo::Ptr info)
- {
- m_mojangDownloads = info;
- }
-
- void setHint(const QString &hint)
- {
- m_hint = hint;
- }
-
- /// Set the load rules
- void setRules(QList<std::shared_ptr<Rule>> rules)
- {
- m_rules = rules;
- }
-
- /// Returns true if the library should be loaded (or extracted, in case of natives)
- bool isActive() const;
-
- /// Returns true if the library is contained in an instance and false if it is shared
- bool isLocal() const;
-
- // Get a list of downloads for this library
- QList<NetActionPtr> getDownloads(OpSys system, class HttpMetaCache * cache,
- QStringList & failedFiles, const QString & overridePath) const;
+ /// Returns the raw name field
+ const GradleSpecifier & rawName() const
+ {
+ return m_name;
+ }
+
+ void setRawName(const GradleSpecifier & spec)
+ {
+ m_name = spec;
+ }
+
+ void setClassifier(const QString & spec)
+ {
+ m_name.setClassifier(spec);
+ }
+
+ /// returns the full group and artifact prefix
+ QString artifactPrefix() const
+ {
+ return m_name.artifactPrefix();
+ }
+
+ /// get the artifact ID
+ QString artifactId() const
+ {
+ return m_name.artifactId();
+ }
+
+ /// get the artifact version
+ QString version() const
+ {
+ return m_name.version();
+ }
+
+ /// Returns true if the library is native
+ bool isNative() const
+ {
+ return m_nativeClassifiers.size() != 0;
+ }
+
+ void setStoragePrefix(QString prefix = QString());
+
+ /// Set the url base for downloads
+ void setRepositoryURL(const QString &base_url)
+ {
+ m_repositoryURL = base_url;
+ }
+
+ void getApplicableFiles(OpSys system, QStringList & jar, QStringList & native,
+ QStringList & native32, QStringList & native64, const QString & overridePath) const;
+
+ void setAbsoluteUrl(const QString &absolute_url)
+ {
+ m_absoluteURL = absolute_url;
+ }
+
+ void setFilename(const QString &filename)
+ {
+ m_filename = filename;
+ }
+
+ /// Get the file name of the library
+ QString filename(OpSys system) const;
+
+ // DEPRECATED: set a display name, used by jar mods only
+ void setDisplayName(const QString & displayName)
+ {
+ m_displayname = displayName;
+ }
+
+ /// Get the file name of the library
+ QString displayName(OpSys system) const;
+
+ void setMojangDownloadInfo(MojangLibraryDownloadInfo::Ptr info)
+ {
+ m_mojangDownloads = info;
+ }
+
+ void setHint(const QString &hint)
+ {
+ m_hint = hint;
+ }
+
+ /// Set the load rules
+ void setRules(QList<std::shared_ptr<Rule>> rules)
+ {
+ m_rules = rules;
+ }
+
+ /// Returns true if the library should be loaded (or extracted, in case of natives)
+ bool isActive() const;
+
+ /// Returns true if the library is contained in an instance and false if it is shared
+ bool isLocal() const;
+
+ // Get a list of downloads for this library
+ QList<NetActionPtr> getDownloads(OpSys system, class HttpMetaCache * cache,
+ QStringList & failedFiles, const QString & overridePath) const;
private: /* methods */
- /// the default storage prefix used by MultiMC
- static QString defaultStoragePrefix();
+ /// the default storage prefix used by MultiMC
+ static QString defaultStoragePrefix();
- /// Get the prefix - root of the storage to be used
- QString storagePrefix() const;
+ /// Get the prefix - root of the storage to be used
+ QString storagePrefix() const;
- /// Get the relative file path where the library should be saved
- QString storageSuffix(OpSys system) const;
+ /// Get the relative file path where the library should be saved
+ QString storageSuffix(OpSys system) const;
- QString hint() const
- {
- return m_hint;
- }
+ QString hint() const
+ {
+ return m_hint;
+ }
protected: /* data */
- /// the basic gradle dependency specifier.
- GradleSpecifier m_name;
+ /// the basic gradle dependency specifier.
+ GradleSpecifier m_name;
- /// DEPRECATED URL prefix of the maven repo where the file can be downloaded
- QString m_repositoryURL;
+ /// DEPRECATED URL prefix of the maven repo where the file can be downloaded
+ QString m_repositoryURL;
- /// DEPRECATED: MultiMC-specific absolute URL. takes precedence over the implicit maven repo URL, if defined
- QString m_absoluteURL;
+ /// DEPRECATED: MultiMC-specific absolute URL. takes precedence over the implicit maven repo URL, if defined
+ QString m_absoluteURL;
- /// MultiMC extension - filename override
- QString m_filename;
+ /// MultiMC extension - filename override
+ QString m_filename;
- /// DEPRECATED MultiMC extension - display name
- QString m_displayname;
+ /// DEPRECATED MultiMC extension - display name
+ QString m_displayname;
- /**
- * MultiMC-specific type hint - modifies how the library is treated
- */
- QString m_hint;
+ /**
+ * MultiMC-specific type hint - modifies how the library is treated
+ */
+ QString m_hint;
- /**
- * storage - by default the local libraries folder in multimc, but could be elsewhere
- * MultiMC specific, because of FTB.
- */
- QString m_storagePrefix;
+ /**
+ * storage - by default the local libraries folder in multimc, but could be elsewhere
+ * MultiMC specific, because of FTB.
+ */
+ QString m_storagePrefix;
- /// true if the library had an extract/excludes section (even empty)
- bool m_hasExcludes = false;
+ /// true if the library had an extract/excludes section (even empty)
+ bool m_hasExcludes = false;
- /// a list of files that shouldn't be extracted from the library
- QStringList m_extractExcludes;
+ /// a list of files that shouldn't be extracted from the library
+ QStringList m_extractExcludes;
- /// native suffixes per OS
- QMap<OpSys, QString> m_nativeClassifiers;
+ /// native suffixes per OS
+ QMap<OpSys, QString> m_nativeClassifiers;
- /// true if the library had a rules section (even empty)
- bool applyRules = false;
+ /// true if the library had a rules section (even empty)
+ bool applyRules = false;
- /// rules associated with the library
- QList<std::shared_ptr<Rule>> m_rules;
+ /// rules associated with the library
+ QList<std::shared_ptr<Rule>> m_rules;
- /// MOJANG: container with Mojang style download info
- MojangLibraryDownloadInfo::Ptr m_mojangDownloads;
+ /// MOJANG: container with Mojang style download info
+ MojangLibraryDownloadInfo::Ptr m_mojangDownloads;
};
diff --git a/api/logic/minecraft/Library_test.cpp b/api/logic/minecraft/Library_test.cpp
index 1aac951b..4f9c8006 100644
--- a/api/logic/minecraft/Library_test.cpp
+++ b/api/logic/minecraft/Library_test.cpp
@@ -9,261 +9,261 @@
class LibraryTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private:
- LibraryPtr readMojangJson(const char *file)
- {
- auto path = QFINDTESTDATA(file);
- QFile jsonFile(path);
- jsonFile.open(QIODevice::ReadOnly);
- auto data = jsonFile.readAll();
- jsonFile.close();
- return MojangVersionFormat::libraryFromJson(QJsonDocument::fromJson(data).object(), file);
- }
- // get absolute path to expected storage, assuming default cache prefix
- QStringList getStorage(QString relative)
- {
- return {FS::PathCombine(cache->getBasePath("libraries"), relative)};
- }
+ LibraryPtr readMojangJson(const char *file)
+ {
+ auto path = QFINDTESTDATA(file);
+ QFile jsonFile(path);
+ jsonFile.open(QIODevice::ReadOnly);
+ auto data = jsonFile.readAll();
+ jsonFile.close();
+ return MojangVersionFormat::libraryFromJson(QJsonDocument::fromJson(data).object(), file);
+ }
+ // get absolute path to expected storage, assuming default cache prefix
+ QStringList getStorage(QString relative)
+ {
+ return {FS::PathCombine(cache->getBasePath("libraries"), relative)};
+ }
private
slots:
- void initTestCase()
- {
- cache.reset(new HttpMetaCache());
- cache->addBase("libraries", QDir("libraries").absolutePath());
- dataDir = QDir("data").absolutePath();
- }
- void test_legacy()
- {
- Library test("test.package:testname:testversion");
- QCOMPARE(test.artifactPrefix(), QString("test.package:testname"));
- QCOMPARE(test.isNative(), false);
+ void initTestCase()
+ {
+ cache.reset(new HttpMetaCache());
+ cache->addBase("libraries", QDir("libraries").absolutePath());
+ dataDir = QDir("data").absolutePath();
+ }
+ void test_legacy()
+ {
+ Library test("test.package:testname:testversion");
+ QCOMPARE(test.artifactPrefix(), QString("test.package:testname"));
+ QCOMPARE(test.isNative(), false);
- QStringList jar, native, native32, native64;
- test.getApplicableFiles(currentSystem, jar, native, native32, native64, QString());
- QCOMPARE(jar, getStorage("test/package/testname/testversion/testname-testversion.jar"));
- QCOMPARE(native, {});
- QCOMPARE(native32, {});
- QCOMPARE(native64, {});
- }
- void test_legacy_url()
- {
- QStringList failedFiles;
- Library test("test.package:testname:testversion");
- test.setRepositoryURL("file://foo/bar");
- auto downloads = test.getDownloads(currentSystem, cache.get(), failedFiles, QString());
- QCOMPARE(downloads.size(), 1);
- QCOMPARE(failedFiles, {});
- NetActionPtr dl = downloads[0];
- QCOMPARE(dl->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion.jar"));
- }
- void test_legacy_url_local_broken()
- {
- Library test("test.package:testname:testversion");
- QCOMPARE(test.isNative(), false);
- QStringList failedFiles;
- test.setHint("local");
- auto downloads = test.getDownloads(currentSystem, cache.get(), failedFiles, QString());
- QCOMPARE(downloads.size(), 0);
- QCOMPARE(failedFiles, getStorage("test/package/testname/testversion/testname-testversion.jar"));
- }
- void test_legacy_url_local_override()
- {
- Library test("com.paulscode:codecwav:20101023");
- QCOMPARE(test.isNative(), false);
- QStringList failedFiles;
- test.setHint("local");
- auto downloads = test.getDownloads(currentSystem, cache.get(), failedFiles, QString("data"));
- QCOMPARE(downloads.size(), 0);
- qDebug() << failedFiles;
- QCOMPARE(failedFiles.size(), 0);
+ QStringList jar, native, native32, native64;
+ test.getApplicableFiles(currentSystem, jar, native, native32, native64, QString());
+ QCOMPARE(jar, getStorage("test/package/testname/testversion/testname-testversion.jar"));
+ QCOMPARE(native, {});
+ QCOMPARE(native32, {});
+ QCOMPARE(native64, {});
+ }
+ void test_legacy_url()
+ {
+ QStringList failedFiles;
+ Library test("test.package:testname:testversion");
+ test.setRepositoryURL("file://foo/bar");
+ auto downloads = test.getDownloads(currentSystem, cache.get(), failedFiles, QString());
+ QCOMPARE(downloads.size(), 1);
+ QCOMPARE(failedFiles, {});
+ NetActionPtr dl = downloads[0];
+ QCOMPARE(dl->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion.jar"));
+ }
+ void test_legacy_url_local_broken()
+ {
+ Library test("test.package:testname:testversion");
+ QCOMPARE(test.isNative(), false);
+ QStringList failedFiles;
+ test.setHint("local");
+ auto downloads = test.getDownloads(currentSystem, cache.get(), failedFiles, QString());
+ QCOMPARE(downloads.size(), 0);
+ QCOMPARE(failedFiles, getStorage("test/package/testname/testversion/testname-testversion.jar"));
+ }
+ void test_legacy_url_local_override()
+ {
+ Library test("com.paulscode:codecwav:20101023");
+ QCOMPARE(test.isNative(), false);
+ QStringList failedFiles;
+ test.setHint("local");
+ auto downloads = test.getDownloads(currentSystem, cache.get(), failedFiles, QString("data"));
+ QCOMPARE(downloads.size(), 0);
+ qDebug() << failedFiles;
+ QCOMPARE(failedFiles.size(), 0);
- QStringList jar, native, native32, native64;
- test.getApplicableFiles(currentSystem, jar, native, native32, native64, QString("data"));
- QCOMPARE(jar, {QFileInfo("data/codecwav-20101023.jar").absoluteFilePath()});
- QCOMPARE(native, {});
- QCOMPARE(native32, {});
- QCOMPARE(native64, {});
- }
- void test_legacy_native()
- {
- Library test("test.package:testname:testversion");
- test.m_nativeClassifiers[OpSys::Os_Linux]="linux";
- QCOMPARE(test.isNative(), true);
- test.setRepositoryURL("file://foo/bar");
- {
- QStringList jar, native, native32, native64;
- test.getApplicableFiles(Os_Linux, jar, native, native32, native64, QString());
- QCOMPARE(jar, {});
- QCOMPARE(native, getStorage("test/package/testname/testversion/testname-testversion-linux.jar"));
- QCOMPARE(native32, {});
- QCOMPARE(native64, {});
- QStringList failedFiles;
- auto dls = test.getDownloads(Os_Linux, cache.get(), failedFiles, QString());
- QCOMPARE(dls.size(), 1);
- QCOMPARE(failedFiles, {});
- auto dl = dls[0];
- QCOMPARE(dl->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-linux.jar"));
- }
- }
- void test_legacy_native_arch()
- {
- Library test("test.package:testname:testversion");
- test.m_nativeClassifiers[OpSys::Os_Linux]="linux-${arch}";
- test.m_nativeClassifiers[OpSys::Os_OSX]="osx-${arch}";
- test.m_nativeClassifiers[OpSys::Os_Windows]="windows-${arch}";
- QCOMPARE(test.isNative(), true);
- test.setRepositoryURL("file://foo/bar");
- {
- QStringList jar, native, native32, native64;
- test.getApplicableFiles(Os_Linux, jar, native, native32, native64, QString());
- QCOMPARE(jar, {});
- QCOMPARE(native, {});
- QCOMPARE(native32, getStorage("test/package/testname/testversion/testname-testversion-linux-32.jar"));
- QCOMPARE(native64, getStorage("test/package/testname/testversion/testname-testversion-linux-64.jar"));
- QStringList failedFiles;
- auto dls = test.getDownloads(Os_Linux, cache.get(), failedFiles, QString());
- QCOMPARE(dls.size(), 2);
- QCOMPARE(failedFiles, {});
- QCOMPARE(dls[0]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-linux-32.jar"));
- QCOMPARE(dls[1]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-linux-64.jar"));
- }
- {
- QStringList jar, native, native32, native64;
- test.getApplicableFiles(Os_Windows, jar, native, native32, native64, QString());
- QCOMPARE(jar, {});
- QCOMPARE(native, {});
- QCOMPARE(native32, getStorage("test/package/testname/testversion/testname-testversion-windows-32.jar"));
- QCOMPARE(native64, getStorage("test/package/testname/testversion/testname-testversion-windows-64.jar"));
- QStringList failedFiles;
- auto dls = test.getDownloads(Os_Windows, cache.get(), failedFiles, QString());
- QCOMPARE(dls.size(), 2);
- QCOMPARE(failedFiles, {});
- QCOMPARE(dls[0]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-windows-32.jar"));
- QCOMPARE(dls[1]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-windows-64.jar"));
- }
- {
- QStringList jar, native, native32, native64;
- test.getApplicableFiles(Os_OSX, jar, native, native32, native64, QString());
- QCOMPARE(jar, {});
- QCOMPARE(native, {});
- QCOMPARE(native32, getStorage("test/package/testname/testversion/testname-testversion-osx-32.jar"));
- QCOMPARE(native64, getStorage("test/package/testname/testversion/testname-testversion-osx-64.jar"));
- QStringList failedFiles;
- auto dls = test.getDownloads(Os_OSX, cache.get(), failedFiles, QString());
- QCOMPARE(dls.size(), 2);
- QCOMPARE(failedFiles, {});
- QCOMPARE(dls[0]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-osx-32.jar"));
- QCOMPARE(dls[1]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-osx-64.jar"));
- }
- }
- void test_legacy_native_arch_local_override()
- {
- Library test("test.package:testname:testversion");
- test.m_nativeClassifiers[OpSys::Os_Linux]="linux-${arch}";
- test.setHint("local");
- QCOMPARE(test.isNative(), true);
- test.setRepositoryURL("file://foo/bar");
- {
- QStringList jar, native, native32, native64;
- test.getApplicableFiles(Os_Linux, jar, native, native32, native64, QString("data"));
- QCOMPARE(jar, {});
- QCOMPARE(native, {});
- QCOMPARE(native32, {QFileInfo("data/testname-testversion-linux-32.jar").absoluteFilePath()});
- QCOMPARE(native64, getStorage("test/package/testname/testversion/testname-testversion-linux-64.jar"));
- QStringList failedFiles;
- auto dls = test.getDownloads(Os_Linux, cache.get(), failedFiles, QString("data"));
- QCOMPARE(dls.size(), 0);
- QCOMPARE(failedFiles, {getStorage("test/package/testname/testversion/testname-testversion-linux-64.jar")});
- }
- }
- void test_onenine()
- {
- auto test = readMojangJson("data/lib-simple.json");
- {
- QStringList jar, native, native32, native64;
- test->getApplicableFiles(Os_OSX, jar, native, native32, native64, QString());
- QCOMPARE(jar, getStorage("com/paulscode/codecwav/20101023/codecwav-20101023.jar"));
- QCOMPARE(native, {});
- QCOMPARE(native32, {});
- QCOMPARE(native64, {});
- }
- {
- QStringList failedFiles;
- auto dls = test->getDownloads(Os_Linux, cache.get(), failedFiles, QString());
- QCOMPARE(dls.size(), 1);
- QCOMPARE(failedFiles, {});
- QCOMPARE(dls[0]->m_url, QUrl("https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar"));
- }
- test->setHint("local");
- {
- QStringList jar, native, native32, native64;
- test->getApplicableFiles(Os_OSX, jar, native, native32, native64, QString("data"));
- QCOMPARE(jar, {QFileInfo("data/codecwav-20101023.jar").absoluteFilePath()});
- QCOMPARE(native, {});
- QCOMPARE(native32, {});
- QCOMPARE(native64, {});
- }
- {
- QStringList failedFiles;
- auto dls = test->getDownloads(Os_Linux, cache.get(), failedFiles, QString("data"));
- QCOMPARE(dls.size(), 0);
- QCOMPARE(failedFiles, {});
- }
- }
- void test_onenine_local_override()
- {
- auto test = readMojangJson("data/lib-simple.json");
- test->setHint("local");
- {
- QStringList jar, native, native32, native64;
- test->getApplicableFiles(Os_OSX, jar, native, native32, native64, QString("data"));
- QCOMPARE(jar, {QFileInfo("data/codecwav-20101023.jar").absoluteFilePath()});
- QCOMPARE(native, {});
- QCOMPARE(native32, {});
- QCOMPARE(native64, {});
- }
- {
- QStringList failedFiles;
- auto dls = test->getDownloads(Os_Linux, cache.get(), failedFiles, QString("data"));
- QCOMPARE(dls.size(), 0);
- QCOMPARE(failedFiles, {});
- }
- }
- void test_onenine_native()
- {
- auto test = readMojangJson("data/lib-native.json");
- QStringList jar, native, native32, native64;
- test->getApplicableFiles(Os_OSX, jar, native, native32, native64, QString());
- QCOMPARE(jar, QStringList());
- QCOMPARE(native, getStorage("org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"));
- QCOMPARE(native32, {});
- QCOMPARE(native64, {});
- QStringList failedFiles;
- auto dls = test->getDownloads(Os_OSX, cache.get(), failedFiles, QString());
- QCOMPARE(dls.size(), 1);
- QCOMPARE(failedFiles, {});
- QCOMPARE(dls[0]->m_url, QUrl("https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"));
- }
- void test_onenine_native_arch()
- {
- auto test = readMojangJson("data/lib-native-arch.json");
- QStringList jar, native, native32, native64;
- test->getApplicableFiles(Os_Windows, jar, native, native32, native64, QString());
- QCOMPARE(jar, {});
- QCOMPARE(native, {});
- QCOMPARE(native32, getStorage("tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar"));
- QCOMPARE(native64, getStorage("tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar"));
- QStringList failedFiles;
- auto dls = test->getDownloads(Os_Windows, cache.get(), failedFiles, QString());
- QCOMPARE(dls.size(), 2);
- QCOMPARE(failedFiles, {});
- QCOMPARE(dls[0]->m_url, QUrl("https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar"));
- QCOMPARE(dls[1]->m_url, QUrl("https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar"));
- }
+ QStringList jar, native, native32, native64;
+ test.getApplicableFiles(currentSystem, jar, native, native32, native64, QString("data"));
+ QCOMPARE(jar, {QFileInfo("data/codecwav-20101023.jar").absoluteFilePath()});
+ QCOMPARE(native, {});
+ QCOMPARE(native32, {});
+ QCOMPARE(native64, {});
+ }
+ void test_legacy_native()
+ {
+ Library test("test.package:testname:testversion");
+ test.m_nativeClassifiers[OpSys::Os_Linux]="linux";
+ QCOMPARE(test.isNative(), true);
+ test.setRepositoryURL("file://foo/bar");
+ {
+ QStringList jar, native, native32, native64;
+ test.getApplicableFiles(Os_Linux, jar, native, native32, native64, QString());
+ QCOMPARE(jar, {});
+ QCOMPARE(native, getStorage("test/package/testname/testversion/testname-testversion-linux.jar"));
+ QCOMPARE(native32, {});
+ QCOMPARE(native64, {});
+ QStringList failedFiles;
+ auto dls = test.getDownloads(Os_Linux, cache.get(), failedFiles, QString());
+ QCOMPARE(dls.size(), 1);
+ QCOMPARE(failedFiles, {});
+ auto dl = dls[0];
+ QCOMPARE(dl->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-linux.jar"));
+ }
+ }
+ void test_legacy_native_arch()
+ {
+ Library test("test.package:testname:testversion");
+ test.m_nativeClassifiers[OpSys::Os_Linux]="linux-${arch}";
+ test.m_nativeClassifiers[OpSys::Os_OSX]="osx-${arch}";
+ test.m_nativeClassifiers[OpSys::Os_Windows]="windows-${arch}";
+ QCOMPARE(test.isNative(), true);
+ test.setRepositoryURL("file://foo/bar");
+ {
+ QStringList jar, native, native32, native64;
+ test.getApplicableFiles(Os_Linux, jar, native, native32, native64, QString());
+ QCOMPARE(jar, {});
+ QCOMPARE(native, {});
+ QCOMPARE(native32, getStorage("test/package/testname/testversion/testname-testversion-linux-32.jar"));
+ QCOMPARE(native64, getStorage("test/package/testname/testversion/testname-testversion-linux-64.jar"));
+ QStringList failedFiles;
+ auto dls = test.getDownloads(Os_Linux, cache.get(), failedFiles, QString());
+ QCOMPARE(dls.size(), 2);
+ QCOMPARE(failedFiles, {});
+ QCOMPARE(dls[0]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-linux-32.jar"));
+ QCOMPARE(dls[1]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-linux-64.jar"));
+ }
+ {
+ QStringList jar, native, native32, native64;
+ test.getApplicableFiles(Os_Windows, jar, native, native32, native64, QString());
+ QCOMPARE(jar, {});
+ QCOMPARE(native, {});
+ QCOMPARE(native32, getStorage("test/package/testname/testversion/testname-testversion-windows-32.jar"));
+ QCOMPARE(native64, getStorage("test/package/testname/testversion/testname-testversion-windows-64.jar"));
+ QStringList failedFiles;
+ auto dls = test.getDownloads(Os_Windows, cache.get(), failedFiles, QString());
+ QCOMPARE(dls.size(), 2);
+ QCOMPARE(failedFiles, {});
+ QCOMPARE(dls[0]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-windows-32.jar"));
+ QCOMPARE(dls[1]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-windows-64.jar"));
+ }
+ {
+ QStringList jar, native, native32, native64;
+ test.getApplicableFiles(Os_OSX, jar, native, native32, native64, QString());
+ QCOMPARE(jar, {});
+ QCOMPARE(native, {});
+ QCOMPARE(native32, getStorage("test/package/testname/testversion/testname-testversion-osx-32.jar"));
+ QCOMPARE(native64, getStorage("test/package/testname/testversion/testname-testversion-osx-64.jar"));
+ QStringList failedFiles;
+ auto dls = test.getDownloads(Os_OSX, cache.get(), failedFiles, QString());
+ QCOMPARE(dls.size(), 2);
+ QCOMPARE(failedFiles, {});
+ QCOMPARE(dls[0]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-osx-32.jar"));
+ QCOMPARE(dls[1]->m_url, QUrl("file://foo/bar/test/package/testname/testversion/testname-testversion-osx-64.jar"));
+ }
+ }
+ void test_legacy_native_arch_local_override()
+ {
+ Library test("test.package:testname:testversion");
+ test.m_nativeClassifiers[OpSys::Os_Linux]="linux-${arch}";
+ test.setHint("local");
+ QCOMPARE(test.isNative(), true);
+ test.setRepositoryURL("file://foo/bar");
+ {
+ QStringList jar, native, native32, native64;
+ test.getApplicableFiles(Os_Linux, jar, native, native32, native64, QString("data"));
+ QCOMPARE(jar, {});
+ QCOMPARE(native, {});
+ QCOMPARE(native32, {QFileInfo("data/testname-testversion-linux-32.jar").absoluteFilePath()});
+ QCOMPARE(native64, getStorage("test/package/testname/testversion/testname-testversion-linux-64.jar"));
+ QStringList failedFiles;
+ auto dls = test.getDownloads(Os_Linux, cache.get(), failedFiles, QString("data"));
+ QCOMPARE(dls.size(), 0);
+ QCOMPARE(failedFiles, {getStorage("test/package/testname/testversion/testname-testversion-linux-64.jar")});
+ }
+ }
+ void test_onenine()
+ {
+ auto test = readMojangJson("data/lib-simple.json");
+ {
+ QStringList jar, native, native32, native64;
+ test->getApplicableFiles(Os_OSX, jar, native, native32, native64, QString());
+ QCOMPARE(jar, getStorage("com/paulscode/codecwav/20101023/codecwav-20101023.jar"));
+ QCOMPARE(native, {});
+ QCOMPARE(native32, {});
+ QCOMPARE(native64, {});
+ }
+ {
+ QStringList failedFiles;
+ auto dls = test->getDownloads(Os_Linux, cache.get(), failedFiles, QString());
+ QCOMPARE(dls.size(), 1);
+ QCOMPARE(failedFiles, {});
+ QCOMPARE(dls[0]->m_url, QUrl("https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar"));
+ }
+ test->setHint("local");
+ {
+ QStringList jar, native, native32, native64;
+ test->getApplicableFiles(Os_OSX, jar, native, native32, native64, QString("data"));
+ QCOMPARE(jar, {QFileInfo("data/codecwav-20101023.jar").absoluteFilePath()});
+ QCOMPARE(native, {});
+ QCOMPARE(native32, {});
+ QCOMPARE(native64, {});
+ }
+ {
+ QStringList failedFiles;
+ auto dls = test->getDownloads(Os_Linux, cache.get(), failedFiles, QString("data"));
+ QCOMPARE(dls.size(), 0);
+ QCOMPARE(failedFiles, {});
+ }
+ }
+ void test_onenine_local_override()
+ {
+ auto test = readMojangJson("data/lib-simple.json");
+ test->setHint("local");
+ {
+ QStringList jar, native, native32, native64;
+ test->getApplicableFiles(Os_OSX, jar, native, native32, native64, QString("data"));
+ QCOMPARE(jar, {QFileInfo("data/codecwav-20101023.jar").absoluteFilePath()});
+ QCOMPARE(native, {});
+ QCOMPARE(native32, {});
+ QCOMPARE(native64, {});
+ }
+ {
+ QStringList failedFiles;
+ auto dls = test->getDownloads(Os_Linux, cache.get(), failedFiles, QString("data"));
+ QCOMPARE(dls.size(), 0);
+ QCOMPARE(failedFiles, {});
+ }
+ }
+ void test_onenine_native()
+ {
+ auto test = readMojangJson("data/lib-native.json");
+ QStringList jar, native, native32, native64;
+ test->getApplicableFiles(Os_OSX, jar, native, native32, native64, QString());
+ QCOMPARE(jar, QStringList());
+ QCOMPARE(native, getStorage("org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"));
+ QCOMPARE(native32, {});
+ QCOMPARE(native64, {});
+ QStringList failedFiles;
+ auto dls = test->getDownloads(Os_OSX, cache.get(), failedFiles, QString());
+ QCOMPARE(dls.size(), 1);
+ QCOMPARE(failedFiles, {});
+ QCOMPARE(dls[0]->m_url, QUrl("https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"));
+ }
+ void test_onenine_native_arch()
+ {
+ auto test = readMojangJson("data/lib-native-arch.json");
+ QStringList jar, native, native32, native64;
+ test->getApplicableFiles(Os_Windows, jar, native, native32, native64, QString());
+ QCOMPARE(jar, {});
+ QCOMPARE(native, {});
+ QCOMPARE(native32, getStorage("tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar"));
+ QCOMPARE(native64, getStorage("tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar"));
+ QStringList failedFiles;
+ auto dls = test->getDownloads(Os_Windows, cache.get(), failedFiles, QString());
+ QCOMPARE(dls.size(), 2);
+ QCOMPARE(failedFiles, {});
+ QCOMPARE(dls[0]->m_url, QUrl("https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar"));
+ QCOMPARE(dls[1]->m_url, QUrl("https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar"));
+ }
private:
- std::unique_ptr<HttpMetaCache> cache;
- QString dataDir;
+ std::unique_ptr<HttpMetaCache> cache;
+ QString dataDir;
};
QTEST_GUILESS_MAIN(LibraryTest)
diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp
index e9f67b31..698c1ee2 100644
--- a/api/logic/minecraft/MinecraftInstance.cpp
+++ b/api/logic/minecraft/MinecraftInstance.cpp
@@ -43,73 +43,73 @@
// if either of the settings {a, b} is true, this also resolves to true
class OrSetting : public Setting
{
- Q_OBJECT
+ Q_OBJECT
public:
- OrSetting(QString id, std::shared_ptr<Setting> a, std::shared_ptr<Setting> b)
- :Setting({id}, false), m_a(a), m_b(b)
- {
- }
- virtual QVariant get() const
- {
- bool a = m_a->get().toBool();
- bool b = m_b->get().toBool();
- return a || b;
- }
- virtual void reset() {}
- virtual void set(QVariant value) {}
+ OrSetting(QString id, std::shared_ptr<Setting> a, std::shared_ptr<Setting> b)
+ :Setting({id}, false), m_a(a), m_b(b)
+ {
+ }
+ virtual QVariant get() const
+ {
+ bool a = m_a->get().toBool();
+ bool b = m_b->get().toBool();
+ return a || b;
+ }
+ virtual void reset() {}
+ virtual void set(QVariant value) {}
private:
- std::shared_ptr<Setting> m_a;
- std::shared_ptr<Setting> m_b;
+ std::shared_ptr<Setting> m_a;
+ std::shared_ptr<Setting> m_b;
};
MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : BaseInstance(globalSettings, settings, rootDir)
-{
- // Java Settings
- auto javaOverride = m_settings->registerSetting("OverrideJava", false);
- auto locationOverride = m_settings->registerSetting("OverrideJavaLocation", false);
- auto argsOverride = m_settings->registerSetting("OverrideJavaArgs", false);
-
- // combinations
- auto javaOrLocation = std::make_shared<OrSetting>("JavaOrLocationOverride", javaOverride, locationOverride);
- auto javaOrArgs = std::make_shared<OrSetting>("JavaOrArgsOverride", javaOverride, argsOverride);
-
- m_settings->registerOverride(globalSettings->getSetting("JavaPath"), javaOrLocation);
- m_settings->registerOverride(globalSettings->getSetting("JvmArgs"), javaOrArgs);
-
- // special!
- m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
- m_settings->registerPassthrough(globalSettings->getSetting("JavaVersion"), javaOrLocation);
- m_settings->registerPassthrough(globalSettings->getSetting("JavaArchitecture"), javaOrLocation);
-
- // Window Size
- auto windowSetting = m_settings->registerSetting("OverrideWindow", false);
- m_settings->registerOverride(globalSettings->getSetting("LaunchMaximized"), windowSetting);
- m_settings->registerOverride(globalSettings->getSetting("MinecraftWinWidth"), windowSetting);
- m_settings->registerOverride(globalSettings->getSetting("MinecraftWinHeight"), windowSetting);
-
- // Memory
- auto memorySetting = m_settings->registerSetting("OverrideMemory", false);
- m_settings->registerOverride(globalSettings->getSetting("MinMemAlloc"), memorySetting);
- m_settings->registerOverride(globalSettings->getSetting("MaxMemAlloc"), memorySetting);
- m_settings->registerOverride(globalSettings->getSetting("PermGen"), memorySetting);
-
- // Minecraft launch method
- auto launchMethodOverride = m_settings->registerSetting("OverrideMCLaunchMethod", false);
- m_settings->registerOverride(globalSettings->getSetting("MCLaunchMethod"), launchMethodOverride);
-
- // DEPRECATED: Read what versions the user configuration thinks should be used
- m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
- m_settings->registerSetting("LWJGLVersion", "");
- m_settings->registerSetting("ForgeVersion", "");
- m_settings->registerSetting("LiteloaderVersion", "");
-
- m_components.reset(new ComponentList(this));
- m_components->setOldConfigVersion("net.minecraft", m_settings->get("IntendedVersion").toString());
- auto setting = m_settings->getSetting("LWJGLVersion");
- m_components->setOldConfigVersion("org.lwjgl", m_settings->get("LWJGLVersion").toString());
- m_components->setOldConfigVersion("net.minecraftforge", m_settings->get("ForgeVersion").toString());
- m_components->setOldConfigVersion("com.mumfrey.liteloader", m_settings->get("LiteloaderVersion").toString());
+ : BaseInstance(globalSettings, settings, rootDir)
+{
+ // Java Settings
+ auto javaOverride = m_settings->registerSetting("OverrideJava", false);
+ auto locationOverride = m_settings->registerSetting("OverrideJavaLocation", false);
+ auto argsOverride = m_settings->registerSetting("OverrideJavaArgs", false);
+
+ // combinations
+ auto javaOrLocation = std::make_shared<OrSetting>("JavaOrLocationOverride", javaOverride, locationOverride);
+ auto javaOrArgs = std::make_shared<OrSetting>("JavaOrArgsOverride", javaOverride, argsOverride);
+
+ m_settings->registerOverride(globalSettings->getSetting("JavaPath"), javaOrLocation);
+ m_settings->registerOverride(globalSettings->getSetting("JvmArgs"), javaOrArgs);
+
+ // special!
+ m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
+ m_settings->registerPassthrough(globalSettings->getSetting("JavaVersion"), javaOrLocation);
+ m_settings->registerPassthrough(globalSettings->getSetting("JavaArchitecture"), javaOrLocation);
+
+ // Window Size
+ auto windowSetting = m_settings->registerSetting("OverrideWindow", false);
+ m_settings->registerOverride(globalSettings->getSetting("LaunchMaximized"), windowSetting);
+ m_settings->registerOverride(globalSettings->getSetting("MinecraftWinWidth"), windowSetting);
+ m_settings->registerOverride(globalSettings->getSetting("MinecraftWinHeight"), windowSetting);
+
+ // Memory
+ auto memorySetting = m_settings->registerSetting("OverrideMemory", false);
+ m_settings->registerOverride(globalSettings->getSetting("MinMemAlloc"), memorySetting);
+ m_settings->registerOverride(globalSettings->getSetting("MaxMemAlloc"), memorySetting);
+ m_settings->registerOverride(globalSettings->getSetting("PermGen"), memorySetting);
+
+ // Minecraft launch method
+ auto launchMethodOverride = m_settings->registerSetting("OverrideMCLaunchMethod", false);
+ m_settings->registerOverride(globalSettings->getSetting("MCLaunchMethod"), launchMethodOverride);
+
+ // DEPRECATED: Read what versions the user configuration thinks should be used
+ m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
+ m_settings->registerSetting("LWJGLVersion", "");
+ m_settings->registerSetting("ForgeVersion", "");
+ m_settings->registerSetting("LiteloaderVersion", "");
+
+ m_components.reset(new ComponentList(this));
+ m_components->setOldConfigVersion("net.minecraft", m_settings->get("IntendedVersion").toString());
+ auto setting = m_settings->getSetting("LWJGLVersion");
+ m_components->setOldConfigVersion("org.lwjgl", m_settings->get("LWJGLVersion").toString());
+ m_components->setOldConfigVersion("net.minecraftforge", m_settings->get("ForgeVersion").toString());
+ m_components->setOldConfigVersion("com.mumfrey.liteloader", m_settings->get("LiteloaderVersion").toString());
}
void MinecraftInstance::init()
@@ -118,849 +118,849 @@ void MinecraftInstance::init()
void MinecraftInstance::saveNow()
{
- m_components->saveNow();
+ m_components->saveNow();
}
QString MinecraftInstance::typeName() const
{
- return "Minecraft";
+ return "Minecraft";
}
std::shared_ptr<ComponentList> MinecraftInstance::getComponentList() const
{
- return m_components;
+ return m_components;
}
QSet<QString> MinecraftInstance::traits() const
{
- auto components = getComponentList();
- if (!components)
- {
- return {"version-incomplete"};
- }
- auto profile = components->getProfile();
- if (!profile)
- {
- return {"version-incomplete"};
- }
- return profile->getTraits();
+ auto components = getComponentList();
+ if (!components)
+ {
+ return {"version-incomplete"};
+ }
+ auto profile = components->getProfile();
+ if (!profile)
+ {
+ return {"version-incomplete"};
+ }
+ return profile->getTraits();
}
QString MinecraftInstance::minecraftRoot() const
{
- QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
- QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
+ QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
+ QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
- if (mcDir.exists() && !dotMCDir.exists())
- return mcDir.filePath();
- else
- return dotMCDir.filePath();
+ if (mcDir.exists() && !dotMCDir.exists())
+ return mcDir.filePath();
+ else
+ return dotMCDir.filePath();
}
QString MinecraftInstance::binRoot() const
{
- return FS::PathCombine(minecraftRoot(), "bin");
+ return FS::PathCombine(minecraftRoot(), "bin");
}
QString MinecraftInstance::getNativePath() const
{
- QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/"));
- return natives_dir.absolutePath();
+ QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/"));
+ return natives_dir.absolutePath();
}
QString MinecraftInstance::getLocalLibraryPath() const
{
- QDir libraries_dir(FS::PathCombine(instanceRoot(), "libraries/"));
- return libraries_dir.absolutePath();
+ QDir libraries_dir(FS::PathCombine(instanceRoot(), "libraries/"));
+ return libraries_dir.absolutePath();
}
QString MinecraftInstance::loaderModsDir() const
{
- return FS::PathCombine(minecraftRoot(), "mods");
+ return FS::PathCombine(minecraftRoot(), "mods");
}
QString MinecraftInstance::modsCacheLocation() const
{
- return FS::PathCombine(instanceRoot(), "mods.cache");
+ return FS::PathCombine(instanceRoot(), "mods.cache");
}
QString MinecraftInstance::coreModsDir() const
{
- return FS::PathCombine(minecraftRoot(), "coremods");
+ return FS::PathCombine(minecraftRoot(), "coremods");
}
QString MinecraftInstance::resourcePacksDir() const
{
- return FS::PathCombine(minecraftRoot(), "resourcepacks");
+ return FS::PathCombine(minecraftRoot(), "resourcepacks");
}
QString MinecraftInstance::texturePacksDir() const
{
- return FS::PathCombine(minecraftRoot(), "texturepacks");
+ return FS::PathCombine(minecraftRoot(), "texturepacks");
}
QString MinecraftInstance::instanceConfigFolder() const
{
- return FS::PathCombine(minecraftRoot(), "config");
+ return FS::PathCombine(minecraftRoot(), "config");
}
QString MinecraftInstance::jarModsDir() const
{
- return FS::PathCombine(instanceRoot(), "jarmods");
+ return FS::PathCombine(instanceRoot(), "jarmods");
}
QString MinecraftInstance::libDir() const
{
- return FS::PathCombine(minecraftRoot(), "lib");
+ return FS::PathCombine(minecraftRoot(), "lib");
}
QString MinecraftInstance::worldDir() const
{
- return FS::PathCombine(minecraftRoot(), "saves");
+ return FS::PathCombine(minecraftRoot(), "saves");
}
QDir MinecraftInstance::librariesPath() const
{
- return QDir::current().absoluteFilePath("libraries");
+ return QDir::current().absoluteFilePath("libraries");
}
QDir MinecraftInstance::jarmodsPath() const
{
- return QDir(jarModsDir());
+ return QDir(jarModsDir());
}
QDir MinecraftInstance::versionsPath() const
{
- return QDir::current().absoluteFilePath("versions");
+ return QDir::current().absoluteFilePath("versions");
}
QStringList MinecraftInstance::getClassPath() const
{
- QStringList jars, nativeJars;
- auto javaArchitecture = settings()->get("JavaArchitecture").toString();
- auto profile = m_components->getProfile();
- profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
- return jars;
+ QStringList jars, nativeJars;
+ auto javaArchitecture = settings()->get("JavaArchitecture").toString();
+ auto profile = m_components->getProfile();
+ profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
+ return jars;
}
QString MinecraftInstance::getMainClass() const
{
- auto profile = m_components->getProfile();
- return profile->getMainClass();
+ auto profile = m_components->getProfile();
+ return profile->getMainClass();
}
QStringList MinecraftInstance::getNativeJars() const
{
- QStringList jars, nativeJars;
- auto javaArchitecture = settings()->get("JavaArchitecture").toString();
- auto profile = m_components->getProfile();
- profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
- return nativeJars;
+ QStringList jars, nativeJars;
+ auto javaArchitecture = settings()->get("JavaArchitecture").toString();
+ auto profile = m_components->getProfile();
+ profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
+ return nativeJars;
}
QStringList MinecraftInstance::extraArguments() const
{
- auto list = BaseInstance::extraArguments();
- auto version = getComponentList();
- if (!version)
- return list;
- auto jarMods = getJarMods();
- if (!jarMods.isEmpty())
- {
- list.append({"-Dfml.ignoreInvalidMinecraftCertificates=true",
- "-Dfml.ignorePatchDiscrepancies=true"});
- }
- return list;
+ auto list = BaseInstance::extraArguments();
+ auto version = getComponentList();
+ if (!version)
+ return list;
+ auto jarMods = getJarMods();
+ if (!jarMods.isEmpty())
+ {
+ list.append({"-Dfml.ignoreInvalidMinecraftCertificates=true",
+ "-Dfml.ignorePatchDiscrepancies=true"});
+ }
+ return list;
}
QStringList MinecraftInstance::javaArguments() const
{
- QStringList args;
+ QStringList args;
- // custom args go first. we want to override them if we have our own here.
- args.append(extraArguments());
+ // custom args go first. we want to override them if we have our own here.
+ args.append(extraArguments());
- // OSX dock icon and name
+ // OSX dock icon and name
#ifdef Q_OS_MAC
- args << "-Xdock:icon=icon.png";
- args << QString("-Xdock:name=\"%1\"").arg(windowTitle());
+ args << "-Xdock:icon=icon.png";
+ args << QString("-Xdock:name=\"%1\"").arg(windowTitle());
#endif
- auto traits_ = traits();
- // HACK: fix issues on macOS with 1.13 snapshots
- // NOTE: Oracle Java option. if there are alternate jvm implementations, this would be the place to customize this for them
+ auto traits_ = traits();
+ // HACK: fix issues on macOS with 1.13 snapshots
+ // NOTE: Oracle Java option. if there are alternate jvm implementations, this would be the place to customize this for them
#ifdef Q_OS_MAC
- if(traits_.contains("FirstThreadOnMacOS"))
- {
- args << QString("-XstartOnFirstThread");
- }
+ if(traits_.contains("FirstThreadOnMacOS"))
+ {
+ args << QString("-XstartOnFirstThread");
+ }
#endif
- // HACK: Stupid hack for Intel drivers. See: https://mojang.atlassian.net/browse/MCL-767
+ // HACK: Stupid hack for Intel drivers. See: https://mojang.atlassian.net/browse/MCL-767
#ifdef Q_OS_WIN32
- args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_"
- "minecraft.exe.heapdump");
+ args << QString("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_"
+ "minecraft.exe.heapdump");
#endif
- int min = settings()->get("MinMemAlloc").toInt();
- int max = settings()->get("MaxMemAlloc").toInt();
- if(min < max)
- {
- args << QString("-Xms%1m").arg(min);
- args << QString("-Xmx%1m").arg(max);
- }
- else
- {
- args << QString("-Xms%1m").arg(max);
- args << QString("-Xmx%1m").arg(min);
- }
-
- // No PermGen in newer java.
- JavaVersion javaVersion = getJavaVersion();
- if(javaVersion.requiresPermGen())
- {
- auto permgen = settings()->get("PermGen").toInt();
- if (permgen != 64)
- {
- args << QString("-XX:PermSize=%1m").arg(permgen);
- }
- }
-
- args << "-Duser.language=en";
-
- return args;
+ int min = settings()->get("MinMemAlloc").toInt();
+ int max = settings()->get("MaxMemAlloc").toInt();
+ if(min < max)
+ {
+ args << QString("-Xms%1m").arg(min);
+ args << QString("-Xmx%1m").arg(max);
+ }
+ else
+ {
+ args << QString("-Xms%1m").arg(max);
+ args << QString("-Xmx%1m").arg(min);
+ }
+
+ // No PermGen in newer java.
+ JavaVersion javaVersion = getJavaVersion();
+ if(javaVersion.requiresPermGen())
+ {
+ auto permgen = settings()->get("PermGen").toInt();
+ if (permgen != 64)
+ {
+ args << QString("-XX:PermSize=%1m").arg(permgen);
+ }
+ }
+
+ args << "-Duser.language=en";
+
+ return args;
}
QMap<QString, QString> MinecraftInstance::getVariables() const
{
- QMap<QString, QString> out;
- out.insert("INST_NAME", name());
- out.insert("INST_ID", id());
- out.insert("INST_DIR", QDir(instanceRoot()).absolutePath());
- out.insert("INST_MC_DIR", QDir(minecraftRoot()).absolutePath());
- out.insert("INST_JAVA", settings()->get("JavaPath").toString());
- out.insert("INST_JAVA_ARGS", javaArguments().join(' '));
- return out;
+ QMap<QString, QString> out;
+ out.insert("INST_NAME", name());
+ out.insert("INST_ID", id());
+ out.insert("INST_DIR", QDir(instanceRoot()).absolutePath());
+ out.insert("INST_MC_DIR", QDir(minecraftRoot()).absolutePath());
+ out.insert("INST_JAVA", settings()->get("JavaPath").toString());
+ out.insert("INST_JAVA_ARGS", javaArguments().join(' '));
+ return out;
}
QProcessEnvironment MinecraftInstance::createEnvironment()
{
- // prepare the process environment
- QProcessEnvironment env = CleanEnviroment();
+ // prepare the process environment
+ QProcessEnvironment env = CleanEnviroment();
- // export some infos
- auto variables = getVariables();
- for (auto it = variables.begin(); it != variables.end(); ++it)
- {
- env.insert(it.key(), it.value());
- }
- return env;
+ // export some infos
+ auto variables = getVariables();
+ for (auto it = variables.begin(); it != variables.end(); ++it)
+ {
+ env.insert(it.key(), it.value());
+ }
+ return env;
}
static QString replaceTokensIn(QString text, QMap<QString, QString> with)
{
- QString result;
- QRegExp token_regexp("\\$\\{(.+)\\}");
- token_regexp.setMinimal(true);
- QStringList list;
- int tail = 0;
- int head = 0;
- while ((head = token_regexp.indexIn(text, head)) != -1)
- {
- result.append(text.mid(tail, head - tail));
- QString key = token_regexp.cap(1);
- auto iter = with.find(key);
- if (iter != with.end())
- {
- result.append(*iter);
- }
- head += token_regexp.matchedLength();
- tail = head;
- }
- result.append(text.mid(tail));
- return result;
+ QString result;
+ QRegExp token_regexp("\\$\\{(.+)\\}");
+ token_regexp.setMinimal(true);
+ QStringList list;
+ int tail = 0;
+ int head = 0;
+ while ((head = token_regexp.indexIn(text, head)) != -1)
+ {
+ result.append(text.mid(tail, head - tail));
+ QString key = token_regexp.cap(1);
+ auto iter = with.find(key);
+ if (iter != with.end())
+ {
+ result.append(*iter);
+ }
+ head += token_regexp.matchedLength();
+ tail = head;
+ }
+ result.append(text.mid(tail));
+ return result;
}
QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session) const
{
- auto profile = m_components->getProfile();
- QString args_pattern = profile->getMinecraftArguments();
- for (auto tweaker : profile->getTweakers())
- {
- args_pattern += " --tweakClass " + tweaker;
- }
-
- QMap<QString, QString> token_mapping;
- // yggdrasil!
- if(session)
- {
- token_mapping["auth_username"] = session->username;
- token_mapping["auth_session"] = session->session;
- token_mapping["auth_access_token"] = session->access_token;
- token_mapping["auth_player_name"] = session->player_name;
- token_mapping["auth_uuid"] = session->uuid;
- token_mapping["user_properties"] = session->serializeUserProperties();
- token_mapping["user_type"] = session->user_type;
- }
-
- // blatant self-promotion.
- token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5";
-
- token_mapping["version_type"] = profile->getMinecraftVersionType();
-
- QString absRootDir = QDir(minecraftRoot()).absolutePath();
- token_mapping["game_directory"] = absRootDir;
- QString absAssetsDir = QDir("assets/").absolutePath();
- auto assets = profile->getMinecraftAssets();
- // FIXME: this is wrong and should be run as an async task
- token_mapping["game_assets"] = AssetsUtils::reconstructAssets(assets->id).absolutePath();
-
- // 1.7.3+ assets tokens
- token_mapping["assets_root"] = absAssetsDir;
- token_mapping["assets_index_name"] = assets->id;
-
- QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts);
- for (int i = 0; i < parts.length(); i++)
- {
- parts[i] = replaceTokensIn(parts[i], token_mapping);
- }
- return parts;
+ auto profile = m_components->getProfile();
+ QString args_pattern = profile->getMinecraftArguments();
+ for (auto tweaker : profile->getTweakers())
+ {
+ args_pattern += " --tweakClass " + tweaker;
+ }
+
+ QMap<QString, QString> token_mapping;
+ // yggdrasil!
+ if(session)
+ {
+ token_mapping["auth_username"] = session->username;
+ token_mapping["auth_session"] = session->session;
+ token_mapping["auth_access_token"] = session->access_token;
+ token_mapping["auth_player_name"] = session->player_name;
+ token_mapping["auth_uuid"] = session->uuid;
+ token_mapping["user_properties"] = session->serializeUserProperties();
+ token_mapping["user_type"] = session->user_type;
+ }
+
+ // blatant self-promotion.
+ token_mapping["profile_name"] = token_mapping["version_name"] = "MultiMC5";
+
+ token_mapping["version_type"] = profile->getMinecraftVersionType();
+
+ QString absRootDir = QDir(minecraftRoot()).absolutePath();
+ token_mapping["game_directory"] = absRootDir;
+ QString absAssetsDir = QDir("assets/").absolutePath();
+ auto assets = profile->getMinecraftAssets();
+ // FIXME: this is wrong and should be run as an async task
+ token_mapping["game_assets"] = AssetsUtils::reconstructAssets(assets->id).absolutePath();
+
+ // 1.7.3+ assets tokens
+ token_mapping["assets_root"] = absAssetsDir;
+ token_mapping["assets_index_name"] = assets->id;
+
+ QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts);
+ for (int i = 0; i < parts.length(); i++)
+ {
+ parts[i] = replaceTokensIn(parts[i], token_mapping);
+ }
+ return parts;
}
QString MinecraftInstance::createLaunchScript(AuthSessionPtr session)
{
- QString launchScript;
-
- if (!m_components)
- return QString();
- auto profile = m_components->getProfile();
- if(!profile)
- return QString();
-
- auto mainClass = getMainClass();
- if (!mainClass.isEmpty())
- {
- launchScript += "mainClass " + mainClass + "\n";
- }
- auto appletClass = profile->getAppletClass();
- if (!appletClass.isEmpty())
- {
- launchScript += "appletClass " + appletClass + "\n";
- }
-
- // generic minecraft params
- for (auto param : processMinecraftArgs(session))
- {
- launchScript += "param " + param + "\n";
- }
-
- // window size, title and state, legacy
- {
- QString windowParams;
- if (settings()->get("LaunchMaximized").toBool())
- windowParams = "max";
- else
- windowParams = QString("%1x%2")
- .arg(settings()->get("MinecraftWinWidth").toInt())
- .arg(settings()->get("MinecraftWinHeight").toInt());
- launchScript += "windowTitle " + windowTitle() + "\n";
- launchScript += "windowParams " + windowParams + "\n";
- }
-
- // legacy auth
- if(session)
- {
- launchScript += "userName " + session->player_name + "\n";
- launchScript += "sessionId " + session->session + "\n";
- }
-
- // libraries and class path.
- {
- QStringList jars, nativeJars;
- auto javaArchitecture = settings()->get("JavaArchitecture").toString();
- profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
- for(auto file: jars)
- {
- launchScript += "cp " + file + "\n";
- }
- for(auto file: nativeJars)
- {
- launchScript += "ext " + file + "\n";
- }
- launchScript += "natives " + getNativePath() + "\n";
- }
-
- for (auto trait : profile->getTraits())
- {
- launchScript += "traits " + trait + "\n";
- }
- launchScript += "launcher onesix\n";
- // qDebug() << "Generated launch script:" << launchScript;
- return launchScript;
+ QString launchScript;
+
+ if (!m_components)
+ return QString();
+ auto profile = m_components->getProfile();
+ if(!profile)
+ return QString();
+
+ auto mainClass = getMainClass();
+ if (!mainClass.isEmpty())
+ {
+ launchScript += "mainClass " + mainClass + "\n";
+ }
+ auto appletClass = profile->getAppletClass();
+ if (!appletClass.isEmpty())
+ {
+ launchScript += "appletClass " + appletClass + "\n";
+ }
+
+ // generic minecraft params
+ for (auto param : processMinecraftArgs(session))
+ {
+ launchScript += "param " + param + "\n";
+ }
+
+ // window size, title and state, legacy
+ {
+ QString windowParams;
+ if (settings()->get("LaunchMaximized").toBool())
+ windowParams = "max";
+ else
+ windowParams = QString("%1x%2")
+ .arg(settings()->get("MinecraftWinWidth").toInt())
+ .arg(settings()->get("MinecraftWinHeight").toInt());
+ launchScript += "windowTitle " + windowTitle() + "\n";
+ launchScript += "windowParams " + windowParams + "\n";
+ }
+
+ // legacy auth
+ if(session)
+ {
+ launchScript += "userName " + session->player_name + "\n";
+ launchScript += "sessionId " + session->session + "\n";
+ }
+
+ // libraries and class path.
+ {
+ QStringList jars, nativeJars;
+ auto javaArchitecture = settings()->get("JavaArchitecture").toString();
+ profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
+ for(auto file: jars)
+ {
+ launchScript += "cp " + file + "\n";
+ }
+ for(auto file: nativeJars)
+ {
+ launchScript += "ext " + file + "\n";
+ }
+ launchScript += "natives " + getNativePath() + "\n";
+ }
+
+ for (auto trait : profile->getTraits())
+ {
+ launchScript += "traits " + trait + "\n";
+ }
+ launchScript += "launcher onesix\n";
+ // qDebug() << "Generated launch script:" << launchScript;
+ return launchScript;
}
QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session)
{
- QStringList out;
- out << "Main Class:" << " " + getMainClass() << "";
- out << "Native path:" << " " + getNativePath() << "";
-
- auto profile = m_components->getProfile();
-
- auto alltraits = traits();
- if(alltraits.size())
- {
- out << "Traits:";
- for (auto trait : alltraits)
- {
- out << "traits " + trait;
- }
- out << "";
- }
-
- // libraries and class path.
- {
- out << "Libraries:";
- QStringList jars, nativeJars;
- auto javaArchitecture = settings()->get("JavaArchitecture").toString();
- profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
- auto printLibFile = [&](const QString & path)
- {
- QFileInfo info(path);
- if(info.exists())
- {
- out << " " + path;
- }
- else
- {
- out << " " + path + " (missing)";
- }
- };
- for(auto file: jars)
- {
- printLibFile(file);
- }
- out << "";
- out << "Native libraries:";
- for(auto file: nativeJars)
- {
- printLibFile(file);
- }
- out << "";
- }
-
- if(loaderModList()->size())
- {
- out << "Mods:";
- for(auto & mod: loaderModList()->allMods())
- {
- if(!mod.enabled())
- continue;
- if(mod.type() == Mod::MOD_FOLDER)
- continue;
- // TODO: proper implementation would need to descend into folders.
-
- out << " " + mod.filename().completeBaseName();
- }
- out << "";
- }
-
- if(coreModList()->size())
- {
- out << "Core Mods:";
- for(auto & coremod: coreModList()->allMods())
- {
- if(!coremod.enabled())
- continue;
- if(coremod.type() == Mod::MOD_FOLDER)
- continue;
- // TODO: proper implementation would need to descend into folders.
-
- out << " " + coremod.filename().completeBaseName();
- }
- out << "";
- }
-
- auto & jarMods = profile->getJarMods();
- if(jarMods.size())
- {
- out << "Jar Mods:";
- for(auto & jarmod: jarMods)
- {
- auto displayname = jarmod->displayName(currentSystem);
- auto realname = jarmod->filename(currentSystem);
- if(displayname != realname)
- {
- out << " " + displayname + " (" + realname + ")";
- }
- else
- {
- out << " " + realname;
- }
- }
- out << "";
- }
-
- auto params = processMinecraftArgs(nullptr);
- out << "Params:";
- out << " " + params.join(' ');
- out << "";
-
- QString windowParams;
- if (settings()->get("LaunchMaximized").toBool())
- {
- out << "Window size: max (if available)";
- }
- else
- {
- auto width = settings()->get("MinecraftWinWidth").toInt();
- auto height = settings()->get("MinecraftWinHeight").toInt();
- out << "Window size: " + QString::number(width) + " x " + QString::number(height);
- }
- out << "";
- return out;
+ QStringList out;
+ out << "Main Class:" << " " + getMainClass() << "";
+ out << "Native path:" << " " + getNativePath() << "";
+
+ auto profile = m_components->getProfile();
+
+ auto alltraits = traits();
+ if(alltraits.size())
+ {
+ out << "Traits:";
+ for (auto trait : alltraits)
+ {
+ out << "traits " + trait;
+ }
+ out << "";
+ }
+
+ // libraries and class path.
+ {
+ out << "Libraries:";
+ QStringList jars, nativeJars;
+ auto javaArchitecture = settings()->get("JavaArchitecture").toString();
+ profile->getLibraryFiles(javaArchitecture, jars, nativeJars, getLocalLibraryPath(), binRoot());
+ auto printLibFile = [&](const QString & path)
+ {
+ QFileInfo info(path);
+ if(info.exists())
+ {
+ out << " " + path;
+ }
+ else
+ {
+ out << " " + path + " (missing)";
+ }
+ };
+ for(auto file: jars)
+ {
+ printLibFile(file);
+ }
+ out << "";
+ out << "Native libraries:";
+ for(auto file: nativeJars)
+ {
+ printLibFile(file);
+ }
+ out << "";
+ }
+
+ if(loaderModList()->size())
+ {
+ out << "Mods:";
+ for(auto & mod: loaderModList()->allMods())
+ {
+ if(!mod.enabled())
+ continue;
+ if(mod.type() == Mod::MOD_FOLDER)
+ continue;
+ // TODO: proper implementation would need to descend into folders.
+
+ out << " " + mod.filename().completeBaseName();
+ }
+ out << "";
+ }
+
+ if(coreModList()->size())
+ {
+ out << "Core Mods:";
+ for(auto & coremod: coreModList()->allMods())
+ {
+ if(!coremod.enabled())
+ continue;
+ if(coremod.type() == Mod::MOD_FOLDER)
+ continue;
+ // TODO: proper implementation would need to descend into folders.
+
+ out << " " + coremod.filename().completeBaseName();
+ }
+ out << "";
+ }
+
+ auto & jarMods = profile->getJarMods();
+ if(jarMods.size())
+ {
+ out << "Jar Mods:";
+ for(auto & jarmod: jarMods)
+ {
+ auto displayname = jarmod->displayName(currentSystem);
+ auto realname = jarmod->filename(currentSystem);
+ if(displayname != realname)
+ {
+ out << " " + displayname + " (" + realname + ")";
+ }
+ else
+ {
+ out << " " + realname;
+ }
+ }
+ out << "";
+ }
+
+ auto params = processMinecraftArgs(nullptr);
+ out << "Params:";
+ out << " " + params.join(' ');
+ out << "";
+
+ QString windowParams;
+ if (settings()->get("LaunchMaximized").toBool())
+ {
+ out << "Window size: max (if available)";
+ }
+ else
+ {
+ auto width = settings()->get("MinecraftWinWidth").toInt();
+ auto height = settings()->get("MinecraftWinHeight").toInt();
+ out << "Window size: " + QString::number(width) + " x " + QString::number(height);
+ }
+ out << "";
+ return out;
}
QMap<QString, QString> MinecraftInstance::createCensorFilterFromSession(AuthSessionPtr session)
{
- if(!session)
- {
- return QMap<QString, QString>();
- }
- auto & sessionRef = *session.get();
- QMap<QString, QString> filter;
- auto addToFilter = [&filter](QString key, QString value)
- {
- if(key.trimmed().size())
- {
- filter[key] = value;
- }
- };
- if (sessionRef.session != "-")
- {
- addToFilter(sessionRef.session, tr("<SESSION ID>"));
- }
- addToFilter(sessionRef.access_token, tr("<ACCESS TOKEN>"));
- addToFilter(sessionRef.client_token, tr("<CLIENT TOKEN>"));
- addToFilter(sessionRef.uuid, tr("<PROFILE ID>"));
-
- auto i = sessionRef.u.properties.begin();
- while (i != sessionRef.u.properties.end())
- {
- if(i.key() == "preferredLanguage")
- {
- ++i;
- continue;
- }
- addToFilter(i.value(), "<" + i.key().toUpper() + ">");
- ++i;
- }
- return filter;
+ if(!session)
+ {
+ return QMap<QString, QString>();
+ }
+ auto & sessionRef = *session.get();
+ QMap<QString, QString> filter;
+ auto addToFilter = [&filter](QString key, QString value)
+ {
+ if(key.trimmed().size())
+ {
+ filter[key] = value;
+ }
+ };
+ if (sessionRef.session != "-")
+ {
+ addToFilter(sessionRef.session, tr("<SESSION ID>"));
+ }
+ addToFilter(sessionRef.access_token, tr("<ACCESS TOKEN>"));
+ addToFilter(sessionRef.client_token, tr("<CLIENT TOKEN>"));
+ addToFilter(sessionRef.uuid, tr("<PROFILE ID>"));
+
+ auto i = sessionRef.u.properties.begin();
+ while (i != sessionRef.u.properties.end())
+ {
+ if(i.key() == "preferredLanguage")
+ {
+ ++i;
+ continue;
+ }
+ addToFilter(i.value(), "<" + i.key().toUpper() + ">");
+ ++i;
+ }
+ return filter;
}
MessageLevel::Enum MinecraftInstance::guessLevel(const QString &line, MessageLevel::Enum level)
{
- QRegularExpression re("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
- auto match = re.match(line);
- if(match.hasMatch())
- {
- // New style logs from log4j
- QString timestamp = match.captured("timestamp");
- QString levelStr = match.captured("level");
- if(levelStr == "INFO")
- level = MessageLevel::Message;
- if(levelStr == "WARN")
- level = MessageLevel::Warning;
- if(levelStr == "ERROR")
- level = MessageLevel::Error;
- if(levelStr == "FATAL")
- level = MessageLevel::Fatal;
- if(levelStr == "TRACE" || levelStr == "DEBUG")
- level = MessageLevel::Debug;
- }
- else
- {
- // Old style forge logs
- if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") ||
- line.contains("[FINER]") || line.contains("[FINEST]"))
- level = MessageLevel::Message;
- if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
- level = MessageLevel::Error;
- if (line.contains("[WARNING]"))
- level = MessageLevel::Warning;
- if (line.contains("[DEBUG]"))
- level = MessageLevel::Debug;
- }
- if (line.contains("overwriting existing"))
- return MessageLevel::Fatal;
- //NOTE: this diverges from the real regexp. no unicode, the first section is + instead of *
- static const QString javaSymbol = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*";
- if (line.contains("Exception in thread")
- || line.contains(QRegularExpression("\\s+at " + javaSymbol))
- || line.contains(QRegularExpression("Caused by: " + javaSymbol))
- || line.contains(QRegularExpression("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)"))
- || line.contains(QRegularExpression("... \\d+ more$"))
- )
- return MessageLevel::Error;
- return level;
+ QRegularExpression re("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
+ auto match = re.match(line);
+ if(match.hasMatch())
+ {
+ // New style logs from log4j
+ QString timestamp = match.captured("timestamp");
+ QString levelStr = match.captured("level");
+ if(levelStr == "INFO")
+ level = MessageLevel::Message;
+ if(levelStr == "WARN")
+ level = MessageLevel::Warning;
+ if(levelStr == "ERROR")
+ level = MessageLevel::Error;
+ if(levelStr == "FATAL")
+ level = MessageLevel::Fatal;
+ if(levelStr == "TRACE" || levelStr == "DEBUG")
+ level = MessageLevel::Debug;
+ }
+ else
+ {
+ // Old style forge logs
+ if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") ||
+ line.contains("[FINER]") || line.contains("[FINEST]"))
+ level = MessageLevel::Message;
+ if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
+ level = MessageLevel::Error;
+ if (line.contains("[WARNING]"))
+ level = MessageLevel::Warning;
+ if (line.contains("[DEBUG]"))
+ level = MessageLevel::Debug;
+ }
+ if (line.contains("overwriting existing"))
+ return MessageLevel::Fatal;
+ //NOTE: this diverges from the real regexp. no unicode, the first section is + instead of *
+ static const QString javaSymbol = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*";
+ if (line.contains("Exception in thread")
+ || line.contains(QRegularExpression("\\s+at " + javaSymbol))
+ || line.contains(QRegularExpression("Caused by: " + javaSymbol))
+ || line.contains(QRegularExpression("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)"))
+ || line.contains(QRegularExpression("... \\d+ more$"))
+ )
+ return MessageLevel::Error;
+ return level;
}
IPathMatcher::Ptr MinecraftInstance::getLogFileMatcher()
{
- auto combined = std::make_shared<MultiMatcher>();
- combined->add(std::make_shared<RegexpMatcher>(".*\\.log(\\.[0-9]*)?(\\.gz)?$"));
- combined->add(std::make_shared<RegexpMatcher>("crash-.*\\.txt"));
- combined->add(std::make_shared<RegexpMatcher>("IDMap dump.*\\.txt$"));
- combined->add(std::make_shared<RegexpMatcher>("ModLoader\\.txt(\\..*)?$"));
- return combined;
+ auto combined = std::make_shared<MultiMatcher>();
+ combined->add(std::make_shared<RegexpMatcher>(".*\\.log(\\.[0-9]*)?(\\.gz)?$"));
+ combined->add(std::make_shared<RegexpMatcher>("crash-.*\\.txt"));
+ combined->add(std::make_shared<RegexpMatcher>("IDMap dump.*\\.txt$"));
+ combined->add(std::make_shared<RegexpMatcher>("ModLoader\\.txt(\\..*)?$"));
+ return combined;
}
QString MinecraftInstance::getLogFileRoot()
{
- return minecraftRoot();
+ return minecraftRoot();
}
QString MinecraftInstance::prettifyTimeDuration(int64_t duration)
{
- int seconds = (int) (duration % 60);
- duration /= 60;
- int minutes = (int) (duration % 60);
- duration /= 60;
- int hours = (int) (duration % 24);
- int days = (int) (duration / 24);
- if((hours == 0)&&(days == 0))
- {
- return tr("%1m %2s").arg(minutes).arg(seconds);
- }
- if (days == 0)
- {
- return tr("%1h %2m").arg(hours).arg(minutes);
- }
- return tr("%1d %2h %3m").arg(days).arg(hours).arg(minutes);
+ int seconds = (int) (duration % 60);
+ duration /= 60;
+ int minutes = (int) (duration % 60);
+ duration /= 60;
+ int hours = (int) (duration % 24);
+ int days = (int) (duration / 24);
+ if((hours == 0)&&(days == 0))
+ {
+ return tr("%1m %2s").arg(minutes).arg(seconds);
+ }
+ if (days == 0)
+ {
+ return tr("%1h %2m").arg(hours).arg(minutes);
+ }
+ return tr("%1d %2h %3m").arg(days).arg(hours).arg(minutes);
}
QString MinecraftInstance::getStatusbarDescription()
{
- QStringList traits;
- if (hasVersionBroken())
- {
- traits.append(tr("broken"));
- }
-
- QString description;
- description.append(tr("Minecraft %1 (%2)").arg(m_components->getComponentVersion("net.minecraft")).arg(typeName()));
- if(totalTimePlayed() > 0)
- {
- description.append(tr(", played for %1").arg(prettifyTimeDuration(totalTimePlayed())));
- }
- if(hasCrashed())
- {
- description.append(tr(", has crashed."));
- }
- return description;
+ QStringList traits;
+ if (hasVersionBroken())
+ {
+ traits.append(tr("broken"));
+ }
+
+ QString description;
+ description.append(tr("Minecraft %1 (%2)").arg(m_components->getComponentVersion("net.minecraft")).arg(typeName()));
+ if(totalTimePlayed() > 0)
+ {
+ description.append(tr(", played for %1").arg(prettifyTimeDuration(totalTimePlayed())));
+ }
+ if(hasCrashed())
+ {
+ description.append(tr(", has crashed."));
+ }
+ return description;
}
shared_qobject_ptr<Task> MinecraftInstance::createUpdateTask(Net::Mode mode)
{
- switch (mode)
- {
- case Net::Mode::Offline:
- {
- return shared_qobject_ptr<Task>(new MinecraftLoadAndCheck(this));
- }
- case Net::Mode::Online:
- {
- return shared_qobject_ptr<Task>(new OneSixUpdate(this));
- }
- }
- return nullptr;
+ switch (mode)
+ {
+ case Net::Mode::Offline:
+ {
+ return shared_qobject_ptr<Task>(new MinecraftLoadAndCheck(this));
+ }
+ case Net::Mode::Online:
+ {
+ return shared_qobject_ptr<Task>(new OneSixUpdate(this));
+ }
+ }
+ return nullptr;
}
std::shared_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session)
{
- auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
- auto pptr = process.get();
-
- ENV.icons()->saveIcon(iconKey(), FS::PathCombine(minecraftRoot(), "icon.png"), "PNG");
-
- // print a header
- {
- process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC));
- }
-
- // check java
- {
- auto step = std::make_shared<CheckJava>(pptr);
- process->appendStep(step);
- }
-
- // check launch method
- QStringList validMethods = {"LauncherPart", "DirectJava"};
- QString method = launchMethod();
- if(!validMethods.contains(method))
- {
- process->appendStep(std::make_shared<TextPrint>(pptr, "Selected launch method \"" + method + "\" is not valid.\n", MessageLevel::Fatal));
- return process;
- }
-
- // run pre-launch command if that's needed
- if(getPreLaunchCommand().size())
- {
- auto step = std::make_shared<PreLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
-
- // if we aren't in offline mode,.
- if(session->status != AuthSession::PlayableOffline)
- {
- process->appendStep(std::make_shared<ClaimAccount>(pptr, session));
- process->appendStep(std::make_shared<Update>(pptr, Net::Mode::Online));
- }
- else
- {
- process->appendStep(std::make_shared<Update>(pptr, Net::Mode::Offline));
- }
-
- // if there are any jar mods
- {
- auto step = std::make_shared<ModMinecraftJar>(pptr);
- process->appendStep(step);
- }
-
- // print some instance info here...
- {
- auto step = std::make_shared<PrintInstanceInfo>(pptr, session);
- process->appendStep(step);
- }
-
- // create the server-resource-packs folder (workaround for Minecraft bug MCL-3732)
- {
- auto step = std::make_shared<CreateServerResourcePacksFolder>(pptr);
- process->appendStep(step);
- }
-
- // extract native jars if needed
- {
- auto step = std::make_shared<ExtractNatives>(pptr);
- process->appendStep(step);
- }
-
- {
- // actually launch the game
- auto method = launchMethod();
- if(method == "LauncherPart")
- {
- auto step = std::make_shared<LauncherPartLaunch>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- step->setAuthSession(session);
- process->appendStep(step);
- }
- else if (method == "DirectJava")
- {
- auto step = std::make_shared<DirectJavaLaunch>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- step->setAuthSession(session);
- process->appendStep(step);
- }
- }
-
- // run post-exit command if that's needed
- if(getPostExitCommand().size())
- {
- auto step = std::make_shared<PostLaunchCommand>(pptr);
- step->setWorkingDirectory(minecraftRoot());
- process->appendStep(step);
- }
- if (session)
- {
- process->setCensorFilter(createCensorFilterFromSession(session));
- }
- m_launchProcess = process;
- emit launchTaskChanged(m_launchProcess);
- return m_launchProcess;
+ auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
+ auto pptr = process.get();
+
+ ENV.icons()->saveIcon(iconKey(), FS::PathCombine(minecraftRoot(), "icon.png"), "PNG");
+
+ // print a header
+ {
+ process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + minecraftRoot() + "\n\n", MessageLevel::MultiMC));
+ }
+
+ // check java
+ {
+ auto step = std::make_shared<CheckJava>(pptr);
+ process->appendStep(step);
+ }
+
+ // check launch method
+ QStringList validMethods = {"LauncherPart", "DirectJava"};
+ QString method = launchMethod();
+ if(!validMethods.contains(method))
+ {
+ process->appendStep(std::make_shared<TextPrint>(pptr, "Selected launch method \"" + method + "\" is not valid.\n", MessageLevel::Fatal));
+ return process;
+ }
+
+ // run pre-launch command if that's needed
+ if(getPreLaunchCommand().size())
+ {
+ auto step = std::make_shared<PreLaunchCommand>(pptr);
+ step->setWorkingDirectory(minecraftRoot());
+ process->appendStep(step);
+ }
+
+ // if we aren't in offline mode,.
+ if(session->status != AuthSession::PlayableOffline)
+ {
+ process->appendStep(std::make_shared<ClaimAccount>(pptr, session));
+ process->appendStep(std::make_shared<Update>(pptr, Net::Mode::Online));
+ }
+ else
+ {
+ process->appendStep(std::make_shared<Update>(pptr, Net::Mode::Offline));
+ }
+
+ // if there are any jar mods
+ {
+ auto step = std::make_shared<ModMinecraftJar>(pptr);
+ process->appendStep(step);
+ }
+
+ // print some instance info here...
+ {
+ auto step = std::make_shared<PrintInstanceInfo>(pptr, session);
+ process->appendStep(step);
+ }
+
+ // create the server-resource-packs folder (workaround for Minecraft bug MCL-3732)
+ {
+ auto step = std::make_shared<CreateServerResourcePacksFolder>(pptr);
+ process->appendStep(step);
+ }
+
+ // extract native jars if needed
+ {
+ auto step = std::make_shared<ExtractNatives>(pptr);
+ process->appendStep(step);
+ }
+
+ {
+ // actually launch the game
+ auto method = launchMethod();
+ if(method == "LauncherPart")
+ {
+ auto step = std::make_shared<LauncherPartLaunch>(pptr);
+ step->setWorkingDirectory(minecraftRoot());
+ step->setAuthSession(session);
+ process->appendStep(step);
+ }
+ else if (method == "DirectJava")
+ {
+ auto step = std::make_shared<DirectJavaLaunch>(pptr);
+ step->setWorkingDirectory(minecraftRoot());
+ step->setAuthSession(session);
+ process->appendStep(step);
+ }
+ }
+
+ // run post-exit command if that's needed
+ if(getPostExitCommand().size())
+ {
+ auto step = std::make_shared<PostLaunchCommand>(pptr);
+ step->setWorkingDirectory(minecraftRoot());
+ process->appendStep(step);
+ }
+ if (session)
+ {
+ process->setCensorFilter(createCensorFilterFromSession(session));
+ }
+ m_launchProcess = process;
+ emit launchTaskChanged(m_launchProcess);
+ return m_launchProcess;
}
QString MinecraftInstance::launchMethod()
{
- return m_settings->get("MCLaunchMethod").toString();
+ return m_settings->get("MCLaunchMethod").toString();
}
JavaVersion MinecraftInstance::getJavaVersion() const
{
- return JavaVersion(settings()->get("JavaVersion").toString());
+ return JavaVersion(settings()->get("JavaVersion").toString());
}
std::shared_ptr<SimpleModList> MinecraftInstance::loaderModList() const
{
- if (!m_loader_mod_list)
- {
- m_loader_mod_list.reset(new SimpleModList(loaderModsDir()));
- }
- m_loader_mod_list->update();
- return m_loader_mod_list;
+ if (!m_loader_mod_list)
+ {
+ m_loader_mod_list.reset(new SimpleModList(loaderModsDir()));
+ }
+ m_loader_mod_list->update();
+ return m_loader_mod_list;
}
std::shared_ptr<ModsModel> MinecraftInstance::modsModel() const
{
- if (!m_mods_model)
- {
- m_mods_model.reset(new ModsModel(loaderModsDir(), coreModsDir(), modsCacheLocation()));
- }
- m_mods_model->update();
- return m_mods_model;
+ if (!m_mods_model)
+ {
+ m_mods_model.reset(new ModsModel(loaderModsDir(), coreModsDir(), modsCacheLocation()));
+ }
+ m_mods_model->update();
+ return m_mods_model;
}
std::shared_ptr<SimpleModList> MinecraftInstance::coreModList() const
{
- if (!m_core_mod_list)
- {
- m_core_mod_list.reset(new SimpleModList(coreModsDir()));
- }
- m_core_mod_list->update();
- return m_core_mod_list;
+ if (!m_core_mod_list)
+ {
+ m_core_mod_list.reset(new SimpleModList(coreModsDir()));
+ }
+ m_core_mod_list->update();
+ return m_core_mod_list;
}
std::shared_ptr<SimpleModList> MinecraftInstance::resourcePackList() const
{
- if (!m_resource_pack_list)
- {
- m_resource_pack_list.reset(new SimpleModList(resourcePacksDir()));
- }
- m_resource_pack_list->update();
- return m_resource_pack_list;
+ if (!m_resource_pack_list)
+ {
+ m_resource_pack_list.reset(new SimpleModList(resourcePacksDir()));
+ }
+ m_resource_pack_list->update();
+ return m_resource_pack_list;
}
std::shared_ptr<SimpleModList> MinecraftInstance::texturePackList() const
{
- if (!m_texture_pack_list)
- {
- m_texture_pack_list.reset(new SimpleModList(texturePacksDir()));
- }
- m_texture_pack_list->update();
- return m_texture_pack_list;
+ if (!m_texture_pack_list)
+ {
+ m_texture_pack_list.reset(new SimpleModList(texturePacksDir()));
+ }
+ m_texture_pack_list->update();
+ return m_texture_pack_list;
}
std::shared_ptr<WorldList> MinecraftInstance::worldList() const
{
- if (!m_world_list)
- {
- m_world_list.reset(new WorldList(worldDir()));
- }
- return m_world_list;
+ if (!m_world_list)
+ {
+ m_world_list.reset(new WorldList(worldDir()));
+ }
+ return m_world_list;
}
QList< Mod > MinecraftInstance::getJarMods() const
{
- auto profile = m_components->getProfile();
- QList<Mod> mods;
- for (auto jarmod : profile->getJarMods())
- {
- QStringList jar, temp1, temp2, temp3;
- jarmod->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, jarmodsPath().absolutePath());
- // QString filePath = jarmodsPath().absoluteFilePath(jarmod->filename(currentSystem));
- mods.push_back(Mod(QFileInfo(jar[0])));
- }
- return mods;
+ auto profile = m_components->getProfile();
+ QList<Mod> mods;
+ for (auto jarmod : profile->getJarMods())
+ {
+ QStringList jar, temp1, temp2, temp3;
+ jarmod->getApplicableFiles(currentSystem, jar, temp1, temp2, temp3, jarmodsPath().absolutePath());
+ // QString filePath = jarmodsPath().absoluteFilePath(jarmod->filename(currentSystem));
+ mods.push_back(Mod(QFileInfo(jar[0])));
+ }
+ return mods;
}
diff --git a/api/logic/minecraft/MinecraftInstance.h b/api/logic/minecraft/MinecraftInstance.h
index f1499ef6..460900c8 100644
--- a/api/logic/minecraft/MinecraftInstance.h
+++ b/api/logic/minecraft/MinecraftInstance.h
@@ -14,115 +14,115 @@ class ComponentList;
class MULTIMC_LOGIC_EXPORT MinecraftInstance: public BaseInstance
{
- Q_OBJECT
+ Q_OBJECT
public:
- MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
- virtual ~MinecraftInstance() {};
- virtual void init() override;
- virtual void saveNow() override;
-
- // FIXME: remove
- QString typeName() const override;
- // FIXME: remove
- QSet<QString> traits() const override;
-
- bool canEdit() const override
- {
- return true;
- }
-
- bool canExport() const override
- {
- return true;
- }
-
- ////// Directories and files //////
- QString jarModsDir() const;
- QString resourcePacksDir() const;
- QString texturePacksDir() const;
- QString loaderModsDir() const;
- QString coreModsDir() const;
+ MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
+ virtual ~MinecraftInstance() {};
+ virtual void init() override;
+ virtual void saveNow() override;
+
+ // FIXME: remove
+ QString typeName() const override;
+ // FIXME: remove
+ QSet<QString> traits() const override;
+
+ bool canEdit() const override
+ {
+ return true;
+ }
+
+ bool canExport() const override
+ {
+ return true;
+ }
+
+ ////// Directories and files //////
+ QString jarModsDir() const;
+ QString resourcePacksDir() const;
+ QString texturePacksDir() const;
+ QString loaderModsDir() const;
+ QString coreModsDir() const;
QString modsCacheLocation() const;
- QString libDir() const;
- QString worldDir() const;
- QDir jarmodsPath() const;
- QDir librariesPath() const;
- QDir versionsPath() const;
- QString instanceConfigFolder() const override;
- QString minecraftRoot() const; // Path to the instance's minecraft directory.
- QString binRoot() const; // Path to the instance's minecraft bin directory.
- QString getNativePath() const; // where to put the natives during/before launch
- QString getLocalLibraryPath() const; // where the instance-local libraries should be
-
-
- ////// Profile management //////
- std::shared_ptr<ComponentList> getComponentList() const;
-
- ////// Mod Lists //////
+ QString libDir() const;
+ QString worldDir() const;
+ QDir jarmodsPath() const;
+ QDir librariesPath() const;
+ QDir versionsPath() const;
+ QString instanceConfigFolder() const override;
+ QString minecraftRoot() const; // Path to the instance's minecraft directory.
+ QString binRoot() const; // Path to the instance's minecraft bin directory.
+ QString getNativePath() const; // where to put the natives during/before launch
+ QString getLocalLibraryPath() const; // where the instance-local libraries should be
+
+
+ ////// Profile management //////
+ std::shared_ptr<ComponentList> getComponentList() const;
+
+ ////// Mod Lists //////
std::shared_ptr<ModsModel> modsModel() const;
- std::shared_ptr<SimpleModList> loaderModList() const;
- std::shared_ptr<SimpleModList> coreModList() const;
- std::shared_ptr<SimpleModList> resourcePackList() const;
- std::shared_ptr<SimpleModList> texturePackList() const;
- std::shared_ptr<WorldList> worldList() const;
+ std::shared_ptr<SimpleModList> loaderModList() const;
+ std::shared_ptr<SimpleModList> coreModList() const;
+ std::shared_ptr<SimpleModList> resourcePackList() const;
+ std::shared_ptr<SimpleModList> texturePackList() const;
+ std::shared_ptr<WorldList> worldList() const;
- ////// Launch stuff //////
- shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override;
- std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
- QStringList extraArguments() const override;
- QStringList verboseDescription(AuthSessionPtr session) override;
- QList<Mod> getJarMods() const;
- QString createLaunchScript(AuthSessionPtr session);
- /// get arguments passed to java
- QStringList javaArguments() const;
+ ////// Launch stuff //////
+ shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override;
+ std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
+ QStringList extraArguments() const override;
+ QStringList verboseDescription(AuthSessionPtr session) override;
+ QList<Mod> getJarMods() const;
+ QString createLaunchScript(AuthSessionPtr session);
+ /// get arguments passed to java
+ QStringList javaArguments() const;
- /// get variables for launch command variable substitution/environment
- QMap<QString, QString> getVariables() const override;
+ /// get variables for launch command variable substitution/environment
+ QMap<QString, QString> getVariables() const override;
- /// create an environment for launching processes
- QProcessEnvironment createEnvironment() override;
+ /// create an environment for launching processes
+ QProcessEnvironment createEnvironment() override;
- /// guess log level from a line of minecraft log
- MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level) override;
+ /// guess log level from a line of minecraft log
+ MessageLevel::Enum guessLevel(const QString &line, MessageLevel::Enum level) override;
- IPathMatcher::Ptr getLogFileMatcher() override;
+ IPathMatcher::Ptr getLogFileMatcher() override;
- QString getLogFileRoot() override;
+ QString getLogFileRoot() override;
- QString getStatusbarDescription() override;
+ QString getStatusbarDescription() override;
- // FIXME: remove
- virtual QStringList getClassPath() const;
- // FIXME: remove
- virtual QStringList getNativeJars() const;
- // FIXME: remove
- virtual QString getMainClass() const;
+ // FIXME: remove
+ virtual QStringList getClassPath() const;
+ // FIXME: remove
+ virtual QStringList getNativeJars() const;
+ // FIXME: remove
+ virtual QString getMainClass() const;
- // FIXME: remove
- virtual QStringList processMinecraftArgs(AuthSessionPtr account) const;
+ // FIXME: remove
+ virtual QStringList processMinecraftArgs(AuthSessionPtr account) const;
- virtual JavaVersion getJavaVersion() const;
+ virtual JavaVersion getJavaVersion() const;
signals:
- void versionReloaded();
+ void versionReloaded();
protected:
- QMap<QString, QString> createCensorFilterFromSession(AuthSessionPtr session);
- QStringList validLaunchMethods();
- QString launchMethod();
+ QMap<QString, QString> createCensorFilterFromSession(AuthSessionPtr session);
+ QStringList validLaunchMethods();
+ QString launchMethod();
private:
- QString prettifyTimeDuration(int64_t duration);
+ QString prettifyTimeDuration(int64_t duration);
protected: // data
- std::shared_ptr<ComponentList> m_components;
- mutable std::shared_ptr<ModsModel> m_mods_model;
- mutable std::shared_ptr<SimpleModList> m_loader_mod_list;
- mutable std::shared_ptr<SimpleModList> m_core_mod_list;
- mutable std::shared_ptr<SimpleModList> m_resource_pack_list;
- mutable std::shared_ptr<SimpleModList> m_texture_pack_list;
- mutable std::shared_ptr<WorldList> m_world_list;
+ std::shared_ptr<ComponentList> m_components;
+ mutable std::shared_ptr<ModsModel> m_mods_model;
+ mutable std::shared_ptr<SimpleModList> m_loader_mod_list;
+ mutable std::shared_ptr<SimpleModList> m_core_mod_list;
+ mutable std::shared_ptr<SimpleModList> m_resource_pack_list;
+ mutable std::shared_ptr<SimpleModList> m_texture_pack_list;
+ mutable std::shared_ptr<WorldList> m_world_list;
};
typedef std::shared_ptr<MinecraftInstance> MinecraftInstancePtr;
diff --git a/api/logic/minecraft/MinecraftLoadAndCheck.cpp b/api/logic/minecraft/MinecraftLoadAndCheck.cpp
index c64bbddf..a5052b53 100644
--- a/api/logic/minecraft/MinecraftLoadAndCheck.cpp
+++ b/api/logic/minecraft/MinecraftLoadAndCheck.cpp
@@ -8,38 +8,38 @@ MinecraftLoadAndCheck::MinecraftLoadAndCheck(MinecraftInstance *inst, QObject *p
void MinecraftLoadAndCheck::executeTask()
{
- // add offline metadata load task
- auto components = m_inst->getComponentList();
- components->reload(Net::Mode::Offline);
- m_task = components->getCurrentTask();
+ // add offline metadata load task
+ auto components = m_inst->getComponentList();
+ components->reload(Net::Mode::Offline);
+ m_task = components->getCurrentTask();
- if(!m_task)
- {
- emitSucceeded();
- return;
- }
- connect(m_task.get(), &Task::succeeded, this, &MinecraftLoadAndCheck::subtaskSucceeded);
- connect(m_task.get(), &Task::failed, this, &MinecraftLoadAndCheck::subtaskFailed);
- connect(m_task.get(), &Task::progress, this, &MinecraftLoadAndCheck::progress);
- connect(m_task.get(), &Task::status, this, &MinecraftLoadAndCheck::setStatus);
+ if(!m_task)
+ {
+ emitSucceeded();
+ return;
+ }
+ connect(m_task.get(), &Task::succeeded, this, &MinecraftLoadAndCheck::subtaskSucceeded);
+ connect(m_task.get(), &Task::failed, this, &MinecraftLoadAndCheck::subtaskFailed);
+ connect(m_task.get(), &Task::progress, this, &MinecraftLoadAndCheck::progress);
+ connect(m_task.get(), &Task::status, this, &MinecraftLoadAndCheck::setStatus);
}
void MinecraftLoadAndCheck::subtaskSucceeded()
{
- if(isFinished())
- {
- qCritical() << "OneSixUpdate: Subtask" << sender() << "succeeded, but work was already done!";
- return;
- }
- emitSucceeded();
+ if(isFinished())
+ {
+ qCritical() << "OneSixUpdate: Subtask" << sender() << "succeeded, but work was already done!";
+ return;
+ }
+ emitSucceeded();
}
void MinecraftLoadAndCheck::subtaskFailed(QString error)
{
- if(isFinished())
- {
- qCritical() << "OneSixUpdate: Subtask" << sender() << "failed, but work was already done!";
- return;
- }
- emitFailed(error);
+ if(isFinished())
+ {
+ qCritical() << "OneSixUpdate: Subtask" << sender() << "failed, but work was already done!";
+ return;
+ }
+ emitFailed(error);
}
diff --git a/api/logic/minecraft/MinecraftLoadAndCheck.h b/api/logic/minecraft/MinecraftLoadAndCheck.h
index 91aed674..1f5c2018 100644
--- a/api/logic/minecraft/MinecraftLoadAndCheck.h
+++ b/api/logic/minecraft/MinecraftLoadAndCheck.h
@@ -29,20 +29,20 @@ class MinecraftInstance;
class MinecraftLoadAndCheck : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit MinecraftLoadAndCheck(MinecraftInstance *inst, QObject *parent = 0);
- virtual ~MinecraftLoadAndCheck() {};
- void executeTask() override;
+ explicit MinecraftLoadAndCheck(MinecraftInstance *inst, QObject *parent = 0);
+ virtual ~MinecraftLoadAndCheck() {};
+ void executeTask() override;
private slots:
- void subtaskSucceeded();
- void subtaskFailed(QString error);
+ void subtaskSucceeded();
+ void subtaskFailed(QString error);
private:
- MinecraftInstance *m_inst = nullptr;
- shared_qobject_ptr<Task> m_task;
- QString m_preFailure;
- QString m_fail_reason;
+ MinecraftInstance *m_inst = nullptr;
+ shared_qobject_ptr<Task> m_task;
+ QString m_preFailure;
+ QString m_fail_reason;
};
diff --git a/api/logic/minecraft/MinecraftUpdate.cpp b/api/logic/minecraft/MinecraftUpdate.cpp
index 86835fa4..e62ff745 100644
--- a/api/logic/minecraft/MinecraftUpdate.cpp
+++ b/api/logic/minecraft/MinecraftUpdate.cpp
@@ -43,142 +43,142 @@ OneSixUpdate::OneSixUpdate(MinecraftInstance *inst, QObject *parent) : Task(pare
void OneSixUpdate::executeTask()
{
- m_tasks.clear();
- // create folders
- {
- m_tasks.append(std::make_shared<FoldersTask>(m_inst));
- }
-
- // add metadata update task if necessary
- {
- auto components = m_inst->getComponentList();
- components->reload(Net::Mode::Online);
- auto task = components->getCurrentTask();
- if(task)
- {
- m_tasks.append(task.unwrap());
- }
- }
-
- // libraries download
- {
- m_tasks.append(std::make_shared<LibrariesTask>(m_inst));
- }
-
- // FML libraries download and copy into the instance
- {
- m_tasks.append(std::make_shared<FMLLibrariesTask>(m_inst));
- }
-
- // assets update
- {
- m_tasks.append(std::make_shared<AssetUpdateTask>(m_inst));
- }
-
- if(!m_preFailure.isEmpty())
- {
- emitFailed(m_preFailure);
- return;
- }
- next();
+ m_tasks.clear();
+ // create folders
+ {
+ m_tasks.append(std::make_shared<FoldersTask>(m_inst));
+ }
+
+ // add metadata update task if necessary
+ {
+ auto components = m_inst->getComponentList();
+ components->reload(Net::Mode::Online);
+ auto task = components->getCurrentTask();
+ if(task)
+ {
+ m_tasks.append(task.unwrap());
+ }
+ }
+
+ // libraries download
+ {
+ m_tasks.append(std::make_shared<LibrariesTask>(m_inst));
+ }
+
+ // FML libraries download and copy into the instance
+ {
+ m_tasks.append(std::make_shared<FMLLibrariesTask>(m_inst));
+ }
+
+ // assets update
+ {
+ m_tasks.append(std::make_shared<AssetUpdateTask>(m_inst));
+ }
+
+ if(!m_preFailure.isEmpty())
+ {
+ emitFailed(m_preFailure);
+ return;
+ }
+ next();
}
void OneSixUpdate::next()
{
- if(m_abort)
- {
- emitFailed(tr("Aborted by user."));
- return;
- }
- if(m_failed_out_of_order)
- {
- emitFailed(m_fail_reason);
- return;
- }
- m_currentTask ++;
- if(m_currentTask > 0)
- {
- auto task = m_tasks[m_currentTask - 1];
- disconnect(task.get(), &Task::succeeded, this, &OneSixUpdate::subtaskSucceeded);
- disconnect(task.get(), &Task::failed, this, &OneSixUpdate::subtaskFailed);
- disconnect(task.get(), &Task::progress, this, &OneSixUpdate::progress);
- disconnect(task.get(), &Task::status, this, &OneSixUpdate::setStatus);
- }
- if(m_currentTask == m_tasks.size())
- {
- emitSucceeded();
- return;
- }
- auto task = m_tasks[m_currentTask];
- // if the task is already finished by the time we look at it, skip it
- if(task->isFinished())
- {
- qCritical() << "OneSixUpdate: Skipping finished subtask" << m_currentTask << ":" << task.get();
- next();
- }
- connect(task.get(), &Task::succeeded, this, &OneSixUpdate::subtaskSucceeded);
- connect(task.get(), &Task::failed, this, &OneSixUpdate::subtaskFailed);
- connect(task.get(), &Task::progress, this, &OneSixUpdate::progress);
- connect(task.get(), &Task::status, this, &OneSixUpdate::setStatus);
- // if the task is already running, do not start it again
- if(!task->isRunning())
- {
- task->start();
- }
+ if(m_abort)
+ {
+ emitFailed(tr("Aborted by user."));
+ return;
+ }
+ if(m_failed_out_of_order)
+ {
+ emitFailed(m_fail_reason);
+ return;
+ }
+ m_currentTask ++;
+ if(m_currentTask > 0)
+ {
+ auto task = m_tasks[m_currentTask - 1];
+ disconnect(task.get(), &Task::succeeded, this, &OneSixUpdate::subtaskSucceeded);
+ disconnect(task.get(), &Task::failed, this, &OneSixUpdate::subtaskFailed);
+ disconnect(task.get(), &Task::progress, this, &OneSixUpdate::progress);
+ disconnect(task.get(), &Task::status, this, &OneSixUpdate::setStatus);
+ }
+ if(m_currentTask == m_tasks.size())
+ {
+ emitSucceeded();
+ return;
+ }
+ auto task = m_tasks[m_currentTask];
+ // if the task is already finished by the time we look at it, skip it
+ if(task->isFinished())
+ {
+ qCritical() << "OneSixUpdate: Skipping finished subtask" << m_currentTask << ":" << task.get();
+ next();
+ }
+ connect(task.get(), &Task::succeeded, this, &OneSixUpdate::subtaskSucceeded);
+ connect(task.get(), &Task::failed, this, &OneSixUpdate::subtaskFailed);
+ connect(task.get(), &Task::progress, this, &OneSixUpdate::progress);
+ connect(task.get(), &Task::status, this, &OneSixUpdate::setStatus);
+ // if the task is already running, do not start it again
+ if(!task->isRunning())
+ {
+ task->start();
+ }
}
void OneSixUpdate::subtaskSucceeded()
{
- if(isFinished())
- {
- qCritical() << "OneSixUpdate: Subtask" << sender() << "succeeded, but work was already done!";
- return;
- }
- auto senderTask = QObject::sender();
- auto currentTask = m_tasks[m_currentTask].get();
- if(senderTask != currentTask)
- {
- qDebug() << "OneSixUpdate: Subtask" << sender() << "succeeded out of order.";
- return;
- }
- next();
+ if(isFinished())
+ {
+ qCritical() << "OneSixUpdate: Subtask" << sender() << "succeeded, but work was already done!";
+ return;
+ }
+ auto senderTask = QObject::sender();
+ auto currentTask = m_tasks[m_currentTask].get();
+ if(senderTask != currentTask)
+ {
+ qDebug() << "OneSixUpdate: Subtask" << sender() << "succeeded out of order.";
+ return;
+ }
+ next();
}
void OneSixUpdate::subtaskFailed(QString error)
{
- if(isFinished())
- {
- qCritical() << "OneSixUpdate: Subtask" << sender() << "failed, but work was already done!";
- return;
- }
- auto senderTask = QObject::sender();
- auto currentTask = m_tasks[m_currentTask].get();
- if(senderTask != currentTask)
- {
- qDebug() << "OneSixUpdate: Subtask" << sender() << "failed out of order.";
- m_failed_out_of_order = true;
- m_fail_reason = error;
- return;
- }
- emitFailed(error);
+ if(isFinished())
+ {
+ qCritical() << "OneSixUpdate: Subtask" << sender() << "failed, but work was already done!";
+ return;
+ }
+ auto senderTask = QObject::sender();
+ auto currentTask = m_tasks[m_currentTask].get();
+ if(senderTask != currentTask)
+ {
+ qDebug() << "OneSixUpdate: Subtask" << sender() << "failed out of order.";
+ m_failed_out_of_order = true;
+ m_fail_reason = error;
+ return;
+ }
+ emitFailed(error);
}
bool OneSixUpdate::abort()
{
- if(!m_abort)
- {
- m_abort = true;
- auto task = m_tasks[m_currentTask];
- if(task->canAbort())
- {
- return task->abort();
- }
- }
- return true;
+ if(!m_abort)
+ {
+ m_abort = true;
+ auto task = m_tasks[m_currentTask];
+ if(task->canAbort())
+ {
+ return task->abort();
+ }
+ }
+ return true;
}
bool OneSixUpdate::canAbort() const
{
- return true;
+ return true;
}
diff --git a/api/logic/minecraft/MinecraftUpdate.h b/api/logic/minecraft/MinecraftUpdate.h
index 543b2f64..f7b37d73 100644
--- a/api/logic/minecraft/MinecraftUpdate.h
+++ b/api/logic/minecraft/MinecraftUpdate.h
@@ -29,29 +29,29 @@ class MinecraftInstance;
class OneSixUpdate : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit OneSixUpdate(MinecraftInstance *inst, QObject *parent = 0);
- virtual ~OneSixUpdate() {};
+ explicit OneSixUpdate(MinecraftInstance *inst, QObject *parent = 0);
+ virtual ~OneSixUpdate() {};
- void executeTask() override;
- bool canAbort() const override;
+ void executeTask() override;
+ bool canAbort() const override;
private
slots:
- bool abort() override;
- void subtaskSucceeded();
- void subtaskFailed(QString error);
+ bool abort() override;
+ void subtaskSucceeded();
+ void subtaskFailed(QString error);
private:
- void next();
+ void next();
private:
- MinecraftInstance *m_inst = nullptr;
- QList<std::shared_ptr<Task>> m_tasks;
- QString m_preFailure;
- int m_currentTask = -1;
- bool m_abort = false;
- bool m_failed_out_of_order = false;
- QString m_fail_reason;
+ MinecraftInstance *m_inst = nullptr;
+ QList<std::shared_ptr<Task>> m_tasks;
+ QString m_preFailure;
+ int m_currentTask = -1;
+ bool m_abort = false;
+ bool m_failed_out_of_order = false;
+ QString m_fail_reason;
};
diff --git a/api/logic/minecraft/Mod.cpp b/api/logic/minecraft/Mod.cpp
index 03e04b2b..bd209211 100644
--- a/api/logic/minecraft/Mod.cpp
+++ b/api/logic/minecraft/Mod.cpp
@@ -29,124 +29,124 @@
Mod::Mod(const QFileInfo &file)
{
- repath(file);
- m_changedDateTime = file.lastModified();
+ repath(file);
+ m_changedDateTime = file.lastModified();
}
void Mod::repath(const QFileInfo &file)
{
- m_file = file;
- QString name_base = file.fileName();
+ m_file = file;
+ QString name_base = file.fileName();
- m_type = Mod::MOD_UNKNOWN;
+ m_type = Mod::MOD_UNKNOWN;
- if (m_file.isDir())
- {
- m_type = MOD_FOLDER;
- m_name = name_base;
- m_mmc_id = name_base;
- }
- else if (m_file.isFile())
- {
- if (name_base.endsWith(".disabled"))
- {
- m_enabled = false;
- name_base.chop(9);
- }
- else
- {
- m_enabled = true;
- }
- m_mmc_id = name_base;
- if (name_base.endsWith(".zip") || name_base.endsWith(".jar"))
- {
- m_type = MOD_ZIPFILE;
- name_base.chop(4);
- }
- else if (name_base.endsWith(".litemod"))
- {
- m_type = MOD_LITEMOD;
- name_base.chop(8);
- }
- else
- {
- m_type = MOD_SINGLEFILE;
- }
- m_name = name_base;
- }
+ if (m_file.isDir())
+ {
+ m_type = MOD_FOLDER;
+ m_name = name_base;
+ m_mmc_id = name_base;
+ }
+ else if (m_file.isFile())
+ {
+ if (name_base.endsWith(".disabled"))
+ {
+ m_enabled = false;
+ name_base.chop(9);
+ }
+ else
+ {
+ m_enabled = true;
+ }
+ m_mmc_id = name_base;
+ if (name_base.endsWith(".zip") || name_base.endsWith(".jar"))
+ {
+ m_type = MOD_ZIPFILE;
+ name_base.chop(4);
+ }
+ else if (name_base.endsWith(".litemod"))
+ {
+ m_type = MOD_LITEMOD;
+ name_base.chop(8);
+ }
+ else
+ {
+ m_type = MOD_SINGLEFILE;
+ }
+ m_name = name_base;
+ }
- if (m_type == MOD_ZIPFILE)
- {
- QuaZip zip(m_file.filePath());
- if (!zip.open(QuaZip::mdUnzip))
- return;
+ if (m_type == MOD_ZIPFILE)
+ {
+ QuaZip zip(m_file.filePath());
+ if (!zip.open(QuaZip::mdUnzip))
+ return;
- QuaZipFile file(&zip);
+ QuaZipFile file(&zip);
- if (zip.setCurrentFile("mcmod.info"))
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- return;
- }
+ if (zip.setCurrentFile("mcmod.info"))
+ {
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ zip.close();
+ return;
+ }
- ReadMCModInfo(file.readAll());
- file.close();
- zip.close();
- return;
- }
- else if (zip.setCurrentFile("forgeversion.properties"))
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- return;
- }
+ ReadMCModInfo(file.readAll());
+ file.close();
+ zip.close();
+ return;
+ }
+ else if (zip.setCurrentFile("forgeversion.properties"))
+ {
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ zip.close();
+ return;
+ }
- ReadForgeInfo(file.readAll());
- file.close();
- zip.close();
- return;
- }
+ ReadForgeInfo(file.readAll());
+ file.close();
+ zip.close();
+ return;
+ }
- zip.close();
- }
- else if (m_type == MOD_FOLDER)
- {
- QFileInfo mcmod_info(FS::PathCombine(m_file.filePath(), "mcmod.info"));
- if (mcmod_info.isFile())
- {
- QFile mcmod(mcmod_info.filePath());
- if (!mcmod.open(QIODevice::ReadOnly))
- return;
- auto data = mcmod.readAll();
- if (data.isEmpty() || data.isNull())
- return;
- ReadMCModInfo(data);
- }
- }
- else if (m_type == MOD_LITEMOD)
- {
- QuaZip zip(m_file.filePath());
- if (!zip.open(QuaZip::mdUnzip))
- return;
+ zip.close();
+ }
+ else if (m_type == MOD_FOLDER)
+ {
+ QFileInfo mcmod_info(FS::PathCombine(m_file.filePath(), "mcmod.info"));
+ if (mcmod_info.isFile())
+ {
+ QFile mcmod(mcmod_info.filePath());
+ if (!mcmod.open(QIODevice::ReadOnly))
+ return;
+ auto data = mcmod.readAll();
+ if (data.isEmpty() || data.isNull())
+ return;
+ ReadMCModInfo(data);
+ }
+ }
+ else if (m_type == MOD_LITEMOD)
+ {
+ QuaZip zip(m_file.filePath());
+ if (!zip.open(QuaZip::mdUnzip))
+ return;
- QuaZipFile file(&zip);
+ QuaZipFile file(&zip);
- if (zip.setCurrentFile("litemod.json"))
- {
- if (!file.open(QIODevice::ReadOnly))
- {
- zip.close();
- return;
- }
+ if (zip.setCurrentFile("litemod.json"))
+ {
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ zip.close();
+ return;
+ }
- ReadLiteModInfo(file.readAll());
- file.close();
- }
- zip.close();
- }
+ ReadLiteModInfo(file.readAll());
+ file.close();
+ }
+ zip.close();
+ }
}
// NEW format
@@ -156,223 +156,223 @@ void Mod::repath(const QFileInfo &file)
// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/5bf6a2d05145ec79387acc0d45c958642fb049fc
void Mod::ReadMCModInfo(QByteArray contents)
{
- auto getInfoFromArray = [&](QJsonArray arr)->void
- {
- if (!arr.at(0).isObject())
- return;
- auto firstObj = arr.at(0).toObject();
- m_mod_id = firstObj.value("modid").toString();
- m_name = firstObj.value("name").toString();
- m_version = firstObj.value("version").toString();
- m_homeurl = firstObj.value("url").toString();
- m_updateurl = firstObj.value("updateUrl").toString();
- m_homeurl = m_homeurl.trimmed();
- if(!m_homeurl.isEmpty())
- {
- // fix up url.
- if (!m_homeurl.startsWith("http://") && !m_homeurl.startsWith("https://") &&
- !m_homeurl.startsWith("ftp://"))
- {
- m_homeurl.prepend("http://");
- }
- }
- m_description = firstObj.value("description").toString();
- QJsonArray authors = firstObj.value("authorList").toArray();
- if (authors.size() == 0)
- authors = firstObj.value("authors").toArray();
+ auto getInfoFromArray = [&](QJsonArray arr)->void
+ {
+ if (!arr.at(0).isObject())
+ return;
+ auto firstObj = arr.at(0).toObject();
+ m_mod_id = firstObj.value("modid").toString();
+ m_name = firstObj.value("name").toString();
+ m_version = firstObj.value("version").toString();
+ m_homeurl = firstObj.value("url").toString();
+ m_updateurl = firstObj.value("updateUrl").toString();
+ m_homeurl = m_homeurl.trimmed();
+ if(!m_homeurl.isEmpty())
+ {
+ // fix up url.
+ if (!m_homeurl.startsWith("http://") && !m_homeurl.startsWith("https://") &&
+ !m_homeurl.startsWith("ftp://"))
+ {
+ m_homeurl.prepend("http://");
+ }
+ }
+ m_description = firstObj.value("description").toString();
+ QJsonArray authors = firstObj.value("authorList").toArray();
+ if (authors.size() == 0)
+ authors = firstObj.value("authors").toArray();
- if (authors.size() == 0)
- m_authors = "";
- else if (authors.size() >= 1)
- {
- m_authors = authors.at(0).toString();
- for (int i = 1; i < authors.size(); i++)
- {
- m_authors += ", " + authors.at(i).toString();
- }
- }
- m_credits = firstObj.value("credits").toString();
- return;
- }
- ;
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
- // this is the very old format that had just the array
- if (jsonDoc.isArray())
- {
- getInfoFromArray(jsonDoc.array());
- }
- else if (jsonDoc.isObject())
- {
- auto val = jsonDoc.object().value("modinfoversion");
- if(val.isUndefined())
- val = jsonDoc.object().value("modListVersion");
- int version = val.toDouble();
- if (version != 2)
- {
- qCritical() << "BAD stuff happened to mod json:";
- qCritical() << contents;
- return;
- }
- auto arrVal = jsonDoc.object().value("modlist");
- if(arrVal.isUndefined())
- arrVal = jsonDoc.object().value("modList");
- if (arrVal.isArray())
- {
- getInfoFromArray(arrVal.toArray());
- }
- }
+ if (authors.size() == 0)
+ m_authors = "";
+ else if (authors.size() >= 1)
+ {
+ m_authors = authors.at(0).toString();
+ for (int i = 1; i < authors.size(); i++)
+ {
+ m_authors += ", " + authors.at(i).toString();
+ }
+ }
+ m_credits = firstObj.value("credits").toString();
+ return;
+ }
+ ;
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
+ // this is the very old format that had just the array
+ if (jsonDoc.isArray())
+ {
+ getInfoFromArray(jsonDoc.array());
+ }
+ else if (jsonDoc.isObject())
+ {
+ auto val = jsonDoc.object().value("modinfoversion");
+ if(val.isUndefined())
+ val = jsonDoc.object().value("modListVersion");
+ int version = val.toDouble();
+ if (version != 2)
+ {
+ qCritical() << "BAD stuff happened to mod json:";
+ qCritical() << contents;
+ return;
+ }
+ auto arrVal = jsonDoc.object().value("modlist");
+ if(arrVal.isUndefined())
+ arrVal = jsonDoc.object().value("modList");
+ if (arrVal.isArray())
+ {
+ getInfoFromArray(arrVal.toArray());
+ }
+ }
}
void Mod::ReadForgeInfo(QByteArray contents)
{
- // Read the data
- m_name = "Minecraft Forge";
- m_mod_id = "Forge";
- m_homeurl = "http://www.minecraftforge.net/forum/";
- INIFile ini;
- if (!ini.loadFile(contents))
- return;
+ // Read the data
+ m_name = "Minecraft Forge";
+ m_mod_id = "Forge";
+ m_homeurl = "http://www.minecraftforge.net/forum/";
+ INIFile ini;
+ if (!ini.loadFile(contents))
+ return;
- QString major = ini.get("forge.major.number", "0").toString();
- QString minor = ini.get("forge.minor.number", "0").toString();
- QString revision = ini.get("forge.revision.number", "0").toString();
- QString build = ini.get("forge.build.number", "0").toString();
+ QString major = ini.get("forge.major.number", "0").toString();
+ QString minor = ini.get("forge.minor.number", "0").toString();
+ QString revision = ini.get("forge.revision.number", "0").toString();
+ QString build = ini.get("forge.build.number", "0").toString();
- m_version = major + "." + minor + "." + revision + "." + build;
+ m_version = major + "." + minor + "." + revision + "." + build;
}
void Mod::ReadLiteModInfo(QByteArray contents)
{
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
- auto object = jsonDoc.object();
- if (object.contains("name"))
- {
- m_mod_id = m_name = object.value("name").toString();
- }
- if (object.contains("version"))
- {
- m_version = object.value("version").toString("");
- }
- else
- {
- m_version = object.value("revision").toString("");
- }
- m_mcversion = object.value("mcversion").toString();
- m_authors = object.value("author").toString();
- m_description = object.value("description").toString();
- m_homeurl = object.value("url").toString();
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
+ auto object = jsonDoc.object();
+ if (object.contains("name"))
+ {
+ m_mod_id = m_name = object.value("name").toString();
+ }
+ if (object.contains("version"))
+ {
+ m_version = object.value("version").toString("");
+ }
+ else
+ {
+ m_version = object.value("revision").toString("");
+ }
+ m_mcversion = object.value("mcversion").toString();
+ m_authors = object.value("author").toString();
+ m_description = object.value("description").toString();
+ m_homeurl = object.value("url").toString();
}
bool Mod::replace(Mod &with)
{
- if (!destroy())
- return false;
- bool success = false;
- auto t = with.type();
+ if (!destroy())
+ return false;
+ bool success = false;
+ auto t = with.type();
- if (t == MOD_ZIPFILE || t == MOD_SINGLEFILE || t == MOD_LITEMOD)
- {
- qDebug() << "Copy: " << with.m_file.filePath() << " to " << m_file.filePath();
- success = QFile::copy(with.m_file.filePath(), m_file.filePath());
- }
- if (t == MOD_FOLDER)
- {
- success = FS::copy(with.m_file.filePath(), m_file.path())();
- }
- if (success)
- {
- m_name = with.m_name;
- m_mmc_id = with.m_mmc_id;
- m_mod_id = with.m_mod_id;
- m_version = with.m_version;
- m_mcversion = with.m_mcversion;
- m_description = with.m_description;
- m_authors = with.m_authors;
- m_credits = with.m_credits;
- m_homeurl = with.m_homeurl;
- m_type = with.m_type;
- m_file.refresh();
- }
- return success;
+ if (t == MOD_ZIPFILE || t == MOD_SINGLEFILE || t == MOD_LITEMOD)
+ {
+ qDebug() << "Copy: " << with.m_file.filePath() << " to " << m_file.filePath();
+ success = QFile::copy(with.m_file.filePath(), m_file.filePath());
+ }
+ if (t == MOD_FOLDER)
+ {
+ success = FS::copy(with.m_file.filePath(), m_file.path())();
+ }
+ if (success)
+ {
+ m_name = with.m_name;
+ m_mmc_id = with.m_mmc_id;
+ m_mod_id = with.m_mod_id;
+ m_version = with.m_version;
+ m_mcversion = with.m_mcversion;
+ m_description = with.m_description;
+ m_authors = with.m_authors;
+ m_credits = with.m_credits;
+ m_homeurl = with.m_homeurl;
+ m_type = with.m_type;
+ m_file.refresh();
+ }
+ return success;
}
bool Mod::destroy()
{
- if (m_type == MOD_FOLDER)
- {
- QDir d(m_file.filePath());
- if (d.removeRecursively())
- {
- m_type = MOD_UNKNOWN;
- return true;
- }
- return false;
- }
- else if (m_type == MOD_SINGLEFILE || m_type == MOD_ZIPFILE || m_type == MOD_LITEMOD)
- {
- QFile f(m_file.filePath());
- if (f.remove())
- {
- m_type = MOD_UNKNOWN;
- return true;
- }
- return false;
- }
- return true;
+ if (m_type == MOD_FOLDER)
+ {
+ QDir d(m_file.filePath());
+ if (d.removeRecursively())
+ {
+ m_type = MOD_UNKNOWN;
+ return true;
+ }
+ return false;
+ }
+ else if (m_type == MOD_SINGLEFILE || m_type == MOD_ZIPFILE || m_type == MOD_LITEMOD)
+ {
+ QFile f(m_file.filePath());
+ if (f.remove())
+ {
+ m_type = MOD_UNKNOWN;
+ return true;
+ }
+ return false;
+ }
+ return true;
}
QString Mod::version() const
{
- switch (type())
- {
- case MOD_ZIPFILE:
- case MOD_LITEMOD:
- return m_version;
- case MOD_FOLDER:
- return "Folder";
- case MOD_SINGLEFILE:
- return "File";
- default:
- return "VOID";
- }
+ switch (type())
+ {
+ case MOD_ZIPFILE:
+ case MOD_LITEMOD:
+ return m_version;
+ case MOD_FOLDER:
+ return "Folder";
+ case MOD_SINGLEFILE:
+ return "File";
+ default:
+ return "VOID";
+ }
}
bool Mod::enable(bool value)
{
- if (m_type == Mod::MOD_UNKNOWN || m_type == Mod::MOD_FOLDER)
- return false;
+ if (m_type == Mod::MOD_UNKNOWN || m_type == Mod::MOD_FOLDER)
+ return false;
- if (m_enabled == value)
- return false;
+ if (m_enabled == value)
+ return false;
- QString path = m_file.absoluteFilePath();
- if (value)
- {
- QFile foo(path);
- if (!path.endsWith(".disabled"))
- return false;
- path.chop(9);
- if (!foo.rename(path))
- return false;
- }
- else
- {
- QFile foo(path);
- path += ".disabled";
- if (!foo.rename(path))
- return false;
- }
- m_file = QFileInfo(path);
- m_enabled = value;
- return true;
+ QString path = m_file.absoluteFilePath();
+ if (value)
+ {
+ QFile foo(path);
+ if (!path.endsWith(".disabled"))
+ return false;
+ path.chop(9);
+ if (!foo.rename(path))
+ return false;
+ }
+ else
+ {
+ QFile foo(path);
+ path += ".disabled";
+ if (!foo.rename(path))
+ return false;
+ }
+ m_file = QFileInfo(path);
+ m_enabled = value;
+ return true;
}
bool Mod::operator==(const Mod &other) const
{
- return mmc_id() == other.mmc_id();
+ return mmc_id() == other.mmc_id();
}
bool Mod::strongCompare(const Mod &other) const
{
- return mmc_id() == other.mmc_id() && version() == other.version() && type() == other.type();
+ return mmc_id() == other.mmc_id() && version() == other.version() && type() == other.type();
}
diff --git a/api/logic/minecraft/Mod.h b/api/logic/minecraft/Mod.h
index ccab1867..0c1adf24 100644
--- a/api/logic/minecraft/Mod.h
+++ b/api/logic/minecraft/Mod.h
@@ -20,123 +20,123 @@
class Mod
{
public:
- enum ModType
- {
- MOD_UNKNOWN, //!< Indicates an unspecified mod type.
- MOD_ZIPFILE, //!< The mod is a zip file containing the mod's class files.
- MOD_SINGLEFILE, //!< The mod is a single file (not a zip file).
- MOD_FOLDER, //!< The mod is in a folder on the filesystem.
- MOD_LITEMOD, //!< The mod is a litemod
- };
-
- Mod(const QFileInfo &file);
-
- QFileInfo filename() const
- {
- return m_file;
- }
- QString mmc_id() const
- {
- return m_mmc_id;
- }
- QString mod_id() const
- {
- return m_mod_id;
- }
- ModType type() const
- {
- return m_type;
- }
- QString mcversion() const
- {
- return m_mcversion;
- }
- ;
- bool valid()
- {
- return m_type != MOD_UNKNOWN;
- }
- QString name() const
- {
- QString name = m_name.trimmed();
- if(name.isEmpty() || name == "Example Mod")
- {
- return m_mmc_id;
- }
- return m_name;
- }
-
- QString version() const;
-
- QString homeurl() const
- {
- return m_homeurl;
- }
-
- QString description() const
- {
- return m_description;
- }
-
- QString authors() const
- {
- return m_authors;
- }
-
- QString credits() const
- {
- return m_credits;
- }
-
- QDateTime dateTimeChanged() const
- {
- return m_changedDateTime;
- }
-
- bool enabled() const
- {
- return m_enabled;
- }
-
- bool enable(bool value);
-
- // delete all the files of this mod
- bool destroy();
- // replace this mod with a copy of the other
- bool replace(Mod &with);
- // change the mod's filesystem path (used by mod lists for *MAGIC* purposes)
- void repath(const QFileInfo &file);
-
- // WEAK compare operator - used for replacing mods
- bool operator==(const Mod &other) const;
- bool strongCompare(const Mod &other) const;
+ enum ModType
+ {
+ MOD_UNKNOWN, //!< Indicates an unspecified mod type.
+ MOD_ZIPFILE, //!< The mod is a zip file containing the mod's class files.
+ MOD_SINGLEFILE, //!< The mod is a single file (not a zip file).
+ MOD_FOLDER, //!< The mod is in a folder on the filesystem.
+ MOD_LITEMOD, //!< The mod is a litemod
+ };
+
+ Mod(const QFileInfo &file);
+
+ QFileInfo filename() const
+ {
+ return m_file;
+ }
+ QString mmc_id() const
+ {
+ return m_mmc_id;
+ }
+ QString mod_id() const
+ {
+ return m_mod_id;
+ }
+ ModType type() const
+ {
+ return m_type;
+ }
+ QString mcversion() const
+ {
+ return m_mcversion;
+ }
+ ;
+ bool valid()
+ {
+ return m_type != MOD_UNKNOWN;
+ }
+ QString name() const
+ {
+ QString name = m_name.trimmed();
+ if(name.isEmpty() || name == "Example Mod")
+ {
+ return m_mmc_id;
+ }
+ return m_name;
+ }
+
+ QString version() const;
+
+ QString homeurl() const
+ {
+ return m_homeurl;
+ }
+
+ QString description() const
+ {
+ return m_description;
+ }
+
+ QString authors() const
+ {
+ return m_authors;
+ }
+
+ QString credits() const
+ {
+ return m_credits;
+ }
+
+ QDateTime dateTimeChanged() const
+ {
+ return m_changedDateTime;
+ }
+
+ bool enabled() const
+ {
+ return m_enabled;
+ }
+
+ bool enable(bool value);
+
+ // delete all the files of this mod
+ bool destroy();
+ // replace this mod with a copy of the other
+ bool replace(Mod &with);
+ // change the mod's filesystem path (used by mod lists for *MAGIC* purposes)
+ void repath(const QFileInfo &file);
+
+ // WEAK compare operator - used for replacing mods
+ bool operator==(const Mod &other) const;
+ bool strongCompare(const Mod &other) const;
private:
- void ReadMCModInfo(QByteArray contents);
- void ReadForgeInfo(QByteArray contents);
- void ReadLiteModInfo(QByteArray contents);
+ void ReadMCModInfo(QByteArray contents);
+ void ReadForgeInfo(QByteArray contents);
+ void ReadLiteModInfo(QByteArray contents);
protected:
- // FIXME: what do do with those? HMM...
- /*
- void ReadModInfoData(QString info);
- void ReadForgeInfoData(QString infoFileData);
- */
-
- QFileInfo m_file;
- QDateTime m_changedDateTime;
- QString m_mmc_id;
- QString m_mod_id;
- bool m_enabled = true;
- QString m_name;
- QString m_version;
- QString m_mcversion;
- QString m_homeurl;
- QString m_updateurl;
- QString m_description;
- QString m_authors;
- QString m_credits;
-
- ModType m_type;
+ // FIXME: what do do with those? HMM...
+ /*
+ void ReadModInfoData(QString info);
+ void ReadForgeInfoData(QString infoFileData);
+ */
+
+ QFileInfo m_file;
+ QDateTime m_changedDateTime;
+ QString m_mmc_id;
+ QString m_mod_id;
+ bool m_enabled = true;
+ QString m_name;
+ QString m_version;
+ QString m_mcversion;
+ QString m_homeurl;
+ QString m_updateurl;
+ QString m_description;
+ QString m_authors;
+ QString m_credits;
+
+ ModType m_type;
};
diff --git a/api/logic/minecraft/ModsModel.cpp b/api/logic/minecraft/ModsModel.cpp
index ff99ad4a..e401618a 100644
--- a/api/logic/minecraft/ModsModel.cpp
+++ b/api/logic/minecraft/ModsModel.cpp
@@ -25,350 +25,350 @@
ModsModel::ModsModel(const QString &mainDir, const QString &coreDir, const QString &cacheLocation)
:QAbstractListModel(), m_mainDir(mainDir), m_coreDir(coreDir)
{
- FS::ensureFolderPathExists(m_mainDir.absolutePath());
- m_mainDir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
+ FS::ensureFolderPathExists(m_mainDir.absolutePath());
+ m_mainDir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
QDir::NoSymLinks);
- m_mainDir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
- m_watcher = new QFileSystemWatcher(this);
- connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString)));
+ m_mainDir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
+ m_watcher = new QFileSystemWatcher(this);
+ connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString)));
}
void ModsModel::startWatching()
{
- if(is_watching)
- return;
-
- update();
-
- is_watching = m_watcher->addPath(m_mainDir.absolutePath());
- if (is_watching)
- {
- qDebug() << "Started watching " << m_mainDir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to start watching " << m_mainDir.absolutePath();
- }
+ if(is_watching)
+ return;
+
+ update();
+
+ is_watching = m_watcher->addPath(m_mainDir.absolutePath());
+ if (is_watching)
+ {
+ qDebug() << "Started watching " << m_mainDir.absolutePath();
+ }
+ else
+ {
+ qDebug() << "Failed to start watching " << m_mainDir.absolutePath();
+ }
}
void ModsModel::stopWatching()
{
- if(!is_watching)
- return;
-
- is_watching = !m_watcher->removePath(m_mainDir.absolutePath());
- if (!is_watching)
- {
- qDebug() << "Stopped watching " << m_mainDir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to stop watching " << m_mainDir.absolutePath();
- }
+ if(!is_watching)
+ return;
+
+ is_watching = !m_watcher->removePath(m_mainDir.absolutePath());
+ if (!is_watching)
+ {
+ qDebug() << "Stopped watching " << m_mainDir.absolutePath();
+ }
+ else
+ {
+ qDebug() << "Failed to stop watching " << m_mainDir.absolutePath();
+ }
}
bool ModsModel::update()
{
- if (!isValid())
- return false;
-
- QList<Mod> orderedMods;
- QList<Mod> newMods;
- m_mainDir.refresh();
- auto folderContents = m_mainDir.entryInfoList();
- bool orderOrStateChanged = false;
-
- // if there are any untracked files...
- if (folderContents.size())
- {
- // the order surely changed!
- for (auto entry : folderContents)
- {
- newMods.append(Mod(entry));
- }
- orderedMods.append(newMods);
- orderOrStateChanged = true;
- }
- // otherwise, if we were already tracking some mods
- else if (mods.size())
- {
- // if the number doesn't match, order changed.
- if (mods.size() != orderedMods.size())
- orderOrStateChanged = true;
- // if it does match, compare the mods themselves
- else
- for (int i = 0; i < mods.size(); i++)
- {
- if (!mods[i].strongCompare(orderedMods[i]))
- {
- orderOrStateChanged = true;
- break;
- }
- }
- }
- beginResetModel();
- mods.swap(orderedMods);
- endResetModel();
- if (orderOrStateChanged)
- {
- emit changed();
- }
- return true;
+ if (!isValid())
+ return false;
+
+ QList<Mod> orderedMods;
+ QList<Mod> newMods;
+ m_mainDir.refresh();
+ auto folderContents = m_mainDir.entryInfoList();
+ bool orderOrStateChanged = false;
+
+ // if there are any untracked files...
+ if (folderContents.size())
+ {
+ // the order surely changed!
+ for (auto entry : folderContents)
+ {
+ newMods.append(Mod(entry));
+ }
+ orderedMods.append(newMods);
+ orderOrStateChanged = true;
+ }
+ // otherwise, if we were already tracking some mods
+ else if (mods.size())
+ {
+ // if the number doesn't match, order changed.
+ if (mods.size() != orderedMods.size())
+ orderOrStateChanged = true;
+ // if it does match, compare the mods themselves
+ else
+ for (int i = 0; i < mods.size(); i++)
+ {
+ if (!mods[i].strongCompare(orderedMods[i]))
+ {
+ orderOrStateChanged = true;
+ break;
+ }
+ }
+ }
+ beginResetModel();
+ mods.swap(orderedMods);
+ endResetModel();
+ if (orderOrStateChanged)
+ {
+ emit changed();
+ }
+ return true;
}
void ModsModel::directoryChanged(QString path)
{
- update();
+ update();
}
bool ModsModel::isValid()
{
- return m_mainDir.exists() && m_mainDir.isReadable();
+ return m_mainDir.exists() && m_mainDir.isReadable();
}
bool ModsModel::installMod(const QString &filename)
{
- // NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName
- QFileInfo fileinfo(FS::NormalizePath(filename));
-
- qDebug() << "installing: " << fileinfo.absoluteFilePath();
-
- if (!fileinfo.exists() || !fileinfo.isReadable())
- {
- return false;
- }
- Mod m(fileinfo);
- if (!m.valid())
- return false;
-
- auto type = m.type();
- if (type == Mod::MOD_UNKNOWN)
- return false;
- if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD)
- {
- QString newpath = FS::PathCombine(m_mainDir.path(), fileinfo.fileName());
- if (!QFile::copy(fileinfo.filePath(), newpath))
- return false;
- FS::updateTimestamp(newpath);
- m.repath(newpath);
- update();
- return true;
- }
- else if (type == Mod::MOD_FOLDER)
- {
- QString from = fileinfo.filePath();
- QString to = FS::PathCombine(m_mainDir.path(), fileinfo.fileName());
- if (!FS::copy(from, to)())
- return false;
- m.repath(to);
- update();
- return true;
- }
- return false;
+ // NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName
+ QFileInfo fileinfo(FS::NormalizePath(filename));
+
+ qDebug() << "installing: " << fileinfo.absoluteFilePath();
+
+ if (!fileinfo.exists() || !fileinfo.isReadable())
+ {
+ return false;
+ }
+ Mod m(fileinfo);
+ if (!m.valid())
+ return false;
+
+ auto type = m.type();
+ if (type == Mod::MOD_UNKNOWN)
+ return false;
+ if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD)
+ {
+ QString newpath = FS::PathCombine(m_mainDir.path(), fileinfo.fileName());
+ if (!QFile::copy(fileinfo.filePath(), newpath))
+ return false;
+ FS::updateTimestamp(newpath);
+ m.repath(newpath);
+ update();
+ return true;
+ }
+ else if (type == Mod::MOD_FOLDER)
+ {
+ QString from = fileinfo.filePath();
+ QString to = FS::PathCombine(m_mainDir.path(), fileinfo.fileName());
+ if (!FS::copy(from, to)())
+ return false;
+ m.repath(to);
+ update();
+ return true;
+ }
+ return false;
}
bool ModsModel::enableMods(const QModelIndexList& indexes, bool enable)
{
- if(indexes.isEmpty())
- return true;
-
- for (auto i: indexes)
- {
- Mod &m = mods[i.row()];
- m.enable(enable);
- emit dataChanged(i, i);
- }
- emit changed();
- return true;
+ if(indexes.isEmpty())
+ return true;
+
+ for (auto i: indexes)
+ {
+ Mod &m = mods[i.row()];
+ m.enable(enable);
+ emit dataChanged(i, i);
+ }
+ emit changed();
+ return true;
}
bool ModsModel::deleteMods(const QModelIndexList& indexes)
{
- if(indexes.isEmpty())
- return true;
-
- for (auto i: indexes)
- {
- Mod &m = mods[i.row()];
- m.destroy();
- }
- emit changed();
- return true;
+ if(indexes.isEmpty())
+ return true;
+
+ for (auto i: indexes)
+ {
+ Mod &m = mods[i.row()];
+ m.destroy();
+ }
+ emit changed();
+ return true;
}
int ModsModel::columnCount(const QModelIndex &parent) const
{
- return NUM_COLUMNS;
+ return NUM_COLUMNS;
}
QVariant ModsModel::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= mods.size())
- return QVariant();
-
- switch (role)
- {
- case Qt::DisplayRole:
- switch (column)
- {
- case NameColumn:
- return mods[row].name();
- case VersionColumn:
- return mods[row].version();
- case DateColumn:
- return mods[row].dateTimeChanged();
+ if (!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+ int column = index.column();
+
+ if (row < 0 || row >= mods.size())
+ return QVariant();
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (column)
+ {
+ case NameColumn:
+ return mods[row].name();
+ case VersionColumn:
+ return mods[row].version();
+ case DateColumn:
+ return mods[row].dateTimeChanged();
case LocationColumn:
return "Unknown";
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return mods[row].mmc_id();
-
- case Qt::CheckStateRole:
- switch (column)
- {
- case ActiveColumn:
- return mods[row].enabled() ? Qt::Checked : Qt::Unchecked;
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
+ default:
+ return QVariant();
+ }
+
+ case Qt::ToolTipRole:
+ return mods[row].mmc_id();
+
+ case Qt::CheckStateRole:
+ switch (column)
+ {
+ case ActiveColumn:
+ return mods[row].enabled() ? Qt::Checked : Qt::Unchecked;
+ default:
+ return QVariant();
+ }
+ default:
+ return QVariant();
+ }
}
bool ModsModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return false;
- }
-
- if (role == Qt::CheckStateRole)
- {
- auto &mod = mods[index.row()];
- if (mod.enable(!mod.enabled()))
- {
- emit dataChanged(index, index);
- return true;
- }
- }
- return false;
+ if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
+ {
+ return false;
+ }
+
+ if (role == Qt::CheckStateRole)
+ {
+ auto &mod = mods[index.row()];
+ if (mod.enable(!mod.enabled()))
+ {
+ emit dataChanged(index, index);
+ return true;
+ }
+ }
+ return false;
}
QVariant ModsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case ActiveColumn:
- return QString();
- case NameColumn:
- return tr("Name");
- case VersionColumn:
- return tr("Version");
- case DateColumn:
- return tr("Last changed");
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (section)
+ {
+ case ActiveColumn:
+ return QString();
+ case NameColumn:
+ return tr("Name");
+ case VersionColumn:
+ return tr("Version");
+ case DateColumn:
+ return tr("Last changed");
case LocationColumn:
return tr("Location");
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case ActiveColumn:
- return tr("Is the mod enabled?");
- case NameColumn:
- return tr("The name of the mod.");
- case VersionColumn:
- return tr("The version of the mod.");
- case DateColumn:
- return tr("The date and time this mod was last changed (or added).");
+ default:
+ return QVariant();
+ }
+
+ case Qt::ToolTipRole:
+ switch (section)
+ {
+ case ActiveColumn:
+ return tr("Is the mod enabled?");
+ case NameColumn:
+ return tr("The name of the mod.");
+ case VersionColumn:
+ return tr("The version of the mod.");
+ case DateColumn:
+ return tr("The date and time this mod was last changed (or added).");
case LocationColumn:
return tr("Where the mod is located (inside or outside the instance).");
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
- return QVariant();
+ default:
+ return QVariant();
+ }
+ default:
+ return QVariant();
+ }
+ return QVariant();
}
Qt::ItemFlags ModsModel::flags(const QModelIndex &index) const
{
- Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
- if (index.isValid())
- return Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled |
- defaultFlags;
- else
- return Qt::ItemIsDropEnabled | defaultFlags;
+ Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
+ if (index.isValid())
+ return Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled |
+ defaultFlags;
+ else
+ return Qt::ItemIsDropEnabled | defaultFlags;
}
Qt::DropActions ModsModel::supportedDropActions() const
{
- // copy from outside, move from within and other mod lists
- return Qt::CopyAction | Qt::MoveAction;
+ // copy from outside, move from within and other mod lists
+ return Qt::CopyAction | Qt::MoveAction;
}
QStringList ModsModel::mimeTypes() const
{
- QStringList types;
- types << "text/uri-list";
- return types;
+ QStringList types;
+ types << "text/uri-list";
+ return types;
}
bool ModsModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int, int, const QModelIndex&)
{
- if (action == Qt::IgnoreAction)
- {
- return true;
- }
-
- // check if the action is supported
- if (!data || !(action & supportedDropActions()))
- {
- return false;
- }
-
- // files dropped from outside?
- if (data->hasUrls())
- {
- bool was_watching = is_watching;
- if (was_watching)
- {
- stopWatching();
- }
- auto urls = data->urls();
- for (auto url : urls)
- {
- // only local files may be dropped...
- if (!url.isLocalFile())
- {
- continue;
- }
- // TODO: implement not only copy, but also move
- // FIXME: handle errors here
- installMod(url.toLocalFile());
- }
- if (was_watching)
- {
- startWatching();
- }
- return true;
- }
- return false;
+ if (action == Qt::IgnoreAction)
+ {
+ return true;
+ }
+
+ // check if the action is supported
+ if (!data || !(action & supportedDropActions()))
+ {
+ return false;
+ }
+
+ // files dropped from outside?
+ if (data->hasUrls())
+ {
+ bool was_watching = is_watching;
+ if (was_watching)
+ {
+ stopWatching();
+ }
+ auto urls = data->urls();
+ for (auto url : urls)
+ {
+ // only local files may be dropped...
+ if (!url.isLocalFile())
+ {
+ continue;
+ }
+ // TODO: implement not only copy, but also move
+ // FIXME: handle errors here
+ installMod(url.toLocalFile());
+ }
+ if (was_watching)
+ {
+ startWatching();
+ }
+ return true;
+ }
+ return false;
}
diff --git a/api/logic/minecraft/ModsModel.h b/api/logic/minecraft/ModsModel.h
index 3c8f66fd..b8980ac4 100644
--- a/api/logic/minecraft/ModsModel.h
+++ b/api/logic/minecraft/ModsModel.h
@@ -34,90 +34,90 @@ class QFileSystemWatcher;
*/
class MULTIMC_LOGIC_EXPORT ModsModel : public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum Columns
- {
- ActiveColumn = 0,
- NameColumn,
- DateColumn,
- VersionColumn,
+ enum Columns
+ {
+ ActiveColumn = 0,
+ NameColumn,
+ DateColumn,
+ VersionColumn,
LocationColumn,
- NUM_COLUMNS
- };
- ModsModel(const QString &mainDir, const QString &coreDir, const QString &cacheFile);
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
- Qt::DropActions supportedDropActions() const override;
-
- /// flags, mostly to support drag&drop
- virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
- QStringList mimeTypes() const override;
- bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) override;
-
- virtual int rowCount(const QModelIndex &) const override
- {
- return size();
- }
- ;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
- virtual int columnCount(const QModelIndex &parent) const override;
-
- size_t size() const
- {
- return mods.size();
- }
- ;
- bool empty() const
- {
- return size() == 0;
- }
- Mod &operator[](size_t index)
- {
- return mods[index];
- }
-
- /// Reloads the mod list and returns true if the list changed.
- virtual bool update();
-
- /**
- * Adds the given mod to the list at the given index - if the list supports custom ordering
- */
- bool installMod(const QString& filename);
-
- /// Deletes all the selected mods
- virtual bool deleteMods(const QModelIndexList &indexes);
-
- /// Enable or disable listed mods
- virtual bool enableMods(const QModelIndexList &indexes, bool enable = true);
-
- void startWatching();
- void stopWatching();
-
- virtual bool isValid();
-
- QDir dir()
- {
- return m_mainDir;
- }
-
- const QList<Mod> & allMods()
- {
- return mods;
- }
+ NUM_COLUMNS
+ };
+ ModsModel(const QString &mainDir, const QString &coreDir, const QString &cacheFile);
+
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+ Qt::DropActions supportedDropActions() const override;
+
+ /// flags, mostly to support drag&drop
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
+ QStringList mimeTypes() const override;
+ bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) override;
+
+ virtual int rowCount(const QModelIndex &) const override
+ {
+ return size();
+ }
+ ;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+ virtual int columnCount(const QModelIndex &parent) const override;
+
+ size_t size() const
+ {
+ return mods.size();
+ }
+ ;
+ bool empty() const
+ {
+ return size() == 0;
+ }
+ Mod &operator[](size_t index)
+ {
+ return mods[index];
+ }
+
+ /// Reloads the mod list and returns true if the list changed.
+ virtual bool update();
+
+ /**
+ * Adds the given mod to the list at the given index - if the list supports custom ordering
+ */
+ bool installMod(const QString& filename);
+
+ /// Deletes all the selected mods
+ virtual bool deleteMods(const QModelIndexList &indexes);
+
+ /// Enable or disable listed mods
+ virtual bool enableMods(const QModelIndexList &indexes, bool enable = true);
+
+ void startWatching();
+ void stopWatching();
+
+ virtual bool isValid();
+
+ QDir dir()
+ {
+ return m_mainDir;
+ }
+
+ const QList<Mod> & allMods()
+ {
+ return mods;
+ }
private
slots:
- void directoryChanged(QString path);
+ void directoryChanged(QString path);
signals:
- void changed();
+ void changed();
protected:
- QFileSystemWatcher *m_watcher;
- bool is_watching = false;
- QDir m_mainDir;
+ QFileSystemWatcher *m_watcher;
+ bool is_watching = false;
+ QDir m_mainDir;
QDir m_coreDir;
- QList<Mod> mods;
+ QList<Mod> mods;
};
diff --git a/api/logic/minecraft/MojangDownloadInfo.h b/api/logic/minecraft/MojangDownloadInfo.h
index 7399a56b..88f87287 100644
--- a/api/logic/minecraft/MojangDownloadInfo.h
+++ b/api/logic/minecraft/MojangDownloadInfo.h
@@ -5,78 +5,78 @@
struct MojangDownloadInfo
{
- // types
- typedef std::shared_ptr<MojangDownloadInfo> Ptr;
+ // types
+ typedef std::shared_ptr<MojangDownloadInfo> Ptr;
- // data
- /// Local filesystem path. WARNING: not used, only here so we can pass through mojang files unmolested!
- QString path;
- /// absolute URL of this file
- QString url;
- /// sha-1 checksum of the file
- QString sha1;
- /// size of the file in bytes
- int size;
+ // data
+ /// Local filesystem path. WARNING: not used, only here so we can pass through mojang files unmolested!
+ QString path;
+ /// absolute URL of this file
+ QString url;
+ /// sha-1 checksum of the file
+ QString sha1;
+ /// size of the file in bytes
+ int size;
};
struct MojangLibraryDownloadInfo
{
- MojangLibraryDownloadInfo(MojangDownloadInfo::Ptr artifact): artifact(artifact) {};
- MojangLibraryDownloadInfo() {};
+ MojangLibraryDownloadInfo(MojangDownloadInfo::Ptr artifact): artifact(artifact) {};
+ MojangLibraryDownloadInfo() {};
- // types
- typedef std::shared_ptr<MojangLibraryDownloadInfo> Ptr;
+ // types
+ typedef std::shared_ptr<MojangLibraryDownloadInfo> Ptr;
- // methods
- MojangDownloadInfo *getDownloadInfo(QString classifier)
- {
- if (classifier.isNull())
- {
- return artifact.get();
- }
-
- return classifiers[classifier].get();
- }
+ // methods
+ MojangDownloadInfo *getDownloadInfo(QString classifier)
+ {
+ if (classifier.isNull())
+ {
+ return artifact.get();
+ }
+
+ return classifiers[classifier].get();
+ }
- // data
- MojangDownloadInfo::Ptr artifact;
- QMap<QString, MojangDownloadInfo::Ptr> classifiers;
+ // data
+ MojangDownloadInfo::Ptr artifact;
+ QMap<QString, MojangDownloadInfo::Ptr> classifiers;
};
struct MojangAssetIndexInfo : public MojangDownloadInfo
{
- // types
- typedef std::shared_ptr<MojangAssetIndexInfo> Ptr;
+ // types
+ typedef std::shared_ptr<MojangAssetIndexInfo> Ptr;
- // methods
- MojangAssetIndexInfo()
- {
- }
+ // methods
+ MojangAssetIndexInfo()
+ {
+ }
- MojangAssetIndexInfo(QString id)
- {
- this->id = id;
- // HACK: ignore assets from other version files than Minecraft
- // workaround for stupid assets issue caused by amazon:
- // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
- if(id == "legacy")
- {
- url = "https://launchermeta.mojang.com/mc/assets/legacy/c0fd82e8ce9fbc93119e40d96d5a4e62cfa3f729/legacy.json";
- }
- // HACK
- else
- {
- url = "https://s3.amazonaws.com/Minecraft.Download/indexes/" + id + ".json";
- }
- known = false;
- }
+ MojangAssetIndexInfo(QString id)
+ {
+ this->id = id;
+ // HACK: ignore assets from other version files than Minecraft
+ // workaround for stupid assets issue caused by amazon:
+ // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
+ if(id == "legacy")
+ {
+ url = "https://launchermeta.mojang.com/mc/assets/legacy/c0fd82e8ce9fbc93119e40d96d5a4e62cfa3f729/legacy.json";
+ }
+ // HACK
+ else
+ {
+ url = "https://s3.amazonaws.com/Minecraft.Download/indexes/" + id + ".json";
+ }
+ known = false;
+ }
- // data
- int totalSize;
- QString id;
- bool known = true;
+ // data
+ int totalSize;
+ QString id;
+ bool known = true;
};
diff --git a/api/logic/minecraft/MojangVersionFormat.cpp b/api/logic/minecraft/MojangVersionFormat.cpp
index a0aa2894..33d3c54c 100644
--- a/api/logic/minecraft/MojangVersionFormat.cpp
+++ b/api/logic/minecraft/MojangVersionFormat.cpp
@@ -19,361 +19,361 @@ namespace Bits
{
static void readString(const QJsonObject &root, const QString &key, QString &variable)
{
- if (root.contains(key))
- {
- variable = requireString(root.value(key));
- }
+ if (root.contains(key))
+ {
+ variable = requireString(root.value(key));
+ }
}
static void readDownloadInfo(MojangDownloadInfo::Ptr out, const QJsonObject &obj)
{
- // optional, not used
- readString(obj, "path", out->path);
- // required!
- out->sha1 = requireString(obj, "sha1");
- out->url = requireString(obj, "url");
- out->size = requireInteger(obj, "size");
+ // optional, not used
+ readString(obj, "path", out->path);
+ // required!
+ out->sha1 = requireString(obj, "sha1");
+ out->url = requireString(obj, "url");
+ out->size = requireInteger(obj, "size");
}
static void readAssetIndex(MojangAssetIndexInfo::Ptr out, const QJsonObject &obj)
{
- out->totalSize = requireInteger(obj, "totalSize");
- out->id = requireString(obj, "id");
- // out->known = true;
+ out->totalSize = requireInteger(obj, "totalSize");
+ out->id = requireString(obj, "id");
+ // out->known = true;
}
}
MojangDownloadInfo::Ptr downloadInfoFromJson(const QJsonObject &obj)
{
- auto out = std::make_shared<MojangDownloadInfo>();
- Bits::readDownloadInfo(out, obj);
- return out;
+ auto out = std::make_shared<MojangDownloadInfo>();
+ Bits::readDownloadInfo(out, obj);
+ return out;
}
MojangAssetIndexInfo::Ptr assetIndexFromJson(const QJsonObject &obj)
{
- auto out = std::make_shared<MojangAssetIndexInfo>();
- Bits::readDownloadInfo(out, obj);
- Bits::readAssetIndex(out, obj);
- return out;
+ auto out = std::make_shared<MojangAssetIndexInfo>();
+ Bits::readDownloadInfo(out, obj);
+ Bits::readAssetIndex(out, obj);
+ return out;
}
QJsonObject downloadInfoToJson(MojangDownloadInfo::Ptr info)
{
- QJsonObject out;
- if(!info->path.isNull())
- {
- out.insert("path", info->path);
- }
- out.insert("sha1", info->sha1);
- out.insert("size", info->size);
- out.insert("url", info->url);
- return out;
+ QJsonObject out;
+ if(!info->path.isNull())
+ {
+ out.insert("path", info->path);
+ }
+ out.insert("sha1", info->sha1);
+ out.insert("size", info->size);
+ out.insert("url", info->url);
+ return out;
}
MojangLibraryDownloadInfo::Ptr libDownloadInfoFromJson(const QJsonObject &libObj)
{
- auto out = std::make_shared<MojangLibraryDownloadInfo>();
- auto dlObj = requireObject(libObj.value("downloads"));
- if(dlObj.contains("artifact"))
- {
- out->artifact = downloadInfoFromJson(requireObject(dlObj, "artifact"));
- }
- if(dlObj.contains("classifiers"))
- {
- auto classifiersObj = requireObject(dlObj, "classifiers");
- for(auto iter = classifiersObj.begin(); iter != classifiersObj.end(); iter++)
- {
- auto classifier = iter.key();
- auto classifierObj = requireObject(iter.value());
- out->classifiers[classifier] = downloadInfoFromJson(classifierObj);
- }
- }
- return out;
+ auto out = std::make_shared<MojangLibraryDownloadInfo>();
+ auto dlObj = requireObject(libObj.value("downloads"));
+ if(dlObj.contains("artifact"))
+ {
+ out->artifact = downloadInfoFromJson(requireObject(dlObj, "artifact"));
+ }
+ if(dlObj.contains("classifiers"))
+ {
+ auto classifiersObj = requireObject(dlObj, "classifiers");
+ for(auto iter = classifiersObj.begin(); iter != classifiersObj.end(); iter++)
+ {
+ auto classifier = iter.key();
+ auto classifierObj = requireObject(iter.value());
+ out->classifiers[classifier] = downloadInfoFromJson(classifierObj);
+ }
+ }
+ return out;
}
QJsonObject libDownloadInfoToJson(MojangLibraryDownloadInfo::Ptr libinfo)
{
- QJsonObject out;
- if(libinfo->artifact)
- {
- out.insert("artifact", downloadInfoToJson(libinfo->artifact));
- }
- if(libinfo->classifiers.size())
- {
- QJsonObject classifiersOut;
- for(auto iter = libinfo->classifiers.begin(); iter != libinfo->classifiers.end(); iter++)
- {
- classifiersOut.insert(iter.key(), downloadInfoToJson(iter.value()));
- }
- out.insert("classifiers", classifiersOut);
- }
- return out;
+ QJsonObject out;
+ if(libinfo->artifact)
+ {
+ out.insert("artifact", downloadInfoToJson(libinfo->artifact));
+ }
+ if(libinfo->classifiers.size())
+ {
+ QJsonObject classifiersOut;
+ for(auto iter = libinfo->classifiers.begin(); iter != libinfo->classifiers.end(); iter++)
+ {
+ classifiersOut.insert(iter.key(), downloadInfoToJson(iter.value()));
+ }
+ out.insert("classifiers", classifiersOut);
+ }
+ return out;
}
QJsonObject assetIndexToJson(MojangAssetIndexInfo::Ptr info)
{
- QJsonObject out;
- if(!info->path.isNull())
- {
- out.insert("path", info->path);
- }
- out.insert("sha1", info->sha1);
- out.insert("size", info->size);
- out.insert("url", info->url);
- out.insert("totalSize", info->totalSize);
- out.insert("id", info->id);
- return out;
+ QJsonObject out;
+ if(!info->path.isNull())
+ {
+ out.insert("path", info->path);
+ }
+ out.insert("sha1", info->sha1);
+ out.insert("size", info->size);
+ out.insert("url", info->url);
+ out.insert("totalSize", info->totalSize);
+ out.insert("id", info->id);
+ return out;
}
void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFile *out)
{
- Bits::readString(in, "id", out->minecraftVersion);
- Bits::readString(in, "mainClass", out->mainClass);
- Bits::readString(in, "minecraftArguments", out->minecraftArguments);
- if(out->minecraftArguments.isEmpty())
- {
- QString processArguments;
- Bits::readString(in, "processArguments", processArguments);
- QString toCompare = processArguments.toLower();
- if (toCompare == "legacy")
- {
- out->minecraftArguments = " ${auth_player_name} ${auth_session}";
- }
- else if (toCompare == "username_session")
- {
- out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session}";
- }
- else if (toCompare == "username_session_version")
- {
- out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session} --version ${profile_name}";
- }
- else if (!toCompare.isEmpty())
- {
- out->addProblem(ProblemSeverity::Error, QObject::tr("processArguments is set to unknown value '%1'").arg(processArguments));
- }
- }
- Bits::readString(in, "type", out->type);
+ Bits::readString(in, "id", out->minecraftVersion);
+ Bits::readString(in, "mainClass", out->mainClass);
+ Bits::readString(in, "minecraftArguments", out->minecraftArguments);
+ if(out->minecraftArguments.isEmpty())
+ {
+ QString processArguments;
+ Bits::readString(in, "processArguments", processArguments);
+ QString toCompare = processArguments.toLower();
+ if (toCompare == "legacy")
+ {
+ out->minecraftArguments = " ${auth_player_name} ${auth_session}";
+ }
+ else if (toCompare == "username_session")
+ {
+ out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session}";
+ }
+ else if (toCompare == "username_session_version")
+ {
+ out->minecraftArguments = "--username ${auth_player_name} --session ${auth_session} --version ${profile_name}";
+ }
+ else if (!toCompare.isEmpty())
+ {
+ out->addProblem(ProblemSeverity::Error, QObject::tr("processArguments is set to unknown value '%1'").arg(processArguments));
+ }
+ }
+ Bits::readString(in, "type", out->type);
- Bits::readString(in, "assets", out->assets);
- if(in.contains("assetIndex"))
- {
- out->mojangAssetIndex = assetIndexFromJson(requireObject(in, "assetIndex"));
- }
- else if (!out->assets.isNull())
- {
- out->mojangAssetIndex = std::make_shared<MojangAssetIndexInfo>(out->assets);
- }
+ Bits::readString(in, "assets", out->assets);
+ if(in.contains("assetIndex"))
+ {
+ out->mojangAssetIndex = assetIndexFromJson(requireObject(in, "assetIndex"));
+ }
+ else if (!out->assets.isNull())
+ {
+ out->mojangAssetIndex = std::make_shared<MojangAssetIndexInfo>(out->assets);
+ }
- out->releaseTime = timeFromS3Time(in.value("releaseTime").toString(""));
- out->updateTime = timeFromS3Time(in.value("time").toString(""));
+ out->releaseTime = timeFromS3Time(in.value("releaseTime").toString(""));
+ out->updateTime = timeFromS3Time(in.value("time").toString(""));
- if (in.contains("minimumLauncherVersion"))
- {
- out->minimumLauncherVersion = requireInteger(in.value("minimumLauncherVersion"));
- if (out->minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION)
- {
- out->addProblem(
- ProblemSeverity::Warning,
- QObject::tr("The 'minimumLauncherVersion' value of this version (%1) is higher than supported by MultiMC (%2). It might not work properly!")
- .arg(out->minimumLauncherVersion)
- .arg(CURRENT_MINIMUM_LAUNCHER_VERSION));
- }
- }
- if(in.contains("downloads"))
- {
- auto downloadsObj = requireObject(in, "downloads");
- for(auto iter = downloadsObj.begin(); iter != downloadsObj.end(); iter++)
- {
- auto classifier = iter.key();
- auto classifierObj = requireObject(iter.value());
- out->mojangDownloads[classifier] = downloadInfoFromJson(classifierObj);
- }
- }
+ if (in.contains("minimumLauncherVersion"))
+ {
+ out->minimumLauncherVersion = requireInteger(in.value("minimumLauncherVersion"));
+ if (out->minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION)
+ {
+ out->addProblem(
+ ProblemSeverity::Warning,
+ QObject::tr("The 'minimumLauncherVersion' value of this version (%1) is higher than supported by MultiMC (%2). It might not work properly!")
+ .arg(out->minimumLauncherVersion)
+ .arg(CURRENT_MINIMUM_LAUNCHER_VERSION));
+ }
+ }
+ if(in.contains("downloads"))
+ {
+ auto downloadsObj = requireObject(in, "downloads");
+ for(auto iter = downloadsObj.begin(); iter != downloadsObj.end(); iter++)
+ {
+ auto classifier = iter.key();
+ auto classifierObj = requireObject(iter.value());
+ out->mojangDownloads[classifier] = downloadInfoFromJson(classifierObj);
+ }
+ }
}
VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename)
{
- VersionFilePtr out(new VersionFile());
- if (doc.isEmpty() || doc.isNull())
- {
- throw JSONValidationError(filename + " is empty or null");
- }
- if (!doc.isObject())
- {
- throw JSONValidationError(filename + " is not an object");
- }
+ VersionFilePtr out(new VersionFile());
+ if (doc.isEmpty() || doc.isNull())
+ {
+ throw JSONValidationError(filename + " is empty or null");
+ }
+ if (!doc.isObject())
+ {
+ throw JSONValidationError(filename + " is not an object");
+ }
- QJsonObject root = doc.object();
+ QJsonObject root = doc.object();
- readVersionProperties(root, out.get());
+ readVersionProperties(root, out.get());
- out->name = "Minecraft";
- out->uid = "net.minecraft";
- out->version = out->minecraftVersion;
- // out->filename = filename;
+ out->name = "Minecraft";
+ out->uid = "net.minecraft";
+ out->version = out->minecraftVersion;
+ // out->filename = filename;
- if (root.contains("libraries"))
- {
- for (auto libVal : requireArray(root.value("libraries")))
- {
- auto libObj = requireObject(libVal);
+ if (root.contains("libraries"))
+ {
+ for (auto libVal : requireArray(root.value("libraries")))
+ {
+ auto libObj = requireObject(libVal);
- auto lib = MojangVersionFormat::libraryFromJson(libObj, filename);
- out->libraries.append(lib);
- }
- }
- return out;
+ auto lib = MojangVersionFormat::libraryFromJson(libObj, filename);
+ out->libraries.append(lib);
+ }
+ }
+ return out;
}
void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObject& out)
{
- writeString(out, "id", in->minecraftVersion);
- writeString(out, "mainClass", in->mainClass);
- writeString(out, "minecraftArguments", in->minecraftArguments);
- writeString(out, "type", in->type);
- if(!in->releaseTime.isNull())
- {
- writeString(out, "releaseTime", timeToS3Time(in->releaseTime));
- }
- if(!in->updateTime.isNull())
- {
- writeString(out, "time", timeToS3Time(in->updateTime));
- }
- if(in->minimumLauncherVersion != -1)
- {
- out.insert("minimumLauncherVersion", in->minimumLauncherVersion);
- }
- writeString(out, "assets", in->assets);
- if(in->mojangAssetIndex && in->mojangAssetIndex->known)
- {
- out.insert("assetIndex", assetIndexToJson(in->mojangAssetIndex));
- }
- if(in->mojangDownloads.size())
- {
- QJsonObject downloadsOut;
- for(auto iter = in->mojangDownloads.begin(); iter != in->mojangDownloads.end(); iter++)
- {
- downloadsOut.insert(iter.key(), downloadInfoToJson(iter.value()));
- }
- out.insert("downloads", downloadsOut);
- }
+ writeString(out, "id", in->minecraftVersion);
+ writeString(out, "mainClass", in->mainClass);
+ writeString(out, "minecraftArguments", in->minecraftArguments);
+ writeString(out, "type", in->type);
+ if(!in->releaseTime.isNull())
+ {
+ writeString(out, "releaseTime", timeToS3Time(in->releaseTime));
+ }
+ if(!in->updateTime.isNull())
+ {
+ writeString(out, "time", timeToS3Time(in->updateTime));
+ }
+ if(in->minimumLauncherVersion != -1)
+ {
+ out.insert("minimumLauncherVersion", in->minimumLauncherVersion);
+ }
+ writeString(out, "assets", in->assets);
+ if(in->mojangAssetIndex && in->mojangAssetIndex->known)
+ {
+ out.insert("assetIndex", assetIndexToJson(in->mojangAssetIndex));
+ }
+ if(in->mojangDownloads.size())
+ {
+ QJsonObject downloadsOut;
+ for(auto iter = in->mojangDownloads.begin(); iter != in->mojangDownloads.end(); iter++)
+ {
+ downloadsOut.insert(iter.key(), downloadInfoToJson(iter.value()));
+ }
+ out.insert("downloads", downloadsOut);
+ }
}
QJsonDocument MojangVersionFormat::versionFileToJson(const VersionFilePtr &patch)
{
- QJsonObject root;
- writeVersionProperties(patch.get(), root);
- if (!patch->libraries.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->libraries)
- {
- array.append(MojangVersionFormat::libraryToJson(value.get()));
- }
- root.insert("libraries", array);
- }
+ QJsonObject root;
+ writeVersionProperties(patch.get(), root);
+ if (!patch->libraries.isEmpty())
+ {
+ QJsonArray array;
+ for (auto value: patch->libraries)
+ {
+ array.append(MojangVersionFormat::libraryToJson(value.get()));
+ }
+ root.insert("libraries", array);
+ }
- // write the contents to a json document.
- {
- QJsonDocument out;
- out.setObject(root);
- return out;
- }
+ // write the contents to a json document.
+ {
+ QJsonDocument out;
+ out.setObject(root);
+ return out;
+ }
}
LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename)
{
- LibraryPtr out(new Library());
- if (!libObj.contains("name"))
- {
- throw JSONValidationError(filename + "contains a library that doesn't have a 'name' field");
- }
- out->m_name = libObj.value("name").toString();
+ LibraryPtr out(new Library());
+ if (!libObj.contains("name"))
+ {
+ throw JSONValidationError(filename + "contains a library that doesn't have a 'name' field");
+ }
+ out->m_name = libObj.value("name").toString();
- Bits::readString(libObj, "url", out->m_repositoryURL);
- if (libObj.contains("extract"))
- {
- out->m_hasExcludes = true;
- auto extractObj = requireObject(libObj.value("extract"));
- for (auto excludeVal : requireArray(extractObj.value("exclude")))
- {
- out->m_extractExcludes.append(requireString(excludeVal));
- }
- }
- if (libObj.contains("natives"))
- {
- QJsonObject nativesObj = requireObject(libObj.value("natives"));
- for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it)
- {
- if (!it.value().isString())
- {
- qWarning() << filename << "contains an invalid native (skipping)";
- }
- OpSys opSys = OpSys_fromString(it.key());
- if (opSys != Os_Other)
- {
- out->m_nativeClassifiers[opSys] = it.value().toString();
- }
- }
- }
- if (libObj.contains("rules"))
- {
- out->applyRules = true;
- out->m_rules = rulesFromJsonV4(libObj);
- }
- if (libObj.contains("downloads"))
- {
- out->m_mojangDownloads = libDownloadInfoFromJson(libObj);
- }
- return out;
+ Bits::readString(libObj, "url", out->m_repositoryURL);
+ if (libObj.contains("extract"))
+ {
+ out->m_hasExcludes = true;
+ auto extractObj = requireObject(libObj.value("extract"));
+ for (auto excludeVal : requireArray(extractObj.value("exclude")))
+ {
+ out->m_extractExcludes.append(requireString(excludeVal));
+ }
+ }
+ if (libObj.contains("natives"))
+ {
+ QJsonObject nativesObj = requireObject(libObj.value("natives"));
+ for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it)
+ {
+ if (!it.value().isString())
+ {
+ qWarning() << filename << "contains an invalid native (skipping)";
+ }
+ OpSys opSys = OpSys_fromString(it.key());
+ if (opSys != Os_Other)
+ {
+ out->m_nativeClassifiers[opSys] = it.value().toString();
+ }
+ }
+ }
+ if (libObj.contains("rules"))
+ {
+ out->applyRules = true;
+ out->m_rules = rulesFromJsonV4(libObj);
+ }
+ if (libObj.contains("downloads"))
+ {
+ out->m_mojangDownloads = libDownloadInfoFromJson(libObj);
+ }
+ return out;
}
QJsonObject MojangVersionFormat::libraryToJson(Library *library)
{
- QJsonObject libRoot;
- libRoot.insert("name", (QString)library->m_name);
- if (!library->m_repositoryURL.isEmpty())
- {
- libRoot.insert("url", library->m_repositoryURL);
- }
- if (library->isNative())
- {
- QJsonObject nativeList;
- auto iter = library->m_nativeClassifiers.begin();
- while (iter != library->m_nativeClassifiers.end())
- {
- nativeList.insert(OpSys_toString(iter.key()), iter.value());
- iter++;
- }
- libRoot.insert("natives", nativeList);
- if (library->m_extractExcludes.size())
- {
- QJsonArray excludes;
- QJsonObject extract;
- for (auto exclude : library->m_extractExcludes)
- {
- excludes.append(exclude);
- }
- extract.insert("exclude", excludes);
- libRoot.insert("extract", extract);
- }
- }
- if (library->m_rules.size())
- {
- QJsonArray allRules;
- for (auto &rule : library->m_rules)
- {
- QJsonObject ruleObj = rule->toJson();
- allRules.append(ruleObj);
- }
- libRoot.insert("rules", allRules);
- }
- if(library->m_mojangDownloads)
- {
- auto downloadsObj = libDownloadInfoToJson(library->m_mojangDownloads);
- libRoot.insert("downloads", downloadsObj);
- }
- return libRoot;
+ QJsonObject libRoot;
+ libRoot.insert("name", (QString)library->m_name);
+ if (!library->m_repositoryURL.isEmpty())
+ {
+ libRoot.insert("url", library->m_repositoryURL);
+ }
+ if (library->isNative())
+ {
+ QJsonObject nativeList;
+ auto iter = library->m_nativeClassifiers.begin();
+ while (iter != library->m_nativeClassifiers.end())
+ {
+ nativeList.insert(OpSys_toString(iter.key()), iter.value());
+ iter++;
+ }
+ libRoot.insert("natives", nativeList);
+ if (library->m_extractExcludes.size())
+ {
+ QJsonArray excludes;
+ QJsonObject extract;
+ for (auto exclude : library->m_extractExcludes)
+ {
+ excludes.append(exclude);
+ }
+ extract.insert("exclude", excludes);
+ libRoot.insert("extract", extract);
+ }
+ }
+ if (library->m_rules.size())
+ {
+ QJsonArray allRules;
+ for (auto &rule : library->m_rules)
+ {
+ QJsonObject ruleObj = rule->toJson();
+ allRules.append(ruleObj);
+ }
+ libRoot.insert("rules", allRules);
+ }
+ if(library->m_mojangDownloads)
+ {
+ auto downloadsObj = libDownloadInfoToJson(library->m_mojangDownloads);
+ libRoot.insert("downloads", downloadsObj);
+ }
+ return libRoot;
}
diff --git a/api/logic/minecraft/MojangVersionFormat.h b/api/logic/minecraft/MojangVersionFormat.h
index 4e141088..76c529e9 100644
--- a/api/logic/minecraft/MojangVersionFormat.h
+++ b/api/logic/minecraft/MojangVersionFormat.h
@@ -10,16 +10,16 @@ class MULTIMC_LOGIC_EXPORT MojangVersionFormat
{
friend class OneSixVersionFormat;
protected:
- // does not include libraries
- static void readVersionProperties(const QJsonObject& in, VersionFile* out);
- // does not include libraries
- static void writeVersionProperties(const VersionFile* in, QJsonObject& out);
+ // does not include libraries
+ static void readVersionProperties(const QJsonObject& in, VersionFile* out);
+ // does not include libraries
+ static void writeVersionProperties(const VersionFile* in, QJsonObject& out);
public:
- // version files / profile patches
- static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename);
- static QJsonDocument versionFileToJson(const VersionFilePtr &patch);
+ // version files / profile patches
+ static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename);
+ static QJsonDocument versionFileToJson(const VersionFilePtr &patch);
- // libraries
- static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename);
- static QJsonObject libraryToJson(Library *library);
+ // libraries
+ static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename);
+ static QJsonObject libraryToJson(Library *library);
};
diff --git a/api/logic/minecraft/MojangVersionFormat_test.cpp b/api/logic/minecraft/MojangVersionFormat_test.cpp
index 9c8482ce..9d095340 100644
--- a/api/logic/minecraft/MojangVersionFormat_test.cpp
+++ b/api/logic/minecraft/MojangVersionFormat_test.cpp
@@ -6,47 +6,47 @@
class MojangVersionFormatTest : public QObject
{
- Q_OBJECT
-
- static QJsonDocument readJson(const char *file)
- {
- auto path = QFINDTESTDATA(file);
- QFile jsonFile(path);
- jsonFile.open(QIODevice::ReadOnly);
- auto data = jsonFile.readAll();
- jsonFile.close();
- return QJsonDocument::fromJson(data);
- }
- static void writeJson(const char *file, QJsonDocument doc)
- {
- QFile jsonFile(file);
- jsonFile.open(QIODevice::WriteOnly | QIODevice::Text);
- auto data = doc.toJson(QJsonDocument::Indented);
- qDebug() << QString::fromUtf8(data);
- jsonFile.write(data);
- jsonFile.close();
- }
+ Q_OBJECT
+
+ static QJsonDocument readJson(const char *file)
+ {
+ auto path = QFINDTESTDATA(file);
+ QFile jsonFile(path);
+ jsonFile.open(QIODevice::ReadOnly);
+ auto data = jsonFile.readAll();
+ jsonFile.close();
+ return QJsonDocument::fromJson(data);
+ }
+ static void writeJson(const char *file, QJsonDocument doc)
+ {
+ QFile jsonFile(file);
+ jsonFile.open(QIODevice::WriteOnly | QIODevice::Text);
+ auto data = doc.toJson(QJsonDocument::Indented);
+ qDebug() << QString::fromUtf8(data);
+ jsonFile.write(data);
+ jsonFile.close();
+ }
private
slots:
- void test_Through_Simple()
- {
- QJsonDocument doc = readJson("data/1.9-simple.json");
- auto vfile = MojangVersionFormat::versionFileFromJson(doc, "1.9-simple.json");
- auto doc2 = MojangVersionFormat::versionFileToJson(vfile);
- writeJson("1.9-simple-passthorugh.json", doc2);
-
- QCOMPARE(doc.toJson(), doc2.toJson());
- }
-
- void test_Through()
- {
- QJsonDocument doc = readJson("data/1.9.json");
- auto vfile = MojangVersionFormat::versionFileFromJson(doc, "1.9.json");
- auto doc2 = MojangVersionFormat::versionFileToJson(vfile);
- writeJson("1.9-passthorugh.json", doc2);
- QCOMPARE(doc.toJson(), doc2.toJson());
- }
+ void test_Through_Simple()
+ {
+ QJsonDocument doc = readJson("data/1.9-simple.json");
+ auto vfile = MojangVersionFormat::versionFileFromJson(doc, "1.9-simple.json");
+ auto doc2 = MojangVersionFormat::versionFileToJson(vfile);
+ writeJson("1.9-simple-passthorugh.json", doc2);
+
+ QCOMPARE(doc.toJson(), doc2.toJson());
+ }
+
+ void test_Through()
+ {
+ QJsonDocument doc = readJson("data/1.9.json");
+ auto vfile = MojangVersionFormat::versionFileFromJson(doc, "1.9.json");
+ auto doc2 = MojangVersionFormat::versionFileToJson(vfile);
+ writeJson("1.9-passthorugh.json", doc2);
+ QCOMPARE(doc.toJson(), doc2.toJson());
+ }
};
QTEST_GUILESS_MAIN(MojangVersionFormatTest)
diff --git a/api/logic/minecraft/OneSixVersionFormat.cpp b/api/logic/minecraft/OneSixVersionFormat.cpp
index f7ab25b3..6f3b926b 100644
--- a/api/logic/minecraft/OneSixVersionFormat.cpp
+++ b/api/logic/minecraft/OneSixVersionFormat.cpp
@@ -7,366 +7,366 @@ using namespace Json;
static void readString(const QJsonObject &root, const QString &key, QString &variable)
{
- if (root.contains(key))
- {
- variable = requireString(root.value(key));
- }
+ if (root.contains(key))
+ {
+ variable = requireString(root.value(key));
+ }
}
LibraryPtr OneSixVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename)
{
- LibraryPtr out = MojangVersionFormat::libraryFromJson(libObj, filename);
- readString(libObj, "MMC-hint", out->m_hint);
- readString(libObj, "MMC-absulute_url", out->m_absoluteURL);
- readString(libObj, "MMC-absoluteUrl", out->m_absoluteURL);
- readString(libObj, "MMC-filename", out->m_filename);
- readString(libObj, "MMC-displayname", out->m_displayname);
- return out;
+ LibraryPtr out = MojangVersionFormat::libraryFromJson(libObj, filename);
+ readString(libObj, "MMC-hint", out->m_hint);
+ readString(libObj, "MMC-absulute_url", out->m_absoluteURL);
+ readString(libObj, "MMC-absoluteUrl", out->m_absoluteURL);
+ readString(libObj, "MMC-filename", out->m_filename);
+ readString(libObj, "MMC-displayname", out->m_displayname);
+ return out;
}
QJsonObject OneSixVersionFormat::libraryToJson(Library *library)
{
- QJsonObject libRoot = MojangVersionFormat::libraryToJson(library);
- if (library->m_absoluteURL.size())
- libRoot.insert("MMC-absoluteUrl", library->m_absoluteURL);
- if (library->m_hint.size())
- libRoot.insert("MMC-hint", library->m_hint);
- if (library->m_filename.size())
- libRoot.insert("MMC-filename", library->m_filename);
- if (library->m_displayname.size())
- libRoot.insert("MMC-displayname", library->m_displayname);
- return libRoot;
+ QJsonObject libRoot = MojangVersionFormat::libraryToJson(library);
+ if (library->m_absoluteURL.size())
+ libRoot.insert("MMC-absoluteUrl", library->m_absoluteURL);
+ if (library->m_hint.size())
+ libRoot.insert("MMC-hint", library->m_hint);
+ if (library->m_filename.size())
+ libRoot.insert("MMC-filename", library->m_filename);
+ if (library->m_displayname.size())
+ libRoot.insert("MMC-displayname", library->m_displayname);
+ return libRoot;
}
VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder)
{
- VersionFilePtr out(new VersionFile());
- if (doc.isEmpty() || doc.isNull())
- {
- throw JSONValidationError(filename + " is empty or null");
- }
- if (!doc.isObject())
- {
- throw JSONValidationError(filename + " is not an object");
- }
-
- QJsonObject root = doc.object();
-
- Meta::MetadataVersion formatVersion = Meta::parseFormatVersion(root, false);
- switch(formatVersion)
- {
- case Meta::MetadataVersion::InitialRelease:
- break;
- case Meta::MetadataVersion::Invalid:
- throw JSONValidationError(filename + " does not contain a recognizable version of the metadata format.");
- }
-
- if (requireOrder)
- {
- if (root.contains("order"))
- {
- out->order = requireInteger(root.value("order"));
- }
- else
- {
- // FIXME: evaluate if we don't want to throw exceptions here instead
- qCritical() << filename << "doesn't contain an order field";
- }
- }
-
- out->name = root.value("name").toString();
-
- if(root.contains("uid"))
- {
- out->uid = root.value("uid").toString();
- }
- else
- {
- out->uid = root.value("fileId").toString();
- }
-
- out->version = root.value("version").toString();
-
- MojangVersionFormat::readVersionProperties(root, out.get());
-
- // added for legacy Minecraft window embedding, TODO: remove
- readString(root, "appletClass", out->appletClass);
-
- if (root.contains("+tweakers"))
- {
- for (auto tweakerVal : requireArray(root.value("+tweakers")))
- {
- out->addTweakers.append(requireString(tweakerVal));
- }
- }
-
- if (root.contains("+traits"))
- {
- for (auto tweakerVal : requireArray(root.value("+traits")))
- {
- out->traits.insert(requireString(tweakerVal));
- }
- }
-
-
- if (root.contains("jarMods"))
- {
- for (auto libVal : requireArray(root.value("jarMods")))
- {
- QJsonObject libObj = requireObject(libVal);
- // parse the jarmod
- auto lib = OneSixVersionFormat::jarModFromJson(libObj, filename);
- // and add to jar mods
- out->jarMods.append(lib);
- }
- }
- else if (root.contains("+jarMods")) // DEPRECATED: old style '+jarMods' are only here for backwards compatibility
- {
- for (auto libVal : requireArray(root.value("+jarMods")))
- {
- QJsonObject libObj = requireObject(libVal);
- // parse the jarmod
- auto lib = OneSixVersionFormat::plusJarModFromJson(libObj, filename, out->name);
- // and add to jar mods
- out->jarMods.append(lib);
- }
- }
-
- if (root.contains("mods"))
- {
- for (auto libVal : requireArray(root.value("mods")))
- {
- QJsonObject libObj = requireObject(libVal);
- // parse the jarmod
- auto lib = OneSixVersionFormat::modFromJson(libObj, filename);
- // and add to jar mods
- out->mods.append(lib);
- }
- }
-
- auto readLibs = [&](const char * which)
- {
- for (auto libVal : requireArray(root.value(which)))
- {
- QJsonObject libObj = requireObject(libVal);
- // parse the library
- auto lib = libraryFromJson(libObj, filename);
- out->libraries.append(lib);
- }
- };
- bool hasPlusLibs = root.contains("+libraries");
- bool hasLibs = root.contains("libraries");
- if (hasPlusLibs && hasLibs)
- {
- out->addProblem(ProblemSeverity::Warning,
- QObject::tr("Version file has both '+libraries' and 'libraries'. This is no longer supported."));
- readLibs("libraries");
- readLibs("+libraries");
- }
- else if (hasLibs)
- {
- readLibs("libraries");
- }
- else if(hasPlusLibs)
- {
- readLibs("+libraries");
- }
-
- // if we have mainJar, just use it
- if(root.contains("mainJar"))
- {
- QJsonObject libObj = requireObject(root, "mainJar");
- out->mainJar = libraryFromJson(libObj, filename);
- }
- // else reconstruct it from downloads and id ... if that's available
- else if(!out->minecraftVersion.isEmpty())
- {
- auto lib = std::make_shared<Library>();
- lib->setRawName(GradleSpecifier(QString("com.mojang:minecraft:%1:client").arg(out->minecraftVersion)));
- // we have a reliable client download, use it.
- if(out->mojangDownloads.contains("client"))
- {
- auto LibDLInfo = std::make_shared<MojangLibraryDownloadInfo>();
- LibDLInfo->artifact = out->mojangDownloads["client"];
- lib->setMojangDownloadInfo(LibDLInfo);
- }
- // we got nothing... guess based on ancient hardcoded Mojang behaviour
- // FIXME: this will eventually break...
- else
- {
- lib->setAbsoluteUrl(URLConstants::getLegacyJarUrl(out->minecraftVersion));
- }
- out->mainJar = lib;
- }
-
- if (root.contains("requires"))
- {
- Meta::parseRequires(root, &out->requires);
- }
- QString dependsOnMinecraftVersion = root.value("mcVersion").toString();
- if(!dependsOnMinecraftVersion.isEmpty())
- {
- Meta::Require mcReq;
- mcReq.uid = "net.minecraft";
- mcReq.equalsVersion = dependsOnMinecraftVersion;
- if (out->requires.count(mcReq) == 0)
- {
- out->requires.insert(mcReq);
- }
- }
- if (root.contains("conflicts"))
- {
- Meta::parseRequires(root, &out->conflicts);
- }
- if (root.contains("volatile"))
- {
- out->m_volatile = requireBoolean(root, "volatile");
- }
-
- /* removed features that shouldn't be used */
- if (root.contains("tweakers"))
- {
- out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element 'tweakers'"));
- }
- if (root.contains("-libraries"))
- {
- out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-libraries'"));
- }
- if (root.contains("-tweakers"))
- {
- out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-tweakers'"));
- }
- if (root.contains("-minecraftArguments"))
- {
- out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-minecraftArguments'"));
- }
- if (root.contains("+minecraftArguments"))
- {
- out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '+minecraftArguments'"));
- }
- return out;
+ VersionFilePtr out(new VersionFile());
+ if (doc.isEmpty() || doc.isNull())
+ {
+ throw JSONValidationError(filename + " is empty or null");
+ }
+ if (!doc.isObject())
+ {
+ throw JSONValidationError(filename + " is not an object");
+ }
+
+ QJsonObject root = doc.object();
+
+ Meta::MetadataVersion formatVersion = Meta::parseFormatVersion(root, false);
+ switch(formatVersion)
+ {
+ case Meta::MetadataVersion::InitialRelease:
+ break;
+ case Meta::MetadataVersion::Invalid:
+ throw JSONValidationError(filename + " does not contain a recognizable version of the metadata format.");
+ }
+
+ if (requireOrder)
+ {
+ if (root.contains("order"))
+ {
+ out->order = requireInteger(root.value("order"));
+ }
+ else
+ {
+ // FIXME: evaluate if we don't want to throw exceptions here instead
+ qCritical() << filename << "doesn't contain an order field";
+ }
+ }
+
+ out->name = root.value("name").toString();
+
+ if(root.contains("uid"))
+ {
+ out->uid = root.value("uid").toString();
+ }
+ else
+ {
+ out->uid = root.value("fileId").toString();
+ }
+
+ out->version = root.value("version").toString();
+
+ MojangVersionFormat::readVersionProperties(root, out.get());
+
+ // added for legacy Minecraft window embedding, TODO: remove
+ readString(root, "appletClass", out->appletClass);
+
+ if (root.contains("+tweakers"))
+ {
+ for (auto tweakerVal : requireArray(root.value("+tweakers")))
+ {
+ out->addTweakers.append(requireString(tweakerVal));
+ }
+ }
+
+ if (root.contains("+traits"))
+ {
+ for (auto tweakerVal : requireArray(root.value("+traits")))
+ {
+ out->traits.insert(requireString(tweakerVal));
+ }
+ }
+
+
+ if (root.contains("jarMods"))
+ {
+ for (auto libVal : requireArray(root.value("jarMods")))
+ {
+ QJsonObject libObj = requireObject(libVal);
+ // parse the jarmod
+ auto lib = OneSixVersionFormat::jarModFromJson(libObj, filename);
+ // and add to jar mods
+ out->jarMods.append(lib);
+ }
+ }
+ else if (root.contains("+jarMods")) // DEPRECATED: old style '+jarMods' are only here for backwards compatibility
+ {
+ for (auto libVal : requireArray(root.value("+jarMods")))
+ {
+ QJsonObject libObj = requireObject(libVal);
+ // parse the jarmod
+ auto lib = OneSixVersionFormat::plusJarModFromJson(libObj, filename, out->name);
+ // and add to jar mods
+ out->jarMods.append(lib);
+ }
+ }
+
+ if (root.contains("mods"))
+ {
+ for (auto libVal : requireArray(root.value("mods")))
+ {
+ QJsonObject libObj = requireObject(libVal);
+ // parse the jarmod
+ auto lib = OneSixVersionFormat::modFromJson(libObj, filename);
+ // and add to jar mods
+ out->mods.append(lib);
+ }
+ }
+
+ auto readLibs = [&](const char * which)
+ {
+ for (auto libVal : requireArray(root.value(which)))
+ {
+ QJsonObject libObj = requireObject(libVal);
+ // parse the library
+ auto lib = libraryFromJson(libObj, filename);
+ out->libraries.append(lib);
+ }
+ };
+ bool hasPlusLibs = root.contains("+libraries");
+ bool hasLibs = root.contains("libraries");
+ if (hasPlusLibs && hasLibs)
+ {
+ out->addProblem(ProblemSeverity::Warning,
+ QObject::tr("Version file has both '+libraries' and 'libraries'. This is no longer supported."));
+ readLibs("libraries");
+ readLibs("+libraries");
+ }
+ else if (hasLibs)
+ {
+ readLibs("libraries");
+ }
+ else if(hasPlusLibs)
+ {
+ readLibs("+libraries");
+ }
+
+ // if we have mainJar, just use it
+ if(root.contains("mainJar"))
+ {
+ QJsonObject libObj = requireObject(root, "mainJar");
+ out->mainJar = libraryFromJson(libObj, filename);
+ }
+ // else reconstruct it from downloads and id ... if that's available
+ else if(!out->minecraftVersion.isEmpty())
+ {
+ auto lib = std::make_shared<Library>();
+ lib->setRawName(GradleSpecifier(QString("com.mojang:minecraft:%1:client").arg(out->minecraftVersion)));
+ // we have a reliable client download, use it.
+ if(out->mojangDownloads.contains("client"))
+ {
+ auto LibDLInfo = std::make_shared<MojangLibraryDownloadInfo>();
+ LibDLInfo->artifact = out->mojangDownloads["client"];
+ lib->setMojangDownloadInfo(LibDLInfo);
+ }
+ // we got nothing... guess based on ancient hardcoded Mojang behaviour
+ // FIXME: this will eventually break...
+ else
+ {
+ lib->setAbsoluteUrl(URLConstants::getLegacyJarUrl(out->minecraftVersion));
+ }
+ out->mainJar = lib;
+ }
+
+ if (root.contains("requires"))
+ {
+ Meta::parseRequires(root, &out->requires);
+ }
+ QString dependsOnMinecraftVersion = root.value("mcVersion").toString();
+ if(!dependsOnMinecraftVersion.isEmpty())
+ {
+ Meta::Require mcReq;
+ mcReq.uid = "net.minecraft";
+ mcReq.equalsVersion = dependsOnMinecraftVersion;
+ if (out->requires.count(mcReq) == 0)
+ {
+ out->requires.insert(mcReq);
+ }
+ }
+ if (root.contains("conflicts"))
+ {
+ Meta::parseRequires(root, &out->conflicts);
+ }
+ if (root.contains("volatile"))
+ {
+ out->m_volatile = requireBoolean(root, "volatile");
+ }
+
+ /* removed features that shouldn't be used */
+ if (root.contains("tweakers"))
+ {
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element 'tweakers'"));
+ }
+ if (root.contains("-libraries"))
+ {
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-libraries'"));
+ }
+ if (root.contains("-tweakers"))
+ {
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-tweakers'"));
+ }
+ if (root.contains("-minecraftArguments"))
+ {
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '-minecraftArguments'"));
+ }
+ if (root.contains("+minecraftArguments"))
+ {
+ out->addProblem(ProblemSeverity::Error, QObject::tr("Version file contains unsupported element '+minecraftArguments'"));
+ }
+ return out;
}
QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch)
{
- QJsonObject root;
- writeString(root, "name", patch->name);
-
- writeString(root, "uid", patch->uid);
-
- writeString(root, "version", patch->version);
-
- Meta::serializeFormatVersion(root, Meta::MetadataVersion::InitialRelease);
-
- MojangVersionFormat::writeVersionProperties(patch.get(), root);
-
- if(patch->mainJar)
- {
- root.insert("mainJar", libraryToJson(patch->mainJar.get()));
- }
- writeString(root, "appletClass", patch->appletClass);
- writeStringList(root, "+tweakers", patch->addTweakers);
- writeStringList(root, "+traits", patch->traits.toList());
- if (!patch->libraries.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->libraries)
- {
- array.append(OneSixVersionFormat::libraryToJson(value.get()));
- }
- root.insert("libraries", array);
- }
- if (!patch->jarMods.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->jarMods)
- {
- array.append(OneSixVersionFormat::jarModtoJson(value.get()));
- }
- root.insert("jarMods", array);
- }
- if (!patch->mods.isEmpty())
- {
- QJsonArray array;
- for (auto value: patch->jarMods)
- {
- array.append(OneSixVersionFormat::modtoJson(value.get()));
- }
- root.insert("mods", array);
- }
- if(!patch->requires.empty())
- {
- Meta::serializeRequires(root, &patch->requires, "requires");
- }
- if(!patch->conflicts.empty())
- {
- Meta::serializeRequires(root, &patch->conflicts, "conflicts");
- }
- if(patch->m_volatile)
- {
- root.insert("volatile", true);
- }
- // write the contents to a json document.
- {
- QJsonDocument out;
- out.setObject(root);
- return out;
- }
+ QJsonObject root;
+ writeString(root, "name", patch->name);
+
+ writeString(root, "uid", patch->uid);
+
+ writeString(root, "version", patch->version);
+
+ Meta::serializeFormatVersion(root, Meta::MetadataVersion::InitialRelease);
+
+ MojangVersionFormat::writeVersionProperties(patch.get(), root);
+
+ if(patch->mainJar)
+ {
+ root.insert("mainJar", libraryToJson(patch->mainJar.get()));
+ }
+ writeString(root, "appletClass", patch->appletClass);
+ writeStringList(root, "+tweakers", patch->addTweakers);
+ writeStringList(root, "+traits", patch->traits.toList());
+ if (!patch->libraries.isEmpty())
+ {
+ QJsonArray array;
+ for (auto value: patch->libraries)
+ {
+ array.append(OneSixVersionFormat::libraryToJson(value.get()));
+ }
+ root.insert("libraries", array);
+ }
+ if (!patch->jarMods.isEmpty())
+ {
+ QJsonArray array;
+ for (auto value: patch->jarMods)
+ {
+ array.append(OneSixVersionFormat::jarModtoJson(value.get()));
+ }
+ root.insert("jarMods", array);
+ }
+ if (!patch->mods.isEmpty())
+ {
+ QJsonArray array;
+ for (auto value: patch->jarMods)
+ {
+ array.append(OneSixVersionFormat::modtoJson(value.get()));
+ }
+ root.insert("mods", array);
+ }
+ if(!patch->requires.empty())
+ {
+ Meta::serializeRequires(root, &patch->requires, "requires");
+ }
+ if(!patch->conflicts.empty())
+ {
+ Meta::serializeRequires(root, &patch->conflicts, "conflicts");
+ }
+ if(patch->m_volatile)
+ {
+ root.insert("volatile", true);
+ }
+ // write the contents to a json document.
+ {
+ QJsonDocument out;
+ out.setObject(root);
+ return out;
+ }
}
LibraryPtr OneSixVersionFormat::plusJarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName)
{
- LibraryPtr out(new Library());
- if (!libObj.contains("name"))
- {
- throw JSONValidationError(filename +
- "contains a jarmod that doesn't have a 'name' field");
- }
-
- // just make up something unique on the spot for the library name.
- auto uuid = QUuid::createUuid();
- QString id = uuid.toString().remove('{').remove('}');
- out->setRawName(GradleSpecifier("org.multimc.jarmods:" + id + ":1"));
-
- // filename override is the old name
- out->setFilename(libObj.value("name").toString());
-
- // it needs to be local, it is stored in the instance jarmods folder
- out->setHint("local");
-
- // read the original name if present - some versions did not set it
- // it is the original jar mod filename before it got renamed at the point of addition
- auto displayName = libObj.value("originalName").toString();
- if(displayName.isEmpty())
- {
- auto fixed = originalName;
- fixed.remove(" (jar mod)");
- out->setDisplayName(fixed);
- }
- else
- {
- out->setDisplayName(displayName);
- }
- return out;
+ LibraryPtr out(new Library());
+ if (!libObj.contains("name"))
+ {
+ throw JSONValidationError(filename +
+ "contains a jarmod that doesn't have a 'name' field");
+ }
+
+ // just make up something unique on the spot for the library name.
+ auto uuid = QUuid::createUuid();
+ QString id = uuid.toString().remove('{').remove('}');
+ out->setRawName(GradleSpecifier("org.multimc.jarmods:" + id + ":1"));
+
+ // filename override is the old name
+ out->setFilename(libObj.value("name").toString());
+
+ // it needs to be local, it is stored in the instance jarmods folder
+ out->setHint("local");
+
+ // read the original name if present - some versions did not set it
+ // it is the original jar mod filename before it got renamed at the point of addition
+ auto displayName = libObj.value("originalName").toString();
+ if(displayName.isEmpty())
+ {
+ auto fixed = originalName;
+ fixed.remove(" (jar mod)");
+ out->setDisplayName(fixed);
+ }
+ else
+ {
+ out->setDisplayName(displayName);
+ }
+ return out;
}
LibraryPtr OneSixVersionFormat::jarModFromJson(const QJsonObject& libObj, const QString& filename)
{
- return libraryFromJson(libObj, filename);
+ return libraryFromJson(libObj, filename);
}
QJsonObject OneSixVersionFormat::jarModtoJson(Library *jarmod)
{
- return libraryToJson(jarmod);
+ return libraryToJson(jarmod);
}
LibraryPtr OneSixVersionFormat::modFromJson(const QJsonObject& libObj, const QString& filename)
{
- return libraryFromJson(libObj, filename);
+ return libraryFromJson(libObj, filename);
}
QJsonObject OneSixVersionFormat::modtoJson(Library *jarmod)
{
- return libraryToJson(jarmod);
+ return libraryToJson(jarmod);
}
diff --git a/api/logic/minecraft/OneSixVersionFormat.h b/api/logic/minecraft/OneSixVersionFormat.h
index 8b782db0..6bbebca0 100644
--- a/api/logic/minecraft/OneSixVersionFormat.h
+++ b/api/logic/minecraft/OneSixVersionFormat.h
@@ -8,22 +8,22 @@
class OneSixVersionFormat
{
public:
- // version files / profile patches
- static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder);
- static QJsonDocument versionFileToJson(const VersionFilePtr &patch);
+ // version files / profile patches
+ static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder);
+ static QJsonDocument versionFileToJson(const VersionFilePtr &patch);
- // libraries
- static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename);
- static QJsonObject libraryToJson(Library *library);
+ // libraries
+ static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename);
+ static QJsonObject libraryToJson(Library *library);
- // DEPRECATED: old 'plus' jar mods generated by the application
- static LibraryPtr plusJarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName);
+ // DEPRECATED: old 'plus' jar mods generated by the application
+ static LibraryPtr plusJarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName);
- // new jar mods derived from libraries
- static LibraryPtr jarModFromJson(const QJsonObject &libObj, const QString &filename);
- static QJsonObject jarModtoJson(Library * jarmod);
+ // new jar mods derived from libraries
+ static LibraryPtr jarModFromJson(const QJsonObject &libObj, const QString &filename);
+ static QJsonObject jarModtoJson(Library * jarmod);
- // mods, also derived from libraries
- static LibraryPtr modFromJson(const QJsonObject &libObj, const QString &filename);
- static QJsonObject modtoJson(Library * jarmod);
+ // mods, also derived from libraries
+ static LibraryPtr modFromJson(const QJsonObject &libObj, const QString &filename);
+ static QJsonObject modtoJson(Library * jarmod);
};
diff --git a/api/logic/minecraft/OpSys.cpp b/api/logic/minecraft/OpSys.cpp
index 2165fa7f..2e18634b 100644
--- a/api/logic/minecraft/OpSys.cpp
+++ b/api/logic/minecraft/OpSys.cpp
@@ -17,26 +17,26 @@
OpSys OpSys_fromString(QString name)
{
- if (name == "linux")
- return Os_Linux;
- if (name == "windows")
- return Os_Windows;
- if (name == "osx")
- return Os_OSX;
- return Os_Other;
+ if (name == "linux")
+ return Os_Linux;
+ if (name == "windows")
+ return Os_Windows;
+ if (name == "osx")
+ return Os_OSX;
+ return Os_Other;
}
QString OpSys_toString(OpSys name)
{
- switch (name)
- {
- case Os_Linux:
- return "linux";
- case Os_OSX:
- return "osx";
- case Os_Windows:
- return "windows";
- default:
- return "other";
- }
+ switch (name)
+ {
+ case Os_Linux:
+ return "linux";
+ case Os_OSX:
+ return "osx";
+ case Os_Windows:
+ return "windows";
+ default:
+ return "other";
+ }
} \ No newline at end of file
diff --git a/api/logic/minecraft/OpSys.h b/api/logic/minecraft/OpSys.h
index e44b1e07..8ea84587 100644
--- a/api/logic/minecraft/OpSys.h
+++ b/api/logic/minecraft/OpSys.h
@@ -17,10 +17,10 @@
#include <QString>
enum OpSys
{
- Os_Windows,
- Os_Linux,
- Os_OSX,
- Os_Other
+ Os_Windows,
+ Os_Linux,
+ Os_OSX,
+ Os_Other
};
OpSys OpSys_fromString(QString);
diff --git a/api/logic/minecraft/ParseUtils.cpp b/api/logic/minecraft/ParseUtils.cpp
index ca188432..c9640e77 100644
--- a/api/logic/minecraft/ParseUtils.cpp
+++ b/api/logic/minecraft/ParseUtils.cpp
@@ -6,29 +6,29 @@
QDateTime timeFromS3Time(QString str)
{
- return QDateTime::fromString(str, Qt::ISODate);
+ return QDateTime::fromString(str, Qt::ISODate);
}
QString timeToS3Time(QDateTime time)
{
- // this all because Qt can't format timestamps right.
- int offsetRaw = time.offsetFromUtc();
- bool negative = offsetRaw < 0;
- int offsetAbs = std::abs(offsetRaw);
+ // this all because Qt can't format timestamps right.
+ int offsetRaw = time.offsetFromUtc();
+ bool negative = offsetRaw < 0;
+ int offsetAbs = std::abs(offsetRaw);
- int offsetSeconds = offsetAbs % 60;
- offsetAbs -= offsetSeconds;
+ int offsetSeconds = offsetAbs % 60;
+ offsetAbs -= offsetSeconds;
- int offsetMinutes = offsetAbs % 3600;
- offsetAbs -= offsetMinutes;
- offsetMinutes /= 60;
-
- int offsetHours = offsetAbs / 3600;
+ int offsetMinutes = offsetAbs % 3600;
+ offsetAbs -= offsetMinutes;
+ offsetMinutes /= 60;
+
+ int offsetHours = offsetAbs / 3600;
- QString raw = time.toString("yyyy-MM-ddTHH:mm:ss");
- raw += (negative ? QChar('-') : QChar('+'));
- raw += QString("%1").arg(offsetHours, 2, 10, QChar('0'));
- raw += ":";
- raw += QString("%1").arg(offsetMinutes, 2, 10, QChar('0'));
- return raw;
+ QString raw = time.toString("yyyy-MM-ddTHH:mm:ss");
+ raw += (negative ? QChar('-') : QChar('+'));
+ raw += QString("%1").arg(offsetHours, 2, 10, QChar('0'));
+ raw += ":";
+ raw += QString("%1").arg(offsetMinutes, 2, 10, QChar('0'));
+ return raw;
}
diff --git a/api/logic/minecraft/ParseUtils_test.cpp b/api/logic/minecraft/ParseUtils_test.cpp
index 1ce96248..fde9cdbf 100644
--- a/api/logic/minecraft/ParseUtils_test.cpp
+++ b/api/logic/minecraft/ParseUtils_test.cpp
@@ -5,37 +5,37 @@
class ParseUtilsTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- void test_Through_data()
- {
- QTest::addColumn<QString>("timestamp");
- const char * timestamps[] =
- {
- "2016-02-29T13:49:54+01:00",
- "2016-02-26T15:21:11+00:01",
- "2016-02-24T15:52:36+01:13",
- "2016-02-18T17:41:00+00:00",
- "2016-02-17T15:23:19+00:00",
- "2016-02-16T15:22:39+09:22",
- "2016-02-10T15:06:41+00:00",
- "2016-02-04T15:28:02-05:33"
- };
- for(unsigned i = 0; i < (sizeof(timestamps) / sizeof(const char *)); i++)
- {
- QTest::newRow(timestamps[i]) << QString(timestamps[i]);
- }
- }
- void test_Through()
- {
- QFETCH(QString, timestamp);
+ void test_Through_data()
+ {
+ QTest::addColumn<QString>("timestamp");
+ const char * timestamps[] =
+ {
+ "2016-02-29T13:49:54+01:00",
+ "2016-02-26T15:21:11+00:01",
+ "2016-02-24T15:52:36+01:13",
+ "2016-02-18T17:41:00+00:00",
+ "2016-02-17T15:23:19+00:00",
+ "2016-02-16T15:22:39+09:22",
+ "2016-02-10T15:06:41+00:00",
+ "2016-02-04T15:28:02-05:33"
+ };
+ for(unsigned i = 0; i < (sizeof(timestamps) / sizeof(const char *)); i++)
+ {
+ QTest::newRow(timestamps[i]) << QString(timestamps[i]);
+ }
+ }
+ void test_Through()
+ {
+ QFETCH(QString, timestamp);
- auto time_parsed = timeFromS3Time(timestamp);
- auto time_serialized = timeToS3Time(time_parsed);
-
- QCOMPARE(time_serialized, timestamp);
- }
+ auto time_parsed = timeFromS3Time(timestamp);
+ auto time_serialized = timeToS3Time(time_parsed);
+
+ QCOMPARE(time_serialized, timestamp);
+ }
};
diff --git a/api/logic/minecraft/ProfileUtils.cpp b/api/logic/minecraft/ProfileUtils.cpp
index 2227e438..8ca24cc8 100644
--- a/api/logic/minecraft/ProfileUtils.cpp
+++ b/api/logic/minecraft/ProfileUtils.cpp
@@ -16,163 +16,163 @@ static const int currentOrderFileVersion = 1;
bool readOverrideOrders(QString path, PatchOrder &order)
{
- QFile orderFile(path);
- if (!orderFile.exists())
- {
- qWarning() << "Order file doesn't exist. Ignoring.";
- return false;
- }
- if (!orderFile.open(QFile::ReadOnly))
- {
- qCritical() << "Couldn't open" << orderFile.fileName()
- << " for reading:" << orderFile.errorString();
- qWarning() << "Ignoring overriden order";
- return false;
- }
+ QFile orderFile(path);
+ if (!orderFile.exists())
+ {
+ qWarning() << "Order file doesn't exist. Ignoring.";
+ return false;
+ }
+ if (!orderFile.open(QFile::ReadOnly))
+ {
+ qCritical() << "Couldn't open" << orderFile.fileName()
+ << " for reading:" << orderFile.errorString();
+ qWarning() << "Ignoring overriden order";
+ return false;
+ }
- // and it's valid JSON
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(orderFile.readAll(), &error);
- if (error.error != QJsonParseError::NoError)
- {
- qCritical() << "Couldn't parse" << orderFile.fileName() << ":" << error.errorString();
- qWarning() << "Ignoring overriden order";
- return false;
- }
+ // and it's valid JSON
+ QJsonParseError error;
+ QJsonDocument doc = QJsonDocument::fromJson(orderFile.readAll(), &error);
+ if (error.error != QJsonParseError::NoError)
+ {
+ qCritical() << "Couldn't parse" << orderFile.fileName() << ":" << error.errorString();
+ qWarning() << "Ignoring overriden order";
+ return false;
+ }
- // and then read it and process it if all above is true.
- try
- {
- auto obj = Json::requireObject(doc);
- // check order file version.
- auto version = Json::requireInteger(obj.value("version"));
- if (version != currentOrderFileVersion)
- {
- throw JSONValidationError(QObject::tr("Invalid order file version, expected %1")
- .arg(currentOrderFileVersion));
- }
- auto orderArray = Json::requireArray(obj.value("order"));
- for(auto item: orderArray)
- {
- order.append(Json::requireString(item));
- }
- }
- catch (const JSONValidationError &err)
- {
- qCritical() << "Couldn't parse" << orderFile.fileName() << ": bad file format";
- qWarning() << "Ignoring overriden order";
- order.clear();
- return false;
- }
- return true;
+ // and then read it and process it if all above is true.
+ try
+ {
+ auto obj = Json::requireObject(doc);
+ // check order file version.
+ auto version = Json::requireInteger(obj.value("version"));
+ if (version != currentOrderFileVersion)
+ {
+ throw JSONValidationError(QObject::tr("Invalid order file version, expected %1")
+ .arg(currentOrderFileVersion));
+ }
+ auto orderArray = Json::requireArray(obj.value("order"));
+ for(auto item: orderArray)
+ {
+ order.append(Json::requireString(item));
+ }
+ }
+ catch (const JSONValidationError &err)
+ {
+ qCritical() << "Couldn't parse" << orderFile.fileName() << ": bad file format";
+ qWarning() << "Ignoring overriden order";
+ order.clear();
+ return false;
+ }
+ return true;
}
static VersionFilePtr createErrorVersionFile(QString fileId, QString filepath, QString error)
{
- auto outError = std::make_shared<VersionFile>();
- outError->uid = outError->name = fileId;
- // outError->filename = filepath;
- outError->addProblem(ProblemSeverity::Error, error);
- return outError;
+ auto outError = std::make_shared<VersionFile>();
+ outError->uid = outError->name = fileId;
+ // outError->filename = filepath;
+ outError->addProblem(ProblemSeverity::Error, error);
+ return outError;
}
static VersionFilePtr guardedParseJson(const QJsonDocument & doc,const QString &fileId,const QString &filepath,const bool &requireOrder)
{
- try
- {
- return OneSixVersionFormat::versionFileFromJson(doc, filepath, requireOrder);
- }
- catch (const Exception &e)
- {
- return createErrorVersionFile(fileId, filepath, e.cause());
- }
+ try
+ {
+ return OneSixVersionFormat::versionFileFromJson(doc, filepath, requireOrder);
+ }
+ catch (const Exception &e)
+ {
+ return createErrorVersionFile(fileId, filepath, e.cause());
+ }
}
VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder)
{
- QFile file(fileInfo.absoluteFilePath());
- if (!file.open(QFile::ReadOnly))
- {
- auto errorStr = QObject::tr("Unable to open the version file %1: %2.").arg(fileInfo.fileName(), file.errorString());
- return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
- }
- QJsonParseError error;
- auto data = file.readAll();
- QJsonDocument doc = QJsonDocument::fromJson(data, &error);
- file.close();
- if (error.error != QJsonParseError::NoError)
- {
- int line = 1;
- int column = 0;
- for(int i = 0; i < error.offset; i++)
- {
- if(data[i] == '\n')
- {
- line++;
- column = 0;
- continue;
- }
- column++;
- }
- auto errorStr = QObject::tr("Unable to process the version file %1: %2 at line %3 column %4.")
- .arg(fileInfo.fileName(), error.errorString())
- .arg(line).arg(column);
- return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
- }
- return guardedParseJson(doc, fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), requireOrder);
+ QFile file(fileInfo.absoluteFilePath());
+ if (!file.open(QFile::ReadOnly))
+ {
+ auto errorStr = QObject::tr("Unable to open the version file %1: %2.").arg(fileInfo.fileName(), file.errorString());
+ return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
+ }
+ QJsonParseError error;
+ auto data = file.readAll();
+ QJsonDocument doc = QJsonDocument::fromJson(data, &error);
+ file.close();
+ if (error.error != QJsonParseError::NoError)
+ {
+ int line = 1;
+ int column = 0;
+ for(int i = 0; i < error.offset; i++)
+ {
+ if(data[i] == '\n')
+ {
+ line++;
+ column = 0;
+ continue;
+ }
+ column++;
+ }
+ auto errorStr = QObject::tr("Unable to process the version file %1: %2 at line %3 column %4.")
+ .arg(fileInfo.fileName(), error.errorString())
+ .arg(line).arg(column);
+ return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
+ }
+ return guardedParseJson(doc, fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), requireOrder);
}
bool saveJsonFile(const QJsonDocument doc, const QString & filename)
{
- auto data = doc.toJson();
- QSaveFile jsonFile(filename);
- if(!jsonFile.open(QIODevice::WriteOnly))
- {
- jsonFile.cancelWriting();
- qWarning() << "Couldn't open" << filename << "for writing";
- return false;
- }
- jsonFile.write(data);
- if(!jsonFile.commit())
- {
- qWarning() << "Couldn't save" << filename;
- return false;
- }
- return true;
+ auto data = doc.toJson();
+ QSaveFile jsonFile(filename);
+ if(!jsonFile.open(QIODevice::WriteOnly))
+ {
+ jsonFile.cancelWriting();
+ qWarning() << "Couldn't open" << filename << "for writing";
+ return false;
+ }
+ jsonFile.write(data);
+ if(!jsonFile.commit())
+ {
+ qWarning() << "Couldn't save" << filename;
+ return false;
+ }
+ return true;
}
VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo)
{
- QFile file(fileInfo.absoluteFilePath());
- if (!file.open(QFile::ReadOnly))
- {
- auto errorStr = QObject::tr("Unable to open the version file %1: %2.").arg(fileInfo.fileName(), file.errorString());
- return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
- }
- QJsonDocument doc = QJsonDocument::fromBinaryData(file.readAll());
- file.close();
- if (doc.isNull())
- {
- file.remove();
- throw JSONValidationError(QObject::tr("Unable to process the version file %1.").arg(fileInfo.fileName()));
- }
- return guardedParseJson(doc, fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), false);
+ QFile file(fileInfo.absoluteFilePath());
+ if (!file.open(QFile::ReadOnly))
+ {
+ auto errorStr = QObject::tr("Unable to open the version file %1: %2.").arg(fileInfo.fileName(), file.errorString());
+ return createErrorVersionFile(fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), errorStr);
+ }
+ QJsonDocument doc = QJsonDocument::fromBinaryData(file.readAll());
+ file.close();
+ if (doc.isNull())
+ {
+ file.remove();
+ throw JSONValidationError(QObject::tr("Unable to process the version file %1.").arg(fileInfo.fileName()));
+ }
+ return guardedParseJson(doc, fileInfo.completeBaseName(), fileInfo.absoluteFilePath(), false);
}
void removeLwjglFromPatch(VersionFilePtr patch)
{
- auto filter = [](QList<LibraryPtr>& libs)
- {
- QList<LibraryPtr> filteredLibs;
- for (auto lib : libs)
- {
- if (!g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix()))
- {
- filteredLibs.append(lib);
- }
- }
- libs = filteredLibs;
- };
- filter(patch->libraries);
+ auto filter = [](QList<LibraryPtr>& libs)
+ {
+ QList<LibraryPtr> filteredLibs;
+ for (auto lib : libs)
+ {
+ if (!g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix()))
+ {
+ filteredLibs.append(lib);
+ }
+ }
+ libs = filteredLibs;
+ };
+ filter(patch->libraries);
}
}
diff --git a/api/logic/minecraft/Rule.cpp b/api/logic/minecraft/Rule.cpp
index 43d673c2..a7640635 100644
--- a/api/logic/minecraft/Rule.cpp
+++ b/api/logic/minecraft/Rule.cpp
@@ -20,74 +20,74 @@
RuleAction RuleAction_fromString(QString name)
{
- if (name == "allow")
- return Allow;
- if (name == "disallow")
- return Disallow;
- return Defer;
+ if (name == "allow")
+ return Allow;
+ if (name == "disallow")
+ return Disallow;
+ return Defer;
}
QList<std::shared_ptr<Rule>> rulesFromJsonV4(const QJsonObject &objectWithRules)
{
- QList<std::shared_ptr<Rule>> rules;
- auto rulesVal = objectWithRules.value("rules");
- if (!rulesVal.isArray())
- return rules;
+ QList<std::shared_ptr<Rule>> rules;
+ auto rulesVal = objectWithRules.value("rules");
+ if (!rulesVal.isArray())
+ return rules;
- QJsonArray ruleList = rulesVal.toArray();
- for (auto ruleVal : ruleList)
- {
- std::shared_ptr<Rule> rule;
- if (!ruleVal.isObject())
- continue;
- auto ruleObj = ruleVal.toObject();
- auto actionVal = ruleObj.value("action");
- if (!actionVal.isString())
- continue;
- auto action = RuleAction_fromString(actionVal.toString());
- if (action == Defer)
- continue;
+ QJsonArray ruleList = rulesVal.toArray();
+ for (auto ruleVal : ruleList)
+ {
+ std::shared_ptr<Rule> rule;
+ if (!ruleVal.isObject())
+ continue;
+ auto ruleObj = ruleVal.toObject();
+ auto actionVal = ruleObj.value("action");
+ if (!actionVal.isString())
+ continue;
+ auto action = RuleAction_fromString(actionVal.toString());
+ if (action == Defer)
+ continue;
- auto osVal = ruleObj.value("os");
- if (!osVal.isObject())
- {
- // add a new implicit action rule
- rules.append(ImplicitRule::create(action));
- continue;
- }
+ auto osVal = ruleObj.value("os");
+ if (!osVal.isObject())
+ {
+ // add a new implicit action rule
+ rules.append(ImplicitRule::create(action));
+ continue;
+ }
- auto osObj = osVal.toObject();
- auto osNameVal = osObj.value("name");
- if (!osNameVal.isString())
- continue;
- OpSys requiredOs = OpSys_fromString(osNameVal.toString());
- QString versionRegex = osObj.value("version").toString();
- // add a new OS rule
- rules.append(OsRule::create(action, requiredOs, versionRegex));
- }
+ auto osObj = osVal.toObject();
+ auto osNameVal = osObj.value("name");
+ if (!osNameVal.isString())
+ continue;
+ OpSys requiredOs = OpSys_fromString(osNameVal.toString());
+ QString versionRegex = osObj.value("version").toString();
+ // add a new OS rule
+ rules.append(OsRule::create(action, requiredOs, versionRegex));
+ }
return rules;
}
QJsonObject ImplicitRule::toJson()
{
- QJsonObject ruleObj;
- ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
- return ruleObj;
+ QJsonObject ruleObj;
+ ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
+ return ruleObj;
}
QJsonObject OsRule::toJson()
{
- QJsonObject ruleObj;
- ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
- QJsonObject osObj;
- {
- osObj.insert("name", OpSys_toString(m_system));
- if(!m_version_regexp.isEmpty())
- {
- osObj.insert("version", m_version_regexp);
- }
- }
- ruleObj.insert("os", osObj);
- return ruleObj;
+ QJsonObject ruleObj;
+ ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
+ QJsonObject osObj;
+ {
+ osObj.insert("name", OpSys_toString(m_system));
+ if(!m_version_regexp.isEmpty())
+ {
+ osObj.insert("version", m_version_regexp);
+ }
+ }
+ ruleObj.insert("os", osObj);
+ return ruleObj;
}
diff --git a/api/logic/minecraft/Rule.h b/api/logic/minecraft/Rule.h
index dc1eee0b..ec9b26bd 100644
--- a/api/logic/minecraft/Rule.h
+++ b/api/logic/minecraft/Rule.h
@@ -26,9 +26,9 @@ class Rule;
enum RuleAction
{
- Allow,
- Disallow,
- Defer
+ Allow,
+ Disallow,
+ Defer
};
QList<std::shared_ptr<Rule>> rulesFromJsonV4(const QJsonObject &objectWithRules);
@@ -36,66 +36,66 @@ QList<std::shared_ptr<Rule>> rulesFromJsonV4(const QJsonObject &objectWithRules)
class Rule
{
protected:
- RuleAction m_result;
- virtual bool applies(const Library *parent) = 0;
+ RuleAction m_result;
+ virtual bool applies(const Library *parent) = 0;
public:
- Rule(RuleAction result) : m_result(result)
- {
- }
- virtual ~Rule() {};
- virtual QJsonObject toJson() = 0;
- RuleAction apply(const Library *parent)
- {
- if (applies(parent))
- return m_result;
- else
- return Defer;
- }
+ Rule(RuleAction result) : m_result(result)
+ {
+ }
+ virtual ~Rule() {};
+ virtual QJsonObject toJson() = 0;
+ RuleAction apply(const Library *parent)
+ {
+ if (applies(parent))
+ return m_result;
+ else
+ return Defer;
+ }
};
class OsRule : public Rule
{
private:
- // the OS
- OpSys m_system;
- // the OS version regexp
- QString m_version_regexp;
+ // the OS
+ OpSys m_system;
+ // the OS version regexp
+ QString m_version_regexp;
protected:
- virtual bool applies(const Library *)
- {
- return (m_system == currentSystem);
- }
- OsRule(RuleAction result, OpSys system, QString version_regexp)
- : Rule(result), m_system(system), m_version_regexp(version_regexp)
- {
- }
+ virtual bool applies(const Library *)
+ {
+ return (m_system == currentSystem);
+ }
+ OsRule(RuleAction result, OpSys system, QString version_regexp)
+ : Rule(result), m_system(system), m_version_regexp(version_regexp)
+ {
+ }
public:
- virtual QJsonObject toJson();
- static std::shared_ptr<OsRule> create(RuleAction result, OpSys system,
- QString version_regexp)
- {
- return std::shared_ptr<OsRule>(new OsRule(result, system, version_regexp));
- }
+ virtual QJsonObject toJson();
+ static std::shared_ptr<OsRule> create(RuleAction result, OpSys system,
+ QString version_regexp)
+ {
+ return std::shared_ptr<OsRule>(new OsRule(result, system, version_regexp));
+ }
};
class ImplicitRule : public Rule
{
protected:
- virtual bool applies(const Library *)
- {
- return true;
- }
- ImplicitRule(RuleAction result) : Rule(result)
- {
- }
+ virtual bool applies(const Library *)
+ {
+ return true;
+ }
+ ImplicitRule(RuleAction result) : Rule(result)
+ {
+ }
public:
- virtual QJsonObject toJson();
- static std::shared_ptr<ImplicitRule> create(RuleAction result)
- {
- return std::shared_ptr<ImplicitRule>(new ImplicitRule(result));
- }
+ virtual QJsonObject toJson();
+ static std::shared_ptr<ImplicitRule> create(RuleAction result)
+ {
+ return std::shared_ptr<ImplicitRule>(new ImplicitRule(result));
+ }
};
diff --git a/api/logic/minecraft/SimpleModList.cpp b/api/logic/minecraft/SimpleModList.cpp
index ca923226..a9fb42eb 100644
--- a/api/logic/minecraft/SimpleModList.cpp
+++ b/api/logic/minecraft/SimpleModList.cpp
@@ -24,344 +24,344 @@
SimpleModList::SimpleModList(const QString &dir) : QAbstractListModel(), m_dir(dir)
{
- FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
- QDir::NoSymLinks);
- m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
- m_watcher = new QFileSystemWatcher(this);
- connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString)));
+ FS::ensureFolderPathExists(m_dir.absolutePath());
+ m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
+ QDir::NoSymLinks);
+ m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
+ m_watcher = new QFileSystemWatcher(this);
+ connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString)));
}
void SimpleModList::startWatching()
{
- if(is_watching)
- return;
-
- update();
-
- is_watching = m_watcher->addPath(m_dir.absolutePath());
- if (is_watching)
- {
- qDebug() << "Started watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to start watching " << m_dir.absolutePath();
- }
+ if(is_watching)
+ return;
+
+ update();
+
+ is_watching = m_watcher->addPath(m_dir.absolutePath());
+ if (is_watching)
+ {
+ qDebug() << "Started watching " << m_dir.absolutePath();
+ }
+ else
+ {
+ qDebug() << "Failed to start watching " << m_dir.absolutePath();
+ }
}
void SimpleModList::stopWatching()
{
- if(!is_watching)
- return;
-
- is_watching = !m_watcher->removePath(m_dir.absolutePath());
- if (!is_watching)
- {
- qDebug() << "Stopped watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to stop watching " << m_dir.absolutePath();
- }
+ if(!is_watching)
+ return;
+
+ is_watching = !m_watcher->removePath(m_dir.absolutePath());
+ if (!is_watching)
+ {
+ qDebug() << "Stopped watching " << m_dir.absolutePath();
+ }
+ else
+ {
+ qDebug() << "Failed to stop watching " << m_dir.absolutePath();
+ }
}
bool SimpleModList::update()
{
- if (!isValid())
- return false;
-
- QList<Mod> orderedMods;
- QList<Mod> newMods;
- m_dir.refresh();
- auto folderContents = m_dir.entryInfoList();
- bool orderOrStateChanged = false;
-
- // if there are any untracked files...
- if (folderContents.size())
- {
- // the order surely changed!
- for (auto entry : folderContents)
- {
- newMods.append(Mod(entry));
- }
- orderedMods.append(newMods);
- orderOrStateChanged = true;
- }
- // otherwise, if we were already tracking some mods
- else if (mods.size())
- {
- // if the number doesn't match, order changed.
- if (mods.size() != orderedMods.size())
- orderOrStateChanged = true;
- // if it does match, compare the mods themselves
- else
- for (int i = 0; i < mods.size(); i++)
- {
- if (!mods[i].strongCompare(orderedMods[i]))
- {
- orderOrStateChanged = true;
- break;
- }
- }
- }
- beginResetModel();
- mods.swap(orderedMods);
- endResetModel();
- if (orderOrStateChanged)
- {
- emit changed();
- }
- return true;
+ if (!isValid())
+ return false;
+
+ QList<Mod> orderedMods;
+ QList<Mod> newMods;
+ m_dir.refresh();
+ auto folderContents = m_dir.entryInfoList();
+ bool orderOrStateChanged = false;
+
+ // if there are any untracked files...
+ if (folderContents.size())
+ {
+ // the order surely changed!
+ for (auto entry : folderContents)
+ {
+ newMods.append(Mod(entry));
+ }
+ orderedMods.append(newMods);
+ orderOrStateChanged = true;
+ }
+ // otherwise, if we were already tracking some mods
+ else if (mods.size())
+ {
+ // if the number doesn't match, order changed.
+ if (mods.size() != orderedMods.size())
+ orderOrStateChanged = true;
+ // if it does match, compare the mods themselves
+ else
+ for (int i = 0; i < mods.size(); i++)
+ {
+ if (!mods[i].strongCompare(orderedMods[i]))
+ {
+ orderOrStateChanged = true;
+ break;
+ }
+ }
+ }
+ beginResetModel();
+ mods.swap(orderedMods);
+ endResetModel();
+ if (orderOrStateChanged)
+ {
+ emit changed();
+ }
+ return true;
}
void SimpleModList::directoryChanged(QString path)
{
- update();
+ update();
}
bool SimpleModList::isValid()
{
- return m_dir.exists() && m_dir.isReadable();
+ return m_dir.exists() && m_dir.isReadable();
}
bool SimpleModList::installMod(const QString &filename)
{
- // NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName
- QFileInfo fileinfo(FS::NormalizePath(filename));
-
- qDebug() << "installing: " << fileinfo.absoluteFilePath();
-
- if (!fileinfo.exists() || !fileinfo.isReadable())
- {
- return false;
- }
- Mod m(fileinfo);
- if (!m.valid())
- return false;
-
- auto type = m.type();
- if (type == Mod::MOD_UNKNOWN)
- return false;
- if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD)
- {
- QString newpath = FS::PathCombine(m_dir.path(), fileinfo.fileName());
- if (!QFile::copy(fileinfo.filePath(), newpath))
- return false;
- FS::updateTimestamp(newpath);
- m.repath(newpath);
- update();
- return true;
- }
- else if (type == Mod::MOD_FOLDER)
- {
- QString from = fileinfo.filePath();
- QString to = FS::PathCombine(m_dir.path(), fileinfo.fileName());
- if (!FS::copy(from, to)())
- return false;
- m.repath(to);
- update();
- return true;
- }
- return false;
+ // NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName
+ QFileInfo fileinfo(FS::NormalizePath(filename));
+
+ qDebug() << "installing: " << fileinfo.absoluteFilePath();
+
+ if (!fileinfo.exists() || !fileinfo.isReadable())
+ {
+ return false;
+ }
+ Mod m(fileinfo);
+ if (!m.valid())
+ return false;
+
+ auto type = m.type();
+ if (type == Mod::MOD_UNKNOWN)
+ return false;
+ if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD)
+ {
+ QString newpath = FS::PathCombine(m_dir.path(), fileinfo.fileName());
+ if (!QFile::copy(fileinfo.filePath(), newpath))
+ return false;
+ FS::updateTimestamp(newpath);
+ m.repath(newpath);
+ update();
+ return true;
+ }
+ else if (type == Mod::MOD_FOLDER)
+ {
+ QString from = fileinfo.filePath();
+ QString to = FS::PathCombine(m_dir.path(), fileinfo.fileName());
+ if (!FS::copy(from, to)())
+ return false;
+ m.repath(to);
+ update();
+ return true;
+ }
+ return false;
}
bool SimpleModList::enableMods(const QModelIndexList& indexes, bool enable)
{
- if(indexes.isEmpty())
- return true;
-
- for (auto i: indexes)
- {
- Mod &m = mods[i.row()];
- m.enable(enable);
- emit dataChanged(i, i);
- }
- emit changed();
- return true;
+ if(indexes.isEmpty())
+ return true;
+
+ for (auto i: indexes)
+ {
+ Mod &m = mods[i.row()];
+ m.enable(enable);
+ emit dataChanged(i, i);
+ }
+ emit changed();
+ return true;
}
bool SimpleModList::deleteMods(const QModelIndexList& indexes)
{
- if(indexes.isEmpty())
- return true;
-
- for (auto i: indexes)
- {
- Mod &m = mods[i.row()];
- m.destroy();
- }
- emit changed();
- return true;
+ if(indexes.isEmpty())
+ return true;
+
+ for (auto i: indexes)
+ {
+ Mod &m = mods[i.row()];
+ m.destroy();
+ }
+ emit changed();
+ return true;
}
int SimpleModList::columnCount(const QModelIndex &parent) const
{
- return NUM_COLUMNS;
+ return NUM_COLUMNS;
}
QVariant SimpleModList::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= mods.size())
- return QVariant();
-
- switch (role)
- {
- case Qt::DisplayRole:
- switch (column)
- {
- case NameColumn:
- return mods[row].name();
- case VersionColumn:
- return mods[row].version();
- case DateColumn:
- return mods[row].dateTimeChanged();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return mods[row].mmc_id();
-
- case Qt::CheckStateRole:
- switch (column)
- {
- case ActiveColumn:
- return mods[row].enabled() ? Qt::Checked : Qt::Unchecked;
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
+ if (!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+ int column = index.column();
+
+ if (row < 0 || row >= mods.size())
+ return QVariant();
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (column)
+ {
+ case NameColumn:
+ return mods[row].name();
+ case VersionColumn:
+ return mods[row].version();
+ case DateColumn:
+ return mods[row].dateTimeChanged();
+
+ default:
+ return QVariant();
+ }
+
+ case Qt::ToolTipRole:
+ return mods[row].mmc_id();
+
+ case Qt::CheckStateRole:
+ switch (column)
+ {
+ case ActiveColumn:
+ return mods[row].enabled() ? Qt::Checked : Qt::Unchecked;
+ default:
+ return QVariant();
+ }
+ default:
+ return QVariant();
+ }
}
bool SimpleModList::setData(const QModelIndex &index, const QVariant &value, int role)
{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return false;
- }
-
- if (role == Qt::CheckStateRole)
- {
- auto &mod = mods[index.row()];
- if (mod.enable(!mod.enabled()))
- {
- emit dataChanged(index, index);
- return true;
- }
- }
- return false;
+ if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
+ {
+ return false;
+ }
+
+ if (role == Qt::CheckStateRole)
+ {
+ auto &mod = mods[index.row()];
+ if (mod.enable(!mod.enabled()))
+ {
+ emit dataChanged(index, index);
+ return true;
+ }
+ }
+ return false;
}
QVariant SimpleModList::headerData(int section, Qt::Orientation orientation, int role) const
{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case ActiveColumn:
- return QString();
- case NameColumn:
- return tr("Name");
- case VersionColumn:
- return tr("Version");
- case DateColumn:
- return tr("Last changed");
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case ActiveColumn:
- return tr("Is the mod enabled?");
- case NameColumn:
- return tr("The name of the mod.");
- case VersionColumn:
- return tr("The version of the mod.");
- case DateColumn:
- return tr("The date and time this mod was last changed (or added).");
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
- return QVariant();
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (section)
+ {
+ case ActiveColumn:
+ return QString();
+ case NameColumn:
+ return tr("Name");
+ case VersionColumn:
+ return tr("Version");
+ case DateColumn:
+ return tr("Last changed");
+ default:
+ return QVariant();
+ }
+
+ case Qt::ToolTipRole:
+ switch (section)
+ {
+ case ActiveColumn:
+ return tr("Is the mod enabled?");
+ case NameColumn:
+ return tr("The name of the mod.");
+ case VersionColumn:
+ return tr("The version of the mod.");
+ case DateColumn:
+ return tr("The date and time this mod was last changed (or added).");
+ default:
+ return QVariant();
+ }
+ default:
+ return QVariant();
+ }
+ return QVariant();
}
Qt::ItemFlags SimpleModList::flags(const QModelIndex &index) const
{
- Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
- if (index.isValid())
- return Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled |
- defaultFlags;
- else
- return Qt::ItemIsDropEnabled | defaultFlags;
+ Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
+ if (index.isValid())
+ return Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled |
+ defaultFlags;
+ else
+ return Qt::ItemIsDropEnabled | defaultFlags;
}
Qt::DropActions SimpleModList::supportedDropActions() const
{
- // copy from outside, move from within and other mod lists
- return Qt::CopyAction | Qt::MoveAction;
+ // copy from outside, move from within and other mod lists
+ return Qt::CopyAction | Qt::MoveAction;
}
QStringList SimpleModList::mimeTypes() const
{
- QStringList types;
- types << "text/uri-list";
- return types;
+ QStringList types;
+ types << "text/uri-list";
+ return types;
}
bool SimpleModList::dropMimeData(const QMimeData* data, Qt::DropAction action, int, int, const QModelIndex&)
{
- if (action == Qt::IgnoreAction)
- {
- return true;
- }
-
- // check if the action is supported
- if (!data || !(action & supportedDropActions()))
- {
- return false;
- }
-
- // files dropped from outside?
- if (data->hasUrls())
- {
- bool was_watching = is_watching;
- if (was_watching)
- {
- stopWatching();
- }
- auto urls = data->urls();
- for (auto url : urls)
- {
- // only local files may be dropped...
- if (!url.isLocalFile())
- {
- continue;
- }
- // TODO: implement not only copy, but also move
- // FIXME: handle errors here
- installMod(url.toLocalFile());
- }
- if (was_watching)
- {
- startWatching();
- }
- return true;
- }
- return false;
+ if (action == Qt::IgnoreAction)
+ {
+ return true;
+ }
+
+ // check if the action is supported
+ if (!data || !(action & supportedDropActions()))
+ {
+ return false;
+ }
+
+ // files dropped from outside?
+ if (data->hasUrls())
+ {
+ bool was_watching = is_watching;
+ if (was_watching)
+ {
+ stopWatching();
+ }
+ auto urls = data->urls();
+ for (auto url : urls)
+ {
+ // only local files may be dropped...
+ if (!url.isLocalFile())
+ {
+ continue;
+ }
+ // TODO: implement not only copy, but also move
+ // FIXME: handle errors here
+ installMod(url.toLocalFile());
+ }
+ if (was_watching)
+ {
+ startWatching();
+ }
+ return true;
+ }
+ return false;
}
diff --git a/api/logic/minecraft/SimpleModList.h b/api/logic/minecraft/SimpleModList.h
index 3257edbe..d623a295 100644
--- a/api/logic/minecraft/SimpleModList.h
+++ b/api/logic/minecraft/SimpleModList.h
@@ -34,88 +34,88 @@ class QFileSystemWatcher;
*/
class MULTIMC_LOGIC_EXPORT SimpleModList : public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum Columns
- {
- ActiveColumn = 0,
- NameColumn,
- DateColumn,
- VersionColumn,
- NUM_COLUMNS
- };
- SimpleModList(const QString &dir);
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
- Qt::DropActions supportedDropActions() const override;
-
- /// flags, mostly to support drag&drop
- virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
- QStringList mimeTypes() const override;
- bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) override;
-
- virtual int rowCount(const QModelIndex &) const override
- {
- return size();
- }
- ;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
- virtual int columnCount(const QModelIndex &parent) const override;
-
- size_t size() const
- {
- return mods.size();
- }
- ;
- bool empty() const
- {
- return size() == 0;
- }
- Mod &operator[](size_t index)
- {
- return mods[index];
- }
-
- /// Reloads the mod list and returns true if the list changed.
- virtual bool update();
-
- /**
- * Adds the given mod to the list at the given index - if the list supports custom ordering
- */
- bool installMod(const QString& filename);
-
- /// Deletes all the selected mods
- virtual bool deleteMods(const QModelIndexList &indexes);
-
- /// Enable or disable listed mods
- virtual bool enableMods(const QModelIndexList &indexes, bool enable = true);
-
- void startWatching();
- void stopWatching();
-
- virtual bool isValid();
-
- QDir dir()
- {
- return m_dir;
- }
-
- const QList<Mod> & allMods()
- {
- return mods;
- }
+ enum Columns
+ {
+ ActiveColumn = 0,
+ NameColumn,
+ DateColumn,
+ VersionColumn,
+ NUM_COLUMNS
+ };
+ SimpleModList(const QString &dir);
+
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+ Qt::DropActions supportedDropActions() const override;
+
+ /// flags, mostly to support drag&drop
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
+ QStringList mimeTypes() const override;
+ bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) override;
+
+ virtual int rowCount(const QModelIndex &) const override
+ {
+ return size();
+ }
+ ;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+ virtual int columnCount(const QModelIndex &parent) const override;
+
+ size_t size() const
+ {
+ return mods.size();
+ }
+ ;
+ bool empty() const
+ {
+ return size() == 0;
+ }
+ Mod &operator[](size_t index)
+ {
+ return mods[index];
+ }
+
+ /// Reloads the mod list and returns true if the list changed.
+ virtual bool update();
+
+ /**
+ * Adds the given mod to the list at the given index - if the list supports custom ordering
+ */
+ bool installMod(const QString& filename);
+
+ /// Deletes all the selected mods
+ virtual bool deleteMods(const QModelIndexList &indexes);
+
+ /// Enable or disable listed mods
+ virtual bool enableMods(const QModelIndexList &indexes, bool enable = true);
+
+ void startWatching();
+ void stopWatching();
+
+ virtual bool isValid();
+
+ QDir dir()
+ {
+ return m_dir;
+ }
+
+ const QList<Mod> & allMods()
+ {
+ return mods;
+ }
private
slots:
- void directoryChanged(QString path);
+ void directoryChanged(QString path);
signals:
- void changed();
+ void changed();
protected:
- QFileSystemWatcher *m_watcher;
- bool is_watching = false;
- QDir m_dir;
- QList<Mod> mods;
+ QFileSystemWatcher *m_watcher;
+ bool is_watching = false;
+ QDir m_dir;
+ QList<Mod> mods;
};
diff --git a/api/logic/minecraft/SimpleModList_test.cpp b/api/logic/minecraft/SimpleModList_test.cpp
index 28ce8471..a100b539 100644
--- a/api/logic/minecraft/SimpleModList_test.cpp
+++ b/api/logic/minecraft/SimpleModList_test.cpp
@@ -8,44 +8,44 @@
class SimpleModListTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- // test for GH-1178 - install a folder with files to a mod list
- void test_1178()
- {
- // source
- QString source = QFINDTESTDATA("data/test_folder");
-
- // sanity check
- QVERIFY(!source.endsWith('/'));
-
- auto verify = [](QString path)
- {
- QDir target_dir(FS::PathCombine(path, "test_folder"));
- QVERIFY(target_dir.entryList().contains("pack.mcmeta"));
- QVERIFY(target_dir.entryList().contains("assets"));
- };
-
- // 1. test with no trailing /
- {
- QString folder = source;
- QTemporaryDir tempDir;
- SimpleModList m(tempDir.path());
- m.installMod(folder);
- verify(tempDir.path());
- }
-
- // 2. test with trailing /
- {
- QString folder = source + '/';
- QTemporaryDir tempDir;
- SimpleModList m(tempDir.path());
- m.installMod(folder);
- verify(tempDir.path());
- }
- }
+ // test for GH-1178 - install a folder with files to a mod list
+ void test_1178()
+ {
+ // source
+ QString source = QFINDTESTDATA("data/test_folder");
+
+ // sanity check
+ QVERIFY(!source.endsWith('/'));
+
+ auto verify = [](QString path)
+ {
+ QDir target_dir(FS::PathCombine(path, "test_folder"));
+ QVERIFY(target_dir.entryList().contains("pack.mcmeta"));
+ QVERIFY(target_dir.entryList().contains("assets"));
+ };
+
+ // 1. test with no trailing /
+ {
+ QString folder = source;
+ QTemporaryDir tempDir;
+ SimpleModList m(tempDir.path());
+ m.installMod(folder);
+ verify(tempDir.path());
+ }
+
+ // 2. test with trailing /
+ {
+ QString folder = source + '/';
+ QTemporaryDir tempDir;
+ SimpleModList m(tempDir.path());
+ m.installMod(folder);
+ verify(tempDir.path());
+ }
+ }
};
QTEST_GUILESS_MAIN(SimpleModListTest)
diff --git a/api/logic/minecraft/SkinUpload.cpp b/api/logic/minecraft/SkinUpload.cpp
index bd246139..83bdf592 100644
--- a/api/logic/minecraft/SkinUpload.cpp
+++ b/api/logic/minecraft/SkinUpload.cpp
@@ -4,66 +4,66 @@
#include <Env.h>
QByteArray getModelString(SkinUpload::Model model) {
- switch (model) {
- case SkinUpload::STEVE:
- return "";
- case SkinUpload::ALEX:
- return "slim";
- default:
- qDebug() << "Unknown skin type!";
- return "";
- }
+ switch (model) {
+ case SkinUpload::STEVE:
+ return "";
+ case SkinUpload::ALEX:
+ return "slim";
+ default:
+ qDebug() << "Unknown skin type!";
+ return "";
+ }
}
SkinUpload::SkinUpload(QObject *parent, AuthSessionPtr session, QByteArray skin, SkinUpload::Model model)
- : Task(parent), m_model(model), m_skin(skin), m_session(session)
+ : Task(parent), m_model(model), m_skin(skin), m_session(session)
{
}
void SkinUpload::executeTask()
{
- QNetworkRequest request(QUrl(QString("https://api.mojang.com/user/profile/%1/skin").arg(m_session->uuid)));
- request.setRawHeader("Authorization", QString("Bearer: %1").arg(m_session->access_token).toLocal8Bit());
+ QNetworkRequest request(QUrl(QString("https://api.mojang.com/user/profile/%1/skin").arg(m_session->uuid)));
+ request.setRawHeader("Authorization", QString("Bearer: %1").arg(m_session->access_token).toLocal8Bit());
- QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
+ QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
- QHttpPart model;
- model.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"model\""));
- model.setBody(getModelString(m_model));
+ QHttpPart model;
+ model.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"model\""));
+ model.setBody(getModelString(m_model));
- QHttpPart skin;
- skin.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
- skin.setHeader(QNetworkRequest::ContentDispositionHeader,
- QVariant("form-data; name=\"file\"; filename=\"skin.png\""));
- skin.setBody(m_skin);
+ QHttpPart skin;
+ skin.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
+ skin.setHeader(QNetworkRequest::ContentDispositionHeader,
+ QVariant("form-data; name=\"file\"; filename=\"skin.png\""));
+ skin.setBody(m_skin);
- multiPart->append(model);
- multiPart->append(skin);
+ multiPart->append(model);
+ multiPart->append(skin);
- QNetworkReply *rep = ENV.qnam().put(request, multiPart);
- m_reply = std::shared_ptr<QNetworkReply>(rep);
+ QNetworkReply *rep = ENV.qnam().put(request, multiPart);
+ m_reply = std::shared_ptr<QNetworkReply>(rep);
- setStatus(tr("Uploading skin"));
- connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress);
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, SIGNAL(finished()), this, SLOT(downloadFinished()));
+ setStatus(tr("Uploading skin"));
+ connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress);
+ connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
+ connect(rep, SIGNAL(finished()), this, SLOT(downloadFinished()));
}
void SkinUpload::downloadError(QNetworkReply::NetworkError error)
{
- // error happened during download.
- qCritical() << "Network error: " << error;
- emitFailed(m_reply->errorString());
+ // error happened during download.
+ qCritical() << "Network error: " << error;
+ emitFailed(m_reply->errorString());
}
void SkinUpload::downloadFinished()
{
- // if the download failed
- if (m_reply->error() != QNetworkReply::NetworkError::NoError)
- {
- emitFailed(QString("Network error: %1").arg(m_reply->errorString()));
- m_reply.reset();
- return;
- }
- emitSucceeded();
+ // if the download failed
+ if (m_reply->error() != QNetworkReply::NetworkError::NoError)
+ {
+ emitFailed(QString("Network error: %1").arg(m_reply->errorString()));
+ m_reply.reset();
+ return;
+ }
+ emitSucceeded();
}
diff --git a/api/logic/minecraft/SkinUpload.h b/api/logic/minecraft/SkinUpload.h
index c47283b1..c77abb03 100644
--- a/api/logic/minecraft/SkinUpload.h
+++ b/api/logic/minecraft/SkinUpload.h
@@ -11,29 +11,29 @@ typedef std::shared_ptr<class SkinUpload> SkinUploadPtr;
class MULTIMC_LOGIC_EXPORT SkinUpload : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum Model
- {
- STEVE,
- ALEX
- };
+ enum Model
+ {
+ STEVE,
+ ALEX
+ };
- // Note this class takes ownership of the file.
- SkinUpload(QObject *parent, AuthSessionPtr session, QByteArray skin, Model model = STEVE);
- virtual ~SkinUpload() {}
+ // Note this class takes ownership of the file.
+ SkinUpload(QObject *parent, AuthSessionPtr session, QByteArray skin, Model model = STEVE);
+ virtual ~SkinUpload() {}
private:
- Model m_model;
- QByteArray m_skin;
- AuthSessionPtr m_session;
- std::shared_ptr<QNetworkReply> m_reply;
+ Model m_model;
+ QByteArray m_skin;
+ AuthSessionPtr m_session;
+ std::shared_ptr<QNetworkReply> m_reply;
protected:
- virtual void executeTask();
+ virtual void executeTask();
public slots:
- void downloadError(QNetworkReply::NetworkError);
+ void downloadError(QNetworkReply::NetworkError);
- void downloadFinished();
+ void downloadFinished();
};
diff --git a/api/logic/minecraft/VersionFile.cpp b/api/logic/minecraft/VersionFile.cpp
index 9f485c55..cfb9e504 100644
--- a/api/logic/minecraft/VersionFile.cpp
+++ b/api/logic/minecraft/VersionFile.cpp
@@ -12,45 +12,45 @@
static bool isMinecraftVersion(const QString &uid)
{
- return uid == "net.minecraft";
+ return uid == "net.minecraft";
}
void VersionFile::applyTo(LaunchProfile *profile)
{
- // Only real Minecraft can set those. Don't let anything override them.
- if (isMinecraftVersion(uid))
- {
- profile->applyMinecraftVersion(minecraftVersion);
- profile->applyMinecraftVersionType(type);
- // HACK: ignore assets from other version files than Minecraft
- // workaround for stupid assets issue caused by amazon:
- // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
- profile->applyMinecraftAssets(mojangAssetIndex);
- }
-
- profile->applyMainJar(mainJar);
- profile->applyMainClass(mainClass);
- profile->applyAppletClass(appletClass);
- profile->applyMinecraftArguments(minecraftArguments);
- profile->applyTweakers(addTweakers);
- profile->applyJarMods(jarMods);
- profile->applyMods(mods);
- profile->applyTraits(traits);
-
- for (auto library : libraries)
- {
- profile->applyLibrary(library);
- }
- profile->applyProblemSeverity(getProblemSeverity());
+ // Only real Minecraft can set those. Don't let anything override them.
+ if (isMinecraftVersion(uid))
+ {
+ profile->applyMinecraftVersion(minecraftVersion);
+ profile->applyMinecraftVersionType(type);
+ // HACK: ignore assets from other version files than Minecraft
+ // workaround for stupid assets issue caused by amazon:
+ // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
+ profile->applyMinecraftAssets(mojangAssetIndex);
+ }
+
+ profile->applyMainJar(mainJar);
+ profile->applyMainClass(mainClass);
+ profile->applyAppletClass(appletClass);
+ profile->applyMinecraftArguments(minecraftArguments);
+ profile->applyTweakers(addTweakers);
+ profile->applyJarMods(jarMods);
+ profile->applyMods(mods);
+ profile->applyTraits(traits);
+
+ for (auto library : libraries)
+ {
+ profile->applyLibrary(library);
+ }
+ profile->applyProblemSeverity(getProblemSeverity());
}
/*
- auto theirVersion = profile->getMinecraftVersion();
- if (!theirVersion.isNull() && !dependsOnMinecraftVersion.isNull())
- {
- if (QRegExp(dependsOnMinecraftVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(theirVersion) == -1)
- {
- throw MinecraftVersionMismatch(uid, dependsOnMinecraftVersion, theirVersion);
- }
- }
+ auto theirVersion = profile->getMinecraftVersion();
+ if (!theirVersion.isNull() && !dependsOnMinecraftVersion.isNull())
+ {
+ if (QRegExp(dependsOnMinecraftVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(theirVersion) == -1)
+ {
+ throw MinecraftVersionMismatch(uid, dependsOnMinecraftVersion, theirVersion);
+ }
+ }
*/ \ No newline at end of file
diff --git a/api/logic/minecraft/VersionFile.h b/api/logic/minecraft/VersionFile.h
index 5aea7a7a..3dc9db96 100644
--- a/api/logic/minecraft/VersionFile.h
+++ b/api/logic/minecraft/VersionFile.h
@@ -21,91 +21,91 @@ struct MojangAssetIndexInfo;
using VersionFilePtr = std::shared_ptr<VersionFile>;
class VersionFile : public ProblemContainer
{
- friend class MojangVersionFormat;
- friend class OneSixVersionFormat;
+ friend class MojangVersionFormat;
+ friend class OneSixVersionFormat;
public: /* methods */
- void applyTo(LaunchProfile* profile);
+ void applyTo(LaunchProfile* profile);
public: /* data */
- /// MultiMC: order hint for this version file if no explicit order is set
- int order = 0;
+ /// MultiMC: order hint for this version file if no explicit order is set
+ int order = 0;
- /// MultiMC: human readable name of this package
- QString name;
+ /// MultiMC: human readable name of this package
+ QString name;
- /// MultiMC: package ID of this package
- QString uid;
+ /// MultiMC: package ID of this package
+ QString uid;
- /// MultiMC: version of this package
- QString version;
+ /// MultiMC: version of this package
+ QString version;
- /// MultiMC: DEPRECATED dependency on a Minecraft version
- QString dependsOnMinecraftVersion;
+ /// MultiMC: DEPRECATED dependency on a Minecraft version
+ QString dependsOnMinecraftVersion;
- /// Mojang: DEPRECATED used to version the Mojang version format
- int minimumLauncherVersion = -1;
+ /// Mojang: DEPRECATED used to version the Mojang version format
+ int minimumLauncherVersion = -1;
- /// Mojang: DEPRECATED version of Minecraft this is
- QString minecraftVersion;
+ /// Mojang: DEPRECATED version of Minecraft this is
+ QString minecraftVersion;
- /// Mojang: class to launch Minecraft with
- QString mainClass;
+ /// Mojang: class to launch Minecraft with
+ QString mainClass;
- /// MultiMC: class to launch legacy Minecraft with (embed in a custom window)
- QString appletClass;
+ /// MultiMC: class to launch legacy Minecraft with (embed in a custom window)
+ QString appletClass;
- /// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution)
- QString minecraftArguments;
+ /// Mojang: Minecraft launch arguments (may contain placeholders for variable substitution)
+ QString minecraftArguments;
- /// Mojang: type of the Minecraft version
- QString type;
+ /// Mojang: type of the Minecraft version
+ QString type;
- /// Mojang: the time this version was actually released by Mojang
- QDateTime releaseTime;
+ /// Mojang: the time this version was actually released by Mojang
+ QDateTime releaseTime;
- /// Mojang: DEPRECATED the time this version was last updated by Mojang
- QDateTime updateTime;
+ /// Mojang: DEPRECATED the time this version was last updated by Mojang
+ QDateTime updateTime;
- /// Mojang: DEPRECATED asset group to be used with Minecraft
- QString assets;
+ /// Mojang: DEPRECATED asset group to be used with Minecraft
+ QString assets;
- /// MultiMC: list of tweaker mod arguments for launchwrapper
- QStringList addTweakers;
+ /// MultiMC: list of tweaker mod arguments for launchwrapper
+ QStringList addTweakers;
- /// Mojang: list of libraries to add to the version
- QList<LibraryPtr> libraries;
+ /// Mojang: list of libraries to add to the version
+ QList<LibraryPtr> libraries;
- /// The main jar (Minecraft version library, normally)
- LibraryPtr mainJar;
+ /// The main jar (Minecraft version library, normally)
+ LibraryPtr mainJar;
- /// MultiMC: list of attached traits of this version file - used to enable features
- QSet<QString> traits;
+ /// MultiMC: list of attached traits of this version file - used to enable features
+ QSet<QString> traits;
- /// MultiMC: list of jar mods added to this version
- QList<LibraryPtr> jarMods;
+ /// MultiMC: list of jar mods added to this version
+ QList<LibraryPtr> jarMods;
- /// MultiMC: list of mods added to this version
- QList<LibraryPtr> mods;
+ /// MultiMC: list of mods added to this version
+ QList<LibraryPtr> mods;
- /**
- * MultiMC: set of packages this depends on
- * NOTE: this is shared with the meta format!!!
- */
- Meta::RequireSet requires;
+ /**
+ * MultiMC: set of packages this depends on
+ * NOTE: this is shared with the meta format!!!
+ */
+ Meta::RequireSet requires;
- /**
- * MultiMC: set of packages this conflicts with
- * NOTE: this is shared with the meta format!!!
- */
- Meta::RequireSet conflicts;
+ /**
+ * MultiMC: set of packages this conflicts with
+ * NOTE: this is shared with the meta format!!!
+ */
+ Meta::RequireSet conflicts;
- /// is volatile -- may be removed as soon as it is no longer needed by something else
- bool m_volatile = false;
+ /// is volatile -- may be removed as soon as it is no longer needed by something else
+ bool m_volatile = false;
public:
- // Mojang: DEPRECATED list of 'downloads' - client jar, server jar, windows server exe, maybe more.
- QMap <QString, std::shared_ptr<MojangDownloadInfo>> mojangDownloads;
+ // Mojang: DEPRECATED list of 'downloads' - client jar, server jar, windows server exe, maybe more.
+ QMap <QString, std::shared_ptr<MojangDownloadInfo>> mojangDownloads;
- // Mojang: extended asset index download information
- std::shared_ptr<MojangAssetIndexInfo> mojangAssetIndex;
+ // Mojang: extended asset index download information
+ std::shared_ptr<MojangAssetIndexInfo> mojangAssetIndex;
};
diff --git a/api/logic/minecraft/VersionFilterData.cpp b/api/logic/minecraft/VersionFilterData.cpp
index 5f4ceee6..11f7eea9 100644
--- a/api/logic/minecraft/VersionFilterData.cpp
+++ b/api/logic/minecraft/VersionFilterData.cpp
@@ -5,64 +5,64 @@ VersionFilterData g_VersionFilterData = VersionFilterData();
VersionFilterData::VersionFilterData()
{
- // 1.3.*
- auto libs13 =
- QList<FMLlib>{{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
- {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
- {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false}};
+ // 1.3.*
+ auto libs13 =
+ QList<FMLlib>{{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
+ {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
+ {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false}};
- fmlLibsMapping["1.3.2"] = libs13;
+ fmlLibsMapping["1.3.2"] = libs13;
- // 1.4.*
- auto libs14 = QList<FMLlib>{
- {"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
- {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
- {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false},
- {"bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", false}};
+ // 1.4.*
+ auto libs14 = QList<FMLlib>{
+ {"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false},
+ {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false},
+ {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false},
+ {"bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", false}};
- fmlLibsMapping["1.4"] = libs14;
- fmlLibsMapping["1.4.1"] = libs14;
- fmlLibsMapping["1.4.2"] = libs14;
- fmlLibsMapping["1.4.3"] = libs14;
- fmlLibsMapping["1.4.4"] = libs14;
- fmlLibsMapping["1.4.5"] = libs14;
- fmlLibsMapping["1.4.6"] = libs14;
- fmlLibsMapping["1.4.7"] = libs14;
+ fmlLibsMapping["1.4"] = libs14;
+ fmlLibsMapping["1.4.1"] = libs14;
+ fmlLibsMapping["1.4.2"] = libs14;
+ fmlLibsMapping["1.4.3"] = libs14;
+ fmlLibsMapping["1.4.4"] = libs14;
+ fmlLibsMapping["1.4.5"] = libs14;
+ fmlLibsMapping["1.4.6"] = libs14;
+ fmlLibsMapping["1.4.7"] = libs14;
- // 1.5
- fmlLibsMapping["1.5"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
+ // 1.5
+ fmlLibsMapping["1.5"] = QList<FMLlib>{
+ {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
+ {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
+ {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
+ {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
+ {"deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8", false},
+ {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
- // 1.5.1
- fmlLibsMapping["1.5.1"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
+ // 1.5.1
+ fmlLibsMapping["1.5.1"] = QList<FMLlib>{
+ {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
+ {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
+ {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
+ {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
+ {"deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6", false},
+ {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
- // 1.5.2
- fmlLibsMapping["1.5.2"] = QList<FMLlib>{
- {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
- {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
- {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
- {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
- {"deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9", false},
- {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
+ // 1.5.2
+ fmlLibsMapping["1.5.2"] = QList<FMLlib>{
+ {"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false},
+ {"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false},
+ {"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false},
+ {"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true},
+ {"deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9", false},
+ {"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}};
- // don't use installers for those.
- forgeInstallerBlacklist = QSet<QString>({"1.5.2"});
+ // don't use installers for those.
+ forgeInstallerBlacklist = QSet<QString>({"1.5.2"});
- // FIXME: remove, used for deciding when core mods should display
- legacyCutoffDate = timeFromS3Time("2013-06-25T15:08:56+02:00");
- lwjglWhitelist =
- QSet<QString>{"net.java.jinput:jinput", "net.java.jinput:jinput-platform",
- "net.java.jutils:jutils", "org.lwjgl.lwjgl:lwjgl",
- "org.lwjgl.lwjgl:lwjgl_util", "org.lwjgl.lwjgl:lwjgl-platform"};
+ // FIXME: remove, used for deciding when core mods should display
+ legacyCutoffDate = timeFromS3Time("2013-06-25T15:08:56+02:00");
+ lwjglWhitelist =
+ QSet<QString>{"net.java.jinput:jinput", "net.java.jinput:jinput-platform",
+ "net.java.jutils:jutils", "org.lwjgl.lwjgl:lwjgl",
+ "org.lwjgl.lwjgl:lwjgl_util", "org.lwjgl.lwjgl:lwjgl-platform"};
}
diff --git a/api/logic/minecraft/VersionFilterData.h b/api/logic/minecraft/VersionFilterData.h
index 2408e704..88e91f11 100644
--- a/api/logic/minecraft/VersionFilterData.h
+++ b/api/logic/minecraft/VersionFilterData.h
@@ -8,21 +8,21 @@
struct FMLlib
{
- QString filename;
- QString checksum;
- bool ours;
+ QString filename;
+ QString checksum;
+ bool ours;
};
struct VersionFilterData
{
- VersionFilterData();
- // mapping between minecraft versions and FML libraries required
- QMap<QString, QList<FMLlib>> fmlLibsMapping;
- // set of minecraft versions for which using forge installers is blacklisted
- QSet<QString> forgeInstallerBlacklist;
- // no new versions below this date will be accepted from Mojang servers
- QDateTime legacyCutoffDate;
- // Libraries that belong to LWJGL
- QSet<QString> lwjglWhitelist;
+ VersionFilterData();
+ // mapping between minecraft versions and FML libraries required
+ QMap<QString, QList<FMLlib>> fmlLibsMapping;
+ // set of minecraft versions for which using forge installers is blacklisted
+ QSet<QString> forgeInstallerBlacklist;
+ // no new versions below this date will be accepted from Mojang servers
+ QDateTime legacyCutoffDate;
+ // Libraries that belong to LWJGL
+ QSet<QString> lwjglWhitelist;
};
extern VersionFilterData MULTIMC_LOGIC_EXPORT g_VersionFilterData;
diff --git a/api/logic/minecraft/World.cpp b/api/logic/minecraft/World.cpp
index d7bc4553..b39f940e 100644
--- a/api/logic/minecraft/World.cpp
+++ b/api/logic/minecraft/World.cpp
@@ -32,354 +32,354 @@
std::unique_ptr <nbt::tag_compound> parseLevelDat(QByteArray data)
{
- QByteArray output;
- if(!GZip::unzip(data, output))
- {
- return nullptr;
- }
- std::istringstream foo(std::string(output.constData(), output.size()));
- auto pair = nbt::io::read_compound(foo);
+ QByteArray output;
+ if(!GZip::unzip(data, output))
+ {
+ return nullptr;
+ }
+ std::istringstream foo(std::string(output.constData(), output.size()));
+ auto pair = nbt::io::read_compound(foo);
- if(pair.first != "")
- return nullptr;
+ if(pair.first != "")
+ return nullptr;
- if(pair.second == nullptr)
- return nullptr;
+ if(pair.second == nullptr)
+ return nullptr;
- return std::move(pair.second);
+ return std::move(pair.second);
}
QByteArray serializeLevelDat(nbt::tag_compound * levelInfo)
{
- std::ostringstream s;
- nbt::io::write_tag("", *levelInfo, s);
- QByteArray val( s.str().data(), (int) s.str().size() );
- return val;
+ std::ostringstream s;
+ nbt::io::write_tag("", *levelInfo, s);
+ QByteArray val( s.str().data(), (int) s.str().size() );
+ return val;
}
QString getLevelDatFromFS(const QFileInfo &file)
{
- QDir worldDir(file.filePath());
- if(!file.isDir() || !worldDir.exists("level.dat"))
- {
- return QString();
- }
- return worldDir.absoluteFilePath("level.dat");
+ QDir worldDir(file.filePath());
+ if(!file.isDir() || !worldDir.exists("level.dat"))
+ {
+ return QString();
+ }
+ return worldDir.absoluteFilePath("level.dat");
}
QByteArray getLevelDatDataFromFS(const QFileInfo &file)
{
- auto fullFilePath = getLevelDatFromFS(file);
- if(fullFilePath.isNull())
- {
- return QByteArray();
- }
- QFile f(fullFilePath);
- if(!f.open(QIODevice::ReadOnly))
- {
- return QByteArray();
- }
- return f.readAll();
+ auto fullFilePath = getLevelDatFromFS(file);
+ if(fullFilePath.isNull())
+ {
+ return QByteArray();
+ }
+ QFile f(fullFilePath);
+ if(!f.open(QIODevice::ReadOnly))
+ {
+ return QByteArray();
+ }
+ return f.readAll();
}
bool putLevelDatDataToFS(const QFileInfo &file, QByteArray & data)
{
- auto fullFilePath = getLevelDatFromFS(file);
- if(fullFilePath.isNull())
- {
- return false;
- }
- QSaveFile f(fullFilePath);
- if(!f.open(QIODevice::WriteOnly))
- {
- return false;
- }
- QByteArray compressed;
- if(!GZip::zip(data, compressed))
- {
- return false;
- }
- if(f.write(compressed) != compressed.size())
- {
- f.cancelWriting();
- return false;
- }
- return f.commit();
+ auto fullFilePath = getLevelDatFromFS(file);
+ if(fullFilePath.isNull())
+ {
+ return false;
+ }
+ QSaveFile f(fullFilePath);
+ if(!f.open(QIODevice::WriteOnly))
+ {
+ return false;
+ }
+ QByteArray compressed;
+ if(!GZip::zip(data, compressed))
+ {
+ return false;
+ }
+ if(f.write(compressed) != compressed.size())
+ {
+ f.cancelWriting();
+ return false;
+ }
+ return f.commit();
}
World::World(const QFileInfo &file)
{
- repath(file);
+ repath(file);
}
void World::repath(const QFileInfo &file)
{
- m_containerFile = file;
- m_folderName = file.fileName();
- if(file.isFile() && file.suffix() == "zip")
- {
- readFromZip(file);
- }
- else if(file.isDir())
- {
- readFromFS(file);
- }
+ m_containerFile = file;
+ m_folderName = file.fileName();
+ if(file.isFile() && file.suffix() == "zip")
+ {
+ readFromZip(file);
+ }
+ else if(file.isDir())
+ {
+ readFromFS(file);
+ }
}
void World::readFromFS(const QFileInfo &file)
{
- auto bytes = getLevelDatDataFromFS(file);
- if(bytes.isEmpty())
- {
- is_valid = false;
- return;
- }
- loadFromLevelDat(bytes);
- levelDatTime = file.lastModified();
+ auto bytes = getLevelDatDataFromFS(file);
+ if(bytes.isEmpty())
+ {
+ is_valid = false;
+ return;
+ }
+ loadFromLevelDat(bytes);
+ levelDatTime = file.lastModified();
}
void World::readFromZip(const QFileInfo &file)
{
- QuaZip zip(file.absoluteFilePath());
- is_valid = zip.open(QuaZip::mdUnzip);
- if (!is_valid)
- {
- return;
- }
- auto location = MMCZip::findFolderOfFileInZip(&zip, "level.dat");
- is_valid = !location.isEmpty();
- if (!is_valid)
- {
- return;
- }
- m_containerOffsetPath = location;
- QuaZipFile zippedFile(&zip);
- // read the install profile
- is_valid = zip.setCurrentFile(location + "level.dat");
- if (!is_valid)
- {
- return;
- }
- is_valid = zippedFile.open(QIODevice::ReadOnly);
- QuaZipFileInfo64 levelDatInfo;
- zippedFile.getFileInfo(&levelDatInfo);
- auto modTime = levelDatInfo.getNTFSmTime();
- if(!modTime.isValid())
- {
- modTime = levelDatInfo.dateTime;
- }
- levelDatTime = modTime;
- if (!is_valid)
- {
- return;
- }
- loadFromLevelDat(zippedFile.readAll());
- zippedFile.close();
+ QuaZip zip(file.absoluteFilePath());
+ is_valid = zip.open(QuaZip::mdUnzip);
+ if (!is_valid)
+ {
+ return;
+ }
+ auto location = MMCZip::findFolderOfFileInZip(&zip, "level.dat");
+ is_valid = !location.isEmpty();
+ if (!is_valid)
+ {
+ return;
+ }
+ m_containerOffsetPath = location;
+ QuaZipFile zippedFile(&zip);
+ // read the install profile
+ is_valid = zip.setCurrentFile(location + "level.dat");
+ if (!is_valid)
+ {
+ return;
+ }
+ is_valid = zippedFile.open(QIODevice::ReadOnly);
+ QuaZipFileInfo64 levelDatInfo;
+ zippedFile.getFileInfo(&levelDatInfo);
+ auto modTime = levelDatInfo.getNTFSmTime();
+ if(!modTime.isValid())
+ {
+ modTime = levelDatInfo.dateTime;
+ }
+ levelDatTime = modTime;
+ if (!is_valid)
+ {
+ return;
+ }
+ loadFromLevelDat(zippedFile.readAll());
+ zippedFile.close();
}
bool World::install(const QString &to, const QString &name)
{
- auto finalPath = FS::PathCombine(to, FS::DirNameFromString(m_actualName, to));
- if(!FS::ensureFolderPathExists(finalPath))
- {
- return false;
- }
- bool ok = false;
- if(m_containerFile.isFile())
- {
- QuaZip zip(m_containerFile.absoluteFilePath());
- if (!zip.open(QuaZip::mdUnzip))
- {
- return false;
- }
- ok = !MMCZip::extractSubDir(&zip, m_containerOffsetPath, finalPath).isEmpty();
- }
- else if(m_containerFile.isDir())
- {
- QString from = m_containerFile.filePath();
- ok = FS::copy(from, finalPath)();
- }
-
- if(ok && !name.isEmpty() && m_actualName != name)
- {
- World newWorld(finalPath);
- if(newWorld.isValid())
- {
- newWorld.rename(name);
- }
- }
- return ok;
+ auto finalPath = FS::PathCombine(to, FS::DirNameFromString(m_actualName, to));
+ if(!FS::ensureFolderPathExists(finalPath))
+ {
+ return false;
+ }
+ bool ok = false;
+ if(m_containerFile.isFile())
+ {
+ QuaZip zip(m_containerFile.absoluteFilePath());
+ if (!zip.open(QuaZip::mdUnzip))
+ {
+ return false;
+ }
+ ok = !MMCZip::extractSubDir(&zip, m_containerOffsetPath, finalPath).isEmpty();
+ }
+ else if(m_containerFile.isDir())
+ {
+ QString from = m_containerFile.filePath();
+ ok = FS::copy(from, finalPath)();
+ }
+
+ if(ok && !name.isEmpty() && m_actualName != name)
+ {
+ World newWorld(finalPath);
+ if(newWorld.isValid())
+ {
+ newWorld.rename(name);
+ }
+ }
+ return ok;
}
bool World::rename(const QString &newName)
{
- if(m_containerFile.isFile())
- {
- return false;
- }
-
- auto data = getLevelDatDataFromFS(m_containerFile);
- if(data.isEmpty())
- {
- return false;
- }
-
- auto worldData = parseLevelDat(data);
- if(!worldData)
- {
- return false;
- }
- auto &val = worldData->at("Data");
- if(val.get_type() != nbt::tag_type::Compound)
- {
- return false;
- }
- auto &dataCompound = val.as<nbt::tag_compound>();
- dataCompound.put("LevelName", nbt::value_initializer(newName.toUtf8().data()));
- data = serializeLevelDat(worldData.get());
-
- putLevelDatDataToFS(m_containerFile, data);
-
- m_actualName = newName;
-
- QDir parentDir(m_containerFile.absoluteFilePath());
- parentDir.cdUp();
- QFile container(m_containerFile.absoluteFilePath());
- auto dirName = FS::DirNameFromString(m_actualName, parentDir.absolutePath());
- container.rename(parentDir.absoluteFilePath(dirName));
-
- return true;
+ if(m_containerFile.isFile())
+ {
+ return false;
+ }
+
+ auto data = getLevelDatDataFromFS(m_containerFile);
+ if(data.isEmpty())
+ {
+ return false;
+ }
+
+ auto worldData = parseLevelDat(data);
+ if(!worldData)
+ {
+ return false;
+ }
+ auto &val = worldData->at("Data");
+ if(val.get_type() != nbt::tag_type::Compound)
+ {
+ return false;
+ }
+ auto &dataCompound = val.as<nbt::tag_compound>();
+ dataCompound.put("LevelName", nbt::value_initializer(newName.toUtf8().data()));
+ data = serializeLevelDat(worldData.get());
+
+ putLevelDatDataToFS(m_containerFile, data);
+
+ m_actualName = newName;
+
+ QDir parentDir(m_containerFile.absoluteFilePath());
+ parentDir.cdUp();
+ QFile container(m_containerFile.absoluteFilePath());
+ auto dirName = FS::DirNameFromString(m_actualName, parentDir.absolutePath());
+ container.rename(parentDir.absoluteFilePath(dirName));
+
+ return true;
}
static QString read_string (nbt::value& parent, const char * name, const QString & fallback = QString())
{
- try
- {
- auto &namedValue = parent.at(name);
- if(namedValue.get_type() != nbt::tag_type::String)
- {
- return fallback;
- }
- auto & tag_str = namedValue.as<nbt::tag_string>();
- return QString::fromStdString(tag_str.get());
- }
- catch (const std::out_of_range &e)
- {
- // fallback for old world formats
- qWarning() << "String NBT tag" << name << "could not be found. Defaulting to" << fallback;
- return fallback;
- }
- catch (const std::bad_cast &e)
- {
- // type mismatch
- qWarning() << "NBT tag" << name << "could not be converted to string. Defaulting to" << fallback;
- return fallback;
- }
+ try
+ {
+ auto &namedValue = parent.at(name);
+ if(namedValue.get_type() != nbt::tag_type::String)
+ {
+ return fallback;
+ }
+ auto & tag_str = namedValue.as<nbt::tag_string>();
+ return QString::fromStdString(tag_str.get());
+ }
+ catch (const std::out_of_range &e)
+ {
+ // fallback for old world formats
+ qWarning() << "String NBT tag" << name << "could not be found. Defaulting to" << fallback;
+ return fallback;
+ }
+ catch (const std::bad_cast &e)
+ {
+ // type mismatch
+ qWarning() << "NBT tag" << name << "could not be converted to string. Defaulting to" << fallback;
+ return fallback;
+ }
}
static int64_t read_long (nbt::value& parent, const char * name, const int64_t & fallback = 0)
{
- try
- {
- auto &namedValue = parent.at(name);
- if(namedValue.get_type() != nbt::tag_type::Long)
- {
- return fallback;
- }
- auto & tag_str = namedValue.as<nbt::tag_long>();
- return tag_str.get();
- }
- catch (const std::out_of_range &e)
- {
- // fallback for old world formats
- qWarning() << "Long NBT tag" << name << "could not be found. Defaulting to" << fallback;
- return fallback;
- }
- catch (const std::bad_cast &e)
- {
- // type mismatch
- qWarning() << "NBT tag" << name << "could not be converted to long. Defaulting to" << fallback;
- return fallback;
- }
+ try
+ {
+ auto &namedValue = parent.at(name);
+ if(namedValue.get_type() != nbt::tag_type::Long)
+ {
+ return fallback;
+ }
+ auto & tag_str = namedValue.as<nbt::tag_long>();
+ return tag_str.get();
+ }
+ catch (const std::out_of_range &e)
+ {
+ // fallback for old world formats
+ qWarning() << "Long NBT tag" << name << "could not be found. Defaulting to" << fallback;
+ return fallback;
+ }
+ catch (const std::bad_cast &e)
+ {
+ // type mismatch
+ qWarning() << "NBT tag" << name << "could not be converted to long. Defaulting to" << fallback;
+ return fallback;
+ }
}
void World::loadFromLevelDat(QByteArray data)
{
- try
- {
- auto levelData = parseLevelDat(data);
- if(!levelData)
- {
- is_valid = false;
- return;
- }
-
- auto &val = levelData->at("Data");
- is_valid = val.get_type() == nbt::tag_type::Compound;
- if(!is_valid)
- return;
-
- m_actualName = read_string(val, "LevelName", m_folderName);
-
-
- int64_t temp = read_long(val, "LastPlayed", 0);
- if(temp == 0)
- {
- m_lastPlayed = levelDatTime;
- }
- else
- {
- m_lastPlayed = QDateTime::fromMSecsSinceEpoch(temp);
- }
-
- m_randomSeed = read_long(val, "RandomSeed", 0);
-
- qDebug() << "World Name:" << m_actualName;
- qDebug() << "Last Played:" << m_lastPlayed.toString();
- qDebug() << "Seed:" << m_randomSeed;
- }
- catch (const nbt::io::input_error &e)
- {
- qWarning() << "Unable to load" << m_folderName << ":" << e.what();
- is_valid = false;
- return;
- }
+ try
+ {
+ auto levelData = parseLevelDat(data);
+ if(!levelData)
+ {
+ is_valid = false;
+ return;
+ }
+
+ auto &val = levelData->at("Data");
+ is_valid = val.get_type() == nbt::tag_type::Compound;
+ if(!is_valid)
+ return;
+
+ m_actualName = read_string(val, "LevelName", m_folderName);
+
+
+ int64_t temp = read_long(val, "LastPlayed", 0);
+ if(temp == 0)
+ {
+ m_lastPlayed = levelDatTime;
+ }
+ else
+ {
+ m_lastPlayed = QDateTime::fromMSecsSinceEpoch(temp);
+ }
+
+ m_randomSeed = read_long(val, "RandomSeed", 0);
+
+ qDebug() << "World Name:" << m_actualName;
+ qDebug() << "Last Played:" << m_lastPlayed.toString();
+ qDebug() << "Seed:" << m_randomSeed;
+ }
+ catch (const nbt::io::input_error &e)
+ {
+ qWarning() << "Unable to load" << m_folderName << ":" << e.what();
+ is_valid = false;
+ return;
+ }
}
bool World::replace(World &with)
{
- if (!destroy())
- return false;
- bool success = FS::copy(with.m_containerFile.filePath(), m_containerFile.path())();
- if (success)
- {
- m_folderName = with.m_folderName;
- m_containerFile.refresh();
- }
- return success;
+ if (!destroy())
+ return false;
+ bool success = FS::copy(with.m_containerFile.filePath(), m_containerFile.path())();
+ if (success)
+ {
+ m_folderName = with.m_folderName;
+ m_containerFile.refresh();
+ }
+ return success;
}
bool World::destroy()
{
- if(!is_valid) return false;
- if (m_containerFile.isDir())
- {
- QDir d(m_containerFile.filePath());
- return d.removeRecursively();
- }
- else if(m_containerFile.isFile())
- {
- QFile file(m_containerFile.absoluteFilePath());
- return file.remove();
- }
- return true;
+ if(!is_valid) return false;
+ if (m_containerFile.isDir())
+ {
+ QDir d(m_containerFile.filePath());
+ return d.removeRecursively();
+ }
+ else if(m_containerFile.isFile())
+ {
+ QFile file(m_containerFile.absoluteFilePath());
+ return file.remove();
+ }
+ return true;
}
bool World::operator==(const World &other) const
{
- return is_valid == other.is_valid && folderName() == other.folderName();
+ return is_valid == other.is_valid && folderName() == other.folderName();
}
bool World::strongCompare(const World &other) const
{
- return is_valid == other.is_valid && folderName() == other.folderName();
+ return is_valid == other.is_valid && folderName() == other.folderName();
}
diff --git a/api/logic/minecraft/World.h b/api/logic/minecraft/World.h
index 7087bf48..2cce85a2 100644
--- a/api/logic/minecraft/World.h
+++ b/api/logic/minecraft/World.h
@@ -22,62 +22,62 @@
class MULTIMC_LOGIC_EXPORT World
{
public:
- World(const QFileInfo &file);
- QString folderName() const
- {
- return m_folderName;
- }
- QString name() const
- {
- return m_actualName;
- }
- QDateTime lastPlayed() const
- {
- return m_lastPlayed;
- }
- int64_t seed() const
- {
- return m_randomSeed;
- }
- bool isValid() const
- {
- return is_valid;
- }
- bool isOnFS() const
- {
- return m_containerFile.isDir();
- }
- QFileInfo container() const
- {
- return m_containerFile;
- }
- // delete all the files of this world
- bool destroy();
- // replace this world with a copy of the other
- bool replace(World &with);
- // change the world's filesystem path (used by world lists for *MAGIC* purposes)
- void repath(const QFileInfo &file);
+ World(const QFileInfo &file);
+ QString folderName() const
+ {
+ return m_folderName;
+ }
+ QString name() const
+ {
+ return m_actualName;
+ }
+ QDateTime lastPlayed() const
+ {
+ return m_lastPlayed;
+ }
+ int64_t seed() const
+ {
+ return m_randomSeed;
+ }
+ bool isValid() const
+ {
+ return is_valid;
+ }
+ bool isOnFS() const
+ {
+ return m_containerFile.isDir();
+ }
+ QFileInfo container() const
+ {
+ return m_containerFile;
+ }
+ // delete all the files of this world
+ bool destroy();
+ // replace this world with a copy of the other
+ bool replace(World &with);
+ // change the world's filesystem path (used by world lists for *MAGIC* purposes)
+ void repath(const QFileInfo &file);
- bool rename(const QString &to);
- bool install(const QString &to, const QString &name= QString());
+ bool rename(const QString &to);
+ bool install(const QString &to, const QString &name= QString());
- // WEAK compare operator - used for replacing worlds
- bool operator==(const World &other) const;
- bool strongCompare(const World &other) const;
+ // WEAK compare operator - used for replacing worlds
+ bool operator==(const World &other) const;
+ bool strongCompare(const World &other) const;
private:
- void readFromZip(const QFileInfo &file);
- void readFromFS(const QFileInfo &file);
- void loadFromLevelDat(QByteArray data);
+ void readFromZip(const QFileInfo &file);
+ void readFromFS(const QFileInfo &file);
+ void loadFromLevelDat(QByteArray data);
protected:
- QFileInfo m_containerFile;
- QString m_containerOffsetPath;
- QString m_folderName;
- QString m_actualName;
- QDateTime levelDatTime;
- QDateTime m_lastPlayed;
- int64_t m_randomSeed = 0;
- bool is_valid = false;
+ QFileInfo m_containerFile;
+ QString m_containerOffsetPath;
+ QString m_folderName;
+ QString m_actualName;
+ QDateTime levelDatTime;
+ QDateTime m_lastPlayed;
+ int64_t m_randomSeed = 0;
+ bool is_valid = false;
};
diff --git a/api/logic/minecraft/WorldList.cpp b/api/logic/minecraft/WorldList.cpp
index 4278c2f7..79a5bf38 100644
--- a/api/logic/minecraft/WorldList.cpp
+++ b/api/logic/minecraft/WorldList.cpp
@@ -23,216 +23,216 @@
#include <QDebug>
WorldList::WorldList(const QString &dir)
- : QAbstractListModel(), m_dir(dir)
+ : QAbstractListModel(), m_dir(dir)
{
- FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
- QDir::NoSymLinks);
- m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
- m_watcher = new QFileSystemWatcher(this);
- is_watching = false;
- connect(m_watcher, SIGNAL(directoryChanged(QString)), this,
- SLOT(directoryChanged(QString)));
+ FS::ensureFolderPathExists(m_dir.absolutePath());
+ m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
+ QDir::NoSymLinks);
+ m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
+ m_watcher = new QFileSystemWatcher(this);
+ is_watching = false;
+ connect(m_watcher, SIGNAL(directoryChanged(QString)), this,
+ SLOT(directoryChanged(QString)));
}
void WorldList::startWatching()
{
- if(is_watching)
- {
- return;
- }
- update();
- is_watching = m_watcher->addPath(m_dir.absolutePath());
- if (is_watching)
- {
- qDebug() << "Started watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to start watching " << m_dir.absolutePath();
- }
+ if(is_watching)
+ {
+ return;
+ }
+ update();
+ is_watching = m_watcher->addPath(m_dir.absolutePath());
+ if (is_watching)
+ {
+ qDebug() << "Started watching " << m_dir.absolutePath();
+ }
+ else
+ {
+ qDebug() << "Failed to start watching " << m_dir.absolutePath();
+ }
}
void WorldList::stopWatching()
{
- if(!is_watching)
- {
- return;
- }
- is_watching = !m_watcher->removePath(m_dir.absolutePath());
- if (!is_watching)
- {
- qDebug() << "Stopped watching " << m_dir.absolutePath();
- }
- else
- {
- qDebug() << "Failed to stop watching " << m_dir.absolutePath();
- }
+ if(!is_watching)
+ {
+ return;
+ }
+ is_watching = !m_watcher->removePath(m_dir.absolutePath());
+ if (!is_watching)
+ {
+ qDebug() << "Stopped watching " << m_dir.absolutePath();
+ }
+ else
+ {
+ qDebug() << "Failed to stop watching " << m_dir.absolutePath();
+ }
}
bool WorldList::update()
{
- if (!isValid())
- return false;
-
- QList<World> newWorlds;
- m_dir.refresh();
- auto folderContents = m_dir.entryInfoList();
- // if there are any untracked files...
- for (QFileInfo entry : folderContents)
- {
- if(!entry.isDir())
- continue;
-
- World w(entry);
- if(w.isValid())
- {
- newWorlds.append(w);
- }
- }
- beginResetModel();
- worlds.swap(newWorlds);
- endResetModel();
- return true;
+ if (!isValid())
+ return false;
+
+ QList<World> newWorlds;
+ m_dir.refresh();
+ auto folderContents = m_dir.entryInfoList();
+ // if there are any untracked files...
+ for (QFileInfo entry : folderContents)
+ {
+ if(!entry.isDir())
+ continue;
+
+ World w(entry);
+ if(w.isValid())
+ {
+ newWorlds.append(w);
+ }
+ }
+ beginResetModel();
+ worlds.swap(newWorlds);
+ endResetModel();
+ return true;
}
void WorldList::directoryChanged(QString path)
{
- update();
+ update();
}
bool WorldList::isValid()
{
- return m_dir.exists() && m_dir.isReadable();
+ return m_dir.exists() && m_dir.isReadable();
}
bool WorldList::deleteWorld(int index)
{
- if (index >= worlds.size() || index < 0)
- return false;
- World &m = worlds[index];
- if (m.destroy())
- {
- beginRemoveRows(QModelIndex(), index, index);
- worlds.removeAt(index);
- endRemoveRows();
- emit changed();
- return true;
- }
- return false;
+ if (index >= worlds.size() || index < 0)
+ return false;
+ World &m = worlds[index];
+ if (m.destroy())
+ {
+ beginRemoveRows(QModelIndex(), index, index);
+ worlds.removeAt(index);
+ endRemoveRows();
+ emit changed();
+ return true;
+ }
+ return false;
}
bool WorldList::deleteWorlds(int first, int last)
{
- for (int i = first; i <= last; i++)
- {
- World &m = worlds[i];
- m.destroy();
- }
- beginRemoveRows(QModelIndex(), first, last);
- worlds.erase(worlds.begin() + first, worlds.begin() + last + 1);
- endRemoveRows();
- emit changed();
- return true;
+ for (int i = first; i <= last; i++)
+ {
+ World &m = worlds[i];
+ m.destroy();
+ }
+ beginRemoveRows(QModelIndex(), first, last);
+ worlds.erase(worlds.begin() + first, worlds.begin() + last + 1);
+ endRemoveRows();
+ emit changed();
+ return true;
}
int WorldList::columnCount(const QModelIndex &parent) const
{
- return 2;
+ return 2;
}
QVariant WorldList::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
-
- if (row < 0 || row >= worlds.size())
- return QVariant();
-
- auto & world = worlds[row];
- switch (role)
- {
- case Qt::DisplayRole:
- switch (column)
- {
- case NameColumn:
- return world.name();
-
- case LastPlayedColumn:
- return world.lastPlayed();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- {
- return world.folderName();
- }
- case ObjectRole:
- {
- return QVariant::fromValue<void *>((void *)&world);
- }
- case FolderRole:
- {
- return QDir::toNativeSeparators(dir().absoluteFilePath(world.folderName()));
- }
- case SeedRole:
- {
- return qVariantFromValue<qlonglong>(world.seed());
- }
- case NameRole:
- {
- return world.name();
- }
- case LastPlayedRole:
- {
- return world.lastPlayed();
- }
- default:
- return QVariant();
- }
+ if (!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+ int column = index.column();
+
+ if (row < 0 || row >= worlds.size())
+ return QVariant();
+
+ auto & world = worlds[row];
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (column)
+ {
+ case NameColumn:
+ return world.name();
+
+ case LastPlayedColumn:
+ return world.lastPlayed();
+
+ default:
+ return QVariant();
+ }
+
+ case Qt::ToolTipRole:
+ {
+ return world.folderName();
+ }
+ case ObjectRole:
+ {
+ return QVariant::fromValue<void *>((void *)&world);
+ }
+ case FolderRole:
+ {
+ return QDir::toNativeSeparators(dir().absoluteFilePath(world.folderName()));
+ }
+ case SeedRole:
+ {
+ return qVariantFromValue<qlonglong>(world.seed());
+ }
+ case NameRole:
+ {
+ return world.name();
+ }
+ case LastPlayedRole:
+ {
+ return world.lastPlayed();
+ }
+ default:
+ return QVariant();
+ }
}
QVariant WorldList::headerData(int section, Qt::Orientation orientation, int role) const
{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case NameColumn:
- return tr("Name");
- case LastPlayedColumn:
- return tr("Last Played");
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case NameColumn:
- return tr("The name of the world.");
- case LastPlayedColumn:
- return tr("Date and time the world was last played.");
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
- return QVariant();
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (section)
+ {
+ case NameColumn:
+ return tr("Name");
+ case LastPlayedColumn:
+ return tr("Last Played");
+ default:
+ return QVariant();
+ }
+
+ case Qt::ToolTipRole:
+ switch (section)
+ {
+ case NameColumn:
+ return tr("The name of the world.");
+ case LastPlayedColumn:
+ return tr("Date and time the world was last played.");
+ default:
+ return QVariant();
+ }
+ default:
+ return QVariant();
+ }
+ return QVariant();
}
QStringList WorldList::mimeTypes() const
{
- QStringList types;
- types << "text/uri-list";
- return types;
+ QStringList types;
+ types << "text/uri-list";
+ return types;
}
class WorldMimeData : public QMimeData
@@ -240,124 +240,124 @@ class WorldMimeData : public QMimeData
Q_OBJECT
public:
- WorldMimeData(QList<World> worlds)
- {
- m_worlds = worlds;
+ WorldMimeData(QList<World> worlds)
+ {
+ m_worlds = worlds;
- }
- QStringList formats() const
- {
- return QMimeData::formats() << "text/uri-list";
- }
+ }
+ QStringList formats() const
+ {
+ return QMimeData::formats() << "text/uri-list";
+ }
protected:
- QVariant retrieveData(const QString &mimetype, QVariant::Type type) const
- {
- QList<QUrl> urls;
- for(auto &world: m_worlds)
- {
- if(!world.isValid() || !world.isOnFS())
- continue;
- QString worldPath = world.container().absoluteFilePath();
- qDebug() << worldPath;
- urls.append(QUrl::fromLocalFile(worldPath));
- }
- const_cast<WorldMimeData*>(this)->setUrls(urls);
- return QMimeData::retrieveData(mimetype, type);
- }
+ QVariant retrieveData(const QString &mimetype, QVariant::Type type) const
+ {
+ QList<QUrl> urls;
+ for(auto &world: m_worlds)
+ {
+ if(!world.isValid() || !world.isOnFS())
+ continue;
+ QString worldPath = world.container().absoluteFilePath();
+ qDebug() << worldPath;
+ urls.append(QUrl::fromLocalFile(worldPath));
+ }
+ const_cast<WorldMimeData*>(this)->setUrls(urls);
+ return QMimeData::retrieveData(mimetype, type);
+ }
private:
- QList<World> m_worlds;
+ QList<World> m_worlds;
};
QMimeData *WorldList::mimeData(const QModelIndexList &indexes) const
{
- if (indexes.size() == 0)
- return new QMimeData();
-
- QList<World> worlds;
- for(auto idx : indexes)
- {
- if(idx.column() != 0)
- continue;
- int row = idx.row();
- if (row < 0 || row >= this->worlds.size())
- continue;
- worlds.append(this->worlds[row]);
- }
- if(!worlds.size())
- {
- return new QMimeData();
- }
- return new WorldMimeData(worlds);
+ if (indexes.size() == 0)
+ return new QMimeData();
+
+ QList<World> worlds;
+ for(auto idx : indexes)
+ {
+ if(idx.column() != 0)
+ continue;
+ int row = idx.row();
+ if (row < 0 || row >= this->worlds.size())
+ continue;
+ worlds.append(this->worlds[row]);
+ }
+ if(!worlds.size())
+ {
+ return new QMimeData();
+ }
+ return new WorldMimeData(worlds);
}
Qt::ItemFlags WorldList::flags(const QModelIndex &index) const
{
- Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
- if (index.isValid())
- return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled |
- defaultFlags;
- else
- return Qt::ItemIsDropEnabled | defaultFlags;
+ Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
+ if (index.isValid())
+ return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled |
+ defaultFlags;
+ else
+ return Qt::ItemIsDropEnabled | defaultFlags;
}
Qt::DropActions WorldList::supportedDragActions() const
{
- // move to other mod lists or VOID
- return Qt::MoveAction;
+ // move to other mod lists or VOID
+ return Qt::MoveAction;
}
Qt::DropActions WorldList::supportedDropActions() const
{
- // copy from outside, move from within and other mod lists
- return Qt::CopyAction | Qt::MoveAction;
+ // copy from outside, move from within and other mod lists
+ return Qt::CopyAction | Qt::MoveAction;
}
void WorldList::installWorld(QFileInfo filename)
{
- qDebug() << "installing: " << filename.absoluteFilePath();
- World w(filename);
- if(!w.isValid())
- {
- return;
- }
- w.install(m_dir.absolutePath());
+ qDebug() << "installing: " << filename.absoluteFilePath();
+ World w(filename);
+ if(!w.isValid())
+ {
+ return;
+ }
+ w.install(m_dir.absolutePath());
}
bool WorldList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
- const QModelIndex &parent)
+ const QModelIndex &parent)
{
- if (action == Qt::IgnoreAction)
- return true;
- // check if the action is supported
- if (!data || !(action & supportedDropActions()))
- return false;
- // files dropped from outside?
- if (data->hasUrls())
- {
- bool was_watching = is_watching;
- if (was_watching)
- stopWatching();
- auto urls = data->urls();
- for (auto url : urls)
- {
- // only local files may be dropped...
- if (!url.isLocalFile())
- continue;
- QString filename = url.toLocalFile();
-
- QFileInfo worldInfo(filename);
-
- if(!m_dir.entryInfoList().contains(worldInfo))
- {
- installWorld(worldInfo);
- }
- }
- if (was_watching)
- startWatching();
- return true;
- }
- return false;
+ if (action == Qt::IgnoreAction)
+ return true;
+ // check if the action is supported
+ if (!data || !(action & supportedDropActions()))
+ return false;
+ // files dropped from outside?
+ if (data->hasUrls())
+ {
+ bool was_watching = is_watching;
+ if (was_watching)
+ stopWatching();
+ auto urls = data->urls();
+ for (auto url : urls)
+ {
+ // only local files may be dropped...
+ if (!url.isLocalFile())
+ continue;
+ QString filename = url.toLocalFile();
+
+ QFileInfo worldInfo(filename);
+
+ if(!m_dir.entryInfoList().contains(worldInfo))
+ {
+ installWorld(worldInfo);
+ }
+ }
+ if (was_watching)
+ startWatching();
+ return true;
+ }
+ return false;
}
#include "WorldList.moc"
diff --git a/api/logic/minecraft/WorldList.h b/api/logic/minecraft/WorldList.h
index 811393cd..a1cd8f51 100644
--- a/api/logic/minecraft/WorldList.h
+++ b/api/logic/minecraft/WorldList.h
@@ -28,98 +28,98 @@ class QFileSystemWatcher;
class MULTIMC_LOGIC_EXPORT WorldList : public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum Columns
- {
- NameColumn,
- LastPlayedColumn
- };
-
- enum Roles
- {
- ObjectRole = Qt::UserRole + 1,
- FolderRole,
- SeedRole,
- NameRole,
- LastPlayedRole
- };
-
- WorldList(const QString &dir);
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
-
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
- {
- return size();
- };
- virtual QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- virtual int columnCount(const QModelIndex &parent) const;
-
- size_t size() const
- {
- return worlds.size();
- };
- bool empty() const
- {
- return size() == 0;
- }
- World &operator[](size_t index)
- {
- return worlds[index];
- }
-
- /// Reloads the mod list and returns true if the list changed.
- virtual bool update();
-
- /// Install a world from location
- void installWorld(QFileInfo filename);
-
- /// Deletes the mod at the given index.
- virtual bool deleteWorld(int index);
-
- /// Deletes all the selected mods
- virtual bool deleteWorlds(int first, int last);
-
- /// flags, mostly to support drag&drop
- virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- /// get data for drag action
- virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
- /// get the supported mime types
- virtual QStringList mimeTypes() const;
- /// process data from drop action
- virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
- /// what drag actions do we support?
- virtual Qt::DropActions supportedDragActions() const;
-
- /// what drop actions do we support?
- virtual Qt::DropActions supportedDropActions() const;
-
- void startWatching();
- void stopWatching();
-
- virtual bool isValid();
-
- QDir dir() const
- {
- return m_dir;
- }
-
- const QList<World> &allWorlds() const
- {
- return worlds;
- }
+ enum Columns
+ {
+ NameColumn,
+ LastPlayedColumn
+ };
+
+ enum Roles
+ {
+ ObjectRole = Qt::UserRole + 1,
+ FolderRole,
+ SeedRole,
+ NameRole,
+ LastPlayedRole
+ };
+
+ WorldList(const QString &dir);
+
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
+ {
+ return size();
+ };
+ virtual QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+ virtual int columnCount(const QModelIndex &parent) const;
+
+ size_t size() const
+ {
+ return worlds.size();
+ };
+ bool empty() const
+ {
+ return size() == 0;
+ }
+ World &operator[](size_t index)
+ {
+ return worlds[index];
+ }
+
+ /// Reloads the mod list and returns true if the list changed.
+ virtual bool update();
+
+ /// Install a world from location
+ void installWorld(QFileInfo filename);
+
+ /// Deletes the mod at the given index.
+ virtual bool deleteWorld(int index);
+
+ /// Deletes all the selected mods
+ virtual bool deleteWorlds(int first, int last);
+
+ /// flags, mostly to support drag&drop
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+ /// get data for drag action
+ virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
+ /// get the supported mime types
+ virtual QStringList mimeTypes() const;
+ /// process data from drop action
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+ /// what drag actions do we support?
+ virtual Qt::DropActions supportedDragActions() const;
+
+ /// what drop actions do we support?
+ virtual Qt::DropActions supportedDropActions() const;
+
+ void startWatching();
+ void stopWatching();
+
+ virtual bool isValid();
+
+ QDir dir() const
+ {
+ return m_dir;
+ }
+
+ const QList<World> &allWorlds() const
+ {
+ return worlds;
+ }
private slots:
- void directoryChanged(QString path);
+ void directoryChanged(QString path);
signals:
- void changed();
+ void changed();
protected:
- QFileSystemWatcher *m_watcher;
- bool is_watching;
- QDir m_dir;
- QList<World> worlds;
+ QFileSystemWatcher *m_watcher;
+ bool is_watching;
+ QDir m_dir;
+ QList<World> worlds;
};
diff --git a/api/logic/minecraft/auth/AuthSession.cpp b/api/logic/minecraft/auth/AuthSession.cpp
index 8758bfbd..4e858796 100644
--- a/api/logic/minecraft/auth/AuthSession.cpp
+++ b/api/logic/minecraft/auth/AuthSession.cpp
@@ -6,25 +6,25 @@
QString AuthSession::serializeUserProperties()
{
- QJsonObject userAttrs;
- for (auto key : u.properties.keys())
- {
- auto array = QJsonArray::fromStringList(u.properties.values(key));
- userAttrs.insert(key, array);
- }
- QJsonDocument value(userAttrs);
- return value.toJson(QJsonDocument::Compact);
+ QJsonObject userAttrs;
+ for (auto key : u.properties.keys())
+ {
+ auto array = QJsonArray::fromStringList(u.properties.values(key));
+ userAttrs.insert(key, array);
+ }
+ QJsonDocument value(userAttrs);
+ return value.toJson(QJsonDocument::Compact);
}
bool AuthSession::MakeOffline(QString offline_playername)
{
- if (status != PlayableOffline && status != PlayableOnline)
- {
- return false;
- }
- session = "-";
- player_name = offline_playername;
- status = PlayableOffline;
- return true;
+ if (status != PlayableOffline && status != PlayableOnline)
+ {
+ return false;
+ }
+ session = "-";
+ player_name = offline_playername;
+ status = PlayableOffline;
+ return true;
}
diff --git a/api/logic/minecraft/auth/AuthSession.h b/api/logic/minecraft/auth/AuthSession.h
index d2f66db8..b397d9a1 100644
--- a/api/logic/minecraft/auth/AuthSession.h
+++ b/api/logic/minecraft/auth/AuthSession.h
@@ -10,45 +10,45 @@ class MojangAccount;
struct User
{
- QString id;
- QMultiMap<QString, QString> properties;
+ QString id;
+ QMultiMap<QString, QString> properties;
};
struct MULTIMC_LOGIC_EXPORT AuthSession
{
- bool MakeOffline(QString offline_playername);
-
- QString serializeUserProperties();
-
- enum Status
- {
- Undetermined,
- RequiresPassword,
- PlayableOffline,
- PlayableOnline
- } status = Undetermined;
-
- User u;
-
- // client token
- QString client_token;
- // account user name
- QString username;
- // combined session ID
- QString session;
- // volatile auth token
- QString access_token;
- // profile name
- QString player_name;
- // profile ID
- QString uuid;
- // 'legacy' or 'mojang', depending on account type
- QString user_type;
- // Did the auth server reply?
- bool auth_server_online = false;
- // Did the user request online mode?
- bool wants_online = true;
- std::shared_ptr<MojangAccount> m_accountPtr;
+ bool MakeOffline(QString offline_playername);
+
+ QString serializeUserProperties();
+
+ enum Status
+ {
+ Undetermined,
+ RequiresPassword,
+ PlayableOffline,
+ PlayableOnline
+ } status = Undetermined;
+
+ User u;
+
+ // client token
+ QString client_token;
+ // account user name
+ QString username;
+ // combined session ID
+ QString session;
+ // volatile auth token
+ QString access_token;
+ // profile name
+ QString player_name;
+ // profile ID
+ QString uuid;
+ // 'legacy' or 'mojang', depending on account type
+ QString user_type;
+ // Did the auth server reply?
+ bool auth_server_online = false;
+ // Did the user request online mode?
+ bool wants_online = true;
+ std::shared_ptr<MojangAccount> m_accountPtr;
};
typedef std::shared_ptr<AuthSession> AuthSessionPtr;
diff --git a/api/logic/minecraft/auth/MojangAccount.cpp b/api/logic/minecraft/auth/MojangAccount.cpp
index edad4344..edf1e4e3 100644
--- a/api/logic/minecraft/auth/MojangAccount.cpp
+++ b/api/logic/minecraft/auth/MojangAccount.cpp
@@ -30,286 +30,286 @@
MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject &object)
{
- // The JSON object must at least have a username for it to be valid.
- if (!object.value("username").isString())
- {
- qCritical() << "Can't load Mojang account info from JSON object. Username field is "
- "missing or of the wrong type.";
- return nullptr;
- }
+ // The JSON object must at least have a username for it to be valid.
+ if (!object.value("username").isString())
+ {
+ qCritical() << "Can't load Mojang account info from JSON object. Username field is "
+ "missing or of the wrong type.";
+ return nullptr;
+ }
- QString username = object.value("username").toString("");
- QString clientToken = object.value("clientToken").toString("");
- QString accessToken = object.value("accessToken").toString("");
+ QString username = object.value("username").toString("");
+ QString clientToken = object.value("clientToken").toString("");
+ QString accessToken = object.value("accessToken").toString("");
- QJsonArray profileArray = object.value("profiles").toArray();
- if (profileArray.size() < 1)
- {
- qCritical() << "Can't load Mojang account with username \"" << username
- << "\". No profiles found.";
- return nullptr;
- }
+ QJsonArray profileArray = object.value("profiles").toArray();
+ if (profileArray.size() < 1)
+ {
+ qCritical() << "Can't load Mojang account with username \"" << username
+ << "\". No profiles found.";
+ return nullptr;
+ }
- QList<AccountProfile> profiles;
- for (QJsonValue profileVal : profileArray)
- {
- QJsonObject profileObject = profileVal.toObject();
- QString id = profileObject.value("id").toString("");
- QString name = profileObject.value("name").toString("");
- bool legacy = profileObject.value("legacy").toBool(false);
- if (id.isEmpty() || name.isEmpty())
- {
- qWarning() << "Unable to load a profile because it was missing an ID or a name.";
- continue;
- }
- profiles.append({id, name, legacy});
- }
+ QList<AccountProfile> profiles;
+ for (QJsonValue profileVal : profileArray)
+ {
+ QJsonObject profileObject = profileVal.toObject();
+ QString id = profileObject.value("id").toString("");
+ QString name = profileObject.value("name").toString("");
+ bool legacy = profileObject.value("legacy").toBool(false);
+ if (id.isEmpty() || name.isEmpty())
+ {
+ qWarning() << "Unable to load a profile because it was missing an ID or a name.";
+ continue;
+ }
+ profiles.append({id, name, legacy});
+ }
- MojangAccountPtr account(new MojangAccount());
- if (object.value("user").isObject())
- {
- User u;
- QJsonObject userStructure = object.value("user").toObject();
- u.id = userStructure.value("id").toString();
- /*
- QJsonObject propMap = userStructure.value("properties").toObject();
- for(auto key: propMap.keys())
- {
- auto values = propMap.operator[](key).toArray();
- for(auto value: values)
- u.properties.insert(key, value.toString());
- }
- */
- account->m_user = u;
- }
- account->m_username = username;
- account->m_clientToken = clientToken;
- account->m_accessToken = accessToken;
- account->m_profiles = profiles;
+ MojangAccountPtr account(new MojangAccount());
+ if (object.value("user").isObject())
+ {
+ User u;
+ QJsonObject userStructure = object.value("user").toObject();
+ u.id = userStructure.value("id").toString();
+ /*
+ QJsonObject propMap = userStructure.value("properties").toObject();
+ for(auto key: propMap.keys())
+ {
+ auto values = propMap.operator[](key).toArray();
+ for(auto value: values)
+ u.properties.insert(key, value.toString());
+ }
+ */
+ account->m_user = u;
+ }
+ account->m_username = username;
+ account->m_clientToken = clientToken;
+ account->m_accessToken = accessToken;
+ account->m_profiles = profiles;
- // Get the currently selected profile.
- QString currentProfile = object.value("activeProfile").toString("");
- if (!currentProfile.isEmpty())
- account->setCurrentProfile(currentProfile);
+ // Get the currently selected profile.
+ QString currentProfile = object.value("activeProfile").toString("");
+ if (!currentProfile.isEmpty())
+ account->setCurrentProfile(currentProfile);
- return account;
+ return account;
}
MojangAccountPtr MojangAccount::createFromUsername(const QString &username)
{
- MojangAccountPtr account(new MojangAccount());
- account->m_clientToken = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
- account->m_username = username;
- return account;
+ MojangAccountPtr account(new MojangAccount());
+ account->m_clientToken = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
+ account->m_username = username;
+ return account;
}
QJsonObject MojangAccount::saveToJson() const
{
- QJsonObject json;
- json.insert("username", m_username);
- json.insert("clientToken", m_clientToken);
- json.insert("accessToken", m_accessToken);
+ QJsonObject json;
+ json.insert("username", m_username);
+ json.insert("clientToken", m_clientToken);
+ json.insert("accessToken", m_accessToken);
- QJsonArray profileArray;
- for (AccountProfile profile : m_profiles)
- {
- QJsonObject profileObj;
- profileObj.insert("id", profile.id);
- profileObj.insert("name", profile.name);
- profileObj.insert("legacy", profile.legacy);
- profileArray.append(profileObj);
- }
- json.insert("profiles", profileArray);
+ QJsonArray profileArray;
+ for (AccountProfile profile : m_profiles)
+ {
+ QJsonObject profileObj;
+ profileObj.insert("id", profile.id);
+ profileObj.insert("name", profile.name);
+ profileObj.insert("legacy", profile.legacy);
+ profileArray.append(profileObj);
+ }
+ json.insert("profiles", profileArray);
- QJsonObject userStructure;
- {
- userStructure.insert("id", m_user.id);
- /*
- QJsonObject userAttrs;
- for(auto key: m_user.properties.keys())
- {
- auto array = QJsonArray::fromStringList(m_user.properties.values(key));
- userAttrs.insert(key, array);
- }
- userStructure.insert("properties", userAttrs);
- */
- }
- json.insert("user", userStructure);
+ QJsonObject userStructure;
+ {
+ userStructure.insert("id", m_user.id);
+ /*
+ QJsonObject userAttrs;
+ for(auto key: m_user.properties.keys())
+ {
+ auto array = QJsonArray::fromStringList(m_user.properties.values(key));
+ userAttrs.insert(key, array);
+ }
+ userStructure.insert("properties", userAttrs);
+ */
+ }
+ json.insert("user", userStructure);
- if (m_currentProfile != -1)
- json.insert("activeProfile", currentProfile()->id);
+ if (m_currentProfile != -1)
+ json.insert("activeProfile", currentProfile()->id);
- return json;
+ return json;
}
bool MojangAccount::setCurrentProfile(const QString &profileId)
{
- for (int i = 0; i < m_profiles.length(); i++)
- {
- if (m_profiles[i].id == profileId)
- {
- m_currentProfile = i;
- return true;
- }
- }
- return false;
+ for (int i = 0; i < m_profiles.length(); i++)
+ {
+ if (m_profiles[i].id == profileId)
+ {
+ m_currentProfile = i;
+ return true;
+ }
+ }
+ return false;
}
const AccountProfile *MojangAccount::currentProfile() const
{
- if (m_currentProfile == -1)
- return nullptr;
- return &m_profiles[m_currentProfile];
+ if (m_currentProfile == -1)
+ return nullptr;
+ return &m_profiles[m_currentProfile];
}
AccountStatus MojangAccount::accountStatus() const
{
- if (m_accessToken.isEmpty())
- return NotVerified;
- else
- return Verified;
+ if (m_accessToken.isEmpty())
+ return NotVerified;
+ else
+ return Verified;
}
std::shared_ptr<YggdrasilTask> MojangAccount::login(AuthSessionPtr session, QString password)
{
- Q_ASSERT(m_currentTask.get() == nullptr);
+ Q_ASSERT(m_currentTask.get() == nullptr);
- // take care of the true offline status
- if (accountStatus() == NotVerified && password.isEmpty())
- {
- if (session)
- {
- session->status = AuthSession::RequiresPassword;
- fillSession(session);
- }
- return nullptr;
- }
+ // take care of the true offline status
+ if (accountStatus() == NotVerified && password.isEmpty())
+ {
+ if (session)
+ {
+ session->status = AuthSession::RequiresPassword;
+ fillSession(session);
+ }
+ return nullptr;
+ }
- if(accountStatus() == Verified && !session->wants_online)
- {
- session->status = AuthSession::PlayableOffline;
- session->auth_server_online = false;
- fillSession(session);
- return nullptr;
- }
- else
- {
- if (password.isEmpty())
- {
- m_currentTask.reset(new RefreshTask(this));
- }
- else
- {
- m_currentTask.reset(new AuthenticateTask(this, password));
- }
- m_currentTask->assignSession(session);
+ if(accountStatus() == Verified && !session->wants_online)
+ {
+ session->status = AuthSession::PlayableOffline;
+ session->auth_server_online = false;
+ fillSession(session);
+ return nullptr;
+ }
+ else
+ {
+ if (password.isEmpty())
+ {
+ m_currentTask.reset(new RefreshTask(this));
+ }
+ else
+ {
+ m_currentTask.reset(new AuthenticateTask(this, password));
+ }
+ m_currentTask->assignSession(session);
- connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
- connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
- }
- return m_currentTask;
+ connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
+ connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
+ }
+ return m_currentTask;
}
void MojangAccount::authSucceeded()
{
- auto session = m_currentTask->getAssignedSession();
- if (session)
- {
- session->status =
- session->wants_online ? AuthSession::PlayableOnline : AuthSession::PlayableOffline;
- fillSession(session);
- session->auth_server_online = true;
- }
- m_currentTask.reset();
- emit changed();
+ auto session = m_currentTask->getAssignedSession();
+ if (session)
+ {
+ session->status =
+ session->wants_online ? AuthSession::PlayableOnline : AuthSession::PlayableOffline;
+ fillSession(session);
+ session->auth_server_online = true;
+ }
+ m_currentTask.reset();
+ emit changed();
}
void MojangAccount::authFailed(QString reason)
{
- auto session = m_currentTask->getAssignedSession();
- // This is emitted when the yggdrasil tasks time out or are cancelled.
- // -> we treat the error as no-op
- if (m_currentTask->state() == YggdrasilTask::STATE_FAILED_SOFT)
- {
- if (session)
- {
- session->status = accountStatus() == Verified ? AuthSession::PlayableOffline
- : AuthSession::RequiresPassword;
- session->auth_server_online = false;
- fillSession(session);
- }
- }
- else
- {
- m_accessToken = QString();
- emit changed();
- if (session)
- {
- session->status = AuthSession::RequiresPassword;
- session->auth_server_online = true;
- fillSession(session);
- }
- }
- m_currentTask.reset();
+ auto session = m_currentTask->getAssignedSession();
+ // This is emitted when the yggdrasil tasks time out or are cancelled.
+ // -> we treat the error as no-op
+ if (m_currentTask->state() == YggdrasilTask::STATE_FAILED_SOFT)
+ {
+ if (session)
+ {
+ session->status = accountStatus() == Verified ? AuthSession::PlayableOffline
+ : AuthSession::RequiresPassword;
+ session->auth_server_online = false;
+ fillSession(session);
+ }
+ }
+ else
+ {
+ m_accessToken = QString();
+ emit changed();
+ if (session)
+ {
+ session->status = AuthSession::RequiresPassword;
+ session->auth_server_online = true;
+ fillSession(session);
+ }
+ }
+ m_currentTask.reset();
}
void MojangAccount::fillSession(AuthSessionPtr session)
{
- // the user name. you have to have an user name
- session->username = m_username;
- // volatile auth token
- session->access_token = m_accessToken;
- // the semi-permanent client token
- session->client_token = m_clientToken;
- if (currentProfile())
- {
- // profile name
- session->player_name = currentProfile()->name;
- // profile ID
- session->uuid = currentProfile()->id;
- // 'legacy' or 'mojang', depending on account type
- session->user_type = currentProfile()->legacy ? "legacy" : "mojang";
- if (!session->access_token.isEmpty())
- {
- session->session = "token:" + m_accessToken + ":" + m_profiles[m_currentProfile].id;
- }
- else
- {
- session->session = "-";
- }
- }
- else
- {
- session->player_name = "Player";
- session->session = "-";
- }
- session->u = user();
- session->m_accountPtr = shared_from_this();
+ // the user name. you have to have an user name
+ session->username = m_username;
+ // volatile auth token
+ session->access_token = m_accessToken;
+ // the semi-permanent client token
+ session->client_token = m_clientToken;
+ if (currentProfile())
+ {
+ // profile name
+ session->player_name = currentProfile()->name;
+ // profile ID
+ session->uuid = currentProfile()->id;
+ // 'legacy' or 'mojang', depending on account type
+ session->user_type = currentProfile()->legacy ? "legacy" : "mojang";
+ if (!session->access_token.isEmpty())
+ {
+ session->session = "token:" + m_accessToken + ":" + m_profiles[m_currentProfile].id;
+ }
+ else
+ {
+ session->session = "-";
+ }
+ }
+ else
+ {
+ session->player_name = "Player";
+ session->session = "-";
+ }
+ session->u = user();
+ session->m_accountPtr = shared_from_this();
}
void MojangAccount::decrementUses()
{
- Usable::decrementUses();
- if(!isInUse())
- {
- emit changed();
- qWarning() << "Account" << m_username << "is no longer in use.";
- }
+ Usable::decrementUses();
+ if(!isInUse())
+ {
+ emit changed();
+ qWarning() << "Account" << m_username << "is no longer in use.";
+ }
}
void MojangAccount::incrementUses()
{
- bool wasInUse = isInUse();
- Usable::incrementUses();
- if(!wasInUse)
- {
- emit changed();
- qWarning() << "Account" << m_username << "is now in use.";
- }
+ bool wasInUse = isInUse();
+ Usable::incrementUses();
+ if(!wasInUse)
+ {
+ emit changed();
+ qWarning() << "Account" << m_username << "is now in use.";
+ }
}
void MojangAccount::invalidateClientToken()
{
- m_clientToken = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
- emit changed();
+ m_clientToken = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
+ emit changed();
}
diff --git a/api/logic/minecraft/auth/MojangAccount.h b/api/logic/minecraft/auth/MojangAccount.h
index b2bbc357..8f9bec95 100644
--- a/api/logic/minecraft/auth/MojangAccount.h
+++ b/api/logic/minecraft/auth/MojangAccount.h
@@ -44,15 +44,15 @@ Q_DECLARE_METATYPE(MojangAccountPtr)
*/
struct AccountProfile
{
- QString id;
- QString name;
- bool legacy;
+ QString id;
+ QString name;
+ bool legacy;
};
enum AccountStatus
{
- NotVerified,
- Verified
+ NotVerified,
+ Verified
};
/**
@@ -62,121 +62,121 @@ enum AccountStatus
* token if the user chose to stay logged in.
*/
class MULTIMC_LOGIC_EXPORT MojangAccount :
- public QObject,
- public Usable,
- public std::enable_shared_from_this<MojangAccount>
+ public QObject,
+ public Usable,
+ public std::enable_shared_from_this<MojangAccount>
{
- Q_OBJECT
+ Q_OBJECT
public: /* construction */
- //! Do not copy accounts. ever.
- explicit MojangAccount(const MojangAccount &other, QObject *parent) = delete;
+ //! Do not copy accounts. ever.
+ explicit MojangAccount(const MojangAccount &other, QObject *parent) = delete;
- //! Default constructor
- explicit MojangAccount(QObject *parent = 0) : QObject(parent) {};
+ //! Default constructor
+ explicit MojangAccount(QObject *parent = 0) : QObject(parent) {};
- //! Creates an empty account for the specified user name.
- static MojangAccountPtr createFromUsername(const QString &username);
+ //! Creates an empty account for the specified user name.
+ static MojangAccountPtr createFromUsername(const QString &username);
- //! Loads a MojangAccount from the given JSON object.
- static MojangAccountPtr loadFromJson(const QJsonObject &json);
+ //! Loads a MojangAccount from the given JSON object.
+ static MojangAccountPtr loadFromJson(const QJsonObject &json);
- //! Saves a MojangAccount to a JSON object and returns it.
- QJsonObject saveToJson() const;
+ //! Saves a MojangAccount to a JSON object and returns it.
+ QJsonObject saveToJson() const;
public: /* manipulation */
- /**
- * Sets the currently selected profile to the profile with the given ID string.
- * If profileId is not in the list of available profiles, the function will simply return
- * false.
- */
- bool setCurrentProfile(const QString &profileId);
-
- /**
- * Attempt to login. Empty password means we use the token.
- * If the attempt fails because we already are performing some task, it returns false.
- */
- std::shared_ptr<YggdrasilTask> login(AuthSessionPtr session, QString password = QString());
- void invalidateClientToken();
+ /**
+ * Sets the currently selected profile to the profile with the given ID string.
+ * If profileId is not in the list of available profiles, the function will simply return
+ * false.
+ */
+ bool setCurrentProfile(const QString &profileId);
+
+ /**
+ * Attempt to login. Empty password means we use the token.
+ * If the attempt fails because we already are performing some task, it returns false.
+ */
+ std::shared_ptr<YggdrasilTask> login(AuthSessionPtr session, QString password = QString());
+ void invalidateClientToken();
public: /* queries */
- const QString &username() const
- {
- return m_username;
- }
+ const QString &username() const
+ {
+ return m_username;
+ }
- const QString &clientToken() const
- {
- return m_clientToken;
- }
+ const QString &clientToken() const
+ {
+ return m_clientToken;
+ }
- const QString &accessToken() const
- {
- return m_accessToken;
- }
+ const QString &accessToken() const
+ {
+ return m_accessToken;
+ }
- const QList<AccountProfile> &profiles() const
- {
- return m_profiles;
- }
+ const QList<AccountProfile> &profiles() const
+ {
+ return m_profiles;
+ }
- const User &user()
- {
- return m_user;
- }
+ const User &user()
+ {
+ return m_user;
+ }
- //! Returns the currently selected profile (if none, returns nullptr)
- const AccountProfile *currentProfile() const;
+ //! Returns the currently selected profile (if none, returns nullptr)
+ const AccountProfile *currentProfile() const;
- //! Returns whether the account is NotVerified, Verified or Online
- AccountStatus accountStatus() const;
+ //! Returns whether the account is NotVerified, Verified or Online
+ AccountStatus accountStatus() const;
signals:
- /**
- * This signal is emitted when the account changes
- */
- void changed();
+ /**
+ * This signal is emitted when the account changes
+ */
+ void changed();
- // TODO: better signalling for the various possible state changes - especially errors
+ // TODO: better signalling for the various possible state changes - especially errors
protected: /* variables */
- QString m_username;
+ QString m_username;
- // Used to identify the client - the user can have multiple clients for the same account
- // Think: different launchers, all connecting to the same account/profile
- QString m_clientToken;
+ // Used to identify the client - the user can have multiple clients for the same account
+ // Think: different launchers, all connecting to the same account/profile
+ QString m_clientToken;
- // Blank if not logged in.
- QString m_accessToken;
+ // Blank if not logged in.
+ QString m_accessToken;
- // Index of the selected profile within the list of available
- // profiles. -1 if nothing is selected.
- int m_currentProfile = -1;
+ // Index of the selected profile within the list of available
+ // profiles. -1 if nothing is selected.
+ int m_currentProfile = -1;
- // List of available profiles.
- QList<AccountProfile> m_profiles;
+ // List of available profiles.
+ QList<AccountProfile> m_profiles;
- // the user structure, whatever it is.
- User m_user;
+ // the user structure, whatever it is.
+ User m_user;
- // current task we are executing here
- std::shared_ptr<YggdrasilTask> m_currentTask;
+ // current task we are executing here
+ std::shared_ptr<YggdrasilTask> m_currentTask;
protected: /* methods */
- void incrementUses() override;
- void decrementUses() override;
+ void incrementUses() override;
+ void decrementUses() override;
private
slots:
- void authSucceeded();
- void authFailed(QString reason);
+ void authSucceeded();
+ void authFailed(QString reason);
private:
- void fillSession(AuthSessionPtr session);
+ void fillSession(AuthSessionPtr session);
public:
- friend class YggdrasilTask;
- friend class AuthenticateTask;
- friend class ValidateTask;
- friend class RefreshTask;
+ friend class YggdrasilTask;
+ friend class AuthenticateTask;
+ friend class ValidateTask;
+ friend class RefreshTask;
};
diff --git a/api/logic/minecraft/auth/MojangAccountList.cpp b/api/logic/minecraft/auth/MojangAccountList.cpp
index 21ae188a..de671add 100644
--- a/api/logic/minecraft/auth/MojangAccountList.cpp
+++ b/api/logic/minecraft/auth/MojangAccountList.cpp
@@ -37,432 +37,432 @@ MojangAccountList::MojangAccountList(QObject *parent) : QAbstractListModel(paren
MojangAccountPtr MojangAccountList::findAccount(const QString &username) const
{
- for (int i = 0; i < count(); i++)
- {
- MojangAccountPtr account = at(i);
- if (account->username() == username)
- return account;
- }
- return nullptr;
+ for (int i = 0; i < count(); i++)
+ {
+ MojangAccountPtr account = at(i);
+ if (account->username() == username)
+ return account;
+ }
+ return nullptr;
}
const MojangAccountPtr MojangAccountList::at(int i) const
{
- return MojangAccountPtr(m_accounts.at(i));
+ return MojangAccountPtr(m_accounts.at(i));
}
void MojangAccountList::addAccount(const MojangAccountPtr account)
{
- int row = m_accounts.count();
- beginInsertRows(QModelIndex(), row, row);
- connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
- m_accounts.append(account);
- endInsertRows();
- onListChanged();
+ int row = m_accounts.count();
+ beginInsertRows(QModelIndex(), row, row);
+ connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
+ m_accounts.append(account);
+ endInsertRows();
+ onListChanged();
}
void MojangAccountList::removeAccount(const QString &username)
{
- int idx = 0;
- for (auto account : m_accounts)
- {
- if (account->username() == username)
- {
- beginRemoveRows(QModelIndex(), idx, idx);
- m_accounts.removeOne(account);
- endRemoveRows();
- return;
- }
- idx++;
- }
- onListChanged();
+ int idx = 0;
+ for (auto account : m_accounts)
+ {
+ if (account->username() == username)
+ {
+ beginRemoveRows(QModelIndex(), idx, idx);
+ m_accounts.removeOne(account);
+ endRemoveRows();
+ return;
+ }
+ idx++;
+ }
+ onListChanged();
}
void MojangAccountList::removeAccount(QModelIndex index)
{
- int row = index.row();
- if(index.isValid() && row >= 0 && row < m_accounts.size())
- {
- auto & account = m_accounts[row];
- if(account == m_activeAccount)
- {
- m_activeAccount = nullptr;
- onActiveChanged();
- }
- beginRemoveRows(QModelIndex(), row, row);
- m_accounts.removeAt(index.row());
- endRemoveRows();
- onListChanged();
- }
+ int row = index.row();
+ if(index.isValid() && row >= 0 && row < m_accounts.size())
+ {
+ auto & account = m_accounts[row];
+ if(account == m_activeAccount)
+ {
+ m_activeAccount = nullptr;
+ onActiveChanged();
+ }
+ beginRemoveRows(QModelIndex(), row, row);
+ m_accounts.removeAt(index.row());
+ endRemoveRows();
+ onListChanged();
+ }
}
MojangAccountPtr MojangAccountList::activeAccount() const
{
- return m_activeAccount;
+ return m_activeAccount;
}
void MojangAccountList::setActiveAccount(const QString &username)
{
- if (username.isEmpty() && m_activeAccount)
- {
- int idx = 0;
- auto prevActiveAcc = m_activeAccount;
- m_activeAccount = nullptr;
- for (MojangAccountPtr account : m_accounts)
- {
- if (account == prevActiveAcc)
- {
- emit dataChanged(index(idx), index(idx));
- }
- idx ++;
- }
- onActiveChanged();
- }
- else
- {
- auto currentActiveAccount = m_activeAccount;
- int currentActiveAccountIdx = -1;
- auto newActiveAccount = m_activeAccount;
- int newActiveAccountIdx = -1;
- int idx = 0;
- for (MojangAccountPtr account : m_accounts)
- {
- if (account->username() == username)
- {
- newActiveAccount = account;
- newActiveAccountIdx = idx;
- }
- if(currentActiveAccount == account)
- {
- currentActiveAccountIdx = idx;
- }
- idx++;
- }
- if(currentActiveAccount != newActiveAccount)
- {
- emit dataChanged(index(currentActiveAccountIdx), index(currentActiveAccountIdx));
- emit dataChanged(index(newActiveAccountIdx), index(newActiveAccountIdx));
- m_activeAccount = newActiveAccount;
- onActiveChanged();
- }
- }
+ if (username.isEmpty() && m_activeAccount)
+ {
+ int idx = 0;
+ auto prevActiveAcc = m_activeAccount;
+ m_activeAccount = nullptr;
+ for (MojangAccountPtr account : m_accounts)
+ {
+ if (account == prevActiveAcc)
+ {
+ emit dataChanged(index(idx), index(idx));
+ }
+ idx ++;
+ }
+ onActiveChanged();
+ }
+ else
+ {
+ auto currentActiveAccount = m_activeAccount;
+ int currentActiveAccountIdx = -1;
+ auto newActiveAccount = m_activeAccount;
+ int newActiveAccountIdx = -1;
+ int idx = 0;
+ for (MojangAccountPtr account : m_accounts)
+ {
+ if (account->username() == username)
+ {
+ newActiveAccount = account;
+ newActiveAccountIdx = idx;
+ }
+ if(currentActiveAccount == account)
+ {
+ currentActiveAccountIdx = idx;
+ }
+ idx++;
+ }
+ if(currentActiveAccount != newActiveAccount)
+ {
+ emit dataChanged(index(currentActiveAccountIdx), index(currentActiveAccountIdx));
+ emit dataChanged(index(newActiveAccountIdx), index(newActiveAccountIdx));
+ m_activeAccount = newActiveAccount;
+ onActiveChanged();
+ }
+ }
}
void MojangAccountList::accountChanged()
{
- // the list changed. there is no doubt.
- onListChanged();
+ // the list changed. there is no doubt.
+ onListChanged();
}
void MojangAccountList::onListChanged()
{
- if (m_autosave)
- // TODO: Alert the user if this fails.
- saveList();
+ if (m_autosave)
+ // TODO: Alert the user if this fails.
+ saveList();
- emit listChanged();
+ emit listChanged();
}
void MojangAccountList::onActiveChanged()
{
- if (m_autosave)
- saveList();
+ if (m_autosave)
+ saveList();
- emit activeAccountChanged();
+ emit activeAccountChanged();
}
int MojangAccountList::count() const
{
- return m_accounts.count();
+ return m_accounts.count();
}
QVariant MojangAccountList::data(const QModelIndex &index, int role) const
{
- if (!index.isValid())
- return QVariant();
-
- if (index.row() > count())
- return QVariant();
-
- MojangAccountPtr account = at(index.row());
-
- switch (role)
- {
- case Qt::DisplayRole:
- switch (index.column())
- {
- case NameColumn:
- return account->username();
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- return account->username();
-
- case PointerRole:
- return qVariantFromValue(account);
-
- case Qt::CheckStateRole:
- switch (index.column())
- {
- case ActiveColumn:
- return account == m_activeAccount ? Qt::Checked : Qt::Unchecked;
- }
-
- default:
- return QVariant();
- }
+ if (!index.isValid())
+ return QVariant();
+
+ if (index.row() > count())
+ return QVariant();
+
+ MojangAccountPtr account = at(index.row());
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (index.column())
+ {
+ case NameColumn:
+ return account->username();
+
+ default:
+ return QVariant();
+ }
+
+ case Qt::ToolTipRole:
+ return account->username();
+
+ case PointerRole:
+ return qVariantFromValue(account);
+
+ case Qt::CheckStateRole:
+ switch (index.column())
+ {
+ case ActiveColumn:
+ return account == m_activeAccount ? Qt::Checked : Qt::Unchecked;
+ }
+
+ default:
+ return QVariant();
+ }
}
QVariant MojangAccountList::headerData(int section, Qt::Orientation orientation, int role) const
{
- switch (role)
- {
- case Qt::DisplayRole:
- switch (section)
- {
- case ActiveColumn:
- return tr("Active?");
-
- case NameColumn:
- return tr("Name");
-
- default:
- return QVariant();
- }
-
- case Qt::ToolTipRole:
- switch (section)
- {
- case NameColumn:
- return tr("The name of the version.");
-
- default:
- return QVariant();
- }
-
- default:
- return QVariant();
- }
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch (section)
+ {
+ case ActiveColumn:
+ return tr("Active?");
+
+ case NameColumn:
+ return tr("Name");
+
+ default:
+ return QVariant();
+ }
+
+ case Qt::ToolTipRole:
+ switch (section)
+ {
+ case NameColumn:
+ return tr("The name of the version.");
+
+ default:
+ return QVariant();
+ }
+
+ default:
+ return QVariant();
+ }
}
int MojangAccountList::rowCount(const QModelIndex &) const
{
- // Return count
- return count();
+ // Return count
+ return count();
}
int MojangAccountList::columnCount(const QModelIndex &) const
{
- return 2;
+ return 2;
}
Qt::ItemFlags MojangAccountList::flags(const QModelIndex &index) const
{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return Qt::NoItemFlags;
- }
+ if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
+ {
+ return Qt::NoItemFlags;
+ }
- return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
bool MojangAccountList::setData(const QModelIndex &index, const QVariant &value, int role)
{
- if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
- {
- return false;
- }
-
- if(role == Qt::CheckStateRole)
- {
- if(value == Qt::Checked)
- {
- MojangAccountPtr account = this->at(index.row());
- this->setActiveAccount(account->username());
- }
- }
-
- emit dataChanged(index, index);
- return true;
+ if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
+ {
+ return false;
+ }
+
+ if(role == Qt::CheckStateRole)
+ {
+ if(value == Qt::Checked)
+ {
+ MojangAccountPtr account = this->at(index.row());
+ this->setActiveAccount(account->username());
+ }
+ }
+
+ emit dataChanged(index, index);
+ return true;
}
void MojangAccountList::updateListData(QList<MojangAccountPtr> versions)
{
- beginResetModel();
- m_accounts = versions;
- endResetModel();
+ beginResetModel();
+ m_accounts = versions;
+ endResetModel();
}
bool MojangAccountList::loadList(const QString &filePath)
{
- QString path = filePath;
- if (path.isEmpty())
- path = m_listFilePath;
- if (path.isEmpty())
- {
- qCritical() << "Can't load Mojang account list. No file path given and no default set.";
- return false;
- }
-
- QFile file(path);
-
- // Try to open the file and fail if we can't.
- // TODO: We should probably report this error to the user.
- if (!file.open(QIODevice::ReadOnly))
- {
- qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8();
- return false;
- }
-
- // Read the file and close it.
- QByteArray jsonData = file.readAll();
- file.close();
-
- QJsonParseError parseError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
-
- // Fail if the JSON is invalid.
- if (parseError.error != QJsonParseError::NoError)
- {
- qCritical() << QString("Failed to parse account list file: %1 at offset %2")
- .arg(parseError.errorString(), QString::number(parseError.offset))
- .toUtf8();
- return false;
- }
-
- // Make sure the root is an object.
- if (!jsonDoc.isObject())
- {
- qCritical() << "Invalid account list JSON: Root should be an array.";
- return false;
- }
-
- QJsonObject root = jsonDoc.object();
-
- // Make sure the format version matches.
- if (root.value("formatVersion").toVariant().toInt() != ACCOUNT_LIST_FORMAT_VERSION)
- {
- QString newName = "accounts-old.json";
- qWarning() << "Format version mismatch when loading account list. Existing one will be renamed to"
- << newName;
-
- // Attempt to rename the old version.
- file.rename(newName);
- return false;
- }
-
- // Now, load the accounts array.
- beginResetModel();
- QJsonArray accounts = root.value("accounts").toArray();
- for (QJsonValue accountVal : accounts)
- {
- QJsonObject accountObj = accountVal.toObject();
- MojangAccountPtr account = MojangAccount::loadFromJson(accountObj);
- if (account.get() != nullptr)
- {
- connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
- m_accounts.append(account);
- }
- else
- {
- qWarning() << "Failed to load an account.";
- }
- }
- // Load the active account.
- m_activeAccount = findAccount(root.value("activeAccount").toString(""));
- endResetModel();
- return true;
+ QString path = filePath;
+ if (path.isEmpty())
+ path = m_listFilePath;
+ if (path.isEmpty())
+ {
+ qCritical() << "Can't load Mojang account list. No file path given and no default set.";
+ return false;
+ }
+
+ QFile file(path);
+
+ // Try to open the file and fail if we can't.
+ // TODO: We should probably report this error to the user.
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8();
+ return false;
+ }
+
+ // Read the file and close it.
+ QByteArray jsonData = file.readAll();
+ file.close();
+
+ QJsonParseError parseError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);
+
+ // Fail if the JSON is invalid.
+ if (parseError.error != QJsonParseError::NoError)
+ {
+ qCritical() << QString("Failed to parse account list file: %1 at offset %2")
+ .arg(parseError.errorString(), QString::number(parseError.offset))
+ .toUtf8();
+ return false;
+ }
+
+ // Make sure the root is an object.
+ if (!jsonDoc.isObject())
+ {
+ qCritical() << "Invalid account list JSON: Root should be an array.";
+ return false;
+ }
+
+ QJsonObject root = jsonDoc.object();
+
+ // Make sure the format version matches.
+ if (root.value("formatVersion").toVariant().toInt() != ACCOUNT_LIST_FORMAT_VERSION)
+ {
+ QString newName = "accounts-old.json";
+ qWarning() << "Format version mismatch when loading account list. Existing one will be renamed to"
+ << newName;
+
+ // Attempt to rename the old version.
+ file.rename(newName);
+ return false;
+ }
+
+ // Now, load the accounts array.
+ beginResetModel();
+ QJsonArray accounts = root.value("accounts").toArray();
+ for (QJsonValue accountVal : accounts)
+ {
+ QJsonObject accountObj = accountVal.toObject();
+ MojangAccountPtr account = MojangAccount::loadFromJson(accountObj);
+ if (account.get() != nullptr)
+ {
+ connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
+ m_accounts.append(account);
+ }
+ else
+ {
+ qWarning() << "Failed to load an account.";
+ }
+ }
+ // Load the active account.
+ m_activeAccount = findAccount(root.value("activeAccount").toString(""));
+ endResetModel();
+ return true;
}
bool MojangAccountList::saveList(const QString &filePath)
{
- QString path(filePath);
- if (path.isEmpty())
- path = m_listFilePath;
- if (path.isEmpty())
- {
- qCritical() << "Can't save Mojang account list. No file path given and no default set.";
- return false;
- }
-
- // make sure the parent folder exists
- if(!FS::ensureFilePathExists(path))
- return false;
-
- // make sure the file wasn't overwritten with a folder before (fixes a bug)
- QFileInfo finfo(path);
- if(finfo.isDir())
- {
- QDir badDir(path);
- badDir.removeRecursively();
- }
-
- qDebug() << "Writing account list to" << path;
-
- qDebug() << "Building JSON data structure.";
- // Build the JSON document to write to the list file.
- QJsonObject root;
-
- root.insert("formatVersion", ACCOUNT_LIST_FORMAT_VERSION);
-
- // Build a list of accounts.
- qDebug() << "Building account array.";
- QJsonArray accounts;
- for (MojangAccountPtr account : m_accounts)
- {
- QJsonObject accountObj = account->saveToJson();
- accounts.append(accountObj);
- }
-
- // Insert the account list into the root object.
- root.insert("accounts", accounts);
-
- if(m_activeAccount)
- {
- // Save the active account.
- root.insert("activeAccount", m_activeAccount->username());
- }
-
- // Create a JSON document object to convert our JSON to bytes.
- QJsonDocument doc(root);
-
- // Now that we're done building the JSON object, we can write it to the file.
- qDebug() << "Writing account list to file.";
- QFile file(path);
-
- // Try to open the file and fail if we can't.
- // TODO: We should probably report this error to the user.
- if (!file.open(QIODevice::WriteOnly))
- {
- qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8();
- return false;
- }
-
- // Write the JSON to the file.
- file.write(doc.toJson());
- file.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ReadUser|QFile::WriteUser);
- file.close();
-
- qDebug() << "Saved account list to" << path;
-
- return true;
+ QString path(filePath);
+ if (path.isEmpty())
+ path = m_listFilePath;
+ if (path.isEmpty())
+ {
+ qCritical() << "Can't save Mojang account list. No file path given and no default set.";
+ return false;
+ }
+
+ // make sure the parent folder exists
+ if(!FS::ensureFilePathExists(path))
+ return false;
+
+ // make sure the file wasn't overwritten with a folder before (fixes a bug)
+ QFileInfo finfo(path);
+ if(finfo.isDir())
+ {
+ QDir badDir(path);
+ badDir.removeRecursively();
+ }
+
+ qDebug() << "Writing account list to" << path;
+
+ qDebug() << "Building JSON data structure.";
+ // Build the JSON document to write to the list file.
+ QJsonObject root;
+
+ root.insert("formatVersion", ACCOUNT_LIST_FORMAT_VERSION);
+
+ // Build a list of accounts.
+ qDebug() << "Building account array.";
+ QJsonArray accounts;
+ for (MojangAccountPtr account : m_accounts)
+ {
+ QJsonObject accountObj = account->saveToJson();
+ accounts.append(accountObj);
+ }
+
+ // Insert the account list into the root object.
+ root.insert("accounts", accounts);
+
+ if(m_activeAccount)
+ {
+ // Save the active account.
+ root.insert("activeAccount", m_activeAccount->username());
+ }
+
+ // Create a JSON document object to convert our JSON to bytes.
+ QJsonDocument doc(root);
+
+ // Now that we're done building the JSON object, we can write it to the file.
+ qDebug() << "Writing account list to file.";
+ QFile file(path);
+
+ // Try to open the file and fail if we can't.
+ // TODO: We should probably report this error to the user.
+ if (!file.open(QIODevice::WriteOnly))
+ {
+ qCritical() << QString("Failed to read the account list file (%1).").arg(path).toUtf8();
+ return false;
+ }
+
+ // Write the JSON to the file.
+ file.write(doc.toJson());
+ file.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ReadUser|QFile::WriteUser);
+ file.close();
+
+ qDebug() << "Saved account list to" << path;
+
+ return true;
}
void MojangAccountList::setListFilePath(QString path, bool autosave)
{
- m_listFilePath = path;
- m_autosave = autosave;
+ m_listFilePath = path;
+ m_autosave = autosave;
}
bool MojangAccountList::anyAccountIsValid()
{
- for(auto account:m_accounts)
- {
- if(account->accountStatus() != NotVerified)
- return true;
- }
- return false;
+ for(auto account:m_accounts)
+ {
+ if(account->accountStatus() != NotVerified)
+ return true;
+ }
+ return false;
}
diff --git a/api/logic/minecraft/auth/MojangAccountList.h b/api/logic/minecraft/auth/MojangAccountList.h
index dd6c07e8..33018636 100644
--- a/api/logic/minecraft/auth/MojangAccountList.h
+++ b/api/logic/minecraft/auth/MojangAccountList.h
@@ -35,167 +35,167 @@
*/
class MULTIMC_LOGIC_EXPORT MojangAccountList : public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum ModelRoles
- {
- PointerRole = 0x34B1CB48
- };
-
- enum VListColumns
- {
- // TODO: Add icon column.
-
- // First column - Active?
- ActiveColumn = 0,
-
- // Second column - Name
- NameColumn,
- };
-
- explicit MojangAccountList(QObject *parent = 0);
-
- //! Gets the account at the given index.
- virtual const MojangAccountPtr at(int i) const;
-
- //! Returns the number of accounts in the list.
- virtual int count() const;
-
- //////// List Model Functions ////////
- virtual QVariant data(const QModelIndex &index, int role) const;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- virtual int rowCount(const QModelIndex &parent) const;
- virtual int columnCount(const QModelIndex &parent) const;
- virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
-
- /*!
- * Adds a the given Mojang account to the account list.
- */
- virtual void addAccount(const MojangAccountPtr account);
-
- /*!
- * Removes the mojang account with the given username from the account list.
- */
- virtual void removeAccount(const QString &username);
-
- /*!
- * Removes the account at the given QModelIndex.
- */
- virtual void removeAccount(QModelIndex index);
-
- /*!
- * \brief Finds an account by its username.
- * \param The username of the account to find.
- * \return A const pointer to the account with the given username. NULL if
- * one doesn't exist.
- */
- virtual MojangAccountPtr findAccount(const QString &username) const;
-
- /*!
- * Sets the default path to save the list file to.
- * If autosave is true, this list will automatically save to the given path whenever it changes.
- * THIS FUNCTION DOES NOT LOAD THE LIST. If you set autosave, be sure to call loadList() immediately
- * after calling this function to ensure an autosaved change doesn't overwrite the list you intended
- * to load.
- */
- virtual void setListFilePath(QString path, bool autosave = false);
-
- /*!
- * \brief Loads the account list from the given file path.
- * If the given file is an empty string (default), will load from the default account list file.
- * \return True if successful, otherwise false.
- */
- virtual bool loadList(const QString &file = "");
-
- /*!
- * \brief Saves the account list to the given file.
- * If the given file is an empty string (default), will save from the default account list file.
- * \return True if successful, otherwise false.
- */
- virtual bool saveList(const QString &file = "");
-
- /*!
- * \brief Gets a pointer to the account that the user has selected as their "active" account.
- * Which account is active can be overridden on a per-instance basis, but this will return the one that
- * is set as active globally.
- * \return The currently active MojangAccount. If there isn't an active account, returns a null pointer.
- */
- virtual MojangAccountPtr activeAccount() const;
-
- /*!
- * Sets the given account as the current active account.
- * If the username given is an empty string, sets the active account to nothing.
- */
- virtual void setActiveAccount(const QString &username);
-
- /*!
- * Returns true if any of the account is at least Validated
- */
- bool anyAccountIsValid();
+ enum ModelRoles
+ {
+ PointerRole = 0x34B1CB48
+ };
+
+ enum VListColumns
+ {
+ // TODO: Add icon column.
+
+ // First column - Active?
+ ActiveColumn = 0,
+
+ // Second column - Name
+ NameColumn,
+ };
+
+ explicit MojangAccountList(QObject *parent = 0);
+
+ //! Gets the account at the given index.
+ virtual const MojangAccountPtr at(int i) const;
+
+ //! Returns the number of accounts in the list.
+ virtual int count() const;
+
+ //////// List Model Functions ////////
+ virtual QVariant data(const QModelIndex &index, int role) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ virtual int rowCount(const QModelIndex &parent) const;
+ virtual int columnCount(const QModelIndex &parent) const;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
+
+ /*!
+ * Adds a the given Mojang account to the account list.
+ */
+ virtual void addAccount(const MojangAccountPtr account);
+
+ /*!
+ * Removes the mojang account with the given username from the account list.
+ */
+ virtual void removeAccount(const QString &username);
+
+ /*!
+ * Removes the account at the given QModelIndex.
+ */
+ virtual void removeAccount(QModelIndex index);
+
+ /*!
+ * \brief Finds an account by its username.
+ * \param The username of the account to find.
+ * \return A const pointer to the account with the given username. NULL if
+ * one doesn't exist.
+ */
+ virtual MojangAccountPtr findAccount(const QString &username) const;
+
+ /*!
+ * Sets the default path to save the list file to.
+ * If autosave is true, this list will automatically save to the given path whenever it changes.
+ * THIS FUNCTION DOES NOT LOAD THE LIST. If you set autosave, be sure to call loadList() immediately
+ * after calling this function to ensure an autosaved change doesn't overwrite the list you intended
+ * to load.
+ */
+ virtual void setListFilePath(QString path, bool autosave = false);
+
+ /*!
+ * \brief Loads the account list from the given file path.
+ * If the given file is an empty string (default), will load from the default account list file.
+ * \return True if successful, otherwise false.
+ */
+ virtual bool loadList(const QString &file = "");
+
+ /*!
+ * \brief Saves the account list to the given file.
+ * If the given file is an empty string (default), will save from the default account list file.
+ * \return True if successful, otherwise false.
+ */
+ virtual bool saveList(const QString &file = "");
+
+ /*!
+ * \brief Gets a pointer to the account that the user has selected as their "active" account.
+ * Which account is active can be overridden on a per-instance basis, but this will return the one that
+ * is set as active globally.
+ * \return The currently active MojangAccount. If there isn't an active account, returns a null pointer.
+ */
+ virtual MojangAccountPtr activeAccount() const;
+
+ /*!
+ * Sets the given account as the current active account.
+ * If the username given is an empty string, sets the active account to nothing.
+ */
+ virtual void setActiveAccount(const QString &username);
+
+ /*!
+ * Returns true if any of the account is at least Validated
+ */
+ bool anyAccountIsValid();
signals:
- /*!
- * Signal emitted to indicate that the account list has changed.
- * This will also fire if the value of an element in the list changes (will be implemented
- * later).
- */
- void listChanged();
-
- /*!
- * Signal emitted to indicate that the active account has changed.
- */
- void activeAccountChanged();
+ /*!
+ * Signal emitted to indicate that the account list has changed.
+ * This will also fire if the value of an element in the list changes (will be implemented
+ * later).
+ */
+ void listChanged();
+
+ /*!
+ * Signal emitted to indicate that the active account has changed.
+ */
+ void activeAccountChanged();
public
slots:
- /**
- * This is called when one of the accounts changes and the list needs to be updated
- */
- void accountChanged();
+ /**
+ * This is called when one of the accounts changes and the list needs to be updated
+ */
+ void accountChanged();
protected:
- /*!
- * Called whenever the list changes.
- * This emits the listChanged() signal and autosaves the list (if autosave is enabled).
- */
- void onListChanged();
-
- /*!
- * Called whenever the active account changes.
- * Emits the activeAccountChanged() signal and autosaves the list if enabled.
- */
- void onActiveChanged();
-
- QList<MojangAccountPtr> m_accounts;
-
- /*!
- * Account that is currently active.
- */
- MojangAccountPtr m_activeAccount;
-
- //! Path to the account list file. Empty string if there isn't one.
- QString m_listFilePath;
-
- /*!
- * If true, the account list will automatically save to the account list path when it changes.
- * Ignored if m_listFilePath is blank.
- */
- bool m_autosave = false;
+ /*!
+ * Called whenever the list changes.
+ * This emits the listChanged() signal and autosaves the list (if autosave is enabled).
+ */
+ void onListChanged();
+
+ /*!
+ * Called whenever the active account changes.
+ * Emits the activeAccountChanged() signal and autosaves the list if enabled.
+ */
+ void onActiveChanged();
+
+ QList<MojangAccountPtr> m_accounts;
+
+ /*!
+ * Account that is currently active.
+ */
+ MojangAccountPtr m_activeAccount;
+
+ //! Path to the account list file. Empty string if there isn't one.
+ QString m_listFilePath;
+
+ /*!
+ * If true, the account list will automatically save to the account list path when it changes.
+ * Ignored if m_listFilePath is blank.
+ */
+ bool m_autosave = false;
protected
slots:
- /*!
- * Updates this list with the given list of accounts.
- * This is done by copying each account in the given list and inserting it
- * into this one.
- * We need to do this so that we can set the parents of the accounts are set to this
- * account list. This can't be done in the load task, because the accounts the load
- * task creates are on the load task's thread and Qt won't allow their parents
- * to be set to something created on another thread.
- * To get around that problem, we invoke this method on the GUI thread, which
- * then copies the accounts and sets their parents correctly.
- * \param accounts List of accounts whose parents should be set.
- */
- virtual void updateListData(QList<MojangAccountPtr> versions);
+ /*!
+ * Updates this list with the given list of accounts.
+ * This is done by copying each account in the given list and inserting it
+ * into this one.
+ * We need to do this so that we can set the parents of the accounts are set to this
+ * account list. This can't be done in the load task, because the accounts the load
+ * task creates are on the load task's thread and Qt won't allow their parents
+ * to be set to something created on another thread.
+ * To get around that problem, we invoke this method on the GUI thread, which
+ * then copies the accounts and sets their parents correctly.
+ * \param accounts List of accounts whose parents should be set.
+ */
+ virtual void updateListData(QList<MojangAccountPtr> versions);
};
diff --git a/api/logic/minecraft/auth/YggdrasilTask.cpp b/api/logic/minecraft/auth/YggdrasilTask.cpp
index f17d803f..666e57d6 100644
--- a/api/logic/minecraft/auth/YggdrasilTask.cpp
+++ b/api/logic/minecraft/auth/YggdrasilTask.cpp
@@ -30,226 +30,226 @@
#include <QDebug>
YggdrasilTask::YggdrasilTask(MojangAccount *account, QObject *parent)
- : Task(parent), m_account(account)
+ : Task(parent), m_account(account)
{
- changeState(STATE_CREATED);
+ changeState(STATE_CREATED);
}
void YggdrasilTask::executeTask()
{
- changeState(STATE_SENDING_REQUEST);
-
- // Get the content of the request we're going to send to the server.
- QJsonDocument doc(getRequestContent());
-
- QUrl reqUrl("https://" + URLConstants::AUTH_BASE + getEndpoint());
- QNetworkRequest netRequest(reqUrl);
- netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- QByteArray requestData = doc.toJson();
- m_netReply = ENV.qnam().post(netRequest, requestData);
- connect(m_netReply, &QNetworkReply::finished, this, &YggdrasilTask::processReply);
- connect(m_netReply, &QNetworkReply::uploadProgress, this, &YggdrasilTask::refreshTimers);
- connect(m_netReply, &QNetworkReply::downloadProgress, this, &YggdrasilTask::refreshTimers);
- connect(m_netReply, &QNetworkReply::sslErrors, this, &YggdrasilTask::sslErrors);
- timeout_keeper.setSingleShot(true);
- timeout_keeper.start(timeout_max);
- counter.setSingleShot(false);
- counter.start(time_step);
- progress(0, timeout_max);
- connect(&timeout_keeper, &QTimer::timeout, this, &YggdrasilTask::abortByTimeout);
- connect(&counter, &QTimer::timeout, this, &YggdrasilTask::heartbeat);
+ changeState(STATE_SENDING_REQUEST);
+
+ // Get the content of the request we're going to send to the server.
+ QJsonDocument doc(getRequestContent());
+
+ QUrl reqUrl("https://" + URLConstants::AUTH_BASE + getEndpoint());
+ QNetworkRequest netRequest(reqUrl);
+ netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+ QByteArray requestData = doc.toJson();
+ m_netReply = ENV.qnam().post(netRequest, requestData);
+ connect(m_netReply, &QNetworkReply::finished, this, &YggdrasilTask::processReply);
+ connect(m_netReply, &QNetworkReply::uploadProgress, this, &YggdrasilTask::refreshTimers);
+ connect(m_netReply, &QNetworkReply::downloadProgress, this, &YggdrasilTask::refreshTimers);
+ connect(m_netReply, &QNetworkReply::sslErrors, this, &YggdrasilTask::sslErrors);
+ timeout_keeper.setSingleShot(true);
+ timeout_keeper.start(timeout_max);
+ counter.setSingleShot(false);
+ counter.start(time_step);
+ progress(0, timeout_max);
+ connect(&timeout_keeper, &QTimer::timeout, this, &YggdrasilTask::abortByTimeout);
+ connect(&counter, &QTimer::timeout, this, &YggdrasilTask::heartbeat);
}
void YggdrasilTask::refreshTimers(qint64, qint64)
{
- timeout_keeper.stop();
- timeout_keeper.start(timeout_max);
- progress(count = 0, timeout_max);
+ timeout_keeper.stop();
+ timeout_keeper.start(timeout_max);
+ progress(count = 0, timeout_max);
}
void YggdrasilTask::heartbeat()
{
- count += time_step;
- progress(count, timeout_max);
+ count += time_step;
+ progress(count, timeout_max);
}
bool YggdrasilTask::abort()
{
- progress(timeout_max, timeout_max);
- // TODO: actually use this in a meaningful way
- m_aborted = YggdrasilTask::BY_USER;
- m_netReply->abort();
- return true;
+ progress(timeout_max, timeout_max);
+ // TODO: actually use this in a meaningful way
+ m_aborted = YggdrasilTask::BY_USER;
+ m_netReply->abort();
+ return true;
}
void YggdrasilTask::abortByTimeout()
{
- progress(timeout_max, timeout_max);
- // TODO: actually use this in a meaningful way
- m_aborted = YggdrasilTask::BY_TIMEOUT;
- m_netReply->abort();
+ progress(timeout_max, timeout_max);
+ // TODO: actually use this in a meaningful way
+ m_aborted = YggdrasilTask::BY_TIMEOUT;
+ m_netReply->abort();
}
void YggdrasilTask::sslErrors(QList<QSslError> errors)
{
- int i = 1;
- for (auto error : errors)
- {
- qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString();
- auto cert = error.certificate();
- qCritical() << "Certificate in question:\n" << cert.toText();
- i++;
- }
+ int i = 1;
+ for (auto error : errors)
+ {
+ qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString();
+ auto cert = error.certificate();
+ qCritical() << "Certificate in question:\n" << cert.toText();
+ i++;
+ }
}
void YggdrasilTask::processReply()
{
- changeState(STATE_PROCESSING_RESPONSE);
-
- switch (m_netReply->error())
- {
- case QNetworkReply::NoError:
- break;
- case QNetworkReply::TimeoutError:
- changeState(STATE_FAILED_SOFT, tr("Authentication operation timed out."));
- return;
- case QNetworkReply::OperationCanceledError:
- changeState(STATE_FAILED_SOFT, tr("Authentication operation cancelled."));
- return;
- case QNetworkReply::SslHandshakeFailedError:
- changeState(
- STATE_FAILED_SOFT,
- tr("<b>SSL Handshake failed.</b><br/>There might be a few causes for it:<br/>"
- "<ul>"
- "<li>You use Windows XP and need to <a "
- "href=\"http://www.microsoft.com/en-us/download/details.aspx?id=38918\">update "
- "your root certificates</a></li>"
- "<li>Some device on your network is interfering with SSL traffic. In that case, "
- "you have bigger worries than Minecraft not starting.</li>"
- "<li>Possibly something else. Check the MultiMC log file for details</li>"
- "</ul>"));
- return;
- // used for invalid credentials and similar errors. Fall through.
- case QNetworkReply::ContentAccessDenied:
- case QNetworkReply::ContentOperationNotPermittedError:
- break;
- default:
- changeState(STATE_FAILED_SOFT,
- tr("Authentication operation failed due to a network error: %1 (%2)")
- .arg(m_netReply->errorString()).arg(m_netReply->error()));
- return;
- }
-
- // Try to parse the response regardless of the response code.
- // Sometimes the auth server will give more information and an error code.
- QJsonParseError jsonError;
- QByteArray replyData = m_netReply->readAll();
- QJsonDocument doc = QJsonDocument::fromJson(replyData, &jsonError);
- // Check the response code.
- int responseCode = m_netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-
- if (responseCode == 200)
- {
- // If the response code was 200, then there shouldn't be an error. Make sure
- // anyways.
- // Also, sometimes an empty reply indicates success. If there was no data received,
- // pass an empty json object to the processResponse function.
- if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0)
- {
- processResponse(replyData.size() > 0 ? doc.object() : QJsonObject());
- return;
- }
- else
- {
- changeState(STATE_FAILED_SOFT, tr("Failed to parse authentication server response "
- "JSON response: %1 at offset %2.")
- .arg(jsonError.errorString())
- .arg(jsonError.offset));
- qCritical() << replyData;
- }
- return;
- }
-
- // If the response code was not 200, then Yggdrasil may have given us information
- // about the error.
- // If we can parse the response, then get information from it. Otherwise just say
- // there was an unknown error.
- if (jsonError.error == QJsonParseError::NoError)
- {
- // We were able to parse the server's response. Woo!
- // Call processError. If a subclass has overridden it then they'll handle their
- // stuff there.
- qDebug() << "The request failed, but the server gave us an error message. "
- "Processing error.";
- processError(doc.object());
- }
- else
- {
- // The server didn't say anything regarding the error. Give the user an unknown
- // error.
- qDebug()
- << "The request failed and the server gave no error message. Unknown error.";
- changeState(STATE_FAILED_SOFT,
- tr("An unknown error occurred when trying to communicate with the "
- "authentication server: %1").arg(m_netReply->errorString()));
- }
+ changeState(STATE_PROCESSING_RESPONSE);
+
+ switch (m_netReply->error())
+ {
+ case QNetworkReply::NoError:
+ break;
+ case QNetworkReply::TimeoutError:
+ changeState(STATE_FAILED_SOFT, tr("Authentication operation timed out."));
+ return;
+ case QNetworkReply::OperationCanceledError:
+ changeState(STATE_FAILED_SOFT, tr("Authentication operation cancelled."));
+ return;
+ case QNetworkReply::SslHandshakeFailedError:
+ changeState(
+ STATE_FAILED_SOFT,
+ tr("<b>SSL Handshake failed.</b><br/>There might be a few causes for it:<br/>"
+ "<ul>"
+ "<li>You use Windows XP and need to <a "
+ "href=\"http://www.microsoft.com/en-us/download/details.aspx?id=38918\">update "
+ "your root certificates</a></li>"
+ "<li>Some device on your network is interfering with SSL traffic. In that case, "
+ "you have bigger worries than Minecraft not starting.</li>"
+ "<li>Possibly something else. Check the MultiMC log file for details</li>"
+ "</ul>"));
+ return;
+ // used for invalid credentials and similar errors. Fall through.
+ case QNetworkReply::ContentAccessDenied:
+ case QNetworkReply::ContentOperationNotPermittedError:
+ break;
+ default:
+ changeState(STATE_FAILED_SOFT,
+ tr("Authentication operation failed due to a network error: %1 (%2)")
+ .arg(m_netReply->errorString()).arg(m_netReply->error()));
+ return;
+ }
+
+ // Try to parse the response regardless of the response code.
+ // Sometimes the auth server will give more information and an error code.
+ QJsonParseError jsonError;
+ QByteArray replyData = m_netReply->readAll();
+ QJsonDocument doc = QJsonDocument::fromJson(replyData, &jsonError);
+ // Check the response code.
+ int responseCode = m_netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+
+ if (responseCode == 200)
+ {
+ // If the response code was 200, then there shouldn't be an error. Make sure
+ // anyways.
+ // Also, sometimes an empty reply indicates success. If there was no data received,
+ // pass an empty json object to the processResponse function.
+ if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0)
+ {
+ processResponse(replyData.size() > 0 ? doc.object() : QJsonObject());
+ return;
+ }
+ else
+ {
+ changeState(STATE_FAILED_SOFT, tr("Failed to parse authentication server response "
+ "JSON response: %1 at offset %2.")
+ .arg(jsonError.errorString())
+ .arg(jsonError.offset));
+ qCritical() << replyData;
+ }
+ return;
+ }
+
+ // If the response code was not 200, then Yggdrasil may have given us information
+ // about the error.
+ // If we can parse the response, then get information from it. Otherwise just say
+ // there was an unknown error.
+ if (jsonError.error == QJsonParseError::NoError)
+ {
+ // We were able to parse the server's response. Woo!
+ // Call processError. If a subclass has overridden it then they'll handle their
+ // stuff there.
+ qDebug() << "The request failed, but the server gave us an error message. "
+ "Processing error.";
+ processError(doc.object());
+ }
+ else
+ {
+ // The server didn't say anything regarding the error. Give the user an unknown
+ // error.
+ qDebug()
+ << "The request failed and the server gave no error message. Unknown error.";
+ changeState(STATE_FAILED_SOFT,
+ tr("An unknown error occurred when trying to communicate with the "
+ "authentication server: %1").arg(m_netReply->errorString()));
+ }
}
void YggdrasilTask::processError(QJsonObject responseData)
{
- QJsonValue errorVal = responseData.value("error");
- QJsonValue errorMessageValue = responseData.value("errorMessage");
- QJsonValue causeVal = responseData.value("cause");
-
- if (errorVal.isString() && errorMessageValue.isString())
- {
- m_error = std::shared_ptr<Error>(new Error{
- errorVal.toString(""), errorMessageValue.toString(""), causeVal.toString("")});
- changeState(STATE_FAILED_HARD, m_error->m_errorMessageVerbose);
- }
- else
- {
- // Error is not in standard format. Don't set m_error and return unknown error.
- changeState(STATE_FAILED_HARD, tr("An unknown Yggdrasil error occurred."));
- }
+ QJsonValue errorVal = responseData.value("error");
+ QJsonValue errorMessageValue = responseData.value("errorMessage");
+ QJsonValue causeVal = responseData.value("cause");
+
+ if (errorVal.isString() && errorMessageValue.isString())
+ {
+ m_error = std::shared_ptr<Error>(new Error{
+ errorVal.toString(""), errorMessageValue.toString(""), causeVal.toString("")});
+ changeState(STATE_FAILED_HARD, m_error->m_errorMessageVerbose);
+ }
+ else
+ {
+ // Error is not in standard format. Don't set m_error and return unknown error.
+ changeState(STATE_FAILED_HARD, tr("An unknown Yggdrasil error occurred."));
+ }
}
QString YggdrasilTask::getStateMessage() const
{
- switch (m_state)
- {
- case STATE_CREATED:
- return "Waiting...";
- case STATE_SENDING_REQUEST:
- return tr("Sending request to auth servers...");
- case STATE_PROCESSING_RESPONSE:
- return tr("Processing response from servers...");
- case STATE_SUCCEEDED:
- return tr("Authentication task succeeded.");
- case STATE_FAILED_SOFT:
- return tr("Failed to contact the authentication server.");
- case STATE_FAILED_HARD:
- return tr("Failed to authenticate.");
- default:
- return tr("...");
- }
+ switch (m_state)
+ {
+ case STATE_CREATED:
+ return "Waiting...";
+ case STATE_SENDING_REQUEST:
+ return tr("Sending request to auth servers...");
+ case STATE_PROCESSING_RESPONSE:
+ return tr("Processing response from servers...");
+ case STATE_SUCCEEDED:
+ return tr("Authentication task succeeded.");
+ case STATE_FAILED_SOFT:
+ return tr("Failed to contact the authentication server.");
+ case STATE_FAILED_HARD:
+ return tr("Failed to authenticate.");
+ default:
+ return tr("...");
+ }
}
void YggdrasilTask::changeState(YggdrasilTask::State newState, QString reason)
{
- m_state = newState;
- setStatus(getStateMessage());
- if (newState == STATE_SUCCEEDED)
- {
- emitSucceeded();
- }
- else if (newState == STATE_FAILED_HARD || newState == STATE_FAILED_SOFT)
- {
- emitFailed(reason);
- }
+ m_state = newState;
+ setStatus(getStateMessage());
+ if (newState == STATE_SUCCEEDED)
+ {
+ emitSucceeded();
+ }
+ else if (newState == STATE_FAILED_HARD || newState == STATE_FAILED_SOFT)
+ {
+ emitFailed(reason);
+ }
}
YggdrasilTask::State YggdrasilTask::state()
{
- return m_state;
+ return m_state;
}
diff --git a/api/logic/minecraft/auth/YggdrasilTask.h b/api/logic/minecraft/auth/YggdrasilTask.h
index b5d6af13..4e302195 100644
--- a/api/logic/minecraft/auth/YggdrasilTask.h
+++ b/api/logic/minecraft/auth/YggdrasilTask.h
@@ -31,121 +31,121 @@ class QNetworkReply;
*/
class YggdrasilTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit YggdrasilTask(MojangAccount * account, QObject *parent = 0);
- virtual ~YggdrasilTask() {};
-
- /**
- * assign a session to this task. the session will be filled with required infomration
- * upon completion
- */
- void assignSession(AuthSessionPtr session)
- {
- m_session = session;
- }
-
- /// get the assigned session for filling with information.
- AuthSessionPtr getAssignedSession()
- {
- return m_session;
- }
-
- /**
- * Class describing a Yggdrasil error response.
- */
- struct Error
- {
- QString m_errorMessageShort;
- QString m_errorMessageVerbose;
- QString m_cause;
- };
-
- enum AbortedBy
- {
- BY_NOTHING,
- BY_USER,
- BY_TIMEOUT
- } m_aborted = BY_NOTHING;
-
- /**
- * Enum for describing the state of the current task.
- * Used by the getStateMessage function to determine what the status message should be.
- */
- enum State
- {
- STATE_CREATED,
- STATE_SENDING_REQUEST,
- STATE_PROCESSING_RESPONSE,
- STATE_FAILED_SOFT, //!< soft failure. this generally means the user auth details haven't been invalidated
- STATE_FAILED_HARD, //!< hard failure. auth is invalid
- STATE_SUCCEEDED
- } m_state = STATE_CREATED;
+ explicit YggdrasilTask(MojangAccount * account, QObject *parent = 0);
+ virtual ~YggdrasilTask() {};
+
+ /**
+ * assign a session to this task. the session will be filled with required infomration
+ * upon completion
+ */
+ void assignSession(AuthSessionPtr session)
+ {
+ m_session = session;
+ }
+
+ /// get the assigned session for filling with information.
+ AuthSessionPtr getAssignedSession()
+ {
+ return m_session;
+ }
+
+ /**
+ * Class describing a Yggdrasil error response.
+ */
+ struct Error
+ {
+ QString m_errorMessageShort;
+ QString m_errorMessageVerbose;
+ QString m_cause;
+ };
+
+ enum AbortedBy
+ {
+ BY_NOTHING,
+ BY_USER,
+ BY_TIMEOUT
+ } m_aborted = BY_NOTHING;
+
+ /**
+ * Enum for describing the state of the current task.
+ * Used by the getStateMessage function to determine what the status message should be.
+ */
+ enum State
+ {
+ STATE_CREATED,
+ STATE_SENDING_REQUEST,
+ STATE_PROCESSING_RESPONSE,
+ STATE_FAILED_SOFT, //!< soft failure. this generally means the user auth details haven't been invalidated
+ STATE_FAILED_HARD, //!< hard failure. auth is invalid
+ STATE_SUCCEEDED
+ } m_state = STATE_CREATED;
protected:
- virtual void executeTask() override;
-
- /**
- * Gets the JSON object that will be sent to the authentication server.
- * Should be overridden by subclasses.
- */
- virtual QJsonObject getRequestContent() const = 0;
-
- /**
- * Gets the endpoint to POST to.
- * No leading slash.
- */
- virtual QString getEndpoint() const = 0;
-
- /**
- * Processes the response received from the server.
- * If an error occurred, this should emit a failed signal and return false.
- * If Yggdrasil gave an error response, it should call setError() first, and then return false.
- * Otherwise, it should return true.
- * Note: If the response from the server was blank, and the HTTP code was 200, this function is called with
- * an empty QJsonObject.
- */
- virtual void processResponse(QJsonObject responseData) = 0;
-
- /**
- * Processes an error response received from the server.
- * The default implementation will read data from Yggdrasil's standard error response format and set it as this task's Error.
- * \returns a QString error message that will be passed to emitFailed.
- */
- virtual void processError(QJsonObject responseData);
-
- /**
- * Returns the state message for the given state.
- * Used to set the status message for the task.
- * Should be overridden by subclasses that want to change messages for a given state.
- */
- virtual QString getStateMessage() const;
+ virtual void executeTask() override;
+
+ /**
+ * Gets the JSON object that will be sent to the authentication server.
+ * Should be overridden by subclasses.
+ */
+ virtual QJsonObject getRequestContent() const = 0;
+
+ /**
+ * Gets the endpoint to POST to.
+ * No leading slash.
+ */
+ virtual QString getEndpoint() const = 0;
+
+ /**
+ * Processes the response received from the server.
+ * If an error occurred, this should emit a failed signal and return false.
+ * If Yggdrasil gave an error response, it should call setError() first, and then return false.
+ * Otherwise, it should return true.
+ * Note: If the response from the server was blank, and the HTTP code was 200, this function is called with
+ * an empty QJsonObject.
+ */
+ virtual void processResponse(QJsonObject responseData) = 0;
+
+ /**
+ * Processes an error response received from the server.
+ * The default implementation will read data from Yggdrasil's standard error response format and set it as this task's Error.
+ * \returns a QString error message that will be passed to emitFailed.
+ */
+ virtual void processError(QJsonObject responseData);
+
+ /**
+ * Returns the state message for the given state.
+ * Used to set the status message for the task.
+ * Should be overridden by subclasses that want to change messages for a given state.
+ */
+ virtual QString getStateMessage() const;
protected
slots:
- void processReply();
- void refreshTimers(qint64, qint64);
- void heartbeat();
- void sslErrors(QList<QSslError>);
+ void processReply();
+ void refreshTimers(qint64, qint64);
+ void heartbeat();
+ void sslErrors(QList<QSslError>);
- void changeState(State newState, QString reason=QString());
+ void changeState(State newState, QString reason=QString());
public
slots:
- virtual bool abort() override;
- void abortByTimeout();
- State state();
+ virtual bool abort() override;
+ void abortByTimeout();
+ State state();
protected:
- // FIXME: segfault disaster waiting to happen
- MojangAccount *m_account = nullptr;
- QNetworkReply *m_netReply = nullptr;
- std::shared_ptr<Error> m_error;
- QTimer timeout_keeper;
- QTimer counter;
- int count = 0; // num msec since time reset
-
- const int timeout_max = 30000;
- const int time_step = 50;
-
- AuthSessionPtr m_session;
+ // FIXME: segfault disaster waiting to happen
+ MojangAccount *m_account = nullptr;
+ QNetworkReply *m_netReply = nullptr;
+ std::shared_ptr<Error> m_error;
+ QTimer timeout_keeper;
+ QTimer counter;
+ int count = 0; // num msec since time reset
+
+ const int timeout_max = 30000;
+ const int time_step = 50;
+
+ AuthSessionPtr m_session;
};
diff --git a/api/logic/minecraft/auth/flows/AuthenticateTask.cpp b/api/logic/minecraft/auth/flows/AuthenticateTask.cpp
index ff4e7d47..5e37f0ca 100644
--- a/api/logic/minecraft/auth/flows/AuthenticateTask.cpp
+++ b/api/logic/minecraft/auth/flows/AuthenticateTask.cpp
@@ -26,177 +26,177 @@
#include <QUuid>
AuthenticateTask::AuthenticateTask(MojangAccount * account, const QString &password,
- QObject *parent)
- : YggdrasilTask(account, parent), m_password(password)
+ QObject *parent)
+ : YggdrasilTask(account, parent), m_password(password)
{
}
QJsonObject AuthenticateTask::getRequestContent() const
{
- /*
- * {
- * "agent": { // optional
- * "name": "Minecraft", // So far this is the only encountered value
- * "version": 1 // This number might be increased
- * // by the vanilla client in the future
- * },
- * "username": "mojang account name", // Can be an email address or player name for
- // unmigrated accounts
- * "password": "mojang account password",
- * "clientToken": "client identifier" // optional
- * "requestUser": true/false // request the user structure
- * }
- */
- QJsonObject req;
-
- {
- QJsonObject agent;
- // C++ makes string literals void* for some stupid reason, so we have to tell it
- // QString... Thanks Obama.
- agent.insert("name", QString("Minecraft"));
- agent.insert("version", 1);
- req.insert("agent", agent);
- }
-
- req.insert("username", m_account->username());
- req.insert("password", m_password);
- req.insert("requestUser", true);
-
- // If we already have a client token, give it to the server.
- // Otherwise, let the server give us one.
-
- if(m_account->m_clientToken.isEmpty())
- {
- auto uuid = QUuid::createUuid();
- auto uuidString = uuid.toString().remove('{').remove('-').remove('}');
- m_account->m_clientToken = uuidString;
- }
- req.insert("clientToken", m_account->m_clientToken);
-
- return req;
+ /*
+ * {
+ * "agent": { // optional
+ * "name": "Minecraft", // So far this is the only encountered value
+ * "version": 1 // This number might be increased
+ * // by the vanilla client in the future
+ * },
+ * "username": "mojang account name", // Can be an email address or player name for
+ // unmigrated accounts
+ * "password": "mojang account password",
+ * "clientToken": "client identifier" // optional
+ * "requestUser": true/false // request the user structure
+ * }
+ */
+ QJsonObject req;
+
+ {
+ QJsonObject agent;
+ // C++ makes string literals void* for some stupid reason, so we have to tell it
+ // QString... Thanks Obama.
+ agent.insert("name", QString("Minecraft"));
+ agent.insert("version", 1);
+ req.insert("agent", agent);
+ }
+
+ req.insert("username", m_account->username());
+ req.insert("password", m_password);
+ req.insert("requestUser", true);
+
+ // If we already have a client token, give it to the server.
+ // Otherwise, let the server give us one.
+
+ if(m_account->m_clientToken.isEmpty())
+ {
+ auto uuid = QUuid::createUuid();
+ auto uuidString = uuid.toString().remove('{').remove('-').remove('}');
+ m_account->m_clientToken = uuidString;
+ }
+ req.insert("clientToken", m_account->m_clientToken);
+
+ return req;
}
void AuthenticateTask::processResponse(QJsonObject responseData)
{
- // Read the response data. We need to get the client token, access token, and the selected
- // profile.
- qDebug() << "Processing authentication response.";
- // qDebug() << responseData;
- // If we already have a client token, make sure the one the server gave us matches our
- // existing one.
- qDebug() << "Getting client token.";
- QString clientToken = responseData.value("clientToken").toString("");
- if (clientToken.isEmpty())
- {
- // Fail if the server gave us an empty client token
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
- return;
- }
- if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken)
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
- return;
- }
- // Set the client token.
- m_account->m_clientToken = clientToken;
-
- // Now, we set the access token.
- qDebug() << "Getting access token.";
- QString accessToken = responseData.value("accessToken").toString("");
- if (accessToken.isEmpty())
- {
- // Fail if the server didn't give us an access token.
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
- return;
- }
- // Set the access token.
- m_account->m_accessToken = accessToken;
-
- // Now we load the list of available profiles.
- // Mojang hasn't yet implemented the profile system,
- // but we might as well support what's there so we
- // don't have trouble implementing it later.
- qDebug() << "Loading profile list.";
- QJsonArray availableProfiles = responseData.value("availableProfiles").toArray();
- QList<AccountProfile> loadedProfiles;
- for (auto iter : availableProfiles)
- {
- QJsonObject profile = iter.toObject();
- // Profiles are easy, we just need their ID and name.
- QString id = profile.value("id").toString("");
- QString name = profile.value("name").toString("");
- bool legacy = profile.value("legacy").toBool(false);
-
- if (id.isEmpty() || name.isEmpty())
- {
- // This should never happen, but we might as well
- // warn about it if it does so we can debug it easily.
- // You never know when Mojang might do something truly derpy.
- qWarning() << "Found entry in available profiles list with missing ID or name "
- "field. Ignoring it.";
- }
-
- // Now, add a new AccountProfile entry to the list.
- loadedProfiles.append({id, name, legacy});
- }
- // Put the list of profiles we loaded into the MojangAccount object.
- m_account->m_profiles = loadedProfiles;
-
- // Finally, we set the current profile to the correct value. This is pretty simple.
- // We do need to make sure that the current profile that the server gave us
- // is actually in the available profiles list.
- // If it isn't, we'll just fail horribly (*shouldn't* ever happen, but you never know).
- qDebug() << "Setting current profile.";
- QJsonObject currentProfile = responseData.value("selectedProfile").toObject();
- QString currentProfileId = currentProfile.value("id").toString("");
- if (currentProfileId.isEmpty())
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify a currently selected profile. The account exists, but likely isn't premium."));
- return;
- }
- if (!m_account->setCurrentProfile(currentProfileId))
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server specified a selected profile that wasn't in the available profiles list."));
- return;
- }
-
- // this is what the vanilla launcher passes to the userProperties launch param
- if (responseData.contains("user"))
- {
- User u;
- auto obj = responseData.value("user").toObject();
- u.id = obj.value("id").toString();
- auto propArray = obj.value("properties").toArray();
- for (auto prop : propArray)
- {
- auto propTuple = prop.toObject();
- auto name = propTuple.value("name").toString();
- auto value = propTuple.value("value").toString();
- u.properties.insert(name, value);
- }
- m_account->m_user = u;
- }
-
- // We've made it through the minefield of possible errors. Return true to indicate that
- // we've succeeded.
- qDebug() << "Finished reading authentication response.";
- changeState(STATE_SUCCEEDED);
+ // Read the response data. We need to get the client token, access token, and the selected
+ // profile.
+ qDebug() << "Processing authentication response.";
+ // qDebug() << responseData;
+ // If we already have a client token, make sure the one the server gave us matches our
+ // existing one.
+ qDebug() << "Getting client token.";
+ QString clientToken = responseData.value("clientToken").toString("");
+ if (clientToken.isEmpty())
+ {
+ // Fail if the server gave us an empty client token
+ changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
+ return;
+ }
+ if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken)
+ {
+ changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
+ return;
+ }
+ // Set the client token.
+ m_account->m_clientToken = clientToken;
+
+ // Now, we set the access token.
+ qDebug() << "Getting access token.";
+ QString accessToken = responseData.value("accessToken").toString("");
+ if (accessToken.isEmpty())
+ {
+ // Fail if the server didn't give us an access token.
+ changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
+ return;
+ }
+ // Set the access token.
+ m_account->m_accessToken = accessToken;
+
+ // Now we load the list of available profiles.
+ // Mojang hasn't yet implemented the profile system,
+ // but we might as well support what's there so we
+ // don't have trouble implementing it later.
+ qDebug() << "Loading profile list.";
+ QJsonArray availableProfiles = responseData.value("availableProfiles").toArray();
+ QList<AccountProfile> loadedProfiles;
+ for (auto iter : availableProfiles)
+ {
+ QJsonObject profile = iter.toObject();
+ // Profiles are easy, we just need their ID and name.
+ QString id = profile.value("id").toString("");
+ QString name = profile.value("name").toString("");
+ bool legacy = profile.value("legacy").toBool(false);
+
+ if (id.isEmpty() || name.isEmpty())
+ {
+ // This should never happen, but we might as well
+ // warn about it if it does so we can debug it easily.
+ // You never know when Mojang might do something truly derpy.
+ qWarning() << "Found entry in available profiles list with missing ID or name "
+ "field. Ignoring it.";
+ }
+
+ // Now, add a new AccountProfile entry to the list.
+ loadedProfiles.append({id, name, legacy});
+ }
+ // Put the list of profiles we loaded into the MojangAccount object.
+ m_account->m_profiles = loadedProfiles;
+
+ // Finally, we set the current profile to the correct value. This is pretty simple.
+ // We do need to make sure that the current profile that the server gave us
+ // is actually in the available profiles list.
+ // If it isn't, we'll just fail horribly (*shouldn't* ever happen, but you never know).
+ qDebug() << "Setting current profile.";
+ QJsonObject currentProfile = responseData.value("selectedProfile").toObject();
+ QString currentProfileId = currentProfile.value("id").toString("");
+ if (currentProfileId.isEmpty())
+ {
+ changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify a currently selected profile. The account exists, but likely isn't premium."));
+ return;
+ }
+ if (!m_account->setCurrentProfile(currentProfileId))
+ {
+ changeState(STATE_FAILED_HARD, tr("Authentication server specified a selected profile that wasn't in the available profiles list."));
+ return;
+ }
+
+ // this is what the vanilla launcher passes to the userProperties launch param
+ if (responseData.contains("user"))
+ {
+ User u;
+ auto obj = responseData.value("user").toObject();
+ u.id = obj.value("id").toString();
+ auto propArray = obj.value("properties").toArray();
+ for (auto prop : propArray)
+ {
+ auto propTuple = prop.toObject();
+ auto name = propTuple.value("name").toString();
+ auto value = propTuple.value("value").toString();
+ u.properties.insert(name, value);
+ }
+ m_account->m_user = u;
+ }
+
+ // We've made it through the minefield of possible errors. Return true to indicate that
+ // we've succeeded.
+ qDebug() << "Finished reading authentication response.";
+ changeState(STATE_SUCCEEDED);
}
QString AuthenticateTask::getEndpoint() const
{
- return "authenticate";
+ return "authenticate";
}
QString AuthenticateTask::getStateMessage() const
{
- switch (m_state)
- {
- case STATE_SENDING_REQUEST:
- return tr("Authenticating: Sending request...");
- case STATE_PROCESSING_RESPONSE:
- return tr("Authenticating: Processing response...");
- default:
- return YggdrasilTask::getStateMessage();
- }
+ switch (m_state)
+ {
+ case STATE_SENDING_REQUEST:
+ return tr("Authenticating: Sending request...");
+ case STATE_PROCESSING_RESPONSE:
+ return tr("Authenticating: Processing response...");
+ default:
+ return YggdrasilTask::getStateMessage();
+ }
}
diff --git a/api/logic/minecraft/auth/flows/AuthenticateTask.h b/api/logic/minecraft/auth/flows/AuthenticateTask.h
index ab7a6e64..71f0eab7 100644
--- a/api/logic/minecraft/auth/flows/AuthenticateTask.h
+++ b/api/logic/minecraft/auth/flows/AuthenticateTask.h
@@ -28,19 +28,19 @@
*/
class AuthenticateTask : public YggdrasilTask
{
- Q_OBJECT
+ Q_OBJECT
public:
- AuthenticateTask(MojangAccount *account, const QString &password, QObject *parent = 0);
+ AuthenticateTask(MojangAccount *account, const QString &password, QObject *parent = 0);
protected:
- virtual QJsonObject getRequestContent() const override;
+ virtual QJsonObject getRequestContent() const override;
- virtual QString getEndpoint() const override;
+ virtual QString getEndpoint() const override;
- virtual void processResponse(QJsonObject responseData) override;
+ virtual void processResponse(QJsonObject responseData) override;
- virtual QString getStateMessage() const override;
+ virtual QString getStateMessage() const override;
private:
- QString m_password;
+ QString m_password;
};
diff --git a/api/logic/minecraft/auth/flows/RefreshTask.cpp b/api/logic/minecraft/auth/flows/RefreshTask.cpp
index 73050907..f6fe4757 100644
--- a/api/logic/minecraft/auth/flows/RefreshTask.cpp
+++ b/api/logic/minecraft/auth/flows/RefreshTask.cpp
@@ -29,116 +29,116 @@ RefreshTask::RefreshTask(MojangAccount *account) : YggdrasilTask(account)
QJsonObject RefreshTask::getRequestContent() const
{
- /*
- * {
- * "clientToken": "client identifier"
- * "accessToken": "current access token to be refreshed"
- * "selectedProfile": // specifying this causes errors
- * {
- * "id": "profile ID"
- * "name": "profile name"
- * }
- * "requestUser": true/false // request the user structure
- * }
- */
- QJsonObject req;
- req.insert("clientToken", m_account->m_clientToken);
- req.insert("accessToken", m_account->m_accessToken);
- /*
- {
- auto currentProfile = m_account->currentProfile();
- QJsonObject profile;
- profile.insert("id", currentProfile->id());
- profile.insert("name", currentProfile->name());
- req.insert("selectedProfile", profile);
- }
- */
- req.insert("requestUser", true);
+ /*
+ * {
+ * "clientToken": "client identifier"
+ * "accessToken": "current access token to be refreshed"
+ * "selectedProfile": // specifying this causes errors
+ * {
+ * "id": "profile ID"
+ * "name": "profile name"
+ * }
+ * "requestUser": true/false // request the user structure
+ * }
+ */
+ QJsonObject req;
+ req.insert("clientToken", m_account->m_clientToken);
+ req.insert("accessToken", m_account->m_accessToken);
+ /*
+ {
+ auto currentProfile = m_account->currentProfile();
+ QJsonObject profile;
+ profile.insert("id", currentProfile->id());
+ profile.insert("name", currentProfile->name());
+ req.insert("selectedProfile", profile);
+ }
+ */
+ req.insert("requestUser", true);
- return req;
+ return req;
}
void RefreshTask::processResponse(QJsonObject responseData)
{
- // Read the response data. We need to get the client token, access token, and the selected
- // profile.
- qDebug() << "Processing authentication response.";
+ // Read the response data. We need to get the client token, access token, and the selected
+ // profile.
+ qDebug() << "Processing authentication response.";
- // qDebug() << responseData;
- // If we already have a client token, make sure the one the server gave us matches our
- // existing one.
- QString clientToken = responseData.value("clientToken").toString("");
- if (clientToken.isEmpty())
- {
- // Fail if the server gave us an empty client token
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
- return;
- }
- if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken)
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
- return;
- }
+ // qDebug() << responseData;
+ // If we already have a client token, make sure the one the server gave us matches our
+ // existing one.
+ QString clientToken = responseData.value("clientToken").toString("");
+ if (clientToken.isEmpty())
+ {
+ // Fail if the server gave us an empty client token
+ changeState(STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
+ return;
+ }
+ if (!m_account->m_clientToken.isEmpty() && clientToken != m_account->m_clientToken)
+ {
+ changeState(STATE_FAILED_HARD, tr("Authentication server attempted to change the client token. This isn't supported."));
+ return;
+ }
- // Now, we set the access token.
- qDebug() << "Getting new access token.";
- QString accessToken = responseData.value("accessToken").toString("");
- if (accessToken.isEmpty())
- {
- // Fail if the server didn't give us an access token.
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
- return;
- }
+ // Now, we set the access token.
+ qDebug() << "Getting new access token.";
+ QString accessToken = responseData.value("accessToken").toString("");
+ if (accessToken.isEmpty())
+ {
+ // Fail if the server didn't give us an access token.
+ changeState(STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
+ return;
+ }
- // we validate that the server responded right. (our current profile = returned current
- // profile)
- QJsonObject currentProfile = responseData.value("selectedProfile").toObject();
- QString currentProfileId = currentProfile.value("id").toString("");
- if (m_account->currentProfile()->id != currentProfileId)
- {
- changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify the same prefile as expected."));
- return;
- }
+ // we validate that the server responded right. (our current profile = returned current
+ // profile)
+ QJsonObject currentProfile = responseData.value("selectedProfile").toObject();
+ QString currentProfileId = currentProfile.value("id").toString("");
+ if (m_account->currentProfile()->id != currentProfileId)
+ {
+ changeState(STATE_FAILED_HARD, tr("Authentication server didn't specify the same prefile as expected."));
+ return;
+ }
- // this is what the vanilla launcher passes to the userProperties launch param
- if (responseData.contains("user"))
- {
- User u;
- auto obj = responseData.value("user").toObject();
- u.id = obj.value("id").toString();
- auto propArray = obj.value("properties").toArray();
- for (auto prop : propArray)
- {
- auto propTuple = prop.toObject();
- auto name = propTuple.value("name").toString();
- auto value = propTuple.value("value").toString();
- u.properties.insert(name, value);
- }
- m_account->m_user = u;
- }
+ // this is what the vanilla launcher passes to the userProperties launch param
+ if (responseData.contains("user"))
+ {
+ User u;
+ auto obj = responseData.value("user").toObject();
+ u.id = obj.value("id").toString();
+ auto propArray = obj.value("properties").toArray();
+ for (auto prop : propArray)
+ {
+ auto propTuple = prop.toObject();
+ auto name = propTuple.value("name").toString();
+ auto value = propTuple.value("value").toString();
+ u.properties.insert(name, value);
+ }
+ m_account->m_user = u;
+ }
- // We've made it through the minefield of possible errors. Return true to indicate that
- // we've succeeded.
- qDebug() << "Finished reading refresh response.";
- // Reset the access token.
- m_account->m_accessToken = accessToken;
- changeState(STATE_SUCCEEDED);
+ // We've made it through the minefield of possible errors. Return true to indicate that
+ // we've succeeded.
+ qDebug() << "Finished reading refresh response.";
+ // Reset the access token.
+ m_account->m_accessToken = accessToken;
+ changeState(STATE_SUCCEEDED);
}
QString RefreshTask::getEndpoint() const
{
- return "refresh";
+ return "refresh";
}
QString RefreshTask::getStateMessage() const
{
- switch (m_state)
- {
- case STATE_SENDING_REQUEST:
- return tr("Refreshing login token...");
- case STATE_PROCESSING_RESPONSE:
- return tr("Refreshing login token: Processing response...");
- default:
- return YggdrasilTask::getStateMessage();
- }
+ switch (m_state)
+ {
+ case STATE_SENDING_REQUEST:
+ return tr("Refreshing login token...");
+ case STATE_PROCESSING_RESPONSE:
+ return tr("Refreshing login token: Processing response...");
+ default:
+ return YggdrasilTask::getStateMessage();
+ }
}
diff --git a/api/logic/minecraft/auth/flows/RefreshTask.h b/api/logic/minecraft/auth/flows/RefreshTask.h
index a97b54e6..ff586396 100644
--- a/api/logic/minecraft/auth/flows/RefreshTask.h
+++ b/api/logic/minecraft/auth/flows/RefreshTask.h
@@ -28,17 +28,17 @@
*/
class RefreshTask : public YggdrasilTask
{
- Q_OBJECT
+ Q_OBJECT
public:
- RefreshTask(MojangAccount * account);
+ RefreshTask(MojangAccount * account);
protected:
- virtual QJsonObject getRequestContent() const override;
+ virtual QJsonObject getRequestContent() const override;
- virtual QString getEndpoint() const override;
+ virtual QString getEndpoint() const override;
- virtual void processResponse(QJsonObject responseData) override;
+ virtual void processResponse(QJsonObject responseData) override;
- virtual QString getStateMessage() const override;
+ virtual QString getStateMessage() const override;
};
diff --git a/api/logic/minecraft/auth/flows/ValidateTask.cpp b/api/logic/minecraft/auth/flows/ValidateTask.cpp
index b6d6c823..e82678c8 100644
--- a/api/logic/minecraft/auth/flows/ValidateTask.cpp
+++ b/api/logic/minecraft/auth/flows/ValidateTask.cpp
@@ -25,37 +25,37 @@
#include <QDebug>
ValidateTask::ValidateTask(MojangAccount * account, QObject *parent)
- : YggdrasilTask(account, parent)
+ : YggdrasilTask(account, parent)
{
}
QJsonObject ValidateTask::getRequestContent() const
{
- QJsonObject req;
- req.insert("accessToken", m_account->m_accessToken);
- return req;
+ QJsonObject req;
+ req.insert("accessToken", m_account->m_accessToken);
+ return req;
}
void ValidateTask::processResponse(QJsonObject responseData)
{
- // Assume that if processError wasn't called, then the request was successful.
- changeState(YggdrasilTask::STATE_SUCCEEDED);
+ // Assume that if processError wasn't called, then the request was successful.
+ changeState(YggdrasilTask::STATE_SUCCEEDED);
}
QString ValidateTask::getEndpoint() const
{
- return "validate";
+ return "validate";
}
QString ValidateTask::getStateMessage() const
{
- switch (m_state)
- {
- case YggdrasilTask::STATE_SENDING_REQUEST:
- return tr("Validating access token: Sending request...");
- case YggdrasilTask::STATE_PROCESSING_RESPONSE:
- return tr("Validating access token: Processing response...");
- default:
- return YggdrasilTask::getStateMessage();
- }
+ switch (m_state)
+ {
+ case YggdrasilTask::STATE_SENDING_REQUEST:
+ return tr("Validating access token: Sending request...");
+ case YggdrasilTask::STATE_PROCESSING_RESPONSE:
+ return tr("Validating access token: Processing response...");
+ default:
+ return YggdrasilTask::getStateMessage();
+ }
}
diff --git a/api/logic/minecraft/auth/flows/ValidateTask.h b/api/logic/minecraft/auth/flows/ValidateTask.h
index 77de24c7..87876fb8 100644
--- a/api/logic/minecraft/auth/flows/ValidateTask.h
+++ b/api/logic/minecraft/auth/flows/ValidateTask.h
@@ -30,18 +30,18 @@
*/
class ValidateTask : public YggdrasilTask
{
- Q_OBJECT
+ Q_OBJECT
public:
- ValidateTask(MojangAccount *account, QObject *parent = 0);
+ ValidateTask(MojangAccount *account, QObject *parent = 0);
protected:
- virtual QJsonObject getRequestContent() const override;
+ virtual QJsonObject getRequestContent() const override;
- virtual QString getEndpoint() const override;
+ virtual QString getEndpoint() const override;
- virtual void processResponse(QJsonObject responseData) override;
+ virtual void processResponse(QJsonObject responseData) override;
- virtual QString getStateMessage() const override;
+ virtual QString getStateMessage() const override;
private:
};
diff --git a/api/logic/minecraft/forge/ForgeXzDownload.cpp b/api/logic/minecraft/forge/ForgeXzDownload.cpp
index 4d82a58a..4083bdea 100644
--- a/api/logic/minecraft/forge/ForgeXzDownload.cpp
+++ b/api/logic/minecraft/forge/ForgeXzDownload.cpp
@@ -25,138 +25,138 @@
ForgeXzDownload::ForgeXzDownload(QString relative_path, MetaEntryPtr entry) : NetAction()
{
- m_entry = entry;
- m_target_path = entry->getFullPath();
- m_pack200_xz_file.setFileTemplate("./dl_temp.XXXXXX");
- m_status = Job_NotStarted;
- m_url_path = relative_path;
- m_url = "http://files.minecraftforge.net/maven/" + m_url_path + ".pack.xz";
+ m_entry = entry;
+ m_target_path = entry->getFullPath();
+ m_pack200_xz_file.setFileTemplate("./dl_temp.XXXXXX");
+ m_status = Job_NotStarted;
+ m_url_path = relative_path;
+ m_url = "http://files.minecraftforge.net/maven/" + m_url_path + ".pack.xz";
}
void ForgeXzDownload::start()
{
- if(m_status == Job_Aborted)
- {
- qWarning() << "Attempt to start an aborted Download:" << m_url.toString();
- emit aborted(m_index_within_job);
- return;
- }
- m_status = Job_InProgress;
- if (!m_entry->isStale())
- {
- m_status = Job_Finished;
- emit succeeded(m_index_within_job);
- return;
- }
- // can we actually create the real, final file?
- if (!FS::ensureFilePathExists(m_target_path))
- {
- m_status = Job_Failed;
- emit failed(m_index_within_job);
- return;
- }
-
- qDebug() << "Downloading " << m_url.toString();
- QNetworkRequest request(m_url);
- request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1());
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
-
- QNetworkReply *rep = ENV.qnam().get(request);
-
- m_reply.reset(rep);
- connect(rep, SIGNAL(downloadProgress(qint64, qint64)), SLOT(downloadProgress(qint64, qint64)));
- connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
+ if(m_status == Job_Aborted)
+ {
+ qWarning() << "Attempt to start an aborted Download:" << m_url.toString();
+ emit aborted(m_index_within_job);
+ return;
+ }
+ m_status = Job_InProgress;
+ if (!m_entry->isStale())
+ {
+ m_status = Job_Finished;
+ emit succeeded(m_index_within_job);
+ return;
+ }
+ // can we actually create the real, final file?
+ if (!FS::ensureFilePathExists(m_target_path))
+ {
+ m_status = Job_Failed;
+ emit failed(m_index_within_job);
+ return;
+ }
+
+ qDebug() << "Downloading " << m_url.toString();
+ QNetworkRequest request(m_url);
+ request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1());
+ request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
+
+ QNetworkReply *rep = ENV.qnam().get(request);
+
+ m_reply.reset(rep);
+ connect(rep, SIGNAL(downloadProgress(qint64, qint64)), SLOT(downloadProgress(qint64, qint64)));
+ connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
+ connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError)));
+ connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
}
void ForgeXzDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
+ m_total_progress = bytesTotal;
+ m_progress = bytesReceived;
+ emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
}
void ForgeXzDownload::downloadError(QNetworkReply::NetworkError error)
{
- if(error == QNetworkReply::OperationCanceledError)
- {
- qCritical() << "Aborted " << m_url.toString();
- m_status = Job_Aborted;
- }
- else
- {
- // error happened during download.
- qCritical() << "Failed " << m_url.toString() << " with reason " << error;
- m_status = Job_Failed;
- }
+ if(error == QNetworkReply::OperationCanceledError)
+ {
+ qCritical() << "Aborted " << m_url.toString();
+ m_status = Job_Aborted;
+ }
+ else
+ {
+ // error happened during download.
+ qCritical() << "Failed " << m_url.toString() << " with reason " << error;
+ m_status = Job_Failed;
+ }
}
void ForgeXzDownload::failAndTryNextMirror()
{
- m_status = Job_Failed;
- emit failed(m_index_within_job);
+ m_status = Job_Failed;
+ emit failed(m_index_within_job);
}
void ForgeXzDownload::downloadFinished()
{
- // if the download succeeded
- if (m_status != Job_Failed && m_status != Job_Aborted)
- {
- // nothing went wrong...
- m_status = Job_Finished;
- if (m_pack200_xz_file.isOpen())
- {
- // we actually downloaded something! process and isntall it
- decompressAndInstall();
- return;
- }
- else
- {
- // something bad happened -- on the local machine!
- m_status = Job_Failed;
- m_pack200_xz_file.remove();
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
- }
- else if(m_status == Job_Aborted)
- {
- m_pack200_xz_file.remove();
- m_reply.reset();
- emit failed(m_index_within_job);
- emit aborted(m_index_within_job);
- return;
- }
- // else the download failed
- else
- {
- m_status = Job_Failed;
- m_pack200_xz_file.close();
- m_pack200_xz_file.remove();
- m_reply.reset();
- failAndTryNextMirror();
- return;
- }
+ // if the download succeeded
+ if (m_status != Job_Failed && m_status != Job_Aborted)
+ {
+ // nothing went wrong...
+ m_status = Job_Finished;
+ if (m_pack200_xz_file.isOpen())
+ {
+ // we actually downloaded something! process and isntall it
+ decompressAndInstall();
+ return;
+ }
+ else
+ {
+ // something bad happened -- on the local machine!
+ m_status = Job_Failed;
+ m_pack200_xz_file.remove();
+ m_reply.reset();
+ emit failed(m_index_within_job);
+ return;
+ }
+ }
+ else if(m_status == Job_Aborted)
+ {
+ m_pack200_xz_file.remove();
+ m_reply.reset();
+ emit failed(m_index_within_job);
+ emit aborted(m_index_within_job);
+ return;
+ }
+ // else the download failed
+ else
+ {
+ m_status = Job_Failed;
+ m_pack200_xz_file.close();
+ m_pack200_xz_file.remove();
+ m_reply.reset();
+ failAndTryNextMirror();
+ return;
+ }
}
void ForgeXzDownload::downloadReadyRead()
{
- if (!m_pack200_xz_file.isOpen())
- {
- if (!m_pack200_xz_file.open())
- {
- /*
- * Can't open the file... the job failed
- */
- m_reply->abort();
- emit failed(m_index_within_job);
- return;
- }
- }
- m_pack200_xz_file.write(m_reply->readAll());
+ if (!m_pack200_xz_file.isOpen())
+ {
+ if (!m_pack200_xz_file.open())
+ {
+ /*
+ * Can't open the file... the job failed
+ */
+ m_reply->abort();
+ emit failed(m_index_within_job);
+ return;
+ }
+ }
+ m_pack200_xz_file.write(m_reply->readAll());
}
#include "xz.h"
@@ -169,225 +169,225 @@ const size_t buffer_size = 8196;
// NOTE: once this gets here, it can't be aborted anymore. we don't care.
void ForgeXzDownload::decompressAndInstall()
{
- // rewind the downloaded temp file
- m_pack200_xz_file.seek(0);
- // de-xz'd file
- QTemporaryFile pack200_file("./dl_temp.XXXXXX");
- pack200_file.open();
-
- bool xz_success = false;
- // first, de-xz
- {
- uint8_t in[buffer_size];
- uint8_t out[buffer_size];
- struct xz_buf b;
- struct xz_dec *s;
- enum xz_ret ret;
- xz_crc32_init();
- xz_crc64_init();
- s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
- if (s == nullptr)
- {
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
- }
- b.in = in;
- b.in_pos = 0;
- b.in_size = 0;
- b.out = out;
- b.out_pos = 0;
- b.out_size = buffer_size;
- while (!xz_success)
- {
- if (b.in_pos == b.in_size)
- {
- b.in_size = m_pack200_xz_file.read((char *)in, sizeof(in));
- b.in_pos = 0;
- }
-
- ret = xz_dec_run(s, &b);
-
- if (b.out_pos == sizeof(out))
- {
- auto wresult = pack200_file.write((char *)out, b.out_pos);
- if (wresult < 0 || size_t(wresult) != b.out_pos)
- {
- // msg = "Write error\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
- }
-
- b.out_pos = 0;
- }
-
- if (ret == XZ_OK)
- continue;
-
- if (ret == XZ_UNSUPPORTED_CHECK)
- {
- // unsupported check. this is OK, but we should log this
- continue;
- }
-
- auto wresult = pack200_file.write((char *)out, b.out_pos);
- if (wresult < 0 || size_t(wresult) != b.out_pos)
- {
- // write error
- pack200_file.close();
- xz_dec_end(s);
- return;
- }
-
- switch (ret)
- {
- case XZ_STREAM_END:
- xz_dec_end(s);
- xz_success = true;
- break;
-
- case XZ_MEM_ERROR:
- qCritical() << "Memory allocation failed\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_MEMLIMIT_ERROR:
- qCritical() << "Memory usage limit reached\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_FORMAT_ERROR:
- qCritical() << "Not a .xz file\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_OPTIONS_ERROR:
- qCritical() << "Unsupported options in the .xz headers\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- case XZ_DATA_ERROR:
- case XZ_BUF_ERROR:
- qCritical() << "File is corrupt\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
-
- default:
- qCritical() << "Bug!\n";
- xz_dec_end(s);
- failAndTryNextMirror();
- return;
- }
- }
- }
- m_pack200_xz_file.remove();
-
- // revert pack200
- pack200_file.seek(0);
- int handle_in = pack200_file.handle();
- // FIXME: dispose of file handles, pointers and the like. Ideally wrap in objects.
- if(handle_in == -1)
- {
- qCritical() << "Error reopening " << pack200_file.fileName();
- failAndTryNextMirror();
- return;
- }
- int handle_in_dup = dup (handle_in);
- if(handle_in_dup == -1)
- {
- qCritical() << "Error reopening " << pack200_file.fileName();
- failAndTryNextMirror();
- return;
- }
- FILE *file_in = fdopen (handle_in_dup, "rb");
- if(!file_in)
- {
- qCritical() << "Error reopening " << pack200_file.fileName();
- failAndTryNextMirror();
- return;
- }
- QFile qfile_out(m_target_path);
- if(!qfile_out.open(QIODevice::WriteOnly))
- {
- qCritical() << "Error opening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- int handle_out = qfile_out.handle();
- if(handle_out == -1)
- {
- qCritical() << "Error opening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- int handle_out_dup = dup (handle_out);
- if(handle_out_dup == -1)
- {
- qCritical() << "Error reopening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- FILE *file_out = fdopen (handle_out_dup, "wb");
- if(!file_out)
- {
- qCritical() << "Error opening " << qfile_out.fileName();
- failAndTryNextMirror();
- return;
- }
- try
- {
- // NOTE: this takes ownership of both FILE pointers. That's why we duplicate them above.
- unpack_200(file_in, file_out);
- }
- catch (const std::runtime_error &err)
- {
- m_status = Job_Failed;
- qCritical() << "Error unpacking " << pack200_file.fileName() << " : " << err.what();
- QFile f(m_target_path);
- if (f.exists())
- f.remove();
- failAndTryNextMirror();
- return;
- }
- pack200_file.remove();
-
- QFile jar_file(m_target_path);
-
- if (!jar_file.open(QIODevice::ReadOnly))
- {
- jar_file.remove();
- failAndTryNextMirror();
- return;
- }
- auto hash = QCryptographicHash::hash(jar_file.readAll(), QCryptographicHash::Md5);
- m_entry->setMD5Sum(hash.toHex().constData());
- jar_file.close();
-
- QFileInfo output_file_info(m_target_path);
- m_entry->setETag(m_reply->rawHeader("ETag").constData());
- m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch());
- m_entry->setStale(false);
- ENV.metacache()->updateEntry(m_entry);
-
- m_reply.reset();
- emit succeeded(m_index_within_job);
+ // rewind the downloaded temp file
+ m_pack200_xz_file.seek(0);
+ // de-xz'd file
+ QTemporaryFile pack200_file("./dl_temp.XXXXXX");
+ pack200_file.open();
+
+ bool xz_success = false;
+ // first, de-xz
+ {
+ uint8_t in[buffer_size];
+ uint8_t out[buffer_size];
+ struct xz_buf b;
+ struct xz_dec *s;
+ enum xz_ret ret;
+ xz_crc32_init();
+ xz_crc64_init();
+ s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
+ if (s == nullptr)
+ {
+ xz_dec_end(s);
+ failAndTryNextMirror();
+ return;
+ }
+ b.in = in;
+ b.in_pos = 0;
+ b.in_size = 0;
+ b.out = out;
+ b.out_pos = 0;
+ b.out_size = buffer_size;
+ while (!xz_success)
+ {
+ if (b.in_pos == b.in_size)
+ {
+ b.in_size = m_pack200_xz_file.read((char *)in, sizeof(in));
+ b.in_pos = 0;
+ }
+
+ ret = xz_dec_run(s, &b);
+
+ if (b.out_pos == sizeof(out))
+ {
+ auto wresult = pack200_file.write((char *)out, b.out_pos);
+ if (wresult < 0 || size_t(wresult) != b.out_pos)
+ {
+ // msg = "Write error\n";
+ xz_dec_end(s);
+ failAndTryNextMirror();
+ return;
+ }
+
+ b.out_pos = 0;
+ }
+
+ if (ret == XZ_OK)
+ continue;
+
+ if (ret == XZ_UNSUPPORTED_CHECK)
+ {
+ // unsupported check. this is OK, but we should log this
+ continue;
+ }
+
+ auto wresult = pack200_file.write((char *)out, b.out_pos);
+ if (wresult < 0 || size_t(wresult) != b.out_pos)
+ {
+ // write error
+ pack200_file.close();
+ xz_dec_end(s);
+ return;
+ }
+
+ switch (ret)
+ {
+ case XZ_STREAM_END:
+ xz_dec_end(s);
+ xz_success = true;
+ break;
+
+ case XZ_MEM_ERROR:
+ qCritical() << "Memory allocation failed\n";
+ xz_dec_end(s);
+ failAndTryNextMirror();
+ return;
+
+ case XZ_MEMLIMIT_ERROR:
+ qCritical() << "Memory usage limit reached\n";
+ xz_dec_end(s);
+ failAndTryNextMirror();
+ return;
+
+ case XZ_FORMAT_ERROR:
+ qCritical() << "Not a .xz file\n";
+ xz_dec_end(s);
+ failAndTryNextMirror();
+ return;
+
+ case XZ_OPTIONS_ERROR:
+ qCritical() << "Unsupported options in the .xz headers\n";
+ xz_dec_end(s);
+ failAndTryNextMirror();
+ return;
+
+ case XZ_DATA_ERROR:
+ case XZ_BUF_ERROR:
+ qCritical() << "File is corrupt\n";
+ xz_dec_end(s);
+ failAndTryNextMirror();
+ return;
+
+ default:
+ qCritical() << "Bug!\n";
+ xz_dec_end(s);
+ failAndTryNextMirror();
+ return;
+ }
+ }
+ }
+ m_pack200_xz_file.remove();
+
+ // revert pack200
+ pack200_file.seek(0);
+ int handle_in = pack200_file.handle();
+ // FIXME: dispose of file handles, pointers and the like. Ideally wrap in objects.
+ if(handle_in == -1)
+ {
+ qCritical() << "Error reopening " << pack200_file.fileName();
+ failAndTryNextMirror();
+ return;
+ }
+ int handle_in_dup = dup (handle_in);
+ if(handle_in_dup == -1)
+ {
+ qCritical() << "Error reopening " << pack200_file.fileName();
+ failAndTryNextMirror();
+ return;
+ }
+ FILE *file_in = fdopen (handle_in_dup, "rb");
+ if(!file_in)
+ {
+ qCritical() << "Error reopening " << pack200_file.fileName();
+ failAndTryNextMirror();
+ return;
+ }
+ QFile qfile_out(m_target_path);
+ if(!qfile_out.open(QIODevice::WriteOnly))
+ {
+ qCritical() << "Error opening " << qfile_out.fileName();
+ failAndTryNextMirror();
+ return;
+ }
+ int handle_out = qfile_out.handle();
+ if(handle_out == -1)
+ {
+ qCritical() << "Error opening " << qfile_out.fileName();
+ failAndTryNextMirror();
+ return;
+ }
+ int handle_out_dup = dup (handle_out);
+ if(handle_out_dup == -1)
+ {
+ qCritical() << "Error reopening " << qfile_out.fileName();
+ failAndTryNextMirror();
+ return;
+ }
+ FILE *file_out = fdopen (handle_out_dup, "wb");
+ if(!file_out)
+ {
+ qCritical() << "Error opening " << qfile_out.fileName();
+ failAndTryNextMirror();
+ return;
+ }
+ try
+ {
+ // NOTE: this takes ownership of both FILE pointers. That's why we duplicate them above.
+ unpack_200(file_in, file_out);
+ }
+ catch (const std::runtime_error &err)
+ {
+ m_status = Job_Failed;
+ qCritical() << "Error unpacking " << pack200_file.fileName() << " : " << err.what();
+ QFile f(m_target_path);
+ if (f.exists())
+ f.remove();
+ failAndTryNextMirror();
+ return;
+ }
+ pack200_file.remove();
+
+ QFile jar_file(m_target_path);
+
+ if (!jar_file.open(QIODevice::ReadOnly))
+ {
+ jar_file.remove();
+ failAndTryNextMirror();
+ return;
+ }
+ auto hash = QCryptographicHash::hash(jar_file.readAll(), QCryptographicHash::Md5);
+ m_entry->setMD5Sum(hash.toHex().constData());
+ jar_file.close();
+
+ QFileInfo output_file_info(m_target_path);
+ m_entry->setETag(m_reply->rawHeader("ETag").constData());
+ m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch());
+ m_entry->setStale(false);
+ ENV.metacache()->updateEntry(m_entry);
+
+ m_reply.reset();
+ emit succeeded(m_index_within_job);
}
bool ForgeXzDownload::abort()
{
- if(m_reply)
- m_reply->abort();
- m_status = Job_Aborted;
- return true;
+ if(m_reply)
+ m_reply->abort();
+ m_status = Job_Aborted;
+ return true;
}
bool ForgeXzDownload::canAbort()
{
- return true;
+ return true;
}
diff --git a/api/logic/minecraft/forge/ForgeXzDownload.h b/api/logic/minecraft/forge/ForgeXzDownload.h
index cee402ef..728a7f7a 100644
--- a/api/logic/minecraft/forge/ForgeXzDownload.h
+++ b/api/logic/minecraft/forge/ForgeXzDownload.h
@@ -24,38 +24,38 @@ typedef std::shared_ptr<class ForgeXzDownload> ForgeXzDownloadPtr;
class ForgeXzDownload : public NetAction
{
- Q_OBJECT
+ Q_OBJECT
public:
- MetaEntryPtr m_entry;
- /// if saving to file, use the one specified in this string
- QString m_target_path;
- /// this is the output file, if any
- QTemporaryFile m_pack200_xz_file;
- /// path relative to the mirror base
- QString m_url_path;
+ MetaEntryPtr m_entry;
+ /// if saving to file, use the one specified in this string
+ QString m_target_path;
+ /// this is the output file, if any
+ QTemporaryFile m_pack200_xz_file;
+ /// path relative to the mirror base
+ QString m_url_path;
public:
- explicit ForgeXzDownload(QString relative_path, MetaEntryPtr entry);
- static ForgeXzDownloadPtr make(QString relative_path, MetaEntryPtr entry)
- {
- return ForgeXzDownloadPtr(new ForgeXzDownload(relative_path, entry));
- }
- virtual ~ForgeXzDownload(){};
- bool canAbort() override;
+ explicit ForgeXzDownload(QString relative_path, MetaEntryPtr entry);
+ static ForgeXzDownloadPtr make(QString relative_path, MetaEntryPtr entry)
+ {
+ return ForgeXzDownloadPtr(new ForgeXzDownload(relative_path, entry));
+ }
+ virtual ~ForgeXzDownload(){};
+ bool canAbort() override;
protected
slots:
- void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override;
- void downloadError(QNetworkReply::NetworkError error) override;
- void downloadFinished() override;
- void downloadReadyRead() override;
+ void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override;
+ void downloadError(QNetworkReply::NetworkError error) override;
+ void downloadFinished() override;
+ void downloadReadyRead() override;
public
slots:
- void start() override;
- bool abort() override;
+ void start() override;
+ bool abort() override;
private:
- void decompressAndInstall();
- void failAndTryNextMirror();
+ void decompressAndInstall();
+ void failAndTryNextMirror();
};
diff --git a/api/logic/minecraft/launch/ClaimAccount.cpp b/api/logic/minecraft/launch/ClaimAccount.cpp
index 71670b4f..a1180f0a 100644
--- a/api/logic/minecraft/launch/ClaimAccount.cpp
+++ b/api/logic/minecraft/launch/ClaimAccount.cpp
@@ -3,22 +3,22 @@
ClaimAccount::ClaimAccount(LaunchTask* parent, AuthSessionPtr session): LaunchStep(parent)
{
- if(session->status == AuthSession::Status::PlayableOnline)
- {
- m_account = session->m_accountPtr;
- }
+ if(session->status == AuthSession::Status::PlayableOnline)
+ {
+ m_account = session->m_accountPtr;
+ }
}
void ClaimAccount::executeTask()
{
- if(m_account)
- {
- lock.reset(new UseLock(m_account));
- emitSucceeded();
- }
+ if(m_account)
+ {
+ lock.reset(new UseLock(m_account));
+ emitSucceeded();
+ }
}
void ClaimAccount::finalize()
{
- lock.reset();
+ lock.reset();
}
diff --git a/api/logic/minecraft/launch/ClaimAccount.h b/api/logic/minecraft/launch/ClaimAccount.h
index c11c2128..64891406 100644
--- a/api/logic/minecraft/launch/ClaimAccount.h
+++ b/api/logic/minecraft/launch/ClaimAccount.h
@@ -20,18 +20,18 @@
class ClaimAccount: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ClaimAccount(LaunchTask *parent, AuthSessionPtr session);
- virtual ~ClaimAccount() {};
+ explicit ClaimAccount(LaunchTask *parent, AuthSessionPtr session);
+ virtual ~ClaimAccount() {};
- void executeTask() override;
- void finalize() override;
- bool canAbort() const override
- {
- return false;
- }
+ void executeTask() override;
+ void finalize() override;
+ bool canAbort() const override
+ {
+ return false;
+ }
private:
- std::unique_ptr<UseLock> lock;
- MojangAccountPtr m_account;
+ std::unique_ptr<UseLock> lock;
+ MojangAccountPtr m_account;
};
diff --git a/api/logic/minecraft/launch/CreateServerResourcePacksFolder.cpp b/api/logic/minecraft/launch/CreateServerResourcePacksFolder.cpp
index 5398f7d0..bbca46d5 100644
--- a/api/logic/minecraft/launch/CreateServerResourcePacksFolder.cpp
+++ b/api/logic/minecraft/launch/CreateServerResourcePacksFolder.cpp
@@ -9,11 +9,11 @@ CreateServerResourcePacksFolder::CreateServerResourcePacksFolder(LaunchTask* par
void CreateServerResourcePacksFolder::executeTask()
{
- auto instance = m_parent->instance();
- std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
- if(!FS::ensureFolderPathExists(FS::PathCombine(minecraftInstance->minecraftRoot(), "server-resource-packs")))
- {
- emit logLine(tr("Couldn't create the 'server-resource-packs' folder"), MessageLevel::Error);
- }
- emitSucceeded();
+ auto instance = m_parent->instance();
+ std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
+ if(!FS::ensureFolderPathExists(FS::PathCombine(minecraftInstance->minecraftRoot(), "server-resource-packs")))
+ {
+ emit logLine(tr("Couldn't create the 'server-resource-packs' folder"), MessageLevel::Error);
+ }
+ emitSucceeded();
}
diff --git a/api/logic/minecraft/launch/CreateServerResourcePacksFolder.h b/api/logic/minecraft/launch/CreateServerResourcePacksFolder.h
index 1e7b6621..b29496c9 100644
--- a/api/logic/minecraft/launch/CreateServerResourcePacksFolder.h
+++ b/api/logic/minecraft/launch/CreateServerResourcePacksFolder.h
@@ -22,16 +22,16 @@
// HACK: this is a workaround for MCL-3732 - 'server-resource-packs' folder is created.
class CreateServerResourcePacksFolder: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit CreateServerResourcePacksFolder(LaunchTask *parent);
- virtual ~CreateServerResourcePacksFolder() {};
+ explicit CreateServerResourcePacksFolder(LaunchTask *parent);
+ virtual ~CreateServerResourcePacksFolder() {};
- virtual void executeTask();
- virtual bool canAbort() const
- {
- return false;
- }
+ virtual void executeTask();
+ virtual bool canAbort() const
+ {
+ return false;
+ }
};
diff --git a/api/logic/minecraft/launch/DirectJavaLaunch.cpp b/api/logic/minecraft/launch/DirectJavaLaunch.cpp
index 4ccc5c3c..7ead8324 100644
--- a/api/logic/minecraft/launch/DirectJavaLaunch.cpp
+++ b/api/logic/minecraft/launch/DirectJavaLaunch.cpp
@@ -22,128 +22,128 @@
DirectJavaLaunch::DirectJavaLaunch(LaunchTask *parent) : LaunchStep(parent)
{
- connect(&m_process, &LoggedProcess::log, this, &DirectJavaLaunch::logLines);
- connect(&m_process, &LoggedProcess::stateChanged, this, &DirectJavaLaunch::on_state);
+ connect(&m_process, &LoggedProcess::log, this, &DirectJavaLaunch::logLines);
+ connect(&m_process, &LoggedProcess::stateChanged, this, &DirectJavaLaunch::on_state);
}
void DirectJavaLaunch::executeTask()
{
- auto instance = m_parent->instance();
- std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
- QStringList args = minecraftInstance->javaArguments();
+ auto instance = m_parent->instance();
+ std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
+ QStringList args = minecraftInstance->javaArguments();
- args.append("-Djava.library.path=" + minecraftInstance->getNativePath());
+ args.append("-Djava.library.path=" + minecraftInstance->getNativePath());
- auto classPathEntries = minecraftInstance->getClassPath();
- args.append("-cp");
- QString classpath;
+ auto classPathEntries = minecraftInstance->getClassPath();
+ args.append("-cp");
+ QString classpath;
#ifdef Q_OS_WIN32
- classpath = classPathEntries.join(';');
+ classpath = classPathEntries.join(';');
#else
- classpath = classPathEntries.join(':');
+ classpath = classPathEntries.join(':');
#endif
- args.append(classpath);
- args.append(minecraftInstance->getMainClass());
-
- QString allArgs = args.join(", ");
- emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC);
-
- auto javaPath = FS::ResolveExecutable(instance->settings()->get("JavaPath").toString());
-
- m_process.setProcessEnvironment(instance->createEnvironment());
-
- // make detachable - this will keep the process running even if the object is destroyed
- m_process.setDetachable(true);
-
- auto mcArgs = minecraftInstance->processMinecraftArgs(m_session);
- args.append(mcArgs);
-
- QString wrapperCommandStr = instance->getWrapperCommand().trimmed();
- if(!wrapperCommandStr.isEmpty())
- {
- auto wrapperArgs = Commandline::splitArgs(wrapperCommandStr);
- auto wrapperCommand = wrapperArgs.takeFirst();
- auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand);
- if (realWrapperCommand.isEmpty())
- {
- QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand);
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- return;
- }
- emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::MultiMC);
- args.prepend(javaPath);
- m_process.start(wrapperCommand, wrapperArgs + args);
- }
- else
- {
- m_process.start(javaPath, args);
- }
+ args.append(classpath);
+ args.append(minecraftInstance->getMainClass());
+
+ QString allArgs = args.join(", ");
+ emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC);
+
+ auto javaPath = FS::ResolveExecutable(instance->settings()->get("JavaPath").toString());
+
+ m_process.setProcessEnvironment(instance->createEnvironment());
+
+ // make detachable - this will keep the process running even if the object is destroyed
+ m_process.setDetachable(true);
+
+ auto mcArgs = minecraftInstance->processMinecraftArgs(m_session);
+ args.append(mcArgs);
+
+ QString wrapperCommandStr = instance->getWrapperCommand().trimmed();
+ if(!wrapperCommandStr.isEmpty())
+ {
+ auto wrapperArgs = Commandline::splitArgs(wrapperCommandStr);
+ auto wrapperCommand = wrapperArgs.takeFirst();
+ auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand);
+ if (realWrapperCommand.isEmpty())
+ {
+ QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand);
+ emit logLine(reason, MessageLevel::Fatal);
+ emitFailed(reason);
+ return;
+ }
+ emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::MultiMC);
+ args.prepend(javaPath);
+ m_process.start(wrapperCommand, wrapperArgs + args);
+ }
+ else
+ {
+ m_process.start(javaPath, args);
+ }
}
void DirectJavaLaunch::on_state(LoggedProcess::State state)
{
- switch(state)
- {
- case LoggedProcess::FailedToStart:
- {
- //: Error message displayed if instace can't start
- QString reason = tr("Could not launch minecraft!");
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- return;
- }
- case LoggedProcess::Aborted:
- case LoggedProcess::Crashed:
-
- {
- m_parent->setPid(-1);
- emitFailed("Game crashed.");
- return;
- }
- case LoggedProcess::Finished:
- {
- m_parent->setPid(-1);
- // if the exit code wasn't 0, report this as a crash
- auto exitCode = m_process.exitCode();
- if(exitCode != 0)
- {
- emitFailed("Game crashed.");
- return;
- }
- //FIXME: make this work again
- // m_postlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(exitCode));
- // run post-exit
- emitSucceeded();
- break;
- }
- case LoggedProcess::Running:
- emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC);
- m_parent->setPid(m_process.processId());
- m_parent->instance()->setLastLaunch();
- break;
- default:
- break;
- }
+ switch(state)
+ {
+ case LoggedProcess::FailedToStart:
+ {
+ //: Error message displayed if instace can't start
+ QString reason = tr("Could not launch minecraft!");
+ emit logLine(reason, MessageLevel::Fatal);
+ emitFailed(reason);
+ return;
+ }
+ case LoggedProcess::Aborted:
+ case LoggedProcess::Crashed:
+
+ {
+ m_parent->setPid(-1);
+ emitFailed("Game crashed.");
+ return;
+ }
+ case LoggedProcess::Finished:
+ {
+ m_parent->setPid(-1);
+ // if the exit code wasn't 0, report this as a crash
+ auto exitCode = m_process.exitCode();
+ if(exitCode != 0)
+ {
+ emitFailed("Game crashed.");
+ return;
+ }
+ //FIXME: make this work again
+ // m_postlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(exitCode));
+ // run post-exit
+ emitSucceeded();
+ break;
+ }
+ case LoggedProcess::Running:
+ emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC);
+ m_parent->setPid(m_process.processId());
+ m_parent->instance()->setLastLaunch();
+ break;
+ default:
+ break;
+ }
}
void DirectJavaLaunch::setWorkingDirectory(const QString &wd)
{
- m_process.setWorkingDirectory(wd);
+ m_process.setWorkingDirectory(wd);
}
void DirectJavaLaunch::proceed()
{
- // nil
+ // nil
}
bool DirectJavaLaunch::abort()
{
- auto state = m_process.state();
- if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
- {
- m_process.kill();
- }
- return true;
+ auto state = m_process.state();
+ if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
+ {
+ m_process.kill();
+ }
+ return true;
}
diff --git a/api/logic/minecraft/launch/DirectJavaLaunch.h b/api/logic/minecraft/launch/DirectJavaLaunch.h
index 8d2cc467..fb555e3e 100644
--- a/api/logic/minecraft/launch/DirectJavaLaunch.h
+++ b/api/logic/minecraft/launch/DirectJavaLaunch.h
@@ -21,29 +21,29 @@
class DirectJavaLaunch: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit DirectJavaLaunch(LaunchTask *parent);
- virtual ~DirectJavaLaunch() {};
+ explicit DirectJavaLaunch(LaunchTask *parent);
+ virtual ~DirectJavaLaunch() {};
- virtual void executeTask();
- virtual bool abort();
- virtual void proceed();
- virtual bool canAbort() const
- {
- return true;
- }
- void setWorkingDirectory(const QString &wd);
- void setAuthSession(AuthSessionPtr session)
- {
- m_session = session;
- }
+ virtual void executeTask();
+ virtual bool abort();
+ virtual void proceed();
+ virtual bool canAbort() const
+ {
+ return true;
+ }
+ void setWorkingDirectory(const QString &wd);
+ void setAuthSession(AuthSessionPtr session)
+ {
+ m_session = session;
+ }
private slots:
- void on_state(LoggedProcess::State state);
+ void on_state(LoggedProcess::State state);
private:
- LoggedProcess m_process;
- QString m_command;
- AuthSessionPtr m_session;
+ LoggedProcess m_process;
+ QString m_command;
+ AuthSessionPtr m_session;
};
diff --git a/api/logic/minecraft/launch/ExtractNatives.cpp b/api/logic/minecraft/launch/ExtractNatives.cpp
index 7ddde374..336eddbd 100644
--- a/api/logic/minecraft/launch/ExtractNatives.cpp
+++ b/api/logic/minecraft/launch/ExtractNatives.cpp
@@ -25,76 +25,76 @@
static QString replaceSuffix (QString target, const QString &suffix, const QString &replacement)
{
- if (!target.endsWith(suffix))
- {
- return target;
- }
- target.resize(target.length() - suffix.length());
- return target + replacement;
+ if (!target.endsWith(suffix))
+ {
+ return target;
+ }
+ target.resize(target.length() - suffix.length());
+ return target + replacement;
}
static bool unzipNatives(QString source, QString targetFolder, bool applyJnilibHack)
{
- QuaZip zip(source);
- if(!zip.open(QuaZip::mdUnzip))
- {
- return false;
- }
- QDir directory(targetFolder);
- if (!zip.goToFirstFile())
- {
- return false;
- }
- do
- {
- QString name = zip.getCurrentFileName();
- if(applyJnilibHack)
- {
- name = replaceSuffix(name, ".jnilib", ".dylib");
- }
- QString absFilePath = directory.absoluteFilePath(name);
- if (!JlCompress::extractFile(&zip, "", absFilePath))
- {
- return false;
- }
- } while (zip.goToNextFile());
- zip.close();
- if(zip.getZipError()!=0)
- {
- return false;
- }
- return true;
+ QuaZip zip(source);
+ if(!zip.open(QuaZip::mdUnzip))
+ {
+ return false;
+ }
+ QDir directory(targetFolder);
+ if (!zip.goToFirstFile())
+ {
+ return false;
+ }
+ do
+ {
+ QString name = zip.getCurrentFileName();
+ if(applyJnilibHack)
+ {
+ name = replaceSuffix(name, ".jnilib", ".dylib");
+ }
+ QString absFilePath = directory.absoluteFilePath(name);
+ if (!JlCompress::extractFile(&zip, "", absFilePath))
+ {
+ return false;
+ }
+ } while (zip.goToNextFile());
+ zip.close();
+ if(zip.getZipError()!=0)
+ {
+ return false;
+ }
+ return true;
}
void ExtractNatives::executeTask()
{
- auto instance = m_parent->instance();
- std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
- auto toExtract = minecraftInstance->getNativeJars();
- if(toExtract.isEmpty())
- {
- emitSucceeded();
- return;
- }
- auto outputPath = minecraftInstance->getNativePath();
- auto javaVersion = minecraftInstance->getJavaVersion();
- bool jniHackEnabled = javaVersion.major() >= 8;
- for(const auto &source: toExtract)
- {
- if(!unzipNatives(source, outputPath, jniHackEnabled))
- {
- auto reason = tr("Couldn't extract native jar '%1' to destination '%2'").arg(source, outputPath);
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- }
- }
- emitSucceeded();
+ auto instance = m_parent->instance();
+ std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
+ auto toExtract = minecraftInstance->getNativeJars();
+ if(toExtract.isEmpty())
+ {
+ emitSucceeded();
+ return;
+ }
+ auto outputPath = minecraftInstance->getNativePath();
+ auto javaVersion = minecraftInstance->getJavaVersion();
+ bool jniHackEnabled = javaVersion.major() >= 8;
+ for(const auto &source: toExtract)
+ {
+ if(!unzipNatives(source, outputPath, jniHackEnabled))
+ {
+ auto reason = tr("Couldn't extract native jar '%1' to destination '%2'").arg(source, outputPath);
+ emit logLine(reason, MessageLevel::Fatal);
+ emitFailed(reason);
+ }
+ }
+ emitSucceeded();
}
void ExtractNatives::finalize()
{
- auto instance = m_parent->instance();
- QString target_dir = FS::PathCombine(instance->instanceRoot(), "natives/");
- QDir dir(target_dir);
- dir.removeRecursively();
+ auto instance = m_parent->instance();
+ QString target_dir = FS::PathCombine(instance->instanceRoot(), "natives/");
+ QDir dir(target_dir);
+ dir.removeRecursively();
}
diff --git a/api/logic/minecraft/launch/ExtractNatives.h b/api/logic/minecraft/launch/ExtractNatives.h
index 6e1e7cd4..d9587991 100644
--- a/api/logic/minecraft/launch/ExtractNatives.h
+++ b/api/logic/minecraft/launch/ExtractNatives.h
@@ -22,17 +22,17 @@
// FIXME: temporary wrapper for existing task.
class ExtractNatives: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ExtractNatives(LaunchTask *parent) : LaunchStep(parent){};
- virtual ~ExtractNatives(){};
+ explicit ExtractNatives(LaunchTask *parent) : LaunchStep(parent){};
+ virtual ~ExtractNatives(){};
- void executeTask() override;
- bool canAbort() const override
- {
- return false;
- }
- void finalize() override;
+ void executeTask() override;
+ bool canAbort() const override
+ {
+ return false;
+ }
+ void finalize() override;
};
diff --git a/api/logic/minecraft/launch/LauncherPartLaunch.cpp b/api/logic/minecraft/launch/LauncherPartLaunch.cpp
index 1fe9c323..466c1e46 100644
--- a/api/logic/minecraft/launch/LauncherPartLaunch.cpp
+++ b/api/logic/minecraft/launch/LauncherPartLaunch.cpp
@@ -24,8 +24,8 @@
LauncherPartLaunch::LauncherPartLaunch(LaunchTask *parent) : LaunchStep(parent)
{
- connect(&m_process, &LoggedProcess::log, this, &LauncherPartLaunch::logLines);
- connect(&m_process, &LoggedProcess::stateChanged, this, &LauncherPartLaunch::on_state);
+ connect(&m_process, &LoggedProcess::log, this, &LauncherPartLaunch::logLines);
+ connect(&m_process, &LoggedProcess::stateChanged, this, &LauncherPartLaunch::on_state);
}
#ifdef Q_OS_WIN
@@ -33,187 +33,187 @@ LauncherPartLaunch::LauncherPartLaunch(LaunchTask *parent) : LaunchStep(parent)
#include <windows.h>
QString shortPathName(const QString & file)
{
- auto input = file.toStdWString();
- std::wstring output;
- long length = GetShortPathNameW(input.c_str(), NULL, 0);
- // NOTE: this resizing might seem weird...
- // when GetShortPathNameW fails, it returns length including null character
- // when it succeeds, it returns length excluding null character
- // See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364989(v=vs.85).aspx
- output.resize(length);
- GetShortPathNameW(input.c_str(),(LPWSTR)output.c_str(),length);
- output.resize(length-1);
- QString ret = QString::fromStdWString(output);
- return ret;
+ auto input = file.toStdWString();
+ std::wstring output;
+ long length = GetShortPathNameW(input.c_str(), NULL, 0);
+ // NOTE: this resizing might seem weird...
+ // when GetShortPathNameW fails, it returns length including null character
+ // when it succeeds, it returns length excluding null character
+ // See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364989(v=vs.85).aspx
+ output.resize(length);
+ GetShortPathNameW(input.c_str(),(LPWSTR)output.c_str(),length);
+ output.resize(length-1);
+ QString ret = QString::fromStdWString(output);
+ return ret;
}
#endif
// if the string survives roundtrip through local 8bit encoding...
bool fitsInLocal8bit(const QString & string)
{
- return string == QString::fromLocal8Bit(string.toLocal8Bit());
+ return string == QString::fromLocal8Bit(string.toLocal8Bit());
}
void LauncherPartLaunch::executeTask()
{
- auto instance = m_parent->instance();
- std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
+ auto instance = m_parent->instance();
+ std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
- m_launchScript = minecraftInstance->createLaunchScript(m_session);
- QStringList args = minecraftInstance->javaArguments();
- QString allArgs = args.join(", ");
- emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC);
+ m_launchScript = minecraftInstance->createLaunchScript(m_session);
+ QStringList args = minecraftInstance->javaArguments();
+ QString allArgs = args.join(", ");
+ emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC);
- auto javaPath = FS::ResolveExecutable(instance->settings()->get("JavaPath").toString());
+ auto javaPath = FS::ResolveExecutable(instance->settings()->get("JavaPath").toString());
- m_process.setProcessEnvironment(instance->createEnvironment());
+ m_process.setProcessEnvironment(instance->createEnvironment());
- // make detachable - this will keep the process running even if the object is destroyed
- m_process.setDetachable(true);
+ // make detachable - this will keep the process running even if the object is destroyed
+ m_process.setDetachable(true);
- auto classPath = minecraftInstance->getClassPath();
- classPath.prepend(FS::PathCombine(ENV.getJarsPath(), "NewLaunch.jar"));
+ auto classPath = minecraftInstance->getClassPath();
+ classPath.prepend(FS::PathCombine(ENV.getJarsPath(), "NewLaunch.jar"));
- auto natPath = minecraftInstance->getNativePath();
+ auto natPath = minecraftInstance->getNativePath();
#ifdef Q_OS_WIN
- if (!fitsInLocal8bit(natPath))
- {
- args << "-Djava.library.path=" + shortPathName(natPath);
- }
- else
- {
- args << "-Djava.library.path=" + natPath;
- }
+ if (!fitsInLocal8bit(natPath))
+ {
+ args << "-Djava.library.path=" + shortPathName(natPath);
+ }
+ else
+ {
+ args << "-Djava.library.path=" + natPath;
+ }
#else
- args << "-Djava.library.path=" + natPath;
+ args << "-Djava.library.path=" + natPath;
#endif
- args << "-cp";
+ args << "-cp";
#ifdef Q_OS_WIN
- QStringList processed;
- for(auto & item: classPath)
- {
- if (!fitsInLocal8bit(item))
- {
- processed << shortPathName(item);
- }
- else
- {
- processed << item;
- }
- }
- args << processed.join(';');
+ QStringList processed;
+ for(auto & item: classPath)
+ {
+ if (!fitsInLocal8bit(item))
+ {
+ processed << shortPathName(item);
+ }
+ else
+ {
+ processed << item;
+ }
+ }
+ args << processed.join(';');
#else
- args << classPath.join(':');
+ args << classPath.join(':');
#endif
- args << "org.multimc.EntryPoint";
-
- qDebug() << args.join(' ');
-
- QString wrapperCommandStr = instance->getWrapperCommand().trimmed();
- if(!wrapperCommandStr.isEmpty())
- {
- auto wrapperArgs = Commandline::splitArgs(wrapperCommandStr);
- auto wrapperCommand = wrapperArgs.takeFirst();
- auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand);
- if (realWrapperCommand.isEmpty())
- {
- QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand);
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- return;
- }
- emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::MultiMC);
- args.prepend(javaPath);
- m_process.start(wrapperCommand, wrapperArgs + args);
- }
- else
- {
- m_process.start(javaPath, args);
- }
+ args << "org.multimc.EntryPoint";
+
+ qDebug() << args.join(' ');
+
+ QString wrapperCommandStr = instance->getWrapperCommand().trimmed();
+ if(!wrapperCommandStr.isEmpty())
+ {
+ auto wrapperArgs = Commandline::splitArgs(wrapperCommandStr);
+ auto wrapperCommand = wrapperArgs.takeFirst();
+ auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand);
+ if (realWrapperCommand.isEmpty())
+ {
+ QString reason = tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand);
+ emit logLine(reason, MessageLevel::Fatal);
+ emitFailed(reason);
+ return;
+ }
+ emit logLine("Wrapper command is:\n" + wrapperCommandStr + "\n\n", MessageLevel::MultiMC);
+ args.prepend(javaPath);
+ m_process.start(wrapperCommand, wrapperArgs + args);
+ }
+ else
+ {
+ m_process.start(javaPath, args);
+ }
}
void LauncherPartLaunch::on_state(LoggedProcess::State state)
{
- switch(state)
- {
- case LoggedProcess::FailedToStart:
- {
- //: Error message displayed if instace can't start
- QString reason = tr("Could not launch minecraft!");
- emit logLine(reason, MessageLevel::Fatal);
- emitFailed(reason);
- return;
- }
- case LoggedProcess::Aborted:
- case LoggedProcess::Crashed:
-
- {
- m_parent->setPid(-1);
- emitFailed("Game crashed.");
- return;
- }
- case LoggedProcess::Finished:
- {
- m_parent->setPid(-1);
- // if the exit code wasn't 0, report this as a crash
- auto exitCode = m_process.exitCode();
- if(exitCode != 0)
- {
- emitFailed("Game crashed.");
- return;
- }
- //FIXME: make this work again
- // m_postlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(exitCode));
- // run post-exit
- emitSucceeded();
- break;
- }
- case LoggedProcess::Running:
- emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC);
- m_parent->setPid(m_process.processId());
- m_parent->instance()->setLastLaunch();
- // send the launch script to the launcher part
- m_process.write(m_launchScript.toUtf8());
-
- mayProceed = true;
- emit readyForLaunch();
- break;
- default:
- break;
- }
+ switch(state)
+ {
+ case LoggedProcess::FailedToStart:
+ {
+ //: Error message displayed if instace can't start
+ QString reason = tr("Could not launch minecraft!");
+ emit logLine(reason, MessageLevel::Fatal);
+ emitFailed(reason);
+ return;
+ }
+ case LoggedProcess::Aborted:
+ case LoggedProcess::Crashed:
+
+ {
+ m_parent->setPid(-1);
+ emitFailed("Game crashed.");
+ return;
+ }
+ case LoggedProcess::Finished:
+ {
+ m_parent->setPid(-1);
+ // if the exit code wasn't 0, report this as a crash
+ auto exitCode = m_process.exitCode();
+ if(exitCode != 0)
+ {
+ emitFailed("Game crashed.");
+ return;
+ }
+ //FIXME: make this work again
+ // m_postlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(exitCode));
+ // run post-exit
+ emitSucceeded();
+ break;
+ }
+ case LoggedProcess::Running:
+ emit logLine(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC);
+ m_parent->setPid(m_process.processId());
+ m_parent->instance()->setLastLaunch();
+ // send the launch script to the launcher part
+ m_process.write(m_launchScript.toUtf8());
+
+ mayProceed = true;
+ emit readyForLaunch();
+ break;
+ default:
+ break;
+ }
}
void LauncherPartLaunch::setWorkingDirectory(const QString &wd)
{
- m_process.setWorkingDirectory(wd);
+ m_process.setWorkingDirectory(wd);
}
void LauncherPartLaunch::proceed()
{
- if(mayProceed)
- {
- QString launchString("launch\n");
- m_process.write(launchString.toUtf8());
- mayProceed = false;
- }
+ if(mayProceed)
+ {
+ QString launchString("launch\n");
+ m_process.write(launchString.toUtf8());
+ mayProceed = false;
+ }
}
bool LauncherPartLaunch::abort()
{
- if(mayProceed)
- {
- mayProceed = false;
- QString launchString("abort\n");
- m_process.write(launchString.toUtf8());
- }
- else
- {
- auto state = m_process.state();
- if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
- {
- m_process.kill();
- }
- }
- return true;
+ if(mayProceed)
+ {
+ mayProceed = false;
+ QString launchString("abort\n");
+ m_process.write(launchString.toUtf8());
+ }
+ else
+ {
+ auto state = m_process.state();
+ if (state == LoggedProcess::Running || state == LoggedProcess::Starting)
+ {
+ m_process.kill();
+ }
+ }
+ return true;
}
diff --git a/api/logic/minecraft/launch/LauncherPartLaunch.h b/api/logic/minecraft/launch/LauncherPartLaunch.h
index 6ae85a3f..7fadbd66 100644
--- a/api/logic/minecraft/launch/LauncherPartLaunch.h
+++ b/api/logic/minecraft/launch/LauncherPartLaunch.h
@@ -21,31 +21,31 @@
class LauncherPartLaunch: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit LauncherPartLaunch(LaunchTask *parent);
- virtual ~LauncherPartLaunch() {};
+ explicit LauncherPartLaunch(LaunchTask *parent);
+ virtual ~LauncherPartLaunch() {};
- virtual void executeTask();
- virtual bool abort();
- virtual void proceed();
- virtual bool canAbort() const
- {
- return true;
- }
- void setWorkingDirectory(const QString &wd);
- void setAuthSession(AuthSessionPtr session)
- {
- m_session = session;
- }
+ virtual void executeTask();
+ virtual bool abort();
+ virtual void proceed();
+ virtual bool canAbort() const
+ {
+ return true;
+ }
+ void setWorkingDirectory(const QString &wd);
+ void setAuthSession(AuthSessionPtr session)
+ {
+ m_session = session;
+ }
private slots:
- void on_state(LoggedProcess::State state);
+ void on_state(LoggedProcess::State state);
private:
- LoggedProcess m_process;
- QString m_command;
- AuthSessionPtr m_session;
- QString m_launchScript;
- bool mayProceed = false;
+ LoggedProcess m_process;
+ QString m_command;
+ AuthSessionPtr m_session;
+ QString m_launchScript;
+ bool mayProceed = false;
};
diff --git a/api/logic/minecraft/launch/ModMinecraftJar.cpp b/api/logic/minecraft/launch/ModMinecraftJar.cpp
index 34825b45..34472bb3 100644
--- a/api/logic/minecraft/launch/ModMinecraftJar.cpp
+++ b/api/logic/minecraft/launch/ModMinecraftJar.cpp
@@ -23,60 +23,60 @@
void ModMinecraftJar::executeTask()
{
- auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
+ auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
- if(!m_inst->getJarMods().size())
- {
- emitSucceeded();
- return;
- }
- // nuke obsolete stripped jar(s) if needed
- if(!FS::ensureFolderPathExists(m_inst->binRoot()))
- {
- emitFailed(tr("Couldn't create the bin folder for Minecraft.jar"));
- }
+ if(!m_inst->getJarMods().size())
+ {
+ emitSucceeded();
+ return;
+ }
+ // nuke obsolete stripped jar(s) if needed
+ if(!FS::ensureFolderPathExists(m_inst->binRoot()))
+ {
+ emitFailed(tr("Couldn't create the bin folder for Minecraft.jar"));
+ }
- auto finalJarPath = QDir(m_inst->binRoot()).absoluteFilePath("minecraft.jar");
- if(!removeJar())
- {
- emitFailed(tr("Couldn't remove stale jar file: %1").arg(finalJarPath));
- }
+ auto finalJarPath = QDir(m_inst->binRoot()).absoluteFilePath("minecraft.jar");
+ if(!removeJar())
+ {
+ emitFailed(tr("Couldn't remove stale jar file: %1").arg(finalJarPath));
+ }
- // create temporary modded jar, if needed
- auto components = m_inst->getComponentList();
- auto profile = components->getProfile();
- auto jarMods = m_inst->getJarMods();
- if(jarMods.size())
- {
- auto mainJar = profile->getMainJar();
- QStringList jars, temp1, temp2, temp3, temp4;
- mainJar->getApplicableFiles(currentSystem, jars, temp1, temp2, temp3, m_inst->getLocalLibraryPath());
- auto sourceJarPath = jars[0];
- if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods))
- {
- emitFailed(tr("Failed to create the custom Minecraft jar file."));
- return;
- }
- }
- emitSucceeded();
+ // create temporary modded jar, if needed
+ auto components = m_inst->getComponentList();
+ auto profile = components->getProfile();
+ auto jarMods = m_inst->getJarMods();
+ if(jarMods.size())
+ {
+ auto mainJar = profile->getMainJar();
+ QStringList jars, temp1, temp2, temp3, temp4;
+ mainJar->getApplicableFiles(currentSystem, jars, temp1, temp2, temp3, m_inst->getLocalLibraryPath());
+ auto sourceJarPath = jars[0];
+ if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods))
+ {
+ emitFailed(tr("Failed to create the custom Minecraft jar file."));
+ return;
+ }
+ }
+ emitSucceeded();
}
void ModMinecraftJar::finalize()
{
- removeJar();
+ removeJar();
}
bool ModMinecraftJar::removeJar()
{
- auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
- auto finalJarPath = QDir(m_inst->binRoot()).absoluteFilePath("minecraft.jar");
- QFile finalJar(finalJarPath);
- if(finalJar.exists())
- {
- if(!finalJar.remove())
- {
- return false;
- }
- }
- return true;
+ auto m_inst = std::dynamic_pointer_cast<MinecraftInstance>(m_parent->instance());
+ auto finalJarPath = QDir(m_inst->binRoot()).absoluteFilePath("minecraft.jar");
+ QFile finalJar(finalJarPath);
+ if(finalJar.exists())
+ {
+ if(!finalJar.remove())
+ {
+ return false;
+ }
+ }
+ return true;
}
diff --git a/api/logic/minecraft/launch/ModMinecraftJar.h b/api/logic/minecraft/launch/ModMinecraftJar.h
index dca484f8..48e11736 100644
--- a/api/logic/minecraft/launch/ModMinecraftJar.h
+++ b/api/logic/minecraft/launch/ModMinecraftJar.h
@@ -20,17 +20,17 @@
class ModMinecraftJar: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ModMinecraftJar(LaunchTask *parent) : LaunchStep(parent) {};
- virtual ~ModMinecraftJar(){};
+ explicit ModMinecraftJar(LaunchTask *parent) : LaunchStep(parent) {};
+ virtual ~ModMinecraftJar(){};
- virtual void executeTask() override;
- virtual bool canAbort() const override
- {
- return false;
- }
- void finalize() override;
+ virtual void executeTask() override;
+ virtual bool canAbort() const override
+ {
+ return false;
+ }
+ void finalize() override;
private:
- bool removeJar();
+ bool removeJar();
};
diff --git a/api/logic/minecraft/launch/PrintInstanceInfo.h b/api/logic/minecraft/launch/PrintInstanceInfo.h
index 61615ba1..ae0a0400 100644
--- a/api/logic/minecraft/launch/PrintInstanceInfo.h
+++ b/api/logic/minecraft/launch/PrintInstanceInfo.h
@@ -22,17 +22,17 @@
// FIXME: temporary wrapper for existing task.
class PrintInstanceInfo: public LaunchStep
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit PrintInstanceInfo(LaunchTask *parent, AuthSessionPtr session) : LaunchStep(parent), m_session(session) {};
- virtual ~PrintInstanceInfo(){};
+ explicit PrintInstanceInfo(LaunchTask *parent, AuthSessionPtr session) : LaunchStep(parent), m_session(session) {};
+ virtual ~PrintInstanceInfo(){};
- virtual void executeTask();
- virtual bool canAbort() const
- {
- return false;
- }
+ virtual void executeTask();
+ virtual bool canAbort() const
+ {
+ return false;
+ }
private:
- AuthSessionPtr m_session;
+ AuthSessionPtr m_session;
};
diff --git a/api/logic/minecraft/legacy/LegacyInstance.cpp b/api/logic/minecraft/legacy/LegacyInstance.cpp
index 1282eb4d..d22535e7 100644
--- a/api/logic/minecraft/legacy/LegacyInstance.cpp
+++ b/api/logic/minecraft/legacy/LegacyInstance.cpp
@@ -27,236 +27,236 @@
#include <FileSystem.h>
LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
- : BaseInstance(globalSettings, settings, rootDir)
+ : BaseInstance(globalSettings, settings, rootDir)
{
- settings->registerSetting("NeedsRebuild", true);
- settings->registerSetting("ShouldUpdate", false);
- settings->registerSetting("JarVersion", QString());
- settings->registerSetting("IntendedJarVersion", QString());
- /*
- * custom base jar has no default. it is determined in code... see the accessor methods for
- *it
- *
- * for instances that DO NOT have the CustomBaseJar setting (legacy instances),
- * [.]minecraft/bin/mcbackup.jar is the default base jar
- */
- settings->registerSetting("UseCustomBaseJar", true);
- settings->registerSetting("CustomBaseJar", "");
+ settings->registerSetting("NeedsRebuild", true);
+ settings->registerSetting("ShouldUpdate", false);
+ settings->registerSetting("JarVersion", QString());
+ settings->registerSetting("IntendedJarVersion", QString());
+ /*
+ * custom base jar has no default. it is determined in code... see the accessor methods for
+ *it
+ *
+ * for instances that DO NOT have the CustomBaseJar setting (legacy instances),
+ * [.]minecraft/bin/mcbackup.jar is the default base jar
+ */
+ settings->registerSetting("UseCustomBaseJar", true);
+ settings->registerSetting("CustomBaseJar", "");
}
QString LegacyInstance::mainJarToPreserve() const
{
- bool customJar = m_settings->get("UseCustomBaseJar").toBool();
- if(customJar)
- {
- auto base = baseJar();
- if(QFile::exists(base))
- {
- return base;
- }
- }
- auto runnable = runnableJar();
- if(QFile::exists(runnable))
- {
- return runnable;
- }
- return QString();
+ bool customJar = m_settings->get("UseCustomBaseJar").toBool();
+ if(customJar)
+ {
+ auto base = baseJar();
+ if(QFile::exists(base))
+ {
+ return base;
+ }
+ }
+ auto runnable = runnableJar();
+ if(QFile::exists(runnable))
+ {
+ return runnable;
+ }
+ return QString();
}
QString LegacyInstance::baseJar() const
{
- bool customJar = m_settings->get("UseCustomBaseJar").toBool();
- if (customJar)
- {
- return customBaseJar();
- }
- else
- return defaultBaseJar();
+ bool customJar = m_settings->get("UseCustomBaseJar").toBool();
+ if (customJar)
+ {
+ return customBaseJar();
+ }
+ else
+ return defaultBaseJar();
}
QString LegacyInstance::customBaseJar() const
{
- QString value = m_settings->get("CustomBaseJar").toString();
- if (value.isNull() || value.isEmpty())
- {
- return defaultCustomBaseJar();
- }
- return value;
+ QString value = m_settings->get("CustomBaseJar").toString();
+ if (value.isNull() || value.isEmpty())
+ {
+ return defaultCustomBaseJar();
+ }
+ return value;
}
bool LegacyInstance::shouldUseCustomBaseJar() const
{
- return m_settings->get("UseCustomBaseJar").toBool();
+ return m_settings->get("UseCustomBaseJar").toBool();
}
shared_qobject_ptr<Task> LegacyInstance::createUpdateTask(Net::Mode)
{
- return nullptr;
+ return nullptr;
}
std::shared_ptr<LegacyModList> LegacyInstance::jarModList() const
{
- if (!jar_mod_list)
- {
- auto list = new LegacyModList(jarModsDir(), modListFile());
- jar_mod_list.reset(list);
- }
- jar_mod_list->update();
- return jar_mod_list;
+ if (!jar_mod_list)
+ {
+ auto list = new LegacyModList(jarModsDir(), modListFile());
+ jar_mod_list.reset(list);
+ }
+ jar_mod_list->update();
+ return jar_mod_list;
}
QList<Mod> LegacyInstance::getJarMods() const
{
- return jarModList()->allMods();
+ return jarModList()->allMods();
}
QString LegacyInstance::minecraftRoot() const
{
- QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
- QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
+ QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
+ QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
- if (mcDir.exists() && !dotMCDir.exists())
- return mcDir.filePath();
- else
- return dotMCDir.filePath();
+ if (mcDir.exists() && !dotMCDir.exists())
+ return mcDir.filePath();
+ else
+ return dotMCDir.filePath();
}
QString LegacyInstance::binRoot() const
{
- return FS::PathCombine(minecraftRoot(), "bin");
+ return FS::PathCombine(minecraftRoot(), "bin");
}
QString LegacyInstance::jarModsDir() const
{
- return FS::PathCombine(instanceRoot(), "instMods");
+ return FS::PathCombine(instanceRoot(), "instMods");
}
QString LegacyInstance::libDir() const
{
- return FS::PathCombine(minecraftRoot(), "lib");
+ return FS::PathCombine(minecraftRoot(), "lib");
}
QString LegacyInstance::savesDir() const
{
- return FS::PathCombine(minecraftRoot(), "saves");
+ return FS::PathCombine(minecraftRoot(), "saves");
}
QString LegacyInstance::loaderModsDir() const
{
- return FS::PathCombine(minecraftRoot(), "mods");
+ return FS::PathCombine(minecraftRoot(), "mods");
}
QString LegacyInstance::coreModsDir() const
{
- return FS::PathCombine(minecraftRoot(), "coremods");
+ return FS::PathCombine(minecraftRoot(), "coremods");
}
QString LegacyInstance::resourceDir() const
{
- return FS::PathCombine(minecraftRoot(), "resources");
+ return FS::PathCombine(minecraftRoot(), "resources");
}
QString LegacyInstance::texturePacksDir() const
{
- return FS::PathCombine(minecraftRoot(), "texturepacks");
+ return FS::PathCombine(minecraftRoot(), "texturepacks");
}
QString LegacyInstance::runnableJar() const
{
- return FS::PathCombine(binRoot(), "minecraft.jar");
+ return FS::PathCombine(binRoot(), "minecraft.jar");
}
QString LegacyInstance::modListFile() const
{
- return FS::PathCombine(instanceRoot(), "modlist");
+ return FS::PathCombine(instanceRoot(), "modlist");
}
QString LegacyInstance::instanceConfigFolder() const
{
- return FS::PathCombine(minecraftRoot(), "config");
+ return FS::PathCombine(minecraftRoot(), "config");
}
bool LegacyInstance::shouldRebuild() const
{
- return m_settings->get("NeedsRebuild").toBool();
+ return m_settings->get("NeedsRebuild").toBool();
}
QString LegacyInstance::currentVersionId() const
{
- return m_settings->get("JarVersion").toString();
+ return m_settings->get("JarVersion").toString();
}
QString LegacyInstance::intendedVersionId() const
{
- return m_settings->get("IntendedJarVersion").toString();
+ return m_settings->get("IntendedJarVersion").toString();
}
bool LegacyInstance::shouldUpdate() const
{
- QVariant var = settings()->get("ShouldUpdate");
- if (!var.isValid() || var.toBool() == false)
- {
- return intendedVersionId() != currentVersionId();
- }
- return true;
+ QVariant var = settings()->get("ShouldUpdate");
+ if (!var.isValid() || var.toBool() == false)
+ {
+ return intendedVersionId() != currentVersionId();
+ }
+ return true;
}
QString LegacyInstance::defaultBaseJar() const
{
- return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
+ return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
}
QString LegacyInstance::defaultCustomBaseJar() const
{
- return FS::PathCombine(binRoot(), "mcbackup.jar");
+ return FS::PathCombine(binRoot(), "mcbackup.jar");
}
std::shared_ptr<WorldList> LegacyInstance::worldList() const
{
- if (!m_world_list)
- {
- m_world_list.reset(new WorldList(savesDir()));
- }
- return m_world_list;
+ if (!m_world_list)
+ {
+ m_world_list.reset(new WorldList(savesDir()));
+ }
+ return m_world_list;
}
QString LegacyInstance::typeName() const
{
- return tr("Legacy");
+ return tr("Legacy");
}
QString LegacyInstance::getStatusbarDescription()
{
- return tr("Instance from previous versions.");
+ return tr("Instance from previous versions.");
}
QStringList LegacyInstance::verboseDescription(AuthSessionPtr session)
{
- QStringList out;
-
- auto alltraits = traits();
- if(alltraits.size())
- {
- out << "Traits:";
- for (auto trait : alltraits)
- {
- out << " " + trait;
- }
- out << "";
- }
-
- QString windowParams;
- if (settings()->get("LaunchMaximized").toBool())
- {
- out << "Window size: max (if available)";
- }
- else
- {
- auto width = settings()->get("MinecraftWinWidth").toInt();
- auto height = settings()->get("MinecraftWinHeight").toInt();
- out << "Window size: " + QString::number(width) + " x " + QString::number(height);
- }
- out << "";
- return out;
+ QStringList out;
+
+ auto alltraits = traits();
+ if(alltraits.size())
+ {
+ out << "Traits:";
+ for (auto trait : alltraits)
+ {
+ out << " " + trait;
+ }
+ out << "";
+ }
+
+ QString windowParams;
+ if (settings()->get("LaunchMaximized").toBool())
+ {
+ out << "Window size: max (if available)";
+ }
+ else
+ {
+ auto width = settings()->get("MinecraftWinWidth").toInt();
+ auto height = settings()->get("MinecraftWinHeight").toInt();
+ out << "Window size: " + QString::number(width) + " x " + QString::number(height);
+ }
+ out << "";
+ return out;
}
diff --git a/api/logic/minecraft/legacy/LegacyInstance.h b/api/logic/minecraft/legacy/LegacyInstance.h
index 1b4798f6..3cf641ab 100644
--- a/api/logic/minecraft/legacy/LegacyInstance.h
+++ b/api/logic/minecraft/legacy/LegacyInstance.h
@@ -29,115 +29,115 @@ class Task;
*/
class MULTIMC_LOGIC_EXPORT LegacyInstance : public BaseInstance
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
-
- virtual void init() override {}
- virtual void saveNow() override {}
-
- /// Path to the instance's minecraft.jar
- QString runnableJar() const;
-
- //! Path to the instance's modlist file.
- QString modListFile() const;
-
- ////// Directories //////
- QString libDir() const;
- QString savesDir() const;
- QString texturePacksDir() const;
- QString jarModsDir() const;
- QString loaderModsDir() const;
- QString coreModsDir() const;
- QString resourceDir() const;
- virtual QString instanceConfigFolder() const override;
- QString minecraftRoot() const; // Path to the instance's minecraft directory.
- QString binRoot() const; // Path to the instance's minecraft bin directory.
-
- /// Get the curent base jar of this instance. By default, it's the
- /// versions/$version/$version.jar
- QString baseJar() const;
-
- /// the default base jar of this instance
- QString defaultBaseJar() const;
- /// the default custom base jar of this instance
- QString defaultCustomBaseJar() const;
-
- // the main jar that we actually want to keep when migrating the instance
- QString mainJarToPreserve() const;
-
- /*!
- * Whether or not custom base jar is used
- */
- bool shouldUseCustomBaseJar() const;
-
- /*!
- * The value of the custom base jar
- */
- QString customBaseJar() const;
-
- std::shared_ptr<LegacyModList> jarModList() const;
- QList<Mod> getJarMods() const;
- std::shared_ptr<WorldList> worldList() const;
-
- /*!
- * Whether or not the instance's minecraft.jar needs to be rebuilt.
- * If this is true, when the instance launches, its jar mods will be
- * re-added to a fresh minecraft.jar file.
- */
- bool shouldRebuild() const;
-
- QString currentVersionId() const;
- QString intendedVersionId() const;
-
- QSet<QString> traits() const override
- {
- return {"legacy-instance", "texturepacks"};
- };
-
- virtual bool shouldUpdate() const;
- virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override;
-
- virtual QString typeName() const override;
-
- bool canLaunch() const override
- {
- return false;
- }
- bool canEdit() const override
- {
- return true;
- }
- bool canExport() const override
- {
- return false;
- }
- std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override
- {
- return nullptr;
- }
- IPathMatcher::Ptr getLogFileMatcher() override
- {
- return nullptr;
- }
- QString getLogFileRoot() override
- {
- return minecraftRoot();
- }
-
- QString getStatusbarDescription() override;
- QStringList verboseDescription(AuthSessionPtr session) override;
-
- QProcessEnvironment createEnvironment() override
- {
- return QProcessEnvironment();
- }
- QMap<QString, QString> getVariables() const override
- {
- return {};
- }
+ explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
+
+ virtual void init() override {}
+ virtual void saveNow() override {}
+
+ /// Path to the instance's minecraft.jar
+ QString runnableJar() const;
+
+ //! Path to the instance's modlist file.
+ QString modListFile() const;
+
+ ////// Directories //////
+ QString libDir() const;
+ QString savesDir() const;
+ QString texturePacksDir() const;
+ QString jarModsDir() const;
+ QString loaderModsDir() const;
+ QString coreModsDir() const;
+ QString resourceDir() const;
+ virtual QString instanceConfigFolder() const override;
+ QString minecraftRoot() const; // Path to the instance's minecraft directory.
+ QString binRoot() const; // Path to the instance's minecraft bin directory.
+
+ /// Get the curent base jar of this instance. By default, it's the
+ /// versions/$version/$version.jar
+ QString baseJar() const;
+
+ /// the default base jar of this instance
+ QString defaultBaseJar() const;
+ /// the default custom base jar of this instance
+ QString defaultCustomBaseJar() const;
+
+ // the main jar that we actually want to keep when migrating the instance
+ QString mainJarToPreserve() const;
+
+ /*!
+ * Whether or not custom base jar is used
+ */
+ bool shouldUseCustomBaseJar() const;
+
+ /*!
+ * The value of the custom base jar
+ */
+ QString customBaseJar() const;
+
+ std::shared_ptr<LegacyModList> jarModList() const;
+ QList<Mod> getJarMods() const;
+ std::shared_ptr<WorldList> worldList() const;
+
+ /*!
+ * Whether or not the instance's minecraft.jar needs to be rebuilt.
+ * If this is true, when the instance launches, its jar mods will be
+ * re-added to a fresh minecraft.jar file.
+ */
+ bool shouldRebuild() const;
+
+ QString currentVersionId() const;
+ QString intendedVersionId() const;
+
+ QSet<QString> traits() const override
+ {
+ return {"legacy-instance", "texturepacks"};
+ };
+
+ virtual bool shouldUpdate() const;
+ virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override;
+
+ virtual QString typeName() const override;
+
+ bool canLaunch() const override
+ {
+ return false;
+ }
+ bool canEdit() const override
+ {
+ return true;
+ }
+ bool canExport() const override
+ {
+ return false;
+ }
+ std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override
+ {
+ return nullptr;
+ }
+ IPathMatcher::Ptr getLogFileMatcher() override
+ {
+ return nullptr;
+ }
+ QString getLogFileRoot() override
+ {
+ return minecraftRoot();
+ }
+
+ QString getStatusbarDescription() override;
+ QStringList verboseDescription(AuthSessionPtr session) override;
+
+ QProcessEnvironment createEnvironment() override
+ {
+ return QProcessEnvironment();
+ }
+ QMap<QString, QString> getVariables() const override
+ {
+ return {};
+ }
protected:
- mutable std::shared_ptr<LegacyModList> jar_mod_list;
- mutable std::shared_ptr<WorldList> m_world_list;
+ mutable std::shared_ptr<LegacyModList> jar_mod_list;
+ mutable std::shared_ptr<WorldList> m_world_list;
};
diff --git a/api/logic/minecraft/legacy/LegacyModList.cpp b/api/logic/minecraft/legacy/LegacyModList.cpp
index 638b2e21..ca171b08 100644
--- a/api/logic/minecraft/legacy/LegacyModList.cpp
+++ b/api/logic/minecraft/legacy/LegacyModList.cpp
@@ -19,153 +19,153 @@
#include <QDebug>
LegacyModList::LegacyModList(const QString &dir, const QString &list_file)
- : m_dir(dir), m_list_file(list_file)
+ : m_dir(dir), m_list_file(list_file)
{
- FS::ensureFolderPathExists(m_dir.absolutePath());
- m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
- QDir::NoSymLinks);
- m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
+ FS::ensureFolderPathExists(m_dir.absolutePath());
+ m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
+ QDir::NoSymLinks);
+ m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
}
- struct OrderItem
- {
- QString id;
- bool enabled = false;
- };
- typedef QList<OrderItem> OrderList;
+ struct OrderItem
+ {
+ QString id;
+ bool enabled = false;
+ };
+ typedef QList<OrderItem> OrderList;
static void internalSort(QList<Mod> &what)
{
- auto predicate = [](const Mod &left, const Mod &right)
- {
- if (left.name() == right.name())
- {
- return left.mmc_id().localeAwareCompare(right.mmc_id()) < 0;
- }
- return left.name().localeAwareCompare(right.name()) < 0;
- };
- std::sort(what.begin(), what.end(), predicate);
+ auto predicate = [](const Mod &left, const Mod &right)
+ {
+ if (left.name() == right.name())
+ {
+ return left.mmc_id().localeAwareCompare(right.mmc_id()) < 0;
+ }
+ return left.name().localeAwareCompare(right.name()) < 0;
+ };
+ std::sort(what.begin(), what.end(), predicate);
}
static OrderList readListFile(const QString &m_list_file)
{
- OrderList itemList;
- if (m_list_file.isNull() || m_list_file.isEmpty())
- return itemList;
+ OrderList itemList;
+ if (m_list_file.isNull() || m_list_file.isEmpty())
+ return itemList;
- QFile textFile(m_list_file);
- if (!textFile.open(QIODevice::ReadOnly | QIODevice::Text))
- return OrderList();
+ QFile textFile(m_list_file);
+ if (!textFile.open(QIODevice::ReadOnly | QIODevice::Text))
+ return OrderList();
- QTextStream textStream;
- textStream.setAutoDetectUnicode(true);
- textStream.setDevice(&textFile);
- while (true)
- {
- QString line = textStream.readLine();
- if (line.isNull() || line.isEmpty())
- break;
- else
- {
- OrderItem it;
- it.enabled = !line.endsWith(".disabled");
- if (!it.enabled)
- {
- line.chop(9);
- }
- it.id = line;
- itemList.append(it);
- }
- }
- textFile.close();
- return itemList;
+ QTextStream textStream;
+ textStream.setAutoDetectUnicode(true);
+ textStream.setDevice(&textFile);
+ while (true)
+ {
+ QString line = textStream.readLine();
+ if (line.isNull() || line.isEmpty())
+ break;
+ else
+ {
+ OrderItem it;
+ it.enabled = !line.endsWith(".disabled");
+ if (!it.enabled)
+ {
+ line.chop(9);
+ }
+ it.id = line;
+ itemList.append(it);
+ }
+ }
+ textFile.close();
+ return itemList;
}
bool LegacyModList::update()
{
- if (!m_dir.exists() || !m_dir.isReadable())
- return false;
+ if (!m_dir.exists() || !m_dir.isReadable())
+ return false;
- QList<Mod> orderedMods;
- QList<Mod> newMods;
- m_dir.refresh();
- auto folderContents = m_dir.entryInfoList();
- bool orderOrStateChanged = false;
+ QList<Mod> orderedMods;
+ QList<Mod> newMods;
+ m_dir.refresh();
+ auto folderContents = m_dir.entryInfoList();
+ bool orderOrStateChanged = false;
- // first, process the ordered items (if any)
- OrderList listOrder = readListFile(m_list_file);
- for (auto item : listOrder)
- {
- QFileInfo infoEnabled(m_dir.filePath(item.id));
- QFileInfo infoDisabled(m_dir.filePath(item.id + ".disabled"));
- int idxEnabled = folderContents.indexOf(infoEnabled);
- int idxDisabled = folderContents.indexOf(infoDisabled);
- bool isEnabled;
- // if both enabled and disabled versions are present, it's a special case...
- if (idxEnabled >= 0 && idxDisabled >= 0)
- {
- // we only process the one we actually have in the order file.
- // and exactly as we have it.
- // THIS IS A CORNER CASE
- isEnabled = item.enabled;
- }
- else
- {
- // only one is present.
- // we pick the one that we found.
- // we assume the mod was enabled/disabled by external means
- isEnabled = idxEnabled >= 0;
- }
- int idx = isEnabled ? idxEnabled : idxDisabled;
- QFileInfo &info = isEnabled ? infoEnabled : infoDisabled;
- // if the file from the index file exists
- if (idx != -1)
- {
- // remove from the actual folder contents list
- folderContents.takeAt(idx);
- // append the new mod
- orderedMods.append(Mod(info));
- if (isEnabled != item.enabled)
- orderOrStateChanged = true;
- }
- else
- {
- orderOrStateChanged = true;
- }
- }
- // if there are any untracked files...
- if (folderContents.size())
- {
- // the order surely changed!
- for (auto entry : folderContents)
- {
- newMods.append(Mod(entry));
- }
- internalSort(newMods);
- orderedMods.append(newMods);
- orderOrStateChanged = true;
- }
- // otherwise, if we were already tracking some mods
- else if (mods.size())
- {
- // if the number doesn't match, order changed.
- if (mods.size() != orderedMods.size())
- orderOrStateChanged = true;
- // if it does match, compare the mods themselves
- else
- for (int i = 0; i < mods.size(); i++)
- {
- if (!mods[i].strongCompare(orderedMods[i]))
- {
- orderOrStateChanged = true;
- break;
- }
- }
- }
- mods.swap(orderedMods);
- if (orderOrStateChanged && !m_list_file.isEmpty())
- {
- qDebug() << "Mod list " << m_list_file << " changed!";
- }
- return true;
+ // first, process the ordered items (if any)
+ OrderList listOrder = readListFile(m_list_file);
+ for (auto item : listOrder)
+ {
+ QFileInfo infoEnabled(m_dir.filePath(item.id));
+ QFileInfo infoDisabled(m_dir.filePath(item.id + ".disabled"));
+ int idxEnabled = folderContents.indexOf(infoEnabled);
+ int idxDisabled = folderContents.indexOf(infoDisabled);
+ bool isEnabled;
+ // if both enabled and disabled versions are present, it's a special case...
+ if (idxEnabled >= 0 && idxDisabled >= 0)
+ {
+ // we only process the one we actually have in the order file.
+ // and exactly as we have it.
+ // THIS IS A CORNER CASE
+ isEnabled = item.enabled;
+ }
+ else
+ {
+ // only one is present.
+ // we pick the one that we found.
+ // we assume the mod was enabled/disabled by external means
+ isEnabled = idxEnabled >= 0;
+ }
+ int idx = isEnabled ? idxEnabled : idxDisabled;
+ QFileInfo &info = isEnabled ? infoEnabled : infoDisabled;
+ // if the file from the index file exists
+ if (idx != -1)
+ {
+ // remove from the actual folder contents list
+ folderContents.takeAt(idx);
+ // append the new mod
+ orderedMods.append(Mod(info));
+ if (isEnabled != item.enabled)
+ orderOrStateChanged = true;
+ }
+ else
+ {
+ orderOrStateChanged = true;
+ }
+ }
+ // if there are any untracked files...
+ if (folderContents.size())
+ {
+ // the order surely changed!
+ for (auto entry : folderContents)
+ {
+ newMods.append(Mod(entry));
+ }
+ internalSort(newMods);
+ orderedMods.append(newMods);
+ orderOrStateChanged = true;
+ }
+ // otherwise, if we were already tracking some mods
+ else if (mods.size())
+ {
+ // if the number doesn't match, order changed.
+ if (mods.size() != orderedMods.size())
+ orderOrStateChanged = true;
+ // if it does match, compare the mods themselves
+ else
+ for (int i = 0; i < mods.size(); i++)
+ {
+ if (!mods[i].strongCompare(orderedMods[i]))
+ {
+ orderOrStateChanged = true;
+ break;
+ }
+ }
+ }
+ mods.swap(orderedMods);
+ if (orderOrStateChanged && !m_list_file.isEmpty())
+ {
+ qDebug() << "Mod list " << m_list_file << " changed!";
+ }
+ return true;
}
diff --git a/api/logic/minecraft/legacy/LegacyModList.h b/api/logic/minecraft/legacy/LegacyModList.h
index 19b191a7..8bc68b87 100644
--- a/api/logic/minecraft/legacy/LegacyModList.h
+++ b/api/logic/minecraft/legacy/LegacyModList.h
@@ -34,23 +34,23 @@ class MULTIMC_LOGIC_EXPORT LegacyModList
{
public:
- LegacyModList(const QString &dir, const QString &list_file = QString());
+ LegacyModList(const QString &dir, const QString &list_file = QString());
- /// Reloads the mod list and returns true if the list changed.
- bool update();
+ /// Reloads the mod list and returns true if the list changed.
+ bool update();
- QDir dir()
- {
- return m_dir;
- }
+ QDir dir()
+ {
+ return m_dir;
+ }
- const QList<Mod> & allMods()
- {
- return mods;
- }
+ const QList<Mod> & allMods()
+ {
+ return mods;
+ }
protected:
- QDir m_dir;
- QString m_list_file;
- QList<Mod> mods;
+ QDir m_dir;
+ QString m_list_file;
+ QList<Mod> mods;
};
diff --git a/api/logic/minecraft/legacy/LegacyUpgradeTask.cpp b/api/logic/minecraft/legacy/LegacyUpgradeTask.cpp
index 5cc3b5d9..b274f061 100644
--- a/api/logic/minecraft/legacy/LegacyUpgradeTask.cpp
+++ b/api/logic/minecraft/legacy/LegacyUpgradeTask.cpp
@@ -12,128 +12,128 @@
LegacyUpgradeTask::LegacyUpgradeTask(InstancePtr origInstance)
{
- m_origInstance = origInstance;
+ m_origInstance = origInstance;
}
void LegacyUpgradeTask::executeTask()
{
- setStatus(tr("Copying instance %1").arg(m_origInstance->name()));
+ setStatus(tr("Copying instance %1").arg(m_origInstance->name()));
- FS::copy folderCopy(m_origInstance->instanceRoot(), m_stagingPath);
- folderCopy.followSymlinks(true);
+ FS::copy folderCopy(m_origInstance->instanceRoot(), m_stagingPath);
+ folderCopy.followSymlinks(true);
- m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), folderCopy);
- connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &LegacyUpgradeTask::copyFinished);
- connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &LegacyUpgradeTask::copyAborted);
- m_copyFutureWatcher.setFuture(m_copyFuture);
+ m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), folderCopy);
+ connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &LegacyUpgradeTask::copyFinished);
+ connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &LegacyUpgradeTask::copyAborted);
+ m_copyFutureWatcher.setFuture(m_copyFuture);
}
static QString decideVersion(const QString& currentVersion, const QString& intendedVersion)
{
- if(intendedVersion != currentVersion)
- {
- if(!intendedVersion.isEmpty())
- {
- return intendedVersion;
- }
- else if(!currentVersion.isEmpty())
- {
- return currentVersion;
- }
- }
- else
- {
- if(!intendedVersion.isEmpty())
- {
- return intendedVersion;
- }
- }
- return QString();
+ if(intendedVersion != currentVersion)
+ {
+ if(!intendedVersion.isEmpty())
+ {
+ return intendedVersion;
+ }
+ else if(!currentVersion.isEmpty())
+ {
+ return currentVersion;
+ }
+ }
+ else
+ {
+ if(!intendedVersion.isEmpty())
+ {
+ return intendedVersion;
+ }
+ }
+ return QString();
}
void LegacyUpgradeTask::copyFinished()
{
- auto successful = m_copyFuture.result();
- if(!successful)
- {
- emitFailed(tr("Instance folder copy failed."));
- return;
- }
- auto legacyInst = std::dynamic_pointer_cast<LegacyInstance>(m_origInstance);
+ auto successful = m_copyFuture.result();
+ if(!successful)
+ {
+ emitFailed(tr("Instance folder copy failed."));
+ return;
+ }
+ auto legacyInst = std::dynamic_pointer_cast<LegacyInstance>(m_origInstance);
- auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg"));
- instanceSettings->registerSetting("InstanceType", "Legacy");
- instanceSettings->set("InstanceType", "OneSix");
- // NOTE: this scope ensures the instance is fully saved before we emitSucceeded
- {
- MinecraftInstance inst(m_globalSettings, instanceSettings, m_stagingPath);
- inst.setName(m_instName);
- inst.init();
+ auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg"));
+ instanceSettings->registerSetting("InstanceType", "Legacy");
+ instanceSettings->set("InstanceType", "OneSix");
+ // NOTE: this scope ensures the instance is fully saved before we emitSucceeded
+ {
+ MinecraftInstance inst(m_globalSettings, instanceSettings, m_stagingPath);
+ inst.setName(m_instName);
+ inst.init();
- QString preferredVersionNumber = decideVersion(legacyInst->currentVersionId(), legacyInst->intendedVersionId());
- if(preferredVersionNumber.isNull())
- {
- // try to decide version based on the jar(s?)
- preferredVersionNumber = classparser::GetMinecraftJarVersion(legacyInst->baseJar());
- if(preferredVersionNumber.isNull())
- {
- preferredVersionNumber = classparser::GetMinecraftJarVersion(legacyInst->runnableJar());
- if(preferredVersionNumber.isNull())
- {
- emitFailed(tr("Could not decide Minecraft version."));
- return;
- }
- }
- }
- auto components = inst.getComponentList();
- components->buildingFromScratch();
- components->setComponentVersion("net.minecraft", preferredVersionNumber, true);
+ QString preferredVersionNumber = decideVersion(legacyInst->currentVersionId(), legacyInst->intendedVersionId());
+ if(preferredVersionNumber.isNull())
+ {
+ // try to decide version based on the jar(s?)
+ preferredVersionNumber = classparser::GetMinecraftJarVersion(legacyInst->baseJar());
+ if(preferredVersionNumber.isNull())
+ {
+ preferredVersionNumber = classparser::GetMinecraftJarVersion(legacyInst->runnableJar());
+ if(preferredVersionNumber.isNull())
+ {
+ emitFailed(tr("Could not decide Minecraft version."));
+ return;
+ }
+ }
+ }
+ auto components = inst.getComponentList();
+ components->buildingFromScratch();
+ components->setComponentVersion("net.minecraft", preferredVersionNumber, true);
- QString jarPath = legacyInst->mainJarToPreserve();
- if(!jarPath.isNull())
- {
- qDebug() << "Preserving base jar! : " << jarPath;
- // FIXME: handle case when the jar is unreadable?
- // TODO: check the hash, if it's the same as the upstream jar, do not do this
- components->installCustomJar(jarPath);
- }
+ QString jarPath = legacyInst->mainJarToPreserve();
+ if(!jarPath.isNull())
+ {
+ qDebug() << "Preserving base jar! : " << jarPath;
+ // FIXME: handle case when the jar is unreadable?
+ // TODO: check the hash, if it's the same as the upstream jar, do not do this
+ components->installCustomJar(jarPath);
+ }
- auto jarMods = legacyInst->getJarMods();
- for(auto & jarMod: jarMods)
- {
- QString modPath = jarMod.filename().absoluteFilePath();
- qDebug() << "jarMod: " << modPath;
- components->installJarMods({modPath});
- }
+ auto jarMods = legacyInst->getJarMods();
+ for(auto & jarMod: jarMods)
+ {
+ QString modPath = jarMod.filename().absoluteFilePath();
+ qDebug() << "jarMod: " << modPath;
+ components->installJarMods({modPath});
+ }
- // remove all the extra garbage we no longer need
- auto removeAll = [&](const QString &root, const QStringList &things)
- {
- for(auto &thing : things)
- {
- auto removePath = FS::PathCombine(root, thing);
- QFileInfo stat(removePath);
- if(stat.isDir())
- {
- FS::deletePath(removePath);
- }
- else
- {
- QFile::remove(removePath);
- }
- }
- };
- QStringList rootRemovables = {"modlist", "version", "instMods"};
- QStringList mcRemovables = {"bin", "MultiMCLauncher.jar", "icon.png"};
- removeAll(inst.instanceRoot(), rootRemovables);
- removeAll(inst.minecraftRoot(), mcRemovables);
- }
- emitSucceeded();
+ // remove all the extra garbage we no longer need
+ auto removeAll = [&](const QString &root, const QStringList &things)
+ {
+ for(auto &thing : things)
+ {
+ auto removePath = FS::PathCombine(root, thing);
+ QFileInfo stat(removePath);
+ if(stat.isDir())
+ {
+ FS::deletePath(removePath);
+ }
+ else
+ {
+ QFile::remove(removePath);
+ }
+ }
+ };
+ QStringList rootRemovables = {"modlist", "version", "instMods"};
+ QStringList mcRemovables = {"bin", "MultiMCLauncher.jar", "icon.png"};
+ removeAll(inst.instanceRoot(), rootRemovables);
+ removeAll(inst.minecraftRoot(), mcRemovables);
+ }
+ emitSucceeded();
}
void LegacyUpgradeTask::copyAborted()
{
- emitFailed(tr("Instance folder copy has been aborted."));
- return;
+ emitFailed(tr("Instance folder copy has been aborted."));
+ return;
}
diff --git a/api/logic/minecraft/legacy/LegacyUpgradeTask.h b/api/logic/minecraft/legacy/LegacyUpgradeTask.h
index a93dd0d9..5606eb87 100644
--- a/api/logic/minecraft/legacy/LegacyUpgradeTask.h
+++ b/api/logic/minecraft/legacy/LegacyUpgradeTask.h
@@ -15,18 +15,18 @@ class BaseInstanceProvider;
class MULTIMC_LOGIC_EXPORT LegacyUpgradeTask : public InstanceTask
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit LegacyUpgradeTask(InstancePtr origInstance);
+ explicit LegacyUpgradeTask(InstancePtr origInstance);
protected:
- //! Entry point for tasks.
- virtual void executeTask() override;
- void copyFinished();
- void copyAborted();
+ //! Entry point for tasks.
+ virtual void executeTask() override;
+ void copyFinished();
+ void copyAborted();
private: /* data */
- InstancePtr m_origInstance;
- QFuture<bool> m_copyFuture;
- QFutureWatcher<bool> m_copyFutureWatcher;
+ InstancePtr m_origInstance;
+ QFuture<bool> m_copyFuture;
+ QFutureWatcher<bool> m_copyFutureWatcher;
};
diff --git a/api/logic/minecraft/testdata/lib-native-arch.json b/api/logic/minecraft/testdata/lib-native-arch.json
index a73aac54..501826ae 100644
--- a/api/logic/minecraft/testdata/lib-native-arch.json
+++ b/api/logic/minecraft/testdata/lib-native-arch.json
@@ -1,46 +1,46 @@
{
- "downloads": {
- "classifiers": {
- "natives-osx": {
- "path": "tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-osx.jar",
- "sha1": "62503ee712766cf77f97252e5902786fd834b8c5",
- "size": 418331,
- "url": "https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-osx.jar"
- },
- "natives-windows-32": {
- "path": "tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar",
- "sha1": "7c6affe439099806a4f552da14c42f9d643d8b23",
- "size": 386792,
- "url": "https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar"
- },
- "natives-windows-64": {
- "path": "tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar",
- "sha1": "39d0c3d363735b4785598e0e7fbf8297c706a9f9",
- "size": 463390,
- "url": "https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar"
- }
- }
- },
- "extract": {
- "exclude": [
- "META-INF/"
- ]
- },
- "name": "tv.twitch:twitch-platform:5.16",
- "natives": {
- "linux": "natives-linux",
- "osx": "natives-osx",
- "windows": "natives-windows-${arch}"
- },
- "rules": [
- {
- "action": "allow"
- },
- {
- "action": "disallow",
- "os": {
- "name": "linux"
- }
- }
- ]
+ "downloads": {
+ "classifiers": {
+ "natives-osx": {
+ "path": "tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-osx.jar",
+ "sha1": "62503ee712766cf77f97252e5902786fd834b8c5",
+ "size": 418331,
+ "url": "https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-osx.jar"
+ },
+ "natives-windows-32": {
+ "path": "tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar",
+ "sha1": "7c6affe439099806a4f552da14c42f9d643d8b23",
+ "size": 386792,
+ "url": "https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-32.jar"
+ },
+ "natives-windows-64": {
+ "path": "tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar",
+ "sha1": "39d0c3d363735b4785598e0e7fbf8297c706a9f9",
+ "size": 463390,
+ "url": "https://libraries.minecraft.net/tv/twitch/twitch-platform/5.16/twitch-platform-5.16-natives-windows-64.jar"
+ }
+ }
+ },
+ "extract": {
+ "exclude": [
+ "META-INF/"
+ ]
+ },
+ "name": "tv.twitch:twitch-platform:5.16",
+ "natives": {
+ "linux": "natives-linux",
+ "osx": "natives-osx",
+ "windows": "natives-windows-${arch}"
+ },
+ "rules": [
+ {
+ "action": "allow"
+ },
+ {
+ "action": "disallow",
+ "os": {
+ "name": "linux"
+ }
+ }
+ ]
}
diff --git a/api/logic/minecraft/testdata/lib-native.json b/api/logic/minecraft/testdata/lib-native.json
index 0a95b2b9..5b9f3b55 100644
--- a/api/logic/minecraft/testdata/lib-native.json
+++ b/api/logic/minecraft/testdata/lib-native.json
@@ -1,52 +1,52 @@
{
- "downloads": {
- "artifact": {
- "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar",
- "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33",
- "size": 22,
- "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar"
- },
- "classifiers": {
- "natives-linux": {
- "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar",
- "sha1": "931074f46c795d2f7b30ed6395df5715cfd7675b",
- "size": 578680,
- "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar"
- },
- "natives-osx": {
- "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar",
- "sha1": "bcab850f8f487c3f4c4dbabde778bb82bd1a40ed",
- "size": 426822,
- "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"
- },
- "natives-windows": {
- "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar",
- "sha1": "b84d5102b9dbfabfeb5e43c7e2828d98a7fc80e0",
- "size": 613748,
- "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar"
- }
- }
- },
- "extract": {
- "exclude": [
- "META-INF/"
- ]
- },
- "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209",
- "natives": {
- "linux": "natives-linux",
- "osx": "natives-osx",
- "windows": "natives-windows"
- },
- "rules": [
- {
- "action": "allow"
- },
- {
- "action": "disallow",
- "os": {
- "name": "osx"
- }
- }
- ]
+ "downloads": {
+ "artifact": {
+ "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar",
+ "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33",
+ "size": 22,
+ "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar"
+ },
+ "classifiers": {
+ "natives-linux": {
+ "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar",
+ "sha1": "931074f46c795d2f7b30ed6395df5715cfd7675b",
+ "size": 578680,
+ "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar"
+ },
+ "natives-osx": {
+ "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar",
+ "sha1": "bcab850f8f487c3f4c4dbabde778bb82bd1a40ed",
+ "size": 426822,
+ "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"
+ },
+ "natives-windows": {
+ "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar",
+ "sha1": "b84d5102b9dbfabfeb5e43c7e2828d98a7fc80e0",
+ "size": 613748,
+ "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar"
+ }
+ }
+ },
+ "extract": {
+ "exclude": [
+ "META-INF/"
+ ]
+ },
+ "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209",
+ "natives": {
+ "linux": "natives-linux",
+ "osx": "natives-osx",
+ "windows": "natives-windows"
+ },
+ "rules": [
+ {
+ "action": "allow"
+ },
+ {
+ "action": "disallow",
+ "os": {
+ "name": "osx"
+ }
+ }
+ ]
}
diff --git a/api/logic/minecraft/testdata/lib-simple.json b/api/logic/minecraft/testdata/lib-simple.json
index 3ef0f490..90bbff07 100644
--- a/api/logic/minecraft/testdata/lib-simple.json
+++ b/api/logic/minecraft/testdata/lib-simple.json
@@ -1,11 +1,11 @@
{
- "downloads": {
- "artifact": {
- "path": "com/paulscode/codecwav/20101023/codecwav-20101023.jar",
- "sha1": "12f031cfe88fef5c1dd36c563c0a3a69bd7261da",
- "size": 5618,
- "url": "https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar"
- }
- },
- "name": "com.paulscode:codecwav:20101023"
+ "downloads": {
+ "artifact": {
+ "path": "com/paulscode/codecwav/20101023/codecwav-20101023.jar",
+ "sha1": "12f031cfe88fef5c1dd36c563c0a3a69bd7261da",
+ "size": 5618,
+ "url": "https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar"
+ }
+ },
+ "name": "com.paulscode:codecwav:20101023"
}
diff --git a/api/logic/minecraft/update/AssetUpdateTask.cpp b/api/logic/minecraft/update/AssetUpdateTask.cpp
index 905c5b3d..1661822d 100644
--- a/api/logic/minecraft/update/AssetUpdateTask.cpp
+++ b/api/logic/minecraft/update/AssetUpdateTask.cpp
@@ -7,7 +7,7 @@
AssetUpdateTask::AssetUpdateTask(MinecraftInstance * inst)
{
- m_inst = inst;
+ m_inst = inst;
}
AssetUpdateTask::~AssetUpdateTask()
@@ -16,92 +16,92 @@ AssetUpdateTask::~AssetUpdateTask()
void AssetUpdateTask::executeTask()
{
- setStatus(tr("Updating assets index..."));
- auto components = m_inst->getComponentList();
- auto profile = components->getProfile();
- auto assets = profile->getMinecraftAssets();
- QUrl indexUrl = assets->url;
- QString localPath = assets->id + ".json";
- auto job = new NetJob(tr("Asset index for %1").arg(m_inst->name()));
+ setStatus(tr("Updating assets index..."));
+ auto components = m_inst->getComponentList();
+ auto profile = components->getProfile();
+ auto assets = profile->getMinecraftAssets();
+ QUrl indexUrl = assets->url;
+ QString localPath = assets->id + ".json";
+ auto job = new NetJob(tr("Asset index for %1").arg(m_inst->name()));
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("asset_indexes", localPath);
- entry->setStale(true);
- auto hexSha1 = assets->sha1.toLatin1();
- qDebug() << "Asset index SHA1:" << hexSha1;
- auto dl = Net::Download::makeCached(indexUrl, entry);
- auto rawSha1 = QByteArray::fromHex(assets->sha1.toLatin1());
- dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
- job->addNetAction(dl);
+ auto metacache = ENV.metacache();
+ auto entry = metacache->resolveEntry("asset_indexes", localPath);
+ entry->setStale(true);
+ auto hexSha1 = assets->sha1.toLatin1();
+ qDebug() << "Asset index SHA1:" << hexSha1;
+ auto dl = Net::Download::makeCached(indexUrl, entry);
+ auto rawSha1 = QByteArray::fromHex(assets->sha1.toLatin1());
+ dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
+ job->addNetAction(dl);
- downloadJob.reset(job);
+ downloadJob.reset(job);
- connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::assetIndexFinished);
- connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetIndexFailed);
- connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress);
+ connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::assetIndexFinished);
+ connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetIndexFailed);
+ connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress);
- qDebug() << m_inst->name() << ": Starting asset index download";
- downloadJob->start();
+ qDebug() << m_inst->name() << ": Starting asset index download";
+ downloadJob->start();
}
bool AssetUpdateTask::canAbort() const
{
- return true;
+ return true;
}
void AssetUpdateTask::assetIndexFinished()
{
- AssetsIndex index;
- qDebug() << m_inst->name() << ": Finished asset index download";
+ AssetsIndex index;
+ qDebug() << m_inst->name() << ": Finished asset index download";
- auto components = m_inst->getComponentList();
- auto profile = components->getProfile();
- auto assets = profile->getMinecraftAssets();
+ auto components = m_inst->getComponentList();
+ auto profile = components->getProfile();
+ auto assets = profile->getMinecraftAssets();
- QString asset_fname = "assets/indexes/" + assets->id + ".json";
- // FIXME: this looks like a job for a generic validator based on json schema?
- if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, &index))
- {
- auto metacache = ENV.metacache();
- auto entry = metacache->resolveEntry("asset_indexes", assets->id + ".json");
- metacache->evictEntry(entry);
- emitFailed(tr("Failed to read the assets index!"));
- }
+ QString asset_fname = "assets/indexes/" + assets->id + ".json";
+ // FIXME: this looks like a job for a generic validator based on json schema?
+ if (!AssetsUtils::loadAssetsIndexJson(assets->id, asset_fname, &index))
+ {
+ auto metacache = ENV.metacache();
+ auto entry = metacache->resolveEntry("asset_indexes", assets->id + ".json");
+ metacache->evictEntry(entry);
+ emitFailed(tr("Failed to read the assets index!"));
+ }
- auto job = index.getDownloadJob();
- if(job)
- {
- setStatus(tr("Getting the assets files from Mojang..."));
- downloadJob = job;
- connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::emitSucceeded);
- connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetsFailed);
- connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress);
- downloadJob->start();
- return;
- }
- emitSucceeded();
+ auto job = index.getDownloadJob();
+ if(job)
+ {
+ setStatus(tr("Getting the assets files from Mojang..."));
+ downloadJob = job;
+ connect(downloadJob.get(), &NetJob::succeeded, this, &AssetUpdateTask::emitSucceeded);
+ connect(downloadJob.get(), &NetJob::failed, this, &AssetUpdateTask::assetsFailed);
+ connect(downloadJob.get(), &NetJob::progress, this, &AssetUpdateTask::progress);
+ downloadJob->start();
+ return;
+ }
+ emitSucceeded();
}
void AssetUpdateTask::assetIndexFailed(QString reason)
{
- qDebug() << m_inst->name() << ": Failed asset index download";
- emitFailed(tr("Failed to download the assets index:\n%1").arg(reason));
+ qDebug() << m_inst->name() << ": Failed asset index download";
+ emitFailed(tr("Failed to download the assets index:\n%1").arg(reason));
}
void AssetUpdateTask::assetsFailed(QString reason)
{
- emitFailed(tr("Failed to download assets:\n%1").arg(reason));
+ emitFailed(tr("Failed to download assets:\n%1").arg(reason));
}
bool AssetUpdateTask::abort()
{
- if(downloadJob)
- {
- return downloadJob->abort();
- }
- else
- {
- qWarning() << "Prematurely aborted FMLLibrariesTask";
- }
- return true;
+ if(downloadJob)
+ {
+ return downloadJob->abort();
+ }
+ else
+ {
+ qWarning() << "Prematurely aborted FMLLibrariesTask";
+ }
+ return true;
}
diff --git a/api/logic/minecraft/update/AssetUpdateTask.h b/api/logic/minecraft/update/AssetUpdateTask.h
index 870cede5..fdfa8f1c 100644
--- a/api/logic/minecraft/update/AssetUpdateTask.h
+++ b/api/logic/minecraft/update/AssetUpdateTask.h
@@ -5,24 +5,24 @@ class MinecraftInstance;
class AssetUpdateTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- AssetUpdateTask(MinecraftInstance * inst);
- virtual ~AssetUpdateTask();
+ AssetUpdateTask(MinecraftInstance * inst);
+ virtual ~AssetUpdateTask();
- void executeTask() override;
+ void executeTask() override;
- bool canAbort() const override;
+ bool canAbort() const override;
private slots:
- void assetIndexFinished();
- void assetIndexFailed(QString reason);
- void assetsFailed(QString reason);
+ void assetIndexFinished();
+ void assetIndexFailed(QString reason);
+ void assetsFailed(QString reason);
public slots:
- bool abort() override;
+ bool abort() override;
private:
- MinecraftInstance *m_inst;
- NetJobPtr downloadJob;
+ MinecraftInstance *m_inst;
+ NetJobPtr downloadJob;
};
diff --git a/api/logic/minecraft/update/FMLLibrariesTask.cpp b/api/logic/minecraft/update/FMLLibrariesTask.cpp
index 1bd339e4..5b4975ab 100644
--- a/api/logic/minecraft/update/FMLLibrariesTask.cpp
+++ b/api/logic/minecraft/update/FMLLibrariesTask.cpp
@@ -7,125 +7,125 @@
FMLLibrariesTask::FMLLibrariesTask(MinecraftInstance * inst)
{
- m_inst = inst;
+ m_inst = inst;
}
void FMLLibrariesTask::executeTask()
{
- // Get the mod list
- MinecraftInstance *inst = (MinecraftInstance *)m_inst;
- auto components = inst->getComponentList();
- auto profile = components->getProfile();
+ // Get the mod list
+ MinecraftInstance *inst = (MinecraftInstance *)m_inst;
+ auto components = inst->getComponentList();
+ auto profile = components->getProfile();
- if (!profile->hasTrait("legacyFML"))
- {
- emitSucceeded();
- return;
- }
+ if (!profile->hasTrait("legacyFML"))
+ {
+ emitSucceeded();
+ return;
+ }
- QString version = components->getComponentVersion("net.minecraft");
- auto &fmlLibsMapping = g_VersionFilterData.fmlLibsMapping;
- if (!fmlLibsMapping.contains(version))
- {
- emitSucceeded();
- return;
- }
+ QString version = components->getComponentVersion("net.minecraft");
+ auto &fmlLibsMapping = g_VersionFilterData.fmlLibsMapping;
+ if (!fmlLibsMapping.contains(version))
+ {
+ emitSucceeded();
+ return;
+ }
- auto &libList = fmlLibsMapping[version];
+ auto &libList = fmlLibsMapping[version];
- // determine if we need some libs for FML or forge
- setStatus(tr("Checking for FML libraries..."));
- if(!components->getComponent("net.minecraftforge"))
- {
- emitSucceeded();
- return;
- }
+ // determine if we need some libs for FML or forge
+ setStatus(tr("Checking for FML libraries..."));
+ if(!components->getComponent("net.minecraftforge"))
+ {
+ emitSucceeded();
+ return;
+ }
- // now check the lib folder inside the instance for files.
- for (auto &lib : libList)
- {
- QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
- if (libInfo.exists())
- continue;
- fmlLibsToProcess.append(lib);
- }
+ // now check the lib folder inside the instance for files.
+ for (auto &lib : libList)
+ {
+ QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
+ if (libInfo.exists())
+ continue;
+ fmlLibsToProcess.append(lib);
+ }
- // if everything is in place, there's nothing to do here...
- if (fmlLibsToProcess.isEmpty())
- {
- emitSucceeded();
- return;
- }
+ // if everything is in place, there's nothing to do here...
+ if (fmlLibsToProcess.isEmpty())
+ {
+ emitSucceeded();
+ return;
+ }
- // download missing libs to our place
- setStatus(tr("Dowloading FML libraries..."));
- auto dljob = new NetJob("FML libraries");
- auto metacache = ENV.metacache();
- for (auto &lib : fmlLibsToProcess)
- {
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename
- : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename;
- dljob->addNetAction(Net::Download::makeCached(QUrl(urlString), entry));
- }
+ // download missing libs to our place
+ setStatus(tr("Dowloading FML libraries..."));
+ auto dljob = new NetJob("FML libraries");
+ auto metacache = ENV.metacache();
+ for (auto &lib : fmlLibsToProcess)
+ {
+ auto entry = metacache->resolveEntry("fmllibs", lib.filename);
+ QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename
+ : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename;
+ dljob->addNetAction(Net::Download::makeCached(QUrl(urlString), entry));
+ }
- connect(dljob, &NetJob::succeeded, this, &FMLLibrariesTask::fmllibsFinished);
- connect(dljob, &NetJob::failed, this, &FMLLibrariesTask::fmllibsFailed);
- connect(dljob, &NetJob::progress, this, &FMLLibrariesTask::progress);
- downloadJob.reset(dljob);
- downloadJob->start();
+ connect(dljob, &NetJob::succeeded, this, &FMLLibrariesTask::fmllibsFinished);
+ connect(dljob, &NetJob::failed, this, &FMLLibrariesTask::fmllibsFailed);
+ connect(dljob, &NetJob::progress, this, &FMLLibrariesTask::progress);
+ downloadJob.reset(dljob);
+ downloadJob->start();
}
bool FMLLibrariesTask::canAbort() const
{
- return true;
+ return true;
}
void FMLLibrariesTask::fmllibsFinished()
{
- downloadJob.reset();
- if (!fmlLibsToProcess.isEmpty())
- {
- setStatus(tr("Copying FML libraries into the instance..."));
- MinecraftInstance *inst = (MinecraftInstance *)m_inst;
- auto metacache = ENV.metacache();
- int index = 0;
- for (auto &lib : fmlLibsToProcess)
- {
- progress(index, fmlLibsToProcess.size());
- auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- auto path = FS::PathCombine(inst->libDir(), lib.filename);
- if (!FS::ensureFilePathExists(path))
- {
- emitFailed(tr("Failed creating FML library folder inside the instance."));
- return;
- }
- if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
- {
- emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
- return;
- }
- index++;
- }
- progress(index, fmlLibsToProcess.size());
- }
- emitSucceeded();
+ downloadJob.reset();
+ if (!fmlLibsToProcess.isEmpty())
+ {
+ setStatus(tr("Copying FML libraries into the instance..."));
+ MinecraftInstance *inst = (MinecraftInstance *)m_inst;
+ auto metacache = ENV.metacache();
+ int index = 0;
+ for (auto &lib : fmlLibsToProcess)
+ {
+ progress(index, fmlLibsToProcess.size());
+ auto entry = metacache->resolveEntry("fmllibs", lib.filename);
+ auto path = FS::PathCombine(inst->libDir(), lib.filename);
+ if (!FS::ensureFilePathExists(path))
+ {
+ emitFailed(tr("Failed creating FML library folder inside the instance."));
+ return;
+ }
+ if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
+ {
+ emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
+ return;
+ }
+ index++;
+ }
+ progress(index, fmlLibsToProcess.size());
+ }
+ emitSucceeded();
}
void FMLLibrariesTask::fmllibsFailed(QString reason)
{
- QStringList failed = downloadJob->getFailedFiles();
- QString failed_all = failed.join("\n");
- emitFailed(tr("Failed to download the following files:\n%1\n\nReason:%2\nPlease try again.").arg(failed_all, reason));
+ QStringList failed = downloadJob->getFailedFiles();
+ QString failed_all = failed.join("\n");
+ emitFailed(tr("Failed to download the following files:\n%1\n\nReason:%2\nPlease try again.").arg(failed_all, reason));
}
bool FMLLibrariesTask::abort()
{
- if(downloadJob)
- {
- return downloadJob->abort();
- }
- else
- {
- qWarning() << "Prematurely aborted FMLLibrariesTask";
- }
- return true;
+ if(downloadJob)
+ {
+ return downloadJob->abort();
+ }
+ else
+ {
+ qWarning() << "Prematurely aborted FMLLibrariesTask";
+ }
+ return true;
}
diff --git a/api/logic/minecraft/update/FMLLibrariesTask.h b/api/logic/minecraft/update/FMLLibrariesTask.h
index f281890d..a1e70ed4 100644
--- a/api/logic/minecraft/update/FMLLibrariesTask.h
+++ b/api/logic/minecraft/update/FMLLibrariesTask.h
@@ -7,25 +7,25 @@ class MinecraftInstance;
class FMLLibrariesTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- FMLLibrariesTask(MinecraftInstance * inst);
- virtual ~FMLLibrariesTask() {};
+ FMLLibrariesTask(MinecraftInstance * inst);
+ virtual ~FMLLibrariesTask() {};
- void executeTask() override;
+ void executeTask() override;
- bool canAbort() const override;
+ bool canAbort() const override;
private slots:
- void fmllibsFinished();
- void fmllibsFailed(QString reason);
+ void fmllibsFinished();
+ void fmllibsFailed(QString reason);
public slots:
- bool abort() override;
+ bool abort() override;
private:
- MinecraftInstance *m_inst;
- NetJobPtr downloadJob;
- QList<FMLlib> fmlLibsToProcess;
+ MinecraftInstance *m_inst;
+ NetJobPtr downloadJob;
+ QList<FMLlib> fmlLibsToProcess;
};
diff --git a/api/logic/minecraft/update/FoldersTask.cpp b/api/logic/minecraft/update/FoldersTask.cpp
index 34e2292a..2073b14e 100644
--- a/api/logic/minecraft/update/FoldersTask.cpp
+++ b/api/logic/minecraft/update/FoldersTask.cpp
@@ -3,19 +3,19 @@
#include <QDir>
FoldersTask::FoldersTask(MinecraftInstance * inst)
- :Task()
+ :Task()
{
- m_inst = inst;
+ m_inst = inst;
}
void FoldersTask::executeTask()
{
- // Make directories
- QDir mcDir(m_inst->minecraftRoot());
- if (!mcDir.exists() && !mcDir.mkpath("."))
- {
- emitFailed(tr("Failed to create folder for minecraft binaries."));
- return;
- }
- emitSucceeded();
+ // Make directories
+ QDir mcDir(m_inst->minecraftRoot());
+ if (!mcDir.exists() && !mcDir.mkpath("."))
+ {
+ emitFailed(tr("Failed to create folder for minecraft binaries."));
+ return;
+ }
+ emitSucceeded();
}
diff --git a/api/logic/minecraft/update/FoldersTask.h b/api/logic/minecraft/update/FoldersTask.h
index e0781ad8..f6ed5e6d 100644
--- a/api/logic/minecraft/update/FoldersTask.h
+++ b/api/logic/minecraft/update/FoldersTask.h
@@ -5,13 +5,13 @@
class MinecraftInstance;
class FoldersTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- FoldersTask(MinecraftInstance * inst);
- virtual ~FoldersTask() {};
+ FoldersTask(MinecraftInstance * inst);
+ virtual ~FoldersTask() {};
- void executeTask() override;
+ void executeTask() override;
private:
- MinecraftInstance *m_inst;
+ MinecraftInstance *m_inst;
};
diff --git a/api/logic/minecraft/update/LibrariesTask.cpp b/api/logic/minecraft/update/LibrariesTask.cpp
index 0bec61c1..6dcb149c 100644
--- a/api/logic/minecraft/update/LibrariesTask.cpp
+++ b/api/logic/minecraft/update/LibrariesTask.cpp
@@ -5,86 +5,86 @@
LibrariesTask::LibrariesTask(MinecraftInstance * inst)
{
- m_inst = inst;
+ m_inst = inst;
}
void LibrariesTask::executeTask()
{
- setStatus(tr("Getting the library files from Mojang..."));
- qDebug() << m_inst->name() << ": downloading libraries";
- MinecraftInstance *inst = (MinecraftInstance *)m_inst;
+ setStatus(tr("Getting the library files from Mojang..."));
+ qDebug() << m_inst->name() << ": downloading libraries";
+ MinecraftInstance *inst = (MinecraftInstance *)m_inst;
- // Build a list of URLs that will need to be downloaded.
- auto components = inst->getComponentList();
- auto profile = components->getProfile();
+ // Build a list of URLs that will need to be downloaded.
+ auto components = inst->getComponentList();
+ auto profile = components->getProfile();
- auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name()));
- downloadJob.reset(job);
+ auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name()));
+ downloadJob.reset(job);
- auto metacache = ENV.metacache();
- QList<LibraryPtr> brokenLocalLibs;
- QStringList failedFiles;
- auto createJob = [&](const LibraryPtr & lib)
- {
- if(!lib)
- {
- emitFailed(tr("Null jar is specified in the metadata, aborting."));
- return;
- }
- auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles, inst->getLocalLibraryPath());
- for(auto dl : dls)
- {
- downloadJob->addNetAction(dl);
- }
- };
- auto createJobs = [&](const QList<LibraryPtr> & libs)
- {
- for (auto lib : libs)
- {
- createJob(lib);
- }
- };
- createJobs(profile->getLibraries());
- createJobs(profile->getNativeLibraries());
- createJobs(profile->getJarMods());
- createJob(profile->getMainJar());
+ auto metacache = ENV.metacache();
+ QList<LibraryPtr> brokenLocalLibs;
+ QStringList failedFiles;
+ auto createJob = [&](const LibraryPtr & lib)
+ {
+ if(!lib)
+ {
+ emitFailed(tr("Null jar is specified in the metadata, aborting."));
+ return;
+ }
+ auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles, inst->getLocalLibraryPath());
+ for(auto dl : dls)
+ {
+ downloadJob->addNetAction(dl);
+ }
+ };
+ auto createJobs = [&](const QList<LibraryPtr> & libs)
+ {
+ for (auto lib : libs)
+ {
+ createJob(lib);
+ }
+ };
+ createJobs(profile->getLibraries());
+ createJobs(profile->getNativeLibraries());
+ createJobs(profile->getJarMods());
+ createJob(profile->getMainJar());
- // FIXME: this is never filled!!!!
- if (!brokenLocalLibs.empty())
- {
- downloadJob.reset();
- QString failed_all = failedFiles.join("\n");
- emitFailed(tr("Some libraries marked as 'local' are missing their jar "
- "files:\n%1\n\nYou'll have to correct this problem manually. If this is "
- "an externally tracked instance, make sure to run it at least once "
- "outside of MultiMC.").arg(failed_all));
- return;
- }
- connect(downloadJob.get(), &NetJob::succeeded, this, &LibrariesTask::emitSucceeded);
- connect(downloadJob.get(), &NetJob::failed, this, &LibrariesTask::jarlibFailed);
- connect(downloadJob.get(), &NetJob::progress, this, &LibrariesTask::progress);
- downloadJob->start();
+ // FIXME: this is never filled!!!!
+ if (!brokenLocalLibs.empty())
+ {
+ downloadJob.reset();
+ QString failed_all = failedFiles.join("\n");
+ emitFailed(tr("Some libraries marked as 'local' are missing their jar "
+ "files:\n%1\n\nYou'll have to correct this problem manually. If this is "
+ "an externally tracked instance, make sure to run it at least once "
+ "outside of MultiMC.").arg(failed_all));
+ return;
+ }
+ connect(downloadJob.get(), &NetJob::succeeded, this, &LibrariesTask::emitSucceeded);
+ connect(downloadJob.get(), &NetJob::failed, this, &LibrariesTask::jarlibFailed);
+ connect(downloadJob.get(), &NetJob::progress, this, &LibrariesTask::progress);
+ downloadJob->start();
}
bool LibrariesTask::canAbort() const
{
- return true;
+ return true;
}
void LibrariesTask::jarlibFailed(QString reason)
{
- emitFailed(tr("Game update failed: it was impossible to fetch the required libraries.\nReason:\n%1").arg(reason));
+ emitFailed(tr("Game update failed: it was impossible to fetch the required libraries.\nReason:\n%1").arg(reason));
}
bool LibrariesTask::abort()
{
- if(downloadJob)
- {
- return downloadJob->abort();
- }
- else
- {
- qWarning() << "Prematurely aborted LibrariesTask";
- }
- return true;
+ if(downloadJob)
+ {
+ return downloadJob->abort();
+ }
+ else
+ {
+ qWarning() << "Prematurely aborted LibrariesTask";
+ }
+ return true;
}
diff --git a/api/logic/minecraft/update/LibrariesTask.h b/api/logic/minecraft/update/LibrariesTask.h
index cb9babc3..49f76932 100644
--- a/api/logic/minecraft/update/LibrariesTask.h
+++ b/api/logic/minecraft/update/LibrariesTask.h
@@ -5,22 +5,22 @@ class MinecraftInstance;
class LibrariesTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- LibrariesTask(MinecraftInstance * inst);
- virtual ~LibrariesTask() {};
+ LibrariesTask(MinecraftInstance * inst);
+ virtual ~LibrariesTask() {};
- void executeTask() override;
+ void executeTask() override;
- bool canAbort() const override;
+ bool canAbort() const override;
private slots:
- void jarlibFailed(QString reason);
+ void jarlibFailed(QString reason);
public slots:
- bool abort() override;
+ bool abort() override;
private:
- MinecraftInstance *m_inst;
- NetJobPtr downloadJob;
+ MinecraftInstance *m_inst;
+ NetJobPtr downloadJob;
};
diff --git a/api/logic/modplatform/flame/FileResolvingTask.cpp b/api/logic/modplatform/flame/FileResolvingTask.cpp
index 5eb82458..24cafcdd 100644
--- a/api/logic/modplatform/flame/FileResolvingTask.cpp
+++ b/api/logic/modplatform/flame/FileResolvingTask.cpp
@@ -4,114 +4,114 @@
const char * metabase = "https://cursemeta.dries007.net";
Flame::FileResolvingTask::FileResolvingTask(Flame::Manifest& toProcess)
- : m_toProcess(toProcess)
+ : m_toProcess(toProcess)
{
}
void Flame::FileResolvingTask::executeTask()
{
- setStatus(tr("Resolving mod IDs..."));
- setProgress(0, m_toProcess.files.size());
- m_dljob.reset(new NetJob("Mod id resolver"));
- results.resize(m_toProcess.files.size());
- int index = 0;
- for(auto & file: m_toProcess.files)
- {
- auto projectIdStr = QString::number(file.projectId);
- auto fileIdStr = QString::number(file.fileId);
- QString metaurl = QString("%1/%2/%3.json").arg(metabase, projectIdStr, fileIdStr);
- auto dl = Net::Download::makeByteArray(QUrl(metaurl), &results[index]);
- m_dljob->addNetAction(dl);
- index ++;
- }
- connect(m_dljob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::netJobFinished);
- m_dljob->start();
+ setStatus(tr("Resolving mod IDs..."));
+ setProgress(0, m_toProcess.files.size());
+ m_dljob.reset(new NetJob("Mod id resolver"));
+ results.resize(m_toProcess.files.size());
+ int index = 0;
+ for(auto & file: m_toProcess.files)
+ {
+ auto projectIdStr = QString::number(file.projectId);
+ auto fileIdStr = QString::number(file.fileId);
+ QString metaurl = QString("%1/%2/%3.json").arg(metabase, projectIdStr, fileIdStr);
+ auto dl = Net::Download::makeByteArray(QUrl(metaurl), &results[index]);
+ m_dljob->addNetAction(dl);
+ index ++;
+ }
+ connect(m_dljob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::netJobFinished);
+ m_dljob->start();
}
void Flame::FileResolvingTask::netJobFinished()
{
- bool failed = false;
- int index = 0;
- for(auto & bytes: results)
- {
- try
- {
- auto doc = Json::requireDocument(bytes);
- auto obj = Json::requireObject(doc);
- auto & out = m_toProcess.files[index];
- // result code signifies true failure.
- if(obj.contains("code"))
- {
- qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of a negative result:";
- qCritical() << bytes;
- failed = true;
- continue;
- }
- out.fileName = Json::requireString(obj, "FileNameOnDisk");
- QString rawUrl = Json::requireString(obj, "DownloadURL");
- out.url = QUrl(rawUrl, QUrl::TolerantMode);
- if(!out.url.isValid())
- {
- throw JSONValidationError(QString("Invalid URL: %1").arg(rawUrl));
- }
- // This is a piece of a Flame project JSON pulled out into the file metadata (here) for convenience
- // It is also optional
- QJsonObject projObj = Json::ensureObject(obj, "_Project", {});
- if(!projObj.isEmpty())
- {
- QString strType = Json::ensureString(projObj, "PackageType", "mod").toLower();
- if(strType == "singlefile")
- {
- out.type = File::Type::SingleFile;
- }
- else if(strType == "ctoc")
- {
- out.type = File::Type::Ctoc;
- }
- else if(strType == "cmod2")
- {
- out.type = File::Type::Cmod2;
- }
- else if(strType == "mod")
- {
- out.type = File::Type::Mod;
- }
- else if(strType == "folder")
- {
- out.type = File::Type::Folder;
- }
- else if(strType == "modpack")
- {
- out.type = File::Type::Modpack;
- }
- else
- {
- qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of unknown file type:" << strType;
- out.type = File::Type::Unknown;
- failed = true;
- continue;
- }
- out.targetFolder = Json::ensureString(projObj, "Path", "mods");
- }
- out.resolved = true;
- }
- catch (const JSONValidationError &e)
- {
- auto & out = m_toProcess.files[index];
- qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of a parsing error:";
- qCritical() << e.cause();
- qCritical() << "JSON:";
- qCritical() << bytes;
- failed = true;
- }
- index++;
- }
- if(!failed)
- {
- emitSucceeded();
- }
- else
- {
- emitFailed(tr("Some mod ID resolving tasks failed."));
- }
+ bool failed = false;
+ int index = 0;
+ for(auto & bytes: results)
+ {
+ try
+ {
+ auto doc = Json::requireDocument(bytes);
+ auto obj = Json::requireObject(doc);
+ auto & out = m_toProcess.files[index];
+ // result code signifies true failure.
+ if(obj.contains("code"))
+ {
+ qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of a negative result:";
+ qCritical() << bytes;
+ failed = true;
+ continue;
+ }
+ out.fileName = Json::requireString(obj, "FileNameOnDisk");
+ QString rawUrl = Json::requireString(obj, "DownloadURL");
+ out.url = QUrl(rawUrl, QUrl::TolerantMode);
+ if(!out.url.isValid())
+ {
+ throw JSONValidationError(QString("Invalid URL: %1").arg(rawUrl));
+ }
+ // This is a piece of a Flame project JSON pulled out into the file metadata (here) for convenience
+ // It is also optional
+ QJsonObject projObj = Json::ensureObject(obj, "_Project", {});
+ if(!projObj.isEmpty())
+ {
+ QString strType = Json::ensureString(projObj, "PackageType", "mod").toLower();
+ if(strType == "singlefile")
+ {
+ out.type = File::Type::SingleFile;
+ }
+ else if(strType == "ctoc")
+ {
+ out.type = File::Type::Ctoc;
+ }
+ else if(strType == "cmod2")
+ {
+ out.type = File::Type::Cmod2;
+ }
+ else if(strType == "mod")
+ {
+ out.type = File::Type::Mod;
+ }
+ else if(strType == "folder")
+ {
+ out.type = File::Type::Folder;
+ }
+ else if(strType == "modpack")
+ {
+ out.type = File::Type::Modpack;
+ }
+ else
+ {
+ qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of unknown file type:" << strType;
+ out.type = File::Type::Unknown;
+ failed = true;
+ continue;
+ }
+ out.targetFolder = Json::ensureString(projObj, "Path", "mods");
+ }
+ out.resolved = true;
+ }
+ catch (const JSONValidationError &e)
+ {
+ auto & out = m_toProcess.files[index];
+ qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of a parsing error:";
+ qCritical() << e.cause();
+ qCritical() << "JSON:";
+ qCritical() << bytes;
+ failed = true;
+ }
+ index++;
+ }
+ if(!failed)
+ {
+ emitSucceeded();
+ }
+ else
+ {
+ emitFailed(tr("Some mod ID resolving tasks failed."));
+ }
}
diff --git a/api/logic/modplatform/flame/FileResolvingTask.h b/api/logic/modplatform/flame/FileResolvingTask.h
index e5ed633e..5679b907 100644
--- a/api/logic/modplatform/flame/FileResolvingTask.h
+++ b/api/logic/modplatform/flame/FileResolvingTask.h
@@ -10,25 +10,25 @@ namespace Flame
{
class MULTIMC_LOGIC_EXPORT FileResolvingTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit FileResolvingTask(Flame::Manifest &toProcess);
- virtual ~FileResolvingTask() {};
+ explicit FileResolvingTask(Flame::Manifest &toProcess);
+ virtual ~FileResolvingTask() {};
- const Flame::Manifest &getResults() const
- {
- return m_toProcess;
- }
+ const Flame::Manifest &getResults() const
+ {
+ return m_toProcess;
+ }
protected:
- virtual void executeTask() override;
+ virtual void executeTask() override;
protected slots:
- void netJobFinished();
+ void netJobFinished();
private: /* data */
- Flame::Manifest m_toProcess;
- QVector<QByteArray> results;
- NetJobPtr m_dljob;
+ Flame::Manifest m_toProcess;
+ QVector<QByteArray> results;
+ NetJobPtr m_dljob;
};
}
diff --git a/api/logic/modplatform/flame/PackManifest.cpp b/api/logic/modplatform/flame/PackManifest.cpp
index 6a9324fe..0f57c9bc 100644
--- a/api/logic/modplatform/flame/PackManifest.cpp
+++ b/api/logic/modplatform/flame/PackManifest.cpp
@@ -3,64 +3,64 @@
static void loadFileV1(Flame::File & f, QJsonObject & file)
{
- f.projectId = Json::requireInteger(file, "projectID");
- f.fileId = Json::requireInteger(file, "fileID");
- f.required = Json::ensureBoolean(file, QString("required"), true);
+ f.projectId = Json::requireInteger(file, "projectID");
+ f.fileId = Json::requireInteger(file, "fileID");
+ f.required = Json::ensureBoolean(file, QString("required"), true);
}
static void loadModloaderV1(Flame::Modloader & m, QJsonObject & modLoader)
{
- m.id = Json::requireString(modLoader, "id");
- m.primary = Json::ensureBoolean(modLoader, QString("primary"), false);
+ m.id = Json::requireString(modLoader, "id");
+ m.primary = Json::ensureBoolean(modLoader, QString("primary"), false);
}
static void loadMinecraftV1(Flame::Minecraft & m, QJsonObject & minecraft)
{
- m.version = Json::requireString(minecraft, "version");
- // extra libraries... apparently only used for a custom Minecraft launcher in the 1.2.5 FTB retro pack
- // intended use is likely hardcoded in the 'Flame' client, the manifest says nothing
- m.libraries = Json::ensureString(minecraft, QString("libraries"), QString());
- auto arr = Json::ensureArray(minecraft, "modLoaders", QJsonArray());
- for (const auto & item : arr)
- {
- auto obj = Json::requireObject(item);
- Flame::Modloader loader;
- loadModloaderV1(loader, obj);
- m.modLoaders.append(loader);
- }
+ m.version = Json::requireString(minecraft, "version");
+ // extra libraries... apparently only used for a custom Minecraft launcher in the 1.2.5 FTB retro pack
+ // intended use is likely hardcoded in the 'Flame' client, the manifest says nothing
+ m.libraries = Json::ensureString(minecraft, QString("libraries"), QString());
+ auto arr = Json::ensureArray(minecraft, "modLoaders", QJsonArray());
+ for (const auto & item : arr)
+ {
+ auto obj = Json::requireObject(item);
+ Flame::Modloader loader;
+ loadModloaderV1(loader, obj);
+ m.modLoaders.append(loader);
+ }
}
static void loadManifestV1(Flame::Manifest & m, QJsonObject & manifest)
{
- auto mc = Json::requireObject(manifest, "minecraft");
- loadMinecraftV1(m.minecraft, mc);
- m.name = Json::ensureString(manifest, QString("name"), "Unnamed");
- m.version = Json::ensureString(manifest, QString("version"), QString());
- m.author = Json::ensureString(manifest, QString("author"), "Anonymous Coward");
- auto arr = Json::ensureArray(manifest, "files", QJsonArray());
- for (const auto & item : arr)
- {
- auto obj = Json::requireObject(item);
- Flame::File file;
- loadFileV1(file, obj);
- m.files.append(file);
- }
- m.overrides = Json::ensureString(manifest, "overrides", "overrides");
+ auto mc = Json::requireObject(manifest, "minecraft");
+ loadMinecraftV1(m.minecraft, mc);
+ m.name = Json::ensureString(manifest, QString("name"), "Unnamed");
+ m.version = Json::ensureString(manifest, QString("version"), QString());
+ m.author = Json::ensureString(manifest, QString("author"), "Anonymous Coward");
+ auto arr = Json::ensureArray(manifest, "files", QJsonArray());
+ for (const auto & item : arr)
+ {
+ auto obj = Json::requireObject(item);
+ Flame::File file;
+ loadFileV1(file, obj);
+ m.files.append(file);
+ }
+ m.overrides = Json::ensureString(manifest, "overrides", "overrides");
}
void Flame::loadManifest(Flame::Manifest & m, const QString &filepath)
{
- auto doc = Json::requireDocument(filepath);
- auto obj = Json::requireObject(doc);
- m.manifestType = Json::requireString(obj, "manifestType");
- if(m.manifestType != "minecraftModpack")
- {
- throw JSONValidationError("Not a modpack manifest!");
- }
- m.manifestVersion = Json::requireInteger(obj, "manifestVersion");
- if(m.manifestVersion != 1)
- {
- throw JSONValidationError(QString("Unknown manifest version (%1)").arg(m.manifestVersion));
- }
- loadManifestV1(m, obj);
+ auto doc = Json::requireDocument(filepath);
+ auto obj = Json::requireObject(doc);
+ m.manifestType = Json::requireString(obj, "manifestType");
+ if(m.manifestType != "minecraftModpack")
+ {
+ throw JSONValidationError("Not a modpack manifest!");
+ }
+ m.manifestVersion = Json::requireInteger(obj, "manifestVersion");
+ if(m.manifestVersion != 1)
+ {
+ throw JSONValidationError(QString("Unknown manifest version (%1)").arg(m.manifestVersion));
+ }
+ loadManifestV1(m, obj);
}
diff --git a/api/logic/modplatform/flame/PackManifest.h b/api/logic/modplatform/flame/PackManifest.h
index 1a5254a8..34232eee 100644
--- a/api/logic/modplatform/flame/PackManifest.h
+++ b/api/logic/modplatform/flame/PackManifest.h
@@ -8,51 +8,51 @@ namespace Flame
{
struct File
{
- int projectId = 0;
- int fileId = 0;
- // NOTE: the opposite to 'optional'. This is at the time of writing unused.
- bool required = true;
+ int projectId = 0;
+ int fileId = 0;
+ // NOTE: the opposite to 'optional'. This is at the time of writing unused.
+ bool required = true;
- // our
- bool resolved = false;
- QString fileName;
- QUrl url;
- QString targetFolder = QLatin1Literal("mods");
- enum class Type
- {
- Unknown,
- Folder,
- Ctoc,
- SingleFile,
- Cmod2,
- Modpack,
- Mod
- } type = Type::Mod;
+ // our
+ bool resolved = false;
+ QString fileName;
+ QUrl url;
+ QString targetFolder = QLatin1Literal("mods");
+ enum class Type
+ {
+ Unknown,
+ Folder,
+ Ctoc,
+ SingleFile,
+ Cmod2,
+ Modpack,
+ Mod
+ } type = Type::Mod;
};
struct Modloader
{
- QString id;
- bool primary = false;
+ QString id;
+ bool primary = false;
};
struct Minecraft
{
- QString version;
- QString libraries;
- QVector<Flame::Modloader> modLoaders;
+ QString version;
+ QString libraries;
+ QVector<Flame::Modloader> modLoaders;
};
struct Manifest
{
- QString manifestType;
- int manifestVersion = 0;
- Flame::Minecraft minecraft;
- QString name;
- QString version;
- QString author;
- QVector<Flame::File> files;
- QString overrides;
+ QString manifestType;
+ int manifestVersion = 0;
+ Flame::Minecraft minecraft;
+ QString name;
+ QString version;
+ QString author;
+ QVector<Flame::File> files;
+ QString overrides;
};
void loadManifest(Flame::Manifest & m, const QString &filepath);
diff --git a/api/logic/modplatform/ftb/FtbPackFetchTask.cpp b/api/logic/modplatform/ftb/FtbPackFetchTask.cpp
index 5588a7fd..67248f2c 100644
--- a/api/logic/modplatform/ftb/FtbPackFetchTask.cpp
+++ b/api/logic/modplatform/ftb/FtbPackFetchTask.cpp
@@ -11,107 +11,107 @@ FtbPackFetchTask::~FtbPackFetchTask()
void FtbPackFetchTask::fetch()
{
- NetJob *netJob = new NetJob("FtbModpackFetch");
+ NetJob *netJob = new NetJob("FtbModpackFetch");
- QUrl publicPacksUrl = QUrl("https://ftb.cursecdn.com/FTB2/static/modpacks.xml");
- qDebug() << "Downloading public version info from" << publicPacksUrl.toString();
- netJob->addNetAction(Net::Download::makeByteArray(publicPacksUrl, &publicModpacksXmlFileData));
+ QUrl publicPacksUrl = QUrl("https://ftb.cursecdn.com/FTB2/static/modpacks.xml");
+ qDebug() << "Downloading public version info from" << publicPacksUrl.toString();
+ netJob->addNetAction(Net::Download::makeByteArray(publicPacksUrl, &publicModpacksXmlFileData));
- QUrl thirdPartyUrl = QUrl("https://ftb.cursecdn.com/FTB2/static/thirdparty.xml");
- qDebug() << "Downloading thirdparty version info from" << thirdPartyUrl.toString();
- netJob->addNetAction(Net::Download::makeByteArray(thirdPartyUrl, &thirdPartyModpacksXmlFileData));
+ QUrl thirdPartyUrl = QUrl("https://ftb.cursecdn.com/FTB2/static/thirdparty.xml");
+ qDebug() << "Downloading thirdparty version info from" << thirdPartyUrl.toString();
+ netJob->addNetAction(Net::Download::makeByteArray(thirdPartyUrl, &thirdPartyModpacksXmlFileData));
- QObject::connect(netJob, &NetJob::succeeded, this, &FtbPackFetchTask::fileDownloadFinished);
- QObject::connect(netJob, &NetJob::failed, this, &FtbPackFetchTask::fileDownloadFailed);
+ QObject::connect(netJob, &NetJob::succeeded, this, &FtbPackFetchTask::fileDownloadFinished);
+ QObject::connect(netJob, &NetJob::failed, this, &FtbPackFetchTask::fileDownloadFailed);
- jobPtr.reset(netJob);
- netJob->start();
+ jobPtr.reset(netJob);
+ netJob->start();
}
void FtbPackFetchTask::fileDownloadFinished()
{
- jobPtr.reset();
+ jobPtr.reset();
- QStringList failedLists;
+ QStringList failedLists;
- if(!parseAndAddPacks(publicModpacksXmlFileData, FtbPackType::Public, publicPacks)) {
- failedLists.append(tr("Public Packs"));
- }
+ if(!parseAndAddPacks(publicModpacksXmlFileData, FtbPackType::Public, publicPacks)) {
+ failedLists.append(tr("Public Packs"));
+ }
- if(!parseAndAddPacks(thirdPartyModpacksXmlFileData, FtbPackType::ThirdParty, thirdPartyPacks)) {
- failedLists.append(tr("Third Party Packs"));
- }
+ if(!parseAndAddPacks(thirdPartyModpacksXmlFileData, FtbPackType::ThirdParty, thirdPartyPacks)) {
+ failedLists.append(tr("Third Party Packs"));
+ }
- if(failedLists.size() > 0) {
- emit failed(QString("Failed to download some pack lists:%1").arg(failedLists.join("\n- ")));
- } else {
- emit finished(publicPacks, thirdPartyPacks);
- }
+ if(failedLists.size() > 0) {
+ emit failed(QString("Failed to download some pack lists:%1").arg(failedLists.join("\n- ")));
+ } else {
+ emit finished(publicPacks, thirdPartyPacks);
+ }
}
bool FtbPackFetchTask::parseAndAddPacks(QByteArray &data, FtbPackType packType, FtbModpackList &list)
{
- QDomDocument doc;
-
- QString errorMsg = "Unknown error.";
- int errorLine = -1;
- int errorCol = -1;
-
- if(!doc.setContent(data, false, &errorMsg, &errorLine, &errorCol)){
- auto fullErrMsg = QString("Failed to fetch modpack data: %s %d:%d!").arg(errorMsg, errorLine, errorCol);
- qWarning() << fullErrMsg;
- data.clear();
- return false;
- }
-
- QDomNodeList nodes = doc.elementsByTagName("modpack");
- for(int i = 0; i < nodes.length(); i++) {
- QDomElement element = nodes.at(i).toElement();
-
- FtbModpack modpack;
- modpack.name = element.attribute("name");
- modpack.currentVersion = element.attribute("version");
- modpack.mcVersion = element.attribute("mcVersion");
- modpack.description = element.attribute("description");
- modpack.mods = element.attribute("mods");
- modpack.logo = element.attribute("logo");
- modpack.oldVersions = element.attribute("oldVersions").split(";");
- modpack.broken = false;
- modpack.bugged = false;
-
- //remove empty if the xml is bugged
- for(QString curr : modpack.oldVersions) {
- if(curr.isNull() || curr.isEmpty()) {
- modpack.oldVersions.removeAll(curr);
- modpack.bugged = true;
- qWarning() << "Removed some empty versions from" << modpack.name;
- }
- }
-
- if(modpack.oldVersions.size() < 1) {
- if(!modpack.currentVersion.isNull() && !modpack.currentVersion.isEmpty()) {
- modpack.oldVersions.append(modpack.currentVersion);
- qWarning() << "Added current version to oldVersions because oldVersions was empty! (" + modpack.name + ")";
- } else {
- modpack.broken = true;
- qWarning() << "Broken pack:" << modpack.name << " => No valid version!";
- }
- }
-
- modpack.author = element.attribute("author");
-
- modpack.dir = element.attribute("dir");
- modpack.file = element.attribute("url");
-
- modpack.type = packType;
-
- list.append(modpack);
- }
-
- return true;
+ QDomDocument doc;
+
+ QString errorMsg = "Unknown error.";
+ int errorLine = -1;
+ int errorCol = -1;
+
+ if(!doc.setContent(data, false, &errorMsg, &errorLine, &errorCol)){
+ auto fullErrMsg = QString("Failed to fetch modpack data: %s %d:%d!").arg(errorMsg, errorLine, errorCol);
+ qWarning() << fullErrMsg;
+ data.clear();
+ return false;
+ }
+
+ QDomNodeList nodes = doc.elementsByTagName("modpack");
+ for(int i = 0; i < nodes.length(); i++) {
+ QDomElement element = nodes.at(i).toElement();
+
+ FtbModpack modpack;
+ modpack.name = element.attribute("name");
+ modpack.currentVersion = element.attribute("version");
+ modpack.mcVersion = element.attribute("mcVersion");
+ modpack.description = element.attribute("description");
+ modpack.mods = element.attribute("mods");
+ modpack.logo = element.attribute("logo");
+ modpack.oldVersions = element.attribute("oldVersions").split(";");
+ modpack.broken = false;
+ modpack.bugged = false;
+
+ //remove empty if the xml is bugged
+ for(QString curr : modpack.oldVersions) {
+ if(curr.isNull() || curr.isEmpty()) {
+ modpack.oldVersions.removeAll(curr);
+ modpack.bugged = true;
+ qWarning() << "Removed some empty versions from" << modpack.name;
+ }
+ }
+
+ if(modpack.oldVersions.size() < 1) {
+ if(!modpack.currentVersion.isNull() && !modpack.currentVersion.isEmpty()) {
+ modpack.oldVersions.append(modpack.currentVersion);
+ qWarning() << "Added current version to oldVersions because oldVersions was empty! (" + modpack.name + ")";
+ } else {
+ modpack.broken = true;
+ qWarning() << "Broken pack:" << modpack.name << " => No valid version!";
+ }
+ }
+
+ modpack.author = element.attribute("author");
+
+ modpack.dir = element.attribute("dir");
+ modpack.file = element.attribute("url");
+
+ modpack.type = packType;
+
+ list.append(modpack);
+ }
+
+ return true;
}
void FtbPackFetchTask::fileDownloadFailed(QString reason){
- qWarning() << "Fetching FtbPacks failed: " << reason;
- emit failed(reason);
+ qWarning() << "Fetching FtbPacks failed: " << reason;
+ emit failed(reason);
}
diff --git a/api/logic/modplatform/ftb/FtbPackFetchTask.h b/api/logic/modplatform/ftb/FtbPackFetchTask.h
index b5635b12..c919a6e1 100644
--- a/api/logic/modplatform/ftb/FtbPackFetchTask.h
+++ b/api/logic/modplatform/ftb/FtbPackFetchTask.h
@@ -8,30 +8,30 @@
class MULTIMC_LOGIC_EXPORT FtbPackFetchTask : public QObject {
- Q_OBJECT
+ Q_OBJECT
public:
- FtbPackFetchTask();
- virtual ~FtbPackFetchTask();
+ FtbPackFetchTask();
+ virtual ~FtbPackFetchTask();
- void fetch();
+ void fetch();
private:
- NetJobPtr jobPtr;
+ NetJobPtr jobPtr;
- QByteArray publicModpacksXmlFileData;
- QByteArray thirdPartyModpacksXmlFileData;
+ QByteArray publicModpacksXmlFileData;
+ QByteArray thirdPartyModpacksXmlFileData;
- bool parseAndAddPacks(QByteArray &data, FtbPackType packType, FtbModpackList &list);
- FtbModpackList publicPacks;
- FtbModpackList thirdPartyPacks;
+ bool parseAndAddPacks(QByteArray &data, FtbPackType packType, FtbModpackList &list);
+ FtbModpackList publicPacks;
+ FtbModpackList thirdPartyPacks;
protected slots:
- void fileDownloadFinished();
- void fileDownloadFailed(QString reason);
+ void fileDownloadFinished();
+ void fileDownloadFailed(QString reason);
signals:
- void finished(FtbModpackList publicPacks, FtbModpackList thirdPartyPacks);
- void failed(QString reason);
+ void finished(FtbModpackList publicPacks, FtbModpackList thirdPartyPacks);
+ void failed(QString reason);
};
diff --git a/api/logic/modplatform/ftb/FtbPackInstallTask.cpp b/api/logic/modplatform/ftb/FtbPackInstallTask.cpp
index 7815ef46..cf0abea5 100644
--- a/api/logic/modplatform/ftb/FtbPackInstallTask.cpp
+++ b/api/logic/modplatform/ftb/FtbPackInstallTask.cpp
@@ -11,188 +11,188 @@
FtbPackInstallTask::FtbPackInstallTask(FtbModpack pack, QString version)
{
- m_pack = pack;
- m_version = version;
+ m_pack = pack;
+ m_version = version;
}
void FtbPackInstallTask::executeTask()
{
- downloadPack();
+ downloadPack();
}
void FtbPackInstallTask::downloadPack()
{
- setStatus(tr("Downloading zip for %1").arg(m_pack.name));
+ setStatus(tr("Downloading zip for %1").arg(m_pack.name));
- auto packoffset = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file);
- auto entry = ENV.metacache()->resolveEntry("FTBPacks", packoffset);
- NetJob *job = new NetJob("Download FTB Pack");
+ auto packoffset = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file);
+ auto entry = ENV.metacache()->resolveEntry("FTBPacks", packoffset);
+ NetJob *job = new NetJob("Download FTB Pack");
- entry->setStale(true);
- QString url = QString("http://ftb.cursecdn.com/FTB2/modpacks/%1").arg(packoffset);
- job->addNetAction(Net::Download::makeCached(url, entry));
- archivePath = entry->getFullPath();
+ entry->setStale(true);
+ QString url = QString("http://ftb.cursecdn.com/FTB2/modpacks/%1").arg(packoffset);
+ job->addNetAction(Net::Download::makeCached(url, entry));
+ archivePath = entry->getFullPath();
- netJobContainer.reset(job);
- connect(job, &NetJob::succeeded, this, &FtbPackInstallTask::onDownloadSucceeded);
- connect(job, &NetJob::failed, this, &FtbPackInstallTask::onDownloadFailed);
- connect(job, &NetJob::progress, this, &FtbPackInstallTask::onDownloadProgress);
- job->start();
+ netJobContainer.reset(job);
+ connect(job, &NetJob::succeeded, this, &FtbPackInstallTask::onDownloadSucceeded);
+ connect(job, &NetJob::failed, this, &FtbPackInstallTask::onDownloadFailed);
+ connect(job, &NetJob::progress, this, &FtbPackInstallTask::onDownloadProgress);
+ job->start();
- progress(1, 4);
+ progress(1, 4);
}
void FtbPackInstallTask::onDownloadSucceeded()
{
- abortable = false;
- unzip();
+ abortable = false;
+ unzip();
}
void FtbPackInstallTask::onDownloadFailed(QString reason)
{
- emitFailed(reason);
+ emitFailed(reason);
}
void FtbPackInstallTask::onDownloadProgress(qint64 current, qint64 total)
{
- abortable = true;
- progress(current, total * 4);
- setStatus(tr("Downloading zip for %1 (%2%)").arg(m_pack.name).arg(current / 10));
+ abortable = true;
+ progress(current, total * 4);
+ setStatus(tr("Downloading zip for %1 (%2%)").arg(m_pack.name).arg(current / 10));
}
void FtbPackInstallTask::unzip()
{
- progress(2, 4);
- setStatus(tr("Extracting modpack"));
- QDir extractDir(m_stagingPath);
-
- m_packZip.reset(new QuaZip(archivePath));
- if(!m_packZip->open(QuaZip::mdUnzip))
- {
- emitFailed(tr("Failed to open modpack file %1!").arg(archivePath));
- return;
- }
-
- m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip");
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &FtbPackInstallTask::onUnzipFinished);
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &FtbPackInstallTask::onUnzipCanceled);
- m_extractFutureWatcher.setFuture(m_extractFuture);
+ progress(2, 4);
+ setStatus(tr("Extracting modpack"));
+ QDir extractDir(m_stagingPath);
+
+ m_packZip.reset(new QuaZip(archivePath));
+ if(!m_packZip->open(QuaZip::mdUnzip))
+ {
+ emitFailed(tr("Failed to open modpack file %1!").arg(archivePath));
+ return;
+ }
+
+ m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip");
+ connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &FtbPackInstallTask::onUnzipFinished);
+ connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &FtbPackInstallTask::onUnzipCanceled);
+ m_extractFutureWatcher.setFuture(m_extractFuture);
}
void FtbPackInstallTask::onUnzipFinished()
{
- install();
+ install();
}
void FtbPackInstallTask::onUnzipCanceled()
{
- emitAborted();
+ emitAborted();
}
void FtbPackInstallTask::install()
{
- progress(3, 4);
- setStatus(tr("Installing modpack"));
- QDir unzipMcDir(m_stagingPath + "/unzip/minecraft");
- if(unzipMcDir.exists())
- {
- //ok, found minecraft dir, move contents to instance dir
- if(!QDir().rename(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft"))
- {
- emitFailed(tr("Failed to move unzipped minecraft!"));
- return;
- }
- }
-
- QString instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
- auto instanceSettings = std::make_shared<INISettingsObject>(instanceConfigPath);
- instanceSettings->registerSetting("InstanceType", "Legacy");
- instanceSettings->set("InstanceType", "OneSix");
-
- MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
- auto components = instance.getComponentList();
- components->buildingFromScratch();
- components->setComponentVersion("net.minecraft", m_pack.mcVersion, true);
-
- bool fallback = true;
-
- //handle different versions
- QFile packJson(m_stagingPath + "/.minecraft/pack.json");
- QDir jarmodDir = QDir(m_stagingPath + "/unzip/instMods");
- if(packJson.exists())
- {
- packJson.open(QIODevice::ReadOnly | QIODevice::Text);
- QJsonDocument doc = QJsonDocument::fromJson(packJson.readAll());
- packJson.close();
-
- //we only care about the libs
- QJsonArray libs = doc.object().value("libraries").toArray();
-
- foreach (const QJsonValue &value, libs)
- {
- QString nameValue = value.toObject().value("name").toString();
- if(!nameValue.startsWith("net.minecraftforge"))
- {
- continue;
- }
-
- GradleSpecifier forgeVersion(nameValue);
-
- components->setComponentVersion("net.minecraftforge", forgeVersion.version().replace(m_pack.mcVersion, "").replace("-", ""));
- packJson.remove();
- fallback = false;
- break;
- }
-
- }
-
- if(jarmodDir.exists())
- {
- qDebug() << "Found jarmods, installing...";
-
- QStringList jarmods;
- for (auto info: jarmodDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files))
- {
- qDebug() << "Jarmod:" << info.fileName();
- jarmods.push_back(info.absoluteFilePath());
- }
-
- components->installJarMods(jarmods);
- fallback = false;
- }
-
- //just nuke unzip directory, it s not needed anymore
- FS::deletePath(m_stagingPath + "/unzip");
-
- if(fallback)
- {
- //TODO: Some fallback mechanism... or just keep failing!
- emitFailed(tr("No installation method found!"));
- return;
- }
-
- components->saveNow();
-
- progress(4, 4);
-
- instance.init();
- instance.setName(m_instName);
- if(m_instIcon == "default")
- {
- m_instIcon = "ftb_logo";
- }
- instance.setIconKey(m_instIcon);
- instance.setGroupInitial(m_instGroup);
- instanceSettings->resumeSave();
-
- emitSucceeded();
+ progress(3, 4);
+ setStatus(tr("Installing modpack"));
+ QDir unzipMcDir(m_stagingPath + "/unzip/minecraft");
+ if(unzipMcDir.exists())
+ {
+ //ok, found minecraft dir, move contents to instance dir
+ if(!QDir().rename(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft"))
+ {
+ emitFailed(tr("Failed to move unzipped minecraft!"));
+ return;
+ }
+ }
+
+ QString instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
+ auto instanceSettings = std::make_shared<INISettingsObject>(instanceConfigPath);
+ instanceSettings->registerSetting("InstanceType", "Legacy");
+ instanceSettings->set("InstanceType", "OneSix");
+
+ MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
+ auto components = instance.getComponentList();
+ components->buildingFromScratch();
+ components->setComponentVersion("net.minecraft", m_pack.mcVersion, true);
+
+ bool fallback = true;
+
+ //handle different versions
+ QFile packJson(m_stagingPath + "/.minecraft/pack.json");
+ QDir jarmodDir = QDir(m_stagingPath + "/unzip/instMods");
+ if(packJson.exists())
+ {
+ packJson.open(QIODevice::ReadOnly | QIODevice::Text);
+ QJsonDocument doc = QJsonDocument::fromJson(packJson.readAll());
+ packJson.close();
+
+ //we only care about the libs
+ QJsonArray libs = doc.object().value("libraries").toArray();
+
+ foreach (const QJsonValue &value, libs)
+ {
+ QString nameValue = value.toObject().value("name").toString();
+ if(!nameValue.startsWith("net.minecraftforge"))
+ {
+ continue;
+ }
+
+ GradleSpecifier forgeVersion(nameValue);
+
+ components->setComponentVersion("net.minecraftforge", forgeVersion.version().replace(m_pack.mcVersion, "").replace("-", ""));
+ packJson.remove();
+ fallback = false;
+ break;
+ }
+
+ }
+
+ if(jarmodDir.exists())
+ {
+ qDebug() << "Found jarmods, installing...";
+
+ QStringList jarmods;
+ for (auto info: jarmodDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files))
+ {
+ qDebug() << "Jarmod:" << info.fileName();
+ jarmods.push_back(info.absoluteFilePath());
+ }
+
+ components->installJarMods(jarmods);
+ fallback = false;
+ }
+
+ //just nuke unzip directory, it s not needed anymore
+ FS::deletePath(m_stagingPath + "/unzip");
+
+ if(fallback)
+ {
+ //TODO: Some fallback mechanism... or just keep failing!
+ emitFailed(tr("No installation method found!"));
+ return;
+ }
+
+ components->saveNow();
+
+ progress(4, 4);
+
+ instance.init();
+ instance.setName(m_instName);
+ if(m_instIcon == "default")
+ {
+ m_instIcon = "ftb_logo";
+ }
+ instance.setIconKey(m_instIcon);
+ instance.setGroupInitial(m_instGroup);
+ instanceSettings->resumeSave();
+
+ emitSucceeded();
}
bool FtbPackInstallTask::abort()
{
- if(abortable)
- {
- return netJobContainer->abort();
- }
- return false;
+ if(abortable)
+ {
+ return netJobContainer->abort();
+ }
+ return false;
}
diff --git a/api/logic/modplatform/ftb/FtbPackInstallTask.h b/api/logic/modplatform/ftb/FtbPackInstallTask.h
index 0bfba3d6..8705ef89 100644
--- a/api/logic/modplatform/ftb/FtbPackInstallTask.h
+++ b/api/logic/modplatform/ftb/FtbPackInstallTask.h
@@ -11,39 +11,39 @@
class MULTIMC_LOGIC_EXPORT FtbPackInstallTask : public InstanceTask {
- Q_OBJECT
+ Q_OBJECT
public:
- explicit FtbPackInstallTask(FtbModpack pack, QString version);
- virtual ~FtbPackInstallTask(){}
+ explicit FtbPackInstallTask(FtbModpack pack, QString version);
+ virtual ~FtbPackInstallTask(){}
- bool abort() override;
+ bool abort() override;
protected:
- //! Entry point for tasks.
- virtual void executeTask() override;
+ //! Entry point for tasks.
+ virtual void executeTask() override;
private:
- void downloadPack();
- void unzip();
- void install();
+ void downloadPack();
+ void unzip();
+ void install();
private slots:
- void onDownloadSucceeded();
- void onDownloadFailed(QString reason);
- void onDownloadProgress(qint64 current, qint64 total);
+ void onDownloadSucceeded();
+ void onDownloadFailed(QString reason);
+ void onDownloadProgress(qint64 current, qint64 total);
- void onUnzipFinished();
- void onUnzipCanceled();
+ void onUnzipFinished();
+ void onUnzipCanceled();
private: /* data */
- bool abortable = false;
- std::unique_ptr<QuaZip> m_packZip;
- QFuture<QStringList> m_extractFuture;
- QFutureWatcher<QStringList> m_extractFutureWatcher;
- NetJobPtr netJobContainer;
- QString archivePath;
-
- FtbModpack m_pack;
- QString m_version;
+ bool abortable = false;
+ std::unique_ptr<QuaZip> m_packZip;
+ QFuture<QStringList> m_extractFuture;
+ QFutureWatcher<QStringList> m_extractFutureWatcher;
+ NetJobPtr netJobContainer;
+ QString archivePath;
+
+ FtbModpack m_pack;
+ QString m_version;
};
diff --git a/api/logic/modplatform/ftb/PackHelpers.h b/api/logic/modplatform/ftb/PackHelpers.h
index 39b65927..0b36f10b 100644
--- a/api/logic/modplatform/ftb/PackHelpers.h
+++ b/api/logic/modplatform/ftb/PackHelpers.h
@@ -7,29 +7,29 @@
//Header for structs etc...
enum FtbPackType {
- Public,
- ThirdParty,
- Private
+ Public,
+ ThirdParty,
+ Private
};
struct FtbModpack {
- QString name;
- QString description;
- QString author;
- QStringList oldVersions;
- QString currentVersion;
- QString mcVersion;
- QString mods;
- QString logo;
-
- //Technical data
- QString dir;
- QString file; //<- Url in the xml, but doesn't make much sense
-
- bool bugged = false;
- bool broken = false;
-
- FtbPackType type;
+ QString name;
+ QString description;
+ QString author;
+ QStringList oldVersions;
+ QString currentVersion;
+ QString mcVersion;
+ QString mods;
+ QString logo;
+
+ //Technical data
+ QString dir;
+ QString file; //<- Url in the xml, but doesn't make much sense
+
+ bool bugged = false;
+ bool broken = false;
+
+ FtbPackType type;
};
//We need it for the proxy model
diff --git a/api/logic/net/ByteArraySink.h b/api/logic/net/ByteArraySink.h
index 03b77fcc..20e6764c 100644
--- a/api/logic/net/ByteArraySink.h
+++ b/api/logic/net/ByteArraySink.h
@@ -9,54 +9,54 @@ namespace Net {
class ByteArraySink : public Sink
{
public:
- ByteArraySink(QByteArray *output)
- :m_output(output)
- {
- // nil
- };
+ ByteArraySink(QByteArray *output)
+ :m_output(output)
+ {
+ // nil
+ };
- virtual ~ByteArraySink()
- {
- // nil
- }
+ virtual ~ByteArraySink()
+ {
+ // nil
+ }
public:
- JobStatus init(QNetworkRequest & request) override
- {
- m_output->clear();
- if(initAllValidators(request))
- return Job_InProgress;
- return Job_Failed;
- };
-
- JobStatus write(QByteArray & data) override
- {
- m_output->append(data);
- if(writeAllValidators(data))
- return Job_InProgress;
- return Job_Failed;
- }
-
- JobStatus abort() override
- {
- m_output->clear();
- failAllValidators();
- return Job_Failed;
- }
-
- JobStatus finalize(QNetworkReply &reply) override
- {
- if(finalizeAllValidators(reply))
- return Job_Finished;
- return Job_Failed;
- }
-
- bool hasLocalData() override
- {
- return false;
- }
+ JobStatus init(QNetworkRequest & request) override
+ {
+ m_output->clear();
+ if(initAllValidators(request))
+ return Job_InProgress;
+ return Job_Failed;
+ };
+
+ JobStatus write(QByteArray & data) override
+ {
+ m_output->append(data);
+ if(writeAllValidators(data))
+ return Job_InProgress;
+ return Job_Failed;
+ }
+
+ JobStatus abort() override
+ {
+ m_output->clear();
+ failAllValidators();
+ return Job_Failed;
+ }
+
+ JobStatus finalize(QNetworkReply &reply) override
+ {
+ if(finalizeAllValidators(reply))
+ return Job_Finished;
+ return Job_Failed;
+ }
+
+ bool hasLocalData() override
+ {
+ return false;
+ }
private:
- QByteArray * m_output;
+ QByteArray * m_output;
};
}
diff --git a/api/logic/net/ChecksumValidator.h b/api/logic/net/ChecksumValidator.h
index 187e4b30..0d6b19c2 100644
--- a/api/logic/net/ChecksumValidator.h
+++ b/api/logic/net/ChecksumValidator.h
@@ -9,47 +9,47 @@ namespace Net {
class ChecksumValidator: public Validator
{
public: /* con/des */
- ChecksumValidator(QCryptographicHash::Algorithm algorithm, QByteArray expected = QByteArray())
- :m_checksum(algorithm), m_expected(expected)
- {
- };
- virtual ~ChecksumValidator() {};
+ ChecksumValidator(QCryptographicHash::Algorithm algorithm, QByteArray expected = QByteArray())
+ :m_checksum(algorithm), m_expected(expected)
+ {
+ };
+ virtual ~ChecksumValidator() {};
public: /* methods */
- bool init(QNetworkRequest &) override
- {
- m_checksum.reset();
- return true;
- }
- bool write(QByteArray & data) override
- {
- m_checksum.addData(data);
- return true;
- }
- bool abort() override
- {
- return true;
- }
- bool validate(QNetworkReply &) override
- {
- if(m_expected.size() && m_expected != hash())
- {
- qWarning() << "Checksum mismatch, download is bad.";
- return false;
- }
- return true;
- }
- QByteArray hash()
- {
- return m_checksum.result();
- }
- void setExpected(QByteArray expected)
- {
- m_expected = expected;
- }
+ bool init(QNetworkRequest &) override
+ {
+ m_checksum.reset();
+ return true;
+ }
+ bool write(QByteArray & data) override
+ {
+ m_checksum.addData(data);
+ return true;
+ }
+ bool abort() override
+ {
+ return true;
+ }
+ bool validate(QNetworkReply &) override
+ {
+ if(m_expected.size() && m_expected != hash())
+ {
+ qWarning() << "Checksum mismatch, download is bad.";
+ return false;
+ }
+ return true;
+ }
+ QByteArray hash()
+ {
+ return m_checksum.result();
+ }
+ void setExpected(QByteArray expected)
+ {
+ m_expected = expected;
+ }
private: /* data */
- QCryptographicHash m_checksum;
- QByteArray m_expected;
+ QCryptographicHash m_checksum;
+ QByteArray m_expected;
};
} \ No newline at end of file
diff --git a/api/logic/net/Download.cpp b/api/logic/net/Download.cpp
index 631d3076..fc634e3d 100644
--- a/api/logic/net/Download.cpp
+++ b/api/logic/net/Download.cpp
@@ -28,271 +28,271 @@ namespace Net {
Download::Download():NetAction()
{
- m_status = Job_NotStarted;
+ m_status = Job_NotStarted;
}
Download::Ptr Download::makeCached(QUrl url, MetaEntryPtr entry, Options options)
{
- Download * dl = new Download();
- dl->m_url = url;
- dl->m_options = options;
- auto md5Node = new ChecksumValidator(QCryptographicHash::Md5);
- auto cachedNode = new MetaCacheSink(entry, md5Node);
- dl->m_sink.reset(cachedNode);
- dl->m_target_path = entry->getFullPath();
- return std::shared_ptr<Download>(dl);
+ Download * dl = new Download();
+ dl->m_url = url;
+ dl->m_options = options;
+ auto md5Node = new ChecksumValidator(QCryptographicHash::Md5);
+ auto cachedNode = new MetaCacheSink(entry, md5Node);
+ dl->m_sink.reset(cachedNode);
+ dl->m_target_path = entry->getFullPath();
+ return std::shared_ptr<Download>(dl);
}
Download::Ptr Download::makeByteArray(QUrl url, QByteArray *output, Options options)
{
- Download * dl = new Download();
- dl->m_url = url;
- dl->m_options = options;
- dl->m_sink.reset(new ByteArraySink(output));
- return std::shared_ptr<Download>(dl);
+ Download * dl = new Download();
+ dl->m_url = url;
+ dl->m_options = options;
+ dl->m_sink.reset(new ByteArraySink(output));
+ return std::shared_ptr<Download>(dl);
}
Download::Ptr Download::makeFile(QUrl url, QString path, Options options)
{
- Download * dl = new Download();
- dl->m_url = url;
- dl->m_options = options;
- dl->m_sink.reset(new FileSink(path));
- return std::shared_ptr<Download>(dl);
+ Download * dl = new Download();
+ dl->m_url = url;
+ dl->m_options = options;
+ dl->m_sink.reset(new FileSink(path));
+ return std::shared_ptr<Download>(dl);
}
void Download::addValidator(Validator * v)
{
- m_sink->addValidator(v);
+ m_sink->addValidator(v);
}
void Download::start()
{
- if(m_status == Job_Aborted)
- {
- qWarning() << "Attempt to start an aborted Download:" << m_url.toString();
- emit aborted(m_index_within_job);
- return;
- }
- QNetworkRequest request(m_url);
- m_status = m_sink->init(request);
- switch(m_status)
- {
- case Job_Finished:
- emit succeeded(m_index_within_job);
- qDebug() << "Download cache hit " << m_url.toString();
- return;
- case Job_InProgress:
- qDebug() << "Downloading " << m_url.toString();
- break;
- case Job_Failed_Proceed: // this is meaningless in this context. We do need a sink.
- case Job_NotStarted:
- case Job_Failed:
- emit failed(m_index_within_job);
- return;
- case Job_Aborted:
- return;
- }
+ if(m_status == Job_Aborted)
+ {
+ qWarning() << "Attempt to start an aborted Download:" << m_url.toString();
+ emit aborted(m_index_within_job);
+ return;
+ }
+ QNetworkRequest request(m_url);
+ m_status = m_sink->init(request);
+ switch(m_status)
+ {
+ case Job_Finished:
+ emit succeeded(m_index_within_job);
+ qDebug() << "Download cache hit " << m_url.toString();
+ return;
+ case Job_InProgress:
+ qDebug() << "Downloading " << m_url.toString();
+ break;
+ case Job_Failed_Proceed: // this is meaningless in this context. We do need a sink.
+ case Job_NotStarted:
+ case Job_Failed:
+ emit failed(m_index_within_job);
+ return;
+ case Job_Aborted:
+ return;
+ }
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0");
+ request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0");
- QNetworkReply *rep = ENV.qnam().get(request);
+ QNetworkReply *rep = ENV.qnam().get(request);
- m_reply.reset(rep);
- connect(rep, SIGNAL(downloadProgress(qint64, qint64)), SLOT(downloadProgress(qint64, qint64)));
- connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, &QNetworkReply::sslErrors, this, &Download::sslErrors);
- connect(rep, &QNetworkReply::readyRead, this, &Download::downloadReadyRead);
+ m_reply.reset(rep);
+ connect(rep, SIGNAL(downloadProgress(qint64, qint64)), SLOT(downloadProgress(qint64, qint64)));
+ connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
+ connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError)));
+ connect(rep, &QNetworkReply::sslErrors, this, &Download::sslErrors);
+ connect(rep, &QNetworkReply::readyRead, this, &Download::downloadReadyRead);
}
void Download::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
+ m_total_progress = bytesTotal;
+ m_progress = bytesReceived;
+ emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
}
void Download::downloadError(QNetworkReply::NetworkError error)
{
- if(error == QNetworkReply::OperationCanceledError)
- {
- qCritical() << "Aborted " << m_url.toString();
- m_status = Job_Aborted;
- }
- else
- {
- if(m_options & Option::AcceptLocalFiles)
- {
- if(m_sink->hasLocalData())
- {
- m_status = Job_Failed_Proceed;
- return;
- }
- }
- // error happened during download.
- qCritical() << "Failed " << m_url.toString() << " with reason " << error;
- m_status = Job_Failed;
- }
+ if(error == QNetworkReply::OperationCanceledError)
+ {
+ qCritical() << "Aborted " << m_url.toString();
+ m_status = Job_Aborted;
+ }
+ else
+ {
+ if(m_options & Option::AcceptLocalFiles)
+ {
+ if(m_sink->hasLocalData())
+ {
+ m_status = Job_Failed_Proceed;
+ return;
+ }
+ }
+ // error happened during download.
+ qCritical() << "Failed " << m_url.toString() << " with reason " << error;
+ m_status = Job_Failed;
+ }
}
void Download::sslErrors(const QList<QSslError> & errors)
{
- int i = 1;
- for (auto error : errors)
- {
- qCritical() << "Download" << m_url.toString() << "SSL Error #" << i << " : " << error.errorString();
- auto cert = error.certificate();
- qCritical() << "Certificate in question:\n" << cert.toText();
- i++;
- }
+ int i = 1;
+ for (auto error : errors)
+ {
+ qCritical() << "Download" << m_url.toString() << "SSL Error #" << i << " : " << error.errorString();
+ auto cert = error.certificate();
+ qCritical() << "Certificate in question:\n" << cert.toText();
+ i++;
+ }
}
bool Download::handleRedirect()
{
- QUrl redirect = m_reply->header(QNetworkRequest::LocationHeader).toUrl();
- if(!redirect.isValid())
- {
- if(!m_reply->hasRawHeader("Location"))
- {
- // no redirect -> it's fine to continue
- return false;
- }
- // there is a Location header, but it's not correct. we need to apply some workarounds...
- QByteArray redirectBA = m_reply->rawHeader("Location");
- if(redirectBA.size() == 0)
- {
- // empty, yet present redirect header? WTF?
- return false;
- }
- QString redirectStr = QString::fromUtf8(redirectBA);
+ QUrl redirect = m_reply->header(QNetworkRequest::LocationHeader).toUrl();
+ if(!redirect.isValid())
+ {
+ if(!m_reply->hasRawHeader("Location"))
+ {
+ // no redirect -> it's fine to continue
+ return false;
+ }
+ // there is a Location header, but it's not correct. we need to apply some workarounds...
+ QByteArray redirectBA = m_reply->rawHeader("Location");
+ if(redirectBA.size() == 0)
+ {
+ // empty, yet present redirect header? WTF?
+ return false;
+ }
+ QString redirectStr = QString::fromUtf8(redirectBA);
- /*
- * IF the URL begins with //, we need to insert the URL scheme.
- * See: https://bugreports.qt-project.org/browse/QTBUG-41061
- */
- if(redirectStr.startsWith("//"))
- {
- redirectStr = m_reply->url().scheme() + ":" + redirectStr;
- }
+ /*
+ * IF the URL begins with //, we need to insert the URL scheme.
+ * See: https://bugreports.qt-project.org/browse/QTBUG-41061
+ */
+ if(redirectStr.startsWith("//"))
+ {
+ redirectStr = m_reply->url().scheme() + ":" + redirectStr;
+ }
- /*
- * Next, make sure the URL is parsed in tolerant mode. Qt doesn't parse the location header in tolerant mode, which causes issues.
- * FIXME: report Qt bug for this
- */
- redirect = QUrl(redirectStr, QUrl::TolerantMode);
- if(!redirect.isValid())
- {
- qWarning() << "Failed to parse redirect URL:" << redirectStr;
- downloadError(QNetworkReply::ProtocolFailure);
- return false;
- }
- qDebug() << "Fixed location header:" << redirect;
- }
- else
- {
- qDebug() << "Location header:" << redirect;
- }
+ /*
+ * Next, make sure the URL is parsed in tolerant mode. Qt doesn't parse the location header in tolerant mode, which causes issues.
+ * FIXME: report Qt bug for this
+ */
+ redirect = QUrl(redirectStr, QUrl::TolerantMode);
+ if(!redirect.isValid())
+ {
+ qWarning() << "Failed to parse redirect URL:" << redirectStr;
+ downloadError(QNetworkReply::ProtocolFailure);
+ return false;
+ }
+ qDebug() << "Fixed location header:" << redirect;
+ }
+ else
+ {
+ qDebug() << "Location header:" << redirect;
+ }
- m_url = QUrl(redirect.toString());
- qDebug() << "Following redirect to " << m_url.toString();
- start();
- return true;
+ m_url = QUrl(redirect.toString());
+ qDebug() << "Following redirect to " << m_url.toString();
+ start();
+ return true;
}
void Download::downloadFinished()
{
- // handle HTTP redirection first
- if(handleRedirect())
- {
- qDebug() << "Download redirected:" << m_url.toString();
- return;
- }
+ // handle HTTP redirection first
+ if(handleRedirect())
+ {
+ qDebug() << "Download redirected:" << m_url.toString();
+ return;
+ }
- // if the download failed before this point ...
- if (m_status == Job_Failed_Proceed)
- {
- qDebug() << "Download failed but we are allowed to proceed:" << m_url.toString();
- m_sink->abort();
- m_reply.reset();
- emit succeeded(m_index_within_job);
- return;
- }
- else if (m_status == Job_Failed)
- {
- qDebug() << "Download failed in previous step:" << m_url.toString();
- m_sink->abort();
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
- else if(m_status == Job_Aborted)
- {
- qDebug() << "Download aborted in previous step:" << m_url.toString();
- m_sink->abort();
- m_reply.reset();
- emit aborted(m_index_within_job);
- return;
- }
+ // if the download failed before this point ...
+ if (m_status == Job_Failed_Proceed)
+ {
+ qDebug() << "Download failed but we are allowed to proceed:" << m_url.toString();
+ m_sink->abort();
+ m_reply.reset();
+ emit succeeded(m_index_within_job);
+ return;
+ }
+ else if (m_status == Job_Failed)
+ {
+ qDebug() << "Download failed in previous step:" << m_url.toString();
+ m_sink->abort();
+ m_reply.reset();
+ emit failed(m_index_within_job);
+ return;
+ }
+ else if(m_status == Job_Aborted)
+ {
+ qDebug() << "Download aborted in previous step:" << m_url.toString();
+ m_sink->abort();
+ m_reply.reset();
+ emit aborted(m_index_within_job);
+ return;
+ }
- // make sure we got all the remaining data, if any
- auto data = m_reply->readAll();
- if(data.size())
- {
- qDebug() << "Writing extra" << data.size() << "bytes to" << m_target_path;
- m_status = m_sink->write(data);
- }
+ // make sure we got all the remaining data, if any
+ auto data = m_reply->readAll();
+ if(data.size())
+ {
+ qDebug() << "Writing extra" << data.size() << "bytes to" << m_target_path;
+ m_status = m_sink->write(data);
+ }
- // otherwise, finalize the whole graph
- m_status = m_sink->finalize(*m_reply.get());
- if (m_status != Job_Finished)
- {
- qDebug() << "Download failed to finalize:" << m_url.toString();
- m_sink->abort();
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
- m_reply.reset();
- qDebug() << "Download succeeded:" << m_url.toString();
- emit succeeded(m_index_within_job);
+ // otherwise, finalize the whole graph
+ m_status = m_sink->finalize(*m_reply.get());
+ if (m_status != Job_Finished)
+ {
+ qDebug() << "Download failed to finalize:" << m_url.toString();
+ m_sink->abort();
+ m_reply.reset();
+ emit failed(m_index_within_job);
+ return;
+ }
+ m_reply.reset();
+ qDebug() << "Download succeeded:" << m_url.toString();
+ emit succeeded(m_index_within_job);
}
void Download::downloadReadyRead()
{
- if(m_status == Job_InProgress)
- {
- auto data = m_reply->readAll();
- m_status = m_sink->write(data);
- if(m_status == Job_Failed)
- {
- qCritical() << "Failed to process response chunk for " << m_target_path;
- }
- // qDebug() << "Download" << m_url.toString() << "gained" << data.size() << "bytes";
- }
- else
- {
- qCritical() << "Cannot write to " << m_target_path << ", illegal status" << m_status;
- }
+ if(m_status == Job_InProgress)
+ {
+ auto data = m_reply->readAll();
+ m_status = m_sink->write(data);
+ if(m_status == Job_Failed)
+ {
+ qCritical() << "Failed to process response chunk for " << m_target_path;
+ }
+ // qDebug() << "Download" << m_url.toString() << "gained" << data.size() << "bytes";
+ }
+ else
+ {
+ qCritical() << "Cannot write to " << m_target_path << ", illegal status" << m_status;
+ }
}
}
bool Net::Download::abort()
{
- if(m_reply)
- {
- m_reply->abort();
- }
- else
- {
- m_status = Job_Aborted;
- }
- return true;
+ if(m_reply)
+ {
+ m_reply->abort();
+ }
+ else
+ {
+ m_status = Job_Aborted;
+ }
+ return true;
}
bool Net::Download::canAbort()
{
- return true;
+ return true;
}
diff --git a/api/logic/net/Download.h b/api/logic/net/Download.h
index 00bf108c..9d9d7743 100644
--- a/api/logic/net/Download.h
+++ b/api/logic/net/Download.h
@@ -24,52 +24,52 @@
namespace Net {
class MULTIMC_LOGIC_EXPORT Download : public NetAction
{
- Q_OBJECT
+ Q_OBJECT
public: /* types */
- typedef std::shared_ptr<class Download> Ptr;
- enum class Option
- {
- NoOptions = 0,
- AcceptLocalFiles = 1
- };
- Q_DECLARE_FLAGS(Options, Option)
+ typedef std::shared_ptr<class Download> Ptr;
+ enum class Option
+ {
+ NoOptions = 0,
+ AcceptLocalFiles = 1
+ };
+ Q_DECLARE_FLAGS(Options, Option)
protected: /* con/des */
- explicit Download();
+ explicit Download();
public:
- virtual ~Download(){};
- static Download::Ptr makeCached(QUrl url, MetaEntryPtr entry, Options options = Option::NoOptions);
- static Download::Ptr makeByteArray(QUrl url, QByteArray *output, Options options = Option::NoOptions);
- static Download::Ptr makeFile(QUrl url, QString path, Options options = Option::NoOptions);
+ virtual ~Download(){};
+ static Download::Ptr makeCached(QUrl url, MetaEntryPtr entry, Options options = Option::NoOptions);
+ static Download::Ptr makeByteArray(QUrl url, QByteArray *output, Options options = Option::NoOptions);
+ static Download::Ptr makeFile(QUrl url, QString path, Options options = Option::NoOptions);
public: /* methods */
- QString getTargetFilepath()
- {
- return m_target_path;
- }
- void addValidator(Validator * v);
- bool abort() override;
- bool canAbort() override;
+ QString getTargetFilepath()
+ {
+ return m_target_path;
+ }
+ void addValidator(Validator * v);
+ bool abort() override;
+ bool canAbort() override;
private: /* methods */
- bool handleRedirect();
+ bool handleRedirect();
protected slots:
- void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override;
- void downloadError(QNetworkReply::NetworkError error) override;
+ void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override;
+ void downloadError(QNetworkReply::NetworkError error) override;
void sslErrors(const QList<QSslError> & errors);
- void downloadFinished() override;
- void downloadReadyRead() override;
+ void downloadFinished() override;
+ void downloadReadyRead() override;
public slots:
- void start() override;
+ void start() override;
private: /* data */
- // FIXME: remove this, it has no business being here.
- QString m_target_path;
- std::unique_ptr<Sink> m_sink;
- Options m_options;
+ // FIXME: remove this, it has no business being here.
+ QString m_target_path;
+ std::unique_ptr<Sink> m_sink;
+ Options m_options;
};
}
diff --git a/api/logic/net/FileSink.cpp b/api/logic/net/FileSink.cpp
index e3ff0498..8b3e917d 100644
--- a/api/logic/net/FileSink.cpp
+++ b/api/logic/net/FileSink.cpp
@@ -7,109 +7,109 @@
namespace Net {
FileSink::FileSink(QString filename)
- :m_filename(filename)
+ :m_filename(filename)
{
- // nil
+ // nil
}
FileSink::~FileSink()
{
- // nil
+ // nil
}
JobStatus FileSink::init(QNetworkRequest& request)
{
- auto result = initCache(request);
- if(result != Job_InProgress)
- {
- return result;
- }
- // create a new save file and open it for writing
- if (!FS::ensureFilePathExists(m_filename))
- {
- qCritical() << "Could not create folder for " + m_filename;
- return Job_Failed;
- }
- wroteAnyData = false;
- m_output_file.reset(new QSaveFile(m_filename));
- if (!m_output_file->open(QIODevice::WriteOnly))
- {
- qCritical() << "Could not open " + m_filename + " for writing";
- return Job_Failed;
- }
+ auto result = initCache(request);
+ if(result != Job_InProgress)
+ {
+ return result;
+ }
+ // create a new save file and open it for writing
+ if (!FS::ensureFilePathExists(m_filename))
+ {
+ qCritical() << "Could not create folder for " + m_filename;
+ return Job_Failed;
+ }
+ wroteAnyData = false;
+ m_output_file.reset(new QSaveFile(m_filename));
+ if (!m_output_file->open(QIODevice::WriteOnly))
+ {
+ qCritical() << "Could not open " + m_filename + " for writing";
+ return Job_Failed;
+ }
- if(initAllValidators(request))
- return Job_InProgress;
- return Job_Failed;
+ if(initAllValidators(request))
+ return Job_InProgress;
+ return Job_Failed;
}
JobStatus FileSink::initCache(QNetworkRequest &)
{
- return Job_InProgress;
+ return Job_InProgress;
}
JobStatus FileSink::write(QByteArray& data)
{
- if (!writeAllValidators(data) || m_output_file->write(data) != data.size())
- {
- qCritical() << "Failed writing into " + m_filename;
- m_output_file->cancelWriting();
- m_output_file.reset();
- wroteAnyData = false;
- return Job_Failed;
- }
- wroteAnyData = true;
- return Job_InProgress;
+ if (!writeAllValidators(data) || m_output_file->write(data) != data.size())
+ {
+ qCritical() << "Failed writing into " + m_filename;
+ m_output_file->cancelWriting();
+ m_output_file.reset();
+ wroteAnyData = false;
+ return Job_Failed;
+ }
+ wroteAnyData = true;
+ return Job_InProgress;
}
JobStatus FileSink::abort()
{
- m_output_file->cancelWriting();
- failAllValidators();
- return Job_Failed;
+ m_output_file->cancelWriting();
+ failAllValidators();
+ return Job_Failed;
}
JobStatus FileSink::finalize(QNetworkReply& reply)
{
- bool gotFile = false;
- QVariant statusCodeV = reply.attribute(QNetworkRequest::HttpStatusCodeAttribute);
- bool validStatus = false;
- int statusCode = statusCodeV.toInt(&validStatus);
- if(validStatus)
- {
- // this leaves out 304 Not Modified
- gotFile = statusCode == 200 || statusCode == 203;
- }
- // if we wrote any data to the save file, we try to commit the data to the real file.
- // if it actually got a proper file, we write it even if it was empty
- if (gotFile || wroteAnyData)
- {
- // ask validators for data consistency
- // we only do this for actual downloads, not 'your data is still the same' cache hits
- if(!finalizeAllValidators(reply))
- return Job_Failed;
- // nothing went wrong...
- if (!m_output_file->commit())
- {
- qCritical() << "Failed to commit changes to " << m_filename;
- m_output_file->cancelWriting();
- return Job_Failed;
- }
- }
- // then get rid of the save file
- m_output_file.reset();
+ bool gotFile = false;
+ QVariant statusCodeV = reply.attribute(QNetworkRequest::HttpStatusCodeAttribute);
+ bool validStatus = false;
+ int statusCode = statusCodeV.toInt(&validStatus);
+ if(validStatus)
+ {
+ // this leaves out 304 Not Modified
+ gotFile = statusCode == 200 || statusCode == 203;
+ }
+ // if we wrote any data to the save file, we try to commit the data to the real file.
+ // if it actually got a proper file, we write it even if it was empty
+ if (gotFile || wroteAnyData)
+ {
+ // ask validators for data consistency
+ // we only do this for actual downloads, not 'your data is still the same' cache hits
+ if(!finalizeAllValidators(reply))
+ return Job_Failed;
+ // nothing went wrong...
+ if (!m_output_file->commit())
+ {
+ qCritical() << "Failed to commit changes to " << m_filename;
+ m_output_file->cancelWriting();
+ return Job_Failed;
+ }
+ }
+ // then get rid of the save file
+ m_output_file.reset();
- return finalizeCache(reply);
+ return finalizeCache(reply);
}
JobStatus FileSink::finalizeCache(QNetworkReply &)
{
- return Job_Finished;
+ return Job_Finished;
}
bool FileSink::hasLocalData()
{
- QFileInfo info(m_filename);
- return info.exists() && info.size() != 0;
+ QFileInfo info(m_filename);
+ return info.exists() && info.size() != 0;
}
}
diff --git a/api/logic/net/FileSink.h b/api/logic/net/FileSink.h
index 035d5bfd..875fe511 100644
--- a/api/logic/net/FileSink.h
+++ b/api/logic/net/FileSink.h
@@ -6,23 +6,23 @@ namespace Net {
class FileSink : public Sink
{
public: /* con/des */
- FileSink(QString filename);
- virtual ~FileSink();
+ FileSink(QString filename);
+ virtual ~FileSink();
public: /* methods */
- JobStatus init(QNetworkRequest & request) override;
- JobStatus write(QByteArray & data) override;
- JobStatus abort() override;
- JobStatus finalize(QNetworkReply & reply) override;
- bool hasLocalData() override;
+ JobStatus init(QNetworkRequest & request) override;
+ JobStatus write(QByteArray & data) override;
+ JobStatus abort() override;
+ JobStatus finalize(QNetworkReply & reply) override;
+ bool hasLocalData() override;
protected: /* methods */
- virtual JobStatus initCache(QNetworkRequest &);
- virtual JobStatus finalizeCache(QNetworkReply &reply);
+ virtual JobStatus initCache(QNetworkRequest &);
+ virtual JobStatus finalizeCache(QNetworkReply &reply);
protected: /* data */
- QString m_filename;
- bool wroteAnyData = false;
- std::unique_ptr<QSaveFile> m_output_file;
+ QString m_filename;
+ bool wroteAnyData = false;
+ std::unique_ptr<QSaveFile> m_output_file;
};
}
diff --git a/api/logic/net/HttpMetaCache.cpp b/api/logic/net/HttpMetaCache.cpp
index 95906d2c..66325f71 100644
--- a/api/logic/net/HttpMetaCache.cpp
+++ b/api/logic/net/HttpMetaCache.cpp
@@ -30,244 +30,244 @@
QString MetaEntry::getFullPath()
{
- // FIXME: make local?
- return FS::PathCombine(basePath, relativePath);
+ // FIXME: make local?
+ return FS::PathCombine(basePath, relativePath);
}
HttpMetaCache::HttpMetaCache(QString path) : QObject()
{
- m_index_file = path;
- saveBatchingTimer.setSingleShot(true);
- saveBatchingTimer.setTimerType(Qt::VeryCoarseTimer);
- connect(&saveBatchingTimer, SIGNAL(timeout()), SLOT(SaveNow()));
+ m_index_file = path;
+ saveBatchingTimer.setSingleShot(true);
+ saveBatchingTimer.setTimerType(Qt::VeryCoarseTimer);
+ connect(&saveBatchingTimer, SIGNAL(timeout()), SLOT(SaveNow()));
}
HttpMetaCache::~HttpMetaCache()
{
- saveBatchingTimer.stop();
- SaveNow();
+ saveBatchingTimer.stop();
+ SaveNow();
}
MetaEntryPtr HttpMetaCache::getEntry(QString base, QString resource_path)
{
- // no base. no base path. can't store
- if (!m_entries.contains(base))
- {
- // TODO: log problem
- return MetaEntryPtr();
- }
- EntryMap &map = m_entries[base];
- if (map.entry_list.contains(resource_path))
- {
- return map.entry_list[resource_path];
- }
- return MetaEntryPtr();
+ // no base. no base path. can't store
+ if (!m_entries.contains(base))
+ {
+ // TODO: log problem
+ return MetaEntryPtr();
+ }
+ EntryMap &map = m_entries[base];
+ if (map.entry_list.contains(resource_path))
+ {
+ return map.entry_list[resource_path];
+ }
+ return MetaEntryPtr();
}
MetaEntryPtr HttpMetaCache::resolveEntry(QString base, QString resource_path, QString expected_etag)
{
- auto entry = getEntry(base, resource_path);
- // it's not present? generate a default stale entry
- if (!entry)
- {
- return staleEntry(base, resource_path);
- }
+ auto entry = getEntry(base, resource_path);
+ // it's not present? generate a default stale entry
+ if (!entry)
+ {
+ return staleEntry(base, resource_path);
+ }
- auto &selected_base = m_entries[base];
- QString real_path = FS::PathCombine(selected_base.base_path, resource_path);
- QFileInfo finfo(real_path);
+ auto &selected_base = m_entries[base];
+ QString real_path = FS::PathCombine(selected_base.base_path, resource_path);
+ QFileInfo finfo(real_path);
- // is the file really there? if not -> stale
- if (!finfo.isFile() || !finfo.isReadable())
- {
- // if the file doesn't exist, we disown the entry
- selected_base.entry_list.remove(resource_path);
- return staleEntry(base, resource_path);
- }
+ // is the file really there? if not -> stale
+ if (!finfo.isFile() || !finfo.isReadable())
+ {
+ // if the file doesn't exist, we disown the entry
+ selected_base.entry_list.remove(resource_path);
+ return staleEntry(base, resource_path);
+ }
- if (!expected_etag.isEmpty() && expected_etag != entry->etag)
- {
- // if the etag doesn't match expected, we disown the entry
- selected_base.entry_list.remove(resource_path);
- return staleEntry(base, resource_path);
- }
+ if (!expected_etag.isEmpty() && expected_etag != entry->etag)
+ {
+ // if the etag doesn't match expected, we disown the entry
+ selected_base.entry_list.remove(resource_path);
+ return staleEntry(base, resource_path);
+ }
- // if the file changed, check md5sum
- qint64 file_last_changed = finfo.lastModified().toUTC().toMSecsSinceEpoch();
- if (file_last_changed != entry->local_changed_timestamp)
- {
- QFile input(real_path);
- input.open(QIODevice::ReadOnly);
- QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5)
- .toHex()
- .constData();
- if (entry->md5sum != md5sum)
- {
- selected_base.entry_list.remove(resource_path);
- return staleEntry(base, resource_path);
- }
- // md5sums matched... keep entry and save the new state to file
- entry->local_changed_timestamp = file_last_changed;
- SaveEventually();
- }
+ // if the file changed, check md5sum
+ qint64 file_last_changed = finfo.lastModified().toUTC().toMSecsSinceEpoch();
+ if (file_last_changed != entry->local_changed_timestamp)
+ {
+ QFile input(real_path);
+ input.open(QIODevice::ReadOnly);
+ QString md5sum = QCryptographicHash::hash(input.readAll(), QCryptographicHash::Md5)
+ .toHex()
+ .constData();
+ if (entry->md5sum != md5sum)
+ {
+ selected_base.entry_list.remove(resource_path);
+ return staleEntry(base, resource_path);
+ }
+ // md5sums matched... keep entry and save the new state to file
+ entry->local_changed_timestamp = file_last_changed;
+ SaveEventually();
+ }
- // entry passed all the checks we cared about.
- entry->basePath = getBasePath(base);
- return entry;
+ // entry passed all the checks we cared about.
+ entry->basePath = getBasePath(base);
+ return entry;
}
bool HttpMetaCache::updateEntry(MetaEntryPtr stale_entry)
{
- if (!m_entries.contains(stale_entry->baseId))
- {
- qCritical() << "Cannot add entry with unknown base: "
- << stale_entry->baseId.toLocal8Bit();
- return false;
- }
- if (stale_entry->stale)
- {
- qCritical() << "Cannot add stale entry: " << stale_entry->getFullPath().toLocal8Bit();
- return false;
- }
- m_entries[stale_entry->baseId].entry_list[stale_entry->relativePath] = stale_entry;
- SaveEventually();
- return true;
+ if (!m_entries.contains(stale_entry->baseId))
+ {
+ qCritical() << "Cannot add entry with unknown base: "
+ << stale_entry->baseId.toLocal8Bit();
+ return false;
+ }
+ if (stale_entry->stale)
+ {
+ qCritical() << "Cannot add stale entry: " << stale_entry->getFullPath().toLocal8Bit();
+ return false;
+ }
+ m_entries[stale_entry->baseId].entry_list[stale_entry->relativePath] = stale_entry;
+ SaveEventually();
+ return true;
}
bool HttpMetaCache::evictEntry(MetaEntryPtr entry)
{
- if(entry)
- {
- entry->stale = true;
- SaveEventually();
- return true;
- }
- return false;
+ if(entry)
+ {
+ entry->stale = true;
+ SaveEventually();
+ return true;
+ }
+ return false;
}
MetaEntryPtr HttpMetaCache::staleEntry(QString base, QString resource_path)
{
- auto foo = new MetaEntry();
- foo->baseId = base;
- foo->basePath = getBasePath(base);
- foo->relativePath = resource_path;
- foo->stale = true;
- return MetaEntryPtr(foo);
+ auto foo = new MetaEntry();
+ foo->baseId = base;
+ foo->basePath = getBasePath(base);
+ foo->relativePath = resource_path;
+ foo->stale = true;
+ return MetaEntryPtr(foo);
}
void HttpMetaCache::addBase(QString base, QString base_root)
{
- // TODO: report error
- if (m_entries.contains(base))
- return;
- // TODO: check if the base path is valid
- EntryMap foo;
- foo.base_path = base_root;
- m_entries[base] = foo;
+ // TODO: report error
+ if (m_entries.contains(base))
+ return;
+ // TODO: check if the base path is valid
+ EntryMap foo;
+ foo.base_path = base_root;
+ m_entries[base] = foo;
}
QString HttpMetaCache::getBasePath(QString base)
{
- if (m_entries.contains(base))
- {
- return m_entries[base].base_path;
- }
- return QString();
+ if (m_entries.contains(base))
+ {
+ return m_entries[base].base_path;
+ }
+ return QString();
}
void HttpMetaCache::Load()
{
- if(m_index_file.isNull())
- return;
+ if(m_index_file.isNull())
+ return;
- QFile index(m_index_file);
- if (!index.open(QIODevice::ReadOnly))
- return;
+ QFile index(m_index_file);
+ if (!index.open(QIODevice::ReadOnly))
+ return;
- QJsonDocument json = QJsonDocument::fromJson(index.readAll());
- if (!json.isObject())
- return;
- auto root = json.object();
- // check file version first
- auto version_val = root.value("version");
- if (!version_val.isString())
- return;
- if (version_val.toString() != "1")
- return;
+ QJsonDocument json = QJsonDocument::fromJson(index.readAll());
+ if (!json.isObject())
+ return;
+ auto root = json.object();
+ // check file version first
+ auto version_val = root.value("version");
+ if (!version_val.isString())
+ return;
+ if (version_val.toString() != "1")
+ return;
- // read the entry array
- auto entries_val = root.value("entries");
- if (!entries_val.isArray())
- return;
- QJsonArray array = entries_val.toArray();
- for (auto element : array)
- {
- if (!element.isObject())
- return;
- auto element_obj = element.toObject();
- QString base = element_obj.value("base").toString();
- if (!m_entries.contains(base))
- continue;
- auto &entrymap = m_entries[base];
- auto foo = new MetaEntry();
- foo->baseId = base;
- QString path = foo->relativePath = element_obj.value("path").toString();
- foo->md5sum = element_obj.value("md5sum").toString();
- foo->etag = element_obj.value("etag").toString();
- foo->local_changed_timestamp = element_obj.value("last_changed_timestamp").toDouble();
- foo->remote_changed_timestamp =
- element_obj.value("remote_changed_timestamp").toString();
- // presumed innocent until closer examination
- foo->stale = false;
- entrymap.entry_list[path] = MetaEntryPtr(foo);
- }
+ // read the entry array
+ auto entries_val = root.value("entries");
+ if (!entries_val.isArray())
+ return;
+ QJsonArray array = entries_val.toArray();
+ for (auto element : array)
+ {
+ if (!element.isObject())
+ return;
+ auto element_obj = element.toObject();
+ QString base = element_obj.value("base").toString();
+ if (!m_entries.contains(base))
+ continue;
+ auto &entrymap = m_entries[base];
+ auto foo = new MetaEntry();
+ foo->baseId = base;
+ QString path = foo->relativePath = element_obj.value("path").toString();
+ foo->md5sum = element_obj.value("md5sum").toString();
+ foo->etag = element_obj.value("etag").toString();
+ foo->local_changed_timestamp = element_obj.value("last_changed_timestamp").toDouble();
+ foo->remote_changed_timestamp =
+ element_obj.value("remote_changed_timestamp").toString();
+ // presumed innocent until closer examination
+ foo->stale = false;
+ entrymap.entry_list[path] = MetaEntryPtr(foo);
+ }
}
void HttpMetaCache::SaveEventually()
{
- // reset the save timer
- saveBatchingTimer.stop();
- saveBatchingTimer.start(30000);
+ // reset the save timer
+ saveBatchingTimer.stop();
+ saveBatchingTimer.start(30000);
}
void HttpMetaCache::SaveNow()
{
- if(m_index_file.isNull())
- return;
- QJsonObject toplevel;
- toplevel.insert("version", QJsonValue(QString("1")));
- QJsonArray entriesArr;
- for (auto group : m_entries)
- {
- for (auto entry : group.entry_list)
- {
- // do not save stale entries. they are dead.
- if(entry->stale)
- {
- continue;
- }
- QJsonObject entryObj;
- entryObj.insert("base", QJsonValue(entry->baseId));
- entryObj.insert("path", QJsonValue(entry->relativePath));
- entryObj.insert("md5sum", QJsonValue(entry->md5sum));
- entryObj.insert("etag", QJsonValue(entry->etag));
- entryObj.insert("last_changed_timestamp",
- QJsonValue(double(entry->local_changed_timestamp)));
- if (!entry->remote_changed_timestamp.isEmpty())
- entryObj.insert("remote_changed_timestamp",
- QJsonValue(entry->remote_changed_timestamp));
- entriesArr.append(entryObj);
- }
- }
- toplevel.insert("entries", entriesArr);
+ if(m_index_file.isNull())
+ return;
+ QJsonObject toplevel;
+ toplevel.insert("version", QJsonValue(QString("1")));
+ QJsonArray entriesArr;
+ for (auto group : m_entries)
+ {
+ for (auto entry : group.entry_list)
+ {
+ // do not save stale entries. they are dead.
+ if(entry->stale)
+ {
+ continue;
+ }
+ QJsonObject entryObj;
+ entryObj.insert("base", QJsonValue(entry->baseId));
+ entryObj.insert("path", QJsonValue(entry->relativePath));
+ entryObj.insert("md5sum", QJsonValue(entry->md5sum));
+ entryObj.insert("etag", QJsonValue(entry->etag));
+ entryObj.insert("last_changed_timestamp",
+ QJsonValue(double(entry->local_changed_timestamp)));
+ if (!entry->remote_changed_timestamp.isEmpty())
+ entryObj.insert("remote_changed_timestamp",
+ QJsonValue(entry->remote_changed_timestamp));
+ entriesArr.append(entryObj);
+ }
+ }
+ toplevel.insert("entries", entriesArr);
- QJsonDocument doc(toplevel);
- try
- {
- FS::write(m_index_file, doc.toJson());
- }
- catch (const Exception &e)
- {
- qWarning() << e.what();
- }
+ QJsonDocument doc(toplevel);
+ try
+ {
+ FS::write(m_index_file, doc.toJson());
+ }
+ catch (const Exception &e)
+ {
+ qWarning() << e.what();
+ }
}
diff --git a/api/logic/net/HttpMetaCache.h b/api/logic/net/HttpMetaCache.h
index 7ee5f735..6e240723 100644
--- a/api/logic/net/HttpMetaCache.h
+++ b/api/logic/net/HttpMetaCache.h
@@ -27,99 +27,99 @@ class MULTIMC_LOGIC_EXPORT MetaEntry
{
friend class HttpMetaCache;
protected:
- MetaEntry() {}
+ MetaEntry() {}
public:
- bool isStale()
- {
- return stale;
- }
- void setStale(bool stale)
- {
- this->stale = stale;
- }
- QString getFullPath();
- QString getRemoteChangedTimestamp()
- {
- return remote_changed_timestamp;
- }
- void setRemoteChangedTimestamp(QString remote_changed_timestamp)
- {
- this->remote_changed_timestamp = remote_changed_timestamp;
- }
- void setLocalChangedTimestamp(qint64 timestamp)
- {
- local_changed_timestamp = timestamp;
- }
- QString getETag()
- {
- return etag;
- }
- void setETag(QString etag)
- {
- this->etag = etag;
- }
- QString getMD5Sum()
- {
- return md5sum;
- }
- void setMD5Sum(QString md5sum)
- {
- this->md5sum = md5sum;
- }
+ bool isStale()
+ {
+ return stale;
+ }
+ void setStale(bool stale)
+ {
+ this->stale = stale;
+ }
+ QString getFullPath();
+ QString getRemoteChangedTimestamp()
+ {
+ return remote_changed_timestamp;
+ }
+ void setRemoteChangedTimestamp(QString remote_changed_timestamp)
+ {
+ this->remote_changed_timestamp = remote_changed_timestamp;
+ }
+ void setLocalChangedTimestamp(qint64 timestamp)
+ {
+ local_changed_timestamp = timestamp;
+ }
+ QString getETag()
+ {
+ return etag;
+ }
+ void setETag(QString etag)
+ {
+ this->etag = etag;
+ }
+ QString getMD5Sum()
+ {
+ return md5sum;
+ }
+ void setMD5Sum(QString md5sum)
+ {
+ this->md5sum = md5sum;
+ }
protected:
- QString baseId;
- QString basePath;
- QString relativePath;
- QString md5sum;
- QString etag;
- qint64 local_changed_timestamp = 0;
- QString remote_changed_timestamp; // QString for now, RFC 2822 encoded time
- bool stale = true;
+ QString baseId;
+ QString basePath;
+ QString relativePath;
+ QString md5sum;
+ QString etag;
+ qint64 local_changed_timestamp = 0;
+ QString remote_changed_timestamp; // QString for now, RFC 2822 encoded time
+ bool stale = true;
};
typedef std::shared_ptr<MetaEntry> MetaEntryPtr;
class MULTIMC_LOGIC_EXPORT HttpMetaCache : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- // supply path to the cache index file
- HttpMetaCache(QString path = QString());
- ~HttpMetaCache();
+ // supply path to the cache index file
+ HttpMetaCache(QString path = QString());
+ ~HttpMetaCache();
- // get the entry solely from the cache
- // you probably don't want this, unless you have some specific caching needs.
- MetaEntryPtr getEntry(QString base, QString resource_path);
+ // get the entry solely from the cache
+ // you probably don't want this, unless you have some specific caching needs.
+ MetaEntryPtr getEntry(QString base, QString resource_path);
- // get the entry from cache and verify that it isn't stale (within reason)
- MetaEntryPtr resolveEntry(QString base, QString resource_path,
- QString expected_etag = QString());
+ // get the entry from cache and verify that it isn't stale (within reason)
+ MetaEntryPtr resolveEntry(QString base, QString resource_path,
+ QString expected_etag = QString());
- // add a previously resolved stale entry
- bool updateEntry(MetaEntryPtr stale_entry);
+ // add a previously resolved stale entry
+ bool updateEntry(MetaEntryPtr stale_entry);
- // evict selected entry from cache
- bool evictEntry(MetaEntryPtr entry);
+ // evict selected entry from cache
+ bool evictEntry(MetaEntryPtr entry);
- void addBase(QString base, QString base_root);
+ void addBase(QString base, QString base_root);
- // (re)start a timer that calls SaveNow later.
- void SaveEventually();
- void Load();
- QString getBasePath(QString base);
+ // (re)start a timer that calls SaveNow later.
+ void SaveEventually();
+ void Load();
+ QString getBasePath(QString base);
public
slots:
- void SaveNow();
+ void SaveNow();
private:
- // create a new stale entry, given the parameters
- MetaEntryPtr staleEntry(QString base, QString resource_path);
- struct EntryMap
- {
- QString base_path;
- QMap<QString, MetaEntryPtr> entry_list;
- };
- QMap<QString, EntryMap> m_entries;
- QString m_index_file;
- QTimer saveBatchingTimer;
+ // create a new stale entry, given the parameters
+ MetaEntryPtr staleEntry(QString base, QString resource_path);
+ struct EntryMap
+ {
+ QString base_path;
+ QMap<QString, MetaEntryPtr> entry_list;
+ };
+ QMap<QString, EntryMap> m_entries;
+ QString m_index_file;
+ QTimer saveBatchingTimer;
};
diff --git a/api/logic/net/MetaCacheSink.cpp b/api/logic/net/MetaCacheSink.cpp
index b4b337d6..d7f18533 100644
--- a/api/logic/net/MetaCacheSink.cpp
+++ b/api/logic/net/MetaCacheSink.cpp
@@ -7,59 +7,59 @@
namespace Net {
MetaCacheSink::MetaCacheSink(MetaEntryPtr entry, ChecksumValidator * md5sum)
- :Net::FileSink(entry->getFullPath()), m_entry(entry), m_md5Node(md5sum)
+ :Net::FileSink(entry->getFullPath()), m_entry(entry), m_md5Node(md5sum)
{
- addValidator(md5sum);
+ addValidator(md5sum);
}
MetaCacheSink::~MetaCacheSink()
{
- // nil
+ // nil
}
JobStatus MetaCacheSink::initCache(QNetworkRequest& request)
{
- if (!m_entry->isStale())
- {
- return Job_Finished;
- }
- // check if file exists, if it does, use its information for the request
- QFile current(m_filename);
- if(current.exists() && current.size() != 0)
- {
- if (m_entry->getRemoteChangedTimestamp().size())
- {
- request.setRawHeader(QString("If-Modified-Since").toLatin1(), m_entry->getRemoteChangedTimestamp().toLatin1());
- }
- if (m_entry->getETag().size())
- {
- request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1());
- }
- }
- return Job_InProgress;
+ if (!m_entry->isStale())
+ {
+ return Job_Finished;
+ }
+ // check if file exists, if it does, use its information for the request
+ QFile current(m_filename);
+ if(current.exists() && current.size() != 0)
+ {
+ if (m_entry->getRemoteChangedTimestamp().size())
+ {
+ request.setRawHeader(QString("If-Modified-Since").toLatin1(), m_entry->getRemoteChangedTimestamp().toLatin1());
+ }
+ if (m_entry->getETag().size())
+ {
+ request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1());
+ }
+ }
+ return Job_InProgress;
}
JobStatus MetaCacheSink::finalizeCache(QNetworkReply & reply)
{
- QFileInfo output_file_info(m_filename);
- if(wroteAnyData)
- {
- m_entry->setMD5Sum(m_md5Node->hash().toHex().constData());
- }
- m_entry->setETag(reply.rawHeader("ETag").constData());
- if (reply.hasRawHeader("Last-Modified"))
- {
- m_entry->setRemoteChangedTimestamp(reply.rawHeader("Last-Modified").constData());
- }
- m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch());
- m_entry->setStale(false);
- ENV.metacache()->updateEntry(m_entry);
- return Job_Finished;
+ QFileInfo output_file_info(m_filename);
+ if(wroteAnyData)
+ {
+ m_entry->setMD5Sum(m_md5Node->hash().toHex().constData());
+ }
+ m_entry->setETag(reply.rawHeader("ETag").constData());
+ if (reply.hasRawHeader("Last-Modified"))
+ {
+ m_entry->setRemoteChangedTimestamp(reply.rawHeader("Last-Modified").constData());
+ }
+ m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch());
+ m_entry->setStale(false);
+ ENV.metacache()->updateEntry(m_entry);
+ return Job_Finished;
}
bool MetaCacheSink::hasLocalData()
{
- QFileInfo info(m_filename);
- return info.exists() && info.size() != 0;
+ QFileInfo info(m_filename);
+ return info.exists() && info.size() != 0;
}
}
diff --git a/api/logic/net/MetaCacheSink.h b/api/logic/net/MetaCacheSink.h
index 0f3bbdf6..edcf7ad1 100644
--- a/api/logic/net/MetaCacheSink.h
+++ b/api/logic/net/MetaCacheSink.h
@@ -7,16 +7,16 @@ namespace Net {
class MetaCacheSink : public FileSink
{
public: /* con/des */
- MetaCacheSink(MetaEntryPtr entry, ChecksumValidator * md5sum);
- virtual ~MetaCacheSink();
- bool hasLocalData() override;
+ MetaCacheSink(MetaEntryPtr entry, ChecksumValidator * md5sum);
+ virtual ~MetaCacheSink();
+ bool hasLocalData() override;
protected: /* methods */
- JobStatus initCache(QNetworkRequest & request) override;
- JobStatus finalizeCache(QNetworkReply & reply) override;
+ JobStatus initCache(QNetworkRequest & request) override;
+ JobStatus finalizeCache(QNetworkReply & reply) override;
private: /* data */
- MetaEntryPtr m_entry;
- ChecksumValidator * m_md5Node;
+ MetaEntryPtr m_entry;
+ ChecksumValidator * m_md5Node;
};
}
diff --git a/api/logic/net/Mode.h b/api/logic/net/Mode.h
index 62e26d92..9a95f5ad 100644
--- a/api/logic/net/Mode.h
+++ b/api/logic/net/Mode.h
@@ -4,7 +4,7 @@ namespace Net
{
enum class Mode
{
- Offline,
- Online
+ Offline,
+ Online
};
}
diff --git a/api/logic/net/NetAction.h b/api/logic/net/NetAction.h
index 08e40a29..e1d2881e 100644
--- a/api/logic/net/NetAction.h
+++ b/api/logic/net/NetAction.h
@@ -25,91 +25,91 @@
enum JobStatus
{
- Job_NotStarted,
- Job_InProgress,
- Job_Finished,
- Job_Failed,
- Job_Aborted,
- /*
- * FIXME: @NUKE this confuses the task failing with us having a fallback in the form of local data. Clear up the confusion.
- * Same could be true for aborted task - the presence of pre-existing result is a separate concern
- */
- Job_Failed_Proceed
+ Job_NotStarted,
+ Job_InProgress,
+ Job_Finished,
+ Job_Failed,
+ Job_Aborted,
+ /*
+ * FIXME: @NUKE this confuses the task failing with us having a fallback in the form of local data. Clear up the confusion.
+ * Same could be true for aborted task - the presence of pre-existing result is a separate concern
+ */
+ Job_Failed_Proceed
};
typedef std::shared_ptr<class NetAction> NetActionPtr;
class MULTIMC_LOGIC_EXPORT NetAction : public QObject
{
- Q_OBJECT
+ Q_OBJECT
protected:
- explicit NetAction() : QObject(0) {};
+ explicit NetAction() : QObject(0) {};
public:
- virtual ~NetAction() {};
-
- bool isRunning() const
- {
- return m_status == Job_InProgress;
- }
- bool isFinished() const
- {
- return m_status >= Job_Finished;
- }
- bool wasSuccessful() const
- {
- return m_status == Job_Finished || m_status == Job_Failed_Proceed;
- }
-
- qint64 totalProgress() const
- {
- return m_total_progress;
- }
- qint64 currentProgress() const
- {
- return m_progress;
- }
- virtual bool abort()
- {
- return false;
- }
- virtual bool canAbort()
- {
- return false;
- }
- QUrl url()
- {
- return m_url;
- }
+ virtual ~NetAction() {};
+
+ bool isRunning() const
+ {
+ return m_status == Job_InProgress;
+ }
+ bool isFinished() const
+ {
+ return m_status >= Job_Finished;
+ }
+ bool wasSuccessful() const
+ {
+ return m_status == Job_Finished || m_status == Job_Failed_Proceed;
+ }
+
+ qint64 totalProgress() const
+ {
+ return m_total_progress;
+ }
+ qint64 currentProgress() const
+ {
+ return m_progress;
+ }
+ virtual bool abort()
+ {
+ return false;
+ }
+ virtual bool canAbort()
+ {
+ return false;
+ }
+ QUrl url()
+ {
+ return m_url;
+ }
signals:
- void started(int index);
- void netActionProgress(int index, qint64 current, qint64 total);
- void succeeded(int index);
- void failed(int index);
- void aborted(int index);
+ void started(int index);
+ void netActionProgress(int index, qint64 current, qint64 total);
+ void succeeded(int index);
+ void failed(int index);
+ void aborted(int index);
protected slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) = 0;
- virtual void downloadError(QNetworkReply::NetworkError error) = 0;
- virtual void downloadFinished() = 0;
- virtual void downloadReadyRead() = 0;
+ virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) = 0;
+ virtual void downloadError(QNetworkReply::NetworkError error) = 0;
+ virtual void downloadFinished() = 0;
+ virtual void downloadReadyRead() = 0;
public slots:
- virtual void start() = 0;
+ virtual void start() = 0;
public:
- /// index within the parent job, FIXME: nuke
- int m_index_within_job = 0;
+ /// index within the parent job, FIXME: nuke
+ int m_index_within_job = 0;
- /// the network reply
- unique_qobject_ptr<QNetworkReply> m_reply;
+ /// the network reply
+ unique_qobject_ptr<QNetworkReply> m_reply;
- /// source URL
- QUrl m_url;
+ /// source URL
+ QUrl m_url;
- qint64 m_progress = 0;
- qint64 m_total_progress = 1;
+ qint64 m_progress = 0;
+ qint64 m_total_progress = 1;
protected:
- JobStatus m_status = Job_NotStarted;
+ JobStatus m_status = Job_NotStarted;
};
diff --git a/api/logic/net/NetJob.cpp b/api/logic/net/NetJob.cpp
index 1ff8e28f..19ef742e 100644
--- a/api/logic/net/NetJob.cpp
+++ b/api/logic/net/NetJob.cpp
@@ -20,197 +20,197 @@
void NetJob::partSucceeded(int index)
{
- // do progress. all slots are 1 in size at least
- auto &slot = parts_progress[index];
- partProgress(index, slot.total_progress, slot.total_progress);
-
- m_doing.remove(index);
- m_done.insert(index);
- downloads[index].get()->disconnect(this);
- startMoreParts();
+ // do progress. all slots are 1 in size at least
+ auto &slot = parts_progress[index];
+ partProgress(index, slot.total_progress, slot.total_progress);
+
+ m_doing.remove(index);
+ m_done.insert(index);
+ downloads[index].get()->disconnect(this);
+ startMoreParts();
}
void NetJob::partFailed(int index)
{
- m_doing.remove(index);
- auto &slot = parts_progress[index];
- if (slot.failures == 3)
- {
- m_failed.insert(index);
- }
- else
- {
- slot.failures++;
- m_todo.enqueue(index);
- }
- downloads[index].get()->disconnect(this);
- startMoreParts();
+ m_doing.remove(index);
+ auto &slot = parts_progress[index];
+ if (slot.failures == 3)
+ {
+ m_failed.insert(index);
+ }
+ else
+ {
+ slot.failures++;
+ m_todo.enqueue(index);
+ }
+ downloads[index].get()->disconnect(this);
+ startMoreParts();
}
void NetJob::partAborted(int index)
{
- m_aborted = true;
- m_doing.remove(index);
- m_failed.insert(index);
- downloads[index].get()->disconnect(this);
- startMoreParts();
+ m_aborted = true;
+ m_doing.remove(index);
+ m_failed.insert(index);
+ downloads[index].get()->disconnect(this);
+ startMoreParts();
}
void NetJob::partProgress(int index, qint64 bytesReceived, qint64 bytesTotal)
{
- auto &slot = parts_progress[index];
- slot.current_progress = bytesReceived;
- slot.total_progress = bytesTotal;
-
- int done = m_done.size();
- int doing = m_doing.size();
- int all = parts_progress.size();
-
- qint64 bytesAll = 0;
- qint64 bytesTotalAll = 0;
- for(auto & partIdx: m_doing)
- {
- auto part = parts_progress[partIdx];
- // do not count parts with unknown/nonsensical total size
- if(part.total_progress <= 0)
- {
- continue;
- }
- bytesAll += part.current_progress;
- bytesTotalAll += part.total_progress;
- }
-
- qint64 inprogress = (bytesTotalAll == 0) ? 0 : (bytesAll * 1000) / bytesTotalAll;
- auto current = done * 1000 + doing * inprogress;
- auto current_total = all * 1000;
- // HACK: make sure it never jumps backwards.
- // FAIL: This breaks if the size is not known (or is it something else?) and jumps to 1000, so if it is 1000 reset it to inprogress
- if(m_current_progress == 1000) {
- m_current_progress = inprogress;
- }
- if(m_current_progress > current)
- {
- current = m_current_progress;
- }
- m_current_progress = current;
- setProgress(current, current_total);
+ auto &slot = parts_progress[index];
+ slot.current_progress = bytesReceived;
+ slot.total_progress = bytesTotal;
+
+ int done = m_done.size();
+ int doing = m_doing.size();
+ int all = parts_progress.size();
+
+ qint64 bytesAll = 0;
+ qint64 bytesTotalAll = 0;
+ for(auto & partIdx: m_doing)
+ {
+ auto part = parts_progress[partIdx];
+ // do not count parts with unknown/nonsensical total size
+ if(part.total_progress <= 0)
+ {
+ continue;
+ }
+ bytesAll += part.current_progress;
+ bytesTotalAll += part.total_progress;
+ }
+
+ qint64 inprogress = (bytesTotalAll == 0) ? 0 : (bytesAll * 1000) / bytesTotalAll;
+ auto current = done * 1000 + doing * inprogress;
+ auto current_total = all * 1000;
+ // HACK: make sure it never jumps backwards.
+ // FAIL: This breaks if the size is not known (or is it something else?) and jumps to 1000, so if it is 1000 reset it to inprogress
+ if(m_current_progress == 1000) {
+ m_current_progress = inprogress;
+ }
+ if(m_current_progress > current)
+ {
+ current = m_current_progress;
+ }
+ m_current_progress = current;
+ setProgress(current, current_total);
}
void NetJob::executeTask()
{
- // hack that delays early failures so they can be caught easier
- QMetaObject::invokeMethod(this, "startMoreParts", Qt::QueuedConnection);
+ // hack that delays early failures so they can be caught easier
+ QMetaObject::invokeMethod(this, "startMoreParts", Qt::QueuedConnection);
}
void NetJob::startMoreParts()
{
- if(!isRunning())
- {
- // this actually makes sense. You can put running downloads into a NetJob and then not start it until much later.
- return;
- }
- // OK. We are actively processing tasks, proceed.
- // Check for final conditions if there's nothing in the queue.
- if(!m_todo.size())
- {
- if(!m_doing.size())
- {
- if(!m_failed.size())
- {
- emitSucceeded();
- }
- else if(m_aborted)
- {
- emitAborted();
- }
- else
- {
- emitFailed(tr("Job '%1' failed to process:\n%2").arg(objectName()).arg(getFailedFiles().join("\n")));
- }
- }
- return;
- }
- // There's work to do, try to start more parts.
- while (m_doing.size() < 6)
- {
- if(!m_todo.size())
- return;
- int doThis = m_todo.dequeue();
- m_doing.insert(doThis);
- auto part = downloads[doThis];
- // connect signals :D
- connect(part.get(), SIGNAL(succeeded(int)), SLOT(partSucceeded(int)));
- connect(part.get(), SIGNAL(failed(int)), SLOT(partFailed(int)));
- connect(part.get(), SIGNAL(aborted(int)), SLOT(partAborted(int)));
- connect(part.get(), SIGNAL(netActionProgress(int, qint64, qint64)),
- SLOT(partProgress(int, qint64, qint64)));
- part->start();
- }
+ if(!isRunning())
+ {
+ // this actually makes sense. You can put running downloads into a NetJob and then not start it until much later.
+ return;
+ }
+ // OK. We are actively processing tasks, proceed.
+ // Check for final conditions if there's nothing in the queue.
+ if(!m_todo.size())
+ {
+ if(!m_doing.size())
+ {
+ if(!m_failed.size())
+ {
+ emitSucceeded();
+ }
+ else if(m_aborted)
+ {
+ emitAborted();
+ }
+ else
+ {
+ emitFailed(tr("Job '%1' failed to process:\n%2").arg(objectName()).arg(getFailedFiles().join("\n")));
+ }
+ }
+ return;
+ }
+ // There's work to do, try to start more parts.
+ while (m_doing.size() < 6)
+ {
+ if(!m_todo.size())
+ return;
+ int doThis = m_todo.dequeue();
+ m_doing.insert(doThis);
+ auto part = downloads[doThis];
+ // connect signals :D
+ connect(part.get(), SIGNAL(succeeded(int)), SLOT(partSucceeded(int)));
+ connect(part.get(), SIGNAL(failed(int)), SLOT(partFailed(int)));
+ connect(part.get(), SIGNAL(aborted(int)), SLOT(partAborted(int)));
+ connect(part.get(), SIGNAL(netActionProgress(int, qint64, qint64)),
+ SLOT(partProgress(int, qint64, qint64)));
+ part->start();
+ }
}
QStringList NetJob::getFailedFiles()
{
- QStringList failed;
- for (auto index: m_failed)
- {
- failed.push_back(downloads[index]->url().toString());
- }
- failed.sort();
- return failed;
+ QStringList failed;
+ for (auto index: m_failed)
+ {
+ failed.push_back(downloads[index]->url().toString());
+ }
+ failed.sort();
+ return failed;
}
bool NetJob::canAbort() const
{
- bool canFullyAbort = true;
- // can abort the waiting?
- for(auto index: m_todo)
- {
- auto part = downloads[index];
- canFullyAbort &= part->canAbort();
- }
- // can abort the active?
- for(auto index: m_doing)
- {
- auto part = downloads[index];
- canFullyAbort &= part->canAbort();
- }
- return canFullyAbort;
+ bool canFullyAbort = true;
+ // can abort the waiting?
+ for(auto index: m_todo)
+ {
+ auto part = downloads[index];
+ canFullyAbort &= part->canAbort();
+ }
+ // can abort the active?
+ for(auto index: m_doing)
+ {
+ auto part = downloads[index];
+ canFullyAbort &= part->canAbort();
+ }
+ return canFullyAbort;
}
bool NetJob::abort()
{
- bool fullyAborted = true;
- // fail all waiting
- m_failed.unite(m_todo.toSet());
- m_todo.clear();
- // abort active
- auto toKill = m_doing.toList();
- for(auto index: toKill)
- {
- auto part = downloads[index];
- fullyAborted &= part->abort();
- }
- return fullyAborted;
+ bool fullyAborted = true;
+ // fail all waiting
+ m_failed.unite(m_todo.toSet());
+ m_todo.clear();
+ // abort active
+ auto toKill = m_doing.toList();
+ for(auto index: toKill)
+ {
+ auto part = downloads[index];
+ fullyAborted &= part->abort();
+ }
+ return fullyAborted;
}
bool NetJob::addNetAction(NetActionPtr action)
{
- action->m_index_within_job = downloads.size();
- downloads.append(action);
- part_info pi;
- parts_progress.append(pi);
- partProgress(parts_progress.count() - 1, action->currentProgress(), action->totalProgress());
-
- if(action->isRunning())
- {
- connect(action.get(), SIGNAL(succeeded(int)), SLOT(partSucceeded(int)));
- connect(action.get(), SIGNAL(failed(int)), SLOT(partFailed(int)));
- connect(action.get(), SIGNAL(netActionProgress(int, qint64, qint64)), SLOT(partProgress(int, qint64, qint64)));
- }
- else
- {
- m_todo.append(parts_progress.size() - 1);
- }
- return true;
+ action->m_index_within_job = downloads.size();
+ downloads.append(action);
+ part_info pi;
+ parts_progress.append(pi);
+ partProgress(parts_progress.count() - 1, action->currentProgress(), action->totalProgress());
+
+ if(action->isRunning())
+ {
+ connect(action.get(), SIGNAL(succeeded(int)), SLOT(partSucceeded(int)));
+ connect(action.get(), SIGNAL(failed(int)), SLOT(partFailed(int)));
+ connect(action.get(), SIGNAL(netActionProgress(int, qint64, qint64)), SLOT(partProgress(int, qint64, qint64)));
+ }
+ else
+ {
+ m_todo.append(parts_progress.size() - 1);
+ }
+ return true;
}
diff --git a/api/logic/net/NetJob.h b/api/logic/net/NetJob.h
index be58c61a..3051b943 100644
--- a/api/logic/net/NetJob.h
+++ b/api/logic/net/NetJob.h
@@ -28,64 +28,64 @@ typedef shared_qobject_ptr<NetJob> NetJobPtr;
class MULTIMC_LOGIC_EXPORT NetJob : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit NetJob(QString job_name) : Task()
- {
- setObjectName(job_name);
- }
- virtual ~NetJob() {}
+ explicit NetJob(QString job_name) : Task()
+ {
+ setObjectName(job_name);
+ }
+ virtual ~NetJob() {}
- bool addNetAction(NetActionPtr action);
+ bool addNetAction(NetActionPtr action);
- NetActionPtr operator[](int index)
- {
- return downloads[index];
- }
- const NetActionPtr at(const int index)
- {
- return downloads.at(index);
- }
- NetActionPtr first()
- {
- if (downloads.size())
- return downloads[0];
- return NetActionPtr();
- }
- int size() const
- {
- return downloads.size();
- }
- QStringList getFailedFiles();
+ NetActionPtr operator[](int index)
+ {
+ return downloads[index];
+ }
+ const NetActionPtr at(const int index)
+ {
+ return downloads.at(index);
+ }
+ NetActionPtr first()
+ {
+ if (downloads.size())
+ return downloads[0];
+ return NetActionPtr();
+ }
+ int size() const
+ {
+ return downloads.size();
+ }
+ QStringList getFailedFiles();
- bool canAbort() const override;
+ bool canAbort() const override;
private slots:
- void startMoreParts();
+ void startMoreParts();
public slots:
- virtual void executeTask() override;
- virtual bool abort() override;
+ virtual void executeTask() override;
+ virtual bool abort() override;
private slots:
- void partProgress(int index, qint64 bytesReceived, qint64 bytesTotal);
- void partSucceeded(int index);
- void partFailed(int index);
- void partAborted(int index);
+ void partProgress(int index, qint64 bytesReceived, qint64 bytesTotal);
+ void partSucceeded(int index);
+ void partFailed(int index);
+ void partAborted(int index);
private:
- struct part_info
- {
- qint64 current_progress = 0;
- qint64 total_progress = 1;
- int failures = 0;
- };
- QList<NetActionPtr> downloads;
- QList<part_info> parts_progress;
- QQueue<int> m_todo;
- QSet<int> m_doing;
- QSet<int> m_done;
- QSet<int> m_failed;
- qint64 m_current_progress = 0;
- bool m_aborted = false;
+ struct part_info
+ {
+ qint64 current_progress = 0;
+ qint64 total_progress = 1;
+ int failures = 0;
+ };
+ QList<NetActionPtr> downloads;
+ QList<part_info> parts_progress;
+ QQueue<int> m_todo;
+ QSet<int> m_doing;
+ QSet<int> m_done;
+ QSet<int> m_failed;
+ qint64 m_current_progress = 0;
+ bool m_aborted = false;
};
diff --git a/api/logic/net/PasteUpload.cpp b/api/logic/net/PasteUpload.cpp
index d1ddf39d..3526e207 100644
--- a/api/logic/net/PasteUpload.cpp
+++ b/api/logic/net/PasteUpload.cpp
@@ -8,18 +8,18 @@
PasteUpload::PasteUpload(QWidget *window, QString text, QString key) : m_window(window)
{
- m_key = key;
- QByteArray temp;
- QJsonObject topLevelObj;
- QJsonObject sectionObject;
- sectionObject.insert("contents", text);
- QJsonArray sectionArray;
- sectionArray.append(sectionObject);
- topLevelObj.insert("description", "MultiMC Log Upload");
- topLevelObj.insert("sections", sectionArray);
- QJsonDocument docOut;
- docOut.setObject(topLevelObj);
- m_jsonContent = docOut.toJson();
+ m_key = key;
+ QByteArray temp;
+ QJsonObject topLevelObj;
+ QJsonObject sectionObject;
+ sectionObject.insert("contents", text);
+ QJsonArray sectionArray;
+ sectionArray.append(sectionObject);
+ topLevelObj.insert("description", "MultiMC Log Upload");
+ topLevelObj.insert("sections", sectionArray);
+ QJsonDocument docOut;
+ docOut.setObject(topLevelObj);
+ m_jsonContent = docOut.toJson();
}
PasteUpload::~PasteUpload()
@@ -28,76 +28,76 @@ PasteUpload::~PasteUpload()
bool PasteUpload::validateText()
{
- return m_jsonContent.size() <= maxSize();
+ return m_jsonContent.size() <= maxSize();
}
void PasteUpload::executeTask()
{
- QNetworkRequest request(QUrl("https://api.paste.ee/v1/pastes"));
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
+ QNetworkRequest request(QUrl("https://api.paste.ee/v1/pastes"));
+ request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
- request.setRawHeader("Content-Type", "application/json");
- request.setRawHeader("Content-Length", QByteArray::number(m_jsonContent.size()));
- request.setRawHeader("X-Auth-Token", m_key.toStdString().c_str());
+ request.setRawHeader("Content-Type", "application/json");
+ request.setRawHeader("Content-Length", QByteArray::number(m_jsonContent.size()));
+ request.setRawHeader("X-Auth-Token", m_key.toStdString().c_str());
- QNetworkReply *rep = ENV.qnam().post(request, m_jsonContent);
+ QNetworkReply *rep = ENV.qnam().post(request, m_jsonContent);
- m_reply = std::shared_ptr<QNetworkReply>(rep);
- setStatus(tr("Uploading to paste.ee"));
- connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress);
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(rep, SIGNAL(finished()), this, SLOT(downloadFinished()));
+ m_reply = std::shared_ptr<QNetworkReply>(rep);
+ setStatus(tr("Uploading to paste.ee"));
+ connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress);
+ connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
+ connect(rep, SIGNAL(finished()), this, SLOT(downloadFinished()));
}
void PasteUpload::downloadError(QNetworkReply::NetworkError error)
{
- // error happened during download.
- qCritical() << "Network error: " << error;
- emitFailed(m_reply->errorString());
+ // error happened during download.
+ qCritical() << "Network error: " << error;
+ emitFailed(m_reply->errorString());
}
void PasteUpload::downloadFinished()
{
- QByteArray data = m_reply->readAll();
- // if the download succeeded
- if (m_reply->error() == QNetworkReply::NetworkError::NoError)
- {
- m_reply.reset();
- QJsonParseError jsonError;
- QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- emitFailed(jsonError.errorString());
- return;
- }
- if (!parseResult(doc))
- {
- emitFailed(tr("paste.ee returned an error. Please consult the logs for more information"));
- return;
- }
- }
- // else the download failed
- else
- {
- emitFailed(QString("Network error: %1").arg(m_reply->errorString()));
- m_reply.reset();
- return;
- }
- emitSucceeded();
+ QByteArray data = m_reply->readAll();
+ // if the download succeeded
+ if (m_reply->error() == QNetworkReply::NetworkError::NoError)
+ {
+ m_reply.reset();
+ QJsonParseError jsonError;
+ QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
+ if (jsonError.error != QJsonParseError::NoError)
+ {
+ emitFailed(jsonError.errorString());
+ return;
+ }
+ if (!parseResult(doc))
+ {
+ emitFailed(tr("paste.ee returned an error. Please consult the logs for more information"));
+ return;
+ }
+ }
+ // else the download failed
+ else
+ {
+ emitFailed(QString("Network error: %1").arg(m_reply->errorString()));
+ m_reply.reset();
+ return;
+ }
+ emitSucceeded();
}
bool PasteUpload::parseResult(QJsonDocument doc)
{
- auto object = doc.object();
- auto status = object.value("success").toBool();
- if (!status)
- {
- qCritical() << "paste.ee reported error:" << QString(object.value("error").toString());
- return false;
- }
- m_pasteLink = object.value("link").toString();
- m_pasteID = object.value("id").toString();
- qDebug() << m_pasteLink;
- return true;
+ auto object = doc.object();
+ auto status = object.value("success").toBool();
+ if (!status)
+ {
+ qCritical() << "paste.ee reported error:" << QString(object.value("error").toString());
+ return false;
+ }
+ m_pasteLink = object.value("link").toString();
+ m_pasteID = object.value("id").toString();
+ qDebug() << m_pasteLink;
+ return true;
}
diff --git a/api/logic/net/PasteUpload.h b/api/logic/net/PasteUpload.h
index 24f5b0eb..11e05c2e 100644
--- a/api/logic/net/PasteUpload.h
+++ b/api/logic/net/PasteUpload.h
@@ -8,42 +8,42 @@
class MULTIMC_LOGIC_EXPORT PasteUpload : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- PasteUpload(QWidget *window, QString text, QString key = "public");
- virtual ~PasteUpload();
+ PasteUpload(QWidget *window, QString text, QString key = "public");
+ virtual ~PasteUpload();
- QString pasteLink()
- {
- return m_pasteLink;
- }
- QString pasteID()
- {
- return m_pasteID;
- }
- int maxSize()
- {
- // 2MB for paste.ee - public
- if(m_key == "public")
- return 1024*1024*2;
- // 12MB for paste.ee - with actual key
- return 1024*1024*12;
- }
- bool validateText();
+ QString pasteLink()
+ {
+ return m_pasteLink;
+ }
+ QString pasteID()
+ {
+ return m_pasteID;
+ }
+ int maxSize()
+ {
+ // 2MB for paste.ee - public
+ if(m_key == "public")
+ return 1024*1024*2;
+ // 12MB for paste.ee - with actual key
+ return 1024*1024*12;
+ }
+ bool validateText();
protected:
- virtual void executeTask();
+ virtual void executeTask();
private:
- bool parseResult(QJsonDocument doc);
- QString m_error;
- QWidget *m_window;
- QString m_pasteID;
- QString m_pasteLink;
- QString m_key;
- QByteArray m_jsonContent;
- std::shared_ptr<QNetworkReply> m_reply;
+ bool parseResult(QJsonDocument doc);
+ QString m_error;
+ QWidget *m_window;
+ QString m_pasteID;
+ QString m_pasteLink;
+ QString m_key;
+ QByteArray m_jsonContent;
+ std::shared_ptr<QNetworkReply> m_reply;
public
slots:
- void downloadError(QNetworkReply::NetworkError);
- void downloadFinished();
+ void downloadError(QNetworkReply::NetworkError);
+ void downloadFinished();
};
diff --git a/api/logic/net/Sink.h b/api/logic/net/Sink.h
index de9b1722..d526895c 100644
--- a/api/logic/net/Sink.h
+++ b/api/logic/net/Sink.h
@@ -9,63 +9,63 @@ namespace Net {
class MULTIMC_LOGIC_EXPORT Sink
{
public: /* con/des */
- Sink() {};
- virtual ~Sink() {};
+ Sink() {};
+ virtual ~Sink() {};
public: /* methods */
- virtual JobStatus init(QNetworkRequest & request) = 0;
- virtual JobStatus write(QByteArray & data) = 0;
- virtual JobStatus abort() = 0;
- virtual JobStatus finalize(QNetworkReply & reply) = 0;
- virtual bool hasLocalData() = 0;
+ virtual JobStatus init(QNetworkRequest & request) = 0;
+ virtual JobStatus write(QByteArray & data) = 0;
+ virtual JobStatus abort() = 0;
+ virtual JobStatus finalize(QNetworkReply & reply) = 0;
+ virtual bool hasLocalData() = 0;
- void addValidator(Validator * validator)
- {
- if(validator)
- {
- validators.push_back(std::shared_ptr<Validator>(validator));
- }
- }
+ void addValidator(Validator * validator)
+ {
+ if(validator)
+ {
+ validators.push_back(std::shared_ptr<Validator>(validator));
+ }
+ }
protected: /* methods */
- bool finalizeAllValidators(QNetworkReply & reply)
- {
- for(auto & validator: validators)
- {
- if(!validator->validate(reply))
- return false;
- }
- return true;
- }
- bool failAllValidators()
- {
- bool success = true;
- for(auto & validator: validators)
- {
- success &= validator->abort();
- }
- return success;
- }
- bool initAllValidators(QNetworkRequest & request)
- {
- for(auto & validator: validators)
- {
- if(!validator->init(request))
- return false;
- }
- return true;
- }
- bool writeAllValidators(QByteArray & data)
- {
- for(auto & validator: validators)
- {
- if(!validator->write(data))
- return false;
- }
- return true;
- }
+ bool finalizeAllValidators(QNetworkReply & reply)
+ {
+ for(auto & validator: validators)
+ {
+ if(!validator->validate(reply))
+ return false;
+ }
+ return true;
+ }
+ bool failAllValidators()
+ {
+ bool success = true;
+ for(auto & validator: validators)
+ {
+ success &= validator->abort();
+ }
+ return success;
+ }
+ bool initAllValidators(QNetworkRequest & request)
+ {
+ for(auto & validator: validators)
+ {
+ if(!validator->init(request))
+ return false;
+ }
+ return true;
+ }
+ bool writeAllValidators(QByteArray & data)
+ {
+ for(auto & validator: validators)
+ {
+ if(!validator->write(data))
+ return false;
+ }
+ return true;
+ }
protected: /* data */
- std::vector<std::shared_ptr<Validator>> validators;
+ std::vector<std::shared_ptr<Validator>> validators;
};
}
diff --git a/api/logic/net/URLConstants.cpp b/api/logic/net/URLConstants.cpp
index bd476b2c..5d848d80 100644
--- a/api/logic/net/URLConstants.cpp
+++ b/api/logic/net/URLConstants.cpp
@@ -4,12 +4,12 @@ namespace URLConstants {
QString getLegacyJarUrl(QString version)
{
- return "http://" + AWS_DOWNLOAD_VERSIONS + getJarPath(version);
+ return "http://" + AWS_DOWNLOAD_VERSIONS + getJarPath(version);
}
QString getJarPath(QString version)
{
- return version + "/" + version + ".jar";
+ return version + "/" + version + ".jar";
}
diff --git a/api/logic/net/Validator.h b/api/logic/net/Validator.h
index a390ab28..955412ce 100644
--- a/api/logic/net/Validator.h
+++ b/api/logic/net/Validator.h
@@ -8,13 +8,13 @@ namespace Net {
class MULTIMC_LOGIC_EXPORT Validator
{
public: /* con/des */
- Validator() {};
- virtual ~Validator() {};
+ Validator() {};
+ virtual ~Validator() {};
public: /* methods */
- virtual bool init(QNetworkRequest & request) = 0;
- virtual bool write(QByteArray & data) = 0;
- virtual bool abort() = 0;
- virtual bool validate(QNetworkReply & reply) = 0;
+ virtual bool init(QNetworkRequest & request) = 0;
+ virtual bool write(QByteArray & data) = 0;
+ virtual bool abort() = 0;
+ virtual bool validate(QNetworkReply & reply) = 0;
};
} \ No newline at end of file
diff --git a/api/logic/news/NewsChecker.cpp b/api/logic/news/NewsChecker.cpp
index 0ee3f9da..1f5058ef 100644
--- a/api/logic/news/NewsChecker.cpp
+++ b/api/logic/news/NewsChecker.cpp
@@ -22,110 +22,110 @@
NewsChecker::NewsChecker(const QString& feedUrl)
{
- m_feedUrl = feedUrl;
+ m_feedUrl = feedUrl;
}
void NewsChecker::reloadNews()
{
- // Start a netjob to download the RSS feed and call rssDownloadFinished() when it's done.
- if (isLoadingNews())
- {
- qDebug() << "Ignored request to reload news. Currently reloading already.";
- return;
- }
-
- qDebug() << "Reloading news.";
-
- NetJob* job = new NetJob("News RSS Feed");
- job->addNetAction(Net::Download::makeByteArray(m_feedUrl, &newsData));
- QObject::connect(job, &NetJob::succeeded, this, &NewsChecker::rssDownloadFinished);
- QObject::connect(job, &NetJob::failed, this, &NewsChecker::rssDownloadFailed);
- m_newsNetJob.reset(job);
- job->start();
+ // Start a netjob to download the RSS feed and call rssDownloadFinished() when it's done.
+ if (isLoadingNews())
+ {
+ qDebug() << "Ignored request to reload news. Currently reloading already.";
+ return;
+ }
+
+ qDebug() << "Reloading news.";
+
+ NetJob* job = new NetJob("News RSS Feed");
+ job->addNetAction(Net::Download::makeByteArray(m_feedUrl, &newsData));
+ QObject::connect(job, &NetJob::succeeded, this, &NewsChecker::rssDownloadFinished);
+ QObject::connect(job, &NetJob::failed, this, &NewsChecker::rssDownloadFailed);
+ m_newsNetJob.reset(job);
+ job->start();
}
void NewsChecker::rssDownloadFinished()
{
- // Parse the XML file and process the RSS feed entries.
- qDebug() << "Finished loading RSS feed.";
-
- m_newsNetJob.reset();
- QDomDocument doc;
- {
- // Stuff to store error info in.
- QString errorMsg = "Unknown error.";
- int errorLine = -1;
- int errorCol = -1;
-
- // Parse the XML.
- if (!doc.setContent(newsData, false, &errorMsg, &errorLine, &errorCol))
- {
- QString fullErrorMsg = QString("Error parsing RSS feed XML. %s at %d:%d.").arg(errorMsg, errorLine, errorCol);
- fail(fullErrorMsg);
- newsData.clear();
- return;
- }
- newsData.clear();
- }
-
- // If the parsing succeeded, read it.
- QDomNodeList items = doc.elementsByTagName("item");
- m_newsEntries.clear();
- for (int i = 0; i < items.length(); i++)
- {
- QDomElement element = items.at(i).toElement();
- NewsEntryPtr entry;
- entry.reset(new NewsEntry());
- QString errorMsg = "An unknown error occurred.";
- if (NewsEntry::fromXmlElement(element, entry.get(), &errorMsg))
- {
- qDebug() << "Loaded news entry" << entry->title;
- m_newsEntries.append(entry);
- }
- else
- {
- qWarning() << "Failed to load news entry at index" << i << ":" << errorMsg;
- }
- }
-
- succeed();
+ // Parse the XML file and process the RSS feed entries.
+ qDebug() << "Finished loading RSS feed.";
+
+ m_newsNetJob.reset();
+ QDomDocument doc;
+ {
+ // Stuff to store error info in.
+ QString errorMsg = "Unknown error.";
+ int errorLine = -1;
+ int errorCol = -1;
+
+ // Parse the XML.
+ if (!doc.setContent(newsData, false, &errorMsg, &errorLine, &errorCol))
+ {
+ QString fullErrorMsg = QString("Error parsing RSS feed XML. %s at %d:%d.").arg(errorMsg, errorLine, errorCol);
+ fail(fullErrorMsg);
+ newsData.clear();
+ return;
+ }
+ newsData.clear();
+ }
+
+ // If the parsing succeeded, read it.
+ QDomNodeList items = doc.elementsByTagName("item");
+ m_newsEntries.clear();
+ for (int i = 0; i < items.length(); i++)
+ {
+ QDomElement element = items.at(i).toElement();
+ NewsEntryPtr entry;
+ entry.reset(new NewsEntry());
+ QString errorMsg = "An unknown error occurred.";
+ if (NewsEntry::fromXmlElement(element, entry.get(), &errorMsg))
+ {
+ qDebug() << "Loaded news entry" << entry->title;
+ m_newsEntries.append(entry);
+ }
+ else
+ {
+ qWarning() << "Failed to load news entry at index" << i << ":" << errorMsg;
+ }
+ }
+
+ succeed();
}
void NewsChecker::rssDownloadFailed(QString reason)
{
- // Set an error message and fail.
- fail(tr("Failed to load news RSS feed:\n%1").arg(reason));
+ // Set an error message and fail.
+ fail(tr("Failed to load news RSS feed:\n%1").arg(reason));
}
QList<NewsEntryPtr> NewsChecker::getNewsEntries() const
{
- return m_newsEntries;
+ return m_newsEntries;
}
bool NewsChecker::isLoadingNews() const
{
- return m_newsNetJob.get() != nullptr;
+ return m_newsNetJob.get() != nullptr;
}
QString NewsChecker::getLastLoadErrorMsg() const
{
- return m_lastLoadError;
+ return m_lastLoadError;
}
void NewsChecker::succeed()
{
- m_lastLoadError = "";
- qDebug() << "News loading succeeded.";
- m_newsNetJob.reset();
- emit newsLoaded();
+ m_lastLoadError = "";
+ qDebug() << "News loading succeeded.";
+ m_newsNetJob.reset();
+ emit newsLoaded();
}
void NewsChecker::fail(const QString& errorMsg)
{
- m_lastLoadError = errorMsg;
- qDebug() << "Failed to load news:" << errorMsg;
- m_newsNetJob.reset();
- emit newsLoadingFailed(errorMsg);
+ m_lastLoadError = errorMsg;
+ qDebug() << "Failed to load news:" << errorMsg;
+ m_newsNetJob.reset();
+ emit newsLoadingFailed(errorMsg);
}
diff --git a/api/logic/news/NewsChecker.h b/api/logic/news/NewsChecker.h
index 44f2534a..7af5bd5d 100644
--- a/api/logic/news/NewsChecker.h
+++ b/api/logic/news/NewsChecker.h
@@ -27,79 +27,79 @@
class MULTIMC_LOGIC_EXPORT NewsChecker : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- /*!
- * Constructs a news reader to read from the given RSS feed URL.
- */
- NewsChecker(const QString& feedUrl);
-
- /*!
- * Returns the error message for the last time the news was loaded.
- * Empty string if the last load was successful.
- */
- QString getLastLoadErrorMsg() const;
-
- /*!
- * Returns true if the news has been loaded successfully.
- */
- bool isNewsLoaded() const;
-
- //! True if the news is currently loading. If true, reloadNews() will do nothing.
- bool isLoadingNews() const;
-
- /*!
- * Returns a list of news entries.
- */
- QList<NewsEntryPtr> getNewsEntries() const;
-
- /*!
- * Reloads the news from the website's RSS feed.
- * If the news is already loading, this does nothing.
- */
- void Q_SLOT reloadNews();
+ /*!
+ * Constructs a news reader to read from the given RSS feed URL.
+ */
+ NewsChecker(const QString& feedUrl);
+
+ /*!
+ * Returns the error message for the last time the news was loaded.
+ * Empty string if the last load was successful.
+ */
+ QString getLastLoadErrorMsg() const;
+
+ /*!
+ * Returns true if the news has been loaded successfully.
+ */
+ bool isNewsLoaded() const;
+
+ //! True if the news is currently loading. If true, reloadNews() will do nothing.
+ bool isLoadingNews() const;
+
+ /*!
+ * Returns a list of news entries.
+ */
+ QList<NewsEntryPtr> getNewsEntries() const;
+
+ /*!
+ * Reloads the news from the website's RSS feed.
+ * If the news is already loading, this does nothing.
+ */
+ void Q_SLOT reloadNews();
signals:
- /*!
- * Signal fired after the news has finished loading.
- */
- void newsLoaded();
+ /*!
+ * Signal fired after the news has finished loading.
+ */
+ void newsLoaded();
- /*!
- * Signal fired after the news fails to load.
- */
- void newsLoadingFailed(QString errorMsg);
+ /*!
+ * Signal fired after the news fails to load.
+ */
+ void newsLoadingFailed(QString errorMsg);
protected slots:
- void rssDownloadFinished();
- void rssDownloadFailed(QString reason);
+ void rssDownloadFinished();
+ void rssDownloadFailed(QString reason);
protected: /* data */
- //! The URL for the RSS feed to fetch.
- QString m_feedUrl;
+ //! The URL for the RSS feed to fetch.
+ QString m_feedUrl;
- //! List of news entries.
- QList<NewsEntryPtr> m_newsEntries;
+ //! List of news entries.
+ QList<NewsEntryPtr> m_newsEntries;
- //! The network job to use to load the news.
- NetJobPtr m_newsNetJob;
+ //! The network job to use to load the news.
+ NetJobPtr m_newsNetJob;
- //! True if news has been loaded.
- bool m_loadedNews;
+ //! True if news has been loaded.
+ bool m_loadedNews;
- QByteArray newsData;
+ QByteArray newsData;
- /*!
- * Gets the error message that was given last time the news was loaded.
- * If the last news load succeeded, this will be an empty string.
- */
- QString m_lastLoadError;
+ /*!
+ * Gets the error message that was given last time the news was loaded.
+ * If the last news load succeeded, this will be an empty string.
+ */
+ QString m_lastLoadError;
protected slots:
- /// Emits newsLoaded() and sets m_lastLoadError to empty string.
- void succeed();
+ /// Emits newsLoaded() and sets m_lastLoadError to empty string.
+ void succeed();
- /// Emits newsLoadingFailed() and sets m_lastLoadError to the given message.
- void fail(const QString& errorMsg);
+ /// Emits newsLoadingFailed() and sets m_lastLoadError to the given message.
+ void fail(const QString& errorMsg);
};
diff --git a/api/logic/news/NewsEntry.cpp b/api/logic/news/NewsEntry.cpp
index 4377f766..82d654be 100644
--- a/api/logic/news/NewsEntry.cpp
+++ b/api/logic/news/NewsEntry.cpp
@@ -19,23 +19,23 @@
#include <QVariant>
NewsEntry::NewsEntry(QObject* parent) :
- QObject(parent)
+ QObject(parent)
{
- this->title = tr("Untitled");
- this->content = tr("No content.");
- this->link = "";
- this->author = tr("Unknown Author");
- this->pubDate = QDateTime::currentDateTime();
+ this->title = tr("Untitled");
+ this->content = tr("No content.");
+ this->link = "";
+ this->author = tr("Unknown Author");
+ this->pubDate = QDateTime::currentDateTime();
}
NewsEntry::NewsEntry(const QString& title, const QString& content, const QString& link, const QString& author, const QDateTime& pubDate, QObject* parent) :
- QObject(parent)
+ QObject(parent)
{
- this->title = title;
- this->content = content;
- this->link = link;
- this->author = author;
- this->pubDate = pubDate;
+ this->title = title;
+ this->content = content;
+ this->link = link;
+ this->author = author;
+ this->pubDate = pubDate;
}
/*!
@@ -43,35 +43,35 @@ NewsEntry::NewsEntry(const QString& title, const QString& content, const QString
*/
inline QString childValue(const QDomElement& element, const QString& childName, QString defaultVal="")
{
- QDomNodeList nodes = element.elementsByTagName(childName);
- if (nodes.count() > 0)
- {
- QDomElement element = nodes.at(0).toElement();
- return element.text();
- }
- else
- {
- return defaultVal;
- }
+ QDomNodeList nodes = element.elementsByTagName(childName);
+ if (nodes.count() > 0)
+ {
+ QDomElement element = nodes.at(0).toElement();
+ return element.text();
+ }
+ else
+ {
+ return defaultVal;
+ }
}
bool NewsEntry::fromXmlElement(const QDomElement& element, NewsEntry* entry, QString* errorMsg)
{
- QString title = childValue(element, "title", tr("Untitled"));
- QString content = childValue(element, "description", tr("No content."));
- QString link = childValue(element, "link");
- QString author = childValue(element, "dc:creator", tr("Unknown Author"));
- QString pubDateStr = childValue(element, "pubDate");
+ QString title = childValue(element, "title", tr("Untitled"));
+ QString content = childValue(element, "description", tr("No content."));
+ QString link = childValue(element, "link");
+ QString author = childValue(element, "dc:creator", tr("Unknown Author"));
+ QString pubDateStr = childValue(element, "pubDate");
- // FIXME: For now, we're just ignoring timezones. We assume that all time zones in the RSS feed are the same.
- QString dateFormat("ddd, dd MMM yyyy hh:mm:ss");
- QDateTime pubDate = QDateTime::fromString(pubDateStr, dateFormat);
+ // FIXME: For now, we're just ignoring timezones. We assume that all time zones in the RSS feed are the same.
+ QString dateFormat("ddd, dd MMM yyyy hh:mm:ss");
+ QDateTime pubDate = QDateTime::fromString(pubDateStr, dateFormat);
- entry->title = title;
- entry->content = content;
- entry->link = link;
- entry->author = author;
- entry->pubDate = pubDate;
- return true;
+ entry->title = title;
+ entry->content = content;
+ entry->link = link;
+ entry->author = author;
+ entry->pubDate = pubDate;
+ return true;
}
diff --git a/api/logic/news/NewsEntry.h b/api/logic/news/NewsEntry.h
index 16a17f9c..832766fb 100644
--- a/api/logic/news/NewsEntry.h
+++ b/api/logic/news/NewsEntry.h
@@ -24,41 +24,41 @@
class NewsEntry : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- /*!
- * Constructs an empty news entry.
- */
- explicit NewsEntry(QObject* parent=0);
+ /*!
+ * Constructs an empty news entry.
+ */
+ explicit NewsEntry(QObject* parent=0);
- /*!
- * Constructs a new news entry.
- * Note that content may contain HTML.
- */
- NewsEntry(const QString& title, const QString& content, const QString& link, const QString& author, const QDateTime& pubDate, QObject* parent=0);
+ /*!
+ * Constructs a new news entry.
+ * Note that content may contain HTML.
+ */
+ NewsEntry(const QString& title, const QString& content, const QString& link, const QString& author, const QDateTime& pubDate, QObject* parent=0);
- /*!
- * Attempts to load information from the given XML element into the given news entry pointer.
- * If this fails, the function will return false and store an error message in the errorMsg pointer.
- */
- static bool fromXmlElement(const QDomElement& element, NewsEntry* entry, QString* errorMsg=0);
+ /*!
+ * Attempts to load information from the given XML element into the given news entry pointer.
+ * If this fails, the function will return false and store an error message in the errorMsg pointer.
+ */
+ static bool fromXmlElement(const QDomElement& element, NewsEntry* entry, QString* errorMsg=0);
- //! The post title.
- QString title;
+ //! The post title.
+ QString title;
- //! The post's content. May contain HTML.
- QString content;
+ //! The post's content. May contain HTML.
+ QString content;
- //! URL to the post.
- QString link;
+ //! URL to the post.
+ QString link;
- //! The post's author.
- QString author;
-
- //! The date and time that this post was published.
- QDateTime pubDate;
+ //! The post's author.
+ QString author;
+
+ //! The date and time that this post was published.
+ QDateTime pubDate;
};
typedef std::shared_ptr<NewsEntry> NewsEntryPtr;
diff --git a/api/logic/notifications/NotificationChecker.cpp b/api/logic/notifications/NotificationChecker.cpp
index 6d006c31..8209c28b 100644
--- a/api/logic/notifications/NotificationChecker.cpp
+++ b/api/logic/notifications/NotificationChecker.cpp
@@ -10,120 +10,120 @@
NotificationChecker::NotificationChecker(QObject *parent)
- : QObject(parent)
+ : QObject(parent)
{
}
void NotificationChecker::setNotificationsUrl(const QUrl &notificationsUrl)
{
- m_notificationsUrl = notificationsUrl;
+ m_notificationsUrl = notificationsUrl;
}
void NotificationChecker::setApplicationChannel(QString channel)
{
- m_appVersionChannel = channel;
+ m_appVersionChannel = channel;
}
void NotificationChecker::setApplicationFullVersion(QString version)
{
- m_appFullVersion = version;
+ m_appFullVersion = version;
}
void NotificationChecker::setApplicationPlatform(QString platform)
{
- m_appPlatform = platform;
+ m_appPlatform = platform;
}
QList<NotificationChecker::NotificationEntry> NotificationChecker::notificationEntries() const
{
- return m_entries;
+ return m_entries;
}
void NotificationChecker::checkForNotifications()
{
- if (!m_notificationsUrl.isValid())
- {
- qCritical() << "Failed to check for notifications. No notifications URL set."
- << "If you'd like to use MultiMC's notification system, please pass the "
- "URL to CMake at compile time.";
- return;
- }
- if (m_checkJob)
- {
- return;
- }
- m_checkJob.reset(new NetJob("Checking for notifications"));
- auto entry = ENV.metacache()->resolveEntry("root", "notifications.json");
- entry->setStale(true);
- m_checkJob->addNetAction(m_download = Net::Download::makeCached(m_notificationsUrl, entry));
- connect(m_download.get(), &Net::Download::succeeded, this, &NotificationChecker::downloadSucceeded);
- m_checkJob->start();
+ if (!m_notificationsUrl.isValid())
+ {
+ qCritical() << "Failed to check for notifications. No notifications URL set."
+ << "If you'd like to use MultiMC's notification system, please pass the "
+ "URL to CMake at compile time.";
+ return;
+ }
+ if (m_checkJob)
+ {
+ return;
+ }
+ m_checkJob.reset(new NetJob("Checking for notifications"));
+ auto entry = ENV.metacache()->resolveEntry("root", "notifications.json");
+ entry->setStale(true);
+ m_checkJob->addNetAction(m_download = Net::Download::makeCached(m_notificationsUrl, entry));
+ connect(m_download.get(), &Net::Download::succeeded, this, &NotificationChecker::downloadSucceeded);
+ m_checkJob->start();
}
void NotificationChecker::downloadSucceeded(int)
{
- m_entries.clear();
-
- QFile file(m_download->getTargetFilepath());
- if (file.open(QFile::ReadOnly))
- {
- QJsonArray root = QJsonDocument::fromJson(file.readAll()).array();
- for (auto it = root.begin(); it != root.end(); ++it)
- {
- QJsonObject obj = (*it).toObject();
- NotificationEntry entry;
- entry.id = obj.value("id").toDouble();
- entry.message = obj.value("message").toString();
- entry.channel = obj.value("channel").toString();
- entry.platform = obj.value("platform").toString();
- entry.from = obj.value("from").toString();
- entry.to = obj.value("to").toString();
- const QString type = obj.value("type").toString("critical");
- if (type == "critical")
- {
- entry.type = NotificationEntry::Critical;
- }
- else if (type == "warning")
- {
- entry.type = NotificationEntry::Warning;
- }
- else if (type == "information")
- {
- entry.type = NotificationEntry::Information;
- }
- if(entryApplies(entry))
- m_entries.append(entry);
- }
- }
-
- m_checkJob.reset();
-
- emit notificationCheckFinished();
+ m_entries.clear();
+
+ QFile file(m_download->getTargetFilepath());
+ if (file.open(QFile::ReadOnly))
+ {
+ QJsonArray root = QJsonDocument::fromJson(file.readAll()).array();
+ for (auto it = root.begin(); it != root.end(); ++it)
+ {
+ QJsonObject obj = (*it).toObject();
+ NotificationEntry entry;
+ entry.id = obj.value("id").toDouble();
+ entry.message = obj.value("message").toString();
+ entry.channel = obj.value("channel").toString();
+ entry.platform = obj.value("platform").toString();
+ entry.from = obj.value("from").toString();
+ entry.to = obj.value("to").toString();
+ const QString type = obj.value("type").toString("critical");
+ if (type == "critical")
+ {
+ entry.type = NotificationEntry::Critical;
+ }
+ else if (type == "warning")
+ {
+ entry.type = NotificationEntry::Warning;
+ }
+ else if (type == "information")
+ {
+ entry.type = NotificationEntry::Information;
+ }
+ if(entryApplies(entry))
+ m_entries.append(entry);
+ }
+ }
+
+ m_checkJob.reset();
+
+ emit notificationCheckFinished();
}
bool versionLessThan(const QString &v1, const QString &v2)
{
- QStringList l1 = v1.split('.');
- QStringList l2 = v2.split('.');
- while (!l1.isEmpty() && !l2.isEmpty())
- {
- int one = l1.isEmpty() ? 0 : l1.takeFirst().toInt();
- int two = l2.isEmpty() ? 0 : l2.takeFirst().toInt();
- if (one != two)
- {
- return one < two;
- }
- }
- return false;
+ QStringList l1 = v1.split('.');
+ QStringList l2 = v2.split('.');
+ while (!l1.isEmpty() && !l2.isEmpty())
+ {
+ int one = l1.isEmpty() ? 0 : l1.takeFirst().toInt();
+ int two = l2.isEmpty() ? 0 : l2.takeFirst().toInt();
+ if (one != two)
+ {
+ return one < two;
+ }
+ }
+ return false;
}
bool NotificationChecker::entryApplies(const NotificationChecker::NotificationEntry& entry) const
{
- bool channelApplies = entry.channel.isEmpty() || entry.channel == m_appVersionChannel;
- bool platformApplies = entry.platform.isEmpty() || entry.platform == m_appPlatform;
- bool fromApplies =
- entry.from.isEmpty() || entry.from == m_appFullVersion || !versionLessThan(m_appFullVersion, entry.from);
- bool toApplies =
- entry.to.isEmpty() || entry.to == m_appFullVersion || !versionLessThan(entry.to, m_appFullVersion);
- return channelApplies && platformApplies && fromApplies && toApplies;
+ bool channelApplies = entry.channel.isEmpty() || entry.channel == m_appVersionChannel;
+ bool platformApplies = entry.platform.isEmpty() || entry.platform == m_appPlatform;
+ bool fromApplies =
+ entry.from.isEmpty() || entry.from == m_appFullVersion || !versionLessThan(m_appFullVersion, entry.from);
+ bool toApplies =
+ entry.to.isEmpty() || entry.to == m_appFullVersion || !versionLessThan(entry.to, m_appFullVersion);
+ return channelApplies && platformApplies && fromApplies && toApplies;
}
diff --git a/api/logic/notifications/NotificationChecker.h b/api/logic/notifications/NotificationChecker.h
index c8e831d5..4b1b893d 100644
--- a/api/logic/notifications/NotificationChecker.h
+++ b/api/logic/notifications/NotificationChecker.h
@@ -9,55 +9,55 @@
class MULTIMC_LOGIC_EXPORT NotificationChecker : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit NotificationChecker(QObject *parent = 0);
-
- void setNotificationsUrl(const QUrl &notificationsUrl);
- void setApplicationPlatform(QString platform);
- void setApplicationChannel(QString channel);
- void setApplicationFullVersion(QString version);
-
- struct NotificationEntry
- {
- int id;
- QString message;
- enum
- {
- Critical,
- Warning,
- Information
- } type;
- QString channel;
- QString platform;
- QString from;
- QString to;
- };
-
- QList<NotificationEntry> notificationEntries() const;
+ explicit NotificationChecker(QObject *parent = 0);
+
+ void setNotificationsUrl(const QUrl &notificationsUrl);
+ void setApplicationPlatform(QString platform);
+ void setApplicationChannel(QString channel);
+ void setApplicationFullVersion(QString version);
+
+ struct NotificationEntry
+ {
+ int id;
+ QString message;
+ enum
+ {
+ Critical,
+ Warning,
+ Information
+ } type;
+ QString channel;
+ QString platform;
+ QString from;
+ QString to;
+ };
+
+ QList<NotificationEntry> notificationEntries() const;
public
slots:
- void checkForNotifications();
+ void checkForNotifications();
private
slots:
- void downloadSucceeded(int);
+ void downloadSucceeded(int);
signals:
- void notificationCheckFinished();
+ void notificationCheckFinished();
private:
- bool entryApplies(const NotificationEntry &entry) const;
+ bool entryApplies(const NotificationEntry &entry) const;
private:
- QList<NotificationEntry> m_entries;
- QUrl m_notificationsUrl;
- NetJobPtr m_checkJob;
- Net::Download::Ptr m_download;
-
- QString m_appVersionChannel;
- QString m_appPlatform;
- QString m_appFullVersion;
+ QList<NotificationEntry> m_entries;
+ QUrl m_notificationsUrl;
+ NetJobPtr m_checkJob;
+ Net::Download::Ptr m_download;
+
+ QString m_appVersionChannel;
+ QString m_appPlatform;
+ QString m_appFullVersion;
};
diff --git a/api/logic/pathmatcher/FSTreeMatcher.h b/api/logic/pathmatcher/FSTreeMatcher.h
index a5bed57c..361924af 100644
--- a/api/logic/pathmatcher/FSTreeMatcher.h
+++ b/api/logic/pathmatcher/FSTreeMatcher.h
@@ -7,15 +7,15 @@
class FSTreeMatcher : public IPathMatcher
{
public:
- virtual ~FSTreeMatcher() {};
- FSTreeMatcher(SeparatorPrefixTree<'/'> & tree) : m_fsTree(tree)
- {
- }
+ virtual ~FSTreeMatcher() {};
+ FSTreeMatcher(SeparatorPrefixTree<'/'> & tree) : m_fsTree(tree)
+ {
+ }
- virtual bool matches(const QString &string) const override
- {
- return m_fsTree.covers(string);
- }
+ virtual bool matches(const QString &string) const override
+ {
+ return m_fsTree.covers(string);
+ }
- SeparatorPrefixTree<'/'> & m_fsTree;
+ SeparatorPrefixTree<'/'> & m_fsTree;
};
diff --git a/api/logic/pathmatcher/IPathMatcher.h b/api/logic/pathmatcher/IPathMatcher.h
index 1d410947..b60621c9 100644
--- a/api/logic/pathmatcher/IPathMatcher.h
+++ b/api/logic/pathmatcher/IPathMatcher.h
@@ -4,9 +4,9 @@
class IPathMatcher
{
public:
- typedef std::shared_ptr<IPathMatcher> Ptr;
+ typedef std::shared_ptr<IPathMatcher> Ptr;
public:
- virtual ~IPathMatcher(){};
- virtual bool matches(const QString &string) const = 0;
+ virtual ~IPathMatcher(){};
+ virtual bool matches(const QString &string) const = 0;
};
diff --git a/api/logic/pathmatcher/MultiMatcher.h b/api/logic/pathmatcher/MultiMatcher.h
index 91f70aa4..8bc1b6ee 100644
--- a/api/logic/pathmatcher/MultiMatcher.h
+++ b/api/logic/pathmatcher/MultiMatcher.h
@@ -5,27 +5,27 @@
class MultiMatcher : public IPathMatcher
{
public:
- virtual ~MultiMatcher() {};
- MultiMatcher()
- {
- }
- MultiMatcher &add(Ptr add)
- {
- m_matchers.append(add);
- return *this;
- }
+ virtual ~MultiMatcher() {};
+ MultiMatcher()
+ {
+ }
+ MultiMatcher &add(Ptr add)
+ {
+ m_matchers.append(add);
+ return *this;
+ }
- virtual bool matches(const QString &string) const override
- {
- for(auto iter: m_matchers)
- {
- if(iter->matches(string))
- {
- return true;
- }
- }
- return false;
- }
+ virtual bool matches(const QString &string) const override
+ {
+ for(auto iter: m_matchers)
+ {
+ if(iter->matches(string))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
- QList<Ptr> m_matchers;
+ QList<Ptr> m_matchers;
};
diff --git a/api/logic/pathmatcher/RegexpMatcher.h b/api/logic/pathmatcher/RegexpMatcher.h
index da552123..825d488c 100644
--- a/api/logic/pathmatcher/RegexpMatcher.h
+++ b/api/logic/pathmatcher/RegexpMatcher.h
@@ -4,39 +4,39 @@
class RegexpMatcher : public IPathMatcher
{
public:
- virtual ~RegexpMatcher() {};
- RegexpMatcher(const QString &regexp)
- {
- m_regexp.setPattern(regexp);
- m_onlyFilenamePart = !regexp.contains('/');
- }
+ virtual ~RegexpMatcher() {};
+ RegexpMatcher(const QString &regexp)
+ {
+ m_regexp.setPattern(regexp);
+ m_onlyFilenamePart = !regexp.contains('/');
+ }
- RegexpMatcher &caseSensitive(bool cs = true)
- {
- if(cs)
- {
- m_regexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
- }
- else
- {
- m_regexp.setPatternOptions(QRegularExpression::NoPatternOption);
- }
- return *this;
- }
+ RegexpMatcher &caseSensitive(bool cs = true)
+ {
+ if(cs)
+ {
+ m_regexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
+ }
+ else
+ {
+ m_regexp.setPatternOptions(QRegularExpression::NoPatternOption);
+ }
+ return *this;
+ }
- virtual bool matches(const QString &string) const override
- {
- if(m_onlyFilenamePart)
- {
- auto slash = string.lastIndexOf('/');
- if(slash != -1)
- {
- auto part = string.mid(slash + 1);
- return m_regexp.match(part).hasMatch();
- }
- }
- return m_regexp.match(string).hasMatch();
- }
- QRegularExpression m_regexp;
- bool m_onlyFilenamePart = false;
+ virtual bool matches(const QString &string) const override
+ {
+ if(m_onlyFilenamePart)
+ {
+ auto slash = string.lastIndexOf('/');
+ if(slash != -1)
+ {
+ auto part = string.mid(slash + 1);
+ return m_regexp.match(part).hasMatch();
+ }
+ }
+ return m_regexp.match(string).hasMatch();
+ }
+ QRegularExpression m_regexp;
+ bool m_onlyFilenamePart = false;
};
diff --git a/api/logic/screenshots/ImgurAlbumCreation.cpp b/api/logic/screenshots/ImgurAlbumCreation.cpp
index 3724e3df..3d32f597 100644
--- a/api/logic/screenshots/ImgurAlbumCreation.cpp
+++ b/api/logic/screenshots/ImgurAlbumCreation.cpp
@@ -12,77 +12,77 @@
ImgurAlbumCreation::ImgurAlbumCreation(QList<ScreenshotPtr> screenshots) : NetAction(), m_screenshots(screenshots)
{
- m_url = URLConstants::IMGUR_BASE_URL + "album.json";
- m_status = Job_NotStarted;
+ m_url = URLConstants::IMGUR_BASE_URL + "album.json";
+ m_status = Job_NotStarted;
}
void ImgurAlbumCreation::start()
{
- m_status = Job_InProgress;
- QNetworkRequest request(m_url);
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
- request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3");
- request.setRawHeader("Accept", "application/json");
+ m_status = Job_InProgress;
+ QNetworkRequest request(m_url);
+ request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+ request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3");
+ request.setRawHeader("Accept", "application/json");
- QStringList hashes;
- for (auto shot : m_screenshots)
- {
- hashes.append(shot->m_imgurDeleteHash);
- }
+ QStringList hashes;
+ for (auto shot : m_screenshots)
+ {
+ hashes.append(shot->m_imgurDeleteHash);
+ }
- const QByteArray data = "deletehashes=" + hashes.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden";
+ const QByteArray data = "deletehashes=" + hashes.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden";
- QNetworkReply *rep = ENV.qnam().post(request, data);
+ QNetworkReply *rep = ENV.qnam().post(request, data);
- m_reply.reset(rep);
- connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress);
- connect(rep, &QNetworkReply::finished, this, &ImgurAlbumCreation::downloadFinished);
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError)));
+ m_reply.reset(rep);
+ connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress);
+ connect(rep, &QNetworkReply::finished, this, &ImgurAlbumCreation::downloadFinished);
+ connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError)));
}
void ImgurAlbumCreation::downloadError(QNetworkReply::NetworkError error)
{
- qDebug() << m_reply->errorString();
- m_status = Job_Failed;
+ qDebug() << m_reply->errorString();
+ m_status = Job_Failed;
}
void ImgurAlbumCreation::downloadFinished()
{
- if (m_status != Job_Failed)
- {
- QByteArray data = m_reply->readAll();
- m_reply.reset();
- QJsonParseError jsonError;
- QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- qDebug() << jsonError.errorString();
- emit failed(m_index_within_job);
- return;
- }
- auto object = doc.object();
- if (!object.value("success").toBool())
- {
- qDebug() << doc.toJson();
- emit failed(m_index_within_job);
- return;
- }
- m_deleteHash = object.value("data").toObject().value("deletehash").toString();
- m_id = object.value("data").toObject().value("id").toString();
- m_status = Job_Finished;
- emit succeeded(m_index_within_job);
- return;
- }
- else
- {
- qDebug() << m_reply->readAll();
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
+ if (m_status != Job_Failed)
+ {
+ QByteArray data = m_reply->readAll();
+ m_reply.reset();
+ QJsonParseError jsonError;
+ QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
+ if (jsonError.error != QJsonParseError::NoError)
+ {
+ qDebug() << jsonError.errorString();
+ emit failed(m_index_within_job);
+ return;
+ }
+ auto object = doc.object();
+ if (!object.value("success").toBool())
+ {
+ qDebug() << doc.toJson();
+ emit failed(m_index_within_job);
+ return;
+ }
+ m_deleteHash = object.value("data").toObject().value("deletehash").toString();
+ m_id = object.value("data").toObject().value("id").toString();
+ m_status = Job_Finished;
+ emit succeeded(m_index_within_job);
+ return;
+ }
+ else
+ {
+ qDebug() << m_reply->readAll();
+ m_reply.reset();
+ emit failed(m_index_within_job);
+ return;
+ }
}
void ImgurAlbumCreation::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
+ m_total_progress = bytesTotal;
+ m_progress = bytesReceived;
+ emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
}
diff --git a/api/logic/screenshots/ImgurAlbumCreation.h b/api/logic/screenshots/ImgurAlbumCreation.h
index 469174e4..55478021 100644
--- a/api/logic/screenshots/ImgurAlbumCreation.h
+++ b/api/logic/screenshots/ImgurAlbumCreation.h
@@ -8,37 +8,37 @@ typedef std::shared_ptr<class ImgurAlbumCreation> ImgurAlbumCreationPtr;
class MULTIMC_LOGIC_EXPORT ImgurAlbumCreation : public NetAction
{
public:
- explicit ImgurAlbumCreation(QList<ScreenshotPtr> screenshots);
- static ImgurAlbumCreationPtr make(QList<ScreenshotPtr> screenshots)
- {
- return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots));
- }
+ explicit ImgurAlbumCreation(QList<ScreenshotPtr> screenshots);
+ static ImgurAlbumCreationPtr make(QList<ScreenshotPtr> screenshots)
+ {
+ return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots));
+ }
- QString deleteHash() const
- {
- return m_deleteHash;
- }
- QString id() const
- {
- return m_id;
- }
+ QString deleteHash() const
+ {
+ return m_deleteHash;
+ }
+ QString id() const
+ {
+ return m_id;
+ }
protected
slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- virtual void downloadError(QNetworkReply::NetworkError error);
- virtual void downloadFinished();
- virtual void downloadReadyRead()
- {
- }
+ virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
+ virtual void downloadError(QNetworkReply::NetworkError error);
+ virtual void downloadFinished();
+ virtual void downloadReadyRead()
+ {
+ }
public
slots:
- virtual void start();
+ virtual void start();
private:
- QList<ScreenshotPtr> m_screenshots;
+ QList<ScreenshotPtr> m_screenshots;
- QString m_deleteHash;
- QString m_id;
+ QString m_deleteHash;
+ QString m_id;
};
diff --git a/api/logic/screenshots/ImgurUpload.cpp b/api/logic/screenshots/ImgurUpload.cpp
index 659879f6..74165869 100644
--- a/api/logic/screenshots/ImgurUpload.cpp
+++ b/api/logic/screenshots/ImgurUpload.cpp
@@ -14,101 +14,101 @@
ImgurUpload::ImgurUpload(ScreenshotPtr shot) : NetAction(), m_shot(shot)
{
- m_url = URLConstants::IMGUR_BASE_URL + "upload.json";
- m_status = Job_NotStarted;
+ m_url = URLConstants::IMGUR_BASE_URL + "upload.json";
+ m_status = Job_NotStarted;
}
void ImgurUpload::start()
{
- finished = false;
- m_status = Job_InProgress;
- QNetworkRequest request(m_url);
- request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
- request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3");
- request.setRawHeader("Accept", "application/json");
+ finished = false;
+ m_status = Job_InProgress;
+ QNetworkRequest request(m_url);
+ request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
+ request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3");
+ request.setRawHeader("Accept", "application/json");
- QFile f(m_shot->m_file.absoluteFilePath());
- if (!f.open(QFile::ReadOnly))
- {
- emit failed(m_index_within_job);
- return;
- }
+ QFile f(m_shot->m_file.absoluteFilePath());
+ if (!f.open(QFile::ReadOnly))
+ {
+ emit failed(m_index_within_job);
+ return;
+ }
- QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
- QHttpPart filePart;
- filePart.setBody(f.readAll().toBase64());
- filePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png");
- filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"image\"");
- multipart->append(filePart);
- QHttpPart typePart;
- typePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"type\"");
- typePart.setBody("base64");
- multipart->append(typePart);
- QHttpPart namePart;
- namePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"name\"");
- namePart.setBody(m_shot->m_file.baseName().toUtf8());
- multipart->append(namePart);
+ QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
+ QHttpPart filePart;
+ filePart.setBody(f.readAll().toBase64());
+ filePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png");
+ filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"image\"");
+ multipart->append(filePart);
+ QHttpPart typePart;
+ typePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"type\"");
+ typePart.setBody("base64");
+ multipart->append(typePart);
+ QHttpPart namePart;
+ namePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"name\"");
+ namePart.setBody(m_shot->m_file.baseName().toUtf8());
+ multipart->append(namePart);
- QNetworkReply *rep = ENV.qnam().post(request, multipart);
+ QNetworkReply *rep = ENV.qnam().post(request, multipart);
- m_reply.reset(rep);
- connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress);
- connect(rep, &QNetworkReply::finished, this, &ImgurUpload::downloadFinished);
- connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
- SLOT(downloadError(QNetworkReply::NetworkError)));
+ m_reply.reset(rep);
+ connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress);
+ connect(rep, &QNetworkReply::finished, this, &ImgurUpload::downloadFinished);
+ connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
+ SLOT(downloadError(QNetworkReply::NetworkError)));
}
void ImgurUpload::downloadError(QNetworkReply::NetworkError error)
{
- qCritical() << "ImgurUpload failed with error" << m_reply->errorString() << "Server reply:\n" << m_reply->readAll();
- if(finished)
- {
- qCritical() << "Double finished ImgurUpload!";
- return;
- }
- m_status = Job_Failed;
- finished = true;
- m_reply.reset();
- emit failed(m_index_within_job);
+ qCritical() << "ImgurUpload failed with error" << m_reply->errorString() << "Server reply:\n" << m_reply->readAll();
+ if(finished)
+ {
+ qCritical() << "Double finished ImgurUpload!";
+ return;
+ }
+ m_status = Job_Failed;
+ finished = true;
+ m_reply.reset();
+ emit failed(m_index_within_job);
}
void ImgurUpload::downloadFinished()
{
- if(finished)
- {
- qCritical() << "Double finished ImgurUpload!";
- return;
- }
- QByteArray data = m_reply->readAll();
- m_reply.reset();
- QJsonParseError jsonError;
- QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- qDebug() << "imgur server did not reply with JSON" << jsonError.errorString();
- finished = true;
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
- auto object = doc.object();
- if (!object.value("success").toBool())
- {
- qDebug() << "Screenshot upload not successful:" << doc.toJson();
- finished = true;
- m_reply.reset();
- emit failed(m_index_within_job);
- return;
- }
- m_shot->m_imgurId = object.value("data").toObject().value("id").toString();
- m_shot->m_url = object.value("data").toObject().value("link").toString();
- m_shot->m_imgurDeleteHash = object.value("data").toObject().value("deletehash").toString();
- m_status = Job_Finished;
- finished = true;
- emit succeeded(m_index_within_job);
- return;
+ if(finished)
+ {
+ qCritical() << "Double finished ImgurUpload!";
+ return;
+ }
+ QByteArray data = m_reply->readAll();
+ m_reply.reset();
+ QJsonParseError jsonError;
+ QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
+ if (jsonError.error != QJsonParseError::NoError)
+ {
+ qDebug() << "imgur server did not reply with JSON" << jsonError.errorString();
+ finished = true;
+ m_reply.reset();
+ emit failed(m_index_within_job);
+ return;
+ }
+ auto object = doc.object();
+ if (!object.value("success").toBool())
+ {
+ qDebug() << "Screenshot upload not successful:" << doc.toJson();
+ finished = true;
+ m_reply.reset();
+ emit failed(m_index_within_job);
+ return;
+ }
+ m_shot->m_imgurId = object.value("data").toObject().value("id").toString();
+ m_shot->m_url = object.value("data").toObject().value("link").toString();
+ m_shot->m_imgurDeleteHash = object.value("data").toObject().value("deletehash").toString();
+ m_status = Job_Finished;
+ finished = true;
+ emit succeeded(m_index_within_job);
+ return;
}
void ImgurUpload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
- m_total_progress = bytesTotal;
- m_progress = bytesReceived;
- emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
+ m_total_progress = bytesTotal;
+ m_progress = bytesReceived;
+ emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal);
}
diff --git a/api/logic/screenshots/ImgurUpload.h b/api/logic/screenshots/ImgurUpload.h
index 0a766b8f..d79807f2 100644
--- a/api/logic/screenshots/ImgurUpload.h
+++ b/api/logic/screenshots/ImgurUpload.h
@@ -8,26 +8,26 @@ typedef std::shared_ptr<class ImgurUpload> ImgurUploadPtr;
class MULTIMC_LOGIC_EXPORT ImgurUpload : public NetAction
{
public:
- explicit ImgurUpload(ScreenshotPtr shot);
- static ImgurUploadPtr make(ScreenshotPtr shot)
- {
- return ImgurUploadPtr(new ImgurUpload(shot));
- }
+ explicit ImgurUpload(ScreenshotPtr shot);
+ static ImgurUploadPtr make(ScreenshotPtr shot)
+ {
+ return ImgurUploadPtr(new ImgurUpload(shot));
+ }
protected
slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- virtual void downloadError(QNetworkReply::NetworkError error);
- virtual void downloadFinished();
- virtual void downloadReadyRead()
- {
- }
+ virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
+ virtual void downloadError(QNetworkReply::NetworkError error);
+ virtual void downloadFinished();
+ virtual void downloadReadyRead()
+ {
+ }
public
slots:
- virtual void start();
+ virtual void start();
private:
- ScreenshotPtr m_shot;
- bool finished = true;
+ ScreenshotPtr m_shot;
+ bool finished = true;
};
diff --git a/api/logic/screenshots/Screenshot.h b/api/logic/screenshots/Screenshot.h
index 2c70ecf5..9db3a8a1 100644
--- a/api/logic/screenshots/Screenshot.h
+++ b/api/logic/screenshots/Screenshot.h
@@ -7,14 +7,14 @@
struct ScreenShot
{
- ScreenShot(QFileInfo file)
- {
- m_file = file;
- }
- QFileInfo m_file;
- QString m_url;
- QString m_imgurId;
- QString m_imgurDeleteHash;
+ ScreenShot(QFileInfo file)
+ {
+ m_file = file;
+ }
+ QFileInfo m_file;
+ QString m_url;
+ QString m_imgurId;
+ QString m_imgurDeleteHash;
};
typedef std::shared_ptr<ScreenShot> ScreenshotPtr;
diff --git a/api/logic/settings/INIFile.cpp b/api/logic/settings/INIFile.cpp
index 67c6cf29..5431443e 100644
--- a/api/logic/settings/INIFile.cpp
+++ b/api/logic/settings/INIFile.cpp
@@ -28,124 +28,124 @@ INIFile::INIFile()
QString INIFile::unescape(QString orig)
{
- QString out;
- QChar prev = 0;
- for(auto c: orig)
- {
- if(prev == '\\')
- {
- if(c == 'n')
- out += '\n';
- else if (c == 't')
- out += '\t';
- else
- out += c;
- prev = 0;
- }
- else
- {
- if(c == '\\')
- {
- prev = c;
- continue;
- }
- out += c;
- prev = 0;
- }
- }
- return out;
+ QString out;
+ QChar prev = 0;
+ for(auto c: orig)
+ {
+ if(prev == '\\')
+ {
+ if(c == 'n')
+ out += '\n';
+ else if (c == 't')
+ out += '\t';
+ else
+ out += c;
+ prev = 0;
+ }
+ else
+ {
+ if(c == '\\')
+ {
+ prev = c;
+ continue;
+ }
+ out += c;
+ prev = 0;
+ }
+ }
+ return out;
}
QString INIFile::escape(QString orig)
{
- QString out;
- for(auto c: orig)
- {
- if(c == '\n')
- out += "\\n";
- else if (c == '\t')
- out += "\\t";
- else if(c == '\\')
- out += "\\\\";
- else
- out += c;
- }
- return out;
+ QString out;
+ for(auto c: orig)
+ {
+ if(c == '\n')
+ out += "\\n";
+ else if (c == '\t')
+ out += "\\t";
+ else if(c == '\\')
+ out += "\\\\";
+ else
+ out += c;
+ }
+ return out;
}
bool INIFile::saveFile(QString fileName)
{
- QByteArray outArray;
- for (Iterator iter = begin(); iter != end(); iter++)
- {
- QString value = iter.value().toString();
- value = escape(value);
- outArray.append(iter.key().toUtf8());
- outArray.append('=');
- outArray.append(value.toUtf8());
- outArray.append('\n');
- }
-
- try
- {
- FS::write(fileName, outArray);
- }
- catch (const Exception &e)
- {
- qCritical() << e.what();
- return false;
- }
-
- return true;
+ QByteArray outArray;
+ for (Iterator iter = begin(); iter != end(); iter++)
+ {
+ QString value = iter.value().toString();
+ value = escape(value);
+ outArray.append(iter.key().toUtf8());
+ outArray.append('=');
+ outArray.append(value.toUtf8());
+ outArray.append('\n');
+ }
+
+ try
+ {
+ FS::write(fileName, outArray);
+ }
+ catch (const Exception &e)
+ {
+ qCritical() << e.what();
+ return false;
+ }
+
+ return true;
}
bool INIFile::loadFile(QString fileName)
{
- QFile file(fileName);
- if (!file.open(QIODevice::ReadOnly))
- return false;
- bool success = loadFile(file.readAll());
- file.close();
- return success;
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly))
+ return false;
+ bool success = loadFile(file.readAll());
+ file.close();
+ return success;
}
bool INIFile::loadFile(QByteArray file)
{
- QTextStream in(file);
- in.setCodec("UTF-8");
+ QTextStream in(file);
+ in.setCodec("UTF-8");
- QStringList lines = in.readAll().split('\n');
- for (int i = 0; i < lines.count(); i++)
- {
- QString &lineRaw = lines[i];
- // Ignore comments.
- QString line = lineRaw.left(lineRaw.indexOf('#')).trimmed();
+ QStringList lines = in.readAll().split('\n');
+ for (int i = 0; i < lines.count(); i++)
+ {
+ QString &lineRaw = lines[i];
+ // Ignore comments.
+ QString line = lineRaw.left(lineRaw.indexOf('#')).trimmed();
- int eqPos = line.indexOf('=');
- if (eqPos == -1)
- continue;
- QString key = line.left(eqPos).trimmed();
- QString valueStr = line.right(line.length() - eqPos - 1).trimmed();
+ int eqPos = line.indexOf('=');
+ if (eqPos == -1)
+ continue;
+ QString key = line.left(eqPos).trimmed();
+ QString valueStr = line.right(line.length() - eqPos - 1).trimmed();
- valueStr = unescape(valueStr);
+ valueStr = unescape(valueStr);
- QVariant value(valueStr);
- this->operator[](key) = value;
- }
+ QVariant value(valueStr);
+ this->operator[](key) = value;
+ }
- return true;
+ return true;
}
QVariant INIFile::get(QString key, QVariant def) const
{
- if (!this->contains(key))
- return def;
- else
- return this->operator[](key);
+ if (!this->contains(key))
+ return def;
+ else
+ return this->operator[](key);
}
void INIFile::set(QString key, QVariant val)
{
- this->operator[](key) = val;
+ this->operator[](key) = val;
}
diff --git a/api/logic/settings/INIFile.h b/api/logic/settings/INIFile.h
index f0c63d3c..bdf7fd9a 100644
--- a/api/logic/settings/INIFile.h
+++ b/api/logic/settings/INIFile.h
@@ -25,14 +25,14 @@
class MULTIMC_LOGIC_EXPORT INIFile : public QMap<QString, QVariant>
{
public:
- explicit INIFile();
+ explicit INIFile();
- bool loadFile(QByteArray file);
- bool loadFile(QString fileName);
- bool saveFile(QString fileName);
+ bool loadFile(QByteArray file);
+ bool loadFile(QString fileName);
+ bool saveFile(QString fileName);
- QVariant get(QString key, QVariant def) const;
- void set(QString key, QVariant val);
- static QString unescape(QString orig);
- static QString escape(QString orig);
+ QVariant get(QString key, QVariant def) const;
+ void set(QString key, QVariant val);
+ static QString unescape(QString orig);
+ static QString escape(QString orig);
};
diff --git a/api/logic/settings/INIFile_test.cpp b/api/logic/settings/INIFile_test.cpp
index b3ae7375..45f70973 100644
--- a/api/logic/settings/INIFile_test.cpp
+++ b/api/logic/settings/INIFile_test.cpp
@@ -5,56 +5,56 @@
class IniFileTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- void initTestCase()
- {
-
- }
- void cleanupTestCase()
- {
-
- }
-
- void test_Escape_data()
- {
- QTest::addColumn<QString>("through");
-
- QTest::newRow("unix path") << "/abc/def/ghi/jkl";
- QTest::newRow("windows path") << "C:\\Program files\\terrible\\name\\of something\\";
- QTest::newRow("Plain text") << "Lorem ipsum dolor sit amet.";
- QTest::newRow("Escape sequences") << "Lorem\n\t\n\\n\\tAAZ\nipsum dolor\n\nsit amet.";
- QTest::newRow("Escape sequences 2") << "\"\n\n\"";
- }
- void test_Escape()
- {
- QFETCH(QString, through);
-
- QString there = INIFile::escape(through);
- QString back = INIFile::unescape(there);
-
- QCOMPARE(back, through);
- }
-
- void test_SaveLoad()
- {
- QString a = "a";
- QString b = "a\nb\t\n\\\\\\C:\\Program files\\terrible\\name\\of something\\";
- QString filename = "test_SaveLoad.ini";
-
- // save
- INIFile f;
- f.set("a", a);
- f.set("b", b);
- f.saveFile(filename);
-
- // load
- INIFile f2;
- f2.loadFile(filename);
- QCOMPARE(a, f2.get("a","NOT SET").toString());
- QCOMPARE(b, f2.get("b","NOT SET").toString());
- }
+ void initTestCase()
+ {
+
+ }
+ void cleanupTestCase()
+ {
+
+ }
+
+ void test_Escape_data()
+ {
+ QTest::addColumn<QString>("through");
+
+ QTest::newRow("unix path") << "/abc/def/ghi/jkl";
+ QTest::newRow("windows path") << "C:\\Program files\\terrible\\name\\of something\\";
+ QTest::newRow("Plain text") << "Lorem ipsum dolor sit amet.";
+ QTest::newRow("Escape sequences") << "Lorem\n\t\n\\n\\tAAZ\nipsum dolor\n\nsit amet.";
+ QTest::newRow("Escape sequences 2") << "\"\n\n\"";
+ }
+ void test_Escape()
+ {
+ QFETCH(QString, through);
+
+ QString there = INIFile::escape(through);
+ QString back = INIFile::unescape(there);
+
+ QCOMPARE(back, through);
+ }
+
+ void test_SaveLoad()
+ {
+ QString a = "a";
+ QString b = "a\nb\t\n\\\\\\C:\\Program files\\terrible\\name\\of something\\";
+ QString filename = "test_SaveLoad.ini";
+
+ // save
+ INIFile f;
+ f.set("a", a);
+ f.set("b", b);
+ f.saveFile(filename);
+
+ // load
+ INIFile f2;
+ f2.loadFile(filename);
+ QCOMPARE(a, f2.get("a","NOT SET").toString());
+ QCOMPARE(b, f2.get("b","NOT SET").toString());
+ }
};
QTEST_GUILESS_MAIN(IniFileTest)
diff --git a/api/logic/settings/INISettingsObject.cpp b/api/logic/settings/INISettingsObject.cpp
index ff2cee31..43791c24 100644
--- a/api/logic/settings/INISettingsObject.cpp
+++ b/api/logic/settings/INISettingsObject.cpp
@@ -17,91 +17,91 @@
#include "Setting.h"
INISettingsObject::INISettingsObject(const QString &path, QObject *parent)
- : SettingsObject(parent)
+ : SettingsObject(parent)
{
- m_filePath = path;
- m_ini.loadFile(path);
+ m_filePath = path;
+ m_ini.loadFile(path);
}
void INISettingsObject::setFilePath(const QString &filePath)
{
- m_filePath = filePath;
+ m_filePath = filePath;
}
bool INISettingsObject::reload()
{
- return m_ini.loadFile(m_filePath) && SettingsObject::reload();
+ return m_ini.loadFile(m_filePath) && SettingsObject::reload();
}
void INISettingsObject::suspendSave()
{
- m_suspendSave = true;
+ m_suspendSave = true;
}
void INISettingsObject::resumeSave()
{
- m_suspendSave = false;
- if(m_doSave)
- {
- m_ini.saveFile(m_filePath);
- }
+ m_suspendSave = false;
+ if(m_doSave)
+ {
+ m_ini.saveFile(m_filePath);
+ }
}
void INISettingsObject::changeSetting(const Setting &setting, QVariant value)
{
- if (contains(setting.id()))
- {
- // valid value -> set the main config, remove all the sysnonyms
- if (value.isValid())
- {
- auto list = setting.configKeys();
- m_ini.set(list.takeFirst(), value);
- for(auto iter: list)
- m_ini.remove(iter);
- }
- // invalid -> remove all (just like resetSetting)
- else
- {
- for(auto iter: setting.configKeys())
- m_ini.remove(iter);
- }
- doSave();
- }
+ if (contains(setting.id()))
+ {
+ // valid value -> set the main config, remove all the sysnonyms
+ if (value.isValid())
+ {
+ auto list = setting.configKeys();
+ m_ini.set(list.takeFirst(), value);
+ for(auto iter: list)
+ m_ini.remove(iter);
+ }
+ // invalid -> remove all (just like resetSetting)
+ else
+ {
+ for(auto iter: setting.configKeys())
+ m_ini.remove(iter);
+ }
+ doSave();
+ }
}
void INISettingsObject::doSave()
{
- if(m_suspendSave)
- {
- m_doSave = true;
- }
- else
- {
- m_ini.saveFile(m_filePath);
- }
+ if(m_suspendSave)
+ {
+ m_doSave = true;
+ }
+ else
+ {
+ m_ini.saveFile(m_filePath);
+ }
}
void INISettingsObject::resetSetting(const Setting &setting)
{
- // if we have the setting, remove all the synonyms. ALL OF THEM
- if (contains(setting.id()))
- {
- for(auto iter: setting.configKeys())
- m_ini.remove(iter);
- doSave();
- }
+ // if we have the setting, remove all the synonyms. ALL OF THEM
+ if (contains(setting.id()))
+ {
+ for(auto iter: setting.configKeys())
+ m_ini.remove(iter);
+ doSave();
+ }
}
QVariant INISettingsObject::retrieveValue(const Setting &setting)
{
- // if we have the setting, return value of the first matching synonym
- if (contains(setting.id()))
- {
- for(auto iter: setting.configKeys())
- {
- if(m_ini.contains(iter))
- return m_ini[iter];
- }
- }
- return QVariant();
+ // if we have the setting, return value of the first matching synonym
+ if (contains(setting.id()))
+ {
+ for(auto iter: setting.configKeys())
+ {
+ if(m_ini.contains(iter))
+ return m_ini[iter];
+ }
+ }
+ return QVariant();
}
diff --git a/api/logic/settings/INISettingsObject.h b/api/logic/settings/INISettingsObject.h
index 111215e6..3fc09593 100644
--- a/api/logic/settings/INISettingsObject.h
+++ b/api/logic/settings/INISettingsObject.h
@@ -28,39 +28,39 @@
*/
class MULTIMC_LOGIC_EXPORT INISettingsObject : public SettingsObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit INISettingsObject(const QString &path, QObject *parent = 0);
+ explicit INISettingsObject(const QString &path, QObject *parent = 0);
- /*!
- * \brief Gets the path to the INI file.
- * \return The path to the INI file.
- */
- virtual QString filePath() const
- {
- return m_filePath;
- }
+ /*!
+ * \brief Gets the path to the INI file.
+ * \return The path to the INI file.
+ */
+ virtual QString filePath() const
+ {
+ return m_filePath;
+ }
- /*!
- * \brief Sets the path to the INI file and reloads it.
- * \param filePath The INI file's new path.
- */
- virtual void setFilePath(const QString &filePath);
+ /*!
+ * \brief Sets the path to the INI file and reloads it.
+ * \param filePath The INI file's new path.
+ */
+ virtual void setFilePath(const QString &filePath);
- bool reload() override;
+ bool reload() override;
- void suspendSave() override;
- void resumeSave() override;
+ void suspendSave() override;
+ void resumeSave() override;
protected slots:
- virtual void changeSetting(const Setting &setting, QVariant value) override;
- virtual void resetSetting(const Setting &setting) override;
+ virtual void changeSetting(const Setting &setting, QVariant value) override;
+ virtual void resetSetting(const Setting &setting) override;
protected:
- virtual QVariant retrieveValue(const Setting &setting) override;
- void doSave();
+ virtual QVariant retrieveValue(const Setting &setting) override;
+ void doSave();
protected:
- INIFile m_ini;
- QString m_filePath;
+ INIFile m_ini;
+ QString m_filePath;
};
diff --git a/api/logic/settings/OverrideSetting.cpp b/api/logic/settings/OverrideSetting.cpp
index a3d48e03..e0e407bd 100644
--- a/api/logic/settings/OverrideSetting.cpp
+++ b/api/logic/settings/OverrideSetting.cpp
@@ -16,39 +16,39 @@
#include "OverrideSetting.h"
OverrideSetting::OverrideSetting(std::shared_ptr<Setting> other, std::shared_ptr<Setting> gate)
- : Setting(other->configKeys(), QVariant())
+ : Setting(other->configKeys(), QVariant())
{
- Q_ASSERT(other);
- Q_ASSERT(gate);
- m_other = other;
- m_gate = gate;
+ Q_ASSERT(other);
+ Q_ASSERT(gate);
+ m_other = other;
+ m_gate = gate;
}
bool OverrideSetting::isOverriding() const
{
- return m_gate->get().toBool();
+ return m_gate->get().toBool();
}
QVariant OverrideSetting::defValue() const
{
- return m_other->get();
+ return m_other->get();
}
QVariant OverrideSetting::get() const
{
- if(isOverriding())
- {
- return Setting::get();
- }
- return m_other->get();
+ if(isOverriding())
+ {
+ return Setting::get();
+ }
+ return m_other->get();
}
void OverrideSetting::reset()
{
- Setting::reset();
+ Setting::reset();
}
void OverrideSetting::set(QVariant value)
{
- Setting::set(value);
+ Setting::set(value);
}
diff --git a/api/logic/settings/OverrideSetting.h b/api/logic/settings/OverrideSetting.h
index f2cbc5dc..db28e2fc 100644
--- a/api/logic/settings/OverrideSetting.h
+++ b/api/logic/settings/OverrideSetting.h
@@ -28,19 +28,19 @@
*/
class OverrideSetting : public Setting
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit OverrideSetting(std::shared_ptr<Setting> overriden, std::shared_ptr<Setting> gate);
+ explicit OverrideSetting(std::shared_ptr<Setting> overriden, std::shared_ptr<Setting> gate);
- virtual QVariant defValue() const;
- virtual QVariant get() const;
- virtual void set (QVariant value);
- virtual void reset();
+ virtual QVariant defValue() const;
+ virtual QVariant get() const;
+ virtual void set (QVariant value);
+ virtual void reset();
private:
- bool isOverriding() const;
+ bool isOverriding() const;
protected:
- std::shared_ptr<Setting> m_other;
- std::shared_ptr<Setting> m_gate;
+ std::shared_ptr<Setting> m_other;
+ std::shared_ptr<Setting> m_gate;
};
diff --git a/api/logic/settings/PassthroughSetting.cpp b/api/logic/settings/PassthroughSetting.cpp
index 5da5d11c..58522385 100644
--- a/api/logic/settings/PassthroughSetting.cpp
+++ b/api/logic/settings/PassthroughSetting.cpp
@@ -16,54 +16,54 @@
#include "PassthroughSetting.h"
PassthroughSetting::PassthroughSetting(std::shared_ptr<Setting> other, std::shared_ptr<Setting> gate)
- : Setting(other->configKeys(), QVariant())
+ : Setting(other->configKeys(), QVariant())
{
- Q_ASSERT(other);
- m_other = other;
- m_gate = gate;
+ Q_ASSERT(other);
+ m_other = other;
+ m_gate = gate;
}
bool PassthroughSetting::isOverriding() const
{
- if(!m_gate)
- {
- return false;
- }
- return m_gate->get().toBool();
+ if(!m_gate)
+ {
+ return false;
+ }
+ return m_gate->get().toBool();
}
QVariant PassthroughSetting::defValue() const
{
- if(isOverriding())
- {
- return m_other->get();
- }
- return m_other->defValue();
+ if(isOverriding())
+ {
+ return m_other->get();
+ }
+ return m_other->defValue();
}
QVariant PassthroughSetting::get() const
{
- if(isOverriding())
- {
- return Setting::get();
- }
- return m_other->get();
+ if(isOverriding())
+ {
+ return Setting::get();
+ }
+ return m_other->get();
}
void PassthroughSetting::reset()
{
- if(isOverriding())
- {
- Setting::reset();
- }
- m_other->reset();
+ if(isOverriding())
+ {
+ Setting::reset();
+ }
+ m_other->reset();
}
void PassthroughSetting::set(QVariant value)
{
- if(isOverriding())
- {
- Setting::set(value);
- }
- m_other->set(value);
+ if(isOverriding())
+ {
+ Setting::set(value);
+ }
+ m_other->set(value);
}
diff --git a/api/logic/settings/PassthroughSetting.h b/api/logic/settings/PassthroughSetting.h
index ee844da4..7999be97 100644
--- a/api/logic/settings/PassthroughSetting.h
+++ b/api/logic/settings/PassthroughSetting.h
@@ -27,19 +27,19 @@
*/
class PassthroughSetting : public Setting
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit PassthroughSetting(std::shared_ptr<Setting> overriden, std::shared_ptr<Setting> gate);
+ explicit PassthroughSetting(std::shared_ptr<Setting> overriden, std::shared_ptr<Setting> gate);
- virtual QVariant defValue() const;
- virtual QVariant get() const;
- virtual void set (QVariant value);
- virtual void reset();
+ virtual QVariant defValue() const;
+ virtual QVariant get() const;
+ virtual void set (QVariant value);
+ virtual void reset();
private:
- bool isOverriding() const;
+ bool isOverriding() const;
protected:
- std::shared_ptr<Setting> m_other;
- std::shared_ptr<Setting> m_gate;
+ std::shared_ptr<Setting> m_other;
+ std::shared_ptr<Setting> m_gate;
};
diff --git a/api/logic/settings/Setting.cpp b/api/logic/settings/Setting.cpp
index fa0041e0..8bb42f5e 100644
--- a/api/logic/settings/Setting.cpp
+++ b/api/logic/settings/Setting.cpp
@@ -17,37 +17,37 @@
#include "settings/SettingsObject.h"
Setting::Setting(QStringList synonyms, QVariant defVal)
- : QObject(), m_synonyms(synonyms), m_defVal(defVal)
+ : QObject(), m_synonyms(synonyms), m_defVal(defVal)
{
}
QVariant Setting::get() const
{
- SettingsObject *sbase = m_storage;
- if (!sbase)
- {
- return defValue();
- }
- else
- {
- QVariant test = sbase->retrieveValue(*this);
- if (!test.isValid())
- return defValue();
- return test;
- }
+ SettingsObject *sbase = m_storage;
+ if (!sbase)
+ {
+ return defValue();
+ }
+ else
+ {
+ QVariant test = sbase->retrieveValue(*this);
+ if (!test.isValid())
+ return defValue();
+ return test;
+ }
}
QVariant Setting::defValue() const
{
- return m_defVal;
+ return m_defVal;
}
void Setting::set(QVariant value)
{
- emit SettingChanged(*this, value);
+ emit SettingChanged(*this, value);
}
void Setting::reset()
{
- emit settingReset(*this);
+ emit settingReset(*this);
}
diff --git a/api/logic/settings/Setting.h b/api/logic/settings/Setting.h
index 3edea7be..0e9224c5 100644
--- a/api/logic/settings/Setting.h
+++ b/api/logic/settings/Setting.h
@@ -29,91 +29,91 @@ class SettingsObject;
*/
class MULTIMC_LOGIC_EXPORT Setting : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- /**
- * Construct a Setting
- *
- * Synonyms are all the possible names used in the settings object, in order of preference.
- * First synonym is the ID, which identifies the setting in MultiMC.
- *
- * defVal is the default value that will be returned when the settings object
- * doesn't have any value for this setting.
- */
- explicit Setting(QStringList synonyms, QVariant defVal = QVariant());
+ /**
+ * Construct a Setting
+ *
+ * Synonyms are all the possible names used in the settings object, in order of preference.
+ * First synonym is the ID, which identifies the setting in MultiMC.
+ *
+ * defVal is the default value that will be returned when the settings object
+ * doesn't have any value for this setting.
+ */
+ explicit Setting(QStringList synonyms, QVariant defVal = QVariant());
- /*!
- * \brief Gets this setting's ID.
- * This is used to refer to the setting within the application.
- * \warning Changing the ID while the setting is registered with a SettingsObject results in
- * undefined behavior.
- * \return The ID of the setting.
- */
- virtual QString id() const
- {
- return m_synonyms.first();
- }
+ /*!
+ * \brief Gets this setting's ID.
+ * This is used to refer to the setting within the application.
+ * \warning Changing the ID while the setting is registered with a SettingsObject results in
+ * undefined behavior.
+ * \return The ID of the setting.
+ */
+ virtual QString id() const
+ {
+ return m_synonyms.first();
+ }
- /*!
- * \brief Gets this setting's config file key.
- * This is used to store the setting's value in the config file. It is usually
- * the same as the setting's ID, but it can be different.
- * \return The setting's config file key.
- */
- virtual QStringList configKeys() const
- {
- return m_synonyms;
- }
+ /*!
+ * \brief Gets this setting's config file key.
+ * This is used to store the setting's value in the config file. It is usually
+ * the same as the setting's ID, but it can be different.
+ * \return The setting's config file key.
+ */
+ virtual QStringList configKeys() const
+ {
+ return m_synonyms;
+ }
- /*!
- * \brief Gets this setting's value as a QVariant.
- * This is done by calling the SettingsObject's retrieveValue() function.
- * If this Setting doesn't have a SettingsObject, this returns an invalid QVariant.
- * \return QVariant containing this setting's value.
- * \sa value()
- */
- virtual QVariant get() const;
+ /*!
+ * \brief Gets this setting's value as a QVariant.
+ * This is done by calling the SettingsObject's retrieveValue() function.
+ * If this Setting doesn't have a SettingsObject, this returns an invalid QVariant.
+ * \return QVariant containing this setting's value.
+ * \sa value()
+ */
+ virtual QVariant get() const;
- /*!
- * \brief Gets this setting's default value.
- * \return The default value of this setting.
- */
- virtual QVariant defValue() const;
+ /*!
+ * \brief Gets this setting's default value.
+ * \return The default value of this setting.
+ */
+ virtual QVariant defValue() const;
signals:
- /*!
- * \brief Signal emitted when this Setting object's value changes.
- * \param setting A reference to the Setting that changed.
- * \param value This Setting object's new value.
- */
- void SettingChanged(const Setting &setting, QVariant value);
+ /*!
+ * \brief Signal emitted when this Setting object's value changes.
+ * \param setting A reference to the Setting that changed.
+ * \param value This Setting object's new value.
+ */
+ void SettingChanged(const Setting &setting, QVariant value);
- /*!
- * \brief Signal emitted when this Setting object's value resets to default.
- * \param setting A reference to the Setting that changed.
- */
- void settingReset(const Setting &setting);
+ /*!
+ * \brief Signal emitted when this Setting object's value resets to default.
+ * \param setting A reference to the Setting that changed.
+ */
+ void settingReset(const Setting &setting);
public
slots:
- /*!
- * \brief Changes the setting's value.
- * This is done by emitting the SettingChanged() signal which will then be
- * handled by the SettingsObject object and cause the setting to change.
- * \param value The new value.
- */
- virtual void set(QVariant value);
+ /*!
+ * \brief Changes the setting's value.
+ * This is done by emitting the SettingChanged() signal which will then be
+ * handled by the SettingsObject object and cause the setting to change.
+ * \param value The new value.
+ */
+ virtual void set(QVariant value);
- /*!
- * \brief Reset the setting to default
- * This is done by emitting the settingReset() signal which will then be
- * handled by the SettingsObject object and cause the setting to change.
- */
- virtual void reset();
+ /*!
+ * \brief Reset the setting to default
+ * This is done by emitting the settingReset() signal which will then be
+ * handled by the SettingsObject object and cause the setting to change.
+ */
+ virtual void reset();
protected:
- friend class SettingsObject;
- SettingsObject * m_storage;
- QStringList m_synonyms;
- QVariant m_defVal;
+ friend class SettingsObject;
+ SettingsObject * m_storage;
+ QStringList m_synonyms;
+ QVariant m_defVal;
};
diff --git a/api/logic/settings/SettingsObject.cpp b/api/logic/settings/SettingsObject.cpp
index 87a8c2a8..d1851415 100644
--- a/api/logic/settings/SettingsObject.cpp
+++ b/api/logic/settings/SettingsObject.cpp
@@ -27,116 +27,116 @@ SettingsObject::SettingsObject(QObject *parent) : QObject(parent)
SettingsObject::~SettingsObject()
{
- m_settings.clear();
+ m_settings.clear();
}
std::shared_ptr<Setting> SettingsObject::registerOverride(std::shared_ptr<Setting> original,
- std::shared_ptr<Setting> gate)
+ std::shared_ptr<Setting> gate)
{
- if (contains(original->id()))
- {
- qCritical() << QString("Failed to register setting %1. ID already exists.")
- .arg(original->id());
- return nullptr; // Fail
- }
- auto override = std::make_shared<OverrideSetting>(original, gate);
- override->m_storage = this;
- connectSignals(*override);
- m_settings.insert(override->id(), override);
- return override;
+ if (contains(original->id()))
+ {
+ qCritical() << QString("Failed to register setting %1. ID already exists.")
+ .arg(original->id());
+ return nullptr; // Fail
+ }
+ auto override = std::make_shared<OverrideSetting>(original, gate);
+ override->m_storage = this;
+ connectSignals(*override);
+ m_settings.insert(override->id(), override);
+ return override;
}
std::shared_ptr<Setting> SettingsObject::registerPassthrough(std::shared_ptr<Setting> original,
- std::shared_ptr<Setting> gate)
+ std::shared_ptr<Setting> gate)
{
- if (contains(original->id()))
- {
- qCritical() << QString("Failed to register setting %1. ID already exists.")
- .arg(original->id());
- return nullptr; // Fail
- }
- auto passthrough = std::make_shared<PassthroughSetting>(original, gate);
- passthrough->m_storage = this;
- connectSignals(*passthrough);
- m_settings.insert(passthrough->id(), passthrough);
- return passthrough;
+ if (contains(original->id()))
+ {
+ qCritical() << QString("Failed to register setting %1. ID already exists.")
+ .arg(original->id());
+ return nullptr; // Fail
+ }
+ auto passthrough = std::make_shared<PassthroughSetting>(original, gate);
+ passthrough->m_storage = this;
+ connectSignals(*passthrough);
+ m_settings.insert(passthrough->id(), passthrough);
+ return passthrough;
}
std::shared_ptr<Setting> SettingsObject::registerSetting(QStringList synonyms, QVariant defVal)
{
- if (synonyms.empty())
- return nullptr;
- if (contains(synonyms.first()))
- {
- qCritical() << QString("Failed to register setting %1. ID already exists.")
- .arg(synonyms.first());
- return nullptr; // Fail
- }
- auto setting = std::make_shared<Setting>(synonyms, defVal);
- setting->m_storage = this;
- connectSignals(*setting);
- m_settings.insert(setting->id(), setting);
- return setting;
+ if (synonyms.empty())
+ return nullptr;
+ if (contains(synonyms.first()))
+ {
+ qCritical() << QString("Failed to register setting %1. ID already exists.")
+ .arg(synonyms.first());
+ return nullptr; // Fail
+ }
+ auto setting = std::make_shared<Setting>(synonyms, defVal);
+ setting->m_storage = this;
+ connectSignals(*setting);
+ m_settings.insert(setting->id(), setting);
+ return setting;
}
std::shared_ptr<Setting> SettingsObject::getSetting(const QString &id) const
{
- // Make sure there is a setting with the given ID.
- if (!m_settings.contains(id))
- return NULL;
+ // Make sure there is a setting with the given ID.
+ if (!m_settings.contains(id))
+ return NULL;
- return m_settings[id];
+ return m_settings[id];
}
QVariant SettingsObject::get(const QString &id) const
{
- auto setting = getSetting(id);
- return (setting ? setting->get() : QVariant());
+ auto setting = getSetting(id);
+ return (setting ? setting->get() : QVariant());
}
bool SettingsObject::set(const QString &id, QVariant value)
{
- auto setting = getSetting(id);
- if (!setting)
- {
- qCritical() << QString("Error changing setting %1. Setting doesn't exist.").arg(id);
- return false;
- }
- else
- {
- setting->set(value);
- return true;
- }
+ auto setting = getSetting(id);
+ if (!setting)
+ {
+ qCritical() << QString("Error changing setting %1. Setting doesn't exist.").arg(id);
+ return false;
+ }
+ else
+ {
+ setting->set(value);
+ return true;
+ }
}
void SettingsObject::reset(const QString &id) const
{
- auto setting = getSetting(id);
- if (setting)
- setting->reset();
+ auto setting = getSetting(id);
+ if (setting)
+ setting->reset();
}
bool SettingsObject::contains(const QString &id)
{
- return m_settings.contains(id);
+ return m_settings.contains(id);
}
bool SettingsObject::reload()
{
- for (auto setting : m_settings.values())
- {
- setting->set(setting->get());
- }
- return true;
+ for (auto setting : m_settings.values())
+ {
+ setting->set(setting->get());
+ }
+ return true;
}
void SettingsObject::connectSignals(const Setting &setting)
{
- connect(&setting, SIGNAL(SettingChanged(const Setting &, QVariant)),
- SLOT(changeSetting(const Setting &, QVariant)));
- connect(&setting, SIGNAL(SettingChanged(const Setting &, QVariant)),
- SIGNAL(SettingChanged(const Setting &, QVariant)));
+ connect(&setting, SIGNAL(SettingChanged(const Setting &, QVariant)),
+ SLOT(changeSetting(const Setting &, QVariant)));
+ connect(&setting, SIGNAL(SettingChanged(const Setting &, QVariant)),
+ SIGNAL(SettingChanged(const Setting &, QVariant)));
- connect(&setting, SIGNAL(settingReset(Setting)), SLOT(resetSetting(const Setting &)));
- connect(&setting, SIGNAL(settingReset(Setting)), SIGNAL(settingReset(const Setting &)));
+ connect(&setting, SIGNAL(settingReset(Setting)), SLOT(resetSetting(const Setting &)));
+ connect(&setting, SIGNAL(settingReset(Setting)), SIGNAL(settingReset(const Setting &)));
}
diff --git a/api/logic/settings/SettingsObject.h b/api/logic/settings/SettingsObject.h
index 8582d8ad..10a34f81 100644
--- a/api/logic/settings/SettingsObject.h
+++ b/api/logic/settings/SettingsObject.h
@@ -42,173 +42,173 @@ typedef std::shared_ptr<SettingsObject> SettingsObjectPtr;
*/
class MULTIMC_LOGIC_EXPORT SettingsObject : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- class Lock
- {
- public:
- Lock(SettingsObjectPtr locked)
- :m_locked(locked)
- {
- m_locked->suspendSave();
- }
- ~Lock()
- {
- m_locked->resumeSave();
- }
- private:
- SettingsObjectPtr m_locked;
- };
+ class Lock
+ {
+ public:
+ Lock(SettingsObjectPtr locked)
+ :m_locked(locked)
+ {
+ m_locked->suspendSave();
+ }
+ ~Lock()
+ {
+ m_locked->resumeSave();
+ }
+ private:
+ SettingsObjectPtr m_locked;
+ };
public:
- explicit SettingsObject(QObject *parent = 0);
- virtual ~SettingsObject();
- /*!
- * Registers an override setting for the given original setting in this settings object
- * gate decides if the passthrough (true) or the original (false) is used for value
- *
- * This will fail if there is already a setting with the same ID as
- * the one that is being registered.
- * \return A valid Setting shared pointer if successful.
- */
- std::shared_ptr<Setting> registerOverride(std::shared_ptr<Setting> original, std::shared_ptr<Setting> gate);
-
- /*!
- * Registers a passthorugh setting for the given original setting in this settings object
- * gate decides if the passthrough (true) or the original (false) is used for value
- *
- * This will fail if there is already a setting with the same ID as
- * the one that is being registered.
- * \return A valid Setting shared pointer if successful.
- */
- std::shared_ptr<Setting> registerPassthrough(std::shared_ptr<Setting> original, std::shared_ptr<Setting> gate);
-
- /*!
- * Registers the given setting with this SettingsObject and connects the necessary signals.
- *
- * This will fail if there is already a setting with the same ID as
- * the one that is being registered.
- * \return A valid Setting shared pointer if successful.
- */
- std::shared_ptr<Setting> registerSetting(QStringList synonyms,
- QVariant defVal = QVariant());
-
- /*!
- * Registers the given setting with this SettingsObject and connects the necessary signals.
- *
- * This will fail if there is already a setting with the same ID as
- * the one that is being registered.
- * \return A valid Setting shared pointer if successful.
- */
- std::shared_ptr<Setting> registerSetting(QString id, QVariant defVal = QVariant())
- {
- return registerSetting(QStringList(id), defVal);
- }
-
- /*!
- * \brief Gets the setting with the given ID.
- * \param id The ID of the setting to get.
- * \return A pointer to the setting with the given ID.
- * Returns null if there is no setting with the given ID.
- * \sa operator []()
- */
- std::shared_ptr<Setting> getSetting(const QString &id) const;
-
- /*!
- * \brief Gets the value of the setting with the given ID.
- * \param id The ID of the setting to get.
- * \return The setting's value as a QVariant.
- * If no setting with the given ID exists, returns an invalid QVariant.
- */
- QVariant get(const QString &id) const;
-
- /*!
- * \brief Sets the value of the setting with the given ID.
- * If no setting with the given ID exists, returns false
- * \param id The ID of the setting to change.
- * \param value The new value of the setting.
- * \return True if successful, false if it failed.
- */
- bool set(const QString &id, QVariant value);
-
- /*!
- * \brief Reverts the setting with the given ID to default.
- * \param id The ID of the setting to reset.
- */
- void reset(const QString &id) const;
-
- /*!
- * \brief Checks if this SettingsObject contains a setting with the given ID.
- * \param id The ID to check for.
- * \return True if the SettingsObject has a setting with the given ID.
- */
- bool contains(const QString &id);
-
- /*!
- * \brief Reloads the settings and emit signals for changed settings
- * \return True if reloading was successful
- */
- virtual bool reload();
-
- virtual void suspendSave() = 0;
- virtual void resumeSave() = 0;
+ explicit SettingsObject(QObject *parent = 0);
+ virtual ~SettingsObject();
+ /*!
+ * Registers an override setting for the given original setting in this settings object
+ * gate decides if the passthrough (true) or the original (false) is used for value
+ *
+ * This will fail if there is already a setting with the same ID as
+ * the one that is being registered.
+ * \return A valid Setting shared pointer if successful.
+ */
+ std::shared_ptr<Setting> registerOverride(std::shared_ptr<Setting> original, std::shared_ptr<Setting> gate);
+
+ /*!
+ * Registers a passthorugh setting for the given original setting in this settings object
+ * gate decides if the passthrough (true) or the original (false) is used for value
+ *
+ * This will fail if there is already a setting with the same ID as
+ * the one that is being registered.
+ * \return A valid Setting shared pointer if successful.
+ */
+ std::shared_ptr<Setting> registerPassthrough(std::shared_ptr<Setting> original, std::shared_ptr<Setting> gate);
+
+ /*!
+ * Registers the given setting with this SettingsObject and connects the necessary signals.
+ *
+ * This will fail if there is already a setting with the same ID as
+ * the one that is being registered.
+ * \return A valid Setting shared pointer if successful.
+ */
+ std::shared_ptr<Setting> registerSetting(QStringList synonyms,
+ QVariant defVal = QVariant());
+
+ /*!
+ * Registers the given setting with this SettingsObject and connects the necessary signals.
+ *
+ * This will fail if there is already a setting with the same ID as
+ * the one that is being registered.
+ * \return A valid Setting shared pointer if successful.
+ */
+ std::shared_ptr<Setting> registerSetting(QString id, QVariant defVal = QVariant())
+ {
+ return registerSetting(QStringList(id), defVal);
+ }
+
+ /*!
+ * \brief Gets the setting with the given ID.
+ * \param id The ID of the setting to get.
+ * \return A pointer to the setting with the given ID.
+ * Returns null if there is no setting with the given ID.
+ * \sa operator []()
+ */
+ std::shared_ptr<Setting> getSetting(const QString &id) const;
+
+ /*!
+ * \brief Gets the value of the setting with the given ID.
+ * \param id The ID of the setting to get.
+ * \return The setting's value as a QVariant.
+ * If no setting with the given ID exists, returns an invalid QVariant.
+ */
+ QVariant get(const QString &id) const;
+
+ /*!
+ * \brief Sets the value of the setting with the given ID.
+ * If no setting with the given ID exists, returns false
+ * \param id The ID of the setting to change.
+ * \param value The new value of the setting.
+ * \return True if successful, false if it failed.
+ */
+ bool set(const QString &id, QVariant value);
+
+ /*!
+ * \brief Reverts the setting with the given ID to default.
+ * \param id The ID of the setting to reset.
+ */
+ void reset(const QString &id) const;
+
+ /*!
+ * \brief Checks if this SettingsObject contains a setting with the given ID.
+ * \param id The ID to check for.
+ * \return True if the SettingsObject has a setting with the given ID.
+ */
+ bool contains(const QString &id);
+
+ /*!
+ * \brief Reloads the settings and emit signals for changed settings
+ * \return True if reloading was successful
+ */
+ virtual bool reload();
+
+ virtual void suspendSave() = 0;
+ virtual void resumeSave() = 0;
signals:
- /*!
- * \brief Signal emitted when one of this SettingsObject object's settings changes.
- * This is usually just connected directly to each Setting object's
- * SettingChanged() signals.
- * \param setting A reference to the Setting object that changed.
- * \param value The Setting object's new value.
- */
- void SettingChanged(const Setting &setting, QVariant value);
-
- /*!
- * \brief Signal emitted when one of this SettingsObject object's settings resets.
- * This is usually just connected directly to each Setting object's
- * settingReset() signals.
- * \param setting A reference to the Setting object that changed.
- */
- void settingReset(const Setting &setting);
+ /*!
+ * \brief Signal emitted when one of this SettingsObject object's settings changes.
+ * This is usually just connected directly to each Setting object's
+ * SettingChanged() signals.
+ * \param setting A reference to the Setting object that changed.
+ * \param value The Setting object's new value.
+ */
+ void SettingChanged(const Setting &setting, QVariant value);
+
+ /*!
+ * \brief Signal emitted when one of this SettingsObject object's settings resets.
+ * This is usually just connected directly to each Setting object's
+ * settingReset() signals.
+ * \param setting A reference to the Setting object that changed.
+ */
+ void settingReset(const Setting &setting);
protected
slots:
- /*!
- * \brief Changes a setting.
- * This slot is usually connected to each Setting object's
- * SettingChanged() signal. The signal is emitted, causing this slot
- * to update the setting's value in the config file.
- * \param setting A reference to the Setting object that changed.
- * \param value The setting's new value.
- */
- virtual void changeSetting(const Setting &setting, QVariant value) = 0;
-
- /*!
- * \brief Resets a setting.
- * This slot is usually connected to each Setting object's
- * settingReset() signal. The signal is emitted, causing this slot
- * to update the setting's value in the config file.
- * \param setting A reference to the Setting object that changed.
- */
- virtual void resetSetting(const Setting &setting) = 0;
+ /*!
+ * \brief Changes a setting.
+ * This slot is usually connected to each Setting object's
+ * SettingChanged() signal. The signal is emitted, causing this slot
+ * to update the setting's value in the config file.
+ * \param setting A reference to the Setting object that changed.
+ * \param value The setting's new value.
+ */
+ virtual void changeSetting(const Setting &setting, QVariant value) = 0;
+
+ /*!
+ * \brief Resets a setting.
+ * This slot is usually connected to each Setting object's
+ * settingReset() signal. The signal is emitted, causing this slot
+ * to update the setting's value in the config file.
+ * \param setting A reference to the Setting object that changed.
+ */
+ virtual void resetSetting(const Setting &setting) = 0;
protected:
- /*!
- * \brief Connects the necessary signals to the given Setting.
- * \param setting The setting to connect.
- */
- void connectSignals(const Setting &setting);
+ /*!
+ * \brief Connects the necessary signals to the given Setting.
+ * \param setting The setting to connect.
+ */
+ void connectSignals(const Setting &setting);
- /*!
- * \brief Function used by Setting objects to get their values from the SettingsObject.
- * \param setting The
- * \return
- */
- virtual QVariant retrieveValue(const Setting &setting) = 0;
+ /*!
+ * \brief Function used by Setting objects to get their values from the SettingsObject.
+ * \param setting The
+ * \return
+ */
+ virtual QVariant retrieveValue(const Setting &setting) = 0;
- friend class Setting;
+ friend class Setting;
private:
- QMap<QString, std::shared_ptr<Setting>> m_settings;
+ QMap<QString, std::shared_ptr<Setting>> m_settings;
protected:
- bool m_suspendSave = false;
- bool m_doSave = false;
+ bool m_suspendSave = false;
+ bool m_doSave = false;
};
diff --git a/api/logic/status/StatusChecker.cpp b/api/logic/status/StatusChecker.cpp
index bff9fda9..ffadcc74 100644
--- a/api/logic/status/StatusChecker.cpp
+++ b/api/logic/status/StatusChecker.cpp
@@ -28,121 +28,121 @@ StatusChecker::StatusChecker()
void StatusChecker::timerEvent(QTimerEvent *e)
{
- QObject::timerEvent(e);
- reloadStatus();
+ QObject::timerEvent(e);
+ reloadStatus();
}
void StatusChecker::reloadStatus()
{
- if (isLoadingStatus())
- {
- // qDebug() << "Ignored request to reload status. Currently reloading already.";
- return;
- }
-
- // qDebug() << "Reloading status.";
-
- NetJob* job = new NetJob("Status JSON");
- job->addNetAction(Net::Download::makeByteArray(URLConstants::MOJANG_STATUS_URL, &dataSink));
- QObject::connect(job, &NetJob::succeeded, this, &StatusChecker::statusDownloadFinished);
- QObject::connect(job, &NetJob::failed, this, &StatusChecker::statusDownloadFailed);
- m_statusNetJob.reset(job);
- emit statusLoading(true);
- job->start();
+ if (isLoadingStatus())
+ {
+ // qDebug() << "Ignored request to reload status. Currently reloading already.";
+ return;
+ }
+
+ // qDebug() << "Reloading status.";
+
+ NetJob* job = new NetJob("Status JSON");
+ job->addNetAction(Net::Download::makeByteArray(URLConstants::MOJANG_STATUS_URL, &dataSink));
+ QObject::connect(job, &NetJob::succeeded, this, &StatusChecker::statusDownloadFinished);
+ QObject::connect(job, &NetJob::failed, this, &StatusChecker::statusDownloadFailed);
+ m_statusNetJob.reset(job);
+ emit statusLoading(true);
+ job->start();
}
void StatusChecker::statusDownloadFinished()
{
- qDebug() << "Finished loading status JSON.";
- m_statusEntries.clear();
- m_statusNetJob.reset();
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(dataSink, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError)
- {
- fail("Error parsing status JSON:" + jsonError.errorString());
- return;
- }
-
- if (!jsonDoc.isArray())
- {
- fail("Error parsing status JSON: JSON root is not an array");
- return;
- }
-
- QJsonArray root = jsonDoc.array();
-
- for(auto status = root.begin(); status != root.end(); ++status)
- {
- QVariantMap map = (*status).toObject().toVariantMap();
-
- for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
- {
- QString key = iter.key();
- QVariant value = iter.value();
-
- if(value.type() == QVariant::Type::String)
- {
- m_statusEntries.insert(key, value.toString());
- //qDebug() << "Status JSON object: " << key << m_statusEntries[key];
- }
- else
- {
- fail("Malformed status JSON: expected status type to be a string.");
- return;
- }
- }
- }
-
- succeed();
+ qDebug() << "Finished loading status JSON.";
+ m_statusEntries.clear();
+ m_statusNetJob.reset();
+
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(dataSink, &jsonError);
+
+ if (jsonError.error != QJsonParseError::NoError)
+ {
+ fail("Error parsing status JSON:" + jsonError.errorString());
+ return;
+ }
+
+ if (!jsonDoc.isArray())
+ {
+ fail("Error parsing status JSON: JSON root is not an array");
+ return;
+ }
+
+ QJsonArray root = jsonDoc.array();
+
+ for(auto status = root.begin(); status != root.end(); ++status)
+ {
+ QVariantMap map = (*status).toObject().toVariantMap();
+
+ for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
+ {
+ QString key = iter.key();
+ QVariant value = iter.value();
+
+ if(value.type() == QVariant::Type::String)
+ {
+ m_statusEntries.insert(key, value.toString());
+ //qDebug() << "Status JSON object: " << key << m_statusEntries[key];
+ }
+ else
+ {
+ fail("Malformed status JSON: expected status type to be a string.");
+ return;
+ }
+ }
+ }
+
+ succeed();
}
void StatusChecker::statusDownloadFailed(QString reason)
{
- fail(tr("Failed to load status JSON:\n%1").arg(reason));
+ fail(tr("Failed to load status JSON:\n%1").arg(reason));
}
QMap<QString, QString> StatusChecker::getStatusEntries() const
{
- return m_statusEntries;
+ return m_statusEntries;
}
bool StatusChecker::isLoadingStatus() const
{
- return m_statusNetJob.get() != nullptr;
+ return m_statusNetJob.get() != nullptr;
}
QString StatusChecker::getLastLoadErrorMsg() const
{
- return m_lastLoadError;
+ return m_lastLoadError;
}
void StatusChecker::succeed()
{
- if(m_prevEntries != m_statusEntries)
- {
- emit statusChanged(m_statusEntries);
- m_prevEntries = m_statusEntries;
- }
- m_lastLoadError = "";
- qDebug() << "Status loading succeeded.";
- m_statusNetJob.reset();
- emit statusLoading(false);
+ if(m_prevEntries != m_statusEntries)
+ {
+ emit statusChanged(m_statusEntries);
+ m_prevEntries = m_statusEntries;
+ }
+ m_lastLoadError = "";
+ qDebug() << "Status loading succeeded.";
+ m_statusNetJob.reset();
+ emit statusLoading(false);
}
void StatusChecker::fail(const QString& errorMsg)
{
- if(m_prevEntries != m_statusEntries)
- {
- emit statusChanged(m_statusEntries);
- m_prevEntries = m_statusEntries;
- }
- m_lastLoadError = errorMsg;
- qDebug() << "Failed to load status:" << errorMsg;
- m_statusNetJob.reset();
- emit statusLoading(false);
+ if(m_prevEntries != m_statusEntries)
+ {
+ emit statusChanged(m_statusEntries);
+ m_prevEntries = m_statusEntries;
+ }
+ m_lastLoadError = errorMsg;
+ qDebug() << "Failed to load status:" << errorMsg;
+ m_statusNetJob.reset();
+ emit statusLoading(false);
}
diff --git a/api/logic/status/StatusChecker.h b/api/logic/status/StatusChecker.h
index f19aba9a..51a86910 100644
--- a/api/logic/status/StatusChecker.h
+++ b/api/logic/status/StatusChecker.h
@@ -25,36 +25,36 @@
class MULTIMC_LOGIC_EXPORT StatusChecker : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public: /* con/des */
- StatusChecker();
+ StatusChecker();
public: /* methods */
- QString getLastLoadErrorMsg() const;
- bool isLoadingStatus() const;
- QMap<QString, QString> getStatusEntries() const;
+ QString getLastLoadErrorMsg() const;
+ bool isLoadingStatus() const;
+ QMap<QString, QString> getStatusEntries() const;
signals:
- void statusLoading(bool loading);
- void statusChanged(QMap<QString, QString> newStatus);
+ void statusLoading(bool loading);
+ void statusChanged(QMap<QString, QString> newStatus);
public slots:
- void reloadStatus();
+ void reloadStatus();
protected: /* methods */
- virtual void timerEvent(QTimerEvent *);
+ virtual void timerEvent(QTimerEvent *);
protected slots:
- void statusDownloadFinished();
- void statusDownloadFailed(QString reason);
- void succeed();
- void fail(const QString& errorMsg);
+ void statusDownloadFinished();
+ void statusDownloadFailed(QString reason);
+ void succeed();
+ void fail(const QString& errorMsg);
protected: /* data */
- QMap<QString, QString> m_prevEntries;
- QMap<QString, QString> m_statusEntries;
- NetJobPtr m_statusNetJob;
- QString m_lastLoadError;
- QByteArray dataSink;
+ QMap<QString, QString> m_prevEntries;
+ QMap<QString, QString> m_statusEntries;
+ NetJobPtr m_statusNetJob;
+ QString m_lastLoadError;
+ QByteArray dataSink;
};
diff --git a/api/logic/tasks/SequentialTask.cpp b/api/logic/tasks/SequentialTask.cpp
index ac0e7820..d0777132 100644
--- a/api/logic/tasks/SequentialTask.cpp
+++ b/api/logic/tasks/SequentialTask.cpp
@@ -6,50 +6,50 @@ SequentialTask::SequentialTask(QObject *parent) : Task(parent), m_currentIndex(-
void SequentialTask::addTask(std::shared_ptr<Task> task)
{
- m_queue.append(task);
+ m_queue.append(task);
}
void SequentialTask::executeTask()
{
- m_currentIndex = -1;
- startNext();
+ m_currentIndex = -1;
+ startNext();
}
void SequentialTask::startNext()
{
- if (m_currentIndex != -1)
- {
- std::shared_ptr<Task> previous = m_queue[m_currentIndex];
- disconnect(previous.get(), 0, this, 0);
- }
- m_currentIndex++;
- if (m_queue.isEmpty() || m_currentIndex >= m_queue.size())
- {
- emitSucceeded();
- return;
- }
- std::shared_ptr<Task> next = m_queue[m_currentIndex];
- connect(next.get(), SIGNAL(failed(QString)), this, SLOT(subTaskFailed(QString)));
- connect(next.get(), SIGNAL(status(QString)), this, SLOT(subTaskStatus(QString)));
- connect(next.get(), SIGNAL(progress(qint64, qint64)), this, SLOT(subTaskProgress(qint64, qint64)));
- connect(next.get(), SIGNAL(succeeded()), this, SLOT(startNext()));
- next->start();
+ if (m_currentIndex != -1)
+ {
+ std::shared_ptr<Task> previous = m_queue[m_currentIndex];
+ disconnect(previous.get(), 0, this, 0);
+ }
+ m_currentIndex++;
+ if (m_queue.isEmpty() || m_currentIndex >= m_queue.size())
+ {
+ emitSucceeded();
+ return;
+ }
+ std::shared_ptr<Task> next = m_queue[m_currentIndex];
+ connect(next.get(), SIGNAL(failed(QString)), this, SLOT(subTaskFailed(QString)));
+ connect(next.get(), SIGNAL(status(QString)), this, SLOT(subTaskStatus(QString)));
+ connect(next.get(), SIGNAL(progress(qint64, qint64)), this, SLOT(subTaskProgress(qint64, qint64)));
+ connect(next.get(), SIGNAL(succeeded()), this, SLOT(startNext()));
+ next->start();
}
void SequentialTask::subTaskFailed(const QString &msg)
{
- emitFailed(msg);
+ emitFailed(msg);
}
void SequentialTask::subTaskStatus(const QString &msg)
{
- setStatus(msg);
+ setStatus(msg);
}
void SequentialTask::subTaskProgress(qint64 current, qint64 total)
{
- if(total == 0)
- {
- setProgress(0, 100);
- return;
- }
- setProgress(current, total);
+ if(total == 0)
+ {
+ setProgress(0, 100);
+ return;
+ }
+ setProgress(current, total);
}
diff --git a/api/logic/tasks/SequentialTask.h b/api/logic/tasks/SequentialTask.h
index a2f3580f..2ca77c00 100644
--- a/api/logic/tasks/SequentialTask.h
+++ b/api/logic/tasks/SequentialTask.h
@@ -9,24 +9,24 @@
class MULTIMC_LOGIC_EXPORT SequentialTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit SequentialTask(QObject *parent = 0);
- virtual ~SequentialTask() {};
+ explicit SequentialTask(QObject *parent = 0);
+ virtual ~SequentialTask() {};
- void addTask(std::shared_ptr<Task> task);
+ void addTask(std::shared_ptr<Task> task);
protected:
- void executeTask();
+ void executeTask();
private
slots:
- void startNext();
- void subTaskFailed(const QString &msg);
- void subTaskStatus(const QString &msg);
- void subTaskProgress(qint64 current, qint64 total);
+ void startNext();
+ void subTaskFailed(const QString &msg);
+ void subTaskStatus(const QString &msg);
+ void subTaskProgress(qint64 current, qint64 total);
private:
- QQueue<std::shared_ptr<Task> > m_queue;
- int m_currentIndex;
+ QQueue<std::shared_ptr<Task> > m_queue;
+ int m_currentIndex;
};
diff --git a/api/logic/tasks/Task.cpp b/api/logic/tasks/Task.cpp
index 2523aeb2..f7f2d491 100644
--- a/api/logic/tasks/Task.cpp
+++ b/api/logic/tasks/Task.cpp
@@ -23,124 +23,124 @@ Task::Task(QObject *parent) : QObject(parent)
void Task::setStatus(const QString &new_status)
{
- if(m_status != new_status)
- {
- m_status = new_status;
- emit status(m_status);
- }
+ if(m_status != new_status)
+ {
+ m_status = new_status;
+ emit status(m_status);
+ }
}
void Task::setProgress(qint64 current, qint64 total)
{
- m_progress = current;
- m_progressTotal = total;
- emit progress(m_progress, m_progressTotal);
+ m_progress = current;
+ m_progressTotal = total;
+ emit progress(m_progress, m_progressTotal);
}
void Task::start()
{
- m_running = true;
- emit started();
- qDebug() << "Task" << describe() << "started";
- executeTask();
+ m_running = true;
+ emit started();
+ qDebug() << "Task" << describe() << "started";
+ executeTask();
}
void Task::emitFailed(QString reason)
{
- // Don't fail twice.
- if (!m_running)
- {
- qCritical() << "Task" << describe() << "failed while not running!!!!: " << reason;
- return;
- }
- m_running = false;
- m_finished = true;
- m_succeeded = false;
- m_failReason = reason;
- qCritical() << "Task" << describe() << "failed: " << reason;
- emit failed(reason);
- emit finished();
+ // Don't fail twice.
+ if (!m_running)
+ {
+ qCritical() << "Task" << describe() << "failed while not running!!!!: " << reason;
+ return;
+ }
+ m_running = false;
+ m_finished = true;
+ m_succeeded = false;
+ m_failReason = reason;
+ qCritical() << "Task" << describe() << "failed: " << reason;
+ emit failed(reason);
+ emit finished();
}
void Task::emitAborted()
{
- // Don't abort twice.
- if (!m_running)
- {
- qCritical() << "Task" << describe() << "aborted while not running!!!!";
- return;
- }
- m_running = false;
- m_finished = true;
- m_succeeded = false;
- m_failReason = "Aborted.";
- qDebug() << "Task" << describe() << "aborted.";
- emit failed(m_failReason);
- emit finished();
+ // Don't abort twice.
+ if (!m_running)
+ {
+ qCritical() << "Task" << describe() << "aborted while not running!!!!";
+ return;
+ }
+ m_running = false;
+ m_finished = true;
+ m_succeeded = false;
+ m_failReason = "Aborted.";
+ qDebug() << "Task" << describe() << "aborted.";
+ emit failed(m_failReason);
+ emit finished();
}
void Task::emitSucceeded()
{
- // Don't succeed twice.
- if (!m_running)
- {
- qCritical() << "Task" << describe() << "succeeded while not running!!!!";
- return;
- }
- m_running = false;
- m_finished = true;
- m_succeeded = true;
- qDebug() << "Task" << describe() << "succeeded";
- emit succeeded();
- emit finished();
+ // Don't succeed twice.
+ if (!m_running)
+ {
+ qCritical() << "Task" << describe() << "succeeded while not running!!!!";
+ return;
+ }
+ m_running = false;
+ m_finished = true;
+ m_succeeded = true;
+ qDebug() << "Task" << describe() << "succeeded";
+ emit succeeded();
+ emit finished();
}
QString Task::describe()
{
- QString outStr;
- QTextStream out(&outStr);
- out << metaObject()->className() << QChar('(');
- auto name = objectName();
- if(name.isEmpty())
- {
- out << QString("0x%1").arg((quintptr)this, 0, 16);
- }
- else
- {
- out << name;
- }
- out << QChar(')');
- out.flush();
- return outStr;
+ QString outStr;
+ QTextStream out(&outStr);
+ out << metaObject()->className() << QChar('(');
+ auto name = objectName();
+ if(name.isEmpty())
+ {
+ out << QString("0x%1").arg((quintptr)this, 0, 16);
+ }
+ else
+ {
+ out << name;
+ }
+ out << QChar(')');
+ out.flush();
+ return outStr;
}
bool Task::isRunning() const
{
- return m_running;
+ return m_running;
}
bool Task::isFinished() const
{
- return m_finished;
+ return m_finished;
}
bool Task::wasSuccessful() const
{
- return m_succeeded;
+ return m_succeeded;
}
QString Task::failReason() const
{
- return m_failReason;
+ return m_failReason;
}
void Task::logWarning(const QString& line)
{
- qWarning() << line;
- m_Warnings.append(line);
+ qWarning() << line;
+ m_Warnings.append(line);
}
QStringList Task::warnings() const
{
- return m_Warnings;
+ return m_Warnings;
}
diff --git a/api/logic/tasks/Task.h b/api/logic/tasks/Task.h
index 643f8510..58dbc4ca 100644
--- a/api/logic/tasks/Task.h
+++ b/api/logic/tasks/Task.h
@@ -23,78 +23,78 @@
class MULTIMC_LOGIC_EXPORT Task : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit Task(QObject *parent = 0);
- virtual ~Task() {};
+ explicit Task(QObject *parent = 0);
+ virtual ~Task() {};
- bool isRunning() const;
- bool isFinished() const;
- bool wasSuccessful() const;
+ bool isRunning() const;
+ bool isFinished() const;
+ bool wasSuccessful() const;
- /*!
- * Returns the string that was passed to emitFailed as the error message when the task failed.
- * If the task hasn't failed, returns an empty string.
- */
- QString failReason() const;
+ /*!
+ * Returns the string that was passed to emitFailed as the error message when the task failed.
+ * If the task hasn't failed, returns an empty string.
+ */
+ QString failReason() const;
- virtual QStringList warnings() const;
+ virtual QStringList warnings() const;
- virtual bool canAbort() const { return false; }
+ virtual bool canAbort() const { return false; }
- QString getStatus()
- {
- return m_status;
- }
+ QString getStatus()
+ {
+ return m_status;
+ }
- qint64 getProgress()
- {
- return m_progress;
- }
+ qint64 getProgress()
+ {
+ return m_progress;
+ }
- qint64 getTotalProgress()
- {
- return m_progressTotal;
- }
+ qint64 getTotalProgress()
+ {
+ return m_progressTotal;
+ }
protected:
- void logWarning(const QString & line);
+ void logWarning(const QString & line);
private:
- QString describe();
+ QString describe();
signals:
- void started();
- void progress(qint64 current, qint64 total);
- void finished();
- void succeeded();
- void failed(QString reason);
- void status(QString status);
+ void started();
+ void progress(qint64 current, qint64 total);
+ void finished();
+ void succeeded();
+ void failed(QString reason);
+ void status(QString status);
public slots:
- virtual void start();
- virtual bool abort() { return false; };
+ virtual void start();
+ virtual bool abort() { return false; };
protected:
- virtual void executeTask() = 0;
+ virtual void executeTask() = 0;
protected slots:
- virtual void emitSucceeded();
- virtual void emitAborted();
- virtual void emitFailed(QString reason);
+ virtual void emitSucceeded();
+ virtual void emitAborted();
+ virtual void emitFailed(QString reason);
public slots:
- void setStatus(const QString &status);
- void setProgress(qint64 current, qint64 total);
+ void setStatus(const QString &status);
+ void setProgress(qint64 current, qint64 total);
private:
- bool m_running = false;
- bool m_finished = false;
- bool m_succeeded = false;
- QStringList m_Warnings;
- QString m_failReason = "";
- QString m_status;
- int m_progress = 0;
- int m_progressTotal = 100;
+ bool m_running = false;
+ bool m_finished = false;
+ bool m_succeeded = false;
+ QStringList m_Warnings;
+ QString m_failReason = "";
+ QString m_status;
+ int m_progress = 0;
+ int m_progressTotal = 100;
};
diff --git a/api/logic/tools/BaseExternalTool.cpp b/api/logic/tools/BaseExternalTool.cpp
index 2b97c3c9..38d81788 100644
--- a/api/logic/tools/BaseExternalTool.cpp
+++ b/api/logic/tools/BaseExternalTool.cpp
@@ -10,7 +10,7 @@
#include "BaseInstance.h"
BaseExternalTool::BaseExternalTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
- : QObject(parent), m_instance(instance), globalSettings(settings)
+ : QObject(parent), m_instance(instance), globalSettings(settings)
{
}
@@ -19,14 +19,14 @@ BaseExternalTool::~BaseExternalTool()
}
BaseDetachedTool::BaseDetachedTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
- : BaseExternalTool(settings, instance, parent)
+ : BaseExternalTool(settings, instance, parent)
{
}
void BaseDetachedTool::run()
{
- runImpl();
+ runImpl();
}
@@ -35,7 +35,7 @@ BaseExternalToolFactory::~BaseExternalToolFactory()
}
BaseDetachedTool *BaseDetachedToolFactory::createDetachedTool(InstancePtr instance,
- QObject *parent)
+ QObject *parent)
{
- return qobject_cast<BaseDetachedTool *>(createTool(instance, parent));
+ return qobject_cast<BaseDetachedTool *>(createTool(instance, parent));
}
diff --git a/api/logic/tools/BaseExternalTool.h b/api/logic/tools/BaseExternalTool.h
index fe1b5dc6..b393b9ef 100644
--- a/api/logic/tools/BaseExternalTool.h
+++ b/api/logic/tools/BaseExternalTool.h
@@ -11,50 +11,50 @@ class QProcess;
class MULTIMC_LOGIC_EXPORT BaseExternalTool : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit BaseExternalTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
- virtual ~BaseExternalTool();
+ explicit BaseExternalTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
+ virtual ~BaseExternalTool();
protected:
- InstancePtr m_instance;
- SettingsObjectPtr globalSettings;
+ InstancePtr m_instance;
+ SettingsObjectPtr globalSettings;
};
class MULTIMC_LOGIC_EXPORT BaseDetachedTool : public BaseExternalTool
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit BaseDetachedTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
+ explicit BaseDetachedTool(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
public
slots:
- void run();
+ void run();
protected:
- virtual void runImpl() = 0;
+ virtual void runImpl() = 0;
};
class MULTIMC_LOGIC_EXPORT BaseExternalToolFactory
{
public:
- virtual ~BaseExternalToolFactory();
+ virtual ~BaseExternalToolFactory();
- virtual QString name() const = 0;
+ virtual QString name() const = 0;
- virtual void registerSettings(SettingsObjectPtr settings) = 0;
+ virtual void registerSettings(SettingsObjectPtr settings) = 0;
- virtual BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) = 0;
+ virtual BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) = 0;
- virtual bool check(QString *error) = 0;
- virtual bool check(const QString &path, QString *error) = 0;
+ virtual bool check(QString *error) = 0;
+ virtual bool check(const QString &path, QString *error) = 0;
protected:
- SettingsObjectPtr globalSettings;
+ SettingsObjectPtr globalSettings;
};
class MULTIMC_LOGIC_EXPORT BaseDetachedToolFactory : public BaseExternalToolFactory
{
public:
- virtual BaseDetachedTool *createDetachedTool(InstancePtr instance, QObject *parent = 0);
+ virtual BaseDetachedTool *createDetachedTool(InstancePtr instance, QObject *parent = 0);
};
diff --git a/api/logic/tools/BaseProfiler.cpp b/api/logic/tools/BaseProfiler.cpp
index 5ff0fa44..c7d83549 100644
--- a/api/logic/tools/BaseProfiler.cpp
+++ b/api/logic/tools/BaseProfiler.cpp
@@ -3,33 +3,33 @@
#include <QProcess>
BaseProfiler::BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
- : BaseExternalTool(settings, instance, parent)
+ : BaseExternalTool(settings, instance, parent)
{
}
void BaseProfiler::beginProfiling(std::shared_ptr<LaunchTask> process)
{
- beginProfilingImpl(process);
+ beginProfilingImpl(process);
}
void BaseProfiler::abortProfiling()
{
- abortProfilingImpl();
+ abortProfilingImpl();
}
void BaseProfiler::abortProfilingImpl()
{
- if (!m_profilerProcess)
- {
- return;
- }
- m_profilerProcess->terminate();
- m_profilerProcess->deleteLater();
- m_profilerProcess = 0;
- emit abortLaunch(tr("Profiler aborted"));
+ if (!m_profilerProcess)
+ {
+ return;
+ }
+ m_profilerProcess->terminate();
+ m_profilerProcess->deleteLater();
+ m_profilerProcess = 0;
+ emit abortLaunch(tr("Profiler aborted"));
}
BaseProfiler *BaseProfilerFactory::createProfiler(InstancePtr instance, QObject *parent)
{
- return qobject_cast<BaseProfiler *>(createTool(instance, parent));
+ return qobject_cast<BaseProfiler *>(createTool(instance, parent));
}
diff --git a/api/logic/tools/BaseProfiler.h b/api/logic/tools/BaseProfiler.h
index 3340b7e4..f3e1ce3d 100644
--- a/api/logic/tools/BaseProfiler.h
+++ b/api/logic/tools/BaseProfiler.h
@@ -11,28 +11,28 @@ class QProcess;
class MULTIMC_LOGIC_EXPORT BaseProfiler : public BaseExternalTool
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
+ explicit BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
public
slots:
- void beginProfiling(std::shared_ptr<LaunchTask> process);
- void abortProfiling();
+ void beginProfiling(std::shared_ptr<LaunchTask> process);
+ void abortProfiling();
protected:
- QProcess *m_profilerProcess;
+ QProcess *m_profilerProcess;
- virtual void beginProfilingImpl(std::shared_ptr<LaunchTask> process) = 0;
- virtual void abortProfilingImpl();
+ virtual void beginProfilingImpl(std::shared_ptr<LaunchTask> process) = 0;
+ virtual void abortProfilingImpl();
signals:
- void readyToLaunch(const QString &message);
- void abortLaunch(const QString &message);
+ void readyToLaunch(const QString &message);
+ void abortLaunch(const QString &message);
};
class MULTIMC_LOGIC_EXPORT BaseProfilerFactory : public BaseExternalToolFactory
{
public:
- virtual BaseProfiler *createProfiler(InstancePtr instance, QObject *parent = 0);
+ virtual BaseProfiler *createProfiler(InstancePtr instance, QObject *parent = 0);
};
diff --git a/api/logic/tools/JProfiler.cpp b/api/logic/tools/JProfiler.cpp
index a0e3c895..b50322fe 100644
--- a/api/logic/tools/JProfiler.cpp
+++ b/api/logic/tools/JProfiler.cpp
@@ -8,109 +8,109 @@
class JProfiler : public BaseProfiler
{
- Q_OBJECT
+ Q_OBJECT
public:
- JProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
+ JProfiler(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
private slots:
- void profilerStarted();
- void profilerFinished(int exit, QProcess::ExitStatus status);
+ void profilerStarted();
+ void profilerFinished(int exit, QProcess::ExitStatus status);
protected:
- void beginProfilingImpl(std::shared_ptr<LaunchTask> process);
+ void beginProfilingImpl(std::shared_ptr<LaunchTask> process);
private:
- int listeningPort = 0;
+ int listeningPort = 0;
};
JProfiler::JProfiler(SettingsObjectPtr settings, InstancePtr instance,
- QObject *parent)
- : BaseProfiler(settings, instance, parent)
+ QObject *parent)
+ : BaseProfiler(settings, instance, parent)
{
}
void JProfiler::profilerStarted()
{
- emit readyToLaunch(tr("Listening on port: %1").arg(listeningPort));
+ emit readyToLaunch(tr("Listening on port: %1").arg(listeningPort));
}
void JProfiler::profilerFinished(int exit, QProcess::ExitStatus status)
{
- if (status == QProcess::CrashExit)
- {
- emit abortLaunch(tr("Profiler aborted"));
- }
- if (m_profilerProcess)
- {
- m_profilerProcess->deleteLater();
- m_profilerProcess = 0;
- }
+ if (status == QProcess::CrashExit)
+ {
+ emit abortLaunch(tr("Profiler aborted"));
+ }
+ if (m_profilerProcess)
+ {
+ m_profilerProcess->deleteLater();
+ m_profilerProcess = 0;
+ }
}
void JProfiler::beginProfilingImpl(std::shared_ptr<LaunchTask> process)
{
- listeningPort = globalSettings->get("JProfilerPort").toInt();
- QProcess *profiler = new QProcess(this);
- QStringList profilerArgs =
- {
- "-d", QString::number(process->pid()),
- "--gui",
- "-p", QString::number(listeningPort)
- };
- auto basePath = globalSettings->get("JProfilerPath").toString();
+ listeningPort = globalSettings->get("JProfilerPort").toInt();
+ QProcess *profiler = new QProcess(this);
+ QStringList profilerArgs =
+ {
+ "-d", QString::number(process->pid()),
+ "--gui",
+ "-p", QString::number(listeningPort)
+ };
+ auto basePath = globalSettings->get("JProfilerPath").toString();
#ifdef Q_OS_WIN
- QString profilerProgram = QDir(basePath).absoluteFilePath("bin/jpenable.exe");
+ QString profilerProgram = QDir(basePath).absoluteFilePath("bin/jpenable.exe");
#else
- QString profilerProgram = QDir(basePath).absoluteFilePath("bin/jpenable");
+ QString profilerProgram = QDir(basePath).absoluteFilePath("bin/jpenable");
#endif
- profiler->setArguments(profilerArgs);
- profiler->setProgram(profilerProgram);
+ profiler->setArguments(profilerArgs);
+ profiler->setProgram(profilerProgram);
- connect(profiler, SIGNAL(started()), SLOT(profilerStarted()));
- connect(profiler, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(profilerFinished(int,QProcess::ExitStatus)));
+ connect(profiler, SIGNAL(started()), SLOT(profilerStarted()));
+ connect(profiler, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(profilerFinished(int,QProcess::ExitStatus)));
- m_profilerProcess = profiler;
- profiler->start();
+ m_profilerProcess = profiler;
+ profiler->start();
}
void JProfilerFactory::registerSettings(SettingsObjectPtr settings)
{
- settings->registerSetting("JProfilerPath");
- settings->registerSetting("JProfilerPort", 42042);
- globalSettings = settings;
+ settings->registerSetting("JProfilerPath");
+ settings->registerSetting("JProfilerPort", 42042);
+ globalSettings = settings;
}
BaseExternalTool *JProfilerFactory::createTool(InstancePtr instance, QObject *parent)
{
- return new JProfiler(globalSettings, instance, parent);
+ return new JProfiler(globalSettings, instance, parent);
}
bool JProfilerFactory::check(QString *error)
{
- return check(globalSettings->get("JProfilerPath").toString(), error);
+ return check(globalSettings->get("JProfilerPath").toString(), error);
}
bool JProfilerFactory::check(const QString &path, QString *error)
{
- if (path.isEmpty())
- {
- *error = QObject::tr("Empty path");
- return false;
- }
- QDir dir(path);
- if (!dir.exists())
- {
- *error = QObject::tr("Path does not exist");
- return false;
- }
- if (!dir.exists("bin") || !(dir.exists("bin/jprofiler") || dir.exists("bin/jprofiler.exe")) || !dir.exists("bin/agent.jar"))
- {
- *error = QObject::tr("Invalid JProfiler install");
- return false;
- }
- return true;
+ if (path.isEmpty())
+ {
+ *error = QObject::tr("Empty path");
+ return false;
+ }
+ QDir dir(path);
+ if (!dir.exists())
+ {
+ *error = QObject::tr("Path does not exist");
+ return false;
+ }
+ if (!dir.exists("bin") || !(dir.exists("bin/jprofiler") || dir.exists("bin/jprofiler.exe")) || !dir.exists("bin/agent.jar"))
+ {
+ *error = QObject::tr("Invalid JProfiler install");
+ return false;
+ }
+ return true;
}
#include "JProfiler.moc"
diff --git a/api/logic/tools/JProfiler.h b/api/logic/tools/JProfiler.h
index d658d6c2..f211ddbf 100644
--- a/api/logic/tools/JProfiler.h
+++ b/api/logic/tools/JProfiler.h
@@ -7,9 +7,9 @@
class MULTIMC_LOGIC_EXPORT JProfilerFactory : public BaseProfilerFactory
{
public:
- QString name() const override { return "JProfiler"; }
- void registerSettings(SettingsObjectPtr settings) override;
- BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
- bool check(QString *error) override;
- bool check(const QString &path, QString *error) override;
+ QString name() const override { return "JProfiler"; }
+ void registerSettings(SettingsObjectPtr settings) override;
+ BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
+ bool check(QString *error) override;
+ bool check(const QString &path, QString *error) override;
};
diff --git a/api/logic/tools/JVisualVM.cpp b/api/logic/tools/JVisualVM.cpp
index 8fdb594f..10886857 100644
--- a/api/logic/tools/JVisualVM.cpp
+++ b/api/logic/tools/JVisualVM.cpp
@@ -9,96 +9,96 @@
class JVisualVM : public BaseProfiler
{
- Q_OBJECT
+ Q_OBJECT
public:
- JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
+ JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject *parent = 0);
private slots:
- void profilerStarted();
- void profilerFinished(int exit, QProcess::ExitStatus status);
+ void profilerStarted();
+ void profilerFinished(int exit, QProcess::ExitStatus status);
protected:
- void beginProfilingImpl(std::shared_ptr<LaunchTask> process);
+ void beginProfilingImpl(std::shared_ptr<LaunchTask> process);
};
JVisualVM::JVisualVM(SettingsObjectPtr settings, InstancePtr instance, QObject *parent)
- : BaseProfiler(settings, instance, parent)
+ : BaseProfiler(settings, instance, parent)
{
}
void JVisualVM::profilerStarted()
{
- emit readyToLaunch(tr("JVisualVM started"));
+ emit readyToLaunch(tr("JVisualVM started"));
}
void JVisualVM::profilerFinished(int exit, QProcess::ExitStatus status)
{
- if (status == QProcess::CrashExit)
- {
- emit abortLaunch(tr("Profiler aborted"));
- }
- if (m_profilerProcess)
- {
- m_profilerProcess->deleteLater();
- m_profilerProcess = 0;
- }
+ if (status == QProcess::CrashExit)
+ {
+ emit abortLaunch(tr("Profiler aborted"));
+ }
+ if (m_profilerProcess)
+ {
+ m_profilerProcess->deleteLater();
+ m_profilerProcess = 0;
+ }
}
void JVisualVM::beginProfilingImpl(std::shared_ptr<LaunchTask> process)
{
- QProcess *profiler = new QProcess(this);
- QStringList profilerArgs =
- {
- "--openpid", QString::number(process->pid())
- };
- auto programPath = globalSettings->get("JVisualVMPath").toString();
+ QProcess *profiler = new QProcess(this);
+ QStringList profilerArgs =
+ {
+ "--openpid", QString::number(process->pid())
+ };
+ auto programPath = globalSettings->get("JVisualVMPath").toString();
- profiler->setArguments(profilerArgs);
- profiler->setProgram(programPath);
+ profiler->setArguments(profilerArgs);
+ profiler->setProgram(programPath);
- connect(profiler, SIGNAL(started()), SLOT(profilerStarted()));
- connect(profiler, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(profilerFinished(int,QProcess::ExitStatus)));
+ connect(profiler, SIGNAL(started()), SLOT(profilerStarted()));
+ connect(profiler, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(profilerFinished(int,QProcess::ExitStatus)));
- profiler->start();
- m_profilerProcess = profiler;
+ profiler->start();
+ m_profilerProcess = profiler;
}
void JVisualVMFactory::registerSettings(SettingsObjectPtr settings)
{
- QString defaultValue = QStandardPaths::findExecutable("jvisualvm");
- if (defaultValue.isNull())
- {
- defaultValue = QStandardPaths::findExecutable("visualvm");
- }
- settings->registerSetting("JVisualVMPath", defaultValue);
- globalSettings = settings;
+ QString defaultValue = QStandardPaths::findExecutable("jvisualvm");
+ if (defaultValue.isNull())
+ {
+ defaultValue = QStandardPaths::findExecutable("visualvm");
+ }
+ settings->registerSetting("JVisualVMPath", defaultValue);
+ globalSettings = settings;
}
BaseExternalTool *JVisualVMFactory::createTool(InstancePtr instance, QObject *parent)
{
- return new JVisualVM(globalSettings, instance, parent);
+ return new JVisualVM(globalSettings, instance, parent);
}
bool JVisualVMFactory::check(QString *error)
{
- return check(globalSettings->get("JVisualVMPath").toString(), error);
+ return check(globalSettings->get("JVisualVMPath").toString(), error);
}
bool JVisualVMFactory::check(const QString &path, QString *error)
{
- if (path.isEmpty())
- {
- *error = QObject::tr("Empty path");
- return false;
- }
- QFileInfo finfo(path);
- if (!finfo.isExecutable() || !finfo.fileName().contains("visualvm"))
- {
- *error = QObject::tr("Invalid path to JVisualVM");
- return false;
- }
- return true;
+ if (path.isEmpty())
+ {
+ *error = QObject::tr("Empty path");
+ return false;
+ }
+ QFileInfo finfo(path);
+ if (!finfo.isExecutable() || !finfo.fileName().contains("visualvm"))
+ {
+ *error = QObject::tr("Invalid path to JVisualVM");
+ return false;
+ }
+ return true;
}
#include "JVisualVM.moc"
diff --git a/api/logic/tools/JVisualVM.h b/api/logic/tools/JVisualVM.h
index 0674da13..91d48d94 100644
--- a/api/logic/tools/JVisualVM.h
+++ b/api/logic/tools/JVisualVM.h
@@ -7,9 +7,9 @@
class MULTIMC_LOGIC_EXPORT JVisualVMFactory : public BaseProfilerFactory
{
public:
- QString name() const override { return "JVisualVM"; }
- void registerSettings(SettingsObjectPtr settings) override;
- BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
- bool check(QString *error) override;
- bool check(const QString &path, QString *error) override;
+ QString name() const override { return "JVisualVM"; }
+ void registerSettings(SettingsObjectPtr settings) override;
+ BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
+ bool check(QString *error) override;
+ bool check(const QString &path, QString *error) override;
};
diff --git a/api/logic/tools/MCEditTool.cpp b/api/logic/tools/MCEditTool.cpp
index 74715d3f..880327c7 100644
--- a/api/logic/tools/MCEditTool.cpp
+++ b/api/logic/tools/MCEditTool.cpp
@@ -10,68 +10,68 @@
MCEditTool::MCEditTool(SettingsObjectPtr settings)
{
- settings->registerSetting("MCEditPath");
- m_settings = settings;
+ settings->registerSetting("MCEditPath");
+ m_settings = settings;
}
void MCEditTool::setPath(QString& path)
{
- m_settings->set("MCEditPath", path);
+ m_settings->set("MCEditPath", path);
}
QString MCEditTool::path() const
{
- return m_settings->get("MCEditPath").toString();
+ return m_settings->get("MCEditPath").toString();
}
bool MCEditTool::check(const QString& toolPath, QString& error)
{
- if (toolPath.isEmpty())
- {
- error = QObject::tr("Path is empty");
- return false;
- }
- const QDir dir(toolPath);
- if (!dir.exists())
- {
- error = QObject::tr("Path does not exist");
- return false;
- }
- if (!dir.exists("mcedit.sh") && !dir.exists("mcedit.py") && !dir.exists("mcedit.exe") && !dir.exists("Contents") && !dir.exists("mcedit2.exe"))
- {
- error = QObject::tr("Path does not seem to be a MCEdit path");
- return false;
- }
- return true;
+ if (toolPath.isEmpty())
+ {
+ error = QObject::tr("Path is empty");
+ return false;
+ }
+ const QDir dir(toolPath);
+ if (!dir.exists())
+ {
+ error = QObject::tr("Path does not exist");
+ return false;
+ }
+ if (!dir.exists("mcedit.sh") && !dir.exists("mcedit.py") && !dir.exists("mcedit.exe") && !dir.exists("Contents") && !dir.exists("mcedit2.exe"))
+ {
+ error = QObject::tr("Path does not seem to be a MCEdit path");
+ return false;
+ }
+ return true;
}
QString MCEditTool::getProgramPath()
{
#ifdef Q_OS_OSX
- return path();
+ return path();
#else
- const QString mceditPath = path();
- QDir mceditDir(mceditPath);
+ const QString mceditPath = path();
+ QDir mceditDir(mceditPath);
#ifdef Q_OS_LINUX
- if (mceditDir.exists("mcedit.sh"))
- {
- return mceditDir.absoluteFilePath("mcedit.sh");
- }
- else if (mceditDir.exists("mcedit.py"))
- {
- return mceditDir.absoluteFilePath("mcedit.py");
- }
- return QString();
+ if (mceditDir.exists("mcedit.sh"))
+ {
+ return mceditDir.absoluteFilePath("mcedit.sh");
+ }
+ else if (mceditDir.exists("mcedit.py"))
+ {
+ return mceditDir.absoluteFilePath("mcedit.py");
+ }
+ return QString();
#elif defined(Q_OS_WIN32)
- if (mceditDir.exists("mcedit.exe"))
- {
- return mceditDir.absoluteFilePath("mcedit.exe");
- }
- else if (mceditDir.exists("mcedit2.exe"))
- {
- return mceditDir.absoluteFilePath("mcedit2.exe");
- }
- return QString();
+ if (mceditDir.exists("mcedit.exe"))
+ {
+ return mceditDir.absoluteFilePath("mcedit.exe");
+ }
+ else if (mceditDir.exists("mcedit2.exe"))
+ {
+ return mceditDir.absoluteFilePath("mcedit2.exe");
+ }
+ return QString();
#endif
#endif
}
diff --git a/api/logic/tools/MCEditTool.h b/api/logic/tools/MCEditTool.h
index 51feb1fe..1465494e 100644
--- a/api/logic/tools/MCEditTool.h
+++ b/api/logic/tools/MCEditTool.h
@@ -7,11 +7,11 @@
class MULTIMC_LOGIC_EXPORT MCEditTool
{
public:
- MCEditTool(SettingsObjectPtr settings);
- void setPath(QString & path);
- QString path() const;
- bool check(const QString &toolPath, QString &error);
- QString getProgramPath();
+ MCEditTool(SettingsObjectPtr settings);
+ void setPath(QString & path);
+ QString path() const;
+ bool check(const QString &toolPath, QString &error);
+ QString getProgramPath();
private:
- SettingsObjectPtr m_settings;
+ SettingsObjectPtr m_settings;
};
diff --git a/api/logic/translations/TranslationsModel.cpp b/api/logic/translations/TranslationsModel.cpp
index 18625ee5..185cc8c4 100644
--- a/api/logic/translations/TranslationsModel.cpp
+++ b/api/logic/translations/TranslationsModel.cpp
@@ -15,33 +15,33 @@ const static QLatin1Literal defaultLangCode("en");
struct Language
{
- QString key;
- QLocale locale;
- bool updated;
+ QString key;
+ QLocale locale;
+ bool updated;
};
struct TranslationsModel::Private
{
- QDir m_dir;
-
- // initial state is just english
- QVector<Language> m_languages = {{defaultLangCode, QLocale(defaultLangCode), false}};
- QString m_selectedLanguage = defaultLangCode;
- std::unique_ptr<QTranslator> m_qt_translator;
- std::unique_ptr<QTranslator> m_app_translator;
-
- std::shared_ptr<Net::Download> m_index_task;
- QString m_downloadingTranslation;
- NetJobPtr m_dl_job;
- NetJobPtr m_index_job;
- QString m_nextDownload;
+ QDir m_dir;
+
+ // initial state is just english
+ QVector<Language> m_languages = {{defaultLangCode, QLocale(defaultLangCode), false}};
+ QString m_selectedLanguage = defaultLangCode;
+ std::unique_ptr<QTranslator> m_qt_translator;
+ std::unique_ptr<QTranslator> m_app_translator;
+
+ std::shared_ptr<Net::Download> m_index_task;
+ QString m_downloadingTranslation;
+ NetJobPtr m_dl_job;
+ NetJobPtr m_index_job;
+ QString m_nextDownload;
};
TranslationsModel::TranslationsModel(QString path, QObject* parent): QAbstractListModel(parent)
{
- d.reset(new Private);
- d->m_dir.setPath(path);
- loadLocalIndex();
+ d.reset(new Private);
+ d->m_dir.setPath(path);
+ loadLocalIndex();
}
TranslationsModel::~TranslationsModel()
@@ -50,270 +50,270 @@ TranslationsModel::~TranslationsModel()
QVariant TranslationsModel::data(const QModelIndex& index, int role) const
{
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
-
- if (row < 0 || row >= d->m_languages.size())
- return QVariant();
-
- switch (role)
- {
- case Qt::DisplayRole:
- return d->m_languages[row].locale.nativeLanguageName();
- case Qt::UserRole:
- return d->m_languages[row].key;
- default:
- return QVariant();
- }
+ if (!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+
+ if (row < 0 || row >= d->m_languages.size())
+ return QVariant();
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ return d->m_languages[row].locale.nativeLanguageName();
+ case Qt::UserRole:
+ return d->m_languages[row].key;
+ default:
+ return QVariant();
+ }
}
int TranslationsModel::rowCount(const QModelIndex& parent) const
{
- return d->m_languages.size();
+ return d->m_languages.size();
}
Language * TranslationsModel::findLanguage(const QString& key)
{
- auto found = std::find_if(d->m_languages.begin(), d->m_languages.end(), [&](Language & lang)
- {
- return lang.key == key;
- });
- if(found == d->m_languages.end())
- {
- return nullptr;
- }
- else
- {
- return found;
- }
+ auto found = std::find_if(d->m_languages.begin(), d->m_languages.end(), [&](Language & lang)
+ {
+ return lang.key == key;
+ });
+ if(found == d->m_languages.end())
+ {
+ return nullptr;
+ }
+ else
+ {
+ return found;
+ }
}
bool TranslationsModel::selectLanguage(QString key)
{
- QString &langCode = key;
- auto langPtr = findLanguage(key);
- if(!langPtr)
- {
- qWarning() << "Selected invalid language" << key << ", defaulting to" << defaultLangCode;
- langCode = defaultLangCode;
- }
- else
- {
- langCode = langPtr->key;
- }
-
- // uninstall existing translators if there are any
- if (d->m_app_translator)
- {
- QCoreApplication::removeTranslator(d->m_app_translator.get());
- d->m_app_translator.reset();
- }
- if (d->m_qt_translator)
- {
- QCoreApplication::removeTranslator(d->m_qt_translator.get());
- d->m_qt_translator.reset();
- }
-
- /*
- * FIXME: potential source of crashes:
- * In a multithreaded application, the default locale should be set at application startup, before any non-GUI threads are created.
- * This function is not reentrant.
- */
- QLocale locale(langCode);
- QLocale::setDefault(locale);
-
- // if it's the default UI language, finish
- if(langCode == defaultLangCode)
- {
- d->m_selectedLanguage = langCode;
- return true;
- }
-
- // otherwise install new translations
- bool successful = false;
- // FIXME: this is likely never present. FIX IT.
- d->m_qt_translator.reset(new QTranslator());
- if (d->m_qt_translator->load("qt_" + langCode, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
- {
- qDebug() << "Loading Qt Language File for" << langCode.toLocal8Bit().constData() << "...";
- if (!QCoreApplication::installTranslator(d->m_qt_translator.get()))
- {
- qCritical() << "Loading Qt Language File failed.";
- d->m_qt_translator.reset();
- }
- else
- {
- successful = true;
- }
- }
- else
- {
- d->m_qt_translator.reset();
- }
-
- d->m_app_translator.reset(new QTranslator());
- if (d->m_app_translator->load("mmc_" + langCode, d->m_dir.path()))
- {
- qDebug() << "Loading Application Language File for" << langCode.toLocal8Bit().constData() << "...";
- if (!QCoreApplication::installTranslator(d->m_app_translator.get()))
- {
- qCritical() << "Loading Application Language File failed.";
- d->m_app_translator.reset();
- }
- else
- {
- successful = true;
- }
- }
- else
- {
- d->m_app_translator.reset();
- }
- d->m_selectedLanguage = langCode;
- return successful;
+ QString &langCode = key;
+ auto langPtr = findLanguage(key);
+ if(!langPtr)
+ {
+ qWarning() << "Selected invalid language" << key << ", defaulting to" << defaultLangCode;
+ langCode = defaultLangCode;
+ }
+ else
+ {
+ langCode = langPtr->key;
+ }
+
+ // uninstall existing translators if there are any
+ if (d->m_app_translator)
+ {
+ QCoreApplication::removeTranslator(d->m_app_translator.get());
+ d->m_app_translator.reset();
+ }
+ if (d->m_qt_translator)
+ {
+ QCoreApplication::removeTranslator(d->m_qt_translator.get());
+ d->m_qt_translator.reset();
+ }
+
+ /*
+ * FIXME: potential source of crashes:
+ * In a multithreaded application, the default locale should be set at application startup, before any non-GUI threads are created.
+ * This function is not reentrant.
+ */
+ QLocale locale(langCode);
+ QLocale::setDefault(locale);
+
+ // if it's the default UI language, finish
+ if(langCode == defaultLangCode)
+ {
+ d->m_selectedLanguage = langCode;
+ return true;
+ }
+
+ // otherwise install new translations
+ bool successful = false;
+ // FIXME: this is likely never present. FIX IT.
+ d->m_qt_translator.reset(new QTranslator());
+ if (d->m_qt_translator->load("qt_" + langCode, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+ {
+ qDebug() << "Loading Qt Language File for" << langCode.toLocal8Bit().constData() << "...";
+ if (!QCoreApplication::installTranslator(d->m_qt_translator.get()))
+ {
+ qCritical() << "Loading Qt Language File failed.";
+ d->m_qt_translator.reset();
+ }
+ else
+ {
+ successful = true;
+ }
+ }
+ else
+ {
+ d->m_qt_translator.reset();
+ }
+
+ d->m_app_translator.reset(new QTranslator());
+ if (d->m_app_translator->load("mmc_" + langCode, d->m_dir.path()))
+ {
+ qDebug() << "Loading Application Language File for" << langCode.toLocal8Bit().constData() << "...";
+ if (!QCoreApplication::installTranslator(d->m_app_translator.get()))
+ {
+ qCritical() << "Loading Application Language File failed.";
+ d->m_app_translator.reset();
+ }
+ else
+ {
+ successful = true;
+ }
+ }
+ else
+ {
+ d->m_app_translator.reset();
+ }
+ d->m_selectedLanguage = langCode;
+ return successful;
}
QModelIndex TranslationsModel::selectedIndex()
{
- auto found = findLanguage(d->m_selectedLanguage);
- if(found)
- {
- // QVector iterator freely converts to pointer to contained type
- return index(found - d->m_languages.begin(), 0, QModelIndex());
- }
- return QModelIndex();
+ auto found = findLanguage(d->m_selectedLanguage);
+ if(found)
+ {
+ // QVector iterator freely converts to pointer to contained type
+ return index(found - d->m_languages.begin(), 0, QModelIndex());
+ }
+ return QModelIndex();
}
QString TranslationsModel::selectedLanguage()
{
- return d->m_selectedLanguage;
+ return d->m_selectedLanguage;
}
void TranslationsModel::downloadIndex()
{
- if(d->m_index_job || d->m_dl_job)
- {
- return;
- }
- qDebug() << "Downloading Translations Index...";
- d->m_index_job.reset(new NetJob("Translations Index"));
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "index");
- d->m_index_task = Net::Download::makeCached(QUrl("http://files.multimc.org/translations/index"), entry);
- d->m_index_job->addNetAction(d->m_index_task);
- connect(d->m_index_job.get(), &NetJob::failed, this, &TranslationsModel::indexFailed);
- connect(d->m_index_job.get(), &NetJob::succeeded, this, &TranslationsModel::indexRecieved);
- d->m_index_job->start();
+ if(d->m_index_job || d->m_dl_job)
+ {
+ return;
+ }
+ qDebug() << "Downloading Translations Index...";
+ d->m_index_job.reset(new NetJob("Translations Index"));
+ MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "index");
+ d->m_index_task = Net::Download::makeCached(QUrl("http://files.multimc.org/translations/index"), entry);
+ d->m_index_job->addNetAction(d->m_index_task);
+ connect(d->m_index_job.get(), &NetJob::failed, this, &TranslationsModel::indexFailed);
+ connect(d->m_index_job.get(), &NetJob::succeeded, this, &TranslationsModel::indexRecieved);
+ d->m_index_job->start();
}
void TranslationsModel::indexRecieved()
{
- qDebug() << "Got translations index!";
- d->m_index_job.reset();
- loadLocalIndex();
- if(d->m_selectedLanguage != defaultLangCode)
- {
- downloadTranslation(d->m_selectedLanguage);
- }
+ qDebug() << "Got translations index!";
+ d->m_index_job.reset();
+ loadLocalIndex();
+ if(d->m_selectedLanguage != defaultLangCode)
+ {
+ downloadTranslation(d->m_selectedLanguage);
+ }
}
void TranslationsModel::loadLocalIndex()
{
- QByteArray data;
- try
- {
- data = FS::read(d->m_dir.absoluteFilePath("index"));
- }
- catch (const Exception &e)
- {
- qCritical() << "Translations Download Failed: index file not readable";
- return;
- }
- QVector<Language> languages;
- QList<QByteArray> lines = data.split('\n');
- // add the default english.
- languages.append({defaultLangCode, QLocale(defaultLangCode), true});
- for (const auto line : lines)
- {
- if(!line.isEmpty())
- {
- auto str = QString::fromLatin1(line);
- str.remove(".qm");
- languages.append({str, QLocale(str), false});
- }
- }
- beginResetModel();
- d->m_languages.swap(languages);
- endResetModel();
+ QByteArray data;
+ try
+ {
+ data = FS::read(d->m_dir.absoluteFilePath("index"));
+ }
+ catch (const Exception &e)
+ {
+ qCritical() << "Translations Download Failed: index file not readable";
+ return;
+ }
+ QVector<Language> languages;
+ QList<QByteArray> lines = data.split('\n');
+ // add the default english.
+ languages.append({defaultLangCode, QLocale(defaultLangCode), true});
+ for (const auto line : lines)
+ {
+ if(!line.isEmpty())
+ {
+ auto str = QString::fromLatin1(line);
+ str.remove(".qm");
+ languages.append({str, QLocale(str), false});
+ }
+ }
+ beginResetModel();
+ d->m_languages.swap(languages);
+ endResetModel();
}
void TranslationsModel::updateLanguage(QString key)
{
- if(key == defaultLangCode)
- {
- qWarning() << "Cannot update builtin language" << key;
- return;
- }
- auto found = findLanguage(key);
- if(!found)
- {
- qWarning() << "Cannot update invalid language" << key;
- return;
- }
- if(!found->updated)
- {
- downloadTranslation(key);
- }
+ if(key == defaultLangCode)
+ {
+ qWarning() << "Cannot update builtin language" << key;
+ return;
+ }
+ auto found = findLanguage(key);
+ if(!found)
+ {
+ qWarning() << "Cannot update invalid language" << key;
+ return;
+ }
+ if(!found->updated)
+ {
+ downloadTranslation(key);
+ }
}
void TranslationsModel::downloadTranslation(QString key)
{
- if(d->m_dl_job)
- {
- d->m_nextDownload = key;
- return;
- }
- d->m_downloadingTranslation = key;
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "mmc_" + key + ".qm");
- entry->setStale(true);
- d->m_dl_job.reset(new NetJob("Translation for " + key));
- d->m_dl_job->addNetAction(Net::Download::makeCached(QUrl(URLConstants::TRANSLATIONS_BASE_URL + key + ".qm"), entry));
- connect(d->m_dl_job.get(), &NetJob::succeeded, this, &TranslationsModel::dlGood);
- connect(d->m_dl_job.get(), &NetJob::failed, this, &TranslationsModel::dlFailed);
- d->m_dl_job->start();
+ if(d->m_dl_job)
+ {
+ d->m_nextDownload = key;
+ return;
+ }
+ d->m_downloadingTranslation = key;
+ MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "mmc_" + key + ".qm");
+ entry->setStale(true);
+ d->m_dl_job.reset(new NetJob("Translation for " + key));
+ d->m_dl_job->addNetAction(Net::Download::makeCached(QUrl(URLConstants::TRANSLATIONS_BASE_URL + key + ".qm"), entry));
+ connect(d->m_dl_job.get(), &NetJob::succeeded, this, &TranslationsModel::dlGood);
+ connect(d->m_dl_job.get(), &NetJob::failed, this, &TranslationsModel::dlFailed);
+ d->m_dl_job->start();
}
void TranslationsModel::downloadNext()
{
- if(!d->m_nextDownload.isEmpty())
- {
- downloadTranslation(d->m_nextDownload);
- d->m_nextDownload.clear();
- }
+ if(!d->m_nextDownload.isEmpty())
+ {
+ downloadTranslation(d->m_nextDownload);
+ d->m_nextDownload.clear();
+ }
}
void TranslationsModel::dlFailed(QString reason)
{
- qCritical() << "Translations Download Failed:" << reason;
- d->m_dl_job.reset();
- downloadNext();
+ qCritical() << "Translations Download Failed:" << reason;
+ d->m_dl_job.reset();
+ downloadNext();
}
void TranslationsModel::dlGood()
{
- qDebug() << "Got translation:" << d->m_downloadingTranslation;
-
- if(d->m_downloadingTranslation == d->m_selectedLanguage)
- {
- selectLanguage(d->m_selectedLanguage);
- }
- d->m_dl_job.reset();
- downloadNext();
+ qDebug() << "Got translation:" << d->m_downloadingTranslation;
+
+ if(d->m_downloadingTranslation == d->m_selectedLanguage)
+ {
+ selectLanguage(d->m_selectedLanguage);
+ }
+ d->m_dl_job.reset();
+ downloadNext();
}
void TranslationsModel::indexFailed(QString reason)
{
- qCritical() << "Translations Index Download Failed:" << reason;
- d->m_index_job.reset();
+ qCritical() << "Translations Index Download Failed:" << reason;
+ d->m_index_job.reset();
}
diff --git a/api/logic/translations/TranslationsModel.h b/api/logic/translations/TranslationsModel.h
index bd481134..8a9298d4 100644
--- a/api/logic/translations/TranslationsModel.h
+++ b/api/logic/translations/TranslationsModel.h
@@ -23,39 +23,39 @@ struct Language;
class MULTIMC_LOGIC_EXPORT TranslationsModel : public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit TranslationsModel(QString path, QObject *parent = 0);
- virtual ~TranslationsModel();
+ explicit TranslationsModel(QString path, QObject *parent = 0);
+ virtual ~TranslationsModel();
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- bool selectLanguage(QString key);
- void updateLanguage(QString key);
- QModelIndex selectedIndex();
- QString selectedLanguage();
+ bool selectLanguage(QString key);
+ void updateLanguage(QString key);
+ QModelIndex selectedIndex();
+ QString selectedLanguage();
- void downloadIndex();
+ void downloadIndex();
private:
- Language *findLanguage(const QString & key);
- void loadLocalIndex();
- void downloadTranslation(QString key);
- void downloadNext();
+ Language *findLanguage(const QString & key);
+ void loadLocalIndex();
+ void downloadTranslation(QString key);
+ void downloadNext();
- // hide copy constructor
- TranslationsModel(const TranslationsModel &) = delete;
- // hide assign op
- TranslationsModel &operator=(const TranslationsModel &) = delete;
+ // hide copy constructor
+ TranslationsModel(const TranslationsModel &) = delete;
+ // hide assign op
+ TranslationsModel &operator=(const TranslationsModel &) = delete;
private slots:
- void indexRecieved();
- void indexFailed(QString reason);
- void dlFailed(QString reason);
- void dlGood();
+ void indexRecieved();
+ void indexFailed(QString reason);
+ void dlFailed(QString reason);
+ void dlGood();
private: /* data */
- struct Private;
- std::unique_ptr<Private> d;
+ struct Private;
+ std::unique_ptr<Private> d;
};
diff --git a/api/logic/updater/DownloadTask.cpp b/api/logic/updater/DownloadTask.cpp
index e0adf593..cb92018d 100644
--- a/api/logic/updater/DownloadTask.cpp
+++ b/api/logic/updater/DownloadTask.cpp
@@ -27,140 +27,140 @@ namespace GoUpdate
{
DownloadTask::DownloadTask(Status status, QString target, QObject *parent)
- : Task(parent), m_updateFilesDir(target)
+ : Task(parent), m_updateFilesDir(target)
{
- m_status = status;
+ m_status = status;
- m_updateFilesDir.setAutoRemove(false);
+ m_updateFilesDir.setAutoRemove(false);
}
void DownloadTask::executeTask()
{
- loadVersionInfo();
+ loadVersionInfo();
}
void DownloadTask::loadVersionInfo()
{
- setStatus(tr("Loading version information..."));
+ setStatus(tr("Loading version information..."));
- NetJob *netJob = new NetJob("Version Info");
+ NetJob *netJob = new NetJob("Version Info");
- // Find the index URL.
- QUrl newIndexUrl = QUrl(m_status.newRepoUrl).resolved(QString::number(m_status.newVersionId) + ".json");
- qDebug() << m_status.newRepoUrl << " turns into " << newIndexUrl;
+ // Find the index URL.
+ QUrl newIndexUrl = QUrl(m_status.newRepoUrl).resolved(QString::number(m_status.newVersionId) + ".json");
+ qDebug() << m_status.newRepoUrl << " turns into " << newIndexUrl;
- netJob->addNetAction(m_newVersionFileListDownload = Net::Download::makeByteArray(newIndexUrl, &newVersionFileListData));
+ netJob->addNetAction(m_newVersionFileListDownload = Net::Download::makeByteArray(newIndexUrl, &newVersionFileListData));
- // If we have a current version URL, get that one too.
- if (!m_status.currentRepoUrl.isEmpty())
- {
- QUrl cIndexUrl = QUrl(m_status.currentRepoUrl).resolved(QString::number(m_status.currentVersionId) + ".json");
- netJob->addNetAction(m_currentVersionFileListDownload = Net::Download::makeByteArray(cIndexUrl, &currentVersionFileListData));
- qDebug() << m_status.currentRepoUrl << " turns into " << cIndexUrl;
- }
+ // If we have a current version URL, get that one too.
+ if (!m_status.currentRepoUrl.isEmpty())
+ {
+ QUrl cIndexUrl = QUrl(m_status.currentRepoUrl).resolved(QString::number(m_status.currentVersionId) + ".json");
+ netJob->addNetAction(m_currentVersionFileListDownload = Net::Download::makeByteArray(cIndexUrl, &currentVersionFileListData));
+ qDebug() << m_status.currentRepoUrl << " turns into " << cIndexUrl;
+ }
- // connect signals and start the job
- connect(netJob, &NetJob::succeeded, this, &DownloadTask::processDownloadedVersionInfo);
- connect(netJob, &NetJob::failed, this, &DownloadTask::vinfoDownloadFailed);
- m_vinfoNetJob.reset(netJob);
- netJob->start();
+ // connect signals and start the job
+ connect(netJob, &NetJob::succeeded, this, &DownloadTask::processDownloadedVersionInfo);
+ connect(netJob, &NetJob::failed, this, &DownloadTask::vinfoDownloadFailed);
+ m_vinfoNetJob.reset(netJob);
+ netJob->start();
}
void DownloadTask::vinfoDownloadFailed()
{
- // Something failed. We really need the second download (current version info), so parse
- // downloads anyways as long as the first one succeeded.
- if (m_newVersionFileListDownload->wasSuccessful())
- {
- processDownloadedVersionInfo();
- return;
- }
-
- // TODO: Give a more detailed error message.
- qCritical() << "Failed to download version info files.";
- emitFailed(tr("Failed to download version info files."));
+ // Something failed. We really need the second download (current version info), so parse
+ // downloads anyways as long as the first one succeeded.
+ if (m_newVersionFileListDownload->wasSuccessful())
+ {
+ processDownloadedVersionInfo();
+ return;
+ }
+
+ // TODO: Give a more detailed error message.
+ qCritical() << "Failed to download version info files.";
+ emitFailed(tr("Failed to download version info files."));
}
void DownloadTask::processDownloadedVersionInfo()
{
- VersionFileList m_currentVersionFileList;
- VersionFileList m_newVersionFileList;
-
- setStatus(tr("Reading file list for new version..."));
- qDebug() << "Reading file list for new version...";
- QString error;
- if (!parseVersionInfo(newVersionFileListData, m_newVersionFileList, error))
- {
- qCritical() << error;
- emitFailed(error);
- return;
- }
-
- // if we have the current version info, use it.
- if (m_currentVersionFileListDownload && m_currentVersionFileListDownload->wasSuccessful())
- {
- setStatus(tr("Reading file list for current version..."));
- qDebug() << "Reading file list for current version...";
- // if this fails, it's not a complete loss.
- QString error;
- if(!parseVersionInfo( currentVersionFileListData, m_currentVersionFileList, error))
- {
- qDebug() << error << "This is not a fatal error.";
- }
- }
-
- // We don't need this any more.
- m_currentVersionFileListDownload.reset();
- m_newVersionFileListDownload.reset();
- m_vinfoNetJob.reset();
-
- setStatus(tr("Processing file lists - figuring out how to install the update..."));
-
- // make a new netjob for the actual update files
- NetJobPtr netJob (new NetJob("Update Files"));
-
- // fill netJob and operationList
- if (!processFileLists(m_currentVersionFileList, m_newVersionFileList, m_status.rootPath, m_updateFilesDir.path(), netJob, m_operations))
- {
- emitFailed(tr("Failed to process update lists..."));
- return;
- }
-
- // Now start the download.
- QObject::connect(netJob.get(), &NetJob::succeeded, this, &DownloadTask::fileDownloadFinished);
- QObject::connect(netJob.get(), &NetJob::progress, this, &DownloadTask::fileDownloadProgressChanged);
- QObject::connect(netJob.get(), &NetJob::failed, this, &DownloadTask::fileDownloadFailed);
-
- setStatus(tr("Downloading %1 update files.").arg(QString::number(netJob->size())));
- qDebug() << "Begin downloading update files to" << m_updateFilesDir.path();
- m_filesNetJob = netJob;
- m_filesNetJob->start();
+ VersionFileList m_currentVersionFileList;
+ VersionFileList m_newVersionFileList;
+
+ setStatus(tr("Reading file list for new version..."));
+ qDebug() << "Reading file list for new version...";
+ QString error;
+ if (!parseVersionInfo(newVersionFileListData, m_newVersionFileList, error))
+ {
+ qCritical() << error;
+ emitFailed(error);
+ return;
+ }
+
+ // if we have the current version info, use it.
+ if (m_currentVersionFileListDownload && m_currentVersionFileListDownload->wasSuccessful())
+ {
+ setStatus(tr("Reading file list for current version..."));
+ qDebug() << "Reading file list for current version...";
+ // if this fails, it's not a complete loss.
+ QString error;
+ if(!parseVersionInfo( currentVersionFileListData, m_currentVersionFileList, error))
+ {
+ qDebug() << error << "This is not a fatal error.";
+ }
+ }
+
+ // We don't need this any more.
+ m_currentVersionFileListDownload.reset();
+ m_newVersionFileListDownload.reset();
+ m_vinfoNetJob.reset();
+
+ setStatus(tr("Processing file lists - figuring out how to install the update..."));
+
+ // make a new netjob for the actual update files
+ NetJobPtr netJob (new NetJob("Update Files"));
+
+ // fill netJob and operationList
+ if (!processFileLists(m_currentVersionFileList, m_newVersionFileList, m_status.rootPath, m_updateFilesDir.path(), netJob, m_operations))
+ {
+ emitFailed(tr("Failed to process update lists..."));
+ return;
+ }
+
+ // Now start the download.
+ QObject::connect(netJob.get(), &NetJob::succeeded, this, &DownloadTask::fileDownloadFinished);
+ QObject::connect(netJob.get(), &NetJob::progress, this, &DownloadTask::fileDownloadProgressChanged);
+ QObject::connect(netJob.get(), &NetJob::failed, this, &DownloadTask::fileDownloadFailed);
+
+ setStatus(tr("Downloading %1 update files.").arg(QString::number(netJob->size())));
+ qDebug() << "Begin downloading update files to" << m_updateFilesDir.path();
+ m_filesNetJob = netJob;
+ m_filesNetJob->start();
}
void DownloadTask::fileDownloadFinished()
{
- emitSucceeded();
+ emitSucceeded();
}
void DownloadTask::fileDownloadFailed(QString reason)
{
- qCritical() << "Failed to download update files:" << reason;
- emitFailed(tr("Failed to download update files: %1").arg(reason));
+ qCritical() << "Failed to download update files:" << reason;
+ emitFailed(tr("Failed to download update files: %1").arg(reason));
}
void DownloadTask::fileDownloadProgressChanged(qint64 current, qint64 total)
{
- setProgress(current, total);
+ setProgress(current, total);
}
QString DownloadTask::updateFilesDir()
{
- return m_updateFilesDir.path();
+ return m_updateFilesDir.path();
}
OperationList DownloadTask::operations()
{
- return m_operations;
+ return m_operations;
}
} \ No newline at end of file
diff --git a/api/logic/updater/DownloadTask.h b/api/logic/updater/DownloadTask.h
index 8330d3e8..30b4b9ec 100644
--- a/api/logic/updater/DownloadTask.h
+++ b/api/logic/updater/DownloadTask.h
@@ -29,70 +29,70 @@ namespace GoUpdate
*/
class MULTIMC_LOGIC_EXPORT DownloadTask : public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- /**
- * Create a download task
- *
- * target is a template - XXXXXX at the end will be replaced with a random generated string, ensuring uniqueness
- */
- explicit DownloadTask(Status status, QString target, QObject* parent = 0);
- virtual ~DownloadTask() {};
+ /**
+ * Create a download task
+ *
+ * target is a template - XXXXXX at the end will be replaced with a random generated string, ensuring uniqueness
+ */
+ explicit DownloadTask(Status status, QString target, QObject* parent = 0);
+ virtual ~DownloadTask() {};
- /// Get the directory that will contain the update files.
- QString updateFilesDir();
+ /// Get the directory that will contain the update files.
+ QString updateFilesDir();
- /// Get the list of operations that should be done
- OperationList operations();
+ /// Get the list of operations that should be done
+ OperationList operations();
- /// set updater download behavior
- void setUseLocalUpdater(bool useLocal);
+ /// set updater download behavior
+ void setUseLocalUpdater(bool useLocal);
protected:
- //! Entry point for tasks.
- virtual void executeTask() override;
-
- /*!
- * Downloads the version info files from the repository.
- * The files for both the current build, and the build that we're updating to need to be downloaded.
- * If the current version's info file can't be found, MultiMC will not delete files that
- * were removed between versions. It will still replace files that have changed, however.
- * Note that although the repository URL for the current version is not given to the update task,
- * the task will attempt to look it up in the UpdateChecker's channel list.
- * If an error occurs here, the function will call emitFailed and return false.
- */
- void loadVersionInfo();
-
- NetJobPtr m_vinfoNetJob;
- QByteArray currentVersionFileListData;
- QByteArray newVersionFileListData;
- Net::Download::Ptr m_currentVersionFileListDownload;
- Net::Download::Ptr m_newVersionFileListDownload;
-
- NetJobPtr m_filesNetJob;
-
- Status m_status;
-
- OperationList m_operations;
-
- /*!
- * Temporary directory to store update files in.
- * This will be set to not auto delete. Task will fail if this fails to be created.
- */
- QTemporaryDir m_updateFilesDir;
+ //! Entry point for tasks.
+ virtual void executeTask() override;
+
+ /*!
+ * Downloads the version info files from the repository.
+ * The files for both the current build, and the build that we're updating to need to be downloaded.
+ * If the current version's info file can't be found, MultiMC will not delete files that
+ * were removed between versions. It will still replace files that have changed, however.
+ * Note that although the repository URL for the current version is not given to the update task,
+ * the task will attempt to look it up in the UpdateChecker's channel list.
+ * If an error occurs here, the function will call emitFailed and return false.
+ */
+ void loadVersionInfo();
+
+ NetJobPtr m_vinfoNetJob;
+ QByteArray currentVersionFileListData;
+ QByteArray newVersionFileListData;
+ Net::Download::Ptr m_currentVersionFileListDownload;
+ Net::Download::Ptr m_newVersionFileListDownload;
+
+ NetJobPtr m_filesNetJob;
+
+ Status m_status;
+
+ OperationList m_operations;
+
+ /*!
+ * Temporary directory to store update files in.
+ * This will be set to not auto delete. Task will fail if this fails to be created.
+ */
+ QTemporaryDir m_updateFilesDir;
protected slots:
- /*!
- * This function is called when version information is finished downloading
- * and at least the new file list download succeeded
- */
- void processDownloadedVersionInfo();
- void vinfoDownloadFailed();
-
- void fileDownloadFinished();
- void fileDownloadFailed(QString reason);
- void fileDownloadProgressChanged(qint64 current, qint64 total);
+ /*!
+ * This function is called when version information is finished downloading
+ * and at least the new file list download succeeded
+ */
+ void processDownloadedVersionInfo();
+ void vinfoDownloadFailed();
+
+ void fileDownloadFinished();
+ void fileDownloadFailed(QString reason);
+ void fileDownloadProgressChanged(qint64 current, qint64 total);
};
} \ No newline at end of file
diff --git a/api/logic/updater/DownloadTask_test.cpp b/api/logic/updater/DownloadTask_test.cpp
index e75c3ffa..531b2527 100644
--- a/api/logic/updater/DownloadTask_test.cpp
+++ b/api/logic/updater/DownloadTask_test.cpp
@@ -12,11 +12,11 @@ using namespace GoUpdate;
FileSourceList encodeBaseFile(const char *suffix)
{
- auto base = QDir::currentPath();
- QUrl localFile = QUrl::fromLocalFile(base + suffix);
- QString localUrlString = localFile.toString(QUrl::FullyEncoded);
- auto item = FileSource("http", localUrlString);
- return FileSourceList({item});
+ auto base = QDir::currentPath();
+ QUrl localFile = QUrl::fromLocalFile(base + suffix);
+ QString localUrlString = localFile.toString(QUrl::FullyEncoded);
+ auto item = FileSource("http", localUrlString);
+ return FileSourceList({item});
}
Q_DECLARE_METATYPE(VersionFileList)
@@ -24,191 +24,191 @@ Q_DECLARE_METATYPE(Operation)
QDebug operator<<(QDebug dbg, const FileSource &f)
{
- dbg.nospace() << "FileSource(type=" << f.type << " url=" << f.url
- << " comp=" << f.compressionType << ")";
- return dbg.maybeSpace();
+ dbg.nospace() << "FileSource(type=" << f.type << " url=" << f.url
+ << " comp=" << f.compressionType << ")";
+ return dbg.maybeSpace();
}
QDebug operator<<(QDebug dbg, const VersionFileEntry &v)
{
- dbg.nospace() << "VersionFileEntry(path=" << v.path << " mode=" << v.mode
- << " md5=" << v.md5 << " sources=" << v.sources << ")";
- return dbg.maybeSpace();
+ dbg.nospace() << "VersionFileEntry(path=" << v.path << " mode=" << v.mode
+ << " md5=" << v.md5 << " sources=" << v.sources << ")";
+ return dbg.maybeSpace();
}
QDebug operator<<(QDebug dbg, const Operation::Type &t)
{
- switch (t)
- {
- case Operation::OP_REPLACE:
- dbg << "OP_COPY";
- break;
- case Operation::OP_DELETE:
- dbg << "OP_DELETE";
- break;
- }
- return dbg.maybeSpace();
+ switch (t)
+ {
+ case Operation::OP_REPLACE:
+ dbg << "OP_COPY";
+ break;
+ case Operation::OP_DELETE:
+ dbg << "OP_DELETE";
+ break;
+ }
+ return dbg.maybeSpace();
}
QDebug operator<<(QDebug dbg, const Operation &u)
{
- dbg.nospace() << "Operation(type=" << u.type << " file=" << u.source
- << " dest=" << u.destination << " mode=" << u.destinationMode << ")";
- return dbg.maybeSpace();
+ dbg.nospace() << "Operation(type=" << u.type << " file=" << u.source
+ << " dest=" << u.destination << " mode=" << u.destinationMode << ")";
+ return dbg.maybeSpace();
}
class DownloadTaskTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- void initTestCase()
- {
- }
- void cleanupTestCase()
- {
- }
-
- void test_parseVersionInfo_data()
- {
- QTest::addColumn<QByteArray>("data");
- QTest::addColumn<VersionFileList>("list");
- QTest::addColumn<QString>("error");
- QTest::addColumn<bool>("ret");
-
- QTest::newRow("one")
- << MULTIMC_GET_TEST_FILE("data/1.json")
- << (VersionFileList()
- << VersionFileEntry{"fileOne",
- 493,
- encodeBaseFile("/data/fileOneA"),
- "9eb84090956c484e32cb6c08455a667b"}
- << VersionFileEntry{"fileTwo",
- 644,
- encodeBaseFile("/data/fileTwo"),
- "38f94f54fa3eb72b0ea836538c10b043"}
- << VersionFileEntry{"fileThree",
- 750,
- encodeBaseFile("/data/fileThree"),
- "f12df554b21e320be6471d7154130e70"})
- << QString() << true;
- QTest::newRow("two")
- << MULTIMC_GET_TEST_FILE("data/2.json")
- << (VersionFileList()
- << VersionFileEntry{"fileOne",
- 493,
- encodeBaseFile("/data/fileOneB"),
- "42915a71277c9016668cce7b82c6b577"}
- << VersionFileEntry{"fileTwo",
- 644,
- encodeBaseFile("/data/fileTwo"),
- "38f94f54fa3eb72b0ea836538c10b043"})
- << QString() << true;
- }
- void test_parseVersionInfo()
- {
- QFETCH(QByteArray, data);
- QFETCH(VersionFileList, list);
- QFETCH(QString, error);
- QFETCH(bool, ret);
-
- VersionFileList outList;
- QString outError;
- bool outRet = parseVersionInfo(data, outList, outError);
- QCOMPARE(outRet, ret);
- QCOMPARE(outList, list);
- QCOMPARE(outError, error);
- }
-
- void test_processFileLists_data()
- {
- QTest::addColumn<QString>("tempFolder");
- QTest::addColumn<VersionFileList>("currentVersion");
- QTest::addColumn<VersionFileList>("newVersion");
- QTest::addColumn<OperationList>("expectedOperations");
-
- QTemporaryDir tempFolderObj;
- QString tempFolder = tempFolderObj.path();
- // update fileOne, keep fileTwo, remove fileThree
- QTest::newRow("test 1")
- << tempFolder << (VersionFileList()
- << VersionFileEntry{
- "data/fileOne", 493,
- FileSourceList()
- << FileSource(
- "http", "http://host/path/fileOne-1"),
- "9eb84090956c484e32cb6c08455a667b"}
- << VersionFileEntry{
- "data/fileTwo", 644,
- FileSourceList()
- << FileSource(
- "http", "http://host/path/fileTwo-1"),
- "38f94f54fa3eb72b0ea836538c10b043"}
- << VersionFileEntry{
- "data/fileThree", 420,
- FileSourceList()
- << FileSource(
- "http", "http://host/path/fileThree-1"),
- "f12df554b21e320be6471d7154130e70"})
- << (VersionFileList()
- << VersionFileEntry{
- "data/fileOne", 493,
- FileSourceList()
- << FileSource("http",
- "http://host/path/fileOne-2"),
- "42915a71277c9016668cce7b82c6b577"}
- << VersionFileEntry{
- "data/fileTwo", 644,
- FileSourceList()
- << FileSource("http",
- "http://host/path/fileTwo-2"),
- "38f94f54fa3eb72b0ea836538c10b043"})
- << (OperationList()
- << Operation::DeleteOp("data/fileThree")
- << Operation::CopyOp(
- FS::PathCombine(tempFolder,
- QString("data/fileOne").replace("/", "_")),
- "data/fileOne", 493));
- }
- void test_processFileLists()
- {
- QFETCH(QString, tempFolder);
- QFETCH(VersionFileList, currentVersion);
- QFETCH(VersionFileList, newVersion);
- QFETCH(OperationList, expectedOperations);
-
- OperationList operations;
-
- processFileLists(currentVersion, newVersion, QDir::currentPath(), tempFolder, new NetJob("Dummy"), operations);
- qDebug() << (operations == expectedOperations);
- qDebug() << operations;
- qDebug() << expectedOperations;
- QCOMPARE(operations, expectedOperations);
- }
-
- void test_OSXPathFixup()
- {
- QString path, pathOrig;
- bool result;
- // Proper OSX path
- pathOrig = path = "MultiMC.app/Foo/Bar/Baz";
- qDebug() << "Proper OSX path: " << path;
- result = fixPathForOSX(path);
- QCOMPARE(path, QString("Foo/Bar/Baz"));
- QCOMPARE(result, true);
-
- // Bad OSX path
- pathOrig = path = "translations/klingon.lol";
- qDebug() << "Bad OSX path: " << path;
- result = fixPathForOSX(path);
- QCOMPARE(path, pathOrig);
- QCOMPARE(result, false);
- }
+ void initTestCase()
+ {
+ }
+ void cleanupTestCase()
+ {
+ }
+
+ void test_parseVersionInfo_data()
+ {
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<VersionFileList>("list");
+ QTest::addColumn<QString>("error");
+ QTest::addColumn<bool>("ret");
+
+ QTest::newRow("one")
+ << MULTIMC_GET_TEST_FILE("data/1.json")
+ << (VersionFileList()
+ << VersionFileEntry{"fileOne",
+ 493,
+ encodeBaseFile("/data/fileOneA"),
+ "9eb84090956c484e32cb6c08455a667b"}
+ << VersionFileEntry{"fileTwo",
+ 644,
+ encodeBaseFile("/data/fileTwo"),
+ "38f94f54fa3eb72b0ea836538c10b043"}
+ << VersionFileEntry{"fileThree",
+ 750,
+ encodeBaseFile("/data/fileThree"),
+ "f12df554b21e320be6471d7154130e70"})
+ << QString() << true;
+ QTest::newRow("two")
+ << MULTIMC_GET_TEST_FILE("data/2.json")
+ << (VersionFileList()
+ << VersionFileEntry{"fileOne",
+ 493,
+ encodeBaseFile("/data/fileOneB"),
+ "42915a71277c9016668cce7b82c6b577"}
+ << VersionFileEntry{"fileTwo",
+ 644,
+ encodeBaseFile("/data/fileTwo"),
+ "38f94f54fa3eb72b0ea836538c10b043"})
+ << QString() << true;
+ }
+ void test_parseVersionInfo()
+ {
+ QFETCH(QByteArray, data);
+ QFETCH(VersionFileList, list);
+ QFETCH(QString, error);
+ QFETCH(bool, ret);
+
+ VersionFileList outList;
+ QString outError;
+ bool outRet = parseVersionInfo(data, outList, outError);
+ QCOMPARE(outRet, ret);
+ QCOMPARE(outList, list);
+ QCOMPARE(outError, error);
+ }
+
+ void test_processFileLists_data()
+ {
+ QTest::addColumn<QString>("tempFolder");
+ QTest::addColumn<VersionFileList>("currentVersion");
+ QTest::addColumn<VersionFileList>("newVersion");
+ QTest::addColumn<OperationList>("expectedOperations");
+
+ QTemporaryDir tempFolderObj;
+ QString tempFolder = tempFolderObj.path();
+ // update fileOne, keep fileTwo, remove fileThree
+ QTest::newRow("test 1")
+ << tempFolder << (VersionFileList()
+ << VersionFileEntry{
+ "data/fileOne", 493,
+ FileSourceList()
+ << FileSource(
+ "http", "http://host/path/fileOne-1"),
+ "9eb84090956c484e32cb6c08455a667b"}
+ << VersionFileEntry{
+ "data/fileTwo", 644,
+ FileSourceList()
+ << FileSource(
+ "http", "http://host/path/fileTwo-1"),
+ "38f94f54fa3eb72b0ea836538c10b043"}
+ << VersionFileEntry{
+ "data/fileThree", 420,
+ FileSourceList()
+ << FileSource(
+ "http", "http://host/path/fileThree-1"),
+ "f12df554b21e320be6471d7154130e70"})
+ << (VersionFileList()
+ << VersionFileEntry{
+ "data/fileOne", 493,
+ FileSourceList()
+ << FileSource("http",
+ "http://host/path/fileOne-2"),
+ "42915a71277c9016668cce7b82c6b577"}
+ << VersionFileEntry{
+ "data/fileTwo", 644,
+ FileSourceList()
+ << FileSource("http",
+ "http://host/path/fileTwo-2"),
+ "38f94f54fa3eb72b0ea836538c10b043"})
+ << (OperationList()
+ << Operation::DeleteOp("data/fileThree")
+ << Operation::CopyOp(
+ FS::PathCombine(tempFolder,
+ QString("data/fileOne").replace("/", "_")),
+ "data/fileOne", 493));
+ }
+ void test_processFileLists()
+ {
+ QFETCH(QString, tempFolder);
+ QFETCH(VersionFileList, currentVersion);
+ QFETCH(VersionFileList, newVersion);
+ QFETCH(OperationList, expectedOperations);
+
+ OperationList operations;
+
+ processFileLists(currentVersion, newVersion, QDir::currentPath(), tempFolder, new NetJob("Dummy"), operations);
+ qDebug() << (operations == expectedOperations);
+ qDebug() << operations;
+ qDebug() << expectedOperations;
+ QCOMPARE(operations, expectedOperations);
+ }
+
+ void test_OSXPathFixup()
+ {
+ QString path, pathOrig;
+ bool result;
+ // Proper OSX path
+ pathOrig = path = "MultiMC.app/Foo/Bar/Baz";
+ qDebug() << "Proper OSX path: " << path;
+ result = fixPathForOSX(path);
+ QCOMPARE(path, QString("Foo/Bar/Baz"));
+ QCOMPARE(result, true);
+
+ // Bad OSX path
+ pathOrig = path = "translations/klingon.lol";
+ qDebug() << "Bad OSX path: " << path;
+ result = fixPathForOSX(path);
+ QCOMPARE(path, pathOrig);
+ QCOMPARE(result, false);
+ }
};
extern "C"
{
- QTEST_GUILESS_MAIN(DownloadTaskTest)
+ QTEST_GUILESS_MAIN(DownloadTaskTest)
}
#include "DownloadTask_test.moc"
diff --git a/api/logic/updater/GoUpdate.cpp b/api/logic/updater/GoUpdate.cpp
index 716048a0..ef040db6 100644
--- a/api/logic/updater/GoUpdate.cpp
+++ b/api/logic/updater/GoUpdate.cpp
@@ -12,208 +12,208 @@ namespace GoUpdate
bool parseVersionInfo(const QByteArray &data, VersionFileList &list, QString &error)
{
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- error = QString("Failed to parse version info JSON: %1 at %2")
- .arg(jsonError.errorString())
- .arg(jsonError.offset);
- qCritical() << error;
- return false;
- }
-
- QJsonObject json = jsonDoc.object();
-
- qDebug() << data;
- qDebug() << "Loading version info from JSON.";
- QJsonArray filesArray = json.value("Files").toArray();
- for (QJsonValue fileValue : filesArray)
- {
- QJsonObject fileObj = fileValue.toObject();
-
- QString file_path = fileObj.value("Path").toString();
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
+ if (jsonError.error != QJsonParseError::NoError)
+ {
+ error = QString("Failed to parse version info JSON: %1 at %2")
+ .arg(jsonError.errorString())
+ .arg(jsonError.offset);
+ qCritical() << error;
+ return false;
+ }
+
+ QJsonObject json = jsonDoc.object();
+
+ qDebug() << data;
+ qDebug() << "Loading version info from JSON.";
+ QJsonArray filesArray = json.value("Files").toArray();
+ for (QJsonValue fileValue : filesArray)
+ {
+ QJsonObject fileObj = fileValue.toObject();
+
+ QString file_path = fileObj.value("Path").toString();
#ifdef Q_OS_MAC
- // On OSX, the paths for the updater need to be fixed.
- // basically, anything that isn't in the .app folder is ignored.
- // everything else is changed so the code that processes the files actually finds
- // them and puts the replacements in the right spots.
- fixPathForOSX(file_path);
+ // On OSX, the paths for the updater need to be fixed.
+ // basically, anything that isn't in the .app folder is ignored.
+ // everything else is changed so the code that processes the files actually finds
+ // them and puts the replacements in the right spots.
+ fixPathForOSX(file_path);
#endif
- VersionFileEntry file{file_path, fileObj.value("Perms").toVariant().toInt(),
- FileSourceList(), fileObj.value("MD5").toString(), };
- qDebug() << "File" << file.path << "with perms" << file.mode;
-
- QJsonArray sourceArray = fileObj.value("Sources").toArray();
- for (QJsonValue val : sourceArray)
- {
- QJsonObject sourceObj = val.toObject();
-
- QString type = sourceObj.value("SourceType").toString();
- if (type == "http")
- {
- file.sources.append(FileSource("http", sourceObj.value("Url").toString()));
- }
- else
- {
- qWarning() << "Unknown source type" << type << "ignored.";
- }
- }
-
- qDebug() << "Loaded info for" << file.path;
-
- list.append(file);
- }
-
- return true;
+ VersionFileEntry file{file_path, fileObj.value("Perms").toVariant().toInt(),
+ FileSourceList(), fileObj.value("MD5").toString(), };
+ qDebug() << "File" << file.path << "with perms" << file.mode;
+
+ QJsonArray sourceArray = fileObj.value("Sources").toArray();
+ for (QJsonValue val : sourceArray)
+ {
+ QJsonObject sourceObj = val.toObject();
+
+ QString type = sourceObj.value("SourceType").toString();
+ if (type == "http")
+ {
+ file.sources.append(FileSource("http", sourceObj.value("Url").toString()));
+ }
+ else
+ {
+ qWarning() << "Unknown source type" << type << "ignored.";
+ }
+ }
+
+ qDebug() << "Loaded info for" << file.path;
+
+ list.append(file);
+ }
+
+ return true;
}
bool processFileLists
(
- const VersionFileList &currentVersion,
- const VersionFileList &newVersion,
- const QString &rootPath,
- const QString &tempPath,
- NetJobPtr job,
- OperationList &ops
+ const VersionFileList &currentVersion,
+ const VersionFileList &newVersion,
+ const QString &rootPath,
+ const QString &tempPath,
+ NetJobPtr job,
+ OperationList &ops
)
{
- // First, if we've loaded the current version's file list, we need to iterate through it and
- // delete anything in the current one version's list that isn't in the new version's list.
- for (VersionFileEntry entry : currentVersion)
- {
- QFileInfo toDelete(FS::PathCombine(rootPath, entry.path));
- if (!toDelete.exists())
- {
- qCritical() << "Expected file " << toDelete.absoluteFilePath()
- << " doesn't exist!";
- }
- bool keep = false;
-
- //
- for (VersionFileEntry newEntry : newVersion)
- {
- if (newEntry.path == entry.path)
- {
- qDebug() << "Not deleting" << entry.path
- << "because it is still present in the new version.";
- keep = true;
- break;
- }
- }
-
- // If the loop reaches the end and we didn't find a match, delete the file.
- if (!keep)
- {
- if (toDelete.exists())
- ops.append(Operation::DeleteOp(entry.path));
- }
- }
-
- // Next, check each file in MultiMC's folder and see if we need to update them.
- for (VersionFileEntry entry : newVersion)
- {
- // TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a
- // way to do this in the background.
- QString fileMD5;
- QString realEntryPath = FS::PathCombine(rootPath, entry.path);
- QFile entryFile(realEntryPath);
- QFileInfo entryInfo(realEntryPath);
-
- bool needs_upgrade = false;
- if (!entryFile.exists())
- {
- needs_upgrade = true;
- }
- else
- {
- bool pass = true;
- if (!entryInfo.isReadable())
- {
- qCritical() << "File " << realEntryPath << " is not readable.";
- pass = false;
- }
- if (!entryInfo.isWritable())
- {
- qCritical() << "File " << realEntryPath << " is not writable.";
- pass = false;
- }
- if (!entryFile.open(QFile::ReadOnly))
- {
- qCritical() << "File " << realEntryPath << " cannot be opened for reading.";
- pass = false;
- }
- if (!pass)
- {
- ops.clear();
- return false;
- }
- }
-
- if(!needs_upgrade)
- {
- QCryptographicHash hash(QCryptographicHash::Md5);
- auto foo = entryFile.readAll();
-
- hash.addData(foo);
- fileMD5 = hash.result().toHex();
- if ((fileMD5 != entry.md5))
- {
- qDebug() << "MD5Sum does not match!";
- qDebug() << "Expected:'" << entry.md5 << "'";
- qDebug() << "Got: '" << fileMD5 << "'";
- needs_upgrade = true;
- }
- }
-
- // skip file. it doesn't need an upgrade.
- if (!needs_upgrade)
- {
- qDebug() << "File" << realEntryPath << " does not need updating.";
- continue;
- }
-
- // yep. this file actually needs an upgrade. PROCEED.
- qDebug() << "Found file" << realEntryPath << " that needs updating.";
-
- // Go through the sources list and find one to use.
- // TODO: Make a NetAction that takes a source list and tries each of them until one
- // works. For now, we'll just use the first http one.
- for (FileSource source : entry.sources)
- {
- if (source.type != "http")
- continue;
-
- qDebug() << "Will download" << entry.path << "from" << source.url;
-
- // Download it to updatedir/<filepath>-<md5> where filepath is the file's
- // path with slashes replaced by underscores.
- QString dlPath = FS::PathCombine(tempPath, QString(entry.path).replace("/", "_"));
-
- // We need to download the file to the updatefiles folder and add a task
- // to copy it to its install path.
- auto download = Net::Download::makeFile(source.url, dlPath);
- auto rawMd5 = QByteArray::fromHex(entry.md5.toLatin1());
- download->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
- job->addNetAction(download);
- ops.append(Operation::CopyOp(dlPath, entry.path, entry.mode));
- }
- }
- return true;
+ // First, if we've loaded the current version's file list, we need to iterate through it and
+ // delete anything in the current one version's list that isn't in the new version's list.
+ for (VersionFileEntry entry : currentVersion)
+ {
+ QFileInfo toDelete(FS::PathCombine(rootPath, entry.path));
+ if (!toDelete.exists())
+ {
+ qCritical() << "Expected file " << toDelete.absoluteFilePath()
+ << " doesn't exist!";
+ }
+ bool keep = false;
+
+ //
+ for (VersionFileEntry newEntry : newVersion)
+ {
+ if (newEntry.path == entry.path)
+ {
+ qDebug() << "Not deleting" << entry.path
+ << "because it is still present in the new version.";
+ keep = true;
+ break;
+ }
+ }
+
+ // If the loop reaches the end and we didn't find a match, delete the file.
+ if (!keep)
+ {
+ if (toDelete.exists())
+ ops.append(Operation::DeleteOp(entry.path));
+ }
+ }
+
+ // Next, check each file in MultiMC's folder and see if we need to update them.
+ for (VersionFileEntry entry : newVersion)
+ {
+ // TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a
+ // way to do this in the background.
+ QString fileMD5;
+ QString realEntryPath = FS::PathCombine(rootPath, entry.path);
+ QFile entryFile(realEntryPath);
+ QFileInfo entryInfo(realEntryPath);
+
+ bool needs_upgrade = false;
+ if (!entryFile.exists())
+ {
+ needs_upgrade = true;
+ }
+ else
+ {
+ bool pass = true;
+ if (!entryInfo.isReadable())
+ {
+ qCritical() << "File " << realEntryPath << " is not readable.";
+ pass = false;
+ }
+ if (!entryInfo.isWritable())
+ {
+ qCritical() << "File " << realEntryPath << " is not writable.";
+ pass = false;
+ }
+ if (!entryFile.open(QFile::ReadOnly))
+ {
+ qCritical() << "File " << realEntryPath << " cannot be opened for reading.";
+ pass = false;
+ }
+ if (!pass)
+ {
+ ops.clear();
+ return false;
+ }
+ }
+
+ if(!needs_upgrade)
+ {
+ QCryptographicHash hash(QCryptographicHash::Md5);
+ auto foo = entryFile.readAll();
+
+ hash.addData(foo);
+ fileMD5 = hash.result().toHex();
+ if ((fileMD5 != entry.md5))
+ {
+ qDebug() << "MD5Sum does not match!";
+ qDebug() << "Expected:'" << entry.md5 << "'";
+ qDebug() << "Got: '" << fileMD5 << "'";
+ needs_upgrade = true;
+ }
+ }
+
+ // skip file. it doesn't need an upgrade.
+ if (!needs_upgrade)
+ {
+ qDebug() << "File" << realEntryPath << " does not need updating.";
+ continue;
+ }
+
+ // yep. this file actually needs an upgrade. PROCEED.
+ qDebug() << "Found file" << realEntryPath << " that needs updating.";
+
+ // Go through the sources list and find one to use.
+ // TODO: Make a NetAction that takes a source list and tries each of them until one
+ // works. For now, we'll just use the first http one.
+ for (FileSource source : entry.sources)
+ {
+ if (source.type != "http")
+ continue;
+
+ qDebug() << "Will download" << entry.path << "from" << source.url;
+
+ // Download it to updatedir/<filepath>-<md5> where filepath is the file's
+ // path with slashes replaced by underscores.
+ QString dlPath = FS::PathCombine(tempPath, QString(entry.path).replace("/", "_"));
+
+ // We need to download the file to the updatefiles folder and add a task
+ // to copy it to its install path.
+ auto download = Net::Download::makeFile(source.url, dlPath);
+ auto rawMd5 = QByteArray::fromHex(entry.md5.toLatin1());
+ download->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
+ job->addNetAction(download);
+ ops.append(Operation::CopyOp(dlPath, entry.path, entry.mode));
+ }
+ }
+ return true;
}
bool fixPathForOSX(QString &path)
{
- if (path.startsWith("MultiMC.app/"))
- {
- // remove the prefix and add a new, more appropriate one.
- path.remove(0, 12);
- return true;
- }
- else
- {
- qCritical() << "Update path not within .app: " << path;
- return false;
- }
+ if (path.startsWith("MultiMC.app/"))
+ {
+ // remove the prefix and add a new, more appropriate one.
+ path.remove(0, 12);
+ return true;
+ }
+ else
+ {
+ qCritical() << "Update path not within .app: " << path;
+ return false;
+ }
}
} \ No newline at end of file
diff --git a/api/logic/updater/GoUpdate.h b/api/logic/updater/GoUpdate.h
index 0e183b9f..54559a3c 100644
--- a/api/logic/updater/GoUpdate.h
+++ b/api/logic/updater/GoUpdate.h
@@ -12,16 +12,16 @@ namespace GoUpdate
*/
struct MULTIMC_LOGIC_EXPORT Status
{
- bool updateAvailable = false;
+ bool updateAvailable = false;
- int newVersionId = -1;
- QString newRepoUrl;
+ int newVersionId = -1;
+ QString newRepoUrl;
- int currentVersionId = -1;
- QString currentRepoUrl;
+ int currentVersionId = -1;
+ QString currentRepoUrl;
- // path to the root of the application
- QString rootPath;
+ // path to the root of the application
+ QString rootPath;
};
/**
@@ -29,21 +29,21 @@ struct MULTIMC_LOGIC_EXPORT Status
*/
struct MULTIMC_LOGIC_EXPORT FileSource
{
- FileSource(QString type, QString url, QString compression="")
- {
- this->type = type;
- this->url = url;
- this->compressionType = compression;
- }
-
- bool operator==(const FileSource &f2) const
- {
- return type == f2.type && url == f2.url && compressionType == f2.compressionType;
- }
-
- QString type;
- QString url;
- QString compressionType;
+ FileSource(QString type, QString url, QString compression="")
+ {
+ this->type = type;
+ this->url = url;
+ this->compressionType = compression;
+ }
+
+ bool operator==(const FileSource &f2) const
+ {
+ return type == f2.type && url == f2.url && compressionType == f2.compressionType;
+ }
+
+ QString type;
+ QString url;
+ QString compressionType;
};
typedef QList<FileSource> FileSourceList;
@@ -52,14 +52,14 @@ typedef QList<FileSource> FileSourceList;
*/
struct MULTIMC_LOGIC_EXPORT VersionFileEntry
{
- QString path;
- int mode;
- FileSourceList sources;
- QString md5;
- bool operator==(const VersionFileEntry &v2) const
- {
- return path == v2.path && mode == v2.mode && sources == v2.sources && md5 == v2.md5;
- }
+ QString path;
+ int mode;
+ FileSourceList sources;
+ QString md5;
+ bool operator==(const VersionFileEntry &v2) const
+ {
+ return path == v2.path && mode == v2.mode && sources == v2.sources && md5 == v2.md5;
+ }
};
typedef QList<VersionFileEntry> VersionFileList;
@@ -68,39 +68,39 @@ typedef QList<VersionFileEntry> VersionFileList;
*/
struct MULTIMC_LOGIC_EXPORT Operation
{
- static Operation CopyOp(QString from, QString to, int fmode=0644)
- {
- return Operation{OP_REPLACE, from, to, fmode};
- }
- static Operation DeleteOp(QString file)
- {
- return Operation{OP_DELETE, QString(), file, 0644};
- }
-
- // FIXME: for some types, some of the other fields are irrelevant!
- bool operator==(const Operation &u2) const
- {
- return type == u2.type &&
- source == u2.source &&
- destination == u2.destination &&
- destinationMode == u2.destinationMode;
- }
-
- //! Specifies the type of operation that this is.
- enum Type
- {
- OP_REPLACE,
- OP_DELETE,
- } type;
-
- //! The source file, if any
- QString source;
-
- //! The destination file.
- QString destination;
-
- //! The mode to change the destination file to.
- int destinationMode;
+ static Operation CopyOp(QString from, QString to, int fmode=0644)
+ {
+ return Operation{OP_REPLACE, from, to, fmode};
+ }
+ static Operation DeleteOp(QString file)
+ {
+ return Operation{OP_DELETE, QString(), file, 0644};
+ }
+
+ // FIXME: for some types, some of the other fields are irrelevant!
+ bool operator==(const Operation &u2) const
+ {
+ return type == u2.type &&
+ source == u2.source &&
+ destination == u2.destination &&
+ destinationMode == u2.destinationMode;
+ }
+
+ //! Specifies the type of operation that this is.
+ enum Type
+ {
+ OP_REPLACE,
+ OP_DELETE,
+ } type;
+
+ //! The source file, if any
+ QString source;
+
+ //! The destination file.
+ QString destination;
+
+ //! The mode to change the destination file to.
+ int destinationMode;
};
typedef QList<Operation> OperationList;
@@ -115,12 +115,12 @@ bool MULTIMC_LOGIC_EXPORT parseVersionInfo(const QByteArray &data, VersionFileLi
*/
bool MULTIMC_LOGIC_EXPORT processFileLists
(
- const VersionFileList &currentVersion,
- const VersionFileList &newVersion,
- const QString &rootPath,
- const QString &tempPath,
- NetJobPtr job,
- OperationList &ops
+ const VersionFileList &currentVersion,
+ const VersionFileList &newVersion,
+ const QString &rootPath,
+ const QString &tempPath,
+ NetJobPtr job,
+ OperationList &ops
);
/*!
diff --git a/api/logic/updater/UpdateChecker.cpp b/api/logic/updater/UpdateChecker.cpp
index d8be2c1a..9e610d52 100644
--- a/api/logic/updater/UpdateChecker.cpp
+++ b/api/logic/updater/UpdateChecker.cpp
@@ -25,236 +25,236 @@
UpdateChecker::UpdateChecker(QString channelListUrl, QString currentChannel, int currentBuild)
{
- m_channelListUrl = channelListUrl;
- m_currentChannel = currentChannel;
- m_currentBuild = currentBuild;
+ m_channelListUrl = channelListUrl;
+ m_currentChannel = currentChannel;
+ m_currentBuild = currentBuild;
}
QList<UpdateChecker::ChannelListEntry> UpdateChecker::getChannelList() const
{
- return m_channels;
+ return m_channels;
}
bool UpdateChecker::hasChannels() const
{
- return !m_channels.isEmpty();
+ return !m_channels.isEmpty();
}
void UpdateChecker::checkForUpdate(QString updateChannel, bool notifyNoUpdate)
{
- qDebug() << "Checking for updates.";
-
- // If the channel list hasn't loaded yet, load it and defer checking for updates until
- // later.
- if (!m_chanListLoaded)
- {
- qDebug() << "Channel list isn't loaded yet. Loading channel list and deferring "
- "update check.";
- m_checkUpdateWaiting = true;
- m_deferredUpdateChannel = updateChannel;
- updateChanList(notifyNoUpdate);
- return;
- }
-
- if (m_updateChecking)
- {
- qDebug() << "Ignoring update check request. Already checking for updates.";
- return;
- }
-
- m_updateChecking = true;
-
- // Find the desired channel within the channel list and get its repo URL. If if cannot be
- // found, error.
- m_newRepoUrl = "";
- for (ChannelListEntry entry : m_channels)
- {
- if (entry.id == updateChannel)
- m_newRepoUrl = entry.url;
- if (entry.id == m_currentChannel)
- m_currentRepoUrl = entry.url;
- }
-
- qDebug() << "m_repoUrl = " << m_newRepoUrl;
-
- // If we didn't find our channel, error.
- if (m_newRepoUrl.isEmpty())
- {
- qCritical() << "m_repoUrl is empty!";
- emit updateCheckFailed();
- return;
- }
-
- QUrl indexUrl = QUrl(m_newRepoUrl).resolved(QUrl("index.json"));
-
- auto job = new NetJob("GoUpdate Repository Index");
- job->addNetAction(Net::Download::makeByteArray(indexUrl, &indexData));
- connect(job, &NetJob::succeeded, [this, notifyNoUpdate](){ updateCheckFinished(notifyNoUpdate); });
- connect(job, &NetJob::failed, this, &UpdateChecker::updateCheckFailed);
- indexJob.reset(job);
- job->start();
+ qDebug() << "Checking for updates.";
+
+ // If the channel list hasn't loaded yet, load it and defer checking for updates until
+ // later.
+ if (!m_chanListLoaded)
+ {
+ qDebug() << "Channel list isn't loaded yet. Loading channel list and deferring "
+ "update check.";
+ m_checkUpdateWaiting = true;
+ m_deferredUpdateChannel = updateChannel;
+ updateChanList(notifyNoUpdate);
+ return;
+ }
+
+ if (m_updateChecking)
+ {
+ qDebug() << "Ignoring update check request. Already checking for updates.";
+ return;
+ }
+
+ m_updateChecking = true;
+
+ // Find the desired channel within the channel list and get its repo URL. If if cannot be
+ // found, error.
+ m_newRepoUrl = "";
+ for (ChannelListEntry entry : m_channels)
+ {
+ if (entry.id == updateChannel)
+ m_newRepoUrl = entry.url;
+ if (entry.id == m_currentChannel)
+ m_currentRepoUrl = entry.url;
+ }
+
+ qDebug() << "m_repoUrl = " << m_newRepoUrl;
+
+ // If we didn't find our channel, error.
+ if (m_newRepoUrl.isEmpty())
+ {
+ qCritical() << "m_repoUrl is empty!";
+ emit updateCheckFailed();
+ return;
+ }
+
+ QUrl indexUrl = QUrl(m_newRepoUrl).resolved(QUrl("index.json"));
+
+ auto job = new NetJob("GoUpdate Repository Index");
+ job->addNetAction(Net::Download::makeByteArray(indexUrl, &indexData));
+ connect(job, &NetJob::succeeded, [this, notifyNoUpdate](){ updateCheckFinished(notifyNoUpdate); });
+ connect(job, &NetJob::failed, this, &UpdateChecker::updateCheckFailed);
+ indexJob.reset(job);
+ job->start();
}
void UpdateChecker::updateCheckFinished(bool notifyNoUpdate)
{
- qDebug() << "Finished downloading repo index. Checking for new versions.";
-
- QJsonParseError jsonError;
- indexJob.reset();
-
- QJsonDocument jsonDoc = QJsonDocument::fromJson(indexData, &jsonError);
- indexData.clear();
- if (jsonError.error != QJsonParseError::NoError || !jsonDoc.isObject())
- {
- qCritical() << "Failed to parse GoUpdate repository index. JSON error"
- << jsonError.errorString() << "at offset" << jsonError.offset;
- m_updateChecking = false;
- return;
- }
-
- QJsonObject object = jsonDoc.object();
-
- bool success = false;
- int apiVersion = object.value("ApiVersion").toVariant().toInt(&success);
- if (apiVersion != API_VERSION || !success)
- {
- qCritical() << "Failed to check for updates. API version mismatch. We're using"
- << API_VERSION << "server has" << apiVersion;
- m_updateChecking = false;
- return;
- }
-
- qDebug() << "Processing repository version list.";
- QJsonObject newestVersion;
- QJsonArray versions = object.value("Versions").toArray();
- for (QJsonValue versionVal : versions)
- {
- QJsonObject version = versionVal.toObject();
- if (newestVersion.value("Id").toVariant().toInt() <
- version.value("Id").toVariant().toInt())
- {
- newestVersion = version;
- }
- }
-
- // We've got the version with the greatest ID number. Now compare it to our current build
- // number and update if they're different.
- int newBuildNumber = newestVersion.value("Id").toVariant().toInt();
- if (newBuildNumber != m_currentBuild)
- {
- qDebug() << "Found newer version with ID" << newBuildNumber;
- // Update!
- GoUpdate::Status updateStatus;
- updateStatus.updateAvailable = true;
- updateStatus.currentVersionId = m_currentBuild;
- updateStatus.currentRepoUrl = m_currentRepoUrl;
- updateStatus.newVersionId = newBuildNumber;
- updateStatus.newRepoUrl = m_newRepoUrl;
- emit updateAvailable(updateStatus);
- }
- else if (notifyNoUpdate)
- {
- emit noUpdateFound();
- }
- m_updateChecking = false;
+ qDebug() << "Finished downloading repo index. Checking for new versions.";
+
+ QJsonParseError jsonError;
+ indexJob.reset();
+
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(indexData, &jsonError);
+ indexData.clear();
+ if (jsonError.error != QJsonParseError::NoError || !jsonDoc.isObject())
+ {
+ qCritical() << "Failed to parse GoUpdate repository index. JSON error"
+ << jsonError.errorString() << "at offset" << jsonError.offset;
+ m_updateChecking = false;
+ return;
+ }
+
+ QJsonObject object = jsonDoc.object();
+
+ bool success = false;
+ int apiVersion = object.value("ApiVersion").toVariant().toInt(&success);
+ if (apiVersion != API_VERSION || !success)
+ {
+ qCritical() << "Failed to check for updates. API version mismatch. We're using"
+ << API_VERSION << "server has" << apiVersion;
+ m_updateChecking = false;
+ return;
+ }
+
+ qDebug() << "Processing repository version list.";
+ QJsonObject newestVersion;
+ QJsonArray versions = object.value("Versions").toArray();
+ for (QJsonValue versionVal : versions)
+ {
+ QJsonObject version = versionVal.toObject();
+ if (newestVersion.value("Id").toVariant().toInt() <
+ version.value("Id").toVariant().toInt())
+ {
+ newestVersion = version;
+ }
+ }
+
+ // We've got the version with the greatest ID number. Now compare it to our current build
+ // number and update if they're different.
+ int newBuildNumber = newestVersion.value("Id").toVariant().toInt();
+ if (newBuildNumber != m_currentBuild)
+ {
+ qDebug() << "Found newer version with ID" << newBuildNumber;
+ // Update!
+ GoUpdate::Status updateStatus;
+ updateStatus.updateAvailable = true;
+ updateStatus.currentVersionId = m_currentBuild;
+ updateStatus.currentRepoUrl = m_currentRepoUrl;
+ updateStatus.newVersionId = newBuildNumber;
+ updateStatus.newRepoUrl = m_newRepoUrl;
+ emit updateAvailable(updateStatus);
+ }
+ else if (notifyNoUpdate)
+ {
+ emit noUpdateFound();
+ }
+ m_updateChecking = false;
}
void UpdateChecker::updateCheckFailed()
{
- qCritical() << "Update check failed for reasons unknown.";
+ qCritical() << "Update check failed for reasons unknown.";
}
void UpdateChecker::updateChanList(bool notifyNoUpdate)
{
- qDebug() << "Loading the channel list.";
-
- if (m_chanListLoading)
- {
- qDebug() << "Ignoring channel list update request. Already grabbing channel list.";
- return;
- }
-
- if (m_channelListUrl.isEmpty())
- {
- qCritical() << "Failed to update channel list. No channel list URL set."
- << "If you'd like to use MultiMC's update system, please pass the channel "
- "list URL to CMake at compile time.";
- return;
- }
-
- m_chanListLoading = true;
- NetJob *job = new NetJob("Update System Channel List");
- job->addNetAction(Net::Download::makeByteArray(QUrl(m_channelListUrl), &chanlistData));
- connect(job, &NetJob::succeeded, [this, notifyNoUpdate]() { chanListDownloadFinished(notifyNoUpdate); });
- QObject::connect(job, &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed);
- chanListJob.reset(job);
- job->start();
+ qDebug() << "Loading the channel list.";
+
+ if (m_chanListLoading)
+ {
+ qDebug() << "Ignoring channel list update request. Already grabbing channel list.";
+ return;
+ }
+
+ if (m_channelListUrl.isEmpty())
+ {
+ qCritical() << "Failed to update channel list. No channel list URL set."
+ << "If you'd like to use MultiMC's update system, please pass the channel "
+ "list URL to CMake at compile time.";
+ return;
+ }
+
+ m_chanListLoading = true;
+ NetJob *job = new NetJob("Update System Channel List");
+ job->addNetAction(Net::Download::makeByteArray(QUrl(m_channelListUrl), &chanlistData));
+ connect(job, &NetJob::succeeded, [this, notifyNoUpdate]() { chanListDownloadFinished(notifyNoUpdate); });
+ QObject::connect(job, &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed);
+ chanListJob.reset(job);
+ job->start();
}
void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate)
{
- chanListJob.reset();
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(chanlistData, &jsonError);
- chanlistData.clear();
- if (jsonError.error != QJsonParseError::NoError)
- {
- // TODO: Report errors to the user.
- qCritical() << "Failed to parse channel list JSON:" << jsonError.errorString() << "at" << jsonError.offset;
- m_chanListLoading = false;
- return;
- }
-
- QJsonObject object = jsonDoc.object();
-
- bool success = false;
- int formatVersion = object.value("format_version").toVariant().toInt(&success);
- if (formatVersion != CHANLIST_FORMAT || !success)
- {
- qCritical()
- << "Failed to check for updates. Channel list format version mismatch. We're using"
- << CHANLIST_FORMAT << "server has" << formatVersion;
- m_chanListLoading = false;
- return;
- }
-
- // Load channels into a temporary array.
- QList<ChannelListEntry> loadedChannels;
- QJsonArray channelArray = object.value("channels").toArray();
- for (QJsonValue chanVal : channelArray)
- {
- QJsonObject channelObj = chanVal.toObject();
- ChannelListEntry entry{channelObj.value("id").toVariant().toString(),
- channelObj.value("name").toVariant().toString(),
- channelObj.value("description").toVariant().toString(),
- channelObj.value("url").toVariant().toString()};
- if (entry.id.isEmpty() || entry.name.isEmpty() || entry.url.isEmpty())
- {
- qCritical() << "Channel list entry with empty ID, name, or URL. Skipping.";
- continue;
- }
- loadedChannels.append(entry);
- }
-
- // Swap the channel list we just loaded into the object's channel list.
- m_channels.swap(loadedChannels);
-
- m_chanListLoading = false;
- m_chanListLoaded = true;
- qDebug() << "Successfully loaded UpdateChecker channel list.";
-
- // If we're waiting to check for updates, do that now.
- if (m_checkUpdateWaiting)
- checkForUpdate(m_deferredUpdateChannel, notifyNoUpdate);
-
- emit channelListLoaded();
+ chanListJob.reset();
+
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(chanlistData, &jsonError);
+ chanlistData.clear();
+ if (jsonError.error != QJsonParseError::NoError)
+ {
+ // TODO: Report errors to the user.
+ qCritical() << "Failed to parse channel list JSON:" << jsonError.errorString() << "at" << jsonError.offset;
+ m_chanListLoading = false;
+ return;
+ }
+
+ QJsonObject object = jsonDoc.object();
+
+ bool success = false;
+ int formatVersion = object.value("format_version").toVariant().toInt(&success);
+ if (formatVersion != CHANLIST_FORMAT || !success)
+ {
+ qCritical()
+ << "Failed to check for updates. Channel list format version mismatch. We're using"
+ << CHANLIST_FORMAT << "server has" << formatVersion;
+ m_chanListLoading = false;
+ return;
+ }
+
+ // Load channels into a temporary array.
+ QList<ChannelListEntry> loadedChannels;
+ QJsonArray channelArray = object.value("channels").toArray();
+ for (QJsonValue chanVal : channelArray)
+ {
+ QJsonObject channelObj = chanVal.toObject();
+ ChannelListEntry entry{channelObj.value("id").toVariant().toString(),
+ channelObj.value("name").toVariant().toString(),
+ channelObj.value("description").toVariant().toString(),
+ channelObj.value("url").toVariant().toString()};
+ if (entry.id.isEmpty() || entry.name.isEmpty() || entry.url.isEmpty())
+ {
+ qCritical() << "Channel list entry with empty ID, name, or URL. Skipping.";
+ continue;
+ }
+ loadedChannels.append(entry);
+ }
+
+ // Swap the channel list we just loaded into the object's channel list.
+ m_channels.swap(loadedChannels);
+
+ m_chanListLoading = false;
+ m_chanListLoaded = true;
+ qDebug() << "Successfully loaded UpdateChecker channel list.";
+
+ // If we're waiting to check for updates, do that now.
+ if (m_checkUpdateWaiting)
+ checkForUpdate(m_deferredUpdateChannel, notifyNoUpdate);
+
+ emit channelListLoaded();
}
void UpdateChecker::chanListDownloadFailed(QString reason)
{
- m_chanListLoading = false;
- qCritical() << QString("Failed to download channel list: %1").arg(reason);
- emit channelListLoaded();
+ m_chanListLoading = false;
+ qCritical() << QString("Failed to download channel list: %1").arg(reason);
+ emit channelListLoaded();
}
diff --git a/api/logic/updater/UpdateChecker.h b/api/logic/updater/UpdateChecker.h
index 4996da26..bb5013de 100644
--- a/api/logic/updater/UpdateChecker.h
+++ b/api/logic/updater/UpdateChecker.h
@@ -22,100 +22,100 @@
class MULTIMC_LOGIC_EXPORT UpdateChecker : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- UpdateChecker(QString channelListUrl, QString currentChannel, int currentBuild);
- void checkForUpdate(QString updateChannel, bool notifyNoUpdate);
-
- /*!
- * Causes the update checker to download the channel list from the URL specified in config.h (generated by CMake).
- * If this isn't called before checkForUpdate(), it will automatically be called.
- */
- void updateChanList(bool notifyNoUpdate);
-
- /*!
- * An entry in the channel list.
- */
- struct ChannelListEntry
- {
- QString id;
- QString name;
- QString description;
- QString url;
- };
-
- /*!
- * Returns a the current channel list.
- * If the channel list hasn't been loaded, this list will be empty.
- */
- QList<ChannelListEntry> getChannelList() const;
-
- /*!
- * Returns false if the channel list is empty.
- */
- bool hasChannels() const;
+ UpdateChecker(QString channelListUrl, QString currentChannel, int currentBuild);
+ void checkForUpdate(QString updateChannel, bool notifyNoUpdate);
+
+ /*!
+ * Causes the update checker to download the channel list from the URL specified in config.h (generated by CMake).
+ * If this isn't called before checkForUpdate(), it will automatically be called.
+ */
+ void updateChanList(bool notifyNoUpdate);
+
+ /*!
+ * An entry in the channel list.
+ */
+ struct ChannelListEntry
+ {
+ QString id;
+ QString name;
+ QString description;
+ QString url;
+ };
+
+ /*!
+ * Returns a the current channel list.
+ * If the channel list hasn't been loaded, this list will be empty.
+ */
+ QList<ChannelListEntry> getChannelList() const;
+
+ /*!
+ * Returns false if the channel list is empty.
+ */
+ bool hasChannels() const;
signals:
- //! Signal emitted when an update is available. Passes the URL for the repo and the ID and name for the version.
- void updateAvailable(GoUpdate::Status status);
+ //! Signal emitted when an update is available. Passes the URL for the repo and the ID and name for the version.
+ void updateAvailable(GoUpdate::Status status);
- //! Signal emitted when the channel list finishes loading or fails to load.
- void channelListLoaded();
+ //! Signal emitted when the channel list finishes loading or fails to load.
+ void channelListLoaded();
- void noUpdateFound();
+ void noUpdateFound();
private slots:
- void updateCheckFinished(bool notifyNoUpdate);
- void updateCheckFailed();
+ void updateCheckFinished(bool notifyNoUpdate);
+ void updateCheckFailed();
- void chanListDownloadFinished(bool notifyNoUpdate);
- void chanListDownloadFailed(QString reason);
+ void chanListDownloadFinished(bool notifyNoUpdate);
+ void chanListDownloadFailed(QString reason);
private:
- friend class UpdateCheckerTest;
-
- NetJobPtr indexJob;
- QByteArray indexData;
- NetJobPtr chanListJob;
- QByteArray chanlistData;
-
- QString m_channelListUrl;
-
- QList<ChannelListEntry> m_channels;
-
- /*!
- * True while the system is checking for updates.
- * If checkForUpdate is called while this is true, it will be ignored.
- */
- bool m_updateChecking = false;
-
- /*!
- * True if the channel list has loaded.
- * If this is false, trying to check for updates will call updateChanList first.
- */
- bool m_chanListLoaded = false;
-
- /*!
- * Set to true while the channel list is currently loading.
- */
- bool m_chanListLoading = false;
-
- /*!
- * Set to true when checkForUpdate is called while the channel list isn't loaded.
- * When the channel list finishes loading, if this is true, the update checker will check for updates.
- */
- bool m_checkUpdateWaiting = false;
-
- /*!
- * if m_checkUpdateWaiting, this is the last used update channel
- */
- QString m_deferredUpdateChannel;
-
- int m_currentBuild = -1;
- QString m_currentChannel;
- QString m_currentRepoUrl;
-
- QString m_newRepoUrl;
+ friend class UpdateCheckerTest;
+
+ NetJobPtr indexJob;
+ QByteArray indexData;
+ NetJobPtr chanListJob;
+ QByteArray chanlistData;
+
+ QString m_channelListUrl;
+
+ QList<ChannelListEntry> m_channels;
+
+ /*!
+ * True while the system is checking for updates.
+ * If checkForUpdate is called while this is true, it will be ignored.
+ */
+ bool m_updateChecking = false;
+
+ /*!
+ * True if the channel list has loaded.
+ * If this is false, trying to check for updates will call updateChanList first.
+ */
+ bool m_chanListLoaded = false;
+
+ /*!
+ * Set to true while the channel list is currently loading.
+ */
+ bool m_chanListLoading = false;
+
+ /*!
+ * Set to true when checkForUpdate is called while the channel list isn't loaded.
+ * When the channel list finishes loading, if this is true, the update checker will check for updates.
+ */
+ bool m_checkUpdateWaiting = false;
+
+ /*!
+ * if m_checkUpdateWaiting, this is the last used update channel
+ */
+ QString m_deferredUpdateChannel;
+
+ int m_currentBuild = -1;
+ QString m_currentChannel;
+ QString m_currentRepoUrl;
+
+ QString m_newRepoUrl;
};
diff --git a/api/logic/updater/UpdateChecker_test.cpp b/api/logic/updater/UpdateChecker_test.cpp
index 16b21614..59f2a5a1 100644
--- a/api/logic/updater/UpdateChecker_test.cpp
+++ b/api/logic/updater/UpdateChecker_test.cpp
@@ -8,137 +8,137 @@ Q_DECLARE_METATYPE(UpdateChecker::ChannelListEntry)
bool operator==(const UpdateChecker::ChannelListEntry &e1, const UpdateChecker::ChannelListEntry &e2)
{
- qDebug() << e1.url << "vs" << e2.url;
- return e1.id == e2.id &&
- e1.name == e2.name &&
- e1.description == e2.description &&
- e1.url == e2.url;
+ qDebug() << e1.url << "vs" << e2.url;
+ return e1.id == e2.id &&
+ e1.name == e2.name &&
+ e1.description == e2.description &&
+ e1.url == e2.url;
}
QDebug operator<<(QDebug dbg, const UpdateChecker::ChannelListEntry &c)
{
- dbg.nospace() << "ChannelListEntry(id=" << c.id << " name=" << c.name << " description=" << c.description << " url=" << c.url << ")";
- return dbg.maybeSpace();
+ dbg.nospace() << "ChannelListEntry(id=" << c.id << " name=" << c.name << " description=" << c.description << " url=" << c.url << ")";
+ return dbg.maybeSpace();
}
class UpdateCheckerTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- void initTestCase()
- {
-
- }
- void cleanupTestCase()
- {
-
- }
-
- static QString findTestDataUrl(const char *file)
- {
- return QUrl::fromLocalFile(QFINDTESTDATA(file)).toString();
- }
- void tst_ChannelListParsing_data()
- {
- QTest::addColumn<QString>("channel");
- QTest::addColumn<QString>("channelUrl");
- QTest::addColumn<bool>("hasChannels");
- QTest::addColumn<bool>("valid");
- QTest::addColumn<QList<UpdateChecker::ChannelListEntry> >("result");
-
- QTest::newRow("garbage")
- << QString()
- << findTestDataUrl("data/garbageChannels.json")
- << false
- << false
- << QList<UpdateChecker::ChannelListEntry>();
- QTest::newRow("errors")
- << QString()
- << findTestDataUrl("data/errorChannels.json")
- << false
- << true
- << QList<UpdateChecker::ChannelListEntry>();
- QTest::newRow("no channels")
- << QString()
- << findTestDataUrl("data/noChannels.json")
- << false
- << true
- << QList<UpdateChecker::ChannelListEntry>();
- QTest::newRow("one channel")
- << QString("develop")
- << findTestDataUrl("data/oneChannel.json")
- << true
- << true
- << (QList<UpdateChecker::ChannelListEntry>() << UpdateChecker::ChannelListEntry{"develop", "Develop", "The channel called \"develop\"", "http://example.org/stuff"});
- QTest::newRow("several channels")
- << QString("develop")
- << findTestDataUrl("data/channels.json")
- << true
- << true
- << (QList<UpdateChecker::ChannelListEntry>()
- << UpdateChecker::ChannelListEntry{"develop", "Develop", "The channel called \"develop\"", findTestDataUrl("data")}
- << UpdateChecker::ChannelListEntry{"stable", "Stable", "It's stable at least", findTestDataUrl("data")}
- << UpdateChecker::ChannelListEntry{"42", "The Channel", "This is the channel that is going to answer all of your questions", "https://dent.me/tea"});
- }
- void tst_ChannelListParsing()
- {
-
- QFETCH(QString, channel);
- QFETCH(QString, channelUrl);
- QFETCH(bool, hasChannels);
- QFETCH(bool, valid);
- QFETCH(QList<UpdateChecker::ChannelListEntry>, result);
-
- UpdateChecker checker(channelUrl, channel, 0);
-
- QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded()));
- QVERIFY(channelListLoadedSpy.isValid());
-
- checker.updateChanList(false);
-
- if (valid)
- {
- QVERIFY(channelListLoadedSpy.wait());
- QCOMPARE(channelListLoadedSpy.size(), 1);
- }
- else
- {
- channelListLoadedSpy.wait();
- QCOMPARE(channelListLoadedSpy.size(), 0);
- }
-
- QCOMPARE(checker.hasChannels(), hasChannels);
- QCOMPARE(checker.getChannelList(), result);
- }
-
- void tst_UpdateChecking()
- {
- QString channel = "develop";
- QString channelUrl = findTestDataUrl("data/channels.json");
- int currentBuild = 2;
-
- UpdateChecker checker(channelUrl, channel, currentBuild);
-
- QSignalSpy updateAvailableSpy(&checker, SIGNAL(updateAvailable(GoUpdate::Status)));
- QVERIFY(updateAvailableSpy.isValid());
- QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded()));
- QVERIFY(channelListLoadedSpy.isValid());
-
- checker.updateChanList(false);
- QVERIFY(channelListLoadedSpy.wait());
-
- qDebug() << "CWD:" << QDir::current().absolutePath();
- checker.m_channels[0].url = findTestDataUrl("data/");
- checker.checkForUpdate(channel, false);
-
- QVERIFY(updateAvailableSpy.wait());
-
- auto status = updateAvailableSpy.first().first().value<GoUpdate::Status>();
- QCOMPARE(checker.m_channels[0].url, status.newRepoUrl);
- QCOMPARE(3, status.newVersionId);
- QCOMPARE(currentBuild, status.currentVersionId);
- }
+ void initTestCase()
+ {
+
+ }
+ void cleanupTestCase()
+ {
+
+ }
+
+ static QString findTestDataUrl(const char *file)
+ {
+ return QUrl::fromLocalFile(QFINDTESTDATA(file)).toString();
+ }
+ void tst_ChannelListParsing_data()
+ {
+ QTest::addColumn<QString>("channel");
+ QTest::addColumn<QString>("channelUrl");
+ QTest::addColumn<bool>("hasChannels");
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<QList<UpdateChecker::ChannelListEntry> >("result");
+
+ QTest::newRow("garbage")
+ << QString()
+ << findTestDataUrl("data/garbageChannels.json")
+ << false
+ << false
+ << QList<UpdateChecker::ChannelListEntry>();
+ QTest::newRow("errors")
+ << QString()
+ << findTestDataUrl("data/errorChannels.json")
+ << false
+ << true
+ << QList<UpdateChecker::ChannelListEntry>();
+ QTest::newRow("no channels")
+ << QString()
+ << findTestDataUrl("data/noChannels.json")
+ << false
+ << true
+ << QList<UpdateChecker::ChannelListEntry>();
+ QTest::newRow("one channel")
+ << QString("develop")
+ << findTestDataUrl("data/oneChannel.json")
+ << true
+ << true
+ << (QList<UpdateChecker::ChannelListEntry>() << UpdateChecker::ChannelListEntry{"develop", "Develop", "The channel called \"develop\"", "http://example.org/stuff"});
+ QTest::newRow("several channels")
+ << QString("develop")
+ << findTestDataUrl("data/channels.json")
+ << true
+ << true
+ << (QList<UpdateChecker::ChannelListEntry>()
+ << UpdateChecker::ChannelListEntry{"develop", "Develop", "The channel called \"develop\"", findTestDataUrl("data")}
+ << UpdateChecker::ChannelListEntry{"stable", "Stable", "It's stable at least", findTestDataUrl("data")}
+ << UpdateChecker::ChannelListEntry{"42", "The Channel", "This is the channel that is going to answer all of your questions", "https://dent.me/tea"});
+ }
+ void tst_ChannelListParsing()
+ {
+
+ QFETCH(QString, channel);
+ QFETCH(QString, channelUrl);
+ QFETCH(bool, hasChannels);
+ QFETCH(bool, valid);
+ QFETCH(QList<UpdateChecker::ChannelListEntry>, result);
+
+ UpdateChecker checker(channelUrl, channel, 0);
+
+ QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded()));
+ QVERIFY(channelListLoadedSpy.isValid());
+
+ checker.updateChanList(false);
+
+ if (valid)
+ {
+ QVERIFY(channelListLoadedSpy.wait());
+ QCOMPARE(channelListLoadedSpy.size(), 1);
+ }
+ else
+ {
+ channelListLoadedSpy.wait();
+ QCOMPARE(channelListLoadedSpy.size(), 0);
+ }
+
+ QCOMPARE(checker.hasChannels(), hasChannels);
+ QCOMPARE(checker.getChannelList(), result);
+ }
+
+ void tst_UpdateChecking()
+ {
+ QString channel = "develop";
+ QString channelUrl = findTestDataUrl("data/channels.json");
+ int currentBuild = 2;
+
+ UpdateChecker checker(channelUrl, channel, currentBuild);
+
+ QSignalSpy updateAvailableSpy(&checker, SIGNAL(updateAvailable(GoUpdate::Status)));
+ QVERIFY(updateAvailableSpy.isValid());
+ QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded()));
+ QVERIFY(channelListLoadedSpy.isValid());
+
+ checker.updateChanList(false);
+ QVERIFY(channelListLoadedSpy.wait());
+
+ qDebug() << "CWD:" << QDir::current().absolutePath();
+ checker.m_channels[0].url = findTestDataUrl("data/");
+ checker.checkForUpdate(channel, false);
+
+ QVERIFY(updateAvailableSpy.wait());
+
+ auto status = updateAvailableSpy.first().first().value<GoUpdate::Status>();
+ QCOMPARE(checker.m_channels[0].url, status.newRepoUrl);
+ QCOMPARE(3, status.newVersionId);
+ QCOMPARE(currentBuild, status.currentVersionId);
+ }
};
QTEST_GUILESS_MAIN(UpdateCheckerTest)
diff --git a/api/logic/updater/testdata/1.json b/api/logic/updater/testdata/1.json
index 3dd189e5..7af7e52d 100644
--- a/api/logic/updater/testdata/1.json
+++ b/api/logic/updater/testdata/1.json
@@ -1,43 +1,43 @@
{
- "ApiVersion": 0,
- "Id": 1,
- "Name": "1.0.1",
- "Files": [
- {
- "Path": "fileOne",
- "Sources": [
- {
- "SourceType": "http",
- "Url": "@TEST_DATA_URL@/fileOneA"
- }
- ],
- "Executable": true,
- "Perms": 493,
- "MD5": "9eb84090956c484e32cb6c08455a667b"
- },
- {
- "Path": "fileTwo",
- "Sources": [
- {
- "SourceType": "http",
- "Url": "@TEST_DATA_URL@/fileTwo"
- }
- ],
- "Executable": false,
- "Perms": 644,
- "MD5": "38f94f54fa3eb72b0ea836538c10b043"
- },
- {
- "Path": "fileThree",
- "Sources": [
- {
- "SourceType": "http",
- "Url": "@TEST_DATA_URL@/fileThree"
- }
- ],
- "Executable": false,
- "Perms": "750",
- "MD5": "f12df554b21e320be6471d7154130e70"
- }
- ]
+ "ApiVersion": 0,
+ "Id": 1,
+ "Name": "1.0.1",
+ "Files": [
+ {
+ "Path": "fileOne",
+ "Sources": [
+ {
+ "SourceType": "http",
+ "Url": "@TEST_DATA_URL@/fileOneA"
+ }
+ ],
+ "Executable": true,
+ "Perms": 493,
+ "MD5": "9eb84090956c484e32cb6c08455a667b"
+ },
+ {
+ "Path": "fileTwo",
+ "Sources": [
+ {
+ "SourceType": "http",
+ "Url": "@TEST_DATA_URL@/fileTwo"
+ }
+ ],
+ "Executable": false,
+ "Perms": 644,
+ "MD5": "38f94f54fa3eb72b0ea836538c10b043"
+ },
+ {
+ "Path": "fileThree",
+ "Sources": [
+ {
+ "SourceType": "http",
+ "Url": "@TEST_DATA_URL@/fileThree"
+ }
+ ],
+ "Executable": false,
+ "Perms": "750",
+ "MD5": "f12df554b21e320be6471d7154130e70"
+ }
+ ]
}
diff --git a/api/logic/updater/testdata/2.json b/api/logic/updater/testdata/2.json
index a7ba7029..96d430d5 100644
--- a/api/logic/updater/testdata/2.json
+++ b/api/logic/updater/testdata/2.json
@@ -1,31 +1,31 @@
{
- "ApiVersion": 0,
- "Id": 1,
- "Name": "1.0.1",
- "Files": [
- {
- "Path": "fileOne",
- "Sources": [
- {
- "SourceType": "http",
- "Url": "@TEST_DATA_URL@/fileOneB"
- }
- ],
- "Executable": true,
- "Perms": 493,
- "MD5": "42915a71277c9016668cce7b82c6b577"
- },
- {
- "Path": "fileTwo",
- "Sources": [
- {
- "SourceType": "http",
- "Url": "@TEST_DATA_URL@/fileTwo"
- }
- ],
- "Executable": false,
- "Perms": 644,
- "MD5": "38f94f54fa3eb72b0ea836538c10b043"
- }
- ]
+ "ApiVersion": 0,
+ "Id": 1,
+ "Name": "1.0.1",
+ "Files": [
+ {
+ "Path": "fileOne",
+ "Sources": [
+ {
+ "SourceType": "http",
+ "Url": "@TEST_DATA_URL@/fileOneB"
+ }
+ ],
+ "Executable": true,
+ "Perms": 493,
+ "MD5": "42915a71277c9016668cce7b82c6b577"
+ },
+ {
+ "Path": "fileTwo",
+ "Sources": [
+ {
+ "SourceType": "http",
+ "Url": "@TEST_DATA_URL@/fileTwo"
+ }
+ ],
+ "Executable": false,
+ "Perms": 644,
+ "MD5": "38f94f54fa3eb72b0ea836538c10b043"
+ }
+ ]
}
diff --git a/api/logic/updater/testdata/channels.json b/api/logic/updater/testdata/channels.json
index b46c64c8..5c6e42cb 100644
--- a/api/logic/updater/testdata/channels.json
+++ b/api/logic/updater/testdata/channels.json
@@ -1,23 +1,23 @@
{
- "format_version": 0,
- "channels": [
- {
- "id": "develop",
- "name": "Develop",
- "description": "The channel called \"develop\"",
- "url": "@TEST_DATA_URL@"
- },
- {
- "id": "stable",
- "name": "Stable",
- "description": "It's stable at least",
- "url": "@TEST_DATA_URL@"
- },
- {
- "id": "42",
- "name": "The Channel",
- "description": "This is the channel that is going to answer all of your questions",
- "url": "https://dent.me/tea"
- }
- ]
+ "format_version": 0,
+ "channels": [
+ {
+ "id": "develop",
+ "name": "Develop",
+ "description": "The channel called \"develop\"",
+ "url": "@TEST_DATA_URL@"
+ },
+ {
+ "id": "stable",
+ "name": "Stable",
+ "description": "It's stable at least",
+ "url": "@TEST_DATA_URL@"
+ },
+ {
+ "id": "42",
+ "name": "The Channel",
+ "description": "This is the channel that is going to answer all of your questions",
+ "url": "https://dent.me/tea"
+ }
+ ]
}
diff --git a/api/logic/updater/testdata/errorChannels.json b/api/logic/updater/testdata/errorChannels.json
index 333cd445..a2cb2165 100644
--- a/api/logic/updater/testdata/errorChannels.json
+++ b/api/logic/updater/testdata/errorChannels.json
@@ -1,23 +1,23 @@
{
- "format_version": 0,
- "channels": [
- {
- "id": "",
- "name": "Develop",
- "description": "The channel called \"develop\"",
- "url": "http://example.org/stuff"
- },
- {
- "id": "stable",
- "name": "",
- "description": "It's stable at least",
- "url": "ftp://username@host/path/to/stuff"
- },
- {
- "id": "42",
- "name": "The Channel",
- "description": "This is the channel that is going to answer all of your questions",
- "url": ""
- }
- ]
+ "format_version": 0,
+ "channels": [
+ {
+ "id": "",
+ "name": "Develop",
+ "description": "The channel called \"develop\"",
+ "url": "http://example.org/stuff"
+ },
+ {
+ "id": "stable",
+ "name": "",
+ "description": "It's stable at least",
+ "url": "ftp://username@host/path/to/stuff"
+ },
+ {
+ "id": "42",
+ "name": "The Channel",
+ "description": "This is the channel that is going to answer all of your questions",
+ "url": ""
+ }
+ ]
}
diff --git a/api/logic/updater/testdata/garbageChannels.json b/api/logic/updater/testdata/garbageChannels.json
index 1450fb9c..34437451 100644
--- a/api/logic/updater/testdata/garbageChannels.json
+++ b/api/logic/updater/testdata/garbageChannels.json
@@ -1,22 +1,22 @@
{
- "format_version": 0,
- "channels": [
- {
- "id": "develop",
- "name": "Develop",
- "description": "The channel called \"develop\"",
-aa "url": "http://example.org/stuff"
- },
-a "id": "stable",
- "name": "Stable",
- "description": "It's stable at least",
- "url": "ftp://username@host/path/to/stuff"
- },
- {
- "id": "42"f
- "name": "The Channel",
- "description": "This is the channel that is going to answer all of your questions",
- "url": "https://dent.me/tea"
- }
- ]
+ "format_version": 0,
+ "channels": [
+ {
+ "id": "develop",
+ "name": "Develop",
+ "description": "The channel called \"develop\"",
+aa "url": "http://example.org/stuff"
+ },
+a "id": "stable",
+ "name": "Stable",
+ "description": "It's stable at least",
+ "url": "ftp://username@host/path/to/stuff"
+ },
+ {
+ "id": "42"f
+ "name": "The Channel",
+ "description": "This is the channel that is going to answer all of your questions",
+ "url": "https://dent.me/tea"
+ }
+ ]
}
diff --git a/api/logic/updater/testdata/index.json b/api/logic/updater/testdata/index.json
index 20ceb9f4..867bdcfb 100644
--- a/api/logic/updater/testdata/index.json
+++ b/api/logic/updater/testdata/index.json
@@ -1,9 +1,9 @@
{
- "ApiVersion": 0,
- "Versions": [
- { "Id": 0, "Name": "1.0.0" },
- { "Id": 1, "Name": "1.0.1" },
- { "Id": 2, "Name": "1.0.2" },
- { "Id": 3, "Name": "1.0.3" }
- ]
+ "ApiVersion": 0,
+ "Versions": [
+ { "Id": 0, "Name": "1.0.0" },
+ { "Id": 1, "Name": "1.0.1" },
+ { "Id": 2, "Name": "1.0.2" },
+ { "Id": 3, "Name": "1.0.3" }
+ ]
}
diff --git a/api/logic/updater/testdata/noChannels.json b/api/logic/updater/testdata/noChannels.json
index bbb2cb70..76988982 100644
--- a/api/logic/updater/testdata/noChannels.json
+++ b/api/logic/updater/testdata/noChannels.json
@@ -1,5 +1,5 @@
{
- "format_version": 0,
- "channels": [
- ]
+ "format_version": 0,
+ "channels": [
+ ]
}
diff --git a/api/logic/updater/testdata/oneChannel.json b/api/logic/updater/testdata/oneChannel.json
index 84727ac7..cc8ed255 100644
--- a/api/logic/updater/testdata/oneChannel.json
+++ b/api/logic/updater/testdata/oneChannel.json
@@ -1,11 +1,11 @@
{
- "format_version": 0,
- "channels": [
- {
- "id": "develop",
- "name": "Develop",
- "description": "The channel called \"develop\"",
- "url": "http://example.org/stuff"
- }
- ]
+ "format_version": 0,
+ "channels": [
+ {
+ "id": "develop",
+ "name": "Develop",
+ "description": "The channel called \"develop\"",
+ "url": "http://example.org/stuff"
+ }
+ ]
}
diff --git a/application/BuildConfig.cpp.in b/application/BuildConfig.cpp.in
index 99551867..a1d236b2 100644
--- a/application/BuildConfig.cpp.in
+++ b/application/BuildConfig.cpp.in
@@ -5,50 +5,50 @@ Config BuildConfig;
Config::Config()
{
- // Version information
- VERSION_MAJOR = @MultiMC_VERSION_MAJOR@;
- VERSION_MINOR = @MultiMC_VERSION_MINOR@;
- VERSION_HOTFIX = @MultiMC_VERSION_HOTFIX@;
- VERSION_BUILD = @MultiMC_VERSION_BUILD@;
-
- BUILD_PLATFORM = "@MultiMC_BUILD_PLATFORM@";
- CHANLIST_URL = "@MultiMC_CHANLIST_URL@";
- ANALYTICS_ID = "@MultiMC_ANALYTICS_ID@";
- NOTIFICATION_URL = "@MultiMC_NOTIFICATION_URL@";
- FULL_VERSION_STR = "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_BUILD@";
-
- GIT_COMMIT = "@MultiMC_GIT_COMMIT@";
- GIT_REFSPEC = "@MultiMC_GIT_REFSPEC@";
- if(GIT_REFSPEC.startsWith("refs/heads/") && !CHANLIST_URL.isEmpty() && VERSION_BUILD >= 0)
- {
- VERSION_CHANNEL = GIT_REFSPEC;
- VERSION_CHANNEL.remove("refs/heads/");
- UPDATER_ENABLED = true;
- }
- else
- {
- VERSION_CHANNEL = QObject::tr("custom");
- }
-
- VERSION_STR = "@MultiMC_VERSION_STRING@";
- NEWS_RSS_URL = "@MultiMC_NEWS_RSS_URL@";
- PASTE_EE_KEY = "@MultiMC_PASTE_EE_API_KEY@";
+ // Version information
+ VERSION_MAJOR = @MultiMC_VERSION_MAJOR@;
+ VERSION_MINOR = @MultiMC_VERSION_MINOR@;
+ VERSION_HOTFIX = @MultiMC_VERSION_HOTFIX@;
+ VERSION_BUILD = @MultiMC_VERSION_BUILD@;
+
+ BUILD_PLATFORM = "@MultiMC_BUILD_PLATFORM@";
+ CHANLIST_URL = "@MultiMC_CHANLIST_URL@";
+ ANALYTICS_ID = "@MultiMC_ANALYTICS_ID@";
+ NOTIFICATION_URL = "@MultiMC_NOTIFICATION_URL@";
+ FULL_VERSION_STR = "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_BUILD@";
+
+ GIT_COMMIT = "@MultiMC_GIT_COMMIT@";
+ GIT_REFSPEC = "@MultiMC_GIT_REFSPEC@";
+ if(GIT_REFSPEC.startsWith("refs/heads/") && !CHANLIST_URL.isEmpty() && VERSION_BUILD >= 0)
+ {
+ VERSION_CHANNEL = GIT_REFSPEC;
+ VERSION_CHANNEL.remove("refs/heads/");
+ UPDATER_ENABLED = true;
+ }
+ else
+ {
+ VERSION_CHANNEL = QObject::tr("custom");
+ }
+
+ VERSION_STR = "@MultiMC_VERSION_STRING@";
+ NEWS_RSS_URL = "@MultiMC_NEWS_RSS_URL@";
+ PASTE_EE_KEY = "@MultiMC_PASTE_EE_API_KEY@";
}
QString Config::printableVersionString() const
{
- QString vstr = QString("%1.%2.%3").arg(QString::number(VERSION_MAJOR), QString::number(VERSION_MINOR), QString::number(VERSION_HOTFIX));
-
- // If the build is not a main release, append the channel
- if(VERSION_CHANNEL != "stable")
- {
- vstr += "-" + VERSION_CHANNEL;
- }
-
- // if a build number is set, also add it to the end
- if(VERSION_BUILD >= 0)
- {
- vstr += "-" + QString::number(VERSION_BUILD);
- }
- return vstr;
+ QString vstr = QString("%1.%2.%3").arg(QString::number(VERSION_MAJOR), QString::number(VERSION_MINOR), QString::number(VERSION_HOTFIX));
+
+ // If the build is not a main release, append the channel
+ if(VERSION_CHANNEL != "stable")
+ {
+ vstr += "-" + VERSION_CHANNEL;
+ }
+
+ // if a build number is set, also add it to the end
+ if(VERSION_BUILD >= 0)
+ {
+ vstr += "-" + QString::number(VERSION_BUILD);
+ }
+ return vstr;
}
diff --git a/application/BuildConfig.h b/application/BuildConfig.h
index 1c9466ba..05fff490 100644
--- a/application/BuildConfig.h
+++ b/application/BuildConfig.h
@@ -7,64 +7,64 @@
class Config
{
public:
- Config();
- /// The major version number.
- int VERSION_MAJOR;
- /// The minor version number.
- int VERSION_MINOR;
- /// The hotfix number.
- int VERSION_HOTFIX;
- /// The build number.
- int VERSION_BUILD;
+ Config();
+ /// The major version number.
+ int VERSION_MAJOR;
+ /// The minor version number.
+ int VERSION_MINOR;
+ /// The hotfix number.
+ int VERSION_HOTFIX;
+ /// The build number.
+ int VERSION_BUILD;
- /**
- * The version channel
- * This is used by the updater to determine what channel the current version came from.
- */
- QString VERSION_CHANNEL;
+ /**
+ * The version channel
+ * This is used by the updater to determine what channel the current version came from.
+ */
+ QString VERSION_CHANNEL;
- bool UPDATER_ENABLED = false;
+ bool UPDATER_ENABLED = false;
- /// A short string identifying this build's platform. For example, "lin64" or "win32".
- QString BUILD_PLATFORM;
+ /// A short string identifying this build's platform. For example, "lin64" or "win32".
+ QString BUILD_PLATFORM;
- /// URL for the updater's channel
- QString CHANLIST_URL;
+ /// URL for the updater's channel
+ QString CHANLIST_URL;
- /// Google analytics ID
- QString ANALYTICS_ID;
+ /// Google analytics ID
+ QString ANALYTICS_ID;
- /// URL for notifications
- QString NOTIFICATION_URL;
+ /// URL for notifications
+ QString NOTIFICATION_URL;
- /// Used for matching notifications
- QString FULL_VERSION_STR;
+ /// Used for matching notifications
+ QString FULL_VERSION_STR;
- /// The git commit hash of this build
- QString GIT_COMMIT;
+ /// The git commit hash of this build
+ QString GIT_COMMIT;
- /// The git refspec of this build
- QString GIT_REFSPEC;
+ /// The git refspec of this build
+ QString GIT_REFSPEC;
- /// This is printed on start to standard output
- QString VERSION_STR;
+ /// This is printed on start to standard output
+ QString VERSION_STR;
- /**
- * This is used to fetch the news RSS feed.
- * It defaults in CMakeLists.txt to "http://multimc.org/rss.xml"
- */
- QString NEWS_RSS_URL;
+ /**
+ * This is used to fetch the news RSS feed.
+ * It defaults in CMakeLists.txt to "http://multimc.org/rss.xml"
+ */
+ QString NEWS_RSS_URL;
- /**
- * API key you can get from paste.ee when you register an account
- */
- QString PASTE_EE_KEY;
+ /**
+ * API key you can get from paste.ee when you register an account
+ */
+ QString PASTE_EE_KEY;
- /**
- * \brief Converts the Version to a string.
- * \return The version number in string format (major.minor.revision.build).
- */
- QString printableVersionString() const;
+ /**
+ * \brief Converts the Version to a string.
+ * \return The version number in string format (major.minor.revision.build).
+ */
+ QString printableVersionString() const;
};
extern Config BuildConfig;
diff --git a/application/ColorCache.cpp b/application/ColorCache.cpp
index e216b597..ef268dd2 100644
--- a/application/ColorCache.cpp
+++ b/application/ColorCache.cpp
@@ -6,13 +6,13 @@
*/
QColor ColorCache::blend(QColor color)
{
- if (Rainbow::luma(m_front) > Rainbow::luma(m_back))
- {
- // for dark color schemes, produce a fitting color first
- color = Rainbow::tint(m_front, color, 0.5);
- }
- // adapt contrast
- return Rainbow::mix(m_front, color, m_bias);
+ if (Rainbow::luma(m_front) > Rainbow::luma(m_back))
+ {
+ // for dark color schemes, produce a fitting color first
+ color = Rainbow::tint(m_front, color, 0.5);
+ }
+ // adapt contrast
+ return Rainbow::mix(m_front, color, m_bias);
}
/**
@@ -20,16 +20,16 @@ QColor ColorCache::blend(QColor color)
*/
QColor ColorCache::blendBackground(QColor color)
{
- // adapt contrast
- return Rainbow::mix(m_back, color, m_bias);
+ // adapt contrast
+ return Rainbow::mix(m_back, color, m_bias);
}
void ColorCache::recolorAll()
{
- auto iter = m_colors.begin();
- while(iter != m_colors.end())
- {
- iter->front = blend(iter->original);
- iter->back = blendBackground(iter->original);
- }
+ auto iter = m_colors.begin();
+ while(iter != m_colors.end())
+ {
+ iter->front = blend(iter->original);
+ iter->back = blendBackground(iter->original);
+ }
}
diff --git a/application/ColorCache.h b/application/ColorCache.h
index 1ce1c211..6ae633b9 100644
--- a/application/ColorCache.h
+++ b/application/ColorCache.h
@@ -7,113 +7,113 @@
class ColorCache
{
public:
- ColorCache(QColor front, QColor back, qreal bias)
- {
- m_front = front;
- m_back = back;
- m_bias = bias;
- };
+ ColorCache(QColor front, QColor back, qreal bias)
+ {
+ m_front = front;
+ m_back = back;
+ m_bias = bias;
+ };
- void addColor(int key, QColor color)
- {
- m_colors[key] = {color, blend(color), blendBackground(color)};
- }
+ void addColor(int key, QColor color)
+ {
+ m_colors[key] = {color, blend(color), blendBackground(color)};
+ }
- void setForeground(QColor front)
- {
- if(m_front != front)
- {
- m_front = front;
- recolorAll();
- }
- }
+ void setForeground(QColor front)
+ {
+ if(m_front != front)
+ {
+ m_front = front;
+ recolorAll();
+ }
+ }
- void setBackground(QColor back)
- {
- if(m_back != back)
- {
- m_back = back;
- recolorAll();
- }
- }
+ void setBackground(QColor back)
+ {
+ if(m_back != back)
+ {
+ m_back = back;
+ recolorAll();
+ }
+ }
- QColor getFront(int key)
- {
- auto iter = m_colors.find(key);
- if(iter == m_colors.end())
- {
- return QColor();
- }
- return (*iter).front;
- }
+ QColor getFront(int key)
+ {
+ auto iter = m_colors.find(key);
+ if(iter == m_colors.end())
+ {
+ return QColor();
+ }
+ return (*iter).front;
+ }
- QColor getBack(int key)
- {
- auto iter = m_colors.find(key);
- if(iter == m_colors.end())
- {
- return QColor();
- }
- return (*iter).back;
- }
+ QColor getBack(int key)
+ {
+ auto iter = m_colors.find(key);
+ if(iter == m_colors.end())
+ {
+ return QColor();
+ }
+ return (*iter).back;
+ }
- /**
- * Blend the color with the front color, adapting to the back color
- */
- QColor blend(QColor color);
+ /**
+ * Blend the color with the front color, adapting to the back color
+ */
+ QColor blend(QColor color);
- /**
- * Blend the color with the back color
- */
- QColor blendBackground(QColor color);
+ /**
+ * Blend the color with the back color
+ */
+ QColor blendBackground(QColor color);
protected:
- void recolorAll();
+ void recolorAll();
protected:
- struct ColorEntry
- {
- QColor original;
- QColor front;
- QColor back;
- };
+ struct ColorEntry
+ {
+ QColor original;
+ QColor front;
+ QColor back;
+ };
protected:
- qreal m_bias;
- QColor m_front;
- QColor m_back;
- QMap<int, ColorEntry> m_colors;
+ qreal m_bias;
+ QColor m_front;
+ QColor m_back;
+ QMap<int, ColorEntry> m_colors;
};
class LogColorCache : public ColorCache
{
public:
- LogColorCache(QColor front, QColor back)
- : ColorCache(front, back, 1.0)
- {
- addColor((int)MessageLevel::MultiMC, QColor("purple"));
- addColor((int)MessageLevel::Debug, QColor("green"));
- addColor((int)MessageLevel::Warning, QColor("orange"));
- addColor((int)MessageLevel::Error, QColor("red"));
- addColor((int)MessageLevel::Fatal, QColor("red"));
- addColor((int)MessageLevel::Message, front);
- }
+ LogColorCache(QColor front, QColor back)
+ : ColorCache(front, back, 1.0)
+ {
+ addColor((int)MessageLevel::MultiMC, QColor("purple"));
+ addColor((int)MessageLevel::Debug, QColor("green"));
+ addColor((int)MessageLevel::Warning, QColor("orange"));
+ addColor((int)MessageLevel::Error, QColor("red"));
+ addColor((int)MessageLevel::Fatal, QColor("red"));
+ addColor((int)MessageLevel::Message, front);
+ }
- QColor getFront(MessageLevel::Enum level)
- {
- if(!m_colors.contains((int) level))
- {
- return ColorCache::getFront((int)MessageLevel::Message);
- }
- return ColorCache::getFront((int)level);
- }
+ QColor getFront(MessageLevel::Enum level)
+ {
+ if(!m_colors.contains((int) level))
+ {
+ return ColorCache::getFront((int)MessageLevel::Message);
+ }
+ return ColorCache::getFront((int)level);
+ }
- QColor getBack(MessageLevel::Enum level)
- {
- if(level == MessageLevel::Fatal)
- {
- return QColor(Qt::black);
- }
- return QColor(Qt::transparent);
- }
+ QColor getBack(MessageLevel::Enum level)
+ {
+ if(level == MessageLevel::Fatal)
+ {
+ return QColor(Qt::black);
+ }
+ return QColor(Qt::transparent);
+ }
};
diff --git a/application/ColumnResizer.cpp b/application/ColumnResizer.cpp
index ee99bf40..fe415067 100644
--- a/application/ColumnResizer.cpp
+++ b/application/ColumnResizer.cpp
@@ -14,67 +14,67 @@
class FormLayoutWidgetItem : public QWidgetItem
{
public:
- FormLayoutWidgetItem(QWidget* widget, QFormLayout* formLayout, QFormLayout::ItemRole itemRole)
- : QWidgetItem(widget)
- , m_width(-1)
- , m_formLayout(formLayout)
- , m_itemRole(itemRole)
- {}
-
- QSize sizeHint() const
- {
- QSize size = QWidgetItem::sizeHint();
- if (m_width != -1) {
- size.setWidth(m_width);
- }
- return size;
- }
-
- QSize minimumSize() const
- {
- QSize size = QWidgetItem::minimumSize();
- if (m_width != -1) {
- size.setWidth(m_width);
- }
- return size;
- }
-
- QSize maximumSize() const
- {
- QSize size = QWidgetItem::maximumSize();
- if (m_width != -1) {
- size.setWidth(m_width);
- }
- return size;
- }
-
- void setWidth(int width)
- {
- if (width != m_width) {
- m_width = width;
- invalidate();
- }
- }
-
- void setGeometry(const QRect& _rect)
- {
- QRect rect = _rect;
- int width = widget()->sizeHint().width();
- if (m_itemRole == QFormLayout::LabelRole && m_formLayout->labelAlignment() & Qt::AlignRight) {
- rect.setLeft(rect.right() - width);
- }
- QWidgetItem::setGeometry(rect);
- }
-
- QFormLayout* formLayout() const
- {
- return m_formLayout;
- }
+ FormLayoutWidgetItem(QWidget* widget, QFormLayout* formLayout, QFormLayout::ItemRole itemRole)
+ : QWidgetItem(widget)
+ , m_width(-1)
+ , m_formLayout(formLayout)
+ , m_itemRole(itemRole)
+ {}
+
+ QSize sizeHint() const
+ {
+ QSize size = QWidgetItem::sizeHint();
+ if (m_width != -1) {
+ size.setWidth(m_width);
+ }
+ return size;
+ }
+
+ QSize minimumSize() const
+ {
+ QSize size = QWidgetItem::minimumSize();
+ if (m_width != -1) {
+ size.setWidth(m_width);
+ }
+ return size;
+ }
+
+ QSize maximumSize() const
+ {
+ QSize size = QWidgetItem::maximumSize();
+ if (m_width != -1) {
+ size.setWidth(m_width);
+ }
+ return size;
+ }
+
+ void setWidth(int width)
+ {
+ if (width != m_width) {
+ m_width = width;
+ invalidate();
+ }
+ }
+
+ void setGeometry(const QRect& _rect)
+ {
+ QRect rect = _rect;
+ int width = widget()->sizeHint().width();
+ if (m_itemRole == QFormLayout::LabelRole && m_formLayout->labelAlignment() & Qt::AlignRight) {
+ rect.setLeft(rect.right() - width);
+ }
+ QWidgetItem::setGeometry(rect);
+ }
+
+ QFormLayout* formLayout() const
+ {
+ return m_formLayout;
+ }
private:
- int m_width;
- QFormLayout* m_formLayout;
- QFormLayout::ItemRole m_itemRole;
+ int m_width;
+ QFormLayout* m_formLayout;
+ QFormLayout::ItemRole m_itemRole;
};
typedef QPair<QGridLayout*, int> GridColumnInfo;
@@ -82,25 +82,25 @@ typedef QPair<QGridLayout*, int> GridColumnInfo;
class ColumnResizerPrivate
{
public:
- ColumnResizerPrivate(ColumnResizer* q_ptr)
- : q(q_ptr)
- , m_updateTimer(new QTimer(q))
- {
- m_updateTimer->setSingleShot(true);
- m_updateTimer->setInterval(0);
- QObject::connect(m_updateTimer, SIGNAL(timeout()), q, SLOT(updateWidth()));
- }
-
- void scheduleWidthUpdate()
- {
- m_updateTimer->start();
- }
-
- ColumnResizer* q;
- QTimer* m_updateTimer;
- QList<QWidget*> m_widgets;
- QList<FormLayoutWidgetItem*> m_wrWidgetItemList;
- QList<GridColumnInfo> m_gridColumnInfoList;
+ ColumnResizerPrivate(ColumnResizer* q_ptr)
+ : q(q_ptr)
+ , m_updateTimer(new QTimer(q))
+ {
+ m_updateTimer->setSingleShot(true);
+ m_updateTimer->setInterval(0);
+ QObject::connect(m_updateTimer, SIGNAL(timeout()), q, SLOT(updateWidth()));
+ }
+
+ void scheduleWidthUpdate()
+ {
+ m_updateTimer->start();
+ }
+
+ ColumnResizer* q;
+ QTimer* m_updateTimer;
+ QList<QWidget*> m_widgets;
+ QList<FormLayoutWidgetItem*> m_wrWidgetItemList;
+ QList<GridColumnInfo> m_gridColumnInfoList;
};
ColumnResizer::ColumnResizer(QObject* parent)
@@ -110,90 +110,90 @@ ColumnResizer::ColumnResizer(QObject* parent)
ColumnResizer::~ColumnResizer()
{
- delete d;
+ delete d;
}
void ColumnResizer::addWidget(QWidget* widget)
{
- d->m_widgets.append(widget);
- widget->installEventFilter(this);
- d->scheduleWidthUpdate();
+ d->m_widgets.append(widget);
+ widget->installEventFilter(this);
+ d->scheduleWidthUpdate();
}
void ColumnResizer::updateWidth()
{
- int width = 0;
- Q_FOREACH(QWidget* widget, d->m_widgets) {
- width = qMax(widget->sizeHint().width(), width);
- }
- Q_FOREACH(FormLayoutWidgetItem* item, d->m_wrWidgetItemList) {
- item->setWidth(width);
- item->formLayout()->update();
- }
- Q_FOREACH(GridColumnInfo info, d->m_gridColumnInfoList) {
- info.first->setColumnMinimumWidth(info.second, width);
- }
+ int width = 0;
+ Q_FOREACH(QWidget* widget, d->m_widgets) {
+ width = qMax(widget->sizeHint().width(), width);
+ }
+ Q_FOREACH(FormLayoutWidgetItem* item, d->m_wrWidgetItemList) {
+ item->setWidth(width);
+ item->formLayout()->update();
+ }
+ Q_FOREACH(GridColumnInfo info, d->m_gridColumnInfoList) {
+ info.first->setColumnMinimumWidth(info.second, width);
+ }
}
bool ColumnResizer::eventFilter(QObject*, QEvent* event)
{
- if (event->type() == QEvent::Resize) {
- d->scheduleWidthUpdate();
- }
- return false;
+ if (event->type() == QEvent::Resize) {
+ d->scheduleWidthUpdate();
+ }
+ return false;
}
void ColumnResizer::addWidgetsFromLayout(QLayout* layout, int column)
{
- Q_ASSERT(column >= 0);
- QGridLayout* gridLayout = qobject_cast<QGridLayout*>(layout);
- QFormLayout* formLayout = qobject_cast<QFormLayout*>(layout);
- if (gridLayout) {
- addWidgetsFromGridLayout(gridLayout, column);
- } else if (formLayout) {
- if (column > QFormLayout::SpanningRole) {
- qCritical() << "column should not be more than" << QFormLayout::SpanningRole << "for QFormLayout";
- return;
- }
- QFormLayout::ItemRole role = static_cast<QFormLayout::ItemRole>(column);
- addWidgetsFromFormLayout(formLayout, role);
- } else {
- qCritical() << "Don't know how to handle layout" << layout;
- }
+ Q_ASSERT(column >= 0);
+ QGridLayout* gridLayout = qobject_cast<QGridLayout*>(layout);
+ QFormLayout* formLayout = qobject_cast<QFormLayout*>(layout);
+ if (gridLayout) {
+ addWidgetsFromGridLayout(gridLayout, column);
+ } else if (formLayout) {
+ if (column > QFormLayout::SpanningRole) {
+ qCritical() << "column should not be more than" << QFormLayout::SpanningRole << "for QFormLayout";
+ return;
+ }
+ QFormLayout::ItemRole role = static_cast<QFormLayout::ItemRole>(column);
+ addWidgetsFromFormLayout(formLayout, role);
+ } else {
+ qCritical() << "Don't know how to handle layout" << layout;
+ }
}
void ColumnResizer::addWidgetsFromGridLayout(QGridLayout* layout, int column)
{
- for (int row = 0; row < layout->rowCount(); ++row) {
- QLayoutItem* item = layout->itemAtPosition(row, column);
- if (!item) {
- continue;
- }
- QWidget* widget = item->widget();
- if (!widget) {
- continue;
- }
- addWidget(widget);
- }
- d->m_gridColumnInfoList << GridColumnInfo(layout, column);
+ for (int row = 0; row < layout->rowCount(); ++row) {
+ QLayoutItem* item = layout->itemAtPosition(row, column);
+ if (!item) {
+ continue;
+ }
+ QWidget* widget = item->widget();
+ if (!widget) {
+ continue;
+ }
+ addWidget(widget);
+ }
+ d->m_gridColumnInfoList << GridColumnInfo(layout, column);
}
void ColumnResizer::addWidgetsFromFormLayout(QFormLayout* layout, QFormLayout::ItemRole role)
{
- for (int row = 0; row < layout->rowCount(); ++row) {
- QLayoutItem* item = layout->itemAt(row, role);
- if (!item) {
- continue;
- }
- QWidget* widget = item->widget();
- if (!widget) {
- continue;
- }
- layout->removeItem(item);
- delete item;
- FormLayoutWidgetItem* newItem = new FormLayoutWidgetItem(widget, layout, role);
- layout->setItem(row, role, newItem);
- addWidget(widget);
- d->m_wrWidgetItemList << newItem;
- }
+ for (int row = 0; row < layout->rowCount(); ++row) {
+ QLayoutItem* item = layout->itemAt(row, role);
+ if (!item) {
+ continue;
+ }
+ QWidget* widget = item->widget();
+ if (!widget) {
+ continue;
+ }
+ layout->removeItem(item);
+ delete item;
+ FormLayoutWidgetItem* newItem = new FormLayoutWidgetItem(widget, layout, role);
+ layout->setItem(row, role, newItem);
+ addWidget(widget);
+ d->m_wrWidgetItemList << newItem;
+ }
}
diff --git a/application/ColumnResizer.h b/application/ColumnResizer.h
index 78966a7e..8c920f01 100644
--- a/application/ColumnResizer.h
+++ b/application/ColumnResizer.h
@@ -18,24 +18,24 @@ class QWidget;
class ColumnResizerPrivate;
class ColumnResizer : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- ColumnResizer(QObject* parent = 0);
- ~ColumnResizer();
+ ColumnResizer(QObject* parent = 0);
+ ~ColumnResizer();
- void addWidget(QWidget* widget);
- void addWidgetsFromLayout(QLayout*, int column);
- void addWidgetsFromGridLayout(QGridLayout*, int column);
- void addWidgetsFromFormLayout(QFormLayout*, QFormLayout::ItemRole role);
+ void addWidget(QWidget* widget);
+ void addWidgetsFromLayout(QLayout*, int column);
+ void addWidgetsFromGridLayout(QGridLayout*, int column);
+ void addWidgetsFromFormLayout(QFormLayout*, QFormLayout::ItemRole role);
private Q_SLOTS:
- void updateWidth();
+ void updateWidth();
protected:
- bool eventFilter(QObject*, QEvent* event);
+ bool eventFilter(QObject*, QEvent* event);
private:
- ColumnResizerPrivate* const d;
+ ColumnResizerPrivate* const d;
};
#endif /* COLUMNRESIZER_H */
diff --git a/application/GuiUtil.cpp b/application/GuiUtil.cpp
index b05fc57c..302206f5 100644
--- a/application/GuiUtil.cpp
+++ b/application/GuiUtil.cpp
@@ -15,117 +15,117 @@
QString GuiUtil::uploadPaste(const QString &text, QWidget *parentWidget)
{
- ProgressDialog dialog(parentWidget);
- auto APIKeySetting = MMC->settings()->get("PasteEEAPIKey").toString();
- if(APIKeySetting == "multimc")
- {
- APIKeySetting = BuildConfig.PASTE_EE_KEY;
- }
- std::unique_ptr<PasteUpload> paste(new PasteUpload(parentWidget, text, APIKeySetting));
-
- if (!paste->validateText())
- {
- CustomMessageBox::selectable(
- parentWidget, QObject::tr("Upload failed"),
- QObject::tr("The log file is too big. You'll have to upload it manually."),
- QMessageBox::Warning)->exec();
- return QString();
- }
-
- dialog.execWithTask(paste.get());
- if (!paste->wasSuccessful())
- {
- CustomMessageBox::selectable(parentWidget, QObject::tr("Upload failed"),
- paste->failReason(), QMessageBox::Critical)->exec();
- return QString();
- }
- else
- {
- const QString link = paste->pasteLink();
- setClipboardText(link);
- CustomMessageBox::selectable(
- parentWidget, QObject::tr("Upload finished"),
- QObject::tr("The <a href=\"%1\">link to the uploaded log</a> has been placed in your clipboard.").arg(link),
- QMessageBox::Information)->exec();
- return link;
- }
+ ProgressDialog dialog(parentWidget);
+ auto APIKeySetting = MMC->settings()->get("PasteEEAPIKey").toString();
+ if(APIKeySetting == "multimc")
+ {
+ APIKeySetting = BuildConfig.PASTE_EE_KEY;
+ }
+ std::unique_ptr<PasteUpload> paste(new PasteUpload(parentWidget, text, APIKeySetting));
+
+ if (!paste->validateText())
+ {
+ CustomMessageBox::selectable(
+ parentWidget, QObject::tr("Upload failed"),
+ QObject::tr("The log file is too big. You'll have to upload it manually."),
+ QMessageBox::Warning)->exec();
+ return QString();
+ }
+
+ dialog.execWithTask(paste.get());
+ if (!paste->wasSuccessful())
+ {
+ CustomMessageBox::selectable(parentWidget, QObject::tr("Upload failed"),
+ paste->failReason(), QMessageBox::Critical)->exec();
+ return QString();
+ }
+ else
+ {
+ const QString link = paste->pasteLink();
+ setClipboardText(link);
+ CustomMessageBox::selectable(
+ parentWidget, QObject::tr("Upload finished"),
+ QObject::tr("The <a href=\"%1\">link to the uploaded log</a> has been placed in your clipboard.").arg(link),
+ QMessageBox::Information)->exec();
+ return link;
+ }
}
void GuiUtil::setClipboardText(const QString &text)
{
- QApplication::clipboard()->setText(text);
+ QApplication::clipboard()->setText(text);
}
static QStringList BrowseForFileInternal(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget, bool single)
{
- static QMap<QString, QString> savedPaths;
-
- QFileDialog w(parentWidget, caption);
- QSet<QString> locations;
- auto f = [&](QStandardPaths::StandardLocation l)
- {
- QString location = QStandardPaths::writableLocation(l);
- QFileInfo finfo(location);
- if (!finfo.exists())
- return;
- locations.insert(location);
- };
- f(QStandardPaths::DesktopLocation);
- f(QStandardPaths::DocumentsLocation);
- f(QStandardPaths::DownloadLocation);
- f(QStandardPaths::HomeLocation);
- QList<QUrl> urls;
- for (auto location : locations)
- {
- urls.append(QUrl::fromLocalFile(location));
- }
- urls.append(QUrl::fromLocalFile(defaultPath));
-
- w.setFileMode(single ? QFileDialog::ExistingFile : QFileDialog::ExistingFiles);
- w.setAcceptMode(QFileDialog::AcceptOpen);
- w.setNameFilter(filter);
-
- QString pathToOpen;
- if(savedPaths.contains(context))
- {
- pathToOpen = savedPaths[context];
- }
- else
- {
- pathToOpen = defaultPath;
- }
- if(!pathToOpen.isEmpty())
- {
- QFileInfo finfo(pathToOpen);
- if(finfo.exists() && finfo.isDir())
- {
- w.setDirectory(finfo.absoluteFilePath());
- }
- }
-
- w.setSidebarUrls(urls);
-
- if (w.exec())
- {
- savedPaths[context] = w.directory().absolutePath();
- return w.selectedFiles();
- }
- savedPaths[context] = w.directory().absolutePath();
- return {};
+ static QMap<QString, QString> savedPaths;
+
+ QFileDialog w(parentWidget, caption);
+ QSet<QString> locations;
+ auto f = [&](QStandardPaths::StandardLocation l)
+ {
+ QString location = QStandardPaths::writableLocation(l);
+ QFileInfo finfo(location);
+ if (!finfo.exists())
+ return;
+ locations.insert(location);
+ };
+ f(QStandardPaths::DesktopLocation);
+ f(QStandardPaths::DocumentsLocation);
+ f(QStandardPaths::DownloadLocation);
+ f(QStandardPaths::HomeLocation);
+ QList<QUrl> urls;
+ for (auto location : locations)
+ {
+ urls.append(QUrl::fromLocalFile(location));
+ }
+ urls.append(QUrl::fromLocalFile(defaultPath));
+
+ w.setFileMode(single ? QFileDialog::ExistingFile : QFileDialog::ExistingFiles);
+ w.setAcceptMode(QFileDialog::AcceptOpen);
+ w.setNameFilter(filter);
+
+ QString pathToOpen;
+ if(savedPaths.contains(context))
+ {
+ pathToOpen = savedPaths[context];
+ }
+ else
+ {
+ pathToOpen = defaultPath;
+ }
+ if(!pathToOpen.isEmpty())
+ {
+ QFileInfo finfo(pathToOpen);
+ if(finfo.exists() && finfo.isDir())
+ {
+ w.setDirectory(finfo.absoluteFilePath());
+ }
+ }
+
+ w.setSidebarUrls(urls);
+
+ if (w.exec())
+ {
+ savedPaths[context] = w.directory().absolutePath();
+ return w.selectedFiles();
+ }
+ savedPaths[context] = w.directory().absolutePath();
+ return {};
}
QString GuiUtil::BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget)
{
- auto resultList = BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, true);
- if(resultList.size())
- {
- return resultList[0];
- }
- return QString();
+ auto resultList = BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, true);
+ if(resultList.size())
+ {
+ return resultList[0];
+ }
+ return QString();
}
QStringList GuiUtil::BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget)
{
- return BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, false);
+ return BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, false);
}
diff --git a/application/HoeDown.h b/application/HoeDown.h
index 18c315c6..ba94da8c 100644
--- a/application/HoeDown.h
+++ b/application/HoeDown.h
@@ -25,52 +25,52 @@
class HoeDown
{
public:
- class buffer
- {
- public:
- buffer(size_t unit = 4096)
- {
- buf = hoedown_buffer_new(unit);
- }
- ~buffer()
- {
- hoedown_buffer_free(buf);
- }
- const char * cstr()
- {
- return hoedown_buffer_cstr(buf);
- }
- void put(QByteArray input)
- {
- hoedown_buffer_put(buf, (uint8_t *) input.data(), input.size());
- }
- const uint8_t * data() const
- {
- return buf->data;
- }
- size_t size() const
- {
- return buf->size;
- }
- hoedown_buffer * buf;
- } ib, ob;
- HoeDown()
- {
- renderer = hoedown_html_renderer_new((hoedown_html_flags) 0,0);
- document = hoedown_document_new(renderer, (hoedown_extensions) 0, 8);
- }
- ~HoeDown()
- {
- hoedown_document_free(document);
- hoedown_html_renderer_free(renderer);
- }
- QString process(QByteArray input)
- {
- ib.put(input);
- hoedown_document_render(document, ob.buf, ib.data(), ib.size());
- return ob.cstr();
- }
+ class buffer
+ {
+ public:
+ buffer(size_t unit = 4096)
+ {
+ buf = hoedown_buffer_new(unit);
+ }
+ ~buffer()
+ {
+ hoedown_buffer_free(buf);
+ }
+ const char * cstr()
+ {
+ return hoedown_buffer_cstr(buf);
+ }
+ void put(QByteArray input)
+ {
+ hoedown_buffer_put(buf, (uint8_t *) input.data(), input.size());
+ }
+ const uint8_t * data() const
+ {
+ return buf->data;
+ }
+ size_t size() const
+ {
+ return buf->size;
+ }
+ hoedown_buffer * buf;
+ } ib, ob;
+ HoeDown()
+ {
+ renderer = hoedown_html_renderer_new((hoedown_html_flags) 0,0);
+ document = hoedown_document_new(renderer, (hoedown_extensions) 0, 8);
+ }
+ ~HoeDown()
+ {
+ hoedown_document_free(document);
+ hoedown_html_renderer_free(renderer);
+ }
+ QString process(QByteArray input)
+ {
+ ib.put(input);
+ hoedown_document_render(document, ob.buf, ib.data(), ib.size());
+ return ob.cstr();
+ }
private:
- hoedown_document * document;
- hoedown_renderer * renderer;
+ hoedown_document * document;
+ hoedown_renderer * renderer;
};
diff --git a/application/InstancePageProvider.h b/application/InstancePageProvider.h
index ab0f9a72..d07b2ac2 100644
--- a/application/InstancePageProvider.h
+++ b/application/InstancePageProvider.h
@@ -21,57 +21,57 @@
class InstancePageProvider : public QObject, public BasePageProvider
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit InstancePageProvider(InstancePtr parent)
- {
- inst = parent;
- }
+ explicit InstancePageProvider(InstancePtr parent)
+ {
+ inst = parent;
+ }
- virtual ~InstancePageProvider() {};
- virtual QList<BasePage *> getPages() override
- {
- QList<BasePage *> values;
- values.append(new LogPage(inst));
- std::shared_ptr<MinecraftInstance> onesix = std::dynamic_pointer_cast<MinecraftInstance>(inst);
- if(onesix)
- {
- values.append(new VersionPage(onesix.get()));
- auto modsPage = new ModFolderPage(onesix.get(), onesix->loaderModList(), "mods", "loadermods", tr("Loader mods"), "Loader-mods");
- modsPage->setFilter("%1 (*.zip *.jar *.litemod)");
- values.append(modsPage);
- auto modsPage2 = new NewModFolderPage(onesix.get(), onesix->modsModel(), "newmods", "newloadermods", tr("New loader mods"), "New-loader-mods");
- modsPage2->setFilter("%1 (*.zip *.jar *.litemod)");
- values.append(modsPage2);
- values.append(new CoreModFolderPage(onesix.get(), onesix->coreModList(), "coremods", "coremods", tr("Core mods"), "Core-mods"));
- values.append(new ResourcePackPage(onesix.get()));
- values.append(new TexturePackPage(onesix.get()));
- values.append(new NotesPage(onesix.get()));
- values.append(new WorldListPage(onesix.get(), onesix->worldList(), "worlds", "worlds", tr("Worlds"), "Worlds"));
- values.append(new ServersPage(onesix.get()));
- values.append(new ScreenshotsPage(FS::PathCombine(onesix->minecraftRoot(), "screenshots")));
- values.append(new InstanceSettingsPage(onesix.get()));
- }
- std::shared_ptr<LegacyInstance> legacy = std::dynamic_pointer_cast<LegacyInstance>(inst);
- if(legacy)
- {
- values.append(new LegacyUpgradePage(legacy));
- values.append(new NotesPage(legacy.get()));
- values.append(new WorldListPage(legacy.get(), legacy->worldList(), "worlds", "worlds", tr("Worlds"), "Worlds"));
- values.append(new ScreenshotsPage(FS::PathCombine(legacy->minecraftRoot(), "screenshots")));
- }
- auto logMatcher = inst->getLogFileMatcher();
- if(logMatcher)
- {
- values.append(new OtherLogsPage(inst->getLogFileRoot(), logMatcher));
- }
- return values;
- }
+ virtual ~InstancePageProvider() {};
+ virtual QList<BasePage *> getPages() override
+ {
+ QList<BasePage *> values;
+ values.append(new LogPage(inst));
+ std::shared_ptr<MinecraftInstance> onesix = std::dynamic_pointer_cast<MinecraftInstance>(inst);
+ if(onesix)
+ {
+ values.append(new VersionPage(onesix.get()));
+ auto modsPage = new ModFolderPage(onesix.get(), onesix->loaderModList(), "mods", "loadermods", tr("Loader mods"), "Loader-mods");
+ modsPage->setFilter("%1 (*.zip *.jar *.litemod)");
+ values.append(modsPage);
+ auto modsPage2 = new NewModFolderPage(onesix.get(), onesix->modsModel(), "newmods", "newloadermods", tr("New loader mods"), "New-loader-mods");
+ modsPage2->setFilter("%1 (*.zip *.jar *.litemod)");
+ values.append(modsPage2);
+ values.append(new CoreModFolderPage(onesix.get(), onesix->coreModList(), "coremods", "coremods", tr("Core mods"), "Core-mods"));
+ values.append(new ResourcePackPage(onesix.get()));
+ values.append(new TexturePackPage(onesix.get()));
+ values.append(new NotesPage(onesix.get()));
+ values.append(new WorldListPage(onesix.get(), onesix->worldList(), "worlds", "worlds", tr("Worlds"), "Worlds"));
+ values.append(new ServersPage(onesix.get()));
+ values.append(new ScreenshotsPage(FS::PathCombine(onesix->minecraftRoot(), "screenshots")));
+ values.append(new InstanceSettingsPage(onesix.get()));
+ }
+ std::shared_ptr<LegacyInstance> legacy = std::dynamic_pointer_cast<LegacyInstance>(inst);
+ if(legacy)
+ {
+ values.append(new LegacyUpgradePage(legacy));
+ values.append(new NotesPage(legacy.get()));
+ values.append(new WorldListPage(legacy.get(), legacy->worldList(), "worlds", "worlds", tr("Worlds"), "Worlds"));
+ values.append(new ScreenshotsPage(FS::PathCombine(legacy->minecraftRoot(), "screenshots")));
+ }
+ auto logMatcher = inst->getLogFileMatcher();
+ if(logMatcher)
+ {
+ values.append(new OtherLogsPage(inst->getLogFileRoot(), logMatcher));
+ }
+ return values;
+ }
- virtual QString dialogTitle() override
- {
- return tr("Edit Instance (%1)").arg(inst->name());
- }
+ virtual QString dialogTitle() override
+ {
+ return tr("Edit Instance (%1)").arg(inst->name());
+ }
protected:
- InstancePtr inst;
+ InstancePtr inst;
};
diff --git a/application/InstanceProxyModel.cpp b/application/InstanceProxyModel.cpp
index d0e9e10d..5317f60c 100644
--- a/application/InstanceProxyModel.cpp
+++ b/application/InstanceProxyModel.cpp
@@ -9,26 +9,26 @@ InstanceProxyModel::InstanceProxyModel(QObject *parent) : GroupedProxyModel(pare
QVariant InstanceProxyModel::data(const QModelIndex & index, int role) const
{
- QVariant data = QSortFilterProxyModel::data(index, role);
- if(role == Qt::DecorationRole)
- {
- return QVariant(MMC->icons()->getIcon(data.toString()));
- }
- return data;
+ QVariant data = QSortFilterProxyModel::data(index, role);
+ if(role == Qt::DecorationRole)
+ {
+ return QVariant(MMC->icons()->getIcon(data.toString()));
+ }
+ return data;
}
bool InstanceProxyModel::subSortLessThan(const QModelIndex &left,
- const QModelIndex &right) const
+ const QModelIndex &right) const
{
- BaseInstance *pdataLeft = static_cast<BaseInstance *>(left.internalPointer());
- BaseInstance *pdataRight = static_cast<BaseInstance *>(right.internalPointer());
- QString sortMode = MMC->settings()->get("InstSortMode").toString();
- if (sortMode == "LastLaunch")
- {
- return pdataLeft->lastLaunch() > pdataRight->lastLaunch();
- }
- else
- {
- return QString::localeAwareCompare(pdataLeft->name(), pdataRight->name()) < 0;
- }
+ BaseInstance *pdataLeft = static_cast<BaseInstance *>(left.internalPointer());
+ BaseInstance *pdataRight = static_cast<BaseInstance *>(right.internalPointer());
+ QString sortMode = MMC->settings()->get("InstSortMode").toString();
+ if (sortMode == "LastLaunch")
+ {
+ return pdataLeft->lastLaunch() > pdataRight->lastLaunch();
+ }
+ else
+ {
+ return QString::localeAwareCompare(pdataLeft->name(), pdataRight->name()) < 0;
+ }
}
diff --git a/application/InstanceProxyModel.h b/application/InstanceProxyModel.h
index c063f526..fab6f834 100644
--- a/application/InstanceProxyModel.h
+++ b/application/InstanceProxyModel.h
@@ -8,9 +8,9 @@
class InstanceProxyModel : public GroupedProxyModel
{
public:
- explicit InstanceProxyModel(QObject *parent = 0);
- QVariant data(const QModelIndex & index, int role) const override;
+ explicit InstanceProxyModel(QObject *parent = 0);
+ QVariant data(const QModelIndex & index, int role) const override;
protected:
- virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const override;
+ virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const override;
};
diff --git a/application/InstanceWindow.cpp b/application/InstanceWindow.cpp
index b36781a7..711141f2 100644
--- a/application/InstanceWindow.cpp
+++ b/application/InstanceWindow.cpp
@@ -31,184 +31,184 @@
#include "icons/IconList.h"
InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent)
- : QMainWindow(parent), m_instance(instance)
+ : QMainWindow(parent), m_instance(instance)
{
- setAttribute(Qt::WA_DeleteOnClose);
-
- auto icon = MMC->icons()->getIcon(m_instance->iconKey());
- QString windowTitle = tr("Console window for ") + m_instance->name();
-
- // Set window properties
- {
- setWindowIcon(icon);
- setWindowTitle(windowTitle);
- }
-
- // Add page container
- {
- auto provider = std::make_shared<InstancePageProvider>(m_instance);
- m_container = new PageContainer(provider.get(), "console", this);
- m_container->setParentContainer(this);
- setCentralWidget(m_container);
- }
-
- // Add custom buttons to the page container layout.
- {
- auto horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
- horizontalLayout->setContentsMargins(6, -1, 6, -1);
-
- auto btnHelp = new QPushButton();
- btnHelp->setText(tr("Help"));
- horizontalLayout->addWidget(btnHelp);
- connect(btnHelp, SIGNAL(clicked(bool)), m_container, SLOT(help()));
-
- auto spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
- horizontalLayout->addSpacerItem(spacer);
-
- m_killButton = new QPushButton();
- horizontalLayout->addWidget(m_killButton);
- connect(m_killButton, SIGNAL(clicked(bool)), SLOT(on_btnKillMinecraft_clicked()));
-
- m_launchOfflineButton = new QPushButton();
- horizontalLayout->addWidget(m_launchOfflineButton);
- m_launchOfflineButton->setText(tr("Launch Offline"));
- updateLaunchButtons();
- connect(m_launchOfflineButton, SIGNAL(clicked(bool)), SLOT(on_btnLaunchMinecraftOffline_clicked()));
-
- m_closeButton = new QPushButton();
- m_closeButton->setText(tr("Close"));
- horizontalLayout->addWidget(m_closeButton);
- connect(m_closeButton, SIGNAL(clicked(bool)), SLOT(on_closeButton_clicked()));
-
- m_container->addButtons(horizontalLayout);
- }
-
- // restore window state
- {
- auto base64State = MMC->settings()->get("ConsoleWindowState").toByteArray();
- restoreState(QByteArray::fromBase64(base64State));
- auto base64Geometry = MMC->settings()->get("ConsoleWindowGeometry").toByteArray();
- restoreGeometry(QByteArray::fromBase64(base64Geometry));
- }
-
- // set up instance and launch process recognition
- {
- auto launchTask = m_instance->getLaunchTask();
- on_InstanceLaunchTask_changed(launchTask);
- connect(m_instance.get(), &BaseInstance::launchTaskChanged, this, &InstanceWindow::on_InstanceLaunchTask_changed);
- connect(m_instance.get(), &BaseInstance::runningStatusChanged, this, &InstanceWindow::on_RunningState_changed);
- }
-
- // set up instance destruction detection
- {
- connect(m_instance.get(), &BaseInstance::statusChanged, this, &InstanceWindow::on_instanceStatusChanged);
- }
- show();
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ auto icon = MMC->icons()->getIcon(m_instance->iconKey());
+ QString windowTitle = tr("Console window for ") + m_instance->name();
+
+ // Set window properties
+ {
+ setWindowIcon(icon);
+ setWindowTitle(windowTitle);
+ }
+
+ // Add page container
+ {
+ auto provider = std::make_shared<InstancePageProvider>(m_instance);
+ m_container = new PageContainer(provider.get(), "console", this);
+ m_container->setParentContainer(this);
+ setCentralWidget(m_container);
+ }
+
+ // Add custom buttons to the page container layout.
+ {
+ auto horizontalLayout = new QHBoxLayout();
+ horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setContentsMargins(6, -1, 6, -1);
+
+ auto btnHelp = new QPushButton();
+ btnHelp->setText(tr("Help"));
+ horizontalLayout->addWidget(btnHelp);
+ connect(btnHelp, SIGNAL(clicked(bool)), m_container, SLOT(help()));
+
+ auto spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout->addSpacerItem(spacer);
+
+ m_killButton = new QPushButton();
+ horizontalLayout->addWidget(m_killButton);
+ connect(m_killButton, SIGNAL(clicked(bool)), SLOT(on_btnKillMinecraft_clicked()));
+
+ m_launchOfflineButton = new QPushButton();
+ horizontalLayout->addWidget(m_launchOfflineButton);
+ m_launchOfflineButton->setText(tr("Launch Offline"));
+ updateLaunchButtons();
+ connect(m_launchOfflineButton, SIGNAL(clicked(bool)), SLOT(on_btnLaunchMinecraftOffline_clicked()));
+
+ m_closeButton = new QPushButton();
+ m_closeButton->setText(tr("Close"));
+ horizontalLayout->addWidget(m_closeButton);
+ connect(m_closeButton, SIGNAL(clicked(bool)), SLOT(on_closeButton_clicked()));
+
+ m_container->addButtons(horizontalLayout);
+ }
+
+ // restore window state
+ {
+ auto base64State = MMC->settings()->get("ConsoleWindowState").toByteArray();
+ restoreState(QByteArray::fromBase64(base64State));
+ auto base64Geometry = MMC->settings()->get("ConsoleWindowGeometry").toByteArray();
+ restoreGeometry(QByteArray::fromBase64(base64Geometry));
+ }
+
+ // set up instance and launch process recognition
+ {
+ auto launchTask = m_instance->getLaunchTask();
+ on_InstanceLaunchTask_changed(launchTask);
+ connect(m_instance.get(), &BaseInstance::launchTaskChanged, this, &InstanceWindow::on_InstanceLaunchTask_changed);
+ connect(m_instance.get(), &BaseInstance::runningStatusChanged, this, &InstanceWindow::on_RunningState_changed);
+ }
+
+ // set up instance destruction detection
+ {
+ connect(m_instance.get(), &BaseInstance::statusChanged, this, &InstanceWindow::on_instanceStatusChanged);
+ }
+ show();
}
void InstanceWindow::on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus)
{
- if(newStatus == BaseInstance::Status::Gone)
- {
- m_doNotSave = true;
- close();
- }
+ if(newStatus == BaseInstance::Status::Gone)
+ {
+ m_doNotSave = true;
+ close();
+ }
}
void InstanceWindow::updateLaunchButtons()
{
- if(m_instance->isRunning())
- {
- m_launchOfflineButton->setEnabled(false);
- m_killButton->setText(tr("Kill"));
- m_killButton->setToolTip(tr("Kill the running instance"));
- }
- else if(!m_instance->canLaunch())
- {
- m_launchOfflineButton->setEnabled(false);
- m_killButton->setText(tr("Launch"));
- m_killButton->setToolTip(tr("Launch the instance"));
- m_killButton->setEnabled(false);
- }
- else
- {
- m_launchOfflineButton->setEnabled(true);
- m_killButton->setText(tr("Launch"));
- m_killButton->setToolTip(tr("Launch the instance"));
- }
+ if(m_instance->isRunning())
+ {
+ m_launchOfflineButton->setEnabled(false);
+ m_killButton->setText(tr("Kill"));
+ m_killButton->setToolTip(tr("Kill the running instance"));
+ }
+ else if(!m_instance->canLaunch())
+ {
+ m_launchOfflineButton->setEnabled(false);
+ m_killButton->setText(tr("Launch"));
+ m_killButton->setToolTip(tr("Launch the instance"));
+ m_killButton->setEnabled(false);
+ }
+ else
+ {
+ m_launchOfflineButton->setEnabled(true);
+ m_killButton->setText(tr("Launch"));
+ m_killButton->setToolTip(tr("Launch the instance"));
+ }
}
void InstanceWindow::on_btnLaunchMinecraftOffline_clicked()
{
- MMC->launch(m_instance, false, nullptr);
+ MMC->launch(m_instance, false, nullptr);
}
void InstanceWindow::on_InstanceLaunchTask_changed(std::shared_ptr<LaunchTask> proc)
{
- m_proc = proc;
+ m_proc = proc;
}
void InstanceWindow::on_RunningState_changed(bool)
{
- updateLaunchButtons();
- m_container->refreshContainer();
+ updateLaunchButtons();
+ m_container->refreshContainer();
}
void InstanceWindow::on_closeButton_clicked()
{
- close();
+ close();
}
void InstanceWindow::closeEvent(QCloseEvent *event)
{
- bool proceed = true;
- if(!m_doNotSave)
- {
- proceed &= m_container->prepareToClose();
- }
-
- if(!proceed)
- {
- return;
- }
-
- MMC->settings()->set("ConsoleWindowState", saveState().toBase64());
- MMC->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64());
- emit isClosing();
- event->accept();
+ bool proceed = true;
+ if(!m_doNotSave)
+ {
+ proceed &= m_container->prepareToClose();
+ }
+
+ if(!proceed)
+ {
+ return;
+ }
+
+ MMC->settings()->set("ConsoleWindowState", saveState().toBase64());
+ MMC->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64());
+ emit isClosing();
+ event->accept();
}
bool InstanceWindow::saveAll()
{
- return m_container->saveAll();
+ return m_container->saveAll();
}
void InstanceWindow::on_btnKillMinecraft_clicked()
{
- if(m_instance->isRunning())
- {
- MMC->kill(m_instance);
- }
- else
- {
- MMC->launch(m_instance, true, nullptr);
- }
+ if(m_instance->isRunning())
+ {
+ MMC->kill(m_instance);
+ }
+ else
+ {
+ MMC->launch(m_instance, true, nullptr);
+ }
}
QString InstanceWindow::instanceId()
{
- return m_instance->id();
+ return m_instance->id();
}
bool InstanceWindow::selectPage(QString pageId)
{
- return m_container->selectPage(pageId);
+ return m_container->selectPage(pageId);
}
void InstanceWindow::refreshContainer()
{
- m_container->refreshContainer();
+ m_container->refreshContainer();
}
InstanceWindow::~InstanceWindow()
@@ -217,10 +217,10 @@ InstanceWindow::~InstanceWindow()
bool InstanceWindow::requestClose()
{
- if(m_container->prepareToClose())
- {
- close();
- return true;
- }
- return false;
+ if(m_container->prepareToClose())
+ {
+ close();
+ return true;
+ }
+ return false;
}
diff --git a/application/InstanceWindow.h b/application/InstanceWindow.h
index 2b08644e..c1d56143 100644
--- a/application/InstanceWindow.h
+++ b/application/InstanceWindow.h
@@ -26,48 +26,48 @@ class QPushButton;
class PageContainer;
class InstanceWindow : public QMainWindow, public BasePageContainer
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit InstanceWindow(InstancePtr proc, QWidget *parent = 0);
- virtual ~InstanceWindow();
+ explicit InstanceWindow(InstancePtr proc, QWidget *parent = 0);
+ virtual ~InstanceWindow();
- bool selectPage(QString pageId) override;
- void refreshContainer() override;
+ bool selectPage(QString pageId) override;
+ void refreshContainer() override;
- QString instanceId();
+ QString instanceId();
- // save all settings and changes (prepare for launch)
- bool saveAll();
+ // save all settings and changes (prepare for launch)
+ bool saveAll();
- // request closing the window (from a page)
- bool requestClose() override;
+ // request closing the window (from a page)
+ bool requestClose() override;
signals:
- void isClosing();
+ void isClosing();
private
slots:
- void on_closeButton_clicked();
- void on_btnKillMinecraft_clicked();
- void on_btnLaunchMinecraftOffline_clicked();
+ void on_closeButton_clicked();
+ void on_btnKillMinecraft_clicked();
+ void on_btnLaunchMinecraftOffline_clicked();
- void on_InstanceLaunchTask_changed(std::shared_ptr<LaunchTask> proc);
- void on_RunningState_changed(bool running);
- void on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus);
+ void on_InstanceLaunchTask_changed(std::shared_ptr<LaunchTask> proc);
+ void on_RunningState_changed(bool running);
+ void on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus);
protected:
- void closeEvent(QCloseEvent *) override;
+ void closeEvent(QCloseEvent *) override;
private:
- void updateLaunchButtons();
+ void updateLaunchButtons();
private:
- std::shared_ptr<LaunchTask> m_proc;
- InstancePtr m_instance;
- bool m_doNotSave = false;
- PageContainer *m_container = nullptr;
- QPushButton *m_closeButton = nullptr;
- QPushButton *m_killButton = nullptr;
- QPushButton *m_launchOfflineButton = nullptr;
+ std::shared_ptr<LaunchTask> m_proc;
+ InstancePtr m_instance;
+ bool m_doNotSave = false;
+ PageContainer *m_container = nullptr;
+ QPushButton *m_closeButton = nullptr;
+ QPushButton *m_killButton = nullptr;
+ QPushButton *m_launchOfflineButton = nullptr;
};
diff --git a/application/JavaCommon.cpp b/application/JavaCommon.cpp
index 0008fc04..563dfb35 100644
--- a/application/JavaCommon.cpp
+++ b/application/JavaCommon.cpp
@@ -4,100 +4,100 @@
bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent)
{
- if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegExp("-Xm[sx]"))
- || jvmargs.contains("-XX-MaxHeapSize") || jvmargs.contains("-XX:InitialHeapSize"))
- {
- auto warnStr = QObject::tr(
- "You tried to manually set a JVM memory option (using \"-XX:PermSize\", \"-XX-MaxHeapSize\", \"-XX:InitialHeapSize\", \"-Xmx\" or \"-Xms\").\n"
- "There are dedicated boxes for these in the settings (Java tab, in the Memory group at the top).\n"
- "This message will be displayed until you remove them from the JVM arguments.");
- CustomMessageBox::selectable(
- parent, QObject::tr("JVM arguments warning"),
- warnStr,
- QMessageBox::Warning)->exec();
- return false;
- }
- return true;
+ if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegExp("-Xm[sx]"))
+ || jvmargs.contains("-XX-MaxHeapSize") || jvmargs.contains("-XX:InitialHeapSize"))
+ {
+ auto warnStr = QObject::tr(
+ "You tried to manually set a JVM memory option (using \"-XX:PermSize\", \"-XX-MaxHeapSize\", \"-XX:InitialHeapSize\", \"-Xmx\" or \"-Xms\").\n"
+ "There are dedicated boxes for these in the settings (Java tab, in the Memory group at the top).\n"
+ "This message will be displayed until you remove them from the JVM arguments.");
+ CustomMessageBox::selectable(
+ parent, QObject::tr("JVM arguments warning"),
+ warnStr,
+ QMessageBox::Warning)->exec();
+ return false;
+ }
+ return true;
}
void JavaCommon::javaWasOk(QWidget *parent, JavaCheckResult result)
{
- QString text;
- text += QObject::tr("Java test succeeded!<br />Platform reported: %1<br />Java version "
- "reported: %2<br />").arg(result.realPlatform, result.javaVersion.toString());
- if (result.errorLog.size())
- {
- auto htmlError = result.errorLog;
- htmlError.replace('\n', "<br />");
- text += QObject::tr("<br />Warnings:<br /><font color=\"orange\">%1</font>").arg(htmlError);
- }
- CustomMessageBox::selectable(parent, QObject::tr("Java test success"), text, QMessageBox::Information)->show();
+ QString text;
+ text += QObject::tr("Java test succeeded!<br />Platform reported: %1<br />Java version "
+ "reported: %2<br />").arg(result.realPlatform, result.javaVersion.toString());
+ if (result.errorLog.size())
+ {
+ auto htmlError = result.errorLog;
+ htmlError.replace('\n', "<br />");
+ text += QObject::tr("<br />Warnings:<br /><font color=\"orange\">%1</font>").arg(htmlError);
+ }
+ CustomMessageBox::selectable(parent, QObject::tr("Java test success"), text, QMessageBox::Information)->show();
}
void JavaCommon::javaArgsWereBad(QWidget *parent, JavaCheckResult result)
{
- auto htmlError = result.errorLog;
- QString text;
- htmlError.replace('\n', "<br />");
- text += QObject::tr("The specified java binary didn't work with the arguments you provided:<br />");
- text += QString("<font color=\"red\">%1</font>").arg(htmlError);
- CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show();
+ auto htmlError = result.errorLog;
+ QString text;
+ htmlError.replace('\n', "<br />");
+ text += QObject::tr("The specified java binary didn't work with the arguments you provided:<br />");
+ text += QString("<font color=\"red\">%1</font>").arg(htmlError);
+ CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show();
}
void JavaCommon::javaBinaryWasBad(QWidget *parent, JavaCheckResult result)
{
- QString text;
- text += QObject::tr(
- "The specified java binary didn't work.<br />You should use the auto-detect feature, "
- "or set the path to the java executable.<br />");
- CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show();
+ QString text;
+ text += QObject::tr(
+ "The specified java binary didn't work.<br />You should use the auto-detect feature, "
+ "or set the path to the java executable.<br />");
+ CustomMessageBox::selectable(parent, QObject::tr("Java test failure"), text, QMessageBox::Warning)->show();
}
void JavaCommon::TestCheck::run()
{
- if (!JavaCommon::checkJVMArgs(m_args, m_parent))
- {
- emit finished();
- return;
- }
- checker.reset(new JavaChecker());
- connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
- SLOT(checkFinished(JavaCheckResult)));
- checker->m_path = m_path;
- checker->performCheck();
+ if (!JavaCommon::checkJVMArgs(m_args, m_parent))
+ {
+ emit finished();
+ return;
+ }
+ checker.reset(new JavaChecker());
+ connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
+ SLOT(checkFinished(JavaCheckResult)));
+ checker->m_path = m_path;
+ checker->performCheck();
}
void JavaCommon::TestCheck::checkFinished(JavaCheckResult result)
{
- if (result.validity != JavaCheckResult::Validity::Valid)
- {
- javaBinaryWasBad(m_parent, result);
- emit finished();
- return;
- }
- checker.reset(new JavaChecker());
- connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
- SLOT(checkFinishedWithArgs(JavaCheckResult)));
- checker->m_path = m_path;
- checker->m_args = m_args;
- checker->m_minMem = m_minMem;
- checker->m_maxMem = m_maxMem;
- if (result.javaVersion.requiresPermGen())
- {
- checker->m_permGen = m_permGen;
- }
- checker->performCheck();
+ if (result.validity != JavaCheckResult::Validity::Valid)
+ {
+ javaBinaryWasBad(m_parent, result);
+ emit finished();
+ return;
+ }
+ checker.reset(new JavaChecker());
+ connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
+ SLOT(checkFinishedWithArgs(JavaCheckResult)));
+ checker->m_path = m_path;
+ checker->m_args = m_args;
+ checker->m_minMem = m_minMem;
+ checker->m_maxMem = m_maxMem;
+ if (result.javaVersion.requiresPermGen())
+ {
+ checker->m_permGen = m_permGen;
+ }
+ checker->performCheck();
}
void JavaCommon::TestCheck::checkFinishedWithArgs(JavaCheckResult result)
{
- if (result.validity == JavaCheckResult::Validity::Valid)
- {
- javaWasOk(m_parent, result);
- emit finished();
- return;
- }
- javaArgsWereBad(m_parent, result);
- emit finished();
+ if (result.validity == JavaCheckResult::Validity::Valid)
+ {
+ javaWasOk(m_parent, result);
+ emit finished();
+ return;
+ }
+ javaArgsWereBad(m_parent, result);
+ emit finished();
}
diff --git a/application/JavaCommon.h b/application/JavaCommon.h
index 4e4cd633..ca98145c 100644
--- a/application/JavaCommon.h
+++ b/application/JavaCommon.h
@@ -8,41 +8,41 @@ class QWidget;
*/
namespace JavaCommon
{
- bool checkJVMArgs(QString args, QWidget *parent);
-
- // Show a dialog saying that the Java binary was not usable
- void javaBinaryWasBad(QWidget *parent, JavaCheckResult result);
- // Show a dialog saying that the Java binary was not usable because of bad options
- void javaArgsWereBad(QWidget *parent, JavaCheckResult result);
- // Show a dialog saying that the Java binary was usable
- void javaWasOk(QWidget *parent, JavaCheckResult result);
-
- class TestCheck : public QObject
- {
- Q_OBJECT
- public:
- TestCheck(QWidget *parent, QString path, QString args, int minMem, int maxMem, int permGen)
- :m_parent(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen)
- {
- }
- virtual ~TestCheck() {};
-
- void run();
-
- signals:
- void finished();
-
- private slots:
- void checkFinished(JavaCheckResult result);
- void checkFinishedWithArgs(JavaCheckResult result);
-
- private:
- std::shared_ptr<JavaChecker> checker;
- QWidget *m_parent = nullptr;
- QString m_path;
- QString m_args;
- int m_minMem = 0;
- int m_maxMem = 0;
- int m_permGen = 64;
- };
+ bool checkJVMArgs(QString args, QWidget *parent);
+
+ // Show a dialog saying that the Java binary was not usable
+ void javaBinaryWasBad(QWidget *parent, JavaCheckResult result);
+ // Show a dialog saying that the Java binary was not usable because of bad options
+ void javaArgsWereBad(QWidget *parent, JavaCheckResult result);
+ // Show a dialog saying that the Java binary was usable
+ void javaWasOk(QWidget *parent, JavaCheckResult result);
+
+ class TestCheck : public QObject
+ {
+ Q_OBJECT
+ public:
+ TestCheck(QWidget *parent, QString path, QString args, int minMem, int maxMem, int permGen)
+ :m_parent(parent), m_path(path), m_args(args), m_minMem(minMem), m_maxMem(maxMem), m_permGen(permGen)
+ {
+ }
+ virtual ~TestCheck() {};
+
+ void run();
+
+ signals:
+ void finished();
+
+ private slots:
+ void checkFinished(JavaCheckResult result);
+ void checkFinishedWithArgs(JavaCheckResult result);
+
+ private:
+ std::shared_ptr<JavaChecker> checker;
+ QWidget *m_parent = nullptr;
+ QString m_path;
+ QString m_args;
+ int m_minMem = 0;
+ int m_maxMem = 0;
+ int m_permGen = 64;
+ };
}
diff --git a/application/KonamiCode.cpp b/application/KonamiCode.cpp
index e313a856..4c5af837 100644
--- a/application/KonamiCode.cpp
+++ b/application/KonamiCode.cpp
@@ -6,13 +6,13 @@
namespace {
const std::array<Qt::Key, 10> konamiCode =
{
- {
- Qt::Key_Up, Qt::Key_Up,
- Qt::Key_Down, Qt::Key_Down,
- Qt::Key_Left, Qt::Key_Right,
- Qt::Key_Left, Qt::Key_Right,
- Qt::Key_B, Qt::Key_A
- }
+ {
+ Qt::Key_Up, Qt::Key_Up,
+ Qt::Key_Down, Qt::Key_Down,
+ Qt::Key_Left, Qt::Key_Right,
+ Qt::Key_Left, Qt::Key_Right,
+ Qt::Key_B, Qt::Key_A
+ }
};
}
@@ -23,22 +23,22 @@ KonamiCode::KonamiCode(QObject* parent) : QObject(parent)
void KonamiCode::input(QEvent* event)
{
- if( event->type() == QEvent::KeyPress )
- {
- QKeyEvent *keyEvent = static_cast<QKeyEvent*>( event );
- auto key = Qt::Key(keyEvent->key());
- if(key == konamiCode[m_progress])
- {
- m_progress ++;
- }
- else
- {
- m_progress = 0;
- }
- if(m_progress == konamiCode.size())
- {
- m_progress = 0;
- emit triggered();
- }
- }
+ if( event->type() == QEvent::KeyPress )
+ {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent*>( event );
+ auto key = Qt::Key(keyEvent->key());
+ if(key == konamiCode[m_progress])
+ {
+ m_progress ++;
+ }
+ else
+ {
+ m_progress = 0;
+ }
+ if(m_progress == konamiCode.size())
+ {
+ m_progress = 0;
+ emit triggered();
+ }
+ }
}
diff --git a/application/KonamiCode.h b/application/KonamiCode.h
index ad17f8be..3d320ae7 100644
--- a/application/KonamiCode.h
+++ b/application/KonamiCode.h
@@ -4,14 +4,14 @@
class KonamiCode : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- KonamiCode(QObject *parent = 0);
- void input(QEvent *event);
+ KonamiCode(QObject *parent = 0);
+ void input(QEvent *event);
signals:
- void triggered();
+ void triggered();
private:
- int m_progress = 0;
+ int m_progress = 0;
};
diff --git a/application/LaunchController.cpp b/application/LaunchController.cpp
index 2e711933..0115bba4 100644
--- a/application/LaunchController.cpp
+++ b/application/LaunchController.cpp
@@ -23,291 +23,291 @@ LaunchController::LaunchController(QObject *parent) : Task(parent)
void LaunchController::executeTask()
{
- if (!m_instance)
- {
- emitFailed(tr("No instance specified"));
- return;
- }
+ if (!m_instance)
+ {
+ emitFailed(tr("No instance specified"));
+ return;
+ }
- login();
+ login();
}
// FIXME: minecraft specific
void LaunchController::login()
{
- JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget);
+ JavaCommon::checkJVMArgs(m_instance->settings()->get("JvmArgs").toString(), m_parentWidget);
- // Find an account to use.
- std::shared_ptr<MojangAccountList> accounts = MMC->accounts();
- MojangAccountPtr account = accounts->activeAccount();
- if (accounts->count() <= 0)
- {
- // Tell the user they need to log in at least one account in order to play.
- auto reply = CustomMessageBox::selectable(
- m_parentWidget, tr("No Accounts"),
- tr("In order to play Minecraft, you must have at least one Mojang or Minecraft "
- "account logged in to MultiMC."
- "Would you like to open the account manager to add an account now?"),
- QMessageBox::Information, QMessageBox::Yes | QMessageBox::No)->exec();
+ // Find an account to use.
+ std::shared_ptr<MojangAccountList> accounts = MMC->accounts();
+ MojangAccountPtr account = accounts->activeAccount();
+ if (accounts->count() <= 0)
+ {
+ // Tell the user they need to log in at least one account in order to play.
+ auto reply = CustomMessageBox::selectable(
+ m_parentWidget, tr("No Accounts"),
+ tr("In order to play Minecraft, you must have at least one Mojang or Minecraft "
+ "account logged in to MultiMC."
+ "Would you like to open the account manager to add an account now?"),
+ QMessageBox::Information, QMessageBox::Yes | QMessageBox::No)->exec();
- if (reply == QMessageBox::Yes)
- {
- // Open the account manager.
- SettingsUI::ShowPageDialog(MMC->globalSettingsPages(), m_parentWidget, "accounts");
- }
- }
- else if (account.get() == nullptr)
- {
- // If no default account is set, ask the user which one to use.
- ProfileSelectDialog selectDialog(tr("Which profile would you like to use?"),
- ProfileSelectDialog::GlobalDefaultCheckbox, m_parentWidget);
+ if (reply == QMessageBox::Yes)
+ {
+ // Open the account manager.
+ SettingsUI::ShowPageDialog(MMC->globalSettingsPages(), m_parentWidget, "accounts");
+ }
+ }
+ else if (account.get() == nullptr)
+ {
+ // If no default account is set, ask the user which one to use.
+ ProfileSelectDialog selectDialog(tr("Which profile would you like to use?"),
+ ProfileSelectDialog::GlobalDefaultCheckbox, m_parentWidget);
- selectDialog.exec();
+ selectDialog.exec();
- // Launch the instance with the selected account.
- account = selectDialog.selectedAccount();
+ // Launch the instance with the selected account.
+ account = selectDialog.selectedAccount();
- // If the user said to use the account as default, do that.
- if (selectDialog.useAsGlobalDefault() && account.get() != nullptr)
- accounts->setActiveAccount(account->username());
- }
+ // If the user said to use the account as default, do that.
+ if (selectDialog.useAsGlobalDefault() && account.get() != nullptr)
+ accounts->setActiveAccount(account->username());
+ }
- // if no account is selected, we bail
- if (!account.get())
- {
- emitFailed(tr("No account selected for launch"));
- return;
- }
+ // if no account is selected, we bail
+ if (!account.get())
+ {
+ emitFailed(tr("No account selected for launch"));
+ return;
+ }
- // we try empty password first :)
- QString password;
- // we loop until the user succeeds in logging in or gives up
- bool tryagain = true;
- // the failure. the default failure.
- const QString needLoginAgain = tr("Your account is currently not logged in. Please enter "
- "your password to log in again.");
- QString failReason = needLoginAgain;
+ // we try empty password first :)
+ QString password;
+ // we loop until the user succeeds in logging in or gives up
+ bool tryagain = true;
+ // the failure. the default failure.
+ const QString needLoginAgain = tr("Your account is currently not logged in. Please enter "
+ "your password to log in again.");
+ QString failReason = needLoginAgain;
- while (tryagain)
- {
- m_session = std::make_shared<AuthSession>();
- m_session->wants_online = m_online;
- auto task = account->login(m_session, password);
- if (task)
- {
- // We'll need to validate the access token to make sure the account
- // is still logged in.
- ProgressDialog progDialog(m_parentWidget);
- if (m_online)
- {
- progDialog.setSkipButton(true, tr("Play Offline"));
- }
- progDialog.execWithTask(task.get());
- if (!task->wasSuccessful())
- {
- auto failReasonNew = task->failReason();
- if(failReasonNew == "Invalid token.")
- {
- account->invalidateClientToken();
- failReason = needLoginAgain;
- }
- else failReason = failReasonNew;
- }
- }
- switch (m_session->status)
- {
- case AuthSession::Undetermined:
- {
- qCritical() << "Received undetermined session status during login. Bye.";
- tryagain = false;
- emitFailed(tr("Received undetermined session status during login."));
- break;
- }
- case AuthSession::RequiresPassword:
- {
- EditAccountDialog passDialog(failReason, m_parentWidget, EditAccountDialog::PasswordField);
- auto username = m_session->username;
- auto chopN = [](QString toChop, int N) -> QString
- {
- if(toChop.size() > N)
- {
- auto left = toChop.left(N);
- left += QString("\u25CF").repeated(toChop.size() - N);
- return left;
- }
- return toChop;
- };
+ while (tryagain)
+ {
+ m_session = std::make_shared<AuthSession>();
+ m_session->wants_online = m_online;
+ auto task = account->login(m_session, password);
+ if (task)
+ {
+ // We'll need to validate the access token to make sure the account
+ // is still logged in.
+ ProgressDialog progDialog(m_parentWidget);
+ if (m_online)
+ {
+ progDialog.setSkipButton(true, tr("Play Offline"));
+ }
+ progDialog.execWithTask(task.get());
+ if (!task->wasSuccessful())
+ {
+ auto failReasonNew = task->failReason();
+ if(failReasonNew == "Invalid token.")
+ {
+ account->invalidateClientToken();
+ failReason = needLoginAgain;
+ }
+ else failReason = failReasonNew;
+ }
+ }
+ switch (m_session->status)
+ {
+ case AuthSession::Undetermined:
+ {
+ qCritical() << "Received undetermined session status during login. Bye.";
+ tryagain = false;
+ emitFailed(tr("Received undetermined session status during login."));
+ break;
+ }
+ case AuthSession::RequiresPassword:
+ {
+ EditAccountDialog passDialog(failReason, m_parentWidget, EditAccountDialog::PasswordField);
+ auto username = m_session->username;
+ auto chopN = [](QString toChop, int N) -> QString
+ {
+ if(toChop.size() > N)
+ {
+ auto left = toChop.left(N);
+ left += QString("\u25CF").repeated(toChop.size() - N);
+ return left;
+ }
+ return toChop;
+ };
- if(username.contains('@'))
- {
- auto parts = username.split('@');
- auto mailbox = chopN(parts[0],3);
- QString domain = chopN(parts[1], 3);
- username = mailbox + '@' + domain;
- }
- passDialog.setUsername(username);
- if (passDialog.exec() == QDialog::Accepted)
- {
- password = passDialog.password();
- }
- else
- {
- tryagain = false;
- }
- break;
- }
- case AuthSession::PlayableOffline:
- {
- // we ask the user for a player name
- bool ok = false;
- QString usedname = m_session->player_name;
- QString name = QInputDialog::getText(m_parentWidget, tr("Player name"),
- tr("Choose your offline mode player name."),
- QLineEdit::Normal, m_session->player_name, &ok);
- if (!ok)
- {
- tryagain = false;
- break;
- }
- if (name.length())
- {
- usedname = name;
- }
- m_session->MakeOffline(usedname);
- // offline flavored game from here :3
- }
- case AuthSession::PlayableOnline:
- {
- launchInstance();
- tryagain = false;
- return;
- }
- }
- }
- emitFailed(tr("Failed to launch."));
+ if(username.contains('@'))
+ {
+ auto parts = username.split('@');
+ auto mailbox = chopN(parts[0],3);
+ QString domain = chopN(parts[1], 3);
+ username = mailbox + '@' + domain;
+ }
+ passDialog.setUsername(username);
+ if (passDialog.exec() == QDialog::Accepted)
+ {
+ password = passDialog.password();
+ }
+ else
+ {
+ tryagain = false;
+ }
+ break;
+ }
+ case AuthSession::PlayableOffline:
+ {
+ // we ask the user for a player name
+ bool ok = false;
+ QString usedname = m_session->player_name;
+ QString name = QInputDialog::getText(m_parentWidget, tr("Player name"),
+ tr("Choose your offline mode player name."),
+ QLineEdit::Normal, m_session->player_name, &ok);
+ if (!ok)
+ {
+ tryagain = false;
+ break;
+ }
+ if (name.length())
+ {
+ usedname = name;
+ }
+ m_session->MakeOffline(usedname);
+ // offline flavored game from here :3
+ }
+ case AuthSession::PlayableOnline:
+ {
+ launchInstance();
+ tryagain = false;
+ return;
+ }
+ }
+ }
+ emitFailed(tr("Failed to launch."));
}
void LaunchController::launchInstance()
{
- Q_ASSERT_X(m_instance != NULL, "launchInstance", "instance is NULL");
- Q_ASSERT_X(m_session.get() != nullptr, "launchInstance", "session is NULL");
+ Q_ASSERT_X(m_instance != NULL, "launchInstance", "instance is NULL");
+ Q_ASSERT_X(m_session.get() != nullptr, "launchInstance", "session is NULL");
- if(!m_instance->reloadSettings())
- {
- QMessageBox::critical(m_parentWidget, tr("Error"), tr("Couldn't load the instance profile."));
- emitFailed(tr("Couldn't load the instance profile."));
- return;
- }
+ if(!m_instance->reloadSettings())
+ {
+ QMessageBox::critical(m_parentWidget, tr("Error"), tr("Couldn't load the instance profile."));
+ emitFailed(tr("Couldn't load the instance profile."));
+ return;
+ }
- m_launcher = m_instance->createLaunchTask(m_session);
- if (!m_launcher)
- {
- emitFailed(tr("Couldn't instantiate a launcher."));
- return;
- }
+ m_launcher = m_instance->createLaunchTask(m_session);
+ if (!m_launcher)
+ {
+ emitFailed(tr("Couldn't instantiate a launcher."));
+ return;
+ }
- auto console = qobject_cast<InstanceWindow *>(m_parentWidget);
- auto showConsole = m_instance->settings()->get("ShowConsole").toBool();
- if(!console && showConsole)
- {
- MMC->showInstanceWindow(m_instance);
- }
- connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch);
- connect(m_launcher.get(), &LaunchTask::succeeded, this, &LaunchController::onSucceeded);
- connect(m_launcher.get(), &LaunchTask::failed, this, &LaunchController::onFailed);
- connect(m_launcher.get(), &LaunchTask::requestProgress, this, &LaunchController::onProgressRequested);
+ auto console = qobject_cast<InstanceWindow *>(m_parentWidget);
+ auto showConsole = m_instance->settings()->get("ShowConsole").toBool();
+ if(!console && showConsole)
+ {
+ MMC->showInstanceWindow(m_instance);
+ }
+ connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch);
+ connect(m_launcher.get(), &LaunchTask::succeeded, this, &LaunchController::onSucceeded);
+ connect(m_launcher.get(), &LaunchTask::failed, this, &LaunchController::onFailed);
+ connect(m_launcher.get(), &LaunchTask::requestProgress, this, &LaunchController::onProgressRequested);
- m_launcher->prependStep(std::make_shared<TextPrint>(m_launcher.get(), "MultiMC version: " + BuildConfig.printableVersionString() + "\n\n", MessageLevel::MultiMC));
- m_launcher->start();
+ m_launcher->prependStep(std::make_shared<TextPrint>(m_launcher.get(), "MultiMC version: " + BuildConfig.printableVersionString() + "\n\n", MessageLevel::MultiMC));
+ m_launcher->start();
}
void LaunchController::readyForLaunch()
{
- if (!m_profiler)
- {
- m_launcher->proceed();
- return;
- }
+ if (!m_profiler)
+ {
+ m_launcher->proceed();
+ return;
+ }
- QString error;
- if (!m_profiler->check(&error))
- {
- m_launcher->abort();
- QMessageBox::critical(m_parentWidget, tr("Error"), tr("Couldn't start profiler: %1").arg(error));
- emitFailed("Profiler startup failed");
- return;
- }
- BaseProfiler *profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this);
+ QString error;
+ if (!m_profiler->check(&error))
+ {
+ m_launcher->abort();
+ QMessageBox::critical(m_parentWidget, tr("Error"), tr("Couldn't start profiler: %1").arg(error));
+ emitFailed("Profiler startup failed");
+ return;
+ }
+ BaseProfiler *profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this);
- connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString & message)
- {
- QMessageBox msg;
- msg.setText(tr("The game launch is delayed until you press the "
- "button. This is the right time to setup the profiler, as the "
- "profiler server is running now.\n\n%1").arg(message));
- msg.setWindowTitle(tr("Waiting"));
- msg.setIcon(QMessageBox::Information);
- msg.addButton(tr("Launch"), QMessageBox::AcceptRole);
- msg.setModal(true);
- msg.exec();
- m_launcher->proceed();
- });
- connect(profilerInstance, &BaseProfiler::abortLaunch, [this](const QString & message)
- {
- QMessageBox msg;
- msg.setText(tr("Couldn't start the profiler: %1").arg(message));
- msg.setWindowTitle(tr("Error"));
- msg.setIcon(QMessageBox::Critical);
- msg.addButton(QMessageBox::Ok);
- msg.setModal(true);
- msg.exec();
- m_launcher->abort();
- emitFailed("Profiler startup failed");
- });
- profilerInstance->beginProfiling(m_launcher);
+ connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString & message)
+ {
+ QMessageBox msg;
+ msg.setText(tr("The game launch is delayed until you press the "
+ "button. This is the right time to setup the profiler, as the "
+ "profiler server is running now.\n\n%1").arg(message));
+ msg.setWindowTitle(tr("Waiting"));
+ msg.setIcon(QMessageBox::Information);
+ msg.addButton(tr("Launch"), QMessageBox::AcceptRole);
+ msg.setModal(true);
+ msg.exec();
+ m_launcher->proceed();
+ });
+ connect(profilerInstance, &BaseProfiler::abortLaunch, [this](const QString & message)
+ {
+ QMessageBox msg;
+ msg.setText(tr("Couldn't start the profiler: %1").arg(message));
+ msg.setWindowTitle(tr("Error"));
+ msg.setIcon(QMessageBox::Critical);
+ msg.addButton(QMessageBox::Ok);
+ msg.setModal(true);
+ msg.exec();
+ m_launcher->abort();
+ emitFailed("Profiler startup failed");
+ });
+ profilerInstance->beginProfiling(m_launcher);
}
void LaunchController::onSucceeded()
{
- emitSucceeded();
+ emitSucceeded();
}
void LaunchController::onFailed(QString reason)
{
- if(m_instance->settings()->get("ShowConsoleOnError").toBool())
- {
- MMC->showInstanceWindow(m_instance, "console");
- }
- emitFailed(reason);
+ if(m_instance->settings()->get("ShowConsoleOnError").toBool())
+ {
+ MMC->showInstanceWindow(m_instance, "console");
+ }
+ emitFailed(reason);
}
void LaunchController::onProgressRequested(Task* task)
{
- ProgressDialog progDialog(m_parentWidget);
- progDialog.setSkipButton(true, tr("Abort"));
- m_launcher->proceed();
- progDialog.execWithTask(task);
+ ProgressDialog progDialog(m_parentWidget);
+ progDialog.setSkipButton(true, tr("Abort"));
+ m_launcher->proceed();
+ progDialog.execWithTask(task);
}
bool LaunchController::abort()
{
- if(!m_launcher)
- {
- return true;
- }
- if(!m_launcher->canAbort())
- {
- return false;
- }
- auto response = CustomMessageBox::selectable(
- m_parentWidget, tr("Kill Minecraft?"),
- tr("This can cause the instance to get corrupted and should only be used if Minecraft "
- "is frozen for some reason"),
- QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)->exec();
- if (response == QMessageBox::Yes)
- {
- return m_launcher->abort();
- }
- return false;
+ if(!m_launcher)
+ {
+ return true;
+ }
+ if(!m_launcher->canAbort())
+ {
+ return false;
+ }
+ auto response = CustomMessageBox::selectable(
+ m_parentWidget, tr("Kill Minecraft?"),
+ tr("This can cause the instance to get corrupted and should only be used if Minecraft "
+ "is frozen for some reason"),
+ QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)->exec();
+ if (response == QMessageBox::Yes)
+ {
+ return m_launcher->abort();
+ }
+ return false;
}
diff --git a/application/LaunchController.h b/application/LaunchController.h
index 84c65743..1434dec9 100644
--- a/application/LaunchController.h
+++ b/application/LaunchController.h
@@ -6,56 +6,56 @@
class InstanceWindow;
class LaunchController: public Task
{
- Q_OBJECT
+ Q_OBJECT
public:
- void executeTask() override;
+ void executeTask() override;
- LaunchController(QObject * parent = nullptr);
- virtual ~LaunchController(){};
+ LaunchController(QObject * parent = nullptr);
+ virtual ~LaunchController(){};
- void setInstance(InstancePtr instance)
- {
- m_instance = instance;
- }
- InstancePtr instance()
- {
- return m_instance;
- }
- void setOnline(bool online)
- {
- m_online = online;
- }
- void setProfiler(BaseProfilerFactory *profiler)
- {
- m_profiler = profiler;
- }
- void setParentWidget(QWidget * widget)
- {
- m_parentWidget = widget;
- }
- QString id()
- {
- return m_instance->id();
- }
- bool abort() override;
+ void setInstance(InstancePtr instance)
+ {
+ m_instance = instance;
+ }
+ InstancePtr instance()
+ {
+ return m_instance;
+ }
+ void setOnline(bool online)
+ {
+ m_online = online;
+ }
+ void setProfiler(BaseProfilerFactory *profiler)
+ {
+ m_profiler = profiler;
+ }
+ void setParentWidget(QWidget * widget)
+ {
+ m_parentWidget = widget;
+ }
+ QString id()
+ {
+ return m_instance->id();
+ }
+ bool abort() override;
private:
- void login();
- void launchInstance();
+ void login();
+ void launchInstance();
private slots:
- void readyForLaunch();
+ void readyForLaunch();
- void onSucceeded();
- void onFailed(QString reason);
- void onProgressRequested(Task *task);
+ void onSucceeded();
+ void onFailed(QString reason);
+ void onProgressRequested(Task *task);
private:
- BaseProfilerFactory *m_profiler = nullptr;
- bool m_online = true;
- InstancePtr m_instance;
- QWidget * m_parentWidget = nullptr;
- InstanceWindow *m_console = nullptr;
- AuthSessionPtr m_session;
- std::shared_ptr <LaunchTask> m_launcher;
+ BaseProfilerFactory *m_profiler = nullptr;
+ bool m_online = true;
+ InstancePtr m_instance;
+ QWidget * m_parentWidget = nullptr;
+ InstanceWindow *m_console = nullptr;
+ AuthSessionPtr m_session;
+ std::shared_ptr <LaunchTask> m_launcher;
};
diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp
index 7e74a369..b1d60d04 100644
--- a/application/MainWindow.cpp
+++ b/application/MainWindow.cpp
@@ -97,42 +97,42 @@ template <typename T>
class Translated
{
public:
- Translated(){}
- Translated(QWidget *parent)
- {
- m_contained = new T(parent);
- }
- void setTooltipId(const char * tooltip)
- {
- m_tooltip = tooltip;
- }
- void setTextId(const char * text)
- {
- m_text = text;
- }
- operator T*()
- {
- return m_contained;
- }
- T * operator->()
- {
- return m_contained;
- }
- void retranslate()
- {
- if(m_text)
- {
- m_contained->setText(QApplication::translate("MainWindow", m_text));
- }
- if(m_tooltip)
- {
- m_contained->setToolTip(QApplication::translate("MainWindow", m_tooltip));
- }
- }
+ Translated(){}
+ Translated(QWidget *parent)
+ {
+ m_contained = new T(parent);
+ }
+ void setTooltipId(const char * tooltip)
+ {
+ m_tooltip = tooltip;
+ }
+ void setTextId(const char * text)
+ {
+ m_text = text;
+ }
+ operator T*()
+ {
+ return m_contained;
+ }
+ T * operator->()
+ {
+ return m_contained;
+ }
+ void retranslate()
+ {
+ if(m_text)
+ {
+ m_contained->setText(QApplication::translate("MainWindow", m_text));
+ }
+ if(m_tooltip)
+ {
+ m_contained->setToolTip(QApplication::translate("MainWindow", m_tooltip));
+ }
+ }
private:
- T * m_contained = nullptr;
- const char * m_text = nullptr;
- const char * m_tooltip = nullptr;
+ T * m_contained = nullptr;
+ const char * m_text = nullptr;
+ const char * m_tooltip = nullptr;
};
using TranslatedAction = Translated<QAction>;
using TranslatedToolButton = Translated<QToolButton>;
@@ -140,674 +140,674 @@ using TranslatedToolButton = Translated<QToolButton>;
class TranslatedToolbar
{
public:
- TranslatedToolbar(){}
- TranslatedToolbar(QWidget *parent)
- {
- m_contained = new QToolBar(parent);
- }
- void setWindowTitleId(const char * title)
- {
- m_title = title;
- }
- operator QToolBar*()
- {
- return m_contained;
- }
- QToolBar * operator->()
- {
- return m_contained;
- }
- void retranslate()
- {
- if(m_title)
- {
- m_contained->setWindowTitle(QApplication::translate("MainWindow", m_title));
- }
- }
+ TranslatedToolbar(){}
+ TranslatedToolbar(QWidget *parent)
+ {
+ m_contained = new QToolBar(parent);
+ }
+ void setWindowTitleId(const char * title)
+ {
+ m_title = title;
+ }
+ operator QToolBar*()
+ {
+ return m_contained;
+ }
+ QToolBar * operator->()
+ {
+ return m_contained;
+ }
+ void retranslate()
+ {
+ if(m_title)
+ {
+ m_contained->setWindowTitle(QApplication::translate("MainWindow", m_title));
+ }
+ }
private:
- QToolBar * m_contained = nullptr;
- const char * m_title = nullptr;
+ QToolBar * m_contained = nullptr;
+ const char * m_title = nullptr;
};
class MainWindow::Ui
{
public:
- TranslatedAction actionAddInstance;
- //TranslatedAction actionRefresh;
- TranslatedAction actionCheckUpdate;
- TranslatedAction actionSettings;
- TranslatedAction actionPatreon;
- TranslatedAction actionMoreNews;
- TranslatedAction actionManageAccounts;
- TranslatedAction actionLaunchInstance;
- TranslatedAction actionRenameInstance;
- TranslatedAction actionChangeInstGroup;
- TranslatedAction actionChangeInstIcon;
- TranslatedAction actionEditInstNotes;
- TranslatedAction actionEditInstance;
- TranslatedAction actionWorlds;
- TranslatedAction actionViewSelectedInstFolder;
- TranslatedAction actionDeleteInstance;
- TranslatedAction actionConfig_Folder;
- TranslatedAction actionCAT;
- TranslatedAction actionCopyInstance;
- TranslatedAction actionLaunchInstanceOffline;
- TranslatedAction actionScreenshots;
- TranslatedAction actionExportInstance;
- QVector<TranslatedAction *> all_actions;
-
- LabeledToolButton *renameButton = nullptr;
- LabeledToolButton *changeIconButton = nullptr;
-
- QMenu * foldersMenu = nullptr;
- TranslatedToolButton foldersMenuButton;
- TranslatedAction actionViewInstanceFolder;
- TranslatedAction actionViewCentralModsFolder;
-
- QMenu * helpMenu = nullptr;
- TranslatedToolButton helpMenuButton;
- TranslatedAction actionReportBug;
- TranslatedAction actionDISCORD;
- TranslatedAction actionREDDIT;
- TranslatedAction actionAbout;
-
- QVector<TranslatedToolButton *> all_toolbuttons;
-
- QWidget *centralWidget = nullptr;
- QHBoxLayout *horizontalLayout = nullptr;
- QStatusBar *statusBar = nullptr;
-
- TranslatedToolbar mainToolBar;
- TranslatedToolbar instanceToolBar;
- TranslatedToolbar newsToolBar;
- QVector<TranslatedToolbar *> all_toolbars;
- bool m_kill = false;
-
- void updateLaunchAction()
- {
- if(m_kill)
- {
- actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Kill"));
- actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Kill the running instance"));
- }
- else
- {
- actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Launch"));
- actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance."));
- }
- actionLaunchInstance.retranslate();
- }
- void setLaunchAction(bool kill)
- {
- m_kill = kill;
- updateLaunchAction();
- }
-
- void createMainToolbar(QMainWindow *MainWindow)
- {
- mainToolBar = TranslatedToolbar(MainWindow);
- mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
- mainToolBar->setMovable(false);
- mainToolBar->setAllowedAreas(Qt::TopToolBarArea);
- mainToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- mainToolBar->setFloatable(false);
- mainToolBar.setWindowTitleId(QT_TRANSLATE_NOOP("MainWindow", "Main Toolbar"));
-
- actionAddInstance = TranslatedAction(MainWindow);
- actionAddInstance->setObjectName(QStringLiteral("actionAddInstance"));
- actionAddInstance->setIcon(MMC->getThemedIcon("new"));
- actionAddInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Add Instance"));
- actionAddInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Add a new instance."));
- all_actions.append(&actionAddInstance);
- mainToolBar->addAction(actionAddInstance);
-
- mainToolBar->addSeparator();
-
- foldersMenu = new QMenu(MainWindow);
- foldersMenu->setToolTipsVisible(true);
-
- actionViewInstanceFolder = TranslatedAction(MainWindow);
- actionViewInstanceFolder->setObjectName(QStringLiteral("actionViewInstanceFolder"));
- actionViewInstanceFolder->setIcon(MMC->getThemedIcon("viewfolder"));
- actionViewInstanceFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Instance Folder"));
- actionViewInstanceFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the instance folder in a file browser."));
- all_actions.append(&actionViewInstanceFolder);
- foldersMenu->addAction(actionViewInstanceFolder);
-
- actionViewCentralModsFolder = TranslatedAction(MainWindow);
- actionViewCentralModsFolder->setObjectName(QStringLiteral("actionViewCentralModsFolder"));
- actionViewCentralModsFolder->setIcon(MMC->getThemedIcon("centralmods"));
- actionViewCentralModsFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Central Mods Folder"));
- actionViewCentralModsFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the central mods folder in a file browser."));
- all_actions.append(&actionViewCentralModsFolder);
- foldersMenu->addAction(actionViewCentralModsFolder);
-
- foldersMenuButton = TranslatedToolButton(MainWindow);
- foldersMenuButton.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Folders"));
- foldersMenuButton.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open one of the folders shared between instances."));
- foldersMenuButton->setMenu(foldersMenu);
- foldersMenuButton->setPopupMode(QToolButton::InstantPopup);
- foldersMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- foldersMenuButton->setIcon(MMC->getThemedIcon("viewfolder"));
- all_toolbuttons.append(&foldersMenuButton);
- QWidgetAction* foldersButtonAction = new QWidgetAction(MainWindow);
- foldersButtonAction->setDefaultWidget(foldersMenuButton);
- mainToolBar->addAction(foldersButtonAction);
-
- actionSettings = TranslatedAction(MainWindow);
- actionSettings->setObjectName(QStringLiteral("actionSettings"));
- actionSettings->setIcon(MMC->getThemedIcon("settings"));
- actionSettings->setMenuRole(QAction::PreferencesRole);
- actionSettings.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Settings"));
- actionSettings.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change settings."));
- all_actions.append(&actionSettings);
- mainToolBar->addAction(actionSettings);
-
- helpMenu = new QMenu(MainWindow);
- helpMenu->setToolTipsVisible(true);
-
- actionReportBug = TranslatedAction(MainWindow);
- actionReportBug->setObjectName(QStringLiteral("actionReportBug"));
- actionReportBug->setIcon(MMC->getThemedIcon("bug"));
- actionReportBug.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Report a Bug"));
- actionReportBug.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the bug tracker to report a bug with MultiMC."));
- all_actions.append(&actionReportBug);
- helpMenu->addAction(actionReportBug);
-
- actionDISCORD = TranslatedAction(MainWindow);
- actionDISCORD->setObjectName(QStringLiteral("actionDISCORD"));
- actionDISCORD->setIcon(MMC->getThemedIcon("discord"));
- actionDISCORD.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Discord"));
- actionDISCORD.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open MultiMC discord voice chat."));
- all_actions.append(&actionDISCORD);
- helpMenu->addAction(actionDISCORD);
-
- actionREDDIT = TranslatedAction(MainWindow);
- actionREDDIT->setObjectName(QStringLiteral("actionREDDIT"));
- actionREDDIT->setIcon(MMC->getThemedIcon("reddit-alien"));
- actionREDDIT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Reddit"));
- actionREDDIT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open MultiMC subreddit."));
- all_actions.append(&actionREDDIT);
- helpMenu->addAction(actionREDDIT);
-
- actionAbout = TranslatedAction(MainWindow);
- actionAbout->setObjectName(QStringLiteral("actionAbout"));
- actionAbout->setIcon(MMC->getThemedIcon("about"));
- actionAbout->setMenuRole(QAction::AboutRole);
- actionAbout.setTextId(QT_TRANSLATE_NOOP("MainWindow", "About MultiMC"));
- actionAbout.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View information about MultiMC."));
- all_actions.append(&actionAbout);
- helpMenu->addAction(actionAbout);
-
- helpMenuButton = TranslatedToolButton(MainWindow);
- helpMenuButton.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Help"));
- helpMenuButton.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Get help with MultiMC or Minecraft."));
- helpMenuButton->setMenu(helpMenu);
- helpMenuButton->setPopupMode(QToolButton::InstantPopup);
- helpMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- helpMenuButton->setIcon(MMC->getThemedIcon("help"));
- all_toolbuttons.append(&helpMenuButton);
- QWidgetAction* helpButtonAction = new QWidgetAction(MainWindow);
- helpButtonAction->setDefaultWidget(helpMenuButton);
- mainToolBar->addAction(helpButtonAction);
-
- if(BuildConfig.UPDATER_ENABLED)
- {
- actionCheckUpdate = TranslatedAction(MainWindow);
- actionCheckUpdate->setObjectName(QStringLiteral("actionCheckUpdate"));
- actionCheckUpdate->setIcon(MMC->getThemedIcon("checkupdate"));
- actionCheckUpdate.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Update"));
- actionCheckUpdate.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Check for new updates for MultiMC."));
- all_actions.append(&actionCheckUpdate);
- mainToolBar->addAction(actionCheckUpdate);
- }
-
- mainToolBar->addSeparator();
-
- actionPatreon = TranslatedAction(MainWindow);
- actionPatreon->setObjectName(QStringLiteral("actionPatreon"));
- actionPatreon->setIcon(MMC->getThemedIcon("patreon"));
- actionPatreon.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Support MultiMC"));
- actionPatreon.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the MultiMC Patreon page."));
- all_actions.append(&actionPatreon);
- mainToolBar->addAction(actionPatreon);
-
- actionCAT = TranslatedAction(MainWindow);
- actionCAT->setObjectName(QStringLiteral("actionCAT"));
- actionCAT->setCheckable(true);
- actionCAT->setIcon(MMC->getThemedIcon("cat"));
- actionCAT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Meow"));
- actionCAT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "It's a fluffy kitty :3"));
- actionCAT->setPriority(QAction::LowPriority);
- all_actions.append(&actionCAT);
- mainToolBar->addAction(actionCAT);
-
- // profile menu and its actions
- actionManageAccounts = TranslatedAction(MainWindow);
- actionManageAccounts->setObjectName(QStringLiteral("actionManageAccounts"));
- actionManageAccounts.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Manage Accounts"));
- // FIXME: no tooltip!
- actionManageAccounts->setCheckable(false);
- actionManageAccounts->setIcon(MMC->getThemedIcon("accounts"));
- all_actions.append(&actionManageAccounts);
-
- all_toolbars.append(&mainToolBar);
- MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
- }
-
- void createStatusBar(QMainWindow *MainWindow)
- {
- statusBar = new QStatusBar(MainWindow);
- statusBar->setObjectName(QStringLiteral("statusBar"));
- MainWindow->setStatusBar(statusBar);
- }
-
- void createNewsToolbar(QMainWindow *MainWindow)
- {
- newsToolBar = TranslatedToolbar(MainWindow);
- newsToolBar->setObjectName(QStringLiteral("newsToolBar"));
- newsToolBar->setMovable(false);
- newsToolBar->setAllowedAreas(Qt::BottomToolBarArea);
- newsToolBar->setIconSize(QSize(16, 16));
- newsToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- newsToolBar->setFloatable(false);
- newsToolBar->setWindowTitle(QT_TRANSLATE_NOOP("MainWindow", "News Toolbar"));
-
- actionMoreNews = TranslatedAction(MainWindow);
- actionMoreNews->setObjectName(QStringLiteral("actionMoreNews"));
- actionMoreNews->setIcon(MMC->getThemedIcon("news"));
- actionMoreNews.setTextId(QT_TRANSLATE_NOOP("MainWindow", "More news..."));
- actionMoreNews.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the MultiMC development blog to read more news about MultiMC."));
- all_actions.append(&actionMoreNews);
- newsToolBar->addAction(actionMoreNews);
-
- all_toolbars.append(&newsToolBar);
- MainWindow->addToolBar(Qt::BottomToolBarArea, newsToolBar);
- }
-
- void createInstanceToolbar(QMainWindow *MainWindow)
- {
- instanceToolBar = TranslatedToolbar(MainWindow);
- instanceToolBar->setObjectName(QStringLiteral("instanceToolBar"));
- // disabled until we have an instance selected
- instanceToolBar->setEnabled(false);
- instanceToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
- instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextOnly);
- instanceToolBar->setFloatable(false);
- instanceToolBar->setWindowTitle(QT_TRANSLATE_NOOP("MainWindow", "Instance Toolbar"));
-
- // NOTE: not added to toolbar, but used for instance context menu (right click)
- actionChangeInstIcon = TranslatedAction(MainWindow);
- actionChangeInstIcon->setObjectName(QStringLiteral("actionChangeInstIcon"));
- actionChangeInstIcon->setIcon(QIcon(":/icons/instances/infinity"));
- actionChangeInstIcon->setIconVisibleInMenu(true);
- actionChangeInstIcon.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Change Icon"));
- actionChangeInstIcon.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change the selected instance's icon."));
- all_actions.append(&actionChangeInstIcon);
-
- changeIconButton = new LabeledToolButton(MainWindow);
- changeIconButton->setObjectName(QStringLiteral("changeIconButton"));
- changeIconButton->setIcon(MMC->getThemedIcon("news"));
- changeIconButton->setToolTip(actionChangeInstIcon->toolTip());
- changeIconButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
- instanceToolBar->addWidget(changeIconButton);
-
- // NOTE: not added to toolbar, but used for instance context menu (right click)
- actionRenameInstance = TranslatedAction(MainWindow);
- actionRenameInstance->setObjectName(QStringLiteral("actionRenameInstance"));
- actionRenameInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Rename"));
- actionRenameInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Rename the selected instance."));
- all_actions.append(&actionRenameInstance);
-
- // the rename label is inside the rename tool button
- renameButton = new LabeledToolButton(MainWindow);
- renameButton->setObjectName(QStringLiteral("renameButton"));
- renameButton->setToolTip(actionRenameInstance->toolTip());
- renameButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
- instanceToolBar->addWidget(renameButton);
-
- instanceToolBar->addSeparator();
-
- actionLaunchInstance = TranslatedAction(MainWindow);
- actionLaunchInstance->setObjectName(QStringLiteral("actionLaunchInstance"));
- all_actions.append(&actionLaunchInstance);
- instanceToolBar->addAction(actionLaunchInstance);
-
- actionLaunchInstanceOffline = TranslatedAction(MainWindow);
- actionLaunchInstanceOffline->setObjectName(QStringLiteral("actionLaunchInstanceOffline"));
- actionLaunchInstanceOffline.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Launch Offline"));
- actionLaunchInstanceOffline.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance in offline mode."));
- all_actions.append(&actionLaunchInstanceOffline);
- instanceToolBar->addAction(actionLaunchInstanceOffline);
-
- instanceToolBar->addSeparator();
-
- actionEditInstance = TranslatedAction(MainWindow);
- actionEditInstance->setObjectName(QStringLiteral("actionEditInstance"));
- actionEditInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Edit Instance"));
- actionEditInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change the instance settings, mods and versions."));
- all_actions.append(&actionEditInstance);
- instanceToolBar->addAction(actionEditInstance);
-
- actionEditInstNotes = TranslatedAction(MainWindow);
- actionEditInstNotes->setObjectName(QStringLiteral("actionEditInstNotes"));
- actionEditInstNotes.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Edit Notes"));
- actionEditInstNotes.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Edit the notes for the selected instance."));
- all_actions.append(&actionEditInstNotes);
- instanceToolBar->addAction(actionEditInstNotes);
-
- actionWorlds = TranslatedAction(MainWindow);
- actionWorlds->setObjectName(QStringLiteral("actionWorlds"));
- actionWorlds.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Worlds"));
- actionWorlds.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View the worlds of this instance."));
- all_actions.append(&actionWorlds);
- instanceToolBar->addAction(actionWorlds);
-
- actionScreenshots = TranslatedAction(MainWindow);
- actionScreenshots->setObjectName(QStringLiteral("actionScreenshots"));
- actionScreenshots.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Manage Screenshots"));
- actionScreenshots.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View and upload screenshots for this instance."));
- all_actions.append(&actionScreenshots);
- instanceToolBar->addAction(actionScreenshots);
-
- actionChangeInstGroup = TranslatedAction(MainWindow);
- actionChangeInstGroup->setObjectName(QStringLiteral("actionChangeInstGroup"));
- actionChangeInstGroup.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Change Group"));
- actionChangeInstGroup.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change the selected instance's group."));
- all_actions.append(&actionChangeInstGroup);
- instanceToolBar->addAction(actionChangeInstGroup);
-
- instanceToolBar->addSeparator();
-
- actionViewSelectedInstFolder = TranslatedAction(MainWindow);
- actionViewSelectedInstFolder->setObjectName(QStringLiteral("actionViewSelectedInstFolder"));
- actionViewSelectedInstFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Instance Folder"));
- actionViewSelectedInstFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the selected instance's root folder in a file browser."));
- all_actions.append(&actionViewSelectedInstFolder);
- instanceToolBar->addAction(actionViewSelectedInstFolder);
-
- actionConfig_Folder = TranslatedAction(MainWindow);
- actionConfig_Folder->setObjectName(QStringLiteral("actionConfig_Folder"));
- actionConfig_Folder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Config Folder"));
- actionConfig_Folder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the instance's config folder."));
- all_actions.append(&actionConfig_Folder);
- instanceToolBar->addAction(actionConfig_Folder);
-
- instanceToolBar->addSeparator();
-
- actionExportInstance = TranslatedAction(MainWindow);
- actionExportInstance->setObjectName(QStringLiteral("actionExportInstance"));
- actionExportInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Export Instance"));
- // FIXME: missing tooltip
- all_actions.append(&actionExportInstance);
- instanceToolBar->addAction(actionExportInstance);
-
- actionDeleteInstance = TranslatedAction(MainWindow);
- actionDeleteInstance->setObjectName(QStringLiteral("actionDeleteInstance"));
- actionDeleteInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Delete"));
- actionDeleteInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Delete the selected instance."));
- all_actions.append(&actionDeleteInstance);
- instanceToolBar->addAction(actionDeleteInstance);
-
- actionCopyInstance = TranslatedAction(MainWindow);
- actionCopyInstance->setObjectName(QStringLiteral("actionCopyInstance"));
- actionCopyInstance->setIcon(MMC->getThemedIcon("copy"));
- actionCopyInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Copy Instance"));
- actionCopyInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Copy the selected instance."));
- all_actions.append(&actionCopyInstance);
- instanceToolBar->addAction(actionCopyInstance);
-
- all_toolbars.append(&instanceToolBar);
- MainWindow->addToolBar(Qt::RightToolBarArea, instanceToolBar);
- }
-
- void setupUi(QMainWindow *MainWindow)
- {
- if (MainWindow->objectName().isEmpty())
- {
- MainWindow->setObjectName(QStringLiteral("MainWindow"));
- }
- MainWindow->resize(694, 563);
- MainWindow->setWindowIcon(MMC->getThemedIcon("logo"));
- MainWindow->setWindowTitle("MultiMC 5");
-
- createMainToolbar(MainWindow);
-
- 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);
-
- createStatusBar(MainWindow);
- createNewsToolbar(MainWindow);
- createInstanceToolbar(MainWindow);
-
- retranslateUi(MainWindow);
-
- QMetaObject::connectSlotsByName(MainWindow);
- } // setupUi
-
- void retranslateUi(QMainWindow *MainWindow)
- {
- QString winTitle = tr("MultiMC 5 - Version %1").arg(BuildConfig.printableVersionString());
- if (!BuildConfig.BUILD_PLATFORM.isEmpty())
- {
- winTitle += tr(" on %1", "on platform, as in operating system").arg(BuildConfig.BUILD_PLATFORM);
- }
- MainWindow->setWindowTitle(winTitle);
- // all the actions
- for(auto * item: all_actions)
- {
- item->retranslate();
- }
- for(auto * item: all_toolbars)
- {
- item->retranslate();
- }
- for(auto * item: all_toolbuttons)
- {
- item->retranslate();
- }
- // submenu buttons
- foldersMenuButton->setText(tr("Folders"));
- helpMenuButton->setText(tr("Help"));
- } // retranslateUi
+ TranslatedAction actionAddInstance;
+ //TranslatedAction actionRefresh;
+ TranslatedAction actionCheckUpdate;
+ TranslatedAction actionSettings;
+ TranslatedAction actionPatreon;
+ TranslatedAction actionMoreNews;
+ TranslatedAction actionManageAccounts;
+ TranslatedAction actionLaunchInstance;
+ TranslatedAction actionRenameInstance;
+ TranslatedAction actionChangeInstGroup;
+ TranslatedAction actionChangeInstIcon;
+ TranslatedAction actionEditInstNotes;
+ TranslatedAction actionEditInstance;
+ TranslatedAction actionWorlds;
+ TranslatedAction actionViewSelectedInstFolder;
+ TranslatedAction actionDeleteInstance;
+ TranslatedAction actionConfig_Folder;
+ TranslatedAction actionCAT;
+ TranslatedAction actionCopyInstance;
+ TranslatedAction actionLaunchInstanceOffline;
+ TranslatedAction actionScreenshots;
+ TranslatedAction actionExportInstance;
+ QVector<TranslatedAction *> all_actions;
+
+ LabeledToolButton *renameButton = nullptr;
+ LabeledToolButton *changeIconButton = nullptr;
+
+ QMenu * foldersMenu = nullptr;
+ TranslatedToolButton foldersMenuButton;
+ TranslatedAction actionViewInstanceFolder;
+ TranslatedAction actionViewCentralModsFolder;
+
+ QMenu * helpMenu = nullptr;
+ TranslatedToolButton helpMenuButton;
+ TranslatedAction actionReportBug;
+ TranslatedAction actionDISCORD;
+ TranslatedAction actionREDDIT;
+ TranslatedAction actionAbout;
+
+ QVector<TranslatedToolButton *> all_toolbuttons;
+
+ QWidget *centralWidget = nullptr;
+ QHBoxLayout *horizontalLayout = nullptr;
+ QStatusBar *statusBar = nullptr;
+
+ TranslatedToolbar mainToolBar;
+ TranslatedToolbar instanceToolBar;
+ TranslatedToolbar newsToolBar;
+ QVector<TranslatedToolbar *> all_toolbars;
+ bool m_kill = false;
+
+ void updateLaunchAction()
+ {
+ if(m_kill)
+ {
+ actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Kill"));
+ actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Kill the running instance"));
+ }
+ else
+ {
+ actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Launch"));
+ actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance."));
+ }
+ actionLaunchInstance.retranslate();
+ }
+ void setLaunchAction(bool kill)
+ {
+ m_kill = kill;
+ updateLaunchAction();
+ }
+
+ void createMainToolbar(QMainWindow *MainWindow)
+ {
+ mainToolBar = TranslatedToolbar(MainWindow);
+ mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
+ mainToolBar->setMovable(false);
+ mainToolBar->setAllowedAreas(Qt::TopToolBarArea);
+ mainToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ mainToolBar->setFloatable(false);
+ mainToolBar.setWindowTitleId(QT_TRANSLATE_NOOP("MainWindow", "Main Toolbar"));
+
+ actionAddInstance = TranslatedAction(MainWindow);
+ actionAddInstance->setObjectName(QStringLiteral("actionAddInstance"));
+ actionAddInstance->setIcon(MMC->getThemedIcon("new"));
+ actionAddInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Add Instance"));
+ actionAddInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Add a new instance."));
+ all_actions.append(&actionAddInstance);
+ mainToolBar->addAction(actionAddInstance);
+
+ mainToolBar->addSeparator();
+
+ foldersMenu = new QMenu(MainWindow);
+ foldersMenu->setToolTipsVisible(true);
+
+ actionViewInstanceFolder = TranslatedAction(MainWindow);
+ actionViewInstanceFolder->setObjectName(QStringLiteral("actionViewInstanceFolder"));
+ actionViewInstanceFolder->setIcon(MMC->getThemedIcon("viewfolder"));
+ actionViewInstanceFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Instance Folder"));
+ actionViewInstanceFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the instance folder in a file browser."));
+ all_actions.append(&actionViewInstanceFolder);
+ foldersMenu->addAction(actionViewInstanceFolder);
+
+ actionViewCentralModsFolder = TranslatedAction(MainWindow);
+ actionViewCentralModsFolder->setObjectName(QStringLiteral("actionViewCentralModsFolder"));
+ actionViewCentralModsFolder->setIcon(MMC->getThemedIcon("centralmods"));
+ actionViewCentralModsFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Central Mods Folder"));
+ actionViewCentralModsFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the central mods folder in a file browser."));
+ all_actions.append(&actionViewCentralModsFolder);
+ foldersMenu->addAction(actionViewCentralModsFolder);
+
+ foldersMenuButton = TranslatedToolButton(MainWindow);
+ foldersMenuButton.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Folders"));
+ foldersMenuButton.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open one of the folders shared between instances."));
+ foldersMenuButton->setMenu(foldersMenu);
+ foldersMenuButton->setPopupMode(QToolButton::InstantPopup);
+ foldersMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ foldersMenuButton->setIcon(MMC->getThemedIcon("viewfolder"));
+ all_toolbuttons.append(&foldersMenuButton);
+ QWidgetAction* foldersButtonAction = new QWidgetAction(MainWindow);
+ foldersButtonAction->setDefaultWidget(foldersMenuButton);
+ mainToolBar->addAction(foldersButtonAction);
+
+ actionSettings = TranslatedAction(MainWindow);
+ actionSettings->setObjectName(QStringLiteral("actionSettings"));
+ actionSettings->setIcon(MMC->getThemedIcon("settings"));
+ actionSettings->setMenuRole(QAction::PreferencesRole);
+ actionSettings.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Settings"));
+ actionSettings.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change settings."));
+ all_actions.append(&actionSettings);
+ mainToolBar->addAction(actionSettings);
+
+ helpMenu = new QMenu(MainWindow);
+ helpMenu->setToolTipsVisible(true);
+
+ actionReportBug = TranslatedAction(MainWindow);
+ actionReportBug->setObjectName(QStringLiteral("actionReportBug"));
+ actionReportBug->setIcon(MMC->getThemedIcon("bug"));
+ actionReportBug.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Report a Bug"));
+ actionReportBug.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the bug tracker to report a bug with MultiMC."));
+ all_actions.append(&actionReportBug);
+ helpMenu->addAction(actionReportBug);
+
+ actionDISCORD = TranslatedAction(MainWindow);
+ actionDISCORD->setObjectName(QStringLiteral("actionDISCORD"));
+ actionDISCORD->setIcon(MMC->getThemedIcon("discord"));
+ actionDISCORD.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Discord"));
+ actionDISCORD.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open MultiMC discord voice chat."));
+ all_actions.append(&actionDISCORD);
+ helpMenu->addAction(actionDISCORD);
+
+ actionREDDIT = TranslatedAction(MainWindow);
+ actionREDDIT->setObjectName(QStringLiteral("actionREDDIT"));
+ actionREDDIT->setIcon(MMC->getThemedIcon("reddit-alien"));
+ actionREDDIT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Reddit"));
+ actionREDDIT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open MultiMC subreddit."));
+ all_actions.append(&actionREDDIT);
+ helpMenu->addAction(actionREDDIT);
+
+ actionAbout = TranslatedAction(MainWindow);
+ actionAbout->setObjectName(QStringLiteral("actionAbout"));
+ actionAbout->setIcon(MMC->getThemedIcon("about"));
+ actionAbout->setMenuRole(QAction::AboutRole);
+ actionAbout.setTextId(QT_TRANSLATE_NOOP("MainWindow", "About MultiMC"));
+ actionAbout.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View information about MultiMC."));
+ all_actions.append(&actionAbout);
+ helpMenu->addAction(actionAbout);
+
+ helpMenuButton = TranslatedToolButton(MainWindow);
+ helpMenuButton.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Help"));
+ helpMenuButton.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Get help with MultiMC or Minecraft."));
+ helpMenuButton->setMenu(helpMenu);
+ helpMenuButton->setPopupMode(QToolButton::InstantPopup);
+ helpMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ helpMenuButton->setIcon(MMC->getThemedIcon("help"));
+ all_toolbuttons.append(&helpMenuButton);
+ QWidgetAction* helpButtonAction = new QWidgetAction(MainWindow);
+ helpButtonAction->setDefaultWidget(helpMenuButton);
+ mainToolBar->addAction(helpButtonAction);
+
+ if(BuildConfig.UPDATER_ENABLED)
+ {
+ actionCheckUpdate = TranslatedAction(MainWindow);
+ actionCheckUpdate->setObjectName(QStringLiteral("actionCheckUpdate"));
+ actionCheckUpdate->setIcon(MMC->getThemedIcon("checkupdate"));
+ actionCheckUpdate.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Update"));
+ actionCheckUpdate.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Check for new updates for MultiMC."));
+ all_actions.append(&actionCheckUpdate);
+ mainToolBar->addAction(actionCheckUpdate);
+ }
+
+ mainToolBar->addSeparator();
+
+ actionPatreon = TranslatedAction(MainWindow);
+ actionPatreon->setObjectName(QStringLiteral("actionPatreon"));
+ actionPatreon->setIcon(MMC->getThemedIcon("patreon"));
+ actionPatreon.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Support MultiMC"));
+ actionPatreon.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the MultiMC Patreon page."));
+ all_actions.append(&actionPatreon);
+ mainToolBar->addAction(actionPatreon);
+
+ actionCAT = TranslatedAction(MainWindow);
+ actionCAT->setObjectName(QStringLiteral("actionCAT"));
+ actionCAT->setCheckable(true);
+ actionCAT->setIcon(MMC->getThemedIcon("cat"));
+ actionCAT.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Meow"));
+ actionCAT.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "It's a fluffy kitty :3"));
+ actionCAT->setPriority(QAction::LowPriority);
+ all_actions.append(&actionCAT);
+ mainToolBar->addAction(actionCAT);
+
+ // profile menu and its actions
+ actionManageAccounts = TranslatedAction(MainWindow);
+ actionManageAccounts->setObjectName(QStringLiteral("actionManageAccounts"));
+ actionManageAccounts.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Manage Accounts"));
+ // FIXME: no tooltip!
+ actionManageAccounts->setCheckable(false);
+ actionManageAccounts->setIcon(MMC->getThemedIcon("accounts"));
+ all_actions.append(&actionManageAccounts);
+
+ all_toolbars.append(&mainToolBar);
+ MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
+ }
+
+ void createStatusBar(QMainWindow *MainWindow)
+ {
+ statusBar = new QStatusBar(MainWindow);
+ statusBar->setObjectName(QStringLiteral("statusBar"));
+ MainWindow->setStatusBar(statusBar);
+ }
+
+ void createNewsToolbar(QMainWindow *MainWindow)
+ {
+ newsToolBar = TranslatedToolbar(MainWindow);
+ newsToolBar->setObjectName(QStringLiteral("newsToolBar"));
+ newsToolBar->setMovable(false);
+ newsToolBar->setAllowedAreas(Qt::BottomToolBarArea);
+ newsToolBar->setIconSize(QSize(16, 16));
+ newsToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ newsToolBar->setFloatable(false);
+ newsToolBar->setWindowTitle(QT_TRANSLATE_NOOP("MainWindow", "News Toolbar"));
+
+ actionMoreNews = TranslatedAction(MainWindow);
+ actionMoreNews->setObjectName(QStringLiteral("actionMoreNews"));
+ actionMoreNews->setIcon(MMC->getThemedIcon("news"));
+ actionMoreNews.setTextId(QT_TRANSLATE_NOOP("MainWindow", "More news..."));
+ actionMoreNews.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the MultiMC development blog to read more news about MultiMC."));
+ all_actions.append(&actionMoreNews);
+ newsToolBar->addAction(actionMoreNews);
+
+ all_toolbars.append(&newsToolBar);
+ MainWindow->addToolBar(Qt::BottomToolBarArea, newsToolBar);
+ }
+
+ void createInstanceToolbar(QMainWindow *MainWindow)
+ {
+ instanceToolBar = TranslatedToolbar(MainWindow);
+ instanceToolBar->setObjectName(QStringLiteral("instanceToolBar"));
+ // disabled until we have an instance selected
+ instanceToolBar->setEnabled(false);
+ instanceToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
+ instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextOnly);
+ instanceToolBar->setFloatable(false);
+ instanceToolBar->setWindowTitle(QT_TRANSLATE_NOOP("MainWindow", "Instance Toolbar"));
+
+ // NOTE: not added to toolbar, but used for instance context menu (right click)
+ actionChangeInstIcon = TranslatedAction(MainWindow);
+ actionChangeInstIcon->setObjectName(QStringLiteral("actionChangeInstIcon"));
+ actionChangeInstIcon->setIcon(QIcon(":/icons/instances/infinity"));
+ actionChangeInstIcon->setIconVisibleInMenu(true);
+ actionChangeInstIcon.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Change Icon"));
+ actionChangeInstIcon.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change the selected instance's icon."));
+ all_actions.append(&actionChangeInstIcon);
+
+ changeIconButton = new LabeledToolButton(MainWindow);
+ changeIconButton->setObjectName(QStringLiteral("changeIconButton"));
+ changeIconButton->setIcon(MMC->getThemedIcon("news"));
+ changeIconButton->setToolTip(actionChangeInstIcon->toolTip());
+ changeIconButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ instanceToolBar->addWidget(changeIconButton);
+
+ // NOTE: not added to toolbar, but used for instance context menu (right click)
+ actionRenameInstance = TranslatedAction(MainWindow);
+ actionRenameInstance->setObjectName(QStringLiteral("actionRenameInstance"));
+ actionRenameInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Rename"));
+ actionRenameInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Rename the selected instance."));
+ all_actions.append(&actionRenameInstance);
+
+ // the rename label is inside the rename tool button
+ renameButton = new LabeledToolButton(MainWindow);
+ renameButton->setObjectName(QStringLiteral("renameButton"));
+ renameButton->setToolTip(actionRenameInstance->toolTip());
+ renameButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ instanceToolBar->addWidget(renameButton);
+
+ instanceToolBar->addSeparator();
+
+ actionLaunchInstance = TranslatedAction(MainWindow);
+ actionLaunchInstance->setObjectName(QStringLiteral("actionLaunchInstance"));
+ all_actions.append(&actionLaunchInstance);
+ instanceToolBar->addAction(actionLaunchInstance);
+
+ actionLaunchInstanceOffline = TranslatedAction(MainWindow);
+ actionLaunchInstanceOffline->setObjectName(QStringLiteral("actionLaunchInstanceOffline"));
+ actionLaunchInstanceOffline.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Launch Offline"));
+ actionLaunchInstanceOffline.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance in offline mode."));
+ all_actions.append(&actionLaunchInstanceOffline);
+ instanceToolBar->addAction(actionLaunchInstanceOffline);
+
+ instanceToolBar->addSeparator();
+
+ actionEditInstance = TranslatedAction(MainWindow);
+ actionEditInstance->setObjectName(QStringLiteral("actionEditInstance"));
+ actionEditInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Edit Instance"));
+ actionEditInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change the instance settings, mods and versions."));
+ all_actions.append(&actionEditInstance);
+ instanceToolBar->addAction(actionEditInstance);
+
+ actionEditInstNotes = TranslatedAction(MainWindow);
+ actionEditInstNotes->setObjectName(QStringLiteral("actionEditInstNotes"));
+ actionEditInstNotes.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Edit Notes"));
+ actionEditInstNotes.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Edit the notes for the selected instance."));
+ all_actions.append(&actionEditInstNotes);
+ instanceToolBar->addAction(actionEditInstNotes);
+
+ actionWorlds = TranslatedAction(MainWindow);
+ actionWorlds->setObjectName(QStringLiteral("actionWorlds"));
+ actionWorlds.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Worlds"));
+ actionWorlds.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View the worlds of this instance."));
+ all_actions.append(&actionWorlds);
+ instanceToolBar->addAction(actionWorlds);
+
+ actionScreenshots = TranslatedAction(MainWindow);
+ actionScreenshots->setObjectName(QStringLiteral("actionScreenshots"));
+ actionScreenshots.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Manage Screenshots"));
+ actionScreenshots.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View and upload screenshots for this instance."));
+ all_actions.append(&actionScreenshots);
+ instanceToolBar->addAction(actionScreenshots);
+
+ actionChangeInstGroup = TranslatedAction(MainWindow);
+ actionChangeInstGroup->setObjectName(QStringLiteral("actionChangeInstGroup"));
+ actionChangeInstGroup.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Change Group"));
+ actionChangeInstGroup.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Change the selected instance's group."));
+ all_actions.append(&actionChangeInstGroup);
+ instanceToolBar->addAction(actionChangeInstGroup);
+
+ instanceToolBar->addSeparator();
+
+ actionViewSelectedInstFolder = TranslatedAction(MainWindow);
+ actionViewSelectedInstFolder->setObjectName(QStringLiteral("actionViewSelectedInstFolder"));
+ actionViewSelectedInstFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Instance Folder"));
+ actionViewSelectedInstFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the selected instance's root folder in a file browser."));
+ all_actions.append(&actionViewSelectedInstFolder);
+ instanceToolBar->addAction(actionViewSelectedInstFolder);
+
+ actionConfig_Folder = TranslatedAction(MainWindow);
+ actionConfig_Folder->setObjectName(QStringLiteral("actionConfig_Folder"));
+ actionConfig_Folder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Config Folder"));
+ actionConfig_Folder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the instance's config folder."));
+ all_actions.append(&actionConfig_Folder);
+ instanceToolBar->addAction(actionConfig_Folder);
+
+ instanceToolBar->addSeparator();
+
+ actionExportInstance = TranslatedAction(MainWindow);
+ actionExportInstance->setObjectName(QStringLiteral("actionExportInstance"));
+ actionExportInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Export Instance"));
+ // FIXME: missing tooltip
+ all_actions.append(&actionExportInstance);
+ instanceToolBar->addAction(actionExportInstance);
+
+ actionDeleteInstance = TranslatedAction(MainWindow);
+ actionDeleteInstance->setObjectName(QStringLiteral("actionDeleteInstance"));
+ actionDeleteInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Delete"));
+ actionDeleteInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Delete the selected instance."));
+ all_actions.append(&actionDeleteInstance);
+ instanceToolBar->addAction(actionDeleteInstance);
+
+ actionCopyInstance = TranslatedAction(MainWindow);
+ actionCopyInstance->setObjectName(QStringLiteral("actionCopyInstance"));
+ actionCopyInstance->setIcon(MMC->getThemedIcon("copy"));
+ actionCopyInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Copy Instance"));
+ actionCopyInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Copy the selected instance."));
+ all_actions.append(&actionCopyInstance);
+ instanceToolBar->addAction(actionCopyInstance);
+
+ all_toolbars.append(&instanceToolBar);
+ MainWindow->addToolBar(Qt::RightToolBarArea, instanceToolBar);
+ }
+
+ void setupUi(QMainWindow *MainWindow)
+ {
+ if (MainWindow->objectName().isEmpty())
+ {
+ MainWindow->setObjectName(QStringLiteral("MainWindow"));
+ }
+ MainWindow->resize(694, 563);
+ MainWindow->setWindowIcon(MMC->getThemedIcon("logo"));
+ MainWindow->setWindowTitle("MultiMC 5");
+
+ createMainToolbar(MainWindow);
+
+ 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);
+
+ createStatusBar(MainWindow);
+ createNewsToolbar(MainWindow);
+ createInstanceToolbar(MainWindow);
+
+ retranslateUi(MainWindow);
+
+ QMetaObject::connectSlotsByName(MainWindow);
+ } // setupUi
+
+ void retranslateUi(QMainWindow *MainWindow)
+ {
+ QString winTitle = tr("MultiMC 5 - Version %1").arg(BuildConfig.printableVersionString());
+ if (!BuildConfig.BUILD_PLATFORM.isEmpty())
+ {
+ winTitle += tr(" on %1", "on platform, as in operating system").arg(BuildConfig.BUILD_PLATFORM);
+ }
+ MainWindow->setWindowTitle(winTitle);
+ // all the actions
+ for(auto * item: all_actions)
+ {
+ item->retranslate();
+ }
+ for(auto * item: all_toolbars)
+ {
+ item->retranslate();
+ }
+ for(auto * item: all_toolbuttons)
+ {
+ item->retranslate();
+ }
+ // submenu buttons
+ foldersMenuButton->setText(tr("Folders"));
+ helpMenuButton->setText(tr("Help"));
+ } // retranslateUi
};
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow::Ui)
{
- ui->setupUi(this);
-
- // OSX magic.
- setUnifiedTitleAndToolBarOnMac(true);
-
- // Global shortcuts
- {
- // FIXME: This is kinda weird. and bad. We need some kind of managed shutdown.
- auto q = new QShortcut(QKeySequence::Quit, this);
- connect(q, SIGNAL(activated()), qApp, SLOT(quit()));
- }
-
- // Konami Code
- {
- secretEventFilter = new KonamiCode(this);
- connect(secretEventFilter, &KonamiCode::triggered, this, &MainWindow::konamiTriggered);
- }
-
- // Add the news label to the news toolbar.
- {
- m_newsChecker.reset(new NewsChecker(BuildConfig.NEWS_RSS_URL));
- newsLabel = new QToolButton();
- newsLabel->setIcon(MMC->getThemedIcon("news"));
- newsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
- newsLabel->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- ui->newsToolBar->insertWidget(ui->actionMoreNews, newsLabel);
- QObject::connect(newsLabel, &QAbstractButton::clicked, this, &MainWindow::newsButtonClicked);
- QObject::connect(m_newsChecker.get(), &NewsChecker::newsLoaded, this, &MainWindow::updateNewsLabel);
- updateNewsLabel();
- }
-
- // Create the instance list widget
- {
- view = new GroupView(ui->centralWidget);
-
- 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);
- connect(view, &GroupView::droppedURLs, this, &MainWindow::droppedURLs, Qt::QueuedConnection);
-
- proxymodel = new InstanceProxyModel(this);
- proxymodel->setSourceModel(MMC->instances().get());
- proxymodel->sort(0);
- connect(proxymodel, &InstanceProxyModel::dataChanged, this, &MainWindow::instanceDataChanged);
-
- view->setModel(proxymodel);
- ui->horizontalLayout->addWidget(view);
- }
- // The cat background
- {
- bool cat_enable = MMC->settings()->get("TheCat").toBool();
- ui->actionCAT->setChecked(cat_enable);
- connect(ui->actionCAT, SIGNAL(toggled(bool)), SLOT(onCatToggled(bool)));
- setCatBackground(cat_enable);
- }
- // start instance when double-clicked
- connect(view, &GroupView::doubleClicked, this, &MainWindow::instanceActivated);
-
- // track the selection -- update the instance toolbar
- connect(view->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::instanceChanged);
-
- // track icon changes and update the toolbar!
- connect(MMC->icons().get(), &IconList::iconUpdated, this, &MainWindow::iconUpdated);
-
- // model reset -> selection is invalid. All the instance pointers are wrong.
- connect(MMC->instances().get(), &InstanceList::dataIsInvalid, this, &MainWindow::selectionBad);
-
- m_statusLeft = new QLabel(tr("No instance selected"), this);
- m_statusRight = new ServerStatus(this);
- statusBar()->addPermanentWidget(m_statusLeft, 1);
- statusBar()->addPermanentWidget(m_statusRight, 0);
-
- // Add "manage accounts" button, right align
- QWidget *spacer = new QWidget();
- spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- ui->mainToolBar->addWidget(spacer);
-
- accountMenu = new QMenu(this);
-
- repopulateAccountsMenu();
-
- accountMenuButton = new QToolButton(this);
- accountMenuButton->setText(tr("Profiles"));
- accountMenuButton->setMenu(accountMenu);
- accountMenuButton->setPopupMode(QToolButton::InstantPopup);
- accountMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- accountMenuButton->setIcon(MMC->getThemedIcon("noaccount"));
-
- QWidgetAction *accountMenuButtonAction = new QWidgetAction(this);
- accountMenuButtonAction->setDefaultWidget(accountMenuButton);
-
- ui->mainToolBar->addAction(accountMenuButtonAction);
-
- // 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...
- connect(MMC->accounts().get(), &MojangAccountList::activeAccountChanged, [this]
- {
- activeAccountChanged();
- });
- connect(MMC->accounts().get(), &MojangAccountList::listChanged, [this]
- {
- repopulateAccountsMenu();
- });
-
- // Show initial account
- activeAccountChanged();
-
- auto accounts = MMC->accounts();
-
- QList<Net::Download::Ptr> skin_dls;
- for (int i = 0; i < accounts->count(); i++)
- {
- auto account = accounts->at(i);
- if (!account)
- {
- qWarning() << "Null account at index" << i;
- continue;
- }
- for (auto profile : account->profiles())
- {
- auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.id + ".png");
- auto action = Net::Download::makeCached(QUrl("https://" + URLConstants::SKINS_BASE + profile.id + ".png"), meta);
- skin_dls.append(action);
- meta->setStale(true);
- }
- }
- if (!skin_dls.isEmpty())
- {
- auto job = new NetJob("Startup player skins download");
- connect(job, &NetJob::succeeded, this, &MainWindow::skinJobFinished);
- connect(job, &NetJob::failed, this, &MainWindow::skinJobFinished);
- for (auto action : skin_dls)
- {
- job->addNetAction(action);
- }
- skin_download_job.reset(job);
- job->start();
- }
-
- // load the news
- {
- m_newsChecker->reloadNews();
- updateNewsLabel();
- }
-
-
- if(BuildConfig.UPDATER_ENABLED)
- {
- bool updatesAllowed = MMC->updatesAreAllowed();
- updatesAllowedChanged(updatesAllowed);
-
- connect(ui->actionCheckUpdate, &QAction::triggered, this, &MainWindow::checkForUpdates);
-
- // set up the updater object.
- auto updater = MMC->updateChecker();
- connect(updater.get(), &UpdateChecker::updateAvailable, this, &MainWindow::updateAvailable);
- connect(updater.get(), &UpdateChecker::noUpdateFound, this, &MainWindow::updateNotAvailable);
- // if automatic update checks are allowed, start one.
- if (MMC->settings()->get("AutoUpdate").toBool() && updatesAllowed)
- {
- updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), false);
- }
- }
-
- {
- 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);
- connect(m_notificationChecker.get(), &NotificationChecker::notificationCheckFinished, this, &MainWindow::notificationsChanged);
- checker->checkForNotifications();
- }
-
- setSelectedInstanceById(MMC->settings()->get("SelectedInstance").toString());
-
- // removing this looks stupid
- view->setFocus();
+ ui->setupUi(this);
+
+ // OSX magic.
+ setUnifiedTitleAndToolBarOnMac(true);
+
+ // Global shortcuts
+ {
+ // FIXME: This is kinda weird. and bad. We need some kind of managed shutdown.
+ auto q = new QShortcut(QKeySequence::Quit, this);
+ connect(q, SIGNAL(activated()), qApp, SLOT(quit()));
+ }
+
+ // Konami Code
+ {
+ secretEventFilter = new KonamiCode(this);
+ connect(secretEventFilter, &KonamiCode::triggered, this, &MainWindow::konamiTriggered);
+ }
+
+ // Add the news label to the news toolbar.
+ {
+ m_newsChecker.reset(new NewsChecker(BuildConfig.NEWS_RSS_URL));
+ newsLabel = new QToolButton();
+ newsLabel->setIcon(MMC->getThemedIcon("news"));
+ newsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ newsLabel->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ ui->newsToolBar->insertWidget(ui->actionMoreNews, newsLabel);
+ QObject::connect(newsLabel, &QAbstractButton::clicked, this, &MainWindow::newsButtonClicked);
+ QObject::connect(m_newsChecker.get(), &NewsChecker::newsLoaded, this, &MainWindow::updateNewsLabel);
+ updateNewsLabel();
+ }
+
+ // Create the instance list widget
+ {
+ view = new GroupView(ui->centralWidget);
+
+ 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);
+ connect(view, &GroupView::droppedURLs, this, &MainWindow::droppedURLs, Qt::QueuedConnection);
+
+ proxymodel = new InstanceProxyModel(this);
+ proxymodel->setSourceModel(MMC->instances().get());
+ proxymodel->sort(0);
+ connect(proxymodel, &InstanceProxyModel::dataChanged, this, &MainWindow::instanceDataChanged);
+
+ view->setModel(proxymodel);
+ ui->horizontalLayout->addWidget(view);
+ }
+ // The cat background
+ {
+ bool cat_enable = MMC->settings()->get("TheCat").toBool();
+ ui->actionCAT->setChecked(cat_enable);
+ connect(ui->actionCAT, SIGNAL(toggled(bool)), SLOT(onCatToggled(bool)));
+ setCatBackground(cat_enable);
+ }
+ // start instance when double-clicked
+ connect(view, &GroupView::doubleClicked, this, &MainWindow::instanceActivated);
+
+ // track the selection -- update the instance toolbar
+ connect(view->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::instanceChanged);
+
+ // track icon changes and update the toolbar!
+ connect(MMC->icons().get(), &IconList::iconUpdated, this, &MainWindow::iconUpdated);
+
+ // model reset -> selection is invalid. All the instance pointers are wrong.
+ connect(MMC->instances().get(), &InstanceList::dataIsInvalid, this, &MainWindow::selectionBad);
+
+ m_statusLeft = new QLabel(tr("No instance selected"), this);
+ m_statusRight = new ServerStatus(this);
+ statusBar()->addPermanentWidget(m_statusLeft, 1);
+ statusBar()->addPermanentWidget(m_statusRight, 0);
+
+ // Add "manage accounts" button, right align
+ QWidget *spacer = new QWidget();
+ spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ ui->mainToolBar->addWidget(spacer);
+
+ accountMenu = new QMenu(this);
+
+ repopulateAccountsMenu();
+
+ accountMenuButton = new QToolButton(this);
+ accountMenuButton->setText(tr("Profiles"));
+ accountMenuButton->setMenu(accountMenu);
+ accountMenuButton->setPopupMode(QToolButton::InstantPopup);
+ accountMenuButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ accountMenuButton->setIcon(MMC->getThemedIcon("noaccount"));
+
+ QWidgetAction *accountMenuButtonAction = new QWidgetAction(this);
+ accountMenuButtonAction->setDefaultWidget(accountMenuButton);
+
+ ui->mainToolBar->addAction(accountMenuButtonAction);
+
+ // 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...
+ connect(MMC->accounts().get(), &MojangAccountList::activeAccountChanged, [this]
+ {
+ activeAccountChanged();
+ });
+ connect(MMC->accounts().get(), &MojangAccountList::listChanged, [this]
+ {
+ repopulateAccountsMenu();
+ });
+
+ // Show initial account
+ activeAccountChanged();
+
+ auto accounts = MMC->accounts();
+
+ QList<Net::Download::Ptr> skin_dls;
+ for (int i = 0; i < accounts->count(); i++)
+ {
+ auto account = accounts->at(i);
+ if (!account)
+ {
+ qWarning() << "Null account at index" << i;
+ continue;
+ }
+ for (auto profile : account->profiles())
+ {
+ auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.id + ".png");
+ auto action = Net::Download::makeCached(QUrl("https://" + URLConstants::SKINS_BASE + profile.id + ".png"), meta);
+ skin_dls.append(action);
+ meta->setStale(true);
+ }
+ }
+ if (!skin_dls.isEmpty())
+ {
+ auto job = new NetJob("Startup player skins download");
+ connect(job, &NetJob::succeeded, this, &MainWindow::skinJobFinished);
+ connect(job, &NetJob::failed, this, &MainWindow::skinJobFinished);
+ for (auto action : skin_dls)
+ {
+ job->addNetAction(action);
+ }
+ skin_download_job.reset(job);
+ job->start();
+ }
+
+ // load the news
+ {
+ m_newsChecker->reloadNews();
+ updateNewsLabel();
+ }
+
+
+ if(BuildConfig.UPDATER_ENABLED)
+ {
+ bool updatesAllowed = MMC->updatesAreAllowed();
+ updatesAllowedChanged(updatesAllowed);
+
+ connect(ui->actionCheckUpdate, &QAction::triggered, this, &MainWindow::checkForUpdates);
+
+ // set up the updater object.
+ auto updater = MMC->updateChecker();
+ connect(updater.get(), &UpdateChecker::updateAvailable, this, &MainWindow::updateAvailable);
+ connect(updater.get(), &UpdateChecker::noUpdateFound, this, &MainWindow::updateNotAvailable);
+ // if automatic update checks are allowed, start one.
+ if (MMC->settings()->get("AutoUpdate").toBool() && updatesAllowed)
+ {
+ updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), false);
+ }
+ }
+
+ {
+ 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);
+ connect(m_notificationChecker.get(), &NotificationChecker::notificationCheckFinished, this, &MainWindow::notificationsChanged);
+ checker->checkForNotifications();
+ }
+
+ setSelectedInstanceById(MMC->settings()->get("SelectedInstance").toString());
+
+ // removing this looks stupid
+ view->setFocus();
}
MainWindow::~MainWindow()
@@ -816,213 +816,213 @@ MainWindow::~MainWindow()
void MainWindow::konamiTriggered()
{
- qDebug() << "Super Secret Mode ACTIVATED!";
+ qDebug() << "Super Secret Mode ACTIVATED!";
}
void MainWindow::skinJobFinished()
{
- activeAccountChanged();
- skin_download_job.reset();
+ activeAccountChanged();
+ skin_download_job.reset();
}
void MainWindow::showInstanceContextMenu(const QPoint &pos)
{
- QList<QAction *> actions;
-
- QAction *actionSep = new QAction("", this);
- actionSep->setSeparator(true);
-
- bool onInstance = view->indexAt(pos).isValid();
- if (onInstance)
- {
- actions = ui->instanceToolBar->actions();
-
- // replace the change icon widget with an actual action
- actions.replace(0, ui->actionChangeInstIcon);
-
- // replace the rename widget with an actual action
- actions.replace(1, ui->actionRenameInstance);
-
- // 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);
-
- QAction *actionVoid = new QAction("MultiMC", this);
- 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));
+ QList<QAction *> actions;
+
+ QAction *actionSep = new QAction("", this);
+ actionSep->setSeparator(true);
+
+ bool onInstance = view->indexAt(pos).isValid();
+ if (onInstance)
+ {
+ actions = ui->instanceToolBar->actions();
+
+ // replace the change icon widget with an actual action
+ actions.replace(0, ui->actionChangeInstIcon);
+
+ // replace the rename widget with an actual action
+ actions.replace(1, ui->actionRenameInstance);
+
+ // 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);
+
+ QAction *actionVoid = new QAction("MultiMC", this);
+ 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));
}
void MainWindow::updateToolsMenu()
{
- QToolButton *launchButton = dynamic_cast<QToolButton*>(ui->instanceToolBar->widgetForAction(ui->actionLaunchInstance));
- if(!m_selectedInstance || m_selectedInstance->isRunning())
- {
- ui->actionLaunchInstance->setMenu(nullptr);
- launchButton->setPopupMode(QToolButton::InstantPopup);
- return;
- }
-
- QMenu *launchMenu = ui->actionLaunchInstance->menu();
- launchButton->setPopupMode(QToolButton::MenuButtonPopup);
- if (launchMenu)
- {
- launchMenu->clear();
- }
- else
- {
- launchMenu = new QMenu(this);
- }
-
- QAction *normalLaunch = launchMenu->addAction(tr("Launch"));
- connect(normalLaunch, &QAction::triggered, [this]()
- {
- MMC->launch(m_selectedInstance);
- });
- 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);
- profilerAction->setToolTip(tr("Profiler not setup correctly. Go into settings, \"External Tools\"."));
- }
- else
- {
- connect(profilerAction, &QAction::triggered, [this, profiler]()
- {
- MMC->launch(m_selectedInstance, true, profiler.get());
- });
- }
- }
- ui->actionLaunchInstance->setMenu(launchMenu);
+ QToolButton *launchButton = dynamic_cast<QToolButton*>(ui->instanceToolBar->widgetForAction(ui->actionLaunchInstance));
+ if(!m_selectedInstance || m_selectedInstance->isRunning())
+ {
+ ui->actionLaunchInstance->setMenu(nullptr);
+ launchButton->setPopupMode(QToolButton::InstantPopup);
+ return;
+ }
+
+ QMenu *launchMenu = ui->actionLaunchInstance->menu();
+ launchButton->setPopupMode(QToolButton::MenuButtonPopup);
+ if (launchMenu)
+ {
+ launchMenu->clear();
+ }
+ else
+ {
+ launchMenu = new QMenu(this);
+ }
+
+ QAction *normalLaunch = launchMenu->addAction(tr("Launch"));
+ connect(normalLaunch, &QAction::triggered, [this]()
+ {
+ MMC->launch(m_selectedInstance);
+ });
+ 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);
+ profilerAction->setToolTip(tr("Profiler not setup correctly. Go into settings, \"External Tools\"."));
+ }
+ else
+ {
+ connect(profilerAction, &QAction::triggered, [this, profiler]()
+ {
+ MMC->launch(m_selectedInstance, true, profiler.get());
+ });
+ }
+ }
+ ui->actionLaunchInstance->setMenu(launchMenu);
}
QString profileInUseFilter(const QString & profile, bool used)
{
- if(used)
- {
- return profile + QObject::tr(" (in use)");
- }
- else
- {
- return profile;
- }
+ if(used)
+ {
+ return profile + QObject::tr(" (in use)");
+ }
+ else
+ {
+ return profile;
+ }
}
void MainWindow::repopulateAccountsMenu()
{
- accountMenu->clear();
-
- std::shared_ptr<MojangAccountList> accounts = MMC->accounts();
- MojangAccountPtr active_account = accounts->activeAccount();
-
- QString active_username = "";
- if (active_account != nullptr)
- {
- active_username = active_account->username();
- const AccountProfile *profile = active_account->currentProfile();
- // this can be called before accountMenuButton exists
- if (profile != nullptr && accountMenuButton)
- {
- auto profileLabel = profileInUseFilter(profile->name, active_account->isInUse());
- accountMenuButton->setText(profileLabel);
- }
- }
-
- if (accounts->count() <= 0)
- {
- QAction *action = new QAction(tr("No accounts added!"), this);
- action->setEnabled(false);
- accountMenu->addAction(action);
- }
- else
- {
- // TODO: Nicer way to iterate?
- for (int i = 0; i < accounts->count(); i++)
- {
- MojangAccountPtr account = accounts->at(i);
- for (auto profile : account->profiles())
- {
- auto profileLabel = profileInUseFilter(profile.name, account->isInUse());
- QAction *action = new QAction(profileLabel, this);
- action->setData(account->username());
- action->setCheckable(true);
- if (active_username == account->username())
- {
- action->setChecked(true);
- }
-
- action->setIcon(SkinUtils::getFaceFromCache(profile.id));
- accountMenu->addAction(action);
- connect(action, SIGNAL(triggered(bool)), SLOT(changeActiveAccount()));
- }
- }
- }
-
- accountMenu->addSeparator();
-
- QAction *action = new QAction(tr("No Default Account"), this);
- action->setCheckable(true);
- action->setIcon(MMC->getThemedIcon("noaccount"));
- action->setData("");
- if (active_username.isEmpty())
- {
- action->setChecked(true);
- }
-
- accountMenu->addAction(action);
- connect(action, SIGNAL(triggered(bool)), SLOT(changeActiveAccount()));
-
- accountMenu->addSeparator();
- accountMenu->addAction(ui->actionManageAccounts);
+ accountMenu->clear();
+
+ std::shared_ptr<MojangAccountList> accounts = MMC->accounts();
+ MojangAccountPtr active_account = accounts->activeAccount();
+
+ QString active_username = "";
+ if (active_account != nullptr)
+ {
+ active_username = active_account->username();
+ const AccountProfile *profile = active_account->currentProfile();
+ // this can be called before accountMenuButton exists
+ if (profile != nullptr && accountMenuButton)
+ {
+ auto profileLabel = profileInUseFilter(profile->name, active_account->isInUse());
+ accountMenuButton->setText(profileLabel);
+ }
+ }
+
+ if (accounts->count() <= 0)
+ {
+ QAction *action = new QAction(tr("No accounts added!"), this);
+ action->setEnabled(false);
+ accountMenu->addAction(action);
+ }
+ else
+ {
+ // TODO: Nicer way to iterate?
+ for (int i = 0; i < accounts->count(); i++)
+ {
+ MojangAccountPtr account = accounts->at(i);
+ for (auto profile : account->profiles())
+ {
+ auto profileLabel = profileInUseFilter(profile.name, account->isInUse());
+ QAction *action = new QAction(profileLabel, this);
+ action->setData(account->username());
+ action->setCheckable(true);
+ if (active_username == account->username())
+ {
+ action->setChecked(true);
+ }
+
+ action->setIcon(SkinUtils::getFaceFromCache(profile.id));
+ accountMenu->addAction(action);
+ connect(action, SIGNAL(triggered(bool)), SLOT(changeActiveAccount()));
+ }
+ }
+ }
+
+ accountMenu->addSeparator();
+
+ QAction *action = new QAction(tr("No Default Account"), this);
+ action->setCheckable(true);
+ action->setIcon(MMC->getThemedIcon("noaccount"));
+ action->setData("");
+ if (active_username.isEmpty())
+ {
+ action->setChecked(true);
+ }
+
+ accountMenu->addAction(action);
+ connect(action, SIGNAL(triggered(bool)), SLOT(changeActiveAccount()));
+
+ accountMenu->addSeparator();
+ accountMenu->addAction(ui->actionManageAccounts);
}
void MainWindow::updatesAllowedChanged(bool allowed)
{
- if(!BuildConfig.UPDATER_ENABLED)
- {
- return;
- }
- ui->actionCheckUpdate->setEnabled(allowed);
+ if(!BuildConfig.UPDATER_ENABLED)
+ {
+ return;
+ }
+ ui->actionCheckUpdate->setEnabled(allowed);
}
/*
@@ -1030,799 +1030,799 @@ void MainWindow::updatesAllowedChanged(bool allowed)
*/
void MainWindow::changeActiveAccount()
{
- QAction *sAction = (QAction *)sender();
- // Profile's associated Mojang username
- // Will need to change when profiles are properly implemented
- if (sAction->data().type() != QVariant::Type::String)
- return;
+ QAction *sAction = (QAction *)sender();
+ // Profile's associated Mojang username
+ // Will need to change when profiles are properly implemented
+ if (sAction->data().type() != QVariant::Type::String)
+ return;
- QVariant data = sAction->data();
- QString id = "";
- if (!data.isNull())
- {
- id = data.toString();
- }
+ QVariant data = sAction->data();
+ QString id = "";
+ if (!data.isNull())
+ {
+ id = data.toString();
+ }
- MMC->accounts()->setActiveAccount(id);
+ MMC->accounts()->setActiveAccount(id);
- activeAccountChanged();
+ activeAccountChanged();
}
void MainWindow::activeAccountChanged()
{
- repopulateAccountsMenu();
+ repopulateAccountsMenu();
- MojangAccountPtr account = MMC->accounts()->activeAccount();
+ MojangAccountPtr account = MMC->accounts()->activeAccount();
- if (account != nullptr && account->username() != "")
- {
- const AccountProfile *profile = account->currentProfile();
- if (profile != nullptr)
- {
- auto profileLabel = profileInUseFilter(profile->name, account->isInUse());
- accountMenuButton->setIcon(SkinUtils::getFaceFromCache(profile->id));
- accountMenuButton->setText(profileLabel);
- return;
- }
- }
+ if (account != nullptr && account->username() != "")
+ {
+ const AccountProfile *profile = account->currentProfile();
+ if (profile != nullptr)
+ {
+ auto profileLabel = profileInUseFilter(profile->name, account->isInUse());
+ accountMenuButton->setIcon(SkinUtils::getFaceFromCache(profile->id));
+ accountMenuButton->setText(profileLabel);
+ return;
+ }
+ }
- // Set the icon to the "no account" icon.
- accountMenuButton->setIcon(MMC->getThemedIcon("noaccount"));
- accountMenuButton->setText(tr("Profiles"));
+ // Set the icon to the "no account" icon.
+ accountMenuButton->setIcon(MMC->getThemedIcon("noaccount"));
+ accountMenuButton->setText(tr("Profiles"));
}
bool MainWindow::eventFilter(QObject *obj, QEvent *ev)
{
- if (obj == view)
- {
- if (ev->type() == QEvent::KeyPress)
- {
- secretEventFilter->input(ev);
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
- switch (keyEvent->key())
- {
- case Qt::Key_Enter:
- case Qt::Key_Return:
- activateInstance(m_selectedInstance);
- return true;
- 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);
+ if (obj == view)
+ {
+ if (ev->type() == QEvent::KeyPress)
+ {
+ secretEventFilter->input(ev);
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
+ switch (keyEvent->key())
+ {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ activateInstance(m_selectedInstance);
+ return true;
+ 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);
}
void MainWindow::updateNewsLabel()
{
- if (m_newsChecker->isLoadingNews())
- {
- newsLabel->setText(tr("Loading news..."));
- newsLabel->setEnabled(false);
- }
- else
- {
- QList<NewsEntryPtr> entries = m_newsChecker->getNewsEntries();
- if (entries.length() > 0)
- {
- newsLabel->setText(entries[0]->title);
- newsLabel->setEnabled(true);
- }
- else
- {
- newsLabel->setText(tr("No news available."));
- newsLabel->setEnabled(false);
- }
- }
+ if (m_newsChecker->isLoadingNews())
+ {
+ newsLabel->setText(tr("Loading news..."));
+ newsLabel->setEnabled(false);
+ }
+ else
+ {
+ QList<NewsEntryPtr> entries = m_newsChecker->getNewsEntries();
+ if (entries.length() > 0)
+ {
+ newsLabel->setText(entries[0]->title);
+ newsLabel->setEnabled(true);
+ }
+ else
+ {
+ newsLabel->setText(tr("No news available."));
+ newsLabel->setEnabled(false);
+ }
+ }
}
void MainWindow::updateAvailable(GoUpdate::Status status)
{
- if(!MMC->updatesAreAllowed())
- {
- 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;
- }
+ if(!MMC->updatesAreAllowed())
+ {
+ 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;
+ }
}
void MainWindow::updateNotAvailable()
{
- UpdateDialog dlg(false, this);
- dlg.exec();
+ UpdateDialog dlg(false, this);
+ dlg.exec();
}
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;
+ 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(',');
+ QStringList slist;
+ for (int i = 0; i < list.size(); ++i)
+ {
+ slist.append(QString::number(list.at(i)));
+ }
+ return slist.join(',');
}
void MainWindow::notificationsChanged()
{
- QList<NotificationChecker::NotificationEntry> entries = m_notificationChecker->notificationEntries();
- QList<int> shownNotifications = stringToIntList(MMC->settings()->get("ShownNotifications").toString());
- for (auto it = entries.begin(); it != entries.end(); ++it)
- {
- NotificationChecker::NotificationEntry entry = *it;
- if (!shownNotifications.contains(entry.id))
- {
- NotificationDialog dialog(entry, this);
- if (dialog.exec() == NotificationDialog::DontShowAgain)
- {
- shownNotifications.append(entry.id);
- }
- }
- }
- MMC->settings()->set("ShownNotifications", intListToString(shownNotifications));
+ QList<NotificationChecker::NotificationEntry> entries = m_notificationChecker->notificationEntries();
+ QList<int> shownNotifications = stringToIntList(MMC->settings()->get("ShownNotifications").toString());
+ for (auto it = entries.begin(); it != entries.end(); ++it)
+ {
+ NotificationChecker::NotificationEntry entry = *it;
+ if (!shownNotifications.contains(entry.id))
+ {
+ NotificationDialog dialog(entry, this);
+ if (dialog.exec() == NotificationDialog::DontShowAgain)
+ {
+ shownNotifications.append(entry.id);
+ }
+ }
+ }
+ MMC->settings()->set("ShownNotifications", intListToString(shownNotifications));
}
void MainWindow::downloadUpdates(GoUpdate::Status status)
{
- if(!MMC->updatesAreAllowed())
- {
- return;
- }
- qDebug() << "Downloading updates.";
- ProgressDialog updateDlg(this);
- status.rootPath = MMC->root();
-
- auto dlPath = FS::PathCombine(MMC->root(), "update", "XXXXXX");
- if (!FS::ensureFilePathExists(dlPath))
- {
- CustomMessageBox::selectable(this, tr("Error"), tr("Couldn't create folder for update downloads:\n%1").arg(dlPath), QMessageBox::Warning)->show();
- }
- GoUpdate::DownloadTask updateTask(status, dlPath, &updateDlg);
- // 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).
- */
- MMC->updateIsRunning(true);
- UpdateController update(this, MMC->root(), updateTask.updateFilesDir(), updateTask.operations());
- update.installUpdates();
- MMC->updateIsRunning(false);
- }
- else
- {
- CustomMessageBox::selectable(this, tr("Error"), updateTask.failReason(), QMessageBox::Warning)->show();
- }
+ if(!MMC->updatesAreAllowed())
+ {
+ return;
+ }
+ qDebug() << "Downloading updates.";
+ ProgressDialog updateDlg(this);
+ status.rootPath = MMC->root();
+
+ auto dlPath = FS::PathCombine(MMC->root(), "update", "XXXXXX");
+ if (!FS::ensureFilePathExists(dlPath))
+ {
+ CustomMessageBox::selectable(this, tr("Error"), tr("Couldn't create folder for update downloads:\n%1").arg(dlPath), QMessageBox::Warning)->show();
+ }
+ GoUpdate::DownloadTask updateTask(status, dlPath, &updateDlg);
+ // 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).
+ */
+ MMC->updateIsRunning(true);
+ UpdateController update(this, MMC->root(), updateTask.updateFilesDir(), updateTask.operations());
+ update.installUpdates();
+ MMC->updateIsRunning(false);
+ }
+ else
+ {
+ CustomMessageBox::selectable(this, tr("Error"), updateTask.failReason(), QMessageBox::Warning)->show();
+ }
}
void MainWindow::onCatToggled(bool state)
{
- setCatBackground(state);
- MMC->settings()->set("TheCat", state);
+ setCatBackground(state);
+ MMC->settings()->set("TheCat", state);
}
void MainWindow::setCatBackground(bool enabled)
{
- if (enabled)
- {
- view->setStyleSheet("GroupView"
- "{"
- "background-image: url(:/backgrounds/kitteh);"
- "background-attachment: fixed;"
- "background-clip: padding;"
- "background-position: top right;"
- "background-repeat: none;"
- "background-color:palette(base);"
- "}");
- }
- else
- {
- view->setStyleSheet(QString());
- }
+ if (enabled)
+ {
+ view->setStyleSheet("GroupView"
+ "{"
+ "background-image: url(:/backgrounds/kitteh);"
+ "background-attachment: fixed;"
+ "background-clip: padding;"
+ "background-position: top right;"
+ "background-repeat: none;"
+ "background-color:palette(base);"
+ "}");
+ }
+ else
+ {
+ view->setStyleSheet(QString());
+ }
}
void MainWindow::runModalTask(Task *task)
{
- 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();
- }
- });
- ProgressDialog loadDialog(this);
- loadDialog.setSkipButton(true, tr("Abort"));
- loadDialog.execWithTask(task);
+ 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();
+ }
+ });
+ ProgressDialog loadDialog(this);
+ loadDialog.setSkipButton(true, tr("Abort"));
+ loadDialog.execWithTask(task);
}
void MainWindow::instanceFromInstanceTask(InstanceTask *rawTask)
{
- std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(rawTask));
- runModalTask(task.get());
+ std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(rawTask));
+ runModalTask(task.get());
- // FIXME: handle instance selection after creation
- // finalizeInstance(newInstance);
+ // FIXME: handle instance selection after creation
+ // finalizeInstance(newInstance);
}
void MainWindow::on_actionCopyInstance_triggered()
{
- if (!m_selectedInstance)
- return;
+ if (!m_selectedInstance)
+ return;
- CopyInstanceDialog copyInstDlg(m_selectedInstance, this);
- if (!copyInstDlg.exec())
- return;
+ CopyInstanceDialog copyInstDlg(m_selectedInstance, this);
+ if (!copyInstDlg.exec())
+ return;
- auto copyTask = new InstanceCopyTask(m_selectedInstance, copyInstDlg.shouldCopySaves());
- copyTask->setName(copyInstDlg.instName());
- copyTask->setGroup(copyInstDlg.instGroup());
- copyTask->setIcon(copyInstDlg.iconKey());
- std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(copyTask));
- runModalTask(task.get());
+ auto copyTask = new InstanceCopyTask(m_selectedInstance, copyInstDlg.shouldCopySaves());
+ copyTask->setName(copyInstDlg.instName());
+ copyTask->setGroup(copyInstDlg.instGroup());
+ copyTask->setIcon(copyInstDlg.iconKey());
+ std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(copyTask));
+ runModalTask(task.get());
- // FIXME: handle instance selection after creation
- // finalizeInstance(newInstance);
+ // FIXME: handle instance selection after creation
+ // finalizeInstance(newInstance);
}
void MainWindow::finalizeInstance(InstancePtr inst)
{
- view->updateGeometries();
- setSelectedInstanceById(inst->id());
- if (MMC->accounts()->anyAccountIsValid())
- {
- 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
- {
- CustomMessageBox::selectable(this, tr("Error"), tr("MultiMC cannot download Minecraft or update instances unless you have at least "
- "one account added.\nPlease add your Mojang or Minecraft account."),
- QMessageBox::Warning)
- ->show();
- }
+ view->updateGeometries();
+ setSelectedInstanceById(inst->id());
+ if (MMC->accounts()->anyAccountIsValid())
+ {
+ 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
+ {
+ CustomMessageBox::selectable(this, tr("Error"), tr("MultiMC cannot download Minecraft or update instances unless you have at least "
+ "one account added.\nPlease add your Mojang or Minecraft account."),
+ QMessageBox::Warning)
+ ->show();
+ }
}
void MainWindow::addInstance(QString url)
{
- 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())
- {
- groupName = MMC->settings()->get("LastUsedGroupForNewInstance").toString();
- }
-
- NewInstanceDialog newInstDlg(groupName, url, this);
- if (!newInstDlg.exec())
- return;
-
- MMC->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup());
-
- InstanceTask * creationTask = newInstDlg.extractTask();
- if(creationTask)
- {
- instanceFromInstanceTask(creationTask);
- }
+ 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())
+ {
+ groupName = MMC->settings()->get("LastUsedGroupForNewInstance").toString();
+ }
+
+ NewInstanceDialog newInstDlg(groupName, url, this);
+ if (!newInstDlg.exec())
+ return;
+
+ MMC->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup());
+
+ InstanceTask * creationTask = newInstDlg.extractTask();
+ if(creationTask)
+ {
+ instanceFromInstanceTask(creationTask);
+ }
}
void MainWindow::on_actionAddInstance_triggered()
{
- addInstance();
+ addInstance();
}
void MainWindow::droppedURLs(QList<QUrl> urls)
{
- for(auto & url:urls)
- {
- if(url.isLocalFile())
- {
- addInstance(url.toLocalFile());
- }
- else
- {
- addInstance(url.toString());
- }
- // Only process one dropped file...
- break;
- }
+ for(auto & url:urls)
+ {
+ if(url.isLocalFile())
+ {
+ addInstance(url.toLocalFile());
+ }
+ else
+ {
+ addInstance(url.toString());
+ }
+ // Only process one dropped file...
+ break;
+ }
}
void MainWindow::on_actionREDDIT_triggered()
{
- DesktopServices::openUrl(QUrl("https://www.reddit.com/r/MultiMC/"));
+ DesktopServices::openUrl(QUrl("https://www.reddit.com/r/MultiMC/"));
}
void MainWindow::on_actionDISCORD_triggered()
{
- DesktopServices::openUrl(QUrl("https://discord.gg/0k2zsXGNHs0fE4Wm"));
+ DesktopServices::openUrl(QUrl("https://discord.gg/0k2zsXGNHs0fE4Wm"));
}
void MainWindow::on_actionChangeInstIcon_triggered()
{
- if (!m_selectedInstance)
- return;
+ if (!m_selectedInstance)
+ return;
- IconPickerDialog dlg(this);
- dlg.execWithSelection(m_selectedInstance->iconKey());
- if (dlg.result() == QDialog::Accepted)
- {
- m_selectedInstance->setIconKey(dlg.selectedIconKey);
- auto icon = MMC->icons()->getIcon(dlg.selectedIconKey);
- ui->actionChangeInstIcon->setIcon(icon);
- ui->changeIconButton->setIcon(icon);
- }
+ IconPickerDialog dlg(this);
+ dlg.execWithSelection(m_selectedInstance->iconKey());
+ if (dlg.result() == QDialog::Accepted)
+ {
+ m_selectedInstance->setIconKey(dlg.selectedIconKey);
+ auto icon = MMC->icons()->getIcon(dlg.selectedIconKey);
+ ui->actionChangeInstIcon->setIcon(icon);
+ ui->changeIconButton->setIcon(icon);
+ }
}
void MainWindow::iconUpdated(QString icon)
{
- if (icon == m_currentInstIcon)
- {
- auto icon = MMC->icons()->getIcon(m_currentInstIcon);
- ui->actionChangeInstIcon->setIcon(icon);
- ui->changeIconButton->setIcon(icon);
- }
+ if (icon == m_currentInstIcon)
+ {
+ auto icon = MMC->icons()->getIcon(m_currentInstIcon);
+ ui->actionChangeInstIcon->setIcon(icon);
+ ui->changeIconButton->setIcon(icon);
+ }
}
void MainWindow::updateInstanceToolIcon(QString new_icon)
{
- m_currentInstIcon = new_icon;
- auto icon = MMC->icons()->getIcon(m_currentInstIcon);
- ui->actionChangeInstIcon->setIcon(icon);
- ui->changeIconButton->setIcon(icon);
+ m_currentInstIcon = new_icon;
+ auto icon = MMC->icons()->getIcon(m_currentInstIcon);
+ ui->actionChangeInstIcon->setIcon(icon);
+ ui->changeIconButton->setIcon(icon);
}
void MainWindow::setSelectedInstanceById(const QString &id)
{
- if (id.isNull())
- return;
- const QModelIndex index = MMC->instances()->getInstanceIndexById(id);
- if (index.isValid())
- {
- QModelIndex selectionIndex = proxymodel->mapFromSource(index);
- view->selectionModel()->setCurrentIndex(selectionIndex, QItemSelectionModel::ClearAndSelect);
- }
+ if (id.isNull())
+ return;
+ const QModelIndex index = MMC->instances()->getInstanceIndexById(id);
+ if (index.isValid())
+ {
+ QModelIndex selectionIndex = proxymodel->mapFromSource(index);
+ view->selectionModel()->setCurrentIndex(selectionIndex, QItemSelectionModel::ClearAndSelect);
+ }
}
void MainWindow::on_actionChangeInstGroup_triggered()
{
- if (!m_selectedInstance)
- return;
+ if (!m_selectedInstance)
+ return;
- bool ok = false;
- QString name(m_selectedInstance->group());
- auto groups = MMC->instances()->getGroups();
- groups.insert(0, "");
- groups.sort(Qt::CaseInsensitive);
- int foo = groups.indexOf(name);
+ bool ok = false;
+ QString name(m_selectedInstance->group());
+ auto groups = MMC->instances()->getGroups();
+ groups.insert(0, "");
+ groups.sort(Qt::CaseInsensitive);
+ int foo = groups.indexOf(name);
- name = QInputDialog::getItem(this, tr("Group name"), tr("Enter a new group name."), groups, foo, true, &ok);
- name = name.simplified();
- if (ok)
- m_selectedInstance->setGroupPost(name);
+ name = QInputDialog::getItem(this, tr("Group name"), tr("Enter a new group name."), groups, foo, true, &ok);
+ name = name.simplified();
+ if (ok)
+ m_selectedInstance->setGroupPost(name);
}
void MainWindow::deleteGroup()
{
- 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);
- }
+ 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);
+ }
}
void MainWindow::on_actionViewInstanceFolder_triggered()
{
- QString str = MMC->settings()->get("InstanceDir").toString();
- DesktopServices::openDirectory(str);
+ QString str = MMC->settings()->get("InstanceDir").toString();
+ DesktopServices::openDirectory(str);
}
void MainWindow::refreshInstances()
{
- MMC->instances()->loadList(true);
+ MMC->instances()->loadList(true);
}
void MainWindow::on_actionViewCentralModsFolder_triggered()
{
- DesktopServices::openDirectory(MMC->settings()->get("CentralModsDir").toString(), true);
+ DesktopServices::openDirectory(MMC->settings()->get("CentralModsDir").toString(), true);
}
void MainWindow::on_actionConfig_Folder_triggered()
{
- if (m_selectedInstance)
- {
- QString str = m_selectedInstance->instanceConfigFolder();
- DesktopServices::openDirectory(QDir(str).absolutePath());
- }
+ if (m_selectedInstance)
+ {
+ QString str = m_selectedInstance->instanceConfigFolder();
+ DesktopServices::openDirectory(QDir(str).absolutePath());
+ }
}
void MainWindow::checkForUpdates()
{
- 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.";
- }
+ 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.";
+ }
}
void MainWindow::on_actionSettings_triggered()
{
- SettingsUI::ShowPageDialog(MMC->globalSettingsPages(), this, "global-settings");
- // FIXME: quick HACK to make this work. improve, optimize.
- MMC->instances()->loadList(true);
- proxymodel->invalidate();
- proxymodel->sort(0);
- updateToolsMenu();
- update();
+ SettingsUI::ShowPageDialog(MMC->globalSettingsPages(), this, "global-settings");
+ // FIXME: quick HACK to make this work. improve, optimize.
+ MMC->instances()->loadList(true);
+ proxymodel->invalidate();
+ proxymodel->sort(0);
+ updateToolsMenu();
+ update();
}
void MainWindow::on_actionInstanceSettings_triggered()
{
- MMC->showInstanceWindow(m_selectedInstance, "settings");
+ MMC->showInstanceWindow(m_selectedInstance, "settings");
}
void MainWindow::on_actionEditInstNotes_triggered()
{
- MMC->showInstanceWindow(m_selectedInstance, "notes");
+ MMC->showInstanceWindow(m_selectedInstance, "notes");
}
void MainWindow::on_actionWorlds_triggered()
{
- MMC->showInstanceWindow(m_selectedInstance, "worlds");
+ MMC->showInstanceWindow(m_selectedInstance, "worlds");
}
void MainWindow::on_actionEditInstance_triggered()
{
- MMC->showInstanceWindow(m_selectedInstance);
+ MMC->showInstanceWindow(m_selectedInstance);
}
void MainWindow::on_actionScreenshots_triggered()
{
- MMC->showInstanceWindow(m_selectedInstance, "screenshots");
+ MMC->showInstanceWindow(m_selectedInstance, "screenshots");
}
void MainWindow::on_actionManageAccounts_triggered()
{
- SettingsUI::ShowPageDialog(MMC->globalSettingsPages(), this, "accounts");
+ SettingsUI::ShowPageDialog(MMC->globalSettingsPages(), this, "accounts");
}
void MainWindow::on_actionReportBug_triggered()
{
- DesktopServices::openUrl(QUrl("https://github.com/MultiMC/MultiMC5/issues"));
+ DesktopServices::openUrl(QUrl("https://github.com/MultiMC/MultiMC5/issues"));
}
void MainWindow::on_actionPatreon_triggered()
{
- DesktopServices::openUrl(QUrl("http://www.patreon.com/multimc"));
+ DesktopServices::openUrl(QUrl("http://www.patreon.com/multimc"));
}
void MainWindow::on_actionMoreNews_triggered()
{
- DesktopServices::openUrl(QUrl("http://multimc.org/posts.html"));
+ DesktopServices::openUrl(QUrl("http://multimc.org/posts.html"));
}
void MainWindow::newsButtonClicked()
{
- QList<NewsEntryPtr> entries = m_newsChecker->getNewsEntries();
- if (entries.count() > 0)
- {
- DesktopServices::openUrl(QUrl(entries[0]->link));
- }
- else
- {
- DesktopServices::openUrl(QUrl("http://multimc.org/posts.html"));
- }
+ QList<NewsEntryPtr> entries = m_newsChecker->getNewsEntries();
+ if (entries.count() > 0)
+ {
+ DesktopServices::openUrl(QUrl(entries[0]->link));
+ }
+ else
+ {
+ DesktopServices::openUrl(QUrl("http://multimc.org/posts.html"));
+ }
}
void MainWindow::on_actionAbout_triggered()
{
- AboutDialog dialog(this);
- dialog.exec();
+ AboutDialog dialog(this);
+ dialog.exec();
}
void MainWindow::on_mainToolBar_visibilityChanged(bool)
{
- // Don't allow hiding the main toolbar.
- // This is the only way I could find to prevent it... :/
- ui->mainToolBar->setVisible(true);
+ // Don't allow hiding the main toolbar.
+ // This is the only way I could find to prevent it... :/
+ ui->mainToolBar->setVisible(true);
}
void MainWindow::on_actionDeleteInstance_triggered()
{
- if (!m_selectedInstance)
- {
- return;
- }
- auto response = CustomMessageBox::selectable(
- this,
- tr("CAREFUL!"),
- tr("About to delete: %1\nThis is permanent and will completely delete the instance.\n\nAre you sure?").arg(m_selectedInstance->name()),
- QMessageBox::Warning,
- QMessageBox::Yes | QMessageBox::No
- )->exec();
- if (response == QMessageBox::Yes)
- {
- m_selectedInstance->nuke();
- }
+ if (!m_selectedInstance)
+ {
+ return;
+ }
+ auto response = CustomMessageBox::selectable(
+ this,
+ tr("CAREFUL!"),
+ tr("About to delete: %1\nThis is permanent and will completely delete the instance.\n\nAre you sure?").arg(m_selectedInstance->name()),
+ QMessageBox::Warning,
+ QMessageBox::Yes | QMessageBox::No
+ )->exec();
+ if (response == QMessageBox::Yes)
+ {
+ m_selectedInstance->nuke();
+ }
}
void MainWindow::on_actionExportInstance_triggered()
{
- if (m_selectedInstance)
- {
- ExportInstanceDialog dlg(m_selectedInstance, this);
- dlg.exec();
- }
+ if (m_selectedInstance)
+ {
+ ExportInstanceDialog dlg(m_selectedInstance, this);
+ dlg.exec();
+ }
}
void MainWindow::on_actionRenameInstance_triggered()
{
- if (m_selectedInstance)
- {
- bool ok = false;
- QString name(m_selectedInstance->name());
- name = QInputDialog::getText(this, tr("Instance name"), tr("Enter a new instance name."), QLineEdit::Normal, name, &ok);
+ if (m_selectedInstance)
+ {
+ bool ok = false;
+ QString name(m_selectedInstance->name());
+ name = QInputDialog::getText(this, tr("Instance name"), tr("Enter a new instance name."), QLineEdit::Normal, name, &ok);
- name = name.trimmed();
- if (name.length() > 0)
- {
- if (ok && name.length())
- {
- m_selectedInstance->setName(name);
- ui->renameButton->setText(name);
- }
- }
- }
+ name = name.trimmed();
+ if (name.length() > 0)
+ {
+ if (ok && name.length())
+ {
+ m_selectedInstance->setName(name);
+ ui->renameButton->setText(name);
+ }
+ }
+ }
}
void MainWindow::on_actionViewSelectedInstFolder_triggered()
{
- if (m_selectedInstance)
- {
- QString str = m_selectedInstance->instanceRoot();
- DesktopServices::openDirectory(QDir(str).absolutePath());
- }
+ if (m_selectedInstance)
+ {
+ QString str = m_selectedInstance->instanceRoot();
+ DesktopServices::openDirectory(QDir(str).absolutePath());
+ }
}
void MainWindow::closeEvent(QCloseEvent *event)
{
- // Save the window state and geometry.
- MMC->settings()->set("MainWindowState", saveState().toBase64());
- MMC->settings()->set("MainWindowGeometry", saveGeometry().toBase64());
- event->accept();
- emit isClosing();
+ // Save the window state and geometry.
+ MMC->settings()->set("MainWindowState", saveState().toBase64());
+ MMC->settings()->set("MainWindowGeometry", saveGeometry().toBase64());
+ event->accept();
+ emit isClosing();
}
void MainWindow::changeEvent(QEvent* event)
{
- if (event->type() == QEvent::LanguageChange)
- {
- ui->retranslateUi(this);
- }
- QMainWindow::changeEvent(event);
+ if (event->type() == QEvent::LanguageChange)
+ {
+ ui->retranslateUi(this);
+ }
+ QMainWindow::changeEvent(event);
}
void MainWindow::instanceActivated(QModelIndex index)
{
- if (!index.isValid())
- return;
- QString id = index.data(InstanceList::InstanceIDRole).toString();
- InstancePtr inst = MMC->instances()->getInstanceById(id);
- if (!inst)
- return;
+ if (!index.isValid())
+ return;
+ QString id = index.data(InstanceList::InstanceIDRole).toString();
+ InstancePtr inst = MMC->instances()->getInstanceById(id);
+ if (!inst)
+ return;
- activateInstance(inst);
+ activateInstance(inst);
}
void MainWindow::on_actionLaunchInstance_triggered()
{
- if (!m_selectedInstance)
- {
- return;
- }
- if(m_selectedInstance->isRunning())
- {
- MMC->kill(m_selectedInstance);
- }
- else
- {
- MMC->launch(m_selectedInstance);
- }
+ if (!m_selectedInstance)
+ {
+ return;
+ }
+ if(m_selectedInstance->isRunning())
+ {
+ MMC->kill(m_selectedInstance);
+ }
+ else
+ {
+ MMC->launch(m_selectedInstance);
+ }
}
void MainWindow::activateInstance(InstancePtr instance)
{
- MMC->launch(instance);
+ MMC->launch(instance);
}
void MainWindow::on_actionLaunchInstanceOffline_triggered()
{
- if (m_selectedInstance)
- {
- MMC->launch(m_selectedInstance, false);
- }
+ if (m_selectedInstance)
+ {
+ MMC->launch(m_selectedInstance, false);
+ }
}
void MainWindow::taskEnd()
{
- QObject *sender = QObject::sender();
- if (sender == m_versionLoadTask)
- m_versionLoadTask = NULL;
+ QObject *sender = QObject::sender();
+ if (sender == m_versionLoadTask)
+ m_versionLoadTask = NULL;
- sender->deleteLater();
+ sender->deleteLater();
}
void MainWindow::startTask(Task *task)
{
- connect(task, SIGNAL(succeeded()), SLOT(taskEnd()));
- connect(task, SIGNAL(failed(QString)), SLOT(taskEnd()));
- task->start();
+ connect(task, SIGNAL(succeeded()), SLOT(taskEnd()));
+ connect(task, SIGNAL(failed(QString)), SLOT(taskEnd()));
+ task->start();
}
void MainWindow::instanceChanged(const QModelIndex &current, const QModelIndex &previous)
{
- if (!current.isValid())
- {
- MMC->settings()->set("SelectedInstance", QString());
- selectionBad();
- return;
- }
- QString id = current.data(InstanceList::InstanceIDRole).toString();
- m_selectedInstance = MMC->instances()->getInstanceById(id);
- if (m_selectedInstance)
- {
- ui->instanceToolBar->setEnabled(true);
- if(m_selectedInstance->isRunning())
- {
- ui->actionLaunchInstance->setEnabled(true);
- ui->setLaunchAction(true);
- }
- else
- {
- ui->actionLaunchInstance->setEnabled(m_selectedInstance->canLaunch());
- ui->setLaunchAction(false);
- }
- ui->actionLaunchInstanceOffline->setEnabled(m_selectedInstance->canLaunch());
- ui->actionExportInstance->setEnabled(m_selectedInstance->canExport());
- ui->renameButton->setText(m_selectedInstance->name());
- m_statusLeft->setText(m_selectedInstance->getStatusbarDescription());
- updateInstanceToolIcon(m_selectedInstance->iconKey());
-
- updateToolsMenu();
-
- MMC->settings()->set("SelectedInstance", m_selectedInstance->id());
- }
- else
- {
- ui->instanceToolBar->setEnabled(false);
- MMC->settings()->set("SelectedInstance", QString());
- selectionBad();
- return;
- }
+ if (!current.isValid())
+ {
+ MMC->settings()->set("SelectedInstance", QString());
+ selectionBad();
+ return;
+ }
+ QString id = current.data(InstanceList::InstanceIDRole).toString();
+ m_selectedInstance = MMC->instances()->getInstanceById(id);
+ if (m_selectedInstance)
+ {
+ ui->instanceToolBar->setEnabled(true);
+ if(m_selectedInstance->isRunning())
+ {
+ ui->actionLaunchInstance->setEnabled(true);
+ ui->setLaunchAction(true);
+ }
+ else
+ {
+ ui->actionLaunchInstance->setEnabled(m_selectedInstance->canLaunch());
+ ui->setLaunchAction(false);
+ }
+ ui->actionLaunchInstanceOffline->setEnabled(m_selectedInstance->canLaunch());
+ ui->actionExportInstance->setEnabled(m_selectedInstance->canExport());
+ ui->renameButton->setText(m_selectedInstance->name());
+ m_statusLeft->setText(m_selectedInstance->getStatusbarDescription());
+ updateInstanceToolIcon(m_selectedInstance->iconKey());
+
+ updateToolsMenu();
+
+ MMC->settings()->set("SelectedInstance", m_selectedInstance->id());
+ }
+ else
+ {
+ ui->instanceToolBar->setEnabled(false);
+ MMC->settings()->set("SelectedInstance", QString());
+ selectionBad();
+ return;
+ }
}
void MainWindow::instanceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
- auto current = view->selectionModel()->currentIndex();
- QItemSelection test(topLeft, bottomRight);
- if (test.contains(current))
- {
- instanceChanged(current, current);
- }
+ auto current = view->selectionModel()->currentIndex();
+ QItemSelection test(topLeft, bottomRight);
+ if (test.contains(current))
+ {
+ instanceChanged(current, current);
+ }
}
void MainWindow::selectionBad()
{
- // start by reseting everything...
- m_selectedInstance = nullptr;
+ // start by reseting everything...
+ m_selectedInstance = nullptr;
- statusBar()->clearMessage();
- ui->instanceToolBar->setEnabled(false);
- ui->renameButton->setText(tr("Rename Instance"));
- updateInstanceToolIcon("infinity");
+ statusBar()->clearMessage();
+ ui->instanceToolBar->setEnabled(false);
+ ui->renameButton->setText(tr("Rename Instance"));
+ updateInstanceToolIcon("infinity");
- // ...and then see if we can enable the previously selected instance
- setSelectedInstanceById(MMC->settings()->get("SelectedInstance").toString());
+ // ...and then see if we can enable the previously selected instance
+ setSelectedInstanceById(MMC->settings()->get("SelectedInstance").toString());
}
void MainWindow::checkInstancePathForProblems()
{
- QString instanceFolder = MMC->settings()->get("InstanceDir").toString();
- if (FS::checkProblemticPathJava(QDir(instanceFolder)))
- {
- QMessageBox warning(this);
- 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"));
- warning.setDefaultButton(QMessageBox::Ok);
- warning.exec();
- }
- auto tempFolderText = tr("This is a problem: <br/>"
- " - 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");
- QString pathfoldername = QDir(instanceFolder).absolutePath();
- if (pathfoldername.contains("Rar$", Qt::CaseInsensitive))
- {
- QMessageBox warning(this);
- warning.setText(tr("Your instance folder contains \'Rar$\' - that means you haven't extracted the MultiMC zip!"));
- warning.setInformativeText(tempFolderText);
- warning.setDefaultButton(QMessageBox::Ok);
- warning.exec();
- }
- else if (pathfoldername.contains(QDir::tempPath()))
- {
- 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();
- }
+ QString instanceFolder = MMC->settings()->get("InstanceDir").toString();
+ if (FS::checkProblemticPathJava(QDir(instanceFolder)))
+ {
+ QMessageBox warning(this);
+ 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"));
+ warning.setDefaultButton(QMessageBox::Ok);
+ warning.exec();
+ }
+ auto tempFolderText = tr("This is a problem: <br/>"
+ " - 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");
+ QString pathfoldername = QDir(instanceFolder).absolutePath();
+ if (pathfoldername.contains("Rar$", Qt::CaseInsensitive))
+ {
+ QMessageBox warning(this);
+ warning.setText(tr("Your instance folder contains \'Rar$\' - that means you haven't extracted the MultiMC zip!"));
+ warning.setInformativeText(tempFolderText);
+ warning.setDefaultButton(QMessageBox::Ok);
+ warning.exec();
+ }
+ else if (pathfoldername.contains(QDir::tempPath()))
+ {
+ 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();
+ }
}
diff --git a/application/MainWindow.h b/application/MainWindow.h
index 8f756412..3095ba41 100644
--- a/application/MainWindow.h
+++ b/application/MainWindow.h
@@ -42,174 +42,174 @@ class InstanceTask;
class MainWindow : public QMainWindow
{
- Q_OBJECT
+ Q_OBJECT
- class Ui;
+ class Ui;
public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
- bool eventFilter(QObject *obj, QEvent *ev) override;
- void closeEvent(QCloseEvent *event) override;
- void changeEvent(QEvent * event) override;
+ bool eventFilter(QObject *obj, QEvent *ev) override;
+ void closeEvent(QCloseEvent *event) override;
+ void changeEvent(QEvent * event) override;
- void checkInstancePathForProblems();
+ void checkInstancePathForProblems();
- void updatesAllowedChanged(bool allowed);
+ void updatesAllowedChanged(bool allowed);
signals:
- void isClosing();
+ void isClosing();
private slots:
- void onCatToggled(bool);
+ void onCatToggled(bool);
- void on_actionAbout_triggered();
+ void on_actionAbout_triggered();
- void on_actionAddInstance_triggered();
+ void on_actionAddInstance_triggered();
- void on_actionREDDIT_triggered();
+ void on_actionREDDIT_triggered();
- void on_actionDISCORD_triggered();
+ void on_actionDISCORD_triggered();
- void on_actionCopyInstance_triggered();
+ void on_actionCopyInstance_triggered();
- void on_actionChangeInstGroup_triggered();
+ void on_actionChangeInstGroup_triggered();
- void on_actionChangeInstIcon_triggered();
- void on_changeIconButton_clicked(bool)
- {
- on_actionChangeInstIcon_triggered();
- }
+ void on_actionChangeInstIcon_triggered();
+ void on_changeIconButton_clicked(bool)
+ {
+ on_actionChangeInstIcon_triggered();
+ }
- void on_actionViewInstanceFolder_triggered();
+ void on_actionViewInstanceFolder_triggered();
- void on_actionConfig_Folder_triggered();
+ void on_actionConfig_Folder_triggered();
- void on_actionViewSelectedInstFolder_triggered();
+ void on_actionViewSelectedInstFolder_triggered();
- void refreshInstances();
+ void refreshInstances();
- void on_actionViewCentralModsFolder_triggered();
+ void on_actionViewCentralModsFolder_triggered();
- void checkForUpdates();
+ void checkForUpdates();
- void on_actionSettings_triggered();
+ void on_actionSettings_triggered();
- void on_actionInstanceSettings_triggered();
+ void on_actionInstanceSettings_triggered();
- void on_actionManageAccounts_triggered();
+ void on_actionManageAccounts_triggered();
- void on_actionReportBug_triggered();
+ void on_actionReportBug_triggered();
- void on_actionPatreon_triggered();
+ void on_actionPatreon_triggered();
- void on_actionMoreNews_triggered();
+ void on_actionMoreNews_triggered();
- void newsButtonClicked();
+ void newsButtonClicked();
- void on_mainToolBar_visibilityChanged(bool);
+ void on_mainToolBar_visibilityChanged(bool);
- void on_actionLaunchInstance_triggered();
+ void on_actionLaunchInstance_triggered();
- void on_actionLaunchInstanceOffline_triggered();
+ void on_actionLaunchInstanceOffline_triggered();
- void on_actionDeleteInstance_triggered();
+ void on_actionDeleteInstance_triggered();
- void deleteGroup();
+ void deleteGroup();
- void on_actionExportInstance_triggered();
+ void on_actionExportInstance_triggered();
- void on_actionRenameInstance_triggered();
- void on_renameButton_clicked(bool)
- {
- on_actionRenameInstance_triggered();
- }
+ void on_actionRenameInstance_triggered();
+ void on_renameButton_clicked(bool)
+ {
+ on_actionRenameInstance_triggered();
+ }
- void on_actionEditInstance_triggered();
+ void on_actionEditInstance_triggered();
- void on_actionEditInstNotes_triggered();
+ void on_actionEditInstNotes_triggered();
- void on_actionWorlds_triggered();
+ void on_actionWorlds_triggered();
- void on_actionScreenshots_triggered();
+ void on_actionScreenshots_triggered();
- void taskEnd();
+ void taskEnd();
- /**
- * called when an icon is changed in the icon model.
- */
- void iconUpdated(QString);
+ /**
+ * called when an icon is changed in the icon model.
+ */
+ void iconUpdated(QString);
- void showInstanceContextMenu(const QPoint &);
+ void showInstanceContextMenu(const QPoint &);
- void updateToolsMenu();
+ void updateToolsMenu();
- void skinJobFinished();
+ void skinJobFinished();
- void instanceActivated(QModelIndex);
+ void instanceActivated(QModelIndex);
- void instanceChanged(const QModelIndex &current, const QModelIndex &previous);
+ void instanceChanged(const QModelIndex &current, const QModelIndex &previous);
- void instanceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void instanceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void selectionBad();
+ void selectionBad();
- void startTask(Task *task);
+ void startTask(Task *task);
- void updateAvailable(GoUpdate::Status status);
+ void updateAvailable(GoUpdate::Status status);
- void updateNotAvailable();
+ void updateNotAvailable();
- void notificationsChanged();
+ void notificationsChanged();
- void activeAccountChanged();
+ void activeAccountChanged();
- void changeActiveAccount();
+ void changeActiveAccount();
- void repopulateAccountsMenu();
+ void repopulateAccountsMenu();
- void updateNewsLabel();
+ void updateNewsLabel();
- /*!
- * Runs the DownloadTask and installs updates.
- */
- void downloadUpdates(GoUpdate::Status status);
+ /*!
+ * Runs the DownloadTask and installs updates.
+ */
+ void downloadUpdates(GoUpdate::Status status);
- void droppedURLs(QList<QUrl> urls);
+ void droppedURLs(QList<QUrl> urls);
- void konamiTriggered();
+ void konamiTriggered();
private:
- void addInstance(QString url = QString());
- void activateInstance(InstancePtr instance);
- void setCatBackground(bool enabled);
- void updateInstanceToolIcon(QString new_icon);
- void setSelectedInstanceById(const QString &id);
+ void addInstance(QString url = QString());
+ void activateInstance(InstancePtr instance);
+ void setCatBackground(bool enabled);
+ void updateInstanceToolIcon(QString new_icon);
+ void setSelectedInstanceById(const QString &id);
- void runModalTask(Task *task);
- void instanceFromInstanceTask(InstanceTask *task);
- void finalizeInstance(InstancePtr inst);
+ void runModalTask(Task *task);
+ void instanceFromInstanceTask(InstanceTask *task);
+ void finalizeInstance(InstancePtr inst);
private:
- std::unique_ptr<Ui> ui;
-
- // these are managed by Qt's memory management model!
- GroupView *view = nullptr;
- InstanceProxyModel *proxymodel = nullptr;
- QToolButton *newsLabel = nullptr;
- QLabel *m_statusLeft = nullptr;
- ServerStatus *m_statusRight = nullptr;
- QMenu *accountMenu = nullptr;
- QToolButton *accountMenuButton = nullptr;
- KonamiCode * secretEventFilter = nullptr;
-
- unique_qobject_ptr<NetJob> skin_download_job;
- unique_qobject_ptr<NewsChecker> m_newsChecker;
- unique_qobject_ptr<NotificationChecker> m_notificationChecker;
-
- InstancePtr m_selectedInstance;
- QString m_currentInstIcon;
-
- // managed by the application object
- Task *m_versionLoadTask = nullptr;
+ std::unique_ptr<Ui> ui;
+
+ // these are managed by Qt's memory management model!
+ GroupView *view = nullptr;
+ InstanceProxyModel *proxymodel = nullptr;
+ QToolButton *newsLabel = nullptr;
+ QLabel *m_statusLeft = nullptr;
+ ServerStatus *m_statusRight = nullptr;
+ QMenu *accountMenu = nullptr;
+ QToolButton *accountMenuButton = nullptr;
+ KonamiCode * secretEventFilter = nullptr;
+
+ unique_qobject_ptr<NetJob> skin_download_job;
+ unique_qobject_ptr<NewsChecker> m_newsChecker;
+ unique_qobject_ptr<NotificationChecker> m_notificationChecker;
+
+ InstancePtr m_selectedInstance;
+ QString m_currentInstIcon;
+
+ // managed by the application object
+ Task *m_versionLoadTask = nullptr;
};
diff --git a/application/MultiMC.cpp b/application/MultiMC.cpp
index e7e6d337..c1996863 100644
--- a/application/MultiMC.cpp
+++ b/application/MultiMC.cpp
@@ -83,1146 +83,1146 @@ static const QLatin1String liveCheckFile("live.check");
using namespace Commandline;
#define MACOS_HINT "If you are on macOS Sierra, you might have to move MultiMC.app to your /Applications or ~/Applications folder. "\
- "This usually fixes the problem and you can move the application elsewhere afterwards.\n"\
- "\n"
+ "This usually fixes the problem and you can move the application elsewhere afterwards.\n"\
+ "\n"
static void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
- const char *levels = "DWCFIS";
- const QString format("%1 %2 %3\n");
-
- qint64 msecstotal = MMC->timeSinceStart();
- qint64 seconds = msecstotal / 1000;
- qint64 msecs = msecstotal % 1000;
- QString foo;
- char buf[1025] = {0};
- ::snprintf(buf, 1024, "%5lld.%03lld", seconds, msecs);
-
- QString out = format.arg(buf).arg(levels[type]).arg(msg);
-
- MMC->logFile->write(out.toUtf8());
- MMC->logFile->flush();
- QTextStream(stderr) << out.toLocal8Bit();
- fflush(stderr);
+ const char *levels = "DWCFIS";
+ const QString format("%1 %2 %3\n");
+
+ qint64 msecstotal = MMC->timeSinceStart();
+ qint64 seconds = msecstotal / 1000;
+ qint64 msecs = msecstotal % 1000;
+ QString foo;
+ char buf[1025] = {0};
+ ::snprintf(buf, 1024, "%5lld.%03lld", seconds, msecs);
+
+ QString out = format.arg(buf).arg(levels[type]).arg(msg);
+
+ MMC->logFile->write(out.toUtf8());
+ MMC->logFile->flush();
+ QTextStream(stderr) << out.toLocal8Bit();
+ fflush(stderr);
}
MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
{
#if defined Q_OS_WIN32
- // attach the parent console
- if(AttachConsole(ATTACH_PARENT_PROCESS))
- {
- // if attach succeeds, reopen and sync all the i/o
- if(freopen("CON", "w", stdout))
- {
- std::cout.sync_with_stdio();
- }
- if(freopen("CON", "w", stderr))
- {
- std::cerr.sync_with_stdio();
- }
- if(freopen("CON", "r", stdin))
- {
- std::cin.sync_with_stdio();
- }
- auto out = GetStdHandle (STD_OUTPUT_HANDLE);
- DWORD written;
- const char * endline = "\n";
- WriteConsole(out, endline, strlen(endline), &written, NULL);
- consoleAttached = true;
- }
+ // attach the parent console
+ if(AttachConsole(ATTACH_PARENT_PROCESS))
+ {
+ // if attach succeeds, reopen and sync all the i/o
+ if(freopen("CON", "w", stdout))
+ {
+ std::cout.sync_with_stdio();
+ }
+ if(freopen("CON", "w", stderr))
+ {
+ std::cerr.sync_with_stdio();
+ }
+ if(freopen("CON", "r", stdin))
+ {
+ std::cin.sync_with_stdio();
+ }
+ auto out = GetStdHandle (STD_OUTPUT_HANDLE);
+ DWORD written;
+ const char * endline = "\n";
+ WriteConsole(out, endline, strlen(endline), &written, NULL);
+ consoleAttached = true;
+ }
#endif
- setOrganizationName("MultiMC");
- setOrganizationDomain("multimc.org");
- setApplicationName("MultiMC5");
- setApplicationDisplayName("MultiMC 5");
- setApplicationVersion(BuildConfig.printableVersionString());
-
- startTime = QDateTime::currentDateTime();
-
- // Don't quit on hiding the last window
- this->setQuitOnLastWindowClosed(false);
-
- // Commandline parsing
- QHash<QString, QVariant> args;
- {
- Parser parser(FlagStyle::GNU, ArgumentStyle::SpaceAndEquals);
-
- // --help
- parser.addSwitch("help");
- parser.addShortOpt("help", 'h');
- parser.addDocumentation("help", "display this help and exit.");
- // --version
- parser.addSwitch("version");
- parser.addShortOpt("version", 'V');
- parser.addDocumentation("version", "display program version and exit.");
- // --dir
- parser.addOption("dir");
- parser.addShortOpt("dir", 'd');
- parser.addDocumentation("dir", "use the supplied folder as MultiMC root instead of "
- "the binary location (use '.' for current)");
- // --launch
- parser.addOption("launch");
- parser.addShortOpt("launch", 'l');
- parser.addDocumentation("launch", "launch the specified instance (by instance ID)");
- // --alive
- parser.addSwitch("alive");
- parser.addDocumentation("alive", "write a small '" + liveCheckFile + "' file after MultiMC starts");
-
- // parse the arguments
- try
- {
- args = parser.parse(arguments());
- }
- catch (const ParsingError &e)
- {
- std::cerr << "CommandLineError: " << e.what() << std::endl;
- std::cerr << "Try '%1 -h' to get help on MultiMC's command line parameters."
- << std::endl;
- m_status = MultiMC::Failed;
- return;
- }
-
- // display help and exit
- if (args["help"].toBool())
- {
- std::cout << qPrintable(parser.compileHelp(arguments()[0]));
- m_status = MultiMC::Succeeded;
- return;
- }
-
- // display version and exit
- if (args["version"].toBool())
- {
- std::cout << "Version " << BuildConfig.printableVersionString().toStdString() << std::endl;
- std::cout << "Git " << BuildConfig.GIT_COMMIT.toStdString() << std::endl;
- m_status = MultiMC::Succeeded;
- return;
- }
- }
- m_instanceIdToLaunch = args["launch"].toString();
- m_liveCheck = args["alive"].toBool();
-
- QString origcwdPath = QDir::currentPath();
- QString binPath = applicationDirPath();
- QString adjustedBy;
- QString dataPath;
- // change folder
- QString dirParam = args["dir"].toString();
- if (!dirParam.isEmpty())
- {
- // the dir param. it makes multimc data path point to whatever the user specified
- // on command line
- adjustedBy += "Command line " + dirParam;
- dataPath = dirParam;
- }
- else
- {
+ setOrganizationName("MultiMC");
+ setOrganizationDomain("multimc.org");
+ setApplicationName("MultiMC5");
+ setApplicationDisplayName("MultiMC 5");
+ setApplicationVersion(BuildConfig.printableVersionString());
+
+ startTime = QDateTime::currentDateTime();
+
+ // Don't quit on hiding the last window
+ this->setQuitOnLastWindowClosed(false);
+
+ // Commandline parsing
+ QHash<QString, QVariant> args;
+ {
+ Parser parser(FlagStyle::GNU, ArgumentStyle::SpaceAndEquals);
+
+ // --help
+ parser.addSwitch("help");
+ parser.addShortOpt("help", 'h');
+ parser.addDocumentation("help", "display this help and exit.");
+ // --version
+ parser.addSwitch("version");
+ parser.addShortOpt("version", 'V');
+ parser.addDocumentation("version", "display program version and exit.");
+ // --dir
+ parser.addOption("dir");
+ parser.addShortOpt("dir", 'd');
+ parser.addDocumentation("dir", "use the supplied folder as MultiMC root instead of "
+ "the binary location (use '.' for current)");
+ // --launch
+ parser.addOption("launch");
+ parser.addShortOpt("launch", 'l');
+ parser.addDocumentation("launch", "launch the specified instance (by instance ID)");
+ // --alive
+ parser.addSwitch("alive");
+ parser.addDocumentation("alive", "write a small '" + liveCheckFile + "' file after MultiMC starts");
+
+ // parse the arguments
+ try
+ {
+ args = parser.parse(arguments());
+ }
+ catch (const ParsingError &e)
+ {
+ std::cerr << "CommandLineError: " << e.what() << std::endl;
+ std::cerr << "Try '%1 -h' to get help on MultiMC's command line parameters."
+ << std::endl;
+ m_status = MultiMC::Failed;
+ return;
+ }
+
+ // display help and exit
+ if (args["help"].toBool())
+ {
+ std::cout << qPrintable(parser.compileHelp(arguments()[0]));
+ m_status = MultiMC::Succeeded;
+ return;
+ }
+
+ // display version and exit
+ if (args["version"].toBool())
+ {
+ std::cout << "Version " << BuildConfig.printableVersionString().toStdString() << std::endl;
+ std::cout << "Git " << BuildConfig.GIT_COMMIT.toStdString() << std::endl;
+ m_status = MultiMC::Succeeded;
+ return;
+ }
+ }
+ m_instanceIdToLaunch = args["launch"].toString();
+ m_liveCheck = args["alive"].toBool();
+
+ QString origcwdPath = QDir::currentPath();
+ QString binPath = applicationDirPath();
+ QString adjustedBy;
+ QString dataPath;
+ // change folder
+ QString dirParam = args["dir"].toString();
+ if (!dirParam.isEmpty())
+ {
+ // the dir param. it makes multimc data path point to whatever the user specified
+ // on command line
+ adjustedBy += "Command line " + dirParam;
+ dataPath = dirParam;
+ }
+ else
+ {
#ifdef MULTIMC_LINUX_DATADIR
- QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
- if (xdgDataHome.isEmpty())
- xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
- dataPath = xdgDataHome + "/multimc";
- adjustedBy += "XDG standard " + dataPath;
+ QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
+ if (xdgDataHome.isEmpty())
+ xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
+ dataPath = xdgDataHome + "/multimc";
+ adjustedBy += "XDG standard " + dataPath;
#else
- dataPath = applicationDirPath();
- adjustedBy += "Fallback to binary path " + dataPath;
+ dataPath = applicationDirPath();
+ adjustedBy += "Fallback to binary path " + dataPath;
#endif
- }
-
- if (!FS::ensureFolderPathExists(dataPath))
- {
- showFatalErrorMessage(
- "MultiMC data folder could not be created.",
- "MultiMC data folder could not be created.\n"
- "\n"
+ }
+
+ if (!FS::ensureFolderPathExists(dataPath))
+ {
+ showFatalErrorMessage(
+ "MultiMC data folder could not be created.",
+ "MultiMC data folder could not be created.\n"
+ "\n"
#if defined(Q_OS_MAC)
- MACOS_HINT
+ MACOS_HINT
#endif
- "Make sure you have the right permissions to the MultiMC data folder and any folder needed to access it.\n"
- "\n"
- "MultiMC cannot continue until you fix this problem."
- );
- return;
- }
- if (!QDir::setCurrent(dataPath))
- {
- showFatalErrorMessage(
- "MultiMC data folder could not be opened.",
- "MultiMC data folder could not be opened.\n"
- "\n"
+ "Make sure you have the right permissions to the MultiMC data folder and any folder needed to access it.\n"
+ "\n"
+ "MultiMC cannot continue until you fix this problem."
+ );
+ return;
+ }
+ if (!QDir::setCurrent(dataPath))
+ {
+ showFatalErrorMessage(
+ "MultiMC data folder could not be opened.",
+ "MultiMC data folder could not be opened.\n"
+ "\n"
#if defined(Q_OS_MAC)
- MACOS_HINT
+ MACOS_HINT
#endif
- "Make sure you have the right permissions to the MultiMC data folder.\n"
- "\n"
- "MultiMC cannot continue until you fix this problem."
- );
- return;
- }
-
- /*
- * Establish the mechanism for communication with an already running MultiMC that uses the same data path.
- * If there is one, tell it what the user actually wanted to do and exit.
- * We want to initialize this before logging to avoid messing with the log of a potential already running copy.
- */
- auto appID = ApplicationId::fromPathAndVersion(QDir::currentPath(), BuildConfig.printableVersionString());
- {
- // FIXME: you can run the same binaries with multiple data dirs and they won't clash. This could cause issues for updates.
- m_peerInstance = new LocalPeer(this, appID);
- connect(m_peerInstance, &LocalPeer::messageReceived, this, &MultiMC::messageReceived);
- if(m_peerInstance->isClient())
- {
- if(m_instanceIdToLaunch.isEmpty())
- {
- m_peerInstance->sendMessage("activate", 2000);
- }
- else
- {
- m_peerInstance->sendMessage(m_instanceIdToLaunch, 2000);
- }
- m_status = MultiMC::Succeeded;
- return;
- }
- }
-
- // init the logger
- {
- static const QString logBase = "MultiMC-%0.log";
- auto moveFile = [](const QString &oldName, const QString &newName)
- {
- QFile::remove(newName);
- QFile::copy(oldName, newName);
- QFile::remove(oldName);
- };
-
- moveFile(logBase.arg(3), logBase.arg(4));
- moveFile(logBase.arg(2), logBase.arg(3));
- moveFile(logBase.arg(1), logBase.arg(2));
- moveFile(logBase.arg(0), logBase.arg(1));
-
- logFile = std::unique_ptr<QFile>(new QFile(logBase.arg(0)));
- if(!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
- {
- showFatalErrorMessage(
- "MultiMC data folder is not writable!",
- "MultiMC couldn't create a log file - the MultiMC data folder is not writable.\n"
- "\n"
- #if defined(Q_OS_MAC)
- MACOS_HINT
- #endif
- "Make sure you have write permissions to the MultiMC data folder.\n"
- "\n"
- "MultiMC cannot continue until you fix this problem."
- );
- return;
- }
- qInstallMessageHandler(appDebugOutput);
- qDebug() << "<> Log initialized.";
- }
-
- // Set up paths
- {
- // Root path is used for updates.
+ "Make sure you have the right permissions to the MultiMC data folder.\n"
+ "\n"
+ "MultiMC cannot continue until you fix this problem."
+ );
+ return;
+ }
+
+ /*
+ * Establish the mechanism for communication with an already running MultiMC that uses the same data path.
+ * If there is one, tell it what the user actually wanted to do and exit.
+ * We want to initialize this before logging to avoid messing with the log of a potential already running copy.
+ */
+ auto appID = ApplicationId::fromPathAndVersion(QDir::currentPath(), BuildConfig.printableVersionString());
+ {
+ // FIXME: you can run the same binaries with multiple data dirs and they won't clash. This could cause issues for updates.
+ m_peerInstance = new LocalPeer(this, appID);
+ connect(m_peerInstance, &LocalPeer::messageReceived, this, &MultiMC::messageReceived);
+ if(m_peerInstance->isClient())
+ {
+ if(m_instanceIdToLaunch.isEmpty())
+ {
+ m_peerInstance->sendMessage("activate", 2000);
+ }
+ else
+ {
+ m_peerInstance->sendMessage(m_instanceIdToLaunch, 2000);
+ }
+ m_status = MultiMC::Succeeded;
+ return;
+ }
+ }
+
+ // init the logger
+ {
+ static const QString logBase = "MultiMC-%0.log";
+ auto moveFile = [](const QString &oldName, const QString &newName)
+ {
+ QFile::remove(newName);
+ QFile::copy(oldName, newName);
+ QFile::remove(oldName);
+ };
+
+ moveFile(logBase.arg(3), logBase.arg(4));
+ moveFile(logBase.arg(2), logBase.arg(3));
+ moveFile(logBase.arg(1), logBase.arg(2));
+ moveFile(logBase.arg(0), logBase.arg(1));
+
+ logFile = std::unique_ptr<QFile>(new QFile(logBase.arg(0)));
+ if(!logFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
+ {
+ showFatalErrorMessage(
+ "MultiMC data folder is not writable!",
+ "MultiMC couldn't create a log file - the MultiMC data folder is not writable.\n"
+ "\n"
+ #if defined(Q_OS_MAC)
+ MACOS_HINT
+ #endif
+ "Make sure you have write permissions to the MultiMC data folder.\n"
+ "\n"
+ "MultiMC cannot continue until you fix this problem."
+ );
+ return;
+ }
+ qInstallMessageHandler(appDebugOutput);
+ qDebug() << "<> Log initialized.";
+ }
+
+ // Set up paths
+ {
+ // Root path is used for updates.
#ifdef Q_OS_LINUX
- QDir foo(FS::PathCombine(binPath, ".."));
- m_rootPath = foo.absolutePath();
+ QDir foo(FS::PathCombine(binPath, ".."));
+ m_rootPath = foo.absolutePath();
#elif defined(Q_OS_WIN32)
- m_rootPath = binPath;
+ m_rootPath = binPath;
#elif defined(Q_OS_MAC)
- QDir foo(FS::PathCombine(binPath, "../.."));
- m_rootPath = foo.absolutePath();
- // on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues)
- FS::updateTimestamp(m_rootPath);
+ QDir foo(FS::PathCombine(binPath, "../.."));
+ m_rootPath = foo.absolutePath();
+ // on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues)
+ FS::updateTimestamp(m_rootPath);
#endif
#ifdef MULTIMC_JARS_LOCATION
- ENV.setJarsPath( TOSTRING(MULTIMC_JARS_LOCATION) );
+ ENV.setJarsPath( TOSTRING(MULTIMC_JARS_LOCATION) );
#endif
- qDebug() << "MultiMC 5, (c) 2013-2018 MultiMC Contributors";
- qDebug() << "Version : " << BuildConfig.printableVersionString();
- qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT;
- qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC;
- if (adjustedBy.size())
- {
- qDebug() << "Work dir before adjustment : " << origcwdPath;
- qDebug() << "Work dir after adjustment : " << QDir::currentPath();
- qDebug() << "Adjusted by : " << adjustedBy;
- }
- else
- {
- qDebug() << "Work dir : " << QDir::currentPath();
- }
- qDebug() << "Binary path : " << binPath;
- qDebug() << "Application root path : " << m_rootPath;
- if(!m_instanceIdToLaunch.isEmpty())
- {
- qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch;
- }
- qDebug() << "<> Paths set.";
- }
-
- do // once
- {
- if(m_liveCheck)
- {
- QFile check(liveCheckFile);
- if(!check.open(QIODevice::WriteOnly | QIODevice::Truncate))
- {
- qWarning() << "Could not open" << liveCheckFile << "for writing!";
- break;
- }
- auto payload = appID.toString().toUtf8();
- if(check.write(payload) != payload.size())
- {
- qWarning() << "Could not write into" << liveCheckFile;
- check.remove();
- break;
- }
- check.close();
- }
- } while(false);
-
- // Initialize application settings
- {
- m_settings.reset(new INISettingsObject("multimc.cfg", this));
- // Updates
- m_settings->registerSetting("UpdateChannel", BuildConfig.VERSION_CHANNEL);
- m_settings->registerSetting("AutoUpdate", true);
-
- // Theming
- m_settings->registerSetting("IconTheme", QString("multimc"));
- m_settings->registerSetting("ApplicationTheme", QString("system"));
-
- // Notifications
- m_settings->registerSetting("ShownNotifications", QString());
-
- // Remembered state
- m_settings->registerSetting("LastUsedGroupForNewInstance", QString());
-
- QString defaultMonospace;
- int defaultSize = 11;
+ qDebug() << "MultiMC 5, (c) 2013-2018 MultiMC Contributors";
+ qDebug() << "Version : " << BuildConfig.printableVersionString();
+ qDebug() << "Git commit : " << BuildConfig.GIT_COMMIT;
+ qDebug() << "Git refspec : " << BuildConfig.GIT_REFSPEC;
+ if (adjustedBy.size())
+ {
+ qDebug() << "Work dir before adjustment : " << origcwdPath;
+ qDebug() << "Work dir after adjustment : " << QDir::currentPath();
+ qDebug() << "Adjusted by : " << adjustedBy;
+ }
+ else
+ {
+ qDebug() << "Work dir : " << QDir::currentPath();
+ }
+ qDebug() << "Binary path : " << binPath;
+ qDebug() << "Application root path : " << m_rootPath;
+ if(!m_instanceIdToLaunch.isEmpty())
+ {
+ qDebug() << "ID of instance to launch : " << m_instanceIdToLaunch;
+ }
+ qDebug() << "<> Paths set.";
+ }
+
+ do // once
+ {
+ if(m_liveCheck)
+ {
+ QFile check(liveCheckFile);
+ if(!check.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ {
+ qWarning() << "Could not open" << liveCheckFile << "for writing!";
+ break;
+ }
+ auto payload = appID.toString().toUtf8();
+ if(check.write(payload) != payload.size())
+ {
+ qWarning() << "Could not write into" << liveCheckFile;
+ check.remove();
+ break;
+ }
+ check.close();
+ }
+ } while(false);
+
+ // Initialize application settings
+ {
+ m_settings.reset(new INISettingsObject("multimc.cfg", this));
+ // Updates
+ m_settings->registerSetting("UpdateChannel", BuildConfig.VERSION_CHANNEL);
+ m_settings->registerSetting("AutoUpdate", true);
+
+ // Theming
+ m_settings->registerSetting("IconTheme", QString("multimc"));
+ m_settings->registerSetting("ApplicationTheme", QString("system"));
+
+ // Notifications
+ m_settings->registerSetting("ShownNotifications", QString());
+
+ // Remembered state
+ m_settings->registerSetting("LastUsedGroupForNewInstance", QString());
+
+ QString defaultMonospace;
+ int defaultSize = 11;
#ifdef Q_OS_WIN32
- defaultMonospace = "Courier";
- defaultSize = 10;
+ defaultMonospace = "Courier";
+ defaultSize = 10;
#elif defined(Q_OS_MAC)
- defaultMonospace = "Menlo";
+ defaultMonospace = "Menlo";
#else
- defaultMonospace = "Monospace";
+ defaultMonospace = "Monospace";
#endif
- // resolve the font so the default actually matches
- QFont consoleFont;
- consoleFont.setFamily(defaultMonospace);
- consoleFont.setStyleHint(QFont::Monospace);
- consoleFont.setFixedPitch(true);
- QFontInfo consoleFontInfo(consoleFont);
- QString resolvedDefaultMonospace = consoleFontInfo.family();
- QFont resolvedFont(resolvedDefaultMonospace);
- qDebug() << "Detected default console font:" << resolvedDefaultMonospace
- << ", substitutions:" << resolvedFont.substitutions().join(',');
-
- m_settings->registerSetting("ConsoleFont", resolvedDefaultMonospace);
- m_settings->registerSetting("ConsoleFontSize", defaultSize);
- m_settings->registerSetting("ConsoleMaxLines", 100000);
- m_settings->registerSetting("ConsoleOverflowStop", true);
-
- // Folders
- m_settings->registerSetting("InstanceDir", "instances");
- m_settings->registerSetting({"CentralModsDir", "ModsDir"}, "mods");
- m_settings->registerSetting("IconsDir", "icons");
-
- // Editors
- m_settings->registerSetting("JsonEditor", QString());
-
- // Language
- m_settings->registerSetting("Language", QString());
-
- // Console
- m_settings->registerSetting("ShowConsole", false);
- m_settings->registerSetting("AutoCloseConsole", false);
- m_settings->registerSetting("ShowConsoleOnError", true);
- m_settings->registerSetting("LogPrePostOutput", true);
-
- // Window Size
- m_settings->registerSetting({"LaunchMaximized", "MCWindowMaximize"}, false);
- m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854);
- m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480);
-
- // Proxy Settings
- m_settings->registerSetting("ProxyType", "None");
- m_settings->registerSetting({"ProxyAddr", "ProxyHostName"}, "127.0.0.1");
- m_settings->registerSetting("ProxyPort", 8080);
- m_settings->registerSetting({"ProxyUser", "ProxyUsername"}, "");
- m_settings->registerSetting({"ProxyPass", "ProxyPassword"}, "");
-
- // Memory
- m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512);
- m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 1024);
- m_settings->registerSetting("PermGen", 128);
-
- // Java Settings
- m_settings->registerSetting("JavaPath", "");
- m_settings->registerSetting("JavaTimestamp", 0);
- m_settings->registerSetting("JavaArchitecture", "");
- m_settings->registerSetting("JavaVersion", "");
- m_settings->registerSetting("LastHostname", "");
- m_settings->registerSetting("JvmArgs", "");
-
- // Minecraft launch method
- m_settings->registerSetting("MCLaunchMethod", "LauncherPart");
-
- // Wrapper command for launch
- m_settings->registerSetting("WrapperCommand", "");
-
- // Custom Commands
- m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, "");
- m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, "");
-
- // The cat
- m_settings->registerSetting("TheCat", false);
-
- m_settings->registerSetting("InstSortMode", "Name");
- m_settings->registerSetting("SelectedInstance", QString());
-
- // Window state and geometry
- m_settings->registerSetting("MainWindowState", "");
- m_settings->registerSetting("MainWindowGeometry", "");
-
- m_settings->registerSetting("ConsoleWindowState", "");
- m_settings->registerSetting("ConsoleWindowGeometry", "");
-
- m_settings->registerSetting("SettingsGeometry", "");
-
- m_settings->registerSetting("PagedGeometry", "");
-
- m_settings->registerSetting("NewInstanceGeometry", "");
-
- m_settings->registerSetting("UpdateDialogGeometry", "");
-
- // paste.ee API key
- m_settings->registerSetting("PasteEEAPIKey", "multimc");
-
- if(!BuildConfig.ANALYTICS_ID.isEmpty())
- {
- // Analytics
- m_settings->registerSetting("Analytics", true);
- m_settings->registerSetting("AnalyticsSeen", 0);
- m_settings->registerSetting("AnalyticsClientID", QString());
- }
-
- // Init page provider
- {
- m_globalSettingsProvider = std::make_shared<GenericPageProvider>(tr("Settings"));
- m_globalSettingsProvider->addPage<MultiMCPage>();
- m_globalSettingsProvider->addPage<MinecraftPage>();
- m_globalSettingsProvider->addPage<JavaPage>();
- m_globalSettingsProvider->addPage<CustomCommandsPage>();
- m_globalSettingsProvider->addPage<ProxyPage>();
- // m_globalSettingsProvider->addPage<PackagesPage>();
- m_globalSettingsProvider->addPage<ExternalToolsPage>();
- m_globalSettingsProvider->addPage<AccountListPage>();
- m_globalSettingsProvider->addPage<PasteEEPage>();
- }
- qDebug() << "<> Settings loaded.";
- }
-
- // load translations
- {
- m_translations.reset(new TranslationsModel("translations"));
- auto bcp47Name = m_settings->get("Language").toString();
- m_translations->selectLanguage(bcp47Name);
- qDebug() << "Your language is" << bcp47Name;
- qDebug() << "<> Translations loaded.";
- }
-
- // initialize the updater
- if(BuildConfig.UPDATER_ENABLED)
- {
- m_updateChecker.reset(new UpdateChecker(BuildConfig.CHANLIST_URL, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD));
- qDebug() << "<> Updater started.";
- }
-
- // Instance icons
- {
- auto setting = MMC->settings()->getSetting("IconsDir");
- QStringList instFolders =
- {
- ":/icons/multimc/32x32/instances/",
- ":/icons/multimc/50x50/instances/",
- ":/icons/multimc/128x128/instances/"
- };
- m_icons.reset(new IconList(instFolders, setting->get().toString()));
- connect(setting.get(), &Setting::SettingChanged,[&](const Setting &, QVariant value)
- {
- m_icons->directoryChanged(value.toString());
- });
- ENV.registerIconList(m_icons);
- qDebug() << "<> Instance icons intialized.";
- }
-
- // Icon themes
- {
- // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies!
- // set icon theme search path!
- auto searchPaths = QIcon::themeSearchPaths();
- searchPaths.append("iconthemes");
- QIcon::setThemeSearchPaths(searchPaths);
- qDebug() << "<> Icon themes initialized.";
- }
-
- // Initialize widget themes
- {
- auto insertTheme = [this](ITheme * theme)
- {
- m_themes.insert(std::make_pair(theme->id(), std::unique_ptr<ITheme>(theme)));
- };
- auto darkTheme = new DarkTheme();
- insertTheme(new SystemTheme());
- insertTheme(darkTheme);
- insertTheme(new BrightTheme());
- insertTheme(new CustomTheme(darkTheme, "custom"));
- qDebug() << "<> Widget themes initialized.";
- }
-
- // initialize and load all instances
- {
- auto InstDirSetting = m_settings->getSetting("InstanceDir");
- // instance path: check for problems with '!' in instance path and warn the user in the log
- // and rememer that we have to show him a dialog when the gui starts (if it does so)
- QString instDir = InstDirSetting->get().toString();
- qDebug() << "Instance path : " << instDir;
- if (FS::checkProblemticPathJava(QDir(instDir)))
- {
- qWarning() << "Your instance path contains \'!\' and this is known to cause java problems";
- }
- m_instances.reset(new InstanceList(this));
- m_instanceFolder = new FolderInstanceProvider(m_settings, instDir);
- connect(InstDirSetting.get(), &Setting::SettingChanged, m_instanceFolder, &FolderInstanceProvider::on_InstFolderChanged);
- m_instances->addInstanceProvider(m_instanceFolder);
- qDebug() << "Loading Instances...";
- m_instances->loadList(true);
- qDebug() << "<> Instances loaded.";
- }
-
- // and accounts
- {
- m_accounts.reset(new MojangAccountList(this));
- qDebug() << "Loading accounts...";
- m_accounts->setListFilePath("accounts.json", true);
- m_accounts->loadList();
- qDebug() << "<> Accounts loaded.";
- }
-
- // init the http meta cache
- {
- ENV.initHttpMetaCache();
- qDebug() << "<> Cache initialized.";
- }
-
- // init proxy settings
- {
- QString proxyTypeStr = settings()->get("ProxyType").toString();
- QString addr = settings()->get("ProxyAddr").toString();
- int port = settings()->get("ProxyPort").value<qint16>();
- QString user = settings()->get("ProxyUser").toString();
- QString pass = settings()->get("ProxyPass").toString();
- ENV.updateProxySettings(proxyTypeStr, addr, port, user, pass);
- qDebug() << "<> Proxy settings done.";
- }
-
- // now we have network, download translation updates
- m_translations->downloadIndex();
-
- //FIXME: what to do with these?
- m_profilers.insert("jprofiler", std::shared_ptr<BaseProfilerFactory>(new JProfilerFactory()));
- m_profilers.insert("jvisualvm", std::shared_ptr<BaseProfilerFactory>(new JVisualVMFactory()));
- for (auto profiler : m_profilers.values())
- {
- profiler->registerSettings(m_settings);
- }
-
- // Create the MCEdit thing... why is this here?
- {
- m_mcedit.reset(new MCEditTool(m_settings));
- }
-
- connect(this, &MultiMC::aboutToQuit, [this](){
- if(m_instances)
- {
- // save any remaining instance state
- m_instances->saveNow();
- }
- if(logFile)
- {
- logFile->flush();
- logFile->close();
- }
- });
-
- {
- setIconTheme(settings()->get("IconTheme").toString());
- qDebug() << "<> Icon theme set.";
- setApplicationTheme(settings()->get("ApplicationTheme").toString(), true);
- qDebug() << "<> Application theme set.";
- }
-
- // Initialize analytics
- [this]()
- {
- const int analyticsVersion = 2;
- if(BuildConfig.ANALYTICS_ID.isEmpty())
- {
- return;
- }
-
- auto analyticsSetting = m_settings->getSetting("Analytics");
- connect(analyticsSetting.get(), &Setting::SettingChanged, this, &MultiMC::analyticsSettingChanged);
- QString clientID = m_settings->get("AnalyticsClientID").toString();
- if(clientID.isEmpty())
- {
- clientID = QUuid::createUuid().toString();
- clientID.remove(QLatin1Char('{'));
- clientID.remove(QLatin1Char('}'));
- m_settings->set("AnalyticsClientID", clientID);
- }
- m_analytics = new GAnalytics(BuildConfig.ANALYTICS_ID, clientID, analyticsVersion, this);
- m_analytics->setLogLevel(GAnalytics::Debug);
- m_analytics->setAnonymizeIPs(true);
- m_analytics->setNetworkAccessManager(&ENV.qnam());
-
- if(m_settings->get("AnalyticsSeen").toInt() < m_analytics->version())
- {
- qDebug() << "Analytics info not seen by user yet (or old version).";
- return;
- }
- if(!m_settings->get("Analytics").toBool())
- {
- qDebug() << "Analytics disabled by user.";
- return;
- }
-
- m_analytics->enable();
- qDebug() << "<> Initialized analytics with tid" << BuildConfig.ANALYTICS_ID;
- }();
-
- if(createSetupWizard())
- {
- return;
- }
- performMainStartupAction();
+ // resolve the font so the default actually matches
+ QFont consoleFont;
+ consoleFont.setFamily(defaultMonospace);
+ consoleFont.setStyleHint(QFont::Monospace);
+ consoleFont.setFixedPitch(true);
+ QFontInfo consoleFontInfo(consoleFont);
+ QString resolvedDefaultMonospace = consoleFontInfo.family();
+ QFont resolvedFont(resolvedDefaultMonospace);
+ qDebug() << "Detected default console font:" << resolvedDefaultMonospace
+ << ", substitutions:" << resolvedFont.substitutions().join(',');
+
+ m_settings->registerSetting("ConsoleFont", resolvedDefaultMonospace);
+ m_settings->registerSetting("ConsoleFontSize", defaultSize);
+ m_settings->registerSetting("ConsoleMaxLines", 100000);
+ m_settings->registerSetting("ConsoleOverflowStop", true);
+
+ // Folders
+ m_settings->registerSetting("InstanceDir", "instances");
+ m_settings->registerSetting({"CentralModsDir", "ModsDir"}, "mods");
+ m_settings->registerSetting("IconsDir", "icons");
+
+ // Editors
+ m_settings->registerSetting("JsonEditor", QString());
+
+ // Language
+ m_settings->registerSetting("Language", QString());
+
+ // Console
+ m_settings->registerSetting("ShowConsole", false);
+ m_settings->registerSetting("AutoCloseConsole", false);
+ m_settings->registerSetting("ShowConsoleOnError", true);
+ m_settings->registerSetting("LogPrePostOutput", true);
+
+ // Window Size
+ m_settings->registerSetting({"LaunchMaximized", "MCWindowMaximize"}, false);
+ m_settings->registerSetting({"MinecraftWinWidth", "MCWindowWidth"}, 854);
+ m_settings->registerSetting({"MinecraftWinHeight", "MCWindowHeight"}, 480);
+
+ // Proxy Settings
+ m_settings->registerSetting("ProxyType", "None");
+ m_settings->registerSetting({"ProxyAddr", "ProxyHostName"}, "127.0.0.1");
+ m_settings->registerSetting("ProxyPort", 8080);
+ m_settings->registerSetting({"ProxyUser", "ProxyUsername"}, "");
+ m_settings->registerSetting({"ProxyPass", "ProxyPassword"}, "");
+
+ // Memory
+ m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512);
+ m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 1024);
+ m_settings->registerSetting("PermGen", 128);
+
+ // Java Settings
+ m_settings->registerSetting("JavaPath", "");
+ m_settings->registerSetting("JavaTimestamp", 0);
+ m_settings->registerSetting("JavaArchitecture", "");
+ m_settings->registerSetting("JavaVersion", "");
+ m_settings->registerSetting("LastHostname", "");
+ m_settings->registerSetting("JvmArgs", "");
+
+ // Minecraft launch method
+ m_settings->registerSetting("MCLaunchMethod", "LauncherPart");
+
+ // Wrapper command for launch
+ m_settings->registerSetting("WrapperCommand", "");
+
+ // Custom Commands
+ m_settings->registerSetting({"PreLaunchCommand", "PreLaunchCmd"}, "");
+ m_settings->registerSetting({"PostExitCommand", "PostExitCmd"}, "");
+
+ // The cat
+ m_settings->registerSetting("TheCat", false);
+
+ m_settings->registerSetting("InstSortMode", "Name");
+ m_settings->registerSetting("SelectedInstance", QString());
+
+ // Window state and geometry
+ m_settings->registerSetting("MainWindowState", "");
+ m_settings->registerSetting("MainWindowGeometry", "");
+
+ m_settings->registerSetting("ConsoleWindowState", "");
+ m_settings->registerSetting("ConsoleWindowGeometry", "");
+
+ m_settings->registerSetting("SettingsGeometry", "");
+
+ m_settings->registerSetting("PagedGeometry", "");
+
+ m_settings->registerSetting("NewInstanceGeometry", "");
+
+ m_settings->registerSetting("UpdateDialogGeometry", "");
+
+ // paste.ee API key
+ m_settings->registerSetting("PasteEEAPIKey", "multimc");
+
+ if(!BuildConfig.ANALYTICS_ID.isEmpty())
+ {
+ // Analytics
+ m_settings->registerSetting("Analytics", true);
+ m_settings->registerSetting("AnalyticsSeen", 0);
+ m_settings->registerSetting("AnalyticsClientID", QString());
+ }
+
+ // Init page provider
+ {
+ m_globalSettingsProvider = std::make_shared<GenericPageProvider>(tr("Settings"));
+ m_globalSettingsProvider->addPage<MultiMCPage>();
+ m_globalSettingsProvider->addPage<MinecraftPage>();
+ m_globalSettingsProvider->addPage<JavaPage>();
+ m_globalSettingsProvider->addPage<CustomCommandsPage>();
+ m_globalSettingsProvider->addPage<ProxyPage>();
+ // m_globalSettingsProvider->addPage<PackagesPage>();
+ m_globalSettingsProvider->addPage<ExternalToolsPage>();
+ m_globalSettingsProvider->addPage<AccountListPage>();
+ m_globalSettingsProvider->addPage<PasteEEPage>();
+ }
+ qDebug() << "<> Settings loaded.";
+ }
+
+ // load translations
+ {
+ m_translations.reset(new TranslationsModel("translations"));
+ auto bcp47Name = m_settings->get("Language").toString();
+ m_translations->selectLanguage(bcp47Name);
+ qDebug() << "Your language is" << bcp47Name;
+ qDebug() << "<> Translations loaded.";
+ }
+
+ // initialize the updater
+ if(BuildConfig.UPDATER_ENABLED)
+ {
+ m_updateChecker.reset(new UpdateChecker(BuildConfig.CHANLIST_URL, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD));
+ qDebug() << "<> Updater started.";
+ }
+
+ // Instance icons
+ {
+ auto setting = MMC->settings()->getSetting("IconsDir");
+ QStringList instFolders =
+ {
+ ":/icons/multimc/32x32/instances/",
+ ":/icons/multimc/50x50/instances/",
+ ":/icons/multimc/128x128/instances/"
+ };
+ m_icons.reset(new IconList(instFolders, setting->get().toString()));
+ connect(setting.get(), &Setting::SettingChanged,[&](const Setting &, QVariant value)
+ {
+ m_icons->directoryChanged(value.toString());
+ });
+ ENV.registerIconList(m_icons);
+ qDebug() << "<> Instance icons intialized.";
+ }
+
+ // Icon themes
+ {
+ // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies!
+ // set icon theme search path!
+ auto searchPaths = QIcon::themeSearchPaths();
+ searchPaths.append("iconthemes");
+ QIcon::setThemeSearchPaths(searchPaths);
+ qDebug() << "<> Icon themes initialized.";
+ }
+
+ // Initialize widget themes
+ {
+ auto insertTheme = [this](ITheme * theme)
+ {
+ m_themes.insert(std::make_pair(theme->id(), std::unique_ptr<ITheme>(theme)));
+ };
+ auto darkTheme = new DarkTheme();
+ insertTheme(new SystemTheme());
+ insertTheme(darkTheme);
+ insertTheme(new BrightTheme());
+ insertTheme(new CustomTheme(darkTheme, "custom"));
+ qDebug() << "<> Widget themes initialized.";
+ }
+
+ // initialize and load all instances
+ {
+ auto InstDirSetting = m_settings->getSetting("InstanceDir");
+ // instance path: check for problems with '!' in instance path and warn the user in the log
+ // and rememer that we have to show him a dialog when the gui starts (if it does so)
+ QString instDir = InstDirSetting->get().toString();
+ qDebug() << "Instance path : " << instDir;
+ if (FS::checkProblemticPathJava(QDir(instDir)))
+ {
+ qWarning() << "Your instance path contains \'!\' and this is known to cause java problems";
+ }
+ m_instances.reset(new InstanceList(this));
+ m_instanceFolder = new FolderInstanceProvider(m_settings, instDir);
+ connect(InstDirSetting.get(), &Setting::SettingChanged, m_instanceFolder, &FolderInstanceProvider::on_InstFolderChanged);
+ m_instances->addInstanceProvider(m_instanceFolder);
+ qDebug() << "Loading Instances...";
+ m_instances->loadList(true);
+ qDebug() << "<> Instances loaded.";
+ }
+
+ // and accounts
+ {
+ m_accounts.reset(new MojangAccountList(this));
+ qDebug() << "Loading accounts...";
+ m_accounts->setListFilePath("accounts.json", true);
+ m_accounts->loadList();
+ qDebug() << "<> Accounts loaded.";
+ }
+
+ // init the http meta cache
+ {
+ ENV.initHttpMetaCache();
+ qDebug() << "<> Cache initialized.";
+ }
+
+ // init proxy settings
+ {
+ QString proxyTypeStr = settings()->get("ProxyType").toString();
+ QString addr = settings()->get("ProxyAddr").toString();
+ int port = settings()->get("ProxyPort").value<qint16>();
+ QString user = settings()->get("ProxyUser").toString();
+ QString pass = settings()->get("ProxyPass").toString();
+ ENV.updateProxySettings(proxyTypeStr, addr, port, user, pass);
+ qDebug() << "<> Proxy settings done.";
+ }
+
+ // now we have network, download translation updates
+ m_translations->downloadIndex();
+
+ //FIXME: what to do with these?
+ m_profilers.insert("jprofiler", std::shared_ptr<BaseProfilerFactory>(new JProfilerFactory()));
+ m_profilers.insert("jvisualvm", std::shared_ptr<BaseProfilerFactory>(new JVisualVMFactory()));
+ for (auto profiler : m_profilers.values())
+ {
+ profiler->registerSettings(m_settings);
+ }
+
+ // Create the MCEdit thing... why is this here?
+ {
+ m_mcedit.reset(new MCEditTool(m_settings));
+ }
+
+ connect(this, &MultiMC::aboutToQuit, [this](){
+ if(m_instances)
+ {
+ // save any remaining instance state
+ m_instances->saveNow();
+ }
+ if(logFile)
+ {
+ logFile->flush();
+ logFile->close();
+ }
+ });
+
+ {
+ setIconTheme(settings()->get("IconTheme").toString());
+ qDebug() << "<> Icon theme set.";
+ setApplicationTheme(settings()->get("ApplicationTheme").toString(), true);
+ qDebug() << "<> Application theme set.";
+ }
+
+ // Initialize analytics
+ [this]()
+ {
+ const int analyticsVersion = 2;
+ if(BuildConfig.ANALYTICS_ID.isEmpty())
+ {
+ return;
+ }
+
+ auto analyticsSetting = m_settings->getSetting("Analytics");
+ connect(analyticsSetting.get(), &Setting::SettingChanged, this, &MultiMC::analyticsSettingChanged);
+ QString clientID = m_settings->get("AnalyticsClientID").toString();
+ if(clientID.isEmpty())
+ {
+ clientID = QUuid::createUuid().toString();
+ clientID.remove(QLatin1Char('{'));
+ clientID.remove(QLatin1Char('}'));
+ m_settings->set("AnalyticsClientID", clientID);
+ }
+ m_analytics = new GAnalytics(BuildConfig.ANALYTICS_ID, clientID, analyticsVersion, this);
+ m_analytics->setLogLevel(GAnalytics::Debug);
+ m_analytics->setAnonymizeIPs(true);
+ m_analytics->setNetworkAccessManager(&ENV.qnam());
+
+ if(m_settings->get("AnalyticsSeen").toInt() < m_analytics->version())
+ {
+ qDebug() << "Analytics info not seen by user yet (or old version).";
+ return;
+ }
+ if(!m_settings->get("Analytics").toBool())
+ {
+ qDebug() << "Analytics disabled by user.";
+ return;
+ }
+
+ m_analytics->enable();
+ qDebug() << "<> Initialized analytics with tid" << BuildConfig.ANALYTICS_ID;
+ }();
+
+ if(createSetupWizard())
+ {
+ return;
+ }
+ performMainStartupAction();
}
bool MultiMC::createSetupWizard()
{
- bool javaRequired = [&]()
- {
- QString currentHostName = QHostInfo::localHostName();
- QString oldHostName = settings()->get("LastHostname").toString();
- if (currentHostName != oldHostName)
- {
- settings()->set("LastHostname", currentHostName);
- return true;
- }
- QString currentJavaPath = settings()->get("JavaPath").toString();
- QString actualPath = FS::ResolveExecutable(currentJavaPath);
- if (actualPath.isNull())
- {
- return true;
- }
- return false;
- }();
- bool analyticsRequired = [&]()
- {
- if(BuildConfig.ANALYTICS_ID.isEmpty())
- {
- return false;
- }
- if (!settings()->get("Analytics").toBool())
- {
- return false;
- }
- if (settings()->get("AnalyticsSeen").toInt() < analytics()->version())
- {
- return true;
- }
- return false;
- }();
- bool languageRequired = [&]()
- {
- if (settings()->get("Language").toString().isEmpty())
- return true;
- return false;
- }();
- bool wizardRequired = javaRequired || analyticsRequired || languageRequired;
-
- if(wizardRequired)
- {
- m_setupWizard = new SetupWizard(nullptr);
- if (languageRequired)
- {
- m_setupWizard->addPage(new LanguageWizardPage(m_setupWizard));
- }
- if (javaRequired)
- {
- m_setupWizard->addPage(new JavaWizardPage(m_setupWizard));
- }
- if(analyticsRequired)
- {
- m_setupWizard->addPage(new AnalyticsWizardPage(m_setupWizard));
- }
- connect(m_setupWizard, &QDialog::finished, this, &MultiMC::setupWizardFinished);
- m_setupWizard->show();
- return true;
- }
- return false;
+ bool javaRequired = [&]()
+ {
+ QString currentHostName = QHostInfo::localHostName();
+ QString oldHostName = settings()->get("LastHostname").toString();
+ if (currentHostName != oldHostName)
+ {
+ settings()->set("LastHostname", currentHostName);
+ return true;
+ }
+ QString currentJavaPath = settings()->get("JavaPath").toString();
+ QString actualPath = FS::ResolveExecutable(currentJavaPath);
+ if (actualPath.isNull())
+ {
+ return true;
+ }
+ return false;
+ }();
+ bool analyticsRequired = [&]()
+ {
+ if(BuildConfig.ANALYTICS_ID.isEmpty())
+ {
+ return false;
+ }
+ if (!settings()->get("Analytics").toBool())
+ {
+ return false;
+ }
+ if (settings()->get("AnalyticsSeen").toInt() < analytics()->version())
+ {
+ return true;
+ }
+ return false;
+ }();
+ bool languageRequired = [&]()
+ {
+ if (settings()->get("Language").toString().isEmpty())
+ return true;
+ return false;
+ }();
+ bool wizardRequired = javaRequired || analyticsRequired || languageRequired;
+
+ if(wizardRequired)
+ {
+ m_setupWizard = new SetupWizard(nullptr);
+ if (languageRequired)
+ {
+ m_setupWizard->addPage(new LanguageWizardPage(m_setupWizard));
+ }
+ if (javaRequired)
+ {
+ m_setupWizard->addPage(new JavaWizardPage(m_setupWizard));
+ }
+ if(analyticsRequired)
+ {
+ m_setupWizard->addPage(new AnalyticsWizardPage(m_setupWizard));
+ }
+ connect(m_setupWizard, &QDialog::finished, this, &MultiMC::setupWizardFinished);
+ m_setupWizard->show();
+ return true;
+ }
+ return false;
}
void MultiMC::setupWizardFinished(int status)
{
- qDebug() << "Wizard result =" << status;
- performMainStartupAction();
+ qDebug() << "Wizard result =" << status;
+ performMainStartupAction();
}
void MultiMC::performMainStartupAction()
{
- m_status = MultiMC::Initialized;
- if(!m_instanceIdToLaunch.isEmpty())
- {
- auto inst = instances()->getInstanceById(m_instanceIdToLaunch);
- if(inst)
- {
- qDebug() << "<> Instance launching:" << m_instanceIdToLaunch;
- launch(inst, true, nullptr);
- return;
- }
- }
- if(!m_mainWindow)
- {
- // normal main window
- showMainWindow(false);
- qDebug() << "<> Main window shown.";
- }
+ m_status = MultiMC::Initialized;
+ if(!m_instanceIdToLaunch.isEmpty())
+ {
+ auto inst = instances()->getInstanceById(m_instanceIdToLaunch);
+ if(inst)
+ {
+ qDebug() << "<> Instance launching:" << m_instanceIdToLaunch;
+ launch(inst, true, nullptr);
+ return;
+ }
+ }
+ if(!m_mainWindow)
+ {
+ // normal main window
+ showMainWindow(false);
+ qDebug() << "<> Main window shown.";
+ }
}
void MultiMC::showFatalErrorMessage(const QString& title, const QString& content)
{
- m_status = MultiMC::Failed;
- auto dialog = CustomMessageBox::selectable(nullptr, title, content, QMessageBox::Critical);
- dialog->exec();
+ m_status = MultiMC::Failed;
+ auto dialog = CustomMessageBox::selectable(nullptr, title, content, QMessageBox::Critical);
+ dialog->exec();
}
MultiMC::~MultiMC()
{
- // kill the other globals.
- Env::dispose();
+ // kill the other globals.
+ Env::dispose();
- // Shut down logger by setting the logger function to nothing
- qInstallMessageHandler(nullptr);
+ // Shut down logger by setting the logger function to nothing
+ qInstallMessageHandler(nullptr);
#if defined Q_OS_WIN32
- // Detach from Windows console
- if(consoleAttached)
- {
- fclose(stdout);
- fclose(stdin);
- fclose(stderr);
- FreeConsole();
- }
+ // Detach from Windows console
+ if(consoleAttached)
+ {
+ fclose(stdout);
+ fclose(stdin);
+ fclose(stderr);
+ FreeConsole();
+ }
#endif
}
void MultiMC::messageReceived(const QString& message)
{
- if(status() != Initialized)
- {
- qDebug() << "Received message" << message << "while still initializing. It will be ignored.";
- return;
- }
- if(message == "activate")
- {
- showMainWindow();
- }
- else
- {
- auto inst = instances()->getInstanceById(message);
- if(inst)
- {
- launch(inst, true, nullptr);
- }
- }
+ if(status() != Initialized)
+ {
+ qDebug() << "Received message" << message << "while still initializing. It will be ignored.";
+ return;
+ }
+ if(message == "activate")
+ {
+ showMainWindow();
+ }
+ else
+ {
+ auto inst = instances()->getInstanceById(message);
+ if(inst)
+ {
+ launch(inst, true, nullptr);
+ }
+ }
}
void MultiMC::analyticsSettingChanged(const Setting&, QVariant value)
{
- if(!m_analytics)
- return;
- bool enabled = value.toBool();
- if(enabled)
- {
- qDebug() << "Analytics enabled by user.";
- }
- else
- {
- qDebug() << "Analytics disabled by user.";
- }
- m_analytics->enable(enabled);
+ if(!m_analytics)
+ return;
+ bool enabled = value.toBool();
+ if(enabled)
+ {
+ qDebug() << "Analytics enabled by user.";
+ }
+ else
+ {
+ qDebug() << "Analytics disabled by user.";
+ }
+ m_analytics->enable(enabled);
}
std::shared_ptr<TranslationsModel> MultiMC::translations()
{
- return m_translations;
+ return m_translations;
}
std::shared_ptr<JavaInstallList> MultiMC::javalist()
{
- if (!m_javalist)
- {
- m_javalist.reset(new JavaInstallList());
- }
- return m_javalist;
+ if (!m_javalist)
+ {
+ m_javalist.reset(new JavaInstallList());
+ }
+ return m_javalist;
}
std::vector<ITheme *> MultiMC::getValidApplicationThemes()
{
- std::vector<ITheme *> ret;
- auto iter = m_themes.cbegin();
- while (iter != m_themes.cend())
- {
- ret.push_back((*iter).second.get());
- iter++;
- }
- return ret;
+ std::vector<ITheme *> ret;
+ auto iter = m_themes.cbegin();
+ while (iter != m_themes.cend())
+ {
+ ret.push_back((*iter).second.get());
+ iter++;
+ }
+ return ret;
}
void MultiMC::setApplicationTheme(const QString& name, bool initial)
{
- auto systemPalette = qApp->palette();
- auto themeIter = m_themes.find(name);
- if(themeIter != m_themes.end())
- {
- auto & theme = (*themeIter).second;
- theme->apply(initial);
- }
- else
- {
- qWarning() << "Tried to set invalid theme:" << name;
- }
+ auto systemPalette = qApp->palette();
+ auto themeIter = m_themes.find(name);
+ if(themeIter != m_themes.end())
+ {
+ auto & theme = (*themeIter).second;
+ theme->apply(initial);
+ }
+ else
+ {
+ qWarning() << "Tried to set invalid theme:" << name;
+ }
}
void MultiMC::setIconTheme(const QString& name)
{
- XdgIcon::setThemeName(name);
+ XdgIcon::setThemeName(name);
}
QIcon MultiMC::getThemedIcon(const QString& name)
{
- return XdgIcon::fromTheme(name);
+ return XdgIcon::fromTheme(name);
}
bool MultiMC::openJsonEditor(const QString &filename)
{
- const QString file = QDir::current().absoluteFilePath(filename);
- if (m_settings->get("JsonEditor").toString().isEmpty())
- {
- return DesktopServices::openUrl(QUrl::fromLocalFile(file));
- }
- else
- {
- //return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file);
- return DesktopServices::run(m_settings->get("JsonEditor").toString(), {file});
- }
+ const QString file = QDir::current().absoluteFilePath(filename);
+ if (m_settings->get("JsonEditor").toString().isEmpty())
+ {
+ return DesktopServices::openUrl(QUrl::fromLocalFile(file));
+ }
+ else
+ {
+ //return DesktopServices::openFile(m_settings->get("JsonEditor").toString(), file);
+ return DesktopServices::run(m_settings->get("JsonEditor").toString(), {file});
+ }
}
bool MultiMC::launch(InstancePtr instance, bool online, BaseProfilerFactory *profiler)
{
- if(m_updateRunning)
- {
- qDebug() << "Cannot launch instances while an update is running.";
- }
- else if(instance->canLaunch())
- {
- auto & extras = m_instanceExtras[instance->id()];
- auto & window = extras.window;
- if(window)
- {
- if(!window->saveAll())
- {
- return false;
- }
- }
- auto & controller = extras.controller;
- controller.reset(new LaunchController());
- controller->setInstance(instance);
- controller->setOnline(online);
- controller->setProfiler(profiler);
- if(window)
- {
- controller->setParentWidget(window);
- }
- else if(m_mainWindow)
- {
- controller->setParentWidget(m_mainWindow);
- }
- connect(controller.get(), &LaunchController::succeeded, this, &MultiMC::controllerSucceeded);
- connect(controller.get(), &LaunchController::failed, this, &MultiMC::controllerFailed);
- addRunningInstance();
- controller->start();
- return true;
- }
- else if (instance->isRunning())
- {
- showInstanceWindow(instance, "console");
- return true;
- }
- else if (instance->canEdit())
- {
- showInstanceWindow(instance);
- return true;
- }
- return false;
+ if(m_updateRunning)
+ {
+ qDebug() << "Cannot launch instances while an update is running.";
+ }
+ else if(instance->canLaunch())
+ {
+ auto & extras = m_instanceExtras[instance->id()];
+ auto & window = extras.window;
+ if(window)
+ {
+ if(!window->saveAll())
+ {
+ return false;
+ }
+ }
+ auto & controller = extras.controller;
+ controller.reset(new LaunchController());
+ controller->setInstance(instance);
+ controller->setOnline(online);
+ controller->setProfiler(profiler);
+ if(window)
+ {
+ controller->setParentWidget(window);
+ }
+ else if(m_mainWindow)
+ {
+ controller->setParentWidget(m_mainWindow);
+ }
+ connect(controller.get(), &LaunchController::succeeded, this, &MultiMC::controllerSucceeded);
+ connect(controller.get(), &LaunchController::failed, this, &MultiMC::controllerFailed);
+ addRunningInstance();
+ controller->start();
+ return true;
+ }
+ else if (instance->isRunning())
+ {
+ showInstanceWindow(instance, "console");
+ return true;
+ }
+ else if (instance->canEdit())
+ {
+ showInstanceWindow(instance);
+ return true;
+ }
+ return false;
}
bool MultiMC::kill(InstancePtr instance)
{
- if (!instance->isRunning())
- {
- qWarning() << "Attempted to kill instance" << instance->id() << "which isn't running.";
- return false;
- }
- auto & extras = m_instanceExtras[instance->id()];
- // NOTE: copy of the shared pointer keeps it alive
- auto controller = extras.controller;
- if(controller)
- {
- return controller->abort();
- }
- return true;
+ if (!instance->isRunning())
+ {
+ qWarning() << "Attempted to kill instance" << instance->id() << "which isn't running.";
+ return false;
+ }
+ auto & extras = m_instanceExtras[instance->id()];
+ // NOTE: copy of the shared pointer keeps it alive
+ auto controller = extras.controller;
+ if(controller)
+ {
+ return controller->abort();
+ }
+ return true;
}
void MultiMC::addRunningInstance()
{
- m_runningInstances ++;
- if(m_runningInstances == 1)
- {
- emit updateAllowedChanged(false);
- }
+ m_runningInstances ++;
+ if(m_runningInstances == 1)
+ {
+ emit updateAllowedChanged(false);
+ }
}
void MultiMC::subRunningInstance()
{
- if(m_runningInstances == 0)
- {
- qCritical() << "Something went really wrong and we now have less than 0 running instances... WTF";
- return;
- }
- m_runningInstances --;
- if(m_runningInstances == 0)
- {
- emit updateAllowedChanged(true);
- }
+ if(m_runningInstances == 0)
+ {
+ qCritical() << "Something went really wrong and we now have less than 0 running instances... WTF";
+ return;
+ }
+ m_runningInstances --;
+ if(m_runningInstances == 0)
+ {
+ emit updateAllowedChanged(true);
+ }
}
bool MultiMC::shouldExitNow() const
{
- return m_runningInstances == 0 && m_openWindows == 0;
+ return m_runningInstances == 0 && m_openWindows == 0;
}
bool MultiMC::updatesAreAllowed()
{
- return m_runningInstances == 0;
+ return m_runningInstances == 0;
}
void MultiMC::updateIsRunning(bool running)
{
- m_updateRunning = running;
+ m_updateRunning = running;
}
void MultiMC::controllerSucceeded()
{
- auto controller = qobject_cast<LaunchController *>(QObject::sender());
- if(!controller)
- return;
- auto id = controller->id();
- auto & extras = m_instanceExtras[id];
-
- // on success, do...
- if (controller->instance()->settings()->get("AutoCloseConsole").toBool())
- {
- if(extras.window)
- {
- extras.window->close();
- }
- }
- extras.controller.reset();
- subRunningInstance();
-
- // quit when there are no more windows.
- if(shouldExitNow())
- {
- m_status = Status::Succeeded;
- exit(0);
- }
+ auto controller = qobject_cast<LaunchController *>(QObject::sender());
+ if(!controller)
+ return;
+ auto id = controller->id();
+ auto & extras = m_instanceExtras[id];
+
+ // on success, do...
+ if (controller->instance()->settings()->get("AutoCloseConsole").toBool())
+ {
+ if(extras.window)
+ {
+ extras.window->close();
+ }
+ }
+ extras.controller.reset();
+ subRunningInstance();
+
+ // quit when there are no more windows.
+ if(shouldExitNow())
+ {
+ m_status = Status::Succeeded;
+ exit(0);
+ }
}
void MultiMC::controllerFailed(const QString& error)
{
- Q_UNUSED(error);
- auto controller = qobject_cast<LaunchController *>(QObject::sender());
- if(!controller)
- return;
- auto id = controller->id();
- auto & extras = m_instanceExtras[id];
-
- // on failure, do... nothing
- extras.controller.reset();
- subRunningInstance();
-
- // quit when there are no more windows.
- if(shouldExitNow())
- {
- m_status = Status::Failed;
- exit(1);
- }
+ Q_UNUSED(error);
+ auto controller = qobject_cast<LaunchController *>(QObject::sender());
+ if(!controller)
+ return;
+ auto id = controller->id();
+ auto & extras = m_instanceExtras[id];
+
+ // on failure, do... nothing
+ extras.controller.reset();
+ subRunningInstance();
+
+ // quit when there are no more windows.
+ if(shouldExitNow())
+ {
+ m_status = Status::Failed;
+ exit(1);
+ }
}
MainWindow* MultiMC::showMainWindow(bool minimized)
{
- if(m_mainWindow)
- {
- m_mainWindow->setWindowState(m_mainWindow->windowState() & ~Qt::WindowMinimized);
- m_mainWindow->raise();
- m_mainWindow->activateWindow();
- }
- else
- {
- m_mainWindow = new MainWindow();
- m_mainWindow->restoreState(QByteArray::fromBase64(MMC->settings()->get("MainWindowState").toByteArray()));
- m_mainWindow->restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("MainWindowGeometry").toByteArray()));
- if(minimized)
- {
- m_mainWindow->showMinimized();
- }
- else
- {
- m_mainWindow->show();
- }
-
- m_mainWindow->checkInstancePathForProblems();
- connect(this, &MultiMC::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged);
- connect(m_mainWindow, &MainWindow::isClosing, this, &MultiMC::on_windowClose);
- m_openWindows++;
- }
- // FIXME: move this somewhere else...
- if(m_analytics)
- {
- auto windowSize = m_mainWindow->size();
- auto sizeString = QString("%1x%2").arg(windowSize.width()).arg(windowSize.height());
- qDebug() << "Viewport size" << sizeString;
- m_analytics->setViewportSize(sizeString);
- /*
- * cm1 = java min heap [MB]
- * cm2 = java max heap [MB]
- * cm3 = system RAM [MB]
- *
- * cd1 = java version
- * cd2 = java architecture
- * cd3 = system architecture
- * cd4 = CPU architecture
- */
- QVariantMap customValues;
- int min = m_settings->get("MinMemAlloc").toInt();
- int max = m_settings->get("MaxMemAlloc").toInt();
- if(min < max)
- {
- customValues["cm1"] = min;
- customValues["cm2"] = max;
- }
- else
- {
- customValues["cm1"] = max;
- customValues["cm2"] = min;
- }
-
- constexpr uint64_t Mega = 1024ull * 1024ull;
- int ramSize = int(Sys::getSystemRam() / Mega);
- qDebug() << "RAM size is" << ramSize << "MB";
- customValues["cm3"] = ramSize;
-
- customValues["cd1"] = m_settings->get("JavaVersion");
- customValues["cd2"] = m_settings->get("JavaArchitecture");
- customValues["cd3"] = Sys::isSystem64bit() ? "64":"32";
- customValues["cd4"] = Sys::isCPU64bit() ? "64":"32";
- auto kernelInfo = Sys::getKernelInfo();
- customValues["cd5"] = kernelInfo.kernelName;
- customValues["cd6"] = kernelInfo.kernelVersion;
- auto distInfo = Sys::getDistributionInfo();
- if(!distInfo.distributionName.isEmpty())
- {
- customValues["cd7"] = distInfo.distributionName;
- }
- if(!distInfo.distributionVersion.isEmpty())
- {
- customValues["cd8"] = distInfo.distributionVersion;
- }
- m_analytics->sendScreenView("Main Window", customValues);
- }
- return m_mainWindow;
+ if(m_mainWindow)
+ {
+ m_mainWindow->setWindowState(m_mainWindow->windowState() & ~Qt::WindowMinimized);
+ m_mainWindow->raise();
+ m_mainWindow->activateWindow();
+ }
+ else
+ {
+ m_mainWindow = new MainWindow();
+ m_mainWindow->restoreState(QByteArray::fromBase64(MMC->settings()->get("MainWindowState").toByteArray()));
+ m_mainWindow->restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("MainWindowGeometry").toByteArray()));
+ if(minimized)
+ {
+ m_mainWindow->showMinimized();
+ }
+ else
+ {
+ m_mainWindow->show();
+ }
+
+ m_mainWindow->checkInstancePathForProblems();
+ connect(this, &MultiMC::updateAllowedChanged, m_mainWindow, &MainWindow::updatesAllowedChanged);
+ connect(m_mainWindow, &MainWindow::isClosing, this, &MultiMC::on_windowClose);
+ m_openWindows++;
+ }
+ // FIXME: move this somewhere else...
+ if(m_analytics)
+ {
+ auto windowSize = m_mainWindow->size();
+ auto sizeString = QString("%1x%2").arg(windowSize.width()).arg(windowSize.height());
+ qDebug() << "Viewport size" << sizeString;
+ m_analytics->setViewportSize(sizeString);
+ /*
+ * cm1 = java min heap [MB]
+ * cm2 = java max heap [MB]
+ * cm3 = system RAM [MB]
+ *
+ * cd1 = java version
+ * cd2 = java architecture
+ * cd3 = system architecture
+ * cd4 = CPU architecture
+ */
+ QVariantMap customValues;
+ int min = m_settings->get("MinMemAlloc").toInt();
+ int max = m_settings->get("MaxMemAlloc").toInt();
+ if(min < max)
+ {
+ customValues["cm1"] = min;
+ customValues["cm2"] = max;
+ }
+ else
+ {
+ customValues["cm1"] = max;
+ customValues["cm2"] = min;
+ }
+
+ constexpr uint64_t Mega = 1024ull * 1024ull;
+ int ramSize = int(Sys::getSystemRam() / Mega);
+ qDebug() << "RAM size is" << ramSize << "MB";
+ customValues["cm3"] = ramSize;
+
+ customValues["cd1"] = m_settings->get("JavaVersion");
+ customValues["cd2"] = m_settings->get("JavaArchitecture");
+ customValues["cd3"] = Sys::isSystem64bit() ? "64":"32";
+ customValues["cd4"] = Sys::isCPU64bit() ? "64":"32";
+ auto kernelInfo = Sys::getKernelInfo();
+ customValues["cd5"] = kernelInfo.kernelName;
+ customValues["cd6"] = kernelInfo.kernelVersion;
+ auto distInfo = Sys::getDistributionInfo();
+ if(!distInfo.distributionName.isEmpty())
+ {
+ customValues["cd7"] = distInfo.distributionName;
+ }
+ if(!distInfo.distributionVersion.isEmpty())
+ {
+ customValues["cd8"] = distInfo.distributionVersion;
+ }
+ m_analytics->sendScreenView("Main Window", customValues);
+ }
+ return m_mainWindow;
}
InstanceWindow *MultiMC::showInstanceWindow(InstancePtr instance, QString page)
{
- if(!instance)
- return nullptr;
- auto id = instance->id();
- auto & extras = m_instanceExtras[id];
- auto & window = extras.window;
-
- if(window)
- {
- window->raise();
- window->activateWindow();
- }
- else
- {
- window = new InstanceWindow(instance);
- m_openWindows ++;
- connect(window, &InstanceWindow::isClosing, this, &MultiMC::on_windowClose);
- }
- if(!page.isEmpty())
- {
- window->selectPage(page);
- }
- if(extras.controller)
- {
- extras.controller->setParentWidget(window);
- }
- return window;
+ if(!instance)
+ return nullptr;
+ auto id = instance->id();
+ auto & extras = m_instanceExtras[id];
+ auto & window = extras.window;
+
+ if(window)
+ {
+ window->raise();
+ window->activateWindow();
+ }
+ else
+ {
+ window = new InstanceWindow(instance);
+ m_openWindows ++;
+ connect(window, &InstanceWindow::isClosing, this, &MultiMC::on_windowClose);
+ }
+ if(!page.isEmpty())
+ {
+ window->selectPage(page);
+ }
+ if(extras.controller)
+ {
+ extras.controller->setParentWidget(window);
+ }
+ return window;
}
void MultiMC::on_windowClose()
{
- m_openWindows--;
- auto instWindow = qobject_cast<InstanceWindow *>(QObject::sender());
- if(instWindow)
- {
- auto & extras = m_instanceExtras[instWindow->instanceId()];
- extras.window = nullptr;
- if(extras.controller)
- {
- extras.controller->setParentWidget(m_mainWindow);
- }
- }
- auto mainWindow = qobject_cast<MainWindow *>(QObject::sender());
- if(mainWindow)
- {
- m_mainWindow = nullptr;
- }
- // quit when there are no more windows.
- if(shouldExitNow())
- {
- exit(0);
- }
+ m_openWindows--;
+ auto instWindow = qobject_cast<InstanceWindow *>(QObject::sender());
+ if(instWindow)
+ {
+ auto & extras = m_instanceExtras[instWindow->instanceId()];
+ extras.window = nullptr;
+ if(extras.controller)
+ {
+ extras.controller->setParentWidget(m_mainWindow);
+ }
+ }
+ auto mainWindow = qobject_cast<MainWindow *>(QObject::sender());
+ if(mainWindow)
+ {
+ m_mainWindow = nullptr;
+ }
+ // quit when there are no more windows.
+ if(shouldExitNow())
+ {
+ exit(0);
+ }
}
diff --git a/application/MultiMC.h b/application/MultiMC.h
index e93d8a69..9fe98aa1 100644
--- a/application/MultiMC.h
+++ b/application/MultiMC.h
@@ -40,187 +40,187 @@ class GAnalytics;
class MultiMC : public QApplication
{
- // friends for the purpose of limiting access to deprecated stuff
- Q_OBJECT
+ // friends for the purpose of limiting access to deprecated stuff
+ Q_OBJECT
public:
- enum Status
- {
- StartingUp,
- Failed,
- Succeeded,
- Initialized
- };
+ enum Status
+ {
+ StartingUp,
+ Failed,
+ Succeeded,
+ Initialized
+ };
public:
- MultiMC(int &argc, char **argv);
- virtual ~MultiMC();
+ MultiMC(int &argc, char **argv);
+ virtual ~MultiMC();
- GAnalytics *analytics() const
- {
- return m_analytics;
- }
+ GAnalytics *analytics() const
+ {
+ return m_analytics;
+ }
- std::shared_ptr<SettingsObject> settings() const
- {
- return m_settings;
- }
+ std::shared_ptr<SettingsObject> settings() const
+ {
+ return m_settings;
+ }
- std::shared_ptr<GenericPageProvider> globalSettingsPages() const
- {
- return m_globalSettingsProvider;
- }
+ std::shared_ptr<GenericPageProvider> globalSettingsPages() const
+ {
+ return m_globalSettingsProvider;
+ }
- qint64 timeSinceStart() const
- {
- return startTime.msecsTo(QDateTime::currentDateTime());
- }
+ qint64 timeSinceStart() const
+ {
+ return startTime.msecsTo(QDateTime::currentDateTime());
+ }
- QIcon getThemedIcon(const QString& name);
+ QIcon getThemedIcon(const QString& name);
- void setIconTheme(const QString& name);
+ void setIconTheme(const QString& name);
- std::vector<ITheme *> getValidApplicationThemes();
+ std::vector<ITheme *> getValidApplicationThemes();
- void setApplicationTheme(const QString& name, bool initial);
+ void setApplicationTheme(const QString& name, bool initial);
- // DownloadUpdateTask
- std::shared_ptr<UpdateChecker> updateChecker()
- {
- return m_updateChecker;
- }
+ // DownloadUpdateTask
+ std::shared_ptr<UpdateChecker> updateChecker()
+ {
+ return m_updateChecker;
+ }
- std::shared_ptr<TranslationsModel> translations();
+ std::shared_ptr<TranslationsModel> translations();
- std::shared_ptr<JavaInstallList> javalist();
+ std::shared_ptr<JavaInstallList> javalist();
- std::shared_ptr<InstanceList> instances() const
- {
- return m_instances;
- }
+ std::shared_ptr<InstanceList> instances() const
+ {
+ return m_instances;
+ }
- FolderInstanceProvider * folderProvider() const
- {
- return m_instanceFolder;
- }
+ FolderInstanceProvider * folderProvider() const
+ {
+ return m_instanceFolder;
+ }
- std::shared_ptr<IconList> icons() const
- {
- return m_icons;
- }
+ std::shared_ptr<IconList> icons() const
+ {
+ return m_icons;
+ }
- MCEditTool *mcedit() const
- {
- return m_mcedit.get();
- }
+ MCEditTool *mcedit() const
+ {
+ return m_mcedit.get();
+ }
- std::shared_ptr<MojangAccountList> accounts() const
- {
- return m_accounts;
- }
+ std::shared_ptr<MojangAccountList> accounts() const
+ {
+ return m_accounts;
+ }
- Status status() const
- {
- return m_status;
- }
+ Status status() const
+ {
+ return m_status;
+ }
- const QMap<QString, std::shared_ptr<BaseProfilerFactory>> &profilers() const
- {
- return m_profilers;
- }
+ const QMap<QString, std::shared_ptr<BaseProfilerFactory>> &profilers() const
+ {
+ return m_profilers;
+ }
- /// this is the root of the 'installation'. Used for automatic updates
- const QString &root()
- {
- return m_rootPath;
- }
+ /// this is the root of the 'installation'. Used for automatic updates
+ const QString &root()
+ {
+ return m_rootPath;
+ }
- /*!
- * Opens a json file using either a system default editor, or, if not empty, the editor
- * specified in the settings
- */
- bool openJsonEditor(const QString &filename);
+ /*!
+ * Opens a json file using either a system default editor, or, if not empty, the editor
+ * specified in the settings
+ */
+ bool openJsonEditor(const QString &filename);
- InstanceWindow *showInstanceWindow(InstancePtr instance, QString page = QString());
- MainWindow *showMainWindow(bool minimized = false);
+ InstanceWindow *showInstanceWindow(InstancePtr instance, QString page = QString());
+ MainWindow *showMainWindow(bool minimized = false);
- void updateIsRunning(bool running);
- bool updatesAreAllowed();
+ void updateIsRunning(bool running);
+ bool updatesAreAllowed();
signals:
- void updateAllowedChanged(bool status);
+ void updateAllowedChanged(bool status);
public slots:
- bool launch(InstancePtr instance, bool online = true, BaseProfilerFactory *profiler = nullptr);
- bool kill(InstancePtr instance);
+ bool launch(InstancePtr instance, bool online = true, BaseProfilerFactory *profiler = nullptr);
+ bool kill(InstancePtr instance);
private slots:
- void on_windowClose();
- void messageReceived(const QString & message);
- void controllerSucceeded();
- void controllerFailed(const QString & error);
- void analyticsSettingChanged(const Setting &setting, QVariant value);
- void setupWizardFinished(int status);
+ void on_windowClose();
+ void messageReceived(const QString & message);
+ void controllerSucceeded();
+ void controllerFailed(const QString & error);
+ void analyticsSettingChanged(const Setting &setting, QVariant value);
+ void setupWizardFinished(int status);
private:
- bool createSetupWizard();
- void performMainStartupAction();
+ bool createSetupWizard();
+ void performMainStartupAction();
- // sets the fatal error message and m_status to Failed.
- void showFatalErrorMessage(const QString & title, const QString & content);
+ // sets the fatal error message and m_status to Failed.
+ void showFatalErrorMessage(const QString & title, const QString & content);
private:
- void addRunningInstance();
- void subRunningInstance();
- bool shouldExitNow() const;
+ void addRunningInstance();
+ void subRunningInstance();
+ bool shouldExitNow() const;
private:
- QDateTime startTime;
+ QDateTime startTime;
- std::shared_ptr<SettingsObject> m_settings;
- std::shared_ptr<InstanceList> m_instances;
- FolderInstanceProvider * m_instanceFolder = nullptr;
- std::shared_ptr<IconList> m_icons;
- std::shared_ptr<UpdateChecker> m_updateChecker;
- std::shared_ptr<MojangAccountList> m_accounts;
- std::shared_ptr<JavaInstallList> m_javalist;
- std::shared_ptr<TranslationsModel> m_translations;
- std::shared_ptr<GenericPageProvider> m_globalSettingsProvider;
- std::map<QString, std::unique_ptr<ITheme>> m_themes;
- std::unique_ptr<MCEditTool> m_mcedit;
+ std::shared_ptr<SettingsObject> m_settings;
+ std::shared_ptr<InstanceList> m_instances;
+ FolderInstanceProvider * m_instanceFolder = nullptr;
+ std::shared_ptr<IconList> m_icons;
+ std::shared_ptr<UpdateChecker> m_updateChecker;
+ std::shared_ptr<MojangAccountList> m_accounts;
+ std::shared_ptr<JavaInstallList> m_javalist;
+ std::shared_ptr<TranslationsModel> m_translations;
+ std::shared_ptr<GenericPageProvider> m_globalSettingsProvider;
+ std::map<QString, std::unique_ptr<ITheme>> m_themes;
+ std::unique_ptr<MCEditTool> m_mcedit;
- QMap<QString, std::shared_ptr<BaseProfilerFactory>> m_profilers;
+ QMap<QString, std::shared_ptr<BaseProfilerFactory>> m_profilers;
- QString m_rootPath;
- Status m_status = MultiMC::StartingUp;
+ QString m_rootPath;
+ Status m_status = MultiMC::StartingUp;
#if defined Q_OS_WIN32
- // used on Windows to attach the standard IO streams
- bool consoleAttached = false;
+ // used on Windows to attach the standard IO streams
+ bool consoleAttached = false;
#endif
- // FIXME: attach to instances instead.
- struct InstanceXtras
- {
- InstanceWindow * window = nullptr;
- shared_qobject_ptr<LaunchController> controller;
- };
- std::map<QString, InstanceXtras> m_instanceExtras;
+ // FIXME: attach to instances instead.
+ struct InstanceXtras
+ {
+ InstanceWindow * window = nullptr;
+ shared_qobject_ptr<LaunchController> controller;
+ };
+ std::map<QString, InstanceXtras> m_instanceExtras;
- // main state variables
- size_t m_openWindows = 0;
- size_t m_runningInstances = 0;
- bool m_updateRunning = false;
+ // main state variables
+ size_t m_openWindows = 0;
+ size_t m_runningInstances = 0;
+ bool m_updateRunning = false;
- // main window, if any
- MainWindow * m_mainWindow = nullptr;
+ // main window, if any
+ MainWindow * m_mainWindow = nullptr;
- // peer MultiMC instance connector - used to implement single instance MultiMC and signalling
- LocalPeer * m_peerInstance = nullptr;
+ // peer MultiMC instance connector - used to implement single instance MultiMC and signalling
+ LocalPeer * m_peerInstance = nullptr;
- GAnalytics * m_analytics = nullptr;
- SetupWizard * m_setupWizard = nullptr;
+ GAnalytics * m_analytics = nullptr;
+ SetupWizard * m_setupWizard = nullptr;
public:
- QString m_instanceIdToLaunch;
- bool m_liveCheck = false;
- std::unique_ptr<QFile> logFile;
+ QString m_instanceIdToLaunch;
+ bool m_liveCheck = false;
+ std::unique_ptr<QFile> logFile;
};
diff --git a/application/SettingsUI.h b/application/SettingsUI.h
index 0d14fbee..474bc1ab 100644
--- a/application/SettingsUI.h
+++ b/application/SettingsUI.h
@@ -14,13 +14,13 @@ namespace SettingsUI
template <typename T>
void ShowPageDialog(T raw_provider, QWidget * parent, QString open_page = QString())
{
- auto provider = std::dynamic_pointer_cast<BasePageProvider>(raw_provider);
- if(!provider)
- return;
- {
- SettingsObject::Lock lock(MMC->settings());
- PageDialog dlg(provider.get(), open_page, parent);
- dlg.exec();
- }
+ auto provider = std::dynamic_pointer_cast<BasePageProvider>(raw_provider);
+ if(!provider)
+ return;
+ {
+ SettingsObject::Lock lock(MMC->settings());
+ PageDialog dlg(provider.get(), open_page, parent);
+ dlg.exec();
+ }
}
}
diff --git a/application/UpdateController.cpp b/application/UpdateController.cpp
index 733e365f..0309ad93 100644
--- a/application/UpdateController.cpp
+++ b/application/UpdateController.cpp
@@ -27,423 +27,423 @@
#endif
static QFile::Permissions unixModeToPermissions(const int mode)
{
- QFile::Permissions perms;
+ QFile::Permissions perms;
- if (mode & S_IRUSR)
- {
- perms |= QFile::ReadUser;
- }
- if (mode & S_IWUSR)
- {
- perms |= QFile::WriteUser;
- }
- if (mode & S_IXUSR)
- {
- perms |= QFile::ExeUser;
- }
+ if (mode & S_IRUSR)
+ {
+ perms |= QFile::ReadUser;
+ }
+ if (mode & S_IWUSR)
+ {
+ perms |= QFile::WriteUser;
+ }
+ if (mode & S_IXUSR)
+ {
+ perms |= QFile::ExeUser;
+ }
- if (mode & S_IRGRP)
- {
- perms |= QFile::ReadGroup;
- }
- if (mode & S_IWGRP)
- {
- perms |= QFile::WriteGroup;
- }
- if (mode & S_IXGRP)
- {
- perms |= QFile::ExeGroup;
- }
+ if (mode & S_IRGRP)
+ {
+ perms |= QFile::ReadGroup;
+ }
+ if (mode & S_IWGRP)
+ {
+ perms |= QFile::WriteGroup;
+ }
+ if (mode & S_IXGRP)
+ {
+ perms |= QFile::ExeGroup;
+ }
- if (mode & S_IROTH)
- {
- perms |= QFile::ReadOther;
- }
- if (mode & S_IWOTH)
- {
- perms |= QFile::WriteOther;
- }
- if (mode & S_IXOTH)
- {
- perms |= QFile::ExeOther;
- }
- return perms;
+ if (mode & S_IROTH)
+ {
+ perms |= QFile::ReadOther;
+ }
+ if (mode & S_IWOTH)
+ {
+ perms |= QFile::WriteOther;
+ }
+ if (mode & S_IXOTH)
+ {
+ perms |= QFile::ExeOther;
+ }
+ return perms;
}
static const QLatin1String liveCheckFile("live.check");
UpdateController::UpdateController(QWidget * parent, const QString& root, const QString updateFilesDir, GoUpdate::OperationList operations)
{
- m_parent = parent;
- m_root = root;
- m_updateFilesDir = updateFilesDir;
- m_operations = operations;
+ m_parent = parent;
+ m_root = root;
+ m_updateFilesDir = updateFilesDir;
+ m_operations = operations;
}
void UpdateController::installUpdates()
{
- qint64 pid = -1;
- QStringList args;
- bool started = false;
+ qint64 pid = -1;
+ QStringList args;
+ bool started = false;
- qDebug() << "Installing updates.";
+ qDebug() << "Installing updates.";
#ifdef Q_OS_WIN
- QString finishCmd = QApplication::applicationFilePath();
+ QString finishCmd = QApplication::applicationFilePath();
#elif defined Q_OS_LINUX
- QString finishCmd = FS::PathCombine(m_root, "MultiMC");
+ QString finishCmd = FS::PathCombine(m_root, "MultiMC");
#elif defined Q_OS_MAC
- QString finishCmd = QApplication::applicationFilePath();
+ QString finishCmd = QApplication::applicationFilePath();
#else
#error Unsupported operating system.
#endif
- QString backupPath = FS::PathCombine(m_root, "update", "backup");
- QDir origin(m_root);
+ QString backupPath = FS::PathCombine(m_root, "update", "backup");
+ QDir origin(m_root);
- // clean up the backup folder. it should be empty before we start
- if(!FS::deletePath(backupPath))
- {
- qWarning() << "couldn't remove previous backup folder" << backupPath;
- }
- // and it should exist.
- if(!FS::ensureFolderPathExists(backupPath))
- {
- qWarning() << "couldn't create folder" << backupPath;
- return;
- }
+ // clean up the backup folder. it should be empty before we start
+ if(!FS::deletePath(backupPath))
+ {
+ qWarning() << "couldn't remove previous backup folder" << backupPath;
+ }
+ // and it should exist.
+ if(!FS::ensureFolderPathExists(backupPath))
+ {
+ qWarning() << "couldn't create folder" << backupPath;
+ return;
+ }
- bool useXPHack = false;
- QString exePath;
- QString exeOrigin;
- QString exeBackup;
+ bool useXPHack = false;
+ QString exePath;
+ QString exeOrigin;
+ QString exeBackup;
- // perform the update operations
- for(auto op: m_operations)
- {
- switch(op.type)
- {
- // replace = move original out to backup, if it exists, move the new file in its place
- case GoUpdate::Operation::OP_REPLACE:
- {
+ // perform the update operations
+ for(auto op: m_operations)
+ {
+ switch(op.type)
+ {
+ // replace = move original out to backup, if it exists, move the new file in its place
+ case GoUpdate::Operation::OP_REPLACE:
+ {
#ifdef Q_OS_WIN32
- // hack for people renaming the .exe because ... reasons :)
- if(op.destination == "MultiMC.exe")
- {
- op.destination = QFileInfo(QApplication::applicationFilePath()).fileName();
- }
+ // hack for people renaming the .exe because ... reasons :)
+ if(op.destination == "MultiMC.exe")
+ {
+ op.destination = QFileInfo(QApplication::applicationFilePath()).fileName();
+ }
#endif
- QFileInfo destination (FS::PathCombine(m_root, op.destination));
+ QFileInfo destination (FS::PathCombine(m_root, op.destination));
#ifdef Q_OS_WIN32
- if(QSysInfo::windowsVersion() < QSysInfo::WV_VISTA)
- {
- if(destination.fileName() == "MultiMC.exe")
- {
- QDir rootDir(m_root);
- exeOrigin = rootDir.relativeFilePath(op.source);
- exePath = rootDir.relativeFilePath(op.destination);
- exeBackup = rootDir.relativeFilePath(FS::PathCombine(backupPath, destination.fileName()));
- useXPHack = true;
- continue;
- }
- }
+ if(QSysInfo::windowsVersion() < QSysInfo::WV_VISTA)
+ {
+ if(destination.fileName() == "MultiMC.exe")
+ {
+ QDir rootDir(m_root);
+ exeOrigin = rootDir.relativeFilePath(op.source);
+ exePath = rootDir.relativeFilePath(op.destination);
+ exeBackup = rootDir.relativeFilePath(FS::PathCombine(backupPath, destination.fileName()));
+ useXPHack = true;
+ continue;
+ }
+ }
#endif
- if(destination.exists())
- {
- QString backupName = op.destination;
- backupName.replace('/', '_');
- QString backupFilePath = FS::PathCombine(backupPath, backupName);
- if(!QFile::rename(destination.absoluteFilePath(), backupFilePath))
- {
- qWarning() << "Couldn't move:" << destination.absoluteFilePath() << "to" << backupFilePath;
- m_failedOperationType = Replace;
- m_failedFile = op.destination;
- fail();
- return;
- }
- BackupEntry be;
- be.original = destination.absoluteFilePath();
- be.backup = backupFilePath;
- be.update = op.source;
- m_replace_backups.append(be);
- }
- // make sure the folder we are putting this into exists
- if(!FS::ensureFilePathExists(destination.absoluteFilePath()))
- {
- qWarning() << "REPLACE: Couldn't create folder:" << destination.absoluteFilePath();
- m_failedOperationType = Replace;
- m_failedFile = op.destination;
- fail();
- return;
- }
- // now move the new file in
- if(!QFile::rename(op.source, destination.absoluteFilePath()))
- {
- qWarning() << "REPLACE: Couldn't move:" << op.source << "to" << destination.absoluteFilePath();
- m_failedOperationType = Replace;
- m_failedFile = op.destination;
- fail();
- return;
- }
- QFile::setPermissions(destination.absoluteFilePath(), unixModeToPermissions(op.destinationMode));
- }
- break;
- // delete = move original to backup
- case GoUpdate::Operation::OP_DELETE:
- {
- QString destFilePath = FS::PathCombine(m_root, op.destination);
- if(QFile::exists(destFilePath))
- {
- QString backupName = op.destination;
- backupName.replace('/', '_');
- QString trashFilePath = FS::PathCombine(backupPath, backupName);
+ if(destination.exists())
+ {
+ QString backupName = op.destination;
+ backupName.replace('/', '_');
+ QString backupFilePath = FS::PathCombine(backupPath, backupName);
+ if(!QFile::rename(destination.absoluteFilePath(), backupFilePath))
+ {
+ qWarning() << "Couldn't move:" << destination.absoluteFilePath() << "to" << backupFilePath;
+ m_failedOperationType = Replace;
+ m_failedFile = op.destination;
+ fail();
+ return;
+ }
+ BackupEntry be;
+ be.original = destination.absoluteFilePath();
+ be.backup = backupFilePath;
+ be.update = op.source;
+ m_replace_backups.append(be);
+ }
+ // make sure the folder we are putting this into exists
+ if(!FS::ensureFilePathExists(destination.absoluteFilePath()))
+ {
+ qWarning() << "REPLACE: Couldn't create folder:" << destination.absoluteFilePath();
+ m_failedOperationType = Replace;
+ m_failedFile = op.destination;
+ fail();
+ return;
+ }
+ // now move the new file in
+ if(!QFile::rename(op.source, destination.absoluteFilePath()))
+ {
+ qWarning() << "REPLACE: Couldn't move:" << op.source << "to" << destination.absoluteFilePath();
+ m_failedOperationType = Replace;
+ m_failedFile = op.destination;
+ fail();
+ return;
+ }
+ QFile::setPermissions(destination.absoluteFilePath(), unixModeToPermissions(op.destinationMode));
+ }
+ break;
+ // delete = move original to backup
+ case GoUpdate::Operation::OP_DELETE:
+ {
+ QString destFilePath = FS::PathCombine(m_root, op.destination);
+ if(QFile::exists(destFilePath))
+ {
+ QString backupName = op.destination;
+ backupName.replace('/', '_');
+ QString trashFilePath = FS::PathCombine(backupPath, backupName);
- if(!QFile::rename(destFilePath, trashFilePath))
- {
- qWarning() << "DELETE: Couldn't move:" << op.destination << "to" << trashFilePath;
- m_failedFile = op.destination;
- m_failedOperationType = Delete;
- fail();
- return;
- }
- BackupEntry be;
- be.original = destFilePath;
- be.backup = trashFilePath;
- m_delete_backups.append(be);
- }
- }
- break;
- }
- }
+ if(!QFile::rename(destFilePath, trashFilePath))
+ {
+ qWarning() << "DELETE: Couldn't move:" << op.destination << "to" << trashFilePath;
+ m_failedFile = op.destination;
+ m_failedOperationType = Delete;
+ fail();
+ return;
+ }
+ BackupEntry be;
+ be.original = destFilePath;
+ be.backup = trashFilePath;
+ m_delete_backups.append(be);
+ }
+ }
+ break;
+ }
+ }
- // try to start the new binary
- args = qApp->arguments();
- args.removeFirst();
+ // try to start the new binary
+ args = qApp->arguments();
+ args.removeFirst();
- // on old Windows, do insane things... no error checking here, this is just to have something.
- if(useXPHack)
- {
- QString script;
- auto nativePath = QDir::toNativeSeparators(exePath);
- auto nativeOriginPath = QDir::toNativeSeparators(exeOrigin);
- auto nativeBackupPath = QDir::toNativeSeparators(exeBackup);
+ // on old Windows, do insane things... no error checking here, this is just to have something.
+ if(useXPHack)
+ {
+ QString script;
+ auto nativePath = QDir::toNativeSeparators(exePath);
+ auto nativeOriginPath = QDir::toNativeSeparators(exeOrigin);
+ auto nativeBackupPath = QDir::toNativeSeparators(exeBackup);
- // so we write this vbscript thing...
- QTextStream out(&script);
- out << "WScript.Sleep 1000\n";
- out << "Set fso=CreateObject(\"Scripting.FileSystemObject\")\n";
- out << "Set shell=CreateObject(\"WScript.Shell\")\n";
- out << "fso.MoveFile \"" << nativePath << "\", \"" << nativeBackupPath << "\"\n";
- out << "fso.MoveFile \"" << nativeOriginPath << "\", \"" << nativePath << "\"\n";
- out << "shell.Run \"" << nativePath << "\"\n";
+ // so we write this vbscript thing...
+ QTextStream out(&script);
+ out << "WScript.Sleep 1000\n";
+ out << "Set fso=CreateObject(\"Scripting.FileSystemObject\")\n";
+ out << "Set shell=CreateObject(\"WScript.Shell\")\n";
+ out << "fso.MoveFile \"" << nativePath << "\", \"" << nativeBackupPath << "\"\n";
+ out << "fso.MoveFile \"" << nativeOriginPath << "\", \"" << nativePath << "\"\n";
+ out << "shell.Run \"" << nativePath << "\"\n";
- QString scriptPath = FS::PathCombine(m_root, "update", "update.vbs");
+ QString scriptPath = FS::PathCombine(m_root, "update", "update.vbs");
- // we save it
- QFile scriptFile(scriptPath);
- scriptFile.open(QIODevice::WriteOnly);
- scriptFile.write(script.toLocal8Bit().replace("\n", "\r\n"));
- scriptFile.close();
+ // we save it
+ QFile scriptFile(scriptPath);
+ scriptFile.open(QIODevice::WriteOnly);
+ scriptFile.write(script.toLocal8Bit().replace("\n", "\r\n"));
+ scriptFile.close();
- // we run it
- started = QProcess::startDetached("wscript", {scriptPath}, m_root);
+ // we run it
+ started = QProcess::startDetached("wscript", {scriptPath}, m_root);
- // and we quit. conscious thought.
- qApp->quit();
- return;
- }
- bool doLiveCheck = true;
- bool startFailed = false;
+ // and we quit. conscious thought.
+ qApp->quit();
+ return;
+ }
+ bool doLiveCheck = true;
+ bool startFailed = false;
- // remove live check file, if any
- if(QFile::exists(liveCheckFile))
- {
- if(!QFile::remove(liveCheckFile))
- {
- qWarning() << "Couldn't remove the" << liveCheckFile << "file! We will proceed without :(";
- doLiveCheck = false;
- }
- }
+ // remove live check file, if any
+ if(QFile::exists(liveCheckFile))
+ {
+ if(!QFile::remove(liveCheckFile))
+ {
+ qWarning() << "Couldn't remove the" << liveCheckFile << "file! We will proceed without :(";
+ doLiveCheck = false;
+ }
+ }
- if(doLiveCheck)
- {
- if(!args.contains("--alive"))
- {
- args.append("--alive");
- }
- }
+ if(doLiveCheck)
+ {
+ if(!args.contains("--alive"))
+ {
+ args.append("--alive");
+ }
+ }
- // FIXME: reparse args and construct a safe variant from scratch. This is a workaround for GH-1874:
- QStringList realargs;
- int skip = 0;
- for(auto & arg: args)
- {
- if(skip)
- {
- skip--;
- continue;
- }
- if(arg == "-l")
- {
- skip = 1;
- continue;
- }
- realargs.append(arg);
- }
+ // FIXME: reparse args and construct a safe variant from scratch. This is a workaround for GH-1874:
+ QStringList realargs;
+ int skip = 0;
+ for(auto & arg: args)
+ {
+ if(skip)
+ {
+ skip--;
+ continue;
+ }
+ if(arg == "-l")
+ {
+ skip = 1;
+ continue;
+ }
+ realargs.append(arg);
+ }
- // start the updated application
- started = QProcess::startDetached(finishCmd, realargs, QDir::currentPath(), &pid);
- // much dumber check - just find out if the call
- if(!started || pid == -1)
- {
- qWarning() << "Couldn't start new process properly!";
- startFailed = true;
- }
- if(!startFailed && doLiveCheck)
- {
- int attempts = 0;
- while(attempts < 10)
- {
- attempts++;
- QString key;
- std::this_thread::sleep_for(std::chrono::milliseconds(250));
- if(!QFile::exists(liveCheckFile))
- {
- qWarning() << "Couldn't find the" << liveCheckFile << "file!";
- startFailed = true;
- continue;
- }
- try
- {
- key = QString::fromUtf8(FS::read(liveCheckFile));
- auto id = ApplicationId::fromRawString(key);
- LocalPeer peer(nullptr, id);
- if(peer.isClient())
- {
- startFailed = false;
- qDebug() << "Found process started with key " << key;
- break;
- }
- else
- {
- startFailed = true;
- qDebug() << "Process started with key " << key << "apparently died or is not reponding...";
- break;
- }
- }
- catch (const Exception &e)
- {
- qWarning() << "Couldn't read the" << liveCheckFile << "file!";
- startFailed = true;
- continue;
- }
- }
- }
- if(startFailed)
- {
- m_failedOperationType = Start;
- fail();
- return;
- }
- else
- {
- origin.rmdir(m_updateFilesDir);
- qApp->quit();
- return;
- }
+ // start the updated application
+ started = QProcess::startDetached(finishCmd, realargs, QDir::currentPath(), &pid);
+ // much dumber check - just find out if the call
+ if(!started || pid == -1)
+ {
+ qWarning() << "Couldn't start new process properly!";
+ startFailed = true;
+ }
+ if(!startFailed && doLiveCheck)
+ {
+ int attempts = 0;
+ while(attempts < 10)
+ {
+ attempts++;
+ QString key;
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ if(!QFile::exists(liveCheckFile))
+ {
+ qWarning() << "Couldn't find the" << liveCheckFile << "file!";
+ startFailed = true;
+ continue;
+ }
+ try
+ {
+ key = QString::fromUtf8(FS::read(liveCheckFile));
+ auto id = ApplicationId::fromRawString(key);
+ LocalPeer peer(nullptr, id);
+ if(peer.isClient())
+ {
+ startFailed = false;
+ qDebug() << "Found process started with key " << key;
+ break;
+ }
+ else
+ {
+ startFailed = true;
+ qDebug() << "Process started with key " << key << "apparently died or is not reponding...";
+ break;
+ }
+ }
+ catch (const Exception &e)
+ {
+ qWarning() << "Couldn't read the" << liveCheckFile << "file!";
+ startFailed = true;
+ continue;
+ }
+ }
+ }
+ if(startFailed)
+ {
+ m_failedOperationType = Start;
+ fail();
+ return;
+ }
+ else
+ {
+ origin.rmdir(m_updateFilesDir);
+ qApp->quit();
+ return;
+ }
}
void UpdateController::fail()
{
- qWarning() << "Update failed!";
+ qWarning() << "Update failed!";
- QString msg;
- bool doRollback = false;
- QString failTitle = QObject::tr("Update failed!");
- QString rollFailTitle = QObject::tr("Rollback failed!");
- switch (m_failedOperationType)
- {
- case Replace:
- {
- msg = QObject::tr("Couldn't replace file %1. Changes will be reverted.\n"
- "See the MultiMC log file for details.").arg(m_failedFile);
- doRollback = true;
- QMessageBox::critical(m_parent, failTitle, msg);
- break;
- }
- case Delete:
- {
- msg = QObject::tr("Couldn't remove file %1. Changes will be reverted.\n"
- "See the MultiMC log file for details.").arg(m_failedFile);
- doRollback = true;
- QMessageBox::critical(m_parent, failTitle, msg);
- break;
- }
- case Start:
- {
- msg = QObject::tr("The new version didn't start or is too old and doesn't respond to startup checks.\n"
- "\n"
- "Roll back to previous version?");
- auto result = QMessageBox::critical(
- m_parent,
- failTitle,
- msg,
- QMessageBox::Yes | QMessageBox::No,
- QMessageBox::Yes
- );
- doRollback = (result == QMessageBox::Yes);
- break;
- }
- case Nothing:
- default:
- return;
- }
- if(doRollback)
- {
- auto rollbackOK = rollback();
- if(!rollbackOK)
- {
- msg = QObject::tr("The rollback failed too.\n"
- "You will have to repair MultiMC manually.\n"
- "Please let us know why and how this happened.").arg(m_failedFile);
- QMessageBox::critical(m_parent, rollFailTitle, msg);
- qApp->quit();
- }
- }
- else
- {
- qApp->quit();
- }
+ QString msg;
+ bool doRollback = false;
+ QString failTitle = QObject::tr("Update failed!");
+ QString rollFailTitle = QObject::tr("Rollback failed!");
+ switch (m_failedOperationType)
+ {
+ case Replace:
+ {
+ msg = QObject::tr("Couldn't replace file %1. Changes will be reverted.\n"
+ "See the MultiMC log file for details.").arg(m_failedFile);
+ doRollback = true;
+ QMessageBox::critical(m_parent, failTitle, msg);
+ break;
+ }
+ case Delete:
+ {
+ msg = QObject::tr("Couldn't remove file %1. Changes will be reverted.\n"
+ "See the MultiMC log file for details.").arg(m_failedFile);
+ doRollback = true;
+ QMessageBox::critical(m_parent, failTitle, msg);
+ break;
+ }
+ case Start:
+ {
+ msg = QObject::tr("The new version didn't start or is too old and doesn't respond to startup checks.\n"
+ "\n"
+ "Roll back to previous version?");
+ auto result = QMessageBox::critical(
+ m_parent,
+ failTitle,
+ msg,
+ QMessageBox::Yes | QMessageBox::No,
+ QMessageBox::Yes
+ );
+ doRollback = (result == QMessageBox::Yes);
+ break;
+ }
+ case Nothing:
+ default:
+ return;
+ }
+ if(doRollback)
+ {
+ auto rollbackOK = rollback();
+ if(!rollbackOK)
+ {
+ msg = QObject::tr("The rollback failed too.\n"
+ "You will have to repair MultiMC manually.\n"
+ "Please let us know why and how this happened.").arg(m_failedFile);
+ QMessageBox::critical(m_parent, rollFailTitle, msg);
+ qApp->quit();
+ }
+ }
+ else
+ {
+ qApp->quit();
+ }
}
bool UpdateController::rollback()
{
- bool revertOK = true;
- // if the above failed, roll back changes
- for(auto backup:m_replace_backups)
- {
- qWarning() << "restoring" << backup.original << "from" << backup.backup;
- if(!QFile::rename(backup.original, backup.update))
- {
- revertOK = false;
- qWarning() << "moving new" << backup.original << "back to" << backup.update << "failed!";
- continue;
- }
+ bool revertOK = true;
+ // if the above failed, roll back changes
+ for(auto backup:m_replace_backups)
+ {
+ qWarning() << "restoring" << backup.original << "from" << backup.backup;
+ if(!QFile::rename(backup.original, backup.update))
+ {
+ revertOK = false;
+ qWarning() << "moving new" << backup.original << "back to" << backup.update << "failed!";
+ continue;
+ }
- if(!QFile::rename(backup.backup, backup.original))
- {
- revertOK = false;
- qWarning() << "restoring" << backup.original << "failed!";
- }
- }
- for(auto backup:m_delete_backups)
- {
- qWarning() << "restoring" << backup.original << "from" << backup.backup;
- if(!QFile::rename(backup.backup, backup.original))
- {
- revertOK = false;
- qWarning() << "restoring" << backup.original << "failed!";
- }
- }
- return revertOK;
+ if(!QFile::rename(backup.backup, backup.original))
+ {
+ revertOK = false;
+ qWarning() << "restoring" << backup.original << "failed!";
+ }
+ }
+ for(auto backup:m_delete_backups)
+ {
+ qWarning() << "restoring" << backup.original << "from" << backup.backup;
+ if(!QFile::rename(backup.backup, backup.original))
+ {
+ revertOK = false;
+ qWarning() << "restoring" << backup.original << "failed!";
+ }
+ }
+ return revertOK;
}
diff --git a/application/UpdateController.h b/application/UpdateController.h
index 2b258701..715554e5 100644
--- a/application/UpdateController.h
+++ b/application/UpdateController.h
@@ -9,36 +9,36 @@ class QWidget;
class UpdateController
{
public:
- UpdateController(QWidget * parent, const QString &root, const QString updateFilesDir, GoUpdate::OperationList operations);
- void installUpdates();
+ UpdateController(QWidget * parent, const QString &root, const QString updateFilesDir, GoUpdate::OperationList operations);
+ void installUpdates();
private:
- void fail();
- bool rollback();
+ void fail();
+ bool rollback();
private:
- QString m_root;
- QString m_updateFilesDir;
- GoUpdate::OperationList m_operations;
- QWidget * m_parent;
+ QString m_root;
+ QString m_updateFilesDir;
+ GoUpdate::OperationList m_operations;
+ QWidget * m_parent;
- struct BackupEntry
- {
- // path where we got the new file from
- QString update;
- // path of what is being actually updated
- QString original;
- // path where the backup of the updated file was placed
- QString backup;
- };
- QList <BackupEntry> m_replace_backups;
- QList <BackupEntry> m_delete_backups;
- enum Failure
- {
- Replace,
- Delete,
- Start,
- Nothing
- } m_failedOperationType = Nothing;
- QString m_failedFile;
+ struct BackupEntry
+ {
+ // path where we got the new file from
+ QString update;
+ // path of what is being actually updated
+ QString original;
+ // path where the backup of the updated file was placed
+ QString backup;
+ };
+ QList <BackupEntry> m_replace_backups;
+ QList <BackupEntry> m_delete_backups;
+ enum Failure
+ {
+ Replace,
+ Delete,
+ Start,
+ Nothing
+ } m_failedOperationType = Nothing;
+ QString m_failedFile;
};
diff --git a/application/VersionProxyModel.cpp b/application/VersionProxyModel.cpp
index 990b949e..338a6064 100644
--- a/application/VersionProxyModel.cpp
+++ b/application/VersionProxyModel.cpp
@@ -7,429 +7,429 @@
class VersionFilterModel : public QSortFilterProxyModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- VersionFilterModel(VersionProxyModel *parent) : QSortFilterProxyModel(parent)
- {
- m_parent = parent;
- setSortRole(BaseVersionList::SortRole);
- sort(0, Qt::DescendingOrder);
- }
-
- bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
- {
- const auto &filters = m_parent->filters();
- for (auto it = filters.begin(); it != filters.end(); ++it)
- {
- auto idx = sourceModel()->index(source_row, 0, source_parent);
- auto data = sourceModel()->data(idx, it.key());
- auto match = data.toString();
- if(!it.value()->accepts(match))
- {
- return false;
- }
- }
- return true;
- }
-
- void filterChanged()
- {
- invalidateFilter();
- }
+ VersionFilterModel(VersionProxyModel *parent) : QSortFilterProxyModel(parent)
+ {
+ m_parent = parent;
+ setSortRole(BaseVersionList::SortRole);
+ sort(0, Qt::DescendingOrder);
+ }
+
+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
+ {
+ const auto &filters = m_parent->filters();
+ for (auto it = filters.begin(); it != filters.end(); ++it)
+ {
+ auto idx = sourceModel()->index(source_row, 0, source_parent);
+ auto data = sourceModel()->data(idx, it.key());
+ auto match = data.toString();
+ if(!it.value()->accepts(match))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void filterChanged()
+ {
+ invalidateFilter();
+ }
private:
- VersionProxyModel *m_parent;
+ VersionProxyModel *m_parent;
};
VersionProxyModel::VersionProxyModel(QObject *parent) : QAbstractProxyModel(parent)
{
- filterModel = new VersionFilterModel(this);
- connect(filterModel, &QAbstractItemModel::dataChanged, this, &VersionProxyModel::sourceDataChanged);
- connect(filterModel, &QAbstractItemModel::rowsAboutToBeInserted, this, &VersionProxyModel::sourceRowsAboutToBeInserted);
- connect(filterModel, &QAbstractItemModel::rowsInserted, this, &VersionProxyModel::sourceRowsInserted);
- connect(filterModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &VersionProxyModel::sourceRowsAboutToBeRemoved);
- connect(filterModel, &QAbstractItemModel::rowsRemoved, this, &VersionProxyModel::sourceRowsRemoved);
- // FIXME: implement when needed
- /*
- connect(replacing, &QAbstractItemModel::rowsAboutToBeMoved, this, &VersionProxyModel::sourceRowsAboutToBeMoved);
- connect(replacing, &QAbstractItemModel::rowsMoved, this, &VersionProxyModel::sourceRowsMoved);
- connect(replacing, &QAbstractItemModel::layoutAboutToBeChanged, this, &VersionProxyModel::sourceLayoutAboutToBeChanged);
- connect(replacing, &QAbstractItemModel::layoutChanged, this, &VersionProxyModel::sourceLayoutChanged);
- */
- connect(filterModel, &QAbstractItemModel::modelAboutToBeReset, this, &VersionProxyModel::sourceAboutToBeReset);
- connect(filterModel, &QAbstractItemModel::modelReset, this, &VersionProxyModel::sourceReset);
-
- QAbstractProxyModel::setSourceModel(filterModel);
+ filterModel = new VersionFilterModel(this);
+ connect(filterModel, &QAbstractItemModel::dataChanged, this, &VersionProxyModel::sourceDataChanged);
+ connect(filterModel, &QAbstractItemModel::rowsAboutToBeInserted, this, &VersionProxyModel::sourceRowsAboutToBeInserted);
+ connect(filterModel, &QAbstractItemModel::rowsInserted, this, &VersionProxyModel::sourceRowsInserted);
+ connect(filterModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &VersionProxyModel::sourceRowsAboutToBeRemoved);
+ connect(filterModel, &QAbstractItemModel::rowsRemoved, this, &VersionProxyModel::sourceRowsRemoved);
+ // FIXME: implement when needed
+ /*
+ connect(replacing, &QAbstractItemModel::rowsAboutToBeMoved, this, &VersionProxyModel::sourceRowsAboutToBeMoved);
+ connect(replacing, &QAbstractItemModel::rowsMoved, this, &VersionProxyModel::sourceRowsMoved);
+ connect(replacing, &QAbstractItemModel::layoutAboutToBeChanged, this, &VersionProxyModel::sourceLayoutAboutToBeChanged);
+ connect(replacing, &QAbstractItemModel::layoutChanged, this, &VersionProxyModel::sourceLayoutChanged);
+ */
+ connect(filterModel, &QAbstractItemModel::modelAboutToBeReset, this, &VersionProxyModel::sourceAboutToBeReset);
+ connect(filterModel, &QAbstractItemModel::modelReset, this, &VersionProxyModel::sourceReset);
+
+ QAbstractProxyModel::setSourceModel(filterModel);
}
QVariant VersionProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
- if(section < 0 || section >= m_columns.size())
- return QVariant();
- if(orientation != Qt::Horizontal)
- return QVariant();
- auto column = m_columns[section];
- if(role == Qt::DisplayRole)
- {
- switch(column)
- {
- case Name:
- return tr("Version");
- case ParentVersion:
- return tr("Minecraft"); //FIXME: this should come from metadata
- case Branch:
- return tr("Branch");
- case Type:
- return tr("Type");
- case Architecture:
- return tr("Architecture");
- case Path:
- return tr("Path");
- case Time:
- return tr("Released");
- }
- }
- else if(role == Qt::ToolTipRole)
- {
- switch(column)
- {
- case Name:
- return tr("The name of the version.");
- case ParentVersion:
- return tr("Minecraft version"); //FIXME: this should come from metadata
- case Branch:
- return tr("The version's branch");
- case Type:
- return tr("The version's type");
- case Architecture:
- return tr("CPU Architecture");
- case Path:
- return tr("Filesystem path to this version");
- case Time:
- return tr("Release date of this version");
- }
- }
- return QVariant();
+ if(section < 0 || section >= m_columns.size())
+ return QVariant();
+ if(orientation != Qt::Horizontal)
+ return QVariant();
+ auto column = m_columns[section];
+ if(role == Qt::DisplayRole)
+ {
+ switch(column)
+ {
+ case Name:
+ return tr("Version");
+ case ParentVersion:
+ return tr("Minecraft"); //FIXME: this should come from metadata
+ case Branch:
+ return tr("Branch");
+ case Type:
+ return tr("Type");
+ case Architecture:
+ return tr("Architecture");
+ case Path:
+ return tr("Path");
+ case Time:
+ return tr("Released");
+ }
+ }
+ else if(role == Qt::ToolTipRole)
+ {
+ switch(column)
+ {
+ case Name:
+ return tr("The name of the version.");
+ case ParentVersion:
+ return tr("Minecraft version"); //FIXME: this should come from metadata
+ case Branch:
+ return tr("The version's branch");
+ case Type:
+ return tr("The version's type");
+ case Architecture:
+ return tr("CPU Architecture");
+ case Path:
+ return tr("Filesystem path to this version");
+ case Time:
+ return tr("Release date of this version");
+ }
+ }
+ return QVariant();
}
QVariant VersionProxyModel::data(const QModelIndex &index, int role) const
{
- if(!index.isValid())
- {
- return QVariant();
- }
- auto column = m_columns[index.column()];
- auto parentIndex = mapToSource(index);
- switch(role)
- {
- case Qt::DisplayRole:
- {
- switch(column)
- {
- case Name:
- return sourceModel()->data(parentIndex, BaseVersionList::VersionRole);
- case ParentVersion:
- return sourceModel()->data(parentIndex, BaseVersionList::ParentVersionRole);
- case Branch:
- return sourceModel()->data(parentIndex, BaseVersionList::BranchRole);
- case Type:
- return sourceModel()->data(parentIndex, BaseVersionList::TypeRole);
- case Architecture:
- return sourceModel()->data(parentIndex, BaseVersionList::ArchitectureRole);
- case Path:
- return sourceModel()->data(parentIndex, BaseVersionList::PathRole);
- case Time:
- return sourceModel()->data(parentIndex, Meta::VersionList::TimeRole).toDate();
- default:
- return QVariant();
- }
- }
- case Qt::ToolTipRole:
- {
- switch(column)
- {
- case Name:
- {
- if(hasRecommended)
- {
- auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole);
- if(value.toBool())
- {
- return tr("Recommended");
- }
- else if(hasLatest)
- {
- auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole);
- if(value.toBool())
- {
- return tr("Latest");
- }
- }
- else if(index.row() == 0)
- {
- return tr("Latest");
- }
- }
- }
- default:
- {
- return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole);
- }
- }
- }
- case Qt::DecorationRole:
- {
- switch(column)
- {
- case Name:
- {
- if(hasRecommended)
- {
- auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole);
- if(value.toBool())
- {
- return MMC->getThemedIcon("star");
- }
- else if(hasLatest)
- {
- auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole);
- if(value.toBool())
- {
- return MMC->getThemedIcon("bug");
- }
- }
- else if(index.row() == 0)
- {
- return MMC->getThemedIcon("bug");
- }
- auto pixmap = QPixmapCache::find("placeholder");
- if(!pixmap)
- {
- QPixmap px(16,16);
- px.fill(Qt::transparent);
- QPixmapCache::insert("placeholder", px);
- return px;
- }
- return *pixmap;
- }
- }
- default:
- {
- return QVariant();
- }
- }
- }
- default:
- {
- if(roles.contains((BaseVersionList::ModelRoles)role))
- {
- return sourceModel()->data(parentIndex, role);
- }
- return QVariant();
- }
- }
+ if(!index.isValid())
+ {
+ return QVariant();
+ }
+ auto column = m_columns[index.column()];
+ auto parentIndex = mapToSource(index);
+ switch(role)
+ {
+ case Qt::DisplayRole:
+ {
+ switch(column)
+ {
+ case Name:
+ return sourceModel()->data(parentIndex, BaseVersionList::VersionRole);
+ case ParentVersion:
+ return sourceModel()->data(parentIndex, BaseVersionList::ParentVersionRole);
+ case Branch:
+ return sourceModel()->data(parentIndex, BaseVersionList::BranchRole);
+ case Type:
+ return sourceModel()->data(parentIndex, BaseVersionList::TypeRole);
+ case Architecture:
+ return sourceModel()->data(parentIndex, BaseVersionList::ArchitectureRole);
+ case Path:
+ return sourceModel()->data(parentIndex, BaseVersionList::PathRole);
+ case Time:
+ return sourceModel()->data(parentIndex, Meta::VersionList::TimeRole).toDate();
+ default:
+ return QVariant();
+ }
+ }
+ case Qt::ToolTipRole:
+ {
+ switch(column)
+ {
+ case Name:
+ {
+ if(hasRecommended)
+ {
+ auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole);
+ if(value.toBool())
+ {
+ return tr("Recommended");
+ }
+ else if(hasLatest)
+ {
+ auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole);
+ if(value.toBool())
+ {
+ return tr("Latest");
+ }
+ }
+ else if(index.row() == 0)
+ {
+ return tr("Latest");
+ }
+ }
+ }
+ default:
+ {
+ return sourceModel()->data(parentIndex, BaseVersionList::VersionIdRole);
+ }
+ }
+ }
+ case Qt::DecorationRole:
+ {
+ switch(column)
+ {
+ case Name:
+ {
+ if(hasRecommended)
+ {
+ auto value = sourceModel()->data(parentIndex, BaseVersionList::RecommendedRole);
+ if(value.toBool())
+ {
+ return MMC->getThemedIcon("star");
+ }
+ else if(hasLatest)
+ {
+ auto value = sourceModel()->data(parentIndex, BaseVersionList::LatestRole);
+ if(value.toBool())
+ {
+ return MMC->getThemedIcon("bug");
+ }
+ }
+ else if(index.row() == 0)
+ {
+ return MMC->getThemedIcon("bug");
+ }
+ auto pixmap = QPixmapCache::find("placeholder");
+ if(!pixmap)
+ {
+ QPixmap px(16,16);
+ px.fill(Qt::transparent);
+ QPixmapCache::insert("placeholder", px);
+ return px;
+ }
+ return *pixmap;
+ }
+ }
+ default:
+ {
+ return QVariant();
+ }
+ }
+ }
+ default:
+ {
+ if(roles.contains((BaseVersionList::ModelRoles)role))
+ {
+ return sourceModel()->data(parentIndex, role);
+ }
+ return QVariant();
+ }
+ }
}
QModelIndex VersionProxyModel::parent(const QModelIndex &child) const
{
- return QModelIndex();
+ return QModelIndex();
}
QModelIndex VersionProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
{
- if(sourceIndex.isValid())
- {
- return index(sourceIndex.row(), 0);
- }
- return QModelIndex();
+ if(sourceIndex.isValid())
+ {
+ return index(sourceIndex.row(), 0);
+ }
+ return QModelIndex();
}
QModelIndex VersionProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{
- if(proxyIndex.isValid())
- {
- return sourceModel()->index(proxyIndex.row(), 0);
- }
- return QModelIndex();
+ if(proxyIndex.isValid())
+ {
+ return sourceModel()->index(proxyIndex.row(), 0);
+ }
+ return QModelIndex();
}
QModelIndex VersionProxyModel::index(int row, int column, const QModelIndex &parent) const
{
- // no trees here... shoo
- if(parent.isValid())
- {
- return QModelIndex();
- }
- if(row < 0 || row >= sourceModel()->rowCount())
- return QModelIndex();
- if(column < 0 || column >= columnCount())
- return QModelIndex();
- return QAbstractItemModel::createIndex(row, column);
+ // no trees here... shoo
+ if(parent.isValid())
+ {
+ return QModelIndex();
+ }
+ if(row < 0 || row >= sourceModel()->rowCount())
+ return QModelIndex();
+ if(column < 0 || column >= columnCount())
+ return QModelIndex();
+ return QAbstractItemModel::createIndex(row, column);
}
int VersionProxyModel::columnCount(const QModelIndex &parent) const
{
- return m_columns.size();
+ return m_columns.size();
}
int VersionProxyModel::rowCount(const QModelIndex &parent) const
{
- if(sourceModel())
- {
- return sourceModel()->rowCount();
- }
- return 0;
+ if(sourceModel())
+ {
+ return sourceModel()->rowCount();
+ }
+ return 0;
}
void VersionProxyModel::sourceDataChanged(const QModelIndex &source_top_left,
- const QModelIndex &source_bottom_right)
+ const QModelIndex &source_bottom_right)
{
- if(source_top_left.parent() != source_bottom_right.parent())
- return;
+ if(source_top_left.parent() != source_bottom_right.parent())
+ return;
- // whole row is getting changed
- auto topLeft = createIndex(source_top_left.row(), 0);
- auto bottomRight = createIndex(source_bottom_right.row(), columnCount() - 1);
- emit dataChanged(topLeft, bottomRight);
+ // whole row is getting changed
+ auto topLeft = createIndex(source_top_left.row(), 0);
+ auto bottomRight = createIndex(source_bottom_right.row(), columnCount() - 1);
+ emit dataChanged(topLeft, bottomRight);
}
void VersionProxyModel::setSourceModel(QAbstractItemModel *replacingRaw)
{
- auto replacing = dynamic_cast<BaseVersionList *>(replacingRaw);
- beginResetModel();
-
- m_columns.clear();
- if(!replacing)
- {
- roles.clear();
- filterModel->setSourceModel(replacing);
- return;
- }
-
- roles = replacing->providesRoles();
- if(roles.contains(BaseVersionList::VersionRole))
- {
- m_columns.push_back(Name);
- }
- /*
- if(roles.contains(BaseVersionList::ParentVersionRole))
- {
- m_columns.push_back(ParentVersion);
- }
- */
- if(roles.contains(BaseVersionList::ArchitectureRole))
- {
- m_columns.push_back(Architecture);
- }
- if(roles.contains(BaseVersionList::PathRole))
- {
- m_columns.push_back(Path);
- }
- if(roles.contains(Meta::VersionList::TimeRole))
- {
- m_columns.push_back(Time);
- }
- if(roles.contains(BaseVersionList::BranchRole))
- {
- m_columns.push_back(Branch);
- }
- if(roles.contains(BaseVersionList::TypeRole))
- {
- m_columns.push_back(Type);
- }
- if(roles.contains(BaseVersionList::RecommendedRole))
- {
- hasRecommended = true;
- }
- if(roles.contains(BaseVersionList::LatestRole))
- {
- hasLatest = true;
- }
- filterModel->setSourceModel(replacing);
-
- endResetModel();
+ auto replacing = dynamic_cast<BaseVersionList *>(replacingRaw);
+ beginResetModel();
+
+ m_columns.clear();
+ if(!replacing)
+ {
+ roles.clear();
+ filterModel->setSourceModel(replacing);
+ return;
+ }
+
+ roles = replacing->providesRoles();
+ if(roles.contains(BaseVersionList::VersionRole))
+ {
+ m_columns.push_back(Name);
+ }
+ /*
+ if(roles.contains(BaseVersionList::ParentVersionRole))
+ {
+ m_columns.push_back(ParentVersion);
+ }
+ */
+ if(roles.contains(BaseVersionList::ArchitectureRole))
+ {
+ m_columns.push_back(Architecture);
+ }
+ if(roles.contains(BaseVersionList::PathRole))
+ {
+ m_columns.push_back(Path);
+ }
+ if(roles.contains(Meta::VersionList::TimeRole))
+ {
+ m_columns.push_back(Time);
+ }
+ if(roles.contains(BaseVersionList::BranchRole))
+ {
+ m_columns.push_back(Branch);
+ }
+ if(roles.contains(BaseVersionList::TypeRole))
+ {
+ m_columns.push_back(Type);
+ }
+ if(roles.contains(BaseVersionList::RecommendedRole))
+ {
+ hasRecommended = true;
+ }
+ if(roles.contains(BaseVersionList::LatestRole))
+ {
+ hasLatest = true;
+ }
+ filterModel->setSourceModel(replacing);
+
+ endResetModel();
}
QModelIndex VersionProxyModel::getRecommended() const
{
- if(!roles.contains(BaseVersionList::RecommendedRole))
- {
- return index(0, 0);
- }
- int recommended = 0;
- for (int i = 0; i < rowCount(); i++)
- {
- auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::RecommendedRole);
- if (value.toBool())
- {
- recommended = i;
- }
- }
- return index(recommended, 0);
+ if(!roles.contains(BaseVersionList::RecommendedRole))
+ {
+ return index(0, 0);
+ }
+ int recommended = 0;
+ for (int i = 0; i < rowCount(); i++)
+ {
+ auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::RecommendedRole);
+ if (value.toBool())
+ {
+ recommended = i;
+ }
+ }
+ return index(recommended, 0);
}
QModelIndex VersionProxyModel::getVersion(const QString& version) const
{
- int found = -1;
- for (int i = 0; i < rowCount(); i++)
- {
- auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::VersionRole);
- if (value.toString() == version)
- {
- found = i;
- }
- }
- if(found == -1)
- {
- return QModelIndex();
- }
- return index(found, 0);
+ int found = -1;
+ for (int i = 0; i < rowCount(); i++)
+ {
+ auto value = sourceModel()->data(mapToSource(index(i, 0)), BaseVersionList::VersionRole);
+ if (value.toString() == version)
+ {
+ found = i;
+ }
+ }
+ if(found == -1)
+ {
+ return QModelIndex();
+ }
+ return index(found, 0);
}
void VersionProxyModel::clearFilters()
{
- m_filters.clear();
- filterModel->filterChanged();
+ m_filters.clear();
+ filterModel->filterChanged();
}
void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filter * f)
{
- m_filters[column].reset(f);
- filterModel->filterChanged();
+ m_filters[column].reset(f);
+ filterModel->filterChanged();
}
const VersionProxyModel::FilterMap &VersionProxyModel::filters() const
{
- return m_filters;
+ return m_filters;
}
void VersionProxyModel::sourceAboutToBeReset()
{
- beginResetModel();
+ beginResetModel();
}
void VersionProxyModel::sourceReset()
{
- endResetModel();
+ endResetModel();
}
void VersionProxyModel::sourceRowsAboutToBeInserted(const QModelIndex& parent, int first, int last)
{
- beginInsertRows(parent, first, last);
+ beginInsertRows(parent, first, last);
}
void VersionProxyModel::sourceRowsInserted(const QModelIndex& parent, int first, int last)
{
- endInsertRows();
+ endInsertRows();
}
void VersionProxyModel::sourceRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last)
{
- beginRemoveRows(parent, first, last);
+ beginRemoveRows(parent, first, last);
}
void VersionProxyModel::sourceRowsRemoved(const QModelIndex& parent, int first, int last)
{
- endRemoveRows();
+ endRemoveRows();
}
diff --git a/application/VersionProxyModel.h b/application/VersionProxyModel.h
index 91d1ba23..457acfeb 100644
--- a/application/VersionProxyModel.h
+++ b/application/VersionProxyModel.h
@@ -8,58 +8,58 @@ class VersionFilterModel;
class VersionProxyModel: public QAbstractProxyModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum Column
- {
- Name,
- ParentVersion,
- Branch,
- Type,
- Architecture,
- Path,
- Time
- };
- typedef QHash<BaseVersionList::ModelRoles, std::shared_ptr<Filter>> FilterMap;
+ enum Column
+ {
+ Name,
+ ParentVersion,
+ Branch,
+ Type,
+ Architecture,
+ Path,
+ Time
+ };
+ typedef QHash<BaseVersionList::ModelRoles, std::shared_ptr<Filter>> FilterMap;
public:
VersionProxyModel ( QObject* parent = 0 );
virtual ~VersionProxyModel() {};
- virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;
- virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
- virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
- virtual QModelIndex parent(const QModelIndex &child) const override;
- virtual void setSourceModel(QAbstractItemModel *sourceModel) override;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;
+ virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
+ virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+ virtual QModelIndex parent(const QModelIndex &child) const override;
+ virtual void setSourceModel(QAbstractItemModel *sourceModel) override;
- const FilterMap &filters() const;
- void setFilter(const BaseVersionList::ModelRoles column, Filter * filter);
- void clearFilters();
- QModelIndex getRecommended() const;
- QModelIndex getVersion(const QString & version) const;
+ const FilterMap &filters() const;
+ void setFilter(const BaseVersionList::ModelRoles column, Filter * filter);
+ void clearFilters();
+ QModelIndex getRecommended() const;
+ QModelIndex getVersion(const QString & version) const;
private slots:
- void sourceDataChanged(const QModelIndex &source_top_left,const QModelIndex &source_bottom_right);
+ void sourceDataChanged(const QModelIndex &source_top_left,const QModelIndex &source_bottom_right);
- void sourceAboutToBeReset();
- void sourceReset();
+ void sourceAboutToBeReset();
+ void sourceReset();
- void sourceRowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
- void sourceRowsInserted(const QModelIndex &parent, int first, int last);
+ void sourceRowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
+ void sourceRowsInserted(const QModelIndex &parent, int first, int last);
- void sourceRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
- void sourceRowsRemoved(const QModelIndex &parent, int first, int last);
+ void sourceRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
+ void sourceRowsRemoved(const QModelIndex &parent, int first, int last);
private:
- QList<Column> m_columns;
- FilterMap m_filters;
- BaseVersionList::RoleList roles;
- VersionFilterModel * filterModel;
- bool hasRecommended = false;
- bool hasLatest = false;
+ QList<Column> m_columns;
+ FilterMap m_filters;
+ BaseVersionList::RoleList roles;
+ VersionFilterModel * filterModel;
+ bool hasRecommended = false;
+ bool hasLatest = false;
};
diff --git a/application/dialogs/AboutDialog.cpp b/application/dialogs/AboutDialog.cpp
index 8f2e72c2..411f10fc 100644
--- a/application/dialogs/AboutDialog.cpp
+++ b/application/dialogs/AboutDialog.cpp
@@ -27,113 +27,113 @@
// This is a hack, but I can't think of a better way to do this easily without screwing with QTextDocument...
static QString getCreditsHtml(QStringList patrons)
{
- QString creditsHtml = QObject::tr(
- "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN' 'http://www.w3.org/TR/REC-html40/strict.dtd'>"
- "<html>"
- ""
- "<head>"
- "<meta name='qrichtext' content='1' />"
- "<style type='text/css'>"
- "p { white-space: pre-wrap; margin-top:2px; margin-bottom:2px; }"
- "</style>"
- "</head>"
- ""
- "<body style=' font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;'>"
- ""
- "<h3>MultiMC Developers</h3>"
- "<p>Andrew Okin &lt;<a href='mailto:forkk@forkk.net'>forkk@forkk.net</a>&gt;</p>"
- "<p>Petr Mrázek &lt;<a href='mailto:peterix@gmail.com'>peterix@gmail.com</a>&gt;</p>"
- "<p>Sky Welch &lt;<a href='mailto:multimc@bunnies.io'>multimc@bunnies.io</a>&gt;</p>"
- "<p>Jan (02JanDal) &lt;<a href='mailto:02jandal@gmail.com'>02jandal@gmail.com</a>&gt;</p>"
- "<p>RoboSky &lt;<a href='https://twitter.com/RoboSky_'>@RoboSky_</a>&gt;</p>"
- ""
- "<h3>With thanks to</h3>"
- "<p>Orochimarufan &lt;<a href='mailto:orochimarufan.x3@gmail.com'>orochimarufan.x3@gmail.com</a>&gt;</p>"
- "<p>TakSuyu &lt;<a href='mailto:taksuyu@gmail.com'>taksuyu@gmail.com</a>&gt;</p>"
- "<p>Kilobyte &lt;<a href='mailto:stiepen22@gmx.de'>stiepen22@gmx.de</a>&gt;</p>"
- "<p>Rootbear75 &lt;<a href='https://twitter.com/rootbear75'>@rootbear75</a>&gt;</p>"
- ""
- "<h3>Patrons</h3>"
- "%1"
- ""
- "</body>"
- "</html>");
- if (patrons.isEmpty())
- return creditsHtml.arg(QObject::tr("<p>Loading...</p>"));
- else
- {
- QString patronsStr;
- for (QString patron : patrons)
- {
- patronsStr.append(QString("<p>%1</p>").arg(patron));
- }
-
- return creditsHtml.arg(patronsStr);
- }
+ QString creditsHtml = QObject::tr(
+ "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN' 'http://www.w3.org/TR/REC-html40/strict.dtd'>"
+ "<html>"
+ ""
+ "<head>"
+ "<meta name='qrichtext' content='1' />"
+ "<style type='text/css'>"
+ "p { white-space: pre-wrap; margin-top:2px; margin-bottom:2px; }"
+ "</style>"
+ "</head>"
+ ""
+ "<body style=' font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;'>"
+ ""
+ "<h3>MultiMC Developers</h3>"
+ "<p>Andrew Okin &lt;<a href='mailto:forkk@forkk.net'>forkk@forkk.net</a>&gt;</p>"
+ "<p>Petr Mrázek &lt;<a href='mailto:peterix@gmail.com'>peterix@gmail.com</a>&gt;</p>"
+ "<p>Sky Welch &lt;<a href='mailto:multimc@bunnies.io'>multimc@bunnies.io</a>&gt;</p>"
+ "<p>Jan (02JanDal) &lt;<a href='mailto:02jandal@gmail.com'>02jandal@gmail.com</a>&gt;</p>"
+ "<p>RoboSky &lt;<a href='https://twitter.com/RoboSky_'>@RoboSky_</a>&gt;</p>"
+ ""
+ "<h3>With thanks to</h3>"
+ "<p>Orochimarufan &lt;<a href='mailto:orochimarufan.x3@gmail.com'>orochimarufan.x3@gmail.com</a>&gt;</p>"
+ "<p>TakSuyu &lt;<a href='mailto:taksuyu@gmail.com'>taksuyu@gmail.com</a>&gt;</p>"
+ "<p>Kilobyte &lt;<a href='mailto:stiepen22@gmx.de'>stiepen22@gmx.de</a>&gt;</p>"
+ "<p>Rootbear75 &lt;<a href='https://twitter.com/rootbear75'>@rootbear75</a>&gt;</p>"
+ ""
+ "<h3>Patrons</h3>"
+ "%1"
+ ""
+ "</body>"
+ "</html>");
+ if (patrons.isEmpty())
+ return creditsHtml.arg(QObject::tr("<p>Loading...</p>"));
+ else
+ {
+ QString patronsStr;
+ for (QString patron : patrons)
+ {
+ patronsStr.append(QString("<p>%1</p>").arg(patron));
+ }
+
+ return creditsHtml.arg(patronsStr);
+ }
}
static QString getLicenseHtml()
{
- HoeDown hoedown;
- QFile dataFile(":/documents/COPYING.md");
- dataFile.open(QIODevice::ReadOnly);
- QString output = hoedown.process(dataFile.readAll());
- return output;
+ HoeDown hoedown;
+ QFile dataFile(":/documents/COPYING.md");
+ dataFile.open(QIODevice::ReadOnly);
+ QString output = hoedown.process(dataFile.readAll());
+ return output;
}
AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog)
{
- ui->setupUi(this);
+ ui->setupUi(this);
- QString chtml = getCreditsHtml(QStringList());
- ui->creditsText->setHtml(chtml);
+ QString chtml = getCreditsHtml(QStringList());
+ ui->creditsText->setHtml(chtml);
- QString lhtml = getLicenseHtml();
- ui->licenseText->setHtml(lhtml);
+ QString lhtml = getLicenseHtml();
+ ui->licenseText->setHtml(lhtml);
- ui->urlLabel->setOpenExternalLinks(true);
+ ui->urlLabel->setOpenExternalLinks(true);
- ui->icon->setPixmap(MMC->getThemedIcon("logo").pixmap(64));
- ui->title->setText("MultiMC 5");
+ ui->icon->setPixmap(MMC->getThemedIcon("logo").pixmap(64));
+ ui->title->setText("MultiMC 5");
- ui->versionLabel->setText(tr("Version") +": " + BuildConfig.printableVersionString());
- ui->platformLabel->setText(tr("Platform") +": " + BuildConfig.BUILD_PLATFORM);
+ ui->versionLabel->setText(tr("Version") +": " + BuildConfig.printableVersionString());
+ ui->platformLabel->setText(tr("Platform") +": " + BuildConfig.BUILD_PLATFORM);
- if (BuildConfig.VERSION_BUILD >= 0)
- ui->buildNumLabel->setText(tr("Build Number") +": " + QString::number(BuildConfig.VERSION_BUILD));
- else
- ui->buildNumLabel->setVisible(false);
+ if (BuildConfig.VERSION_BUILD >= 0)
+ ui->buildNumLabel->setText(tr("Build Number") +": " + QString::number(BuildConfig.VERSION_BUILD));
+ else
+ ui->buildNumLabel->setVisible(false);
- if (!BuildConfig.VERSION_CHANNEL.isEmpty())
- ui->channelLabel->setText(tr("Channel") +": " + BuildConfig.VERSION_CHANNEL);
- else
- ui->channelLabel->setVisible(false);
+ if (!BuildConfig.VERSION_CHANNEL.isEmpty())
+ ui->channelLabel->setText(tr("Channel") +": " + BuildConfig.VERSION_CHANNEL);
+ else
+ ui->channelLabel->setVisible(false);
- connect(ui->closeButton, SIGNAL(clicked()), SLOT(close()));
+ connect(ui->closeButton, SIGNAL(clicked()), SLOT(close()));
- connect(ui->aboutQt, &QPushButton::clicked, &QApplication::aboutQt);
+ connect(ui->aboutQt, &QPushButton::clicked, &QApplication::aboutQt);
- loadPatronList();
+ loadPatronList();
}
AboutDialog::~AboutDialog()
{
- delete ui;
+ delete ui;
}
void AboutDialog::loadPatronList()
{
- netJob.reset(new NetJob("Patreon Patron List"));
- netJob->addNetAction(Net::Download::makeByteArray(QUrl("http://files.multimc.org/patrons.txt"), &dataSink));
- connect(netJob.get(), &NetJob::succeeded, this, &AboutDialog::patronListLoaded);
- netJob->start();
+ netJob.reset(new NetJob("Patreon Patron List"));
+ netJob->addNetAction(Net::Download::makeByteArray(QUrl("http://files.multimc.org/patrons.txt"), &dataSink));
+ connect(netJob.get(), &NetJob::succeeded, this, &AboutDialog::patronListLoaded);
+ netJob->start();
}
void AboutDialog::patronListLoaded()
{
- QString patronListStr(dataSink);
- dataSink.clear();
- QString html = getCreditsHtml(patronListStr.split("\n", QString::SkipEmptyParts));
- ui->creditsText->setHtml(html);
+ QString patronListStr(dataSink);
+ dataSink.clear();
+ QString html = getCreditsHtml(patronListStr.split("\n", QString::SkipEmptyParts));
+ ui->creditsText->setHtml(html);
}
diff --git a/application/dialogs/AboutDialog.h b/application/dialogs/AboutDialog.h
index 9768b866..96624041 100644
--- a/application/dialogs/AboutDialog.h
+++ b/application/dialogs/AboutDialog.h
@@ -25,23 +25,23 @@ class AboutDialog;
class AboutDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit AboutDialog(QWidget *parent = 0);
- ~AboutDialog();
+ explicit AboutDialog(QWidget *parent = 0);
+ ~AboutDialog();
public
slots:
- /// Starts loading a list of Patreon patrons.
- void loadPatronList();
-
- /// Slot for when the patron list loads successfully.
- void patronListLoaded();
+ /// Starts loading a list of Patreon patrons.
+ void loadPatronList();
+
+ /// Slot for when the patron list loads successfully.
+ void patronListLoaded();
private:
- Ui::AboutDialog *ui;
+ Ui::AboutDialog *ui;
- NetJobPtr netJob;
- QByteArray dataSink;
+ NetJobPtr netJob;
+ QByteArray dataSink;
};
diff --git a/application/dialogs/CopyInstanceDialog.cpp b/application/dialogs/CopyInstanceDialog.cpp
index 72ef00fa..c565510c 100644
--- a/application/dialogs/CopyInstanceDialog.cpp
+++ b/application/dialogs/CopyInstanceDialog.cpp
@@ -29,87 +29,87 @@
#include "InstanceList.h"
CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent)
- :QDialog(parent), ui(new Ui::CopyInstanceDialog), m_original(original)
+ :QDialog(parent), ui(new Ui::CopyInstanceDialog), m_original(original)
{
- ui->setupUi(this);
- resize(minimumSizeHint());
- layout()->setSizeConstraint(QLayout::SetFixedSize);
-
- InstIconKey = original->iconKey();
- ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
- ui->instNameTextBox->setText(original->name());
- ui->instNameTextBox->setFocus();
- auto groups = MMC->instances()->getGroups().toSet();
- auto groupList = QStringList(groups.toList());
- groupList.sort(Qt::CaseInsensitive);
- groupList.removeOne("");
- groupList.push_front("");
- ui->groupBox->addItems(groupList);
- int index = groupList.indexOf(m_original->group());
- if(index == -1)
- {
- index = 0;
- }
- ui->groupBox->setCurrentIndex(index);
- ui->groupBox->lineEdit()->setPlaceholderText(tr("No group"));
- ui->copySavesCheckbox->setChecked(m_copySaves);
+ ui->setupUi(this);
+ resize(minimumSizeHint());
+ layout()->setSizeConstraint(QLayout::SetFixedSize);
+
+ InstIconKey = original->iconKey();
+ ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
+ ui->instNameTextBox->setText(original->name());
+ ui->instNameTextBox->setFocus();
+ auto groups = MMC->instances()->getGroups().toSet();
+ auto groupList = QStringList(groups.toList());
+ groupList.sort(Qt::CaseInsensitive);
+ groupList.removeOne("");
+ groupList.push_front("");
+ ui->groupBox->addItems(groupList);
+ int index = groupList.indexOf(m_original->group());
+ if(index == -1)
+ {
+ index = 0;
+ }
+ ui->groupBox->setCurrentIndex(index);
+ ui->groupBox->lineEdit()->setPlaceholderText(tr("No group"));
+ ui->copySavesCheckbox->setChecked(m_copySaves);
}
CopyInstanceDialog::~CopyInstanceDialog()
{
- delete ui;
+ delete ui;
}
void CopyInstanceDialog::updateDialogState()
{
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!instName().isEmpty());
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!instName().isEmpty());
}
QString CopyInstanceDialog::instName() const
{
- return ui->instNameTextBox->text();
+ return ui->instNameTextBox->text();
}
QString CopyInstanceDialog::iconKey() const
{
- return InstIconKey;
+ return InstIconKey;
}
QString CopyInstanceDialog::instGroup() const
{
- return ui->groupBox->currentText();
+ return ui->groupBox->currentText();
}
void CopyInstanceDialog::on_iconButton_clicked()
{
- IconPickerDialog dlg(this);
- dlg.execWithSelection(InstIconKey);
-
- if (dlg.result() == QDialog::Accepted)
- {
- InstIconKey = dlg.selectedIconKey;
- ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
- }
+ IconPickerDialog dlg(this);
+ dlg.execWithSelection(InstIconKey);
+
+ if (dlg.result() == QDialog::Accepted)
+ {
+ InstIconKey = dlg.selectedIconKey;
+ ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
+ }
}
void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1)
{
- updateDialogState();
+ updateDialogState();
}
bool CopyInstanceDialog::shouldCopySaves() const
{
- return m_copySaves;
+ return m_copySaves;
}
void CopyInstanceDialog::on_copySavesCheckbox_stateChanged(int state)
{
- if(state == Qt::Unchecked)
- {
- m_copySaves = false;
- }
- else if(state == Qt::Checked)
- {
- m_copySaves = true;
- }
+ if(state == Qt::Unchecked)
+ {
+ m_copySaves = false;
+ }
+ else if(state == Qt::Checked)
+ {
+ m_copySaves = true;
+ }
}
diff --git a/application/dialogs/CopyInstanceDialog.h b/application/dialogs/CopyInstanceDialog.h
index 809552eb..83ef2b3a 100644
--- a/application/dialogs/CopyInstanceDialog.h
+++ b/application/dialogs/CopyInstanceDialog.h
@@ -28,28 +28,28 @@ class CopyInstanceDialog;
class CopyInstanceDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit CopyInstanceDialog(InstancePtr original, QWidget *parent = 0);
- ~CopyInstanceDialog();
+ explicit CopyInstanceDialog(InstancePtr original, QWidget *parent = 0);
+ ~CopyInstanceDialog();
- void updateDialogState();
+ void updateDialogState();
- QString instName() const;
- QString instGroup() const;
- QString iconKey() const;
- bool shouldCopySaves() const;
+ QString instName() const;
+ QString instGroup() const;
+ QString iconKey() const;
+ bool shouldCopySaves() const;
private
slots:
- void on_iconButton_clicked();
- void on_instNameTextBox_textChanged(const QString &arg1);
- void on_copySavesCheckbox_stateChanged(int state);
+ void on_iconButton_clicked();
+ void on_instNameTextBox_textChanged(const QString &arg1);
+ void on_copySavesCheckbox_stateChanged(int state);
private:
- Ui::CopyInstanceDialog *ui;
- QString InstIconKey;
- InstancePtr m_original;
- bool m_copySaves = true;
+ Ui::CopyInstanceDialog *ui;
+ QString InstIconKey;
+ InstancePtr m_original;
+ bool m_copySaves = true;
};
diff --git a/application/dialogs/CustomMessageBox.cpp b/application/dialogs/CustomMessageBox.cpp
index a7d75263..0ef3c8ce 100644
--- a/application/dialogs/CustomMessageBox.cpp
+++ b/application/dialogs/CustomMessageBox.cpp
@@ -18,18 +18,18 @@
namespace CustomMessageBox
{
QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text,
- QMessageBox::Icon icon, QMessageBox::StandardButtons buttons,
- QMessageBox::StandardButton defaultButton)
+ QMessageBox::Icon icon, QMessageBox::StandardButtons buttons,
+ QMessageBox::StandardButton defaultButton)
{
- QMessageBox *messageBox = new QMessageBox(parent);
- messageBox->setWindowTitle(title);
- messageBox->setText(text);
- messageBox->setStandardButtons(buttons);
- messageBox->setDefaultButton(defaultButton);
- messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
- messageBox->setIcon(icon);
- messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ QMessageBox *messageBox = new QMessageBox(parent);
+ messageBox->setWindowTitle(title);
+ messageBox->setText(text);
+ messageBox->setStandardButtons(buttons);
+ messageBox->setDefaultButton(defaultButton);
+ messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ messageBox->setIcon(icon);
+ messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
- return messageBox;
+ return messageBox;
}
}
diff --git a/application/dialogs/CustomMessageBox.h b/application/dialogs/CustomMessageBox.h
index f9c0ad4e..09e7b46a 100644
--- a/application/dialogs/CustomMessageBox.h
+++ b/application/dialogs/CustomMessageBox.h
@@ -20,7 +20,7 @@
namespace CustomMessageBox
{
QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text,
- QMessageBox::Icon icon = QMessageBox::NoIcon,
- QMessageBox::StandardButtons buttons = QMessageBox::Ok,
- QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+ QMessageBox::Icon icon = QMessageBox::NoIcon,
+ QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
}
diff --git a/application/dialogs/EditAccountDialog.cpp b/application/dialogs/EditAccountDialog.cpp
index e43be1d8..5ab3b025 100644
--- a/application/dialogs/EditAccountDialog.cpp
+++ b/application/dialogs/EditAccountDialog.cpp
@@ -19,43 +19,43 @@
#include <QUrl>
EditAccountDialog::EditAccountDialog(const QString &text, QWidget *parent, int flags)
- : QDialog(parent), ui(new Ui::EditAccountDialog)
+ : QDialog(parent), ui(new Ui::EditAccountDialog)
{
- ui->setupUi(this);
+ ui->setupUi(this);
- ui->label->setText(text);
- ui->label->setVisible(!text.isEmpty());
+ ui->label->setText(text);
+ ui->label->setVisible(!text.isEmpty());
- ui->userTextBox->setEnabled(flags & UsernameField);
- ui->passTextBox->setEnabled(flags & PasswordField);
+ ui->userTextBox->setEnabled(flags & UsernameField);
+ ui->passTextBox->setEnabled(flags & PasswordField);
}
EditAccountDialog::~EditAccountDialog()
{
- delete ui;
+ delete ui;
}
void EditAccountDialog::on_label_linkActivated(const QString &link)
{
- DesktopServices::openUrl(QUrl(link));
+ DesktopServices::openUrl(QUrl(link));
}
void EditAccountDialog::setUsername(const QString & user) const
{
- ui->userTextBox->setText(user);
+ ui->userTextBox->setText(user);
}
QString EditAccountDialog::username() const
{
- return ui->userTextBox->text();
+ return ui->userTextBox->text();
}
void EditAccountDialog::setPassword(const QString & pass) const
{
- ui->passTextBox->setText(pass);
+ ui->passTextBox->setText(pass);
}
QString EditAccountDialog::password() const
{
- return ui->passTextBox->text();
+ return ui->passTextBox->text();
}
diff --git a/application/dialogs/EditAccountDialog.h b/application/dialogs/EditAccountDialog.h
index f121a111..1346d00e 100644
--- a/application/dialogs/EditAccountDialog.h
+++ b/application/dialogs/EditAccountDialog.h
@@ -24,33 +24,33 @@ class EditAccountDialog;
class EditAccountDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit EditAccountDialog(const QString &text = "", QWidget *parent = 0,
- int flags = UsernameField | PasswordField);
- ~EditAccountDialog();
+ explicit EditAccountDialog(const QString &text = "", QWidget *parent = 0,
+ int flags = UsernameField | PasswordField);
+ ~EditAccountDialog();
- void setUsername(const QString & user) const;
- void setPassword(const QString & pass) const;
+ void setUsername(const QString & user) const;
+ void setPassword(const QString & pass) const;
- QString username() const;
- QString password() const;
+ QString username() const;
+ QString password() const;
- enum Flags
- {
- NoFlags = 0,
+ enum Flags
+ {
+ NoFlags = 0,
- //! Specifies that the dialog should have a username field.
- UsernameField,
+ //! Specifies that the dialog should have a username field.
+ UsernameField,
- //! Specifies that the dialog should have a password field.
- PasswordField,
- };
+ //! Specifies that the dialog should have a password field.
+ PasswordField,
+ };
private slots:
void on_label_linkActivated(const QString &link);
private:
- Ui::EditAccountDialog *ui;
+ Ui::EditAccountDialog *ui;
};
diff --git a/application/dialogs/ExportInstanceDialog.cpp b/application/dialogs/ExportInstanceDialog.cpp
index 9029ca50..a9045829 100644
--- a/application/dialogs/ExportInstanceDialog.cpp
+++ b/application/dialogs/ExportInstanceDialog.cpp
@@ -33,456 +33,456 @@
class PackIgnoreProxy : public QSortFilterProxyModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- PackIgnoreProxy(InstancePtr instance, QObject *parent) : QSortFilterProxyModel(parent)
- {
- m_instance = instance;
- }
- // NOTE: Sadly, we have to do sorting ourselves.
- bool lessThan(const QModelIndex &left, const QModelIndex &right) const
- {
- QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel());
- if (!fsm)
- {
- return QSortFilterProxyModel::lessThan(left, right);
- }
- bool asc = sortOrder() == Qt::AscendingOrder ? true : false;
-
- QFileInfo leftFileInfo = fsm->fileInfo(left);
- QFileInfo rightFileInfo = fsm->fileInfo(right);
-
- if (!leftFileInfo.isDir() && rightFileInfo.isDir())
- {
- return !asc;
- }
- if (leftFileInfo.isDir() && !rightFileInfo.isDir())
- {
- return asc;
- }
-
- // sort and proxy model breaks the original model...
- if (sortColumn() == 0)
- {
- return Strings::naturalCompare(leftFileInfo.fileName(), rightFileInfo.fileName(),
- Qt::CaseInsensitive) < 0;
- }
- if (sortColumn() == 1)
- {
- auto leftSize = leftFileInfo.size();
- auto rightSize = rightFileInfo.size();
- if ((leftSize == rightSize) || (leftFileInfo.isDir() && rightFileInfo.isDir()))
- {
- return Strings::naturalCompare(leftFileInfo.fileName(),
- rightFileInfo.fileName(),
- Qt::CaseInsensitive) < 0
- ? asc
- : !asc;
- }
- return leftSize < rightSize;
- }
- return QSortFilterProxyModel::lessThan(left, right);
- }
-
- virtual Qt::ItemFlags flags(const QModelIndex &index) const
- {
- if (!index.isValid())
- return Qt::NoItemFlags;
-
- auto sourceIndex = mapToSource(index);
- Qt::ItemFlags flags = sourceIndex.flags();
- if (index.column() == 0)
- {
- flags |= Qt::ItemIsUserCheckable;
- if (sourceIndex.model()->hasChildren(sourceIndex))
- {
- flags |= Qt::ItemIsTristate;
- }
- }
-
- return flags;
- }
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
- {
- QModelIndex sourceIndex = mapToSource(index);
-
- if (index.column() == 0 && role == Qt::CheckStateRole)
- {
- QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel());
- auto blockedPath = relPath(fsm->filePath(sourceIndex));
- auto cover = blocked.cover(blockedPath);
- if (!cover.isNull())
- {
- return QVariant(Qt::Unchecked);
- }
- else if (blocked.exists(blockedPath))
- {
- return QVariant(Qt::PartiallyChecked);
- }
- else
- {
- return QVariant(Qt::Checked);
- }
- }
-
- return sourceIndex.data(role);
- }
-
- virtual bool setData(const QModelIndex &index, const QVariant &value,
- int role = Qt::EditRole)
- {
- if (index.column() == 0 && role == Qt::CheckStateRole)
- {
- Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
- return setFilterState(index, state);
- }
-
- QModelIndex sourceIndex = mapToSource(index);
- return QSortFilterProxyModel::sourceModel()->setData(sourceIndex, value, role);
- }
-
- QString relPath(const QString &path) const
- {
- QString prefix = QDir().absoluteFilePath(m_instance->instanceRoot());
- prefix += '/';
- if (!path.startsWith(prefix))
- {
- return QString();
- }
- return path.mid(prefix.size());
- }
-
- bool setFilterState(QModelIndex index, Qt::CheckState state)
- {
- QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel());
-
- if (!fsm)
- {
- return false;
- }
-
- QModelIndex sourceIndex = mapToSource(index);
- auto blockedPath = relPath(fsm->filePath(sourceIndex));
- bool changed = false;
- if (state == Qt::Unchecked)
- {
- // blocking a path
- auto &node = blocked.insert(blockedPath);
- // get rid of all blocked nodes below
- node.clear();
- changed = true;
- }
- else if (state == Qt::Checked || state == Qt::PartiallyChecked)
- {
- if (!blocked.remove(blockedPath))
- {
- auto cover = blocked.cover(blockedPath);
- qDebug() << "Blocked by cover" << cover;
- // uncover
- blocked.remove(cover);
- // block all contents, except for any cover
- QModelIndex rootIndex =
- fsm->index(FS::PathCombine(m_instance->instanceRoot(), cover));
- QModelIndex doing = rootIndex;
- int row = 0;
- QStack<QModelIndex> todo;
- while (1)
- {
- auto node = doing.child(row, 0);
- if (!node.isValid())
- {
- if (!todo.size())
- {
- break;
- }
- else
- {
- doing = todo.pop();
- row = 0;
- continue;
- }
- }
- auto relpath = relPath(fsm->filePath(node));
- if (blockedPath.startsWith(relpath)) // cover found?
- {
- // continue processing cover later
- todo.push(node);
- }
- else
- {
- // or just block this one.
- blocked.insert(relpath);
- }
- row++;
- }
- }
- changed = true;
- }
- if (changed)
- {
- // update the thing
- emit dataChanged(index, index, {Qt::CheckStateRole});
- // update everything above index
- QModelIndex up = index.parent();
- while (1)
- {
- if (!up.isValid())
- break;
- emit dataChanged(up, up, {Qt::CheckStateRole});
- up = up.parent();
- }
- // and everything below the index
- QModelIndex doing = index;
- int row = 0;
- QStack<QModelIndex> todo;
- while (1)
- {
- auto node = doing.child(row, 0);
- if (!node.isValid())
- {
- if (!todo.size())
- {
- break;
- }
- else
- {
- doing = todo.pop();
- row = 0;
- continue;
- }
- }
- emit dataChanged(node, node, {Qt::CheckStateRole});
- todo.push(node);
- row++;
- }
- // siblings and unrelated nodes are ignored
- }
- return true;
- }
-
- bool shouldExpand(QModelIndex index)
- {
- QModelIndex sourceIndex = mapToSource(index);
- QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel());
- if (!fsm)
- {
- return false;
- }
- auto blockedPath = relPath(fsm->filePath(sourceIndex));
- auto found = blocked.find(blockedPath);
- if(found)
- {
- return !found->leaf();
- }
- return false;
- }
-
- void setBlockedPaths(QStringList paths)
- {
- beginResetModel();
- blocked.clear();
- blocked.insert(paths);
- endResetModel();
- }
-
- const SeparatorPrefixTree<'/'> & blockedPaths() const
- {
- return blocked;
- }
+ PackIgnoreProxy(InstancePtr instance, QObject *parent) : QSortFilterProxyModel(parent)
+ {
+ m_instance = instance;
+ }
+ // NOTE: Sadly, we have to do sorting ourselves.
+ bool lessThan(const QModelIndex &left, const QModelIndex &right) const
+ {
+ QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel());
+ if (!fsm)
+ {
+ return QSortFilterProxyModel::lessThan(left, right);
+ }
+ bool asc = sortOrder() == Qt::AscendingOrder ? true : false;
+
+ QFileInfo leftFileInfo = fsm->fileInfo(left);
+ QFileInfo rightFileInfo = fsm->fileInfo(right);
+
+ if (!leftFileInfo.isDir() && rightFileInfo.isDir())
+ {
+ return !asc;
+ }
+ if (leftFileInfo.isDir() && !rightFileInfo.isDir())
+ {
+ return asc;
+ }
+
+ // sort and proxy model breaks the original model...
+ if (sortColumn() == 0)
+ {
+ return Strings::naturalCompare(leftFileInfo.fileName(), rightFileInfo.fileName(),
+ Qt::CaseInsensitive) < 0;
+ }
+ if (sortColumn() == 1)
+ {
+ auto leftSize = leftFileInfo.size();
+ auto rightSize = rightFileInfo.size();
+ if ((leftSize == rightSize) || (leftFileInfo.isDir() && rightFileInfo.isDir()))
+ {
+ return Strings::naturalCompare(leftFileInfo.fileName(),
+ rightFileInfo.fileName(),
+ Qt::CaseInsensitive) < 0
+ ? asc
+ : !asc;
+ }
+ return leftSize < rightSize;
+ }
+ return QSortFilterProxyModel::lessThan(left, right);
+ }
+
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const
+ {
+ if (!index.isValid())
+ return Qt::NoItemFlags;
+
+ auto sourceIndex = mapToSource(index);
+ Qt::ItemFlags flags = sourceIndex.flags();
+ if (index.column() == 0)
+ {
+ flags |= Qt::ItemIsUserCheckable;
+ if (sourceIndex.model()->hasChildren(sourceIndex))
+ {
+ flags |= Qt::ItemIsTristate;
+ }
+ }
+
+ return flags;
+ }
+
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
+ {
+ QModelIndex sourceIndex = mapToSource(index);
+
+ if (index.column() == 0 && role == Qt::CheckStateRole)
+ {
+ QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel());
+ auto blockedPath = relPath(fsm->filePath(sourceIndex));
+ auto cover = blocked.cover(blockedPath);
+ if (!cover.isNull())
+ {
+ return QVariant(Qt::Unchecked);
+ }
+ else if (blocked.exists(blockedPath))
+ {
+ return QVariant(Qt::PartiallyChecked);
+ }
+ else
+ {
+ return QVariant(Qt::Checked);
+ }
+ }
+
+ return sourceIndex.data(role);
+ }
+
+ virtual bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole)
+ {
+ if (index.column() == 0 && role == Qt::CheckStateRole)
+ {
+ Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
+ return setFilterState(index, state);
+ }
+
+ QModelIndex sourceIndex = mapToSource(index);
+ return QSortFilterProxyModel::sourceModel()->setData(sourceIndex, value, role);
+ }
+
+ QString relPath(const QString &path) const
+ {
+ QString prefix = QDir().absoluteFilePath(m_instance->instanceRoot());
+ prefix += '/';
+ if (!path.startsWith(prefix))
+ {
+ return QString();
+ }
+ return path.mid(prefix.size());
+ }
+
+ bool setFilterState(QModelIndex index, Qt::CheckState state)
+ {
+ QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel());
+
+ if (!fsm)
+ {
+ return false;
+ }
+
+ QModelIndex sourceIndex = mapToSource(index);
+ auto blockedPath = relPath(fsm->filePath(sourceIndex));
+ bool changed = false;
+ if (state == Qt::Unchecked)
+ {
+ // blocking a path
+ auto &node = blocked.insert(blockedPath);
+ // get rid of all blocked nodes below
+ node.clear();
+ changed = true;
+ }
+ else if (state == Qt::Checked || state == Qt::PartiallyChecked)
+ {
+ if (!blocked.remove(blockedPath))
+ {
+ auto cover = blocked.cover(blockedPath);
+ qDebug() << "Blocked by cover" << cover;
+ // uncover
+ blocked.remove(cover);
+ // block all contents, except for any cover
+ QModelIndex rootIndex =
+ fsm->index(FS::PathCombine(m_instance->instanceRoot(), cover));
+ QModelIndex doing = rootIndex;
+ int row = 0;
+ QStack<QModelIndex> todo;
+ while (1)
+ {
+ auto node = doing.child(row, 0);
+ if (!node.isValid())
+ {
+ if (!todo.size())
+ {
+ break;
+ }
+ else
+ {
+ doing = todo.pop();
+ row = 0;
+ continue;
+ }
+ }
+ auto relpath = relPath(fsm->filePath(node));
+ if (blockedPath.startsWith(relpath)) // cover found?
+ {
+ // continue processing cover later
+ todo.push(node);
+ }
+ else
+ {
+ // or just block this one.
+ blocked.insert(relpath);
+ }
+ row++;
+ }
+ }
+ changed = true;
+ }
+ if (changed)
+ {
+ // update the thing
+ emit dataChanged(index, index, {Qt::CheckStateRole});
+ // update everything above index
+ QModelIndex up = index.parent();
+ while (1)
+ {
+ if (!up.isValid())
+ break;
+ emit dataChanged(up, up, {Qt::CheckStateRole});
+ up = up.parent();
+ }
+ // and everything below the index
+ QModelIndex doing = index;
+ int row = 0;
+ QStack<QModelIndex> todo;
+ while (1)
+ {
+ auto node = doing.child(row, 0);
+ if (!node.isValid())
+ {
+ if (!todo.size())
+ {
+ break;
+ }
+ else
+ {
+ doing = todo.pop();
+ row = 0;
+ continue;
+ }
+ }
+ emit dataChanged(node, node, {Qt::CheckStateRole});
+ todo.push(node);
+ row++;
+ }
+ // siblings and unrelated nodes are ignored
+ }
+ return true;
+ }
+
+ bool shouldExpand(QModelIndex index)
+ {
+ QModelIndex sourceIndex = mapToSource(index);
+ QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel());
+ if (!fsm)
+ {
+ return false;
+ }
+ auto blockedPath = relPath(fsm->filePath(sourceIndex));
+ auto found = blocked.find(blockedPath);
+ if(found)
+ {
+ return !found->leaf();
+ }
+ return false;
+ }
+
+ void setBlockedPaths(QStringList paths)
+ {
+ beginResetModel();
+ blocked.clear();
+ blocked.insert(paths);
+ endResetModel();
+ }
+
+ const SeparatorPrefixTree<'/'> & blockedPaths() const
+ {
+ return blocked;
+ }
protected:
- bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const
- {
- Q_UNUSED(source_parent)
+ bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const
+ {
+ Q_UNUSED(source_parent)
- // adjust the columns you want to filter out here
- // return false for those that will be hidden
- if (source_column == 2 || source_column == 3)
- return false;
+ // adjust the columns you want to filter out here
+ // return false for those that will be hidden
+ if (source_column == 2 || source_column == 3)
+ return false;
- return true;
- }
+ return true;
+ }
private:
- InstancePtr m_instance;
- SeparatorPrefixTree<'/'> blocked;
+ InstancePtr m_instance;
+ SeparatorPrefixTree<'/'> blocked;
};
ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget *parent)
- : QDialog(parent), ui(new Ui::ExportInstanceDialog), m_instance(instance)
+ : QDialog(parent), ui(new Ui::ExportInstanceDialog), m_instance(instance)
{
- ui->setupUi(this);
- auto model = new QFileSystemModel(this);
- proxyModel = new PackIgnoreProxy(m_instance, this);
- loadPackIgnore();
- proxyModel->setSourceModel(model);
- auto root = instance->instanceRoot();
- ui->treeView->setModel(proxyModel);
- ui->treeView->setRootIndex(proxyModel->mapFromSource(model->index(root)));
- ui->treeView->sortByColumn(0, Qt::AscendingOrder);
-
- connect(proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int)));
-
- model->setFilter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden);
- model->setRootPath(root);
- auto headerView = ui->treeView->header();
- headerView->setSectionResizeMode(QHeaderView::ResizeToContents);
- headerView->setSectionResizeMode(0, QHeaderView::Stretch);
+ ui->setupUi(this);
+ auto model = new QFileSystemModel(this);
+ proxyModel = new PackIgnoreProxy(m_instance, this);
+ loadPackIgnore();
+ proxyModel->setSourceModel(model);
+ auto root = instance->instanceRoot();
+ ui->treeView->setModel(proxyModel);
+ ui->treeView->setRootIndex(proxyModel->mapFromSource(model->index(root)));
+ ui->treeView->sortByColumn(0, Qt::AscendingOrder);
+
+ connect(proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int)));
+
+ model->setFilter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden);
+ model->setRootPath(root);
+ auto headerView = ui->treeView->header();
+ headerView->setSectionResizeMode(QHeaderView::ResizeToContents);
+ headerView->setSectionResizeMode(0, QHeaderView::Stretch);
}
ExportInstanceDialog::~ExportInstanceDialog()
{
- delete ui;
+ delete ui;
}
/// Save icon to instance's folder is needed
void SaveIcon(InstancePtr m_instance)
{
- auto iconKey = m_instance->iconKey();
- auto iconList = MMC->icons();
- auto mmcIcon = iconList->icon(iconKey);
- if(mmcIcon)
- {
- bool saveIcon = false;
- switch(mmcIcon->type())
- {
- case IconType::FileBased:
- case IconType::Transient:
- saveIcon = true;
- default:
- break;
- }
- if(saveIcon)
- {
- auto & image = mmcIcon->m_images[mmcIcon->type()];
- auto & icon = image.icon;
- auto sizes = icon.availableSizes();
- if(sizes.size() == 0)
- {
- return;
- }
- auto areaOf = [](QSize size)
- {
- return size.width() * size.height();
- };
- QSize largest = sizes[0];
- // find variant with largest area
- for(auto size: sizes)
- {
- if(areaOf(largest) < areaOf(size))
- {
- largest = size;
- }
- }
- auto pixmap = icon.pixmap(largest);
- pixmap.save(FS::PathCombine(m_instance->instanceRoot(), iconKey + ".png"));
- }
- }
+ auto iconKey = m_instance->iconKey();
+ auto iconList = MMC->icons();
+ auto mmcIcon = iconList->icon(iconKey);
+ if(mmcIcon)
+ {
+ bool saveIcon = false;
+ switch(mmcIcon->type())
+ {
+ case IconType::FileBased:
+ case IconType::Transient:
+ saveIcon = true;
+ default:
+ break;
+ }
+ if(saveIcon)
+ {
+ auto & image = mmcIcon->m_images[mmcIcon->type()];
+ auto & icon = image.icon;
+ auto sizes = icon.availableSizes();
+ if(sizes.size() == 0)
+ {
+ return;
+ }
+ auto areaOf = [](QSize size)
+ {
+ return size.width() * size.height();
+ };
+ QSize largest = sizes[0];
+ // find variant with largest area
+ for(auto size: sizes)
+ {
+ if(areaOf(largest) < areaOf(size))
+ {
+ largest = size;
+ }
+ }
+ auto pixmap = icon.pixmap(largest);
+ pixmap.save(FS::PathCombine(m_instance->instanceRoot(), iconKey + ".png"));
+ }
+ }
}
bool ExportInstanceDialog::doExport()
{
- auto name = FS::RemoveInvalidFilenameChars(m_instance->name());
-
- const QString output = QFileDialog::getSaveFileName(
- this, tr("Export %1").arg(m_instance->name()),
- FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr, QFileDialog::DontConfirmOverwrite);
- if (output.isEmpty())
- {
- return false;
- }
- if (QFile::exists(output))
- {
- int ret =
- QMessageBox::question(this, tr("Overwrite?"),
- tr("This file already exists. Do you want to overwrite it?"),
- QMessageBox::No, QMessageBox::Yes);
- if (ret == QMessageBox::No)
- {
- return false;
- }
- }
-
- SaveIcon(m_instance);
-
- auto & blocked = proxyModel->blockedPaths();
- using std::placeholders::_1;
- if (!JlCompress::compressDir(output, m_instance->instanceRoot(), name, std::bind(&SeparatorPrefixTree<'/'>::covers, blocked, _1)))
- {
- QMessageBox::warning(this, tr("Error"), tr("Unable to export instance"));
- return false;
- }
- return true;
+ auto name = FS::RemoveInvalidFilenameChars(m_instance->name());
+
+ const QString output = QFileDialog::getSaveFileName(
+ this, tr("Export %1").arg(m_instance->name()),
+ FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr, QFileDialog::DontConfirmOverwrite);
+ if (output.isEmpty())
+ {
+ return false;
+ }
+ if (QFile::exists(output))
+ {
+ int ret =
+ QMessageBox::question(this, tr("Overwrite?"),
+ tr("This file already exists. Do you want to overwrite it?"),
+ QMessageBox::No, QMessageBox::Yes);
+ if (ret == QMessageBox::No)
+ {
+ return false;
+ }
+ }
+
+ SaveIcon(m_instance);
+
+ auto & blocked = proxyModel->blockedPaths();
+ using std::placeholders::_1;
+ if (!JlCompress::compressDir(output, m_instance->instanceRoot(), name, std::bind(&SeparatorPrefixTree<'/'>::covers, blocked, _1)))
+ {
+ QMessageBox::warning(this, tr("Error"), tr("Unable to export instance"));
+ return false;
+ }
+ return true;
}
void ExportInstanceDialog::done(int result)
{
- savePackIgnore();
- if (result == QDialog::Accepted)
- {
- if (doExport())
- {
- QDialog::done(QDialog::Accepted);
- return;
- }
- else
- {
- return;
- }
- }
- QDialog::done(result);
+ savePackIgnore();
+ if (result == QDialog::Accepted)
+ {
+ if (doExport())
+ {
+ QDialog::done(QDialog::Accepted);
+ return;
+ }
+ else
+ {
+ return;
+ }
+ }
+ QDialog::done(result);
}
void ExportInstanceDialog::rowsInserted(QModelIndex parent, int top, int bottom)
{
- //WARNING: possible off-by-one?
- for(int i = top; i < bottom; i++)
- {
- auto node = parent.child(i, 0);
- if(proxyModel->shouldExpand(node))
- {
- auto expNode = node.parent();
- if(!expNode.isValid())
- {
- continue;
- }
- ui->treeView->expand(node);
- }
- }
+ //WARNING: possible off-by-one?
+ for(int i = top; i < bottom; i++)
+ {
+ auto node = parent.child(i, 0);
+ if(proxyModel->shouldExpand(node))
+ {
+ auto expNode = node.parent();
+ if(!expNode.isValid())
+ {
+ continue;
+ }
+ ui->treeView->expand(node);
+ }
+ }
}
QString ExportInstanceDialog::ignoreFileName()
{
- return FS::PathCombine(m_instance->instanceRoot(), ".packignore");
+ return FS::PathCombine(m_instance->instanceRoot(), ".packignore");
}
void ExportInstanceDialog::loadPackIgnore()
{
- auto filename = ignoreFileName();
- QFile ignoreFile(filename);
- if(!ignoreFile.open(QIODevice::ReadOnly))
- {
- return;
- }
- auto data = ignoreFile.readAll();
- auto string = QString::fromUtf8(data);
- proxyModel->setBlockedPaths(string.split('\n', QString::SkipEmptyParts));
+ auto filename = ignoreFileName();
+ QFile ignoreFile(filename);
+ if(!ignoreFile.open(QIODevice::ReadOnly))
+ {
+ return;
+ }
+ auto data = ignoreFile.readAll();
+ auto string = QString::fromUtf8(data);
+ proxyModel->setBlockedPaths(string.split('\n', QString::SkipEmptyParts));
}
void ExportInstanceDialog::savePackIgnore()
{
- auto data = proxyModel->blockedPaths().toStringList().join('\n').toUtf8();
- auto filename = ignoreFileName();
- try
- {
- FS::write(filename, data);
- }
- catch (const Exception &e)
- {
- qWarning() << e.cause();
- }
+ auto data = proxyModel->blockedPaths().toStringList().join('\n').toUtf8();
+ auto filename = ignoreFileName();
+ try
+ {
+ FS::write(filename, data);
+ }
+ catch (const Exception &e)
+ {
+ qWarning() << e.cause();
+ }
}
#include "ExportInstanceDialog.moc"
diff --git a/application/dialogs/ExportInstanceDialog.h b/application/dialogs/ExportInstanceDialog.h
index 7b9c6726..4032314d 100644
--- a/application/dialogs/ExportInstanceDialog.h
+++ b/application/dialogs/ExportInstanceDialog.h
@@ -30,25 +30,25 @@ class ExportInstanceDialog;
class ExportInstanceDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ExportInstanceDialog(InstancePtr instance, QWidget *parent = 0);
- ~ExportInstanceDialog();
+ explicit ExportInstanceDialog(InstancePtr instance, QWidget *parent = 0);
+ ~ExportInstanceDialog();
- virtual void done(int result);
+ virtual void done(int result);
private:
- bool doExport();
- void loadPackIgnore();
- void savePackIgnore();
- QString ignoreFileName();
+ bool doExport();
+ void loadPackIgnore();
+ void savePackIgnore();
+ QString ignoreFileName();
private:
- Ui::ExportInstanceDialog *ui;
- InstancePtr m_instance;
- PackIgnoreProxy * proxyModel;
+ Ui::ExportInstanceDialog *ui;
+ InstancePtr m_instance;
+ PackIgnoreProxy * proxyModel;
private slots:
- void rowsInserted(QModelIndex parent, int top, int bottom);
+ void rowsInserted(QModelIndex parent, int top, int bottom);
};
diff --git a/application/dialogs/IconPickerDialog.cpp b/application/dialogs/IconPickerDialog.cpp
index 4ffd12bc..2306bad0 100644
--- a/application/dialogs/IconPickerDialog.cpp
+++ b/application/dialogs/IconPickerDialog.cpp
@@ -28,135 +28,135 @@
#include <DesktopServices.h>
IconPickerDialog::IconPickerDialog(QWidget *parent)
- : QDialog(parent), ui(new Ui::IconPickerDialog)
+ : QDialog(parent), ui(new Ui::IconPickerDialog)
{
- ui->setupUi(this);
- setWindowModality(Qt::WindowModal);
-
- auto contentsWidget = ui->iconView;
- contentsWidget->setViewMode(QListView::IconMode);
- contentsWidget->setFlow(QListView::LeftToRight);
- contentsWidget->setIconSize(QSize(48, 48));
- contentsWidget->setMovement(QListView::Static);
- contentsWidget->setResizeMode(QListView::Adjust);
- contentsWidget->setSelectionMode(QAbstractItemView::SingleSelection);
- contentsWidget->setSpacing(5);
- contentsWidget->setWordWrap(false);
- contentsWidget->setWrapping(true);
- contentsWidget->setUniformItemSizes(true);
- contentsWidget->setTextElideMode(Qt::ElideRight);
- contentsWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
- contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- contentsWidget->setItemDelegate(new ListViewDelegate());
-
- // contentsWidget->setAcceptDrops(true);
- contentsWidget->setDropIndicatorShown(true);
- contentsWidget->viewport()->setAcceptDrops(true);
- contentsWidget->setDragDropMode(QAbstractItemView::DropOnly);
- contentsWidget->setDefaultDropAction(Qt::CopyAction);
-
- contentsWidget->installEventFilter(this);
-
- contentsWidget->setModel(MMC->icons().get());
-
- // NOTE: ResetRole forces the button to be on the left, while the OK/Cancel ones are on the right. We win.
- auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"), QDialogButtonBox::ResetRole);
- auto buttonRemove = ui->buttonBox->addButton(tr("Remove Icon"), QDialogButtonBox::ResetRole);
-
- connect(buttonAdd, SIGNAL(clicked(bool)), SLOT(addNewIcon()));
- connect(buttonRemove, SIGNAL(clicked(bool)), SLOT(removeSelectedIcon()));
-
- connect(contentsWidget, SIGNAL(doubleClicked(QModelIndex)), SLOT(activated(QModelIndex)));
-
- connect(contentsWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection)));
-
- auto buttonFolder = ui->buttonBox->addButton(tr("Open Folder"), QDialogButtonBox::ResetRole);
- connect(buttonFolder, &QPushButton::clicked, this, &IconPickerDialog::openFolder);
+ ui->setupUi(this);
+ setWindowModality(Qt::WindowModal);
+
+ auto contentsWidget = ui->iconView;
+ contentsWidget->setViewMode(QListView::IconMode);
+ contentsWidget->setFlow(QListView::LeftToRight);
+ contentsWidget->setIconSize(QSize(48, 48));
+ contentsWidget->setMovement(QListView::Static);
+ contentsWidget->setResizeMode(QListView::Adjust);
+ contentsWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+ contentsWidget->setSpacing(5);
+ contentsWidget->setWordWrap(false);
+ contentsWidget->setWrapping(true);
+ contentsWidget->setUniformItemSizes(true);
+ contentsWidget->setTextElideMode(Qt::ElideRight);
+ contentsWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
+ contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ contentsWidget->setItemDelegate(new ListViewDelegate());
+
+ // contentsWidget->setAcceptDrops(true);
+ contentsWidget->setDropIndicatorShown(true);
+ contentsWidget->viewport()->setAcceptDrops(true);
+ contentsWidget->setDragDropMode(QAbstractItemView::DropOnly);
+ contentsWidget->setDefaultDropAction(Qt::CopyAction);
+
+ contentsWidget->installEventFilter(this);
+
+ contentsWidget->setModel(MMC->icons().get());
+
+ // NOTE: ResetRole forces the button to be on the left, while the OK/Cancel ones are on the right. We win.
+ auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"), QDialogButtonBox::ResetRole);
+ auto buttonRemove = ui->buttonBox->addButton(tr("Remove Icon"), QDialogButtonBox::ResetRole);
+
+ connect(buttonAdd, SIGNAL(clicked(bool)), SLOT(addNewIcon()));
+ connect(buttonRemove, SIGNAL(clicked(bool)), SLOT(removeSelectedIcon()));
+
+ connect(contentsWidget, SIGNAL(doubleClicked(QModelIndex)), SLOT(activated(QModelIndex)));
+
+ connect(contentsWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection)));
+
+ auto buttonFolder = ui->buttonBox->addButton(tr("Open Folder"), QDialogButtonBox::ResetRole);
+ connect(buttonFolder, &QPushButton::clicked, this, &IconPickerDialog::openFolder);
}
bool IconPickerDialog::eventFilter(QObject *obj, QEvent *evt)
{
- if (obj != ui->iconView)
- return QDialog::eventFilter(obj, evt);
- if (evt->type() != QEvent::KeyPress)
- {
- return QDialog::eventFilter(obj, evt);
- }
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
- switch (keyEvent->key())
- {
- case Qt::Key_Delete:
- removeSelectedIcon();
- return true;
- case Qt::Key_Plus:
- addNewIcon();
- return true;
- default:
- break;
- }
- return QDialog::eventFilter(obj, evt);
+ if (obj != ui->iconView)
+ return QDialog::eventFilter(obj, evt);
+ if (evt->type() != QEvent::KeyPress)
+ {
+ return QDialog::eventFilter(obj, evt);
+ }
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
+ switch (keyEvent->key())
+ {
+ case Qt::Key_Delete:
+ removeSelectedIcon();
+ return true;
+ case Qt::Key_Plus:
+ addNewIcon();
+ return true;
+ default:
+ break;
+ }
+ return QDialog::eventFilter(obj, evt);
}
void IconPickerDialog::addNewIcon()
{
- //: The title of the select icons open file dialog
- QString selectIcons = tr("Select Icons");
- //: The type of icon files
- QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(),
- tr("Icons") + "(*.png *.jpg *.jpeg *.ico *.svg)");
- MMC->icons()->installIcons(fileNames);
+ //: The title of the select icons open file dialog
+ QString selectIcons = tr("Select Icons");
+ //: The type of icon files
+ QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(),
+ tr("Icons") + "(*.png *.jpg *.jpeg *.ico *.svg)");
+ MMC->icons()->installIcons(fileNames);
}
void IconPickerDialog::removeSelectedIcon()
{
- MMC->icons()->deleteIcon(selectedIconKey);
+ MMC->icons()->deleteIcon(selectedIconKey);
}
void IconPickerDialog::activated(QModelIndex index)
{
- selectedIconKey = index.data(Qt::UserRole).toString();
- accept();
+ selectedIconKey = index.data(Qt::UserRole).toString();
+ accept();
}
void IconPickerDialog::selectionChanged(QItemSelection selected, QItemSelection deselected)
{
- if (selected.empty())
- return;
+ if (selected.empty())
+ return;
- QString key = selected.first().indexes().first().data(Qt::UserRole).toString();
- if (!key.isEmpty())
- selectedIconKey = key;
+ QString key = selected.first().indexes().first().data(Qt::UserRole).toString();
+ if (!key.isEmpty())
+ selectedIconKey = key;
}
int IconPickerDialog::execWithSelection(QString selection)
{
- auto list = MMC->icons();
- auto contentsWidget = ui->iconView;
- selectedIconKey = selection;
-
- int index_nr = list->getIconIndex(selection);
- auto model_index = list->index(index_nr);
- contentsWidget->selectionModel()->select(
- model_index, QItemSelectionModel::Current | QItemSelectionModel::Select);
-
- QMetaObject::invokeMethod(this, "delayed_scroll", Qt::QueuedConnection,
- Q_ARG(QModelIndex, model_index));
- return QDialog::exec();
+ auto list = MMC->icons();
+ auto contentsWidget = ui->iconView;
+ selectedIconKey = selection;
+
+ int index_nr = list->getIconIndex(selection);
+ auto model_index = list->index(index_nr);
+ contentsWidget->selectionModel()->select(
+ model_index, QItemSelectionModel::Current | QItemSelectionModel::Select);
+
+ QMetaObject::invokeMethod(this, "delayed_scroll", Qt::QueuedConnection,
+ Q_ARG(QModelIndex, model_index));
+ return QDialog::exec();
}
void IconPickerDialog::delayed_scroll(QModelIndex model_index)
{
- auto contentsWidget = ui->iconView;
- contentsWidget->scrollTo(model_index);
+ auto contentsWidget = ui->iconView;
+ contentsWidget->scrollTo(model_index);
}
IconPickerDialog::~IconPickerDialog()
{
- delete ui;
+ delete ui;
}
void IconPickerDialog::openFolder()
{
- DesktopServices::openDirectory(MMC->icons()->getDirectory(), true);
+ DesktopServices::openDirectory(MMC->icons()->getDirectory(), true);
}
diff --git a/application/dialogs/IconPickerDialog.h b/application/dialogs/IconPickerDialog.h
index 9053ec61..c76f9a34 100644
--- a/application/dialogs/IconPickerDialog.h
+++ b/application/dialogs/IconPickerDialog.h
@@ -24,26 +24,26 @@ class IconPickerDialog;
class IconPickerDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit IconPickerDialog(QWidget *parent = 0);
- ~IconPickerDialog();
- int execWithSelection(QString selection);
- QString selectedIconKey;
+ explicit IconPickerDialog(QWidget *parent = 0);
+ ~IconPickerDialog();
+ int execWithSelection(QString selection);
+ QString selectedIconKey;
protected:
- virtual bool eventFilter(QObject *, QEvent *);
+ virtual bool eventFilter(QObject *, QEvent *);
private:
- Ui::IconPickerDialog *ui;
+ Ui::IconPickerDialog *ui;
private
slots:
- void selectionChanged(QItemSelection, QItemSelection);
- void activated(QModelIndex);
- void delayed_scroll(QModelIndex);
- void addNewIcon();
- void removeSelectedIcon();
- void openFolder();
+ void selectionChanged(QItemSelection, QItemSelection);
+ void activated(QModelIndex);
+ void delayed_scroll(QModelIndex);
+ void addNewIcon();
+ void removeSelectedIcon();
+ void openFolder();
};
diff --git a/application/dialogs/LoginDialog.cpp b/application/dialogs/LoginDialog.cpp
index b2020372..276aebb9 100644
--- a/application/dialogs/LoginDialog.cpp
+++ b/application/dialogs/LoginDialog.cpp
@@ -22,89 +22,89 @@
LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::LoginDialog)
{
- ui->setupUi(this);
- ui->progressBar->setVisible(false);
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+ ui->setupUi(this);
+ ui->progressBar->setVisible(false);
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
- connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
- connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+ connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
LoginDialog::~LoginDialog()
{
- delete ui;
+ delete ui;
}
// Stage 1: User interaction
void LoginDialog::accept()
{
- setUserInputsEnabled(false);
- ui->progressBar->setVisible(true);
-
- // Setup the login task and start it
- m_account = MojangAccount::createFromUsername(ui->userTextBox->text());
- m_loginTask = m_account->login(nullptr, ui->passTextBox->text());
- connect(m_loginTask.get(), &Task::failed, this, &LoginDialog::onTaskFailed);
- connect(m_loginTask.get(), &Task::succeeded, this,
- &LoginDialog::onTaskSucceeded);
- connect(m_loginTask.get(), &Task::status, this, &LoginDialog::onTaskStatus);
- connect(m_loginTask.get(), &Task::progress, this, &LoginDialog::onTaskProgress);
- m_loginTask->start();
+ setUserInputsEnabled(false);
+ ui->progressBar->setVisible(true);
+
+ // Setup the login task and start it
+ m_account = MojangAccount::createFromUsername(ui->userTextBox->text());
+ m_loginTask = m_account->login(nullptr, ui->passTextBox->text());
+ connect(m_loginTask.get(), &Task::failed, this, &LoginDialog::onTaskFailed);
+ connect(m_loginTask.get(), &Task::succeeded, this,
+ &LoginDialog::onTaskSucceeded);
+ connect(m_loginTask.get(), &Task::status, this, &LoginDialog::onTaskStatus);
+ connect(m_loginTask.get(), &Task::progress, this, &LoginDialog::onTaskProgress);
+ m_loginTask->start();
}
void LoginDialog::setUserInputsEnabled(bool enable)
{
- ui->userTextBox->setEnabled(enable);
- ui->passTextBox->setEnabled(enable);
- ui->buttonBox->setEnabled(enable);
+ ui->userTextBox->setEnabled(enable);
+ ui->passTextBox->setEnabled(enable);
+ ui->buttonBox->setEnabled(enable);
}
// Enable the OK button only when both textboxes contain something.
void LoginDialog::on_userTextBox_textEdited(const QString &newText)
{
- ui->buttonBox->button(QDialogButtonBox::Ok)
- ->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty());
+ ui->buttonBox->button(QDialogButtonBox::Ok)
+ ->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty());
}
void LoginDialog::on_passTextBox_textEdited(const QString &newText)
{
- ui->buttonBox->button(QDialogButtonBox::Ok)
- ->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty());
+ ui->buttonBox->button(QDialogButtonBox::Ok)
+ ->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty());
}
void LoginDialog::onTaskFailed(const QString &reason)
{
- // Set message
- ui->label->setText("<span style='color:red'>" + reason + "</span>");
+ // Set message
+ ui->label->setText("<span style='color:red'>" + reason + "</span>");
- // Re-enable user-interaction
- setUserInputsEnabled(true);
- ui->progressBar->setVisible(false);
+ // Re-enable user-interaction
+ setUserInputsEnabled(true);
+ ui->progressBar->setVisible(false);
}
void LoginDialog::onTaskSucceeded()
{
- QDialog::accept();
+ QDialog::accept();
}
void LoginDialog::onTaskStatus(const QString &status)
{
- ui->label->setText(status);
+ ui->label->setText(status);
}
void LoginDialog::onTaskProgress(qint64 current, qint64 total)
{
- ui->progressBar->setMaximum(total);
- ui->progressBar->setValue(current);
+ ui->progressBar->setMaximum(total);
+ ui->progressBar->setValue(current);
}
// Public interface
MojangAccountPtr LoginDialog::newAccount(QWidget *parent, QString msg)
{
- LoginDialog dlg(parent);
- dlg.ui->label->setText(msg);
- if (dlg.exec() == QDialog::Accepted)
- {
- return dlg.m_account;
- }
- return 0;
+ LoginDialog dlg(parent);
+ dlg.ui->label->setText(msg);
+ if (dlg.exec() == QDialog::Accepted)
+ {
+ return dlg.m_account;
+ }
+ return 0;
}
diff --git a/application/dialogs/LoginDialog.h b/application/dialogs/LoginDialog.h
index 27b97cb0..355599ec 100644
--- a/application/dialogs/LoginDialog.h
+++ b/application/dialogs/LoginDialog.h
@@ -27,32 +27,32 @@ class LoginDialog;
class LoginDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- ~LoginDialog();
+ ~LoginDialog();
- static MojangAccountPtr newAccount(QWidget *parent, QString message);
+ static MojangAccountPtr newAccount(QWidget *parent, QString message);
private:
- explicit LoginDialog(QWidget *parent = 0);
+ explicit LoginDialog(QWidget *parent = 0);
- void setUserInputsEnabled(bool enable);
+ void setUserInputsEnabled(bool enable);
protected
slots:
- void accept();
+ void accept();
- void onTaskFailed(const QString &reason);
- void onTaskSucceeded();
- void onTaskStatus(const QString &status);
- void onTaskProgress(qint64 current, qint64 total);
+ void onTaskFailed(const QString &reason);
+ void onTaskSucceeded();
+ void onTaskStatus(const QString &status);
+ void onTaskProgress(qint64 current, qint64 total);
- void on_userTextBox_textEdited(const QString &newText);
- void on_passTextBox_textEdited(const QString &newText);
+ void on_userTextBox_textEdited(const QString &newText);
+ void on_passTextBox_textEdited(const QString &newText);
private:
- Ui::LoginDialog *ui;
- MojangAccountPtr m_account;
- std::shared_ptr<Task> m_loginTask;
+ Ui::LoginDialog *ui;
+ MojangAccountPtr m_account;
+ std::shared_ptr<Task> m_loginTask;
};
diff --git a/application/dialogs/ModEditDialogCommon.cpp b/application/dialogs/ModEditDialogCommon.cpp
index 4201bdad..e92c5c4d 100644
--- a/application/dialogs/ModEditDialogCommon.cpp
+++ b/application/dialogs/ModEditDialogCommon.cpp
@@ -4,37 +4,37 @@
bool lastfirst(QModelIndexList &list, int &first, int &last)
{
- if (list.isEmpty())
- return false;
- first = last = list[0].row();
- for (auto item : list)
- {
- int row = item.row();
- if (row < first)
- first = row;
- if (row > last)
- last = row;
- }
- return true;
+ if (list.isEmpty())
+ return false;
+ first = last = list[0].row();
+ for (auto item : list)
+ {
+ int row = item.row();
+ if (row < first)
+ first = row;
+ if (row > last)
+ last = row;
+ }
+ return true;
}
void showWebsiteForMod(QWidget *parentDlg, Mod &m)
{
- QString url = m.homeurl();
- if (url.size())
- {
- // catch the cases where the protocol is missing
- if (!url.startsWith("http"))
- {
- url = "http://" + url;
- }
- DesktopServices::openUrl(url);
- }
- else
- {
- CustomMessageBox::selectable(
- parentDlg, QObject::tr("How sad!"),
- QObject::tr("The mod author didn't provide a website link for this mod."),
- QMessageBox::Warning);
- }
+ QString url = m.homeurl();
+ if (url.size())
+ {
+ // catch the cases where the protocol is missing
+ if (!url.startsWith("http"))
+ {
+ url = "http://" + url;
+ }
+ DesktopServices::openUrl(url);
+ }
+ else
+ {
+ CustomMessageBox::selectable(
+ parentDlg, QObject::tr("How sad!"),
+ QObject::tr("The mod author didn't provide a website link for this mod."),
+ QMessageBox::Warning);
+ }
}
diff --git a/application/dialogs/NewComponentDialog.cpp b/application/dialogs/NewComponentDialog.cpp
index 514aa938..c82ba62b 100644
--- a/application/dialogs/NewComponentDialog.cpp
+++ b/application/dialogs/NewComponentDialog.cpp
@@ -35,72 +35,72 @@
#include <meta/VersionList.h>
NewComponentDialog::NewComponentDialog(const QString & initialName, const QString & initialUid, QWidget *parent)
- : QDialog(parent), ui(new Ui::NewComponentDialog)
+ : QDialog(parent), ui(new Ui::NewComponentDialog)
{
- ui->setupUi(this);
- resize(minimumSizeHint());
+ ui->setupUi(this);
+ resize(minimumSizeHint());
- ui->nameTextBox->setText(initialName);
- ui->uidTextBox->setText(initialUid);
+ ui->nameTextBox->setText(initialName);
+ ui->uidTextBox->setText(initialUid);
- connect(ui->nameTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState);
- connect(ui->uidTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState);
+ connect(ui->nameTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState);
+ connect(ui->uidTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState);
- auto groups = MMC->instances()->getGroups().toSet();
- ui->nameTextBox->setFocus();
+ auto groups = MMC->instances()->getGroups().toSet();
+ ui->nameTextBox->setFocus();
- originalPlaceholderText = ui->uidTextBox->placeholderText();
- updateDialogState();
+ originalPlaceholderText = ui->uidTextBox->placeholderText();
+ updateDialogState();
}
NewComponentDialog::~NewComponentDialog()
{
- delete ui;
+ delete ui;
}
void NewComponentDialog::updateDialogState()
{
- auto protoUid = ui->nameTextBox->text().toLower();
- protoUid.remove(QRegularExpression("[^a-z]"));
- if(protoUid.isEmpty())
- {
- ui->uidTextBox->setPlaceholderText(originalPlaceholderText);
- }
- else
- {
- QString suggestedUid = "org.multimc.custom." + protoUid;
- ui->uidTextBox->setPlaceholderText(suggestedUid);
- }
- bool allowOK = !name().isEmpty() && !uid().isEmpty() && !uidBlacklist.contains(uid());
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
+ auto protoUid = ui->nameTextBox->text().toLower();
+ protoUid.remove(QRegularExpression("[^a-z]"));
+ if(protoUid.isEmpty())
+ {
+ ui->uidTextBox->setPlaceholderText(originalPlaceholderText);
+ }
+ else
+ {
+ QString suggestedUid = "org.multimc.custom." + protoUid;
+ ui->uidTextBox->setPlaceholderText(suggestedUid);
+ }
+ bool allowOK = !name().isEmpty() && !uid().isEmpty() && !uidBlacklist.contains(uid());
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
}
QString NewComponentDialog::name() const
{
- auto result = ui->nameTextBox->text();
- if(result.size())
- {
- return result.trimmed();
- }
- return QString();
+ auto result = ui->nameTextBox->text();
+ if(result.size())
+ {
+ return result.trimmed();
+ }
+ return QString();
}
QString NewComponentDialog::uid() const
{
- auto result = ui->uidTextBox->text();
- if(result.size())
- {
- return result.trimmed();
- }
- result = ui->uidTextBox->placeholderText();
- if(result.size() && result != originalPlaceholderText)
- {
- return result.trimmed();
- }
- return QString();
+ auto result = ui->uidTextBox->text();
+ if(result.size())
+ {
+ return result.trimmed();
+ }
+ result = ui->uidTextBox->placeholderText();
+ if(result.size() && result != originalPlaceholderText)
+ {
+ return result.trimmed();
+ }
+ return QString();
}
void NewComponentDialog::setBlacklist(QStringList badUids)
{
- uidBlacklist = badUids;
+ uidBlacklist = badUids;
}
diff --git a/application/dialogs/NewComponentDialog.h b/application/dialogs/NewComponentDialog.h
index 70caec0f..23192605 100644
--- a/application/dialogs/NewComponentDialog.h
+++ b/application/dialogs/NewComponentDialog.h
@@ -27,22 +27,22 @@ class NewComponentDialog;
class NewComponentDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit NewComponentDialog(const QString & initialName = QString(), const QString & initialUid = QString(), QWidget *parent = 0);
- virtual ~NewComponentDialog();
- void setBlacklist(QStringList badUids);
+ explicit NewComponentDialog(const QString & initialName = QString(), const QString & initialUid = QString(), QWidget *parent = 0);
+ virtual ~NewComponentDialog();
+ void setBlacklist(QStringList badUids);
- QString name() const;
- QString uid() const;
+ QString name() const;
+ QString uid() const;
private slots:
- void updateDialogState();
+ void updateDialogState();
private:
- Ui::NewComponentDialog *ui;
+ Ui::NewComponentDialog *ui;
- QString originalPlaceholderText;
- QStringList uidBlacklist;
+ QString originalPlaceholderText;
+ QStringList uidBlacklist;
};
diff --git a/application/dialogs/NewInstanceDialog.cpp b/application/dialogs/NewInstanceDialog.cpp
index 01843505..f1247a50 100644
--- a/application/dialogs/NewInstanceDialog.cpp
+++ b/application/dialogs/NewInstanceDialog.cpp
@@ -40,178 +40,178 @@
#include <pages/modplatform/TechnicPage.h>
NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString & url, QWidget *parent)
- : QDialog(parent), ui(new Ui::NewInstanceDialog)
+ : QDialog(parent), ui(new Ui::NewInstanceDialog)
{
- ui->setupUi(this);
+ ui->setupUi(this);
- setWindowIcon(MMC->getThemedIcon("new"));
+ setWindowIcon(MMC->getThemedIcon("new"));
- InstIconKey = "default";
- ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
+ InstIconKey = "default";
+ ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
- auto groups = MMC->instances()->getGroups().toSet();
- auto groupList = QStringList(groups.toList());
- groupList.sort(Qt::CaseInsensitive);
- groupList.removeOne("");
- groupList.push_front(initialGroup);
- groupList.push_front("");
- ui->groupBox->addItems(groupList);
- int index = groupList.indexOf(initialGroup);
- if(index == -1)
- {
- index = 0;
- }
- ui->groupBox->setCurrentIndex(index);
- ui->groupBox->lineEdit()->setPlaceholderText(tr("No group"));
+ auto groups = MMC->instances()->getGroups().toSet();
+ auto groupList = QStringList(groups.toList());
+ groupList.sort(Qt::CaseInsensitive);
+ groupList.removeOne("");
+ groupList.push_front(initialGroup);
+ groupList.push_front("");
+ ui->groupBox->addItems(groupList);
+ int index = groupList.indexOf(initialGroup);
+ if(index == -1)
+ {
+ index = 0;
+ }
+ ui->groupBox->setCurrentIndex(index);
+ ui->groupBox->lineEdit()->setPlaceholderText(tr("No group"));
- m_buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- m_buttons->button(QDialogButtonBox::Ok)->setDefault(true);
+ m_buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ m_buttons->button(QDialogButtonBox::Ok)->setDefault(true);
- m_container = new PageContainer(this);
- m_container->setSizePolicy(QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Expanding);
- m_container->layout()->setContentsMargins(0, 0, 0, 0);
- ui->verticalLayout->insertWidget(2, m_container);
+ m_container = new PageContainer(this);
+ m_container->setSizePolicy(QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Expanding);
+ m_container->layout()->setContentsMargins(0, 0, 0, 0);
+ ui->verticalLayout->insertWidget(2, m_container);
- m_container->addButtons(m_buttons);
- m_buttons->setFocus();
+ m_container->addButtons(m_buttons);
+ m_buttons->setFocus();
- if(!url.isEmpty())
- {
- m_container->selectPage("import");
- importPage->setUrl(url);
- }
+ if(!url.isEmpty())
+ {
+ m_container->selectPage("import");
+ importPage->setUrl(url);
+ }
- connect(m_buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &NewInstanceDialog::accept);
- connect(m_buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &NewInstanceDialog::reject);
- connect(m_buttons->button(QDialogButtonBox::Help), &QPushButton::clicked, m_container, &PageContainer::help);
+ connect(m_buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &NewInstanceDialog::accept);
+ connect(m_buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &NewInstanceDialog::reject);
+ connect(m_buttons->button(QDialogButtonBox::Help), &QPushButton::clicked, m_container, &PageContainer::help);
- updateDialogState();
+ updateDialogState();
- restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("NewInstanceGeometry").toByteArray()));
+ restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("NewInstanceGeometry").toByteArray()));
}
void NewInstanceDialog::reject()
{
- MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());
- QDialog::reject();
+ MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());
+ QDialog::reject();
}
void NewInstanceDialog::accept()
{
- MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());
- importIconNow();
- QDialog::accept();
+ MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());
+ importIconNow();
+ QDialog::accept();
}
QList<BasePage *> NewInstanceDialog::getPages()
{
- importPage = new ImportPage(this);
- return
- {
- new VanillaPage(this),
- new FTBPage(this),
- importPage,
- new TwitchPage(this),
- new TechnicPage(this)
- };
+ importPage = new ImportPage(this);
+ return
+ {
+ new VanillaPage(this),
+ new FTBPage(this),
+ importPage,
+ new TwitchPage(this),
+ new TechnicPage(this)
+ };
}
QString NewInstanceDialog::dialogTitle()
{
- return tr("New Instance");
+ return tr("New Instance");
}
NewInstanceDialog::~NewInstanceDialog()
{
- delete ui;
+ delete ui;
}
void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task)
{
- creationTask.reset(task);
- ui->instNameTextBox->setPlaceholderText(name);
+ creationTask.reset(task);
+ ui->instNameTextBox->setPlaceholderText(name);
- auto allowOK = task && !instName().isEmpty();
- m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
+ auto allowOK = task && !instName().isEmpty();
+ m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
}
void NewInstanceDialog::setSuggestedIconFromFile(const QString &path, const QString &name)
{
- importIcon = true;
- importIconPath = path;
- importIconName = name;
+ importIcon = true;
+ importIconPath = path;
+ importIconName = name;
- //Hmm, for some reason they can be to small
- ui->iconButton->setIcon(QIcon(path));
+ //Hmm, for some reason they can be to small
+ ui->iconButton->setIcon(QIcon(path));
}
InstanceTask * NewInstanceDialog::extractTask()
{
- InstanceTask * extracted = creationTask.get();
- creationTask.release();
- extracted->setName(instName());
- extracted->setGroup(instGroup());
- extracted->setIcon(iconKey());
- return extracted;
+ InstanceTask * extracted = creationTask.get();
+ creationTask.release();
+ extracted->setName(instName());
+ extracted->setGroup(instGroup());
+ extracted->setIcon(iconKey());
+ return extracted;
}
void NewInstanceDialog::updateDialogState()
{
- auto allowOK = creationTask && !instName().isEmpty();
- m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
+ auto allowOK = creationTask && !instName().isEmpty();
+ m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
}
QString NewInstanceDialog::instName() const
{
- auto result = ui->instNameTextBox->text();
- if(result.size())
- {
- return result.trimmed();
- }
- result = ui->instNameTextBox->placeholderText();
- if(result.size())
- {
- return result.trimmed();
- }
- return QString();
+ auto result = ui->instNameTextBox->text();
+ if(result.size())
+ {
+ return result.trimmed();
+ }
+ result = ui->instNameTextBox->placeholderText();
+ if(result.size())
+ {
+ return result.trimmed();
+ }
+ return QString();
}
QString NewInstanceDialog::instGroup() const
{
- return ui->groupBox->currentText();
+ return ui->groupBox->currentText();
}
QString NewInstanceDialog::iconKey() const
{
- return InstIconKey;
+ return InstIconKey;
}
void NewInstanceDialog::on_iconButton_clicked()
{
- importIconNow(); //so the user can switch back
- IconPickerDialog dlg(this);
- dlg.execWithSelection(InstIconKey);
+ importIconNow(); //so the user can switch back
+ IconPickerDialog dlg(this);
+ dlg.execWithSelection(InstIconKey);
- if (dlg.result() == QDialog::Accepted)
- {
- InstIconKey = dlg.selectedIconKey;
- ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
- importIcon = false;
- }
+ if (dlg.result() == QDialog::Accepted)
+ {
+ InstIconKey = dlg.selectedIconKey;
+ ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
+ importIcon = false;
+ }
}
void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1)
{
- updateDialogState();
+ updateDialogState();
}
void NewInstanceDialog::importIconNow()
{
- if(importIcon) {
- MMC->icons()->installIcon(importIconPath, importIconName);
- InstIconKey = importIconName;
- importIcon = false;
- }
- MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());
+ if(importIcon) {
+ MMC->icons()->installIcon(importIconPath, importIconName);
+ InstIconKey = importIconName;
+ importIcon = false;
+ }
+ MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());
}
diff --git a/application/dialogs/NewInstanceDialog.h b/application/dialogs/NewInstanceDialog.h
index 1448d225..5d4ec5ed 100644
--- a/application/dialogs/NewInstanceDialog.h
+++ b/application/dialogs/NewInstanceDialog.h
@@ -32,46 +32,46 @@ class ImportPage;
class NewInstanceDialog : public QDialog, public BasePageProvider
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit NewInstanceDialog(const QString & initialGroup, const QString & url = QString(), QWidget *parent = 0);
- ~NewInstanceDialog();
+ explicit NewInstanceDialog(const QString & initialGroup, const QString & url = QString(), QWidget *parent = 0);
+ ~NewInstanceDialog();
- void updateDialogState();
+ void updateDialogState();
- void setSuggestedPack(const QString & name = QString(), InstanceTask * task = nullptr);
- void setSuggestedIconFromFile(const QString &path, const QString &name);
+ void setSuggestedPack(const QString & name = QString(), InstanceTask * task = nullptr);
+ void setSuggestedIconFromFile(const QString &path, const QString &name);
- InstanceTask * extractTask();
+ InstanceTask * extractTask();
- QString dialogTitle() override;
- QList<BasePage *> getPages() override;
+ QString dialogTitle() override;
+ QList<BasePage *> getPages() override;
- QString instName() const;
- QString instGroup() const;
- QString iconKey() const;
+ QString instName() const;
+ QString instGroup() const;
+ QString iconKey() const;
public slots:
- void accept() override;
- void reject() override;
+ void accept() override;
+ void reject() override;
private slots:
- void on_iconButton_clicked();
- void on_instNameTextBox_textChanged(const QString &arg1);
+ void on_iconButton_clicked();
+ void on_instNameTextBox_textChanged(const QString &arg1);
private:
- Ui::NewInstanceDialog *ui = nullptr;
- PageContainer * m_container = nullptr;
- QDialogButtonBox * m_buttons = nullptr;
+ Ui::NewInstanceDialog *ui = nullptr;
+ PageContainer * m_container = nullptr;
+ QDialogButtonBox * m_buttons = nullptr;
- QString InstIconKey;
- ImportPage *importPage = nullptr;
- std::unique_ptr<InstanceTask> creationTask;
+ QString InstIconKey;
+ ImportPage *importPage = nullptr;
+ std::unique_ptr<InstanceTask> creationTask;
- bool importIcon = false;
- QString importIconPath;
- QString importIconName;
+ bool importIcon = false;
+ QString importIconPath;
+ QString importIconName;
- void importIconNow();
+ void importIconNow();
};
diff --git a/application/dialogs/NotificationDialog.cpp b/application/dialogs/NotificationDialog.cpp
index 80adab3d..f2a35ae2 100644
--- a/application/dialogs/NotificationDialog.cpp
+++ b/application/dialogs/NotificationDialog.cpp
@@ -5,82 +5,82 @@
#include <QStyle>
NotificationDialog::NotificationDialog(const NotificationChecker::NotificationEntry &entry, QWidget *parent) :
- QDialog(parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::CustomizeWindowHint),
- ui(new Ui::NotificationDialog)
+ QDialog(parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::CustomizeWindowHint),
+ ui(new Ui::NotificationDialog)
{
- ui->setupUi(this);
+ ui->setupUi(this);
- QStyle::StandardPixmap icon;
- switch (entry.type)
- {
- case NotificationChecker::NotificationEntry::Critical:
- icon = QStyle::SP_MessageBoxCritical;
- break;
- case NotificationChecker::NotificationEntry::Warning:
- icon = QStyle::SP_MessageBoxWarning;
- break;
- default:
- case NotificationChecker::NotificationEntry::Information:
- icon = QStyle::SP_MessageBoxInformation;
- break;
- }
- ui->iconLabel->setPixmap(style()->standardPixmap(icon, 0, this));
- ui->messageLabel->setText(entry.message);
+ QStyle::StandardPixmap icon;
+ switch (entry.type)
+ {
+ case NotificationChecker::NotificationEntry::Critical:
+ icon = QStyle::SP_MessageBoxCritical;
+ break;
+ case NotificationChecker::NotificationEntry::Warning:
+ icon = QStyle::SP_MessageBoxWarning;
+ break;
+ default:
+ case NotificationChecker::NotificationEntry::Information:
+ icon = QStyle::SP_MessageBoxInformation;
+ break;
+ }
+ ui->iconLabel->setPixmap(style()->standardPixmap(icon, 0, this));
+ ui->messageLabel->setText(entry.message);
- m_dontShowAgainText = tr("Don't show again");
- m_closeText = tr("Close");
+ m_dontShowAgainText = tr("Don't show again");
+ m_closeText = tr("Close");
- ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime));
- ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime));
+ ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime));
+ ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime));
- startTimer(1000);
+ startTimer(1000);
}
NotificationDialog::~NotificationDialog()
{
- delete ui;
+ delete ui;
}
void NotificationDialog::timerEvent(QTimerEvent *event)
{
- if (m_dontShowAgainTime > 0)
- {
- m_dontShowAgainTime--;
- if (m_dontShowAgainTime == 0)
- {
- ui->dontShowAgainBtn->setText(m_dontShowAgainText);
- ui->dontShowAgainBtn->setEnabled(true);
- }
- else
- {
- ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime));
- }
- }
- if (m_closeTime > 0)
- {
- m_closeTime--;
- if (m_closeTime == 0)
- {
- ui->closeBtn->setText(m_closeText);
- ui->closeBtn->setEnabled(true);
- }
- else
- {
- ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime));
- }
- }
+ if (m_dontShowAgainTime > 0)
+ {
+ m_dontShowAgainTime--;
+ if (m_dontShowAgainTime == 0)
+ {
+ ui->dontShowAgainBtn->setText(m_dontShowAgainText);
+ ui->dontShowAgainBtn->setEnabled(true);
+ }
+ else
+ {
+ ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime));
+ }
+ }
+ if (m_closeTime > 0)
+ {
+ m_closeTime--;
+ if (m_closeTime == 0)
+ {
+ ui->closeBtn->setText(m_closeText);
+ ui->closeBtn->setEnabled(true);
+ }
+ else
+ {
+ ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime));
+ }
+ }
- if (m_closeTime == 0 && m_dontShowAgainTime == 0)
- {
- killTimer(event->timerId());
- }
+ if (m_closeTime == 0 && m_dontShowAgainTime == 0)
+ {
+ killTimer(event->timerId());
+ }
}
void NotificationDialog::on_dontShowAgainBtn_clicked()
{
- done(DontShowAgain);
+ done(DontShowAgain);
}
void NotificationDialog::on_closeBtn_clicked()
{
- done(Normal);
+ done(Normal);
}
diff --git a/application/dialogs/NotificationDialog.h b/application/dialogs/NotificationDialog.h
index 27b9e853..e1cbb9fa 100644
--- a/application/dialogs/NotificationDialog.h
+++ b/application/dialogs/NotificationDialog.h
@@ -11,34 +11,34 @@ class NotificationDialog;
class NotificationDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit NotificationDialog(const NotificationChecker::NotificationEntry &entry, QWidget *parent = 0);
- ~NotificationDialog();
+ explicit NotificationDialog(const NotificationChecker::NotificationEntry &entry, QWidget *parent = 0);
+ ~NotificationDialog();
- enum ExitCode
- {
- Normal,
- DontShowAgain
- };
+ enum ExitCode
+ {
+ Normal,
+ DontShowAgain
+ };
protected:
- void timerEvent(QTimerEvent *event);
+ void timerEvent(QTimerEvent *event);
private:
- Ui::NotificationDialog *ui;
+ Ui::NotificationDialog *ui;
- int m_dontShowAgainTime = 10;
- int m_closeTime = 5;
+ int m_dontShowAgainTime = 10;
+ int m_closeTime = 5;
- QString m_dontShowAgainText;
- QString m_closeText;
+ QString m_dontShowAgainText;
+ QString m_closeText;
private
slots:
- void on_dontShowAgainBtn_clicked();
- void on_closeBtn_clicked();
+ void on_dontShowAgainBtn_clicked();
+ void on_closeBtn_clicked();
};
#endif // NOTIFICATIONDIALOG_H
diff --git a/application/dialogs/ProfileSelectDialog.cpp b/application/dialogs/ProfileSelectDialog.cpp
index f1b335f9..bf31ed02 100644
--- a/application/dialogs/ProfileSelectDialog.cpp
+++ b/application/dialogs/ProfileSelectDialog.cpp
@@ -26,91 +26,91 @@
#include <MultiMC.h>
ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWidget *parent)
- : QDialog(parent), ui(new Ui::ProfileSelectDialog)
+ : QDialog(parent), ui(new Ui::ProfileSelectDialog)
{
- ui->setupUi(this);
-
- m_accounts = MMC->accounts();
- auto view = ui->listView;
- //view->setModel(m_accounts.get());
- //view->hideColumn(MojangAccountList::ActiveColumn);
- view->setColumnCount(1);
- view->setRootIsDecorated(false);
- if(QTreeWidgetItem* header = view->headerItem())
- {
- header->setText(0, tr("Name"));
- }
- else
- {
- view->setHeaderLabel(tr("Name"));
- }
- QList <QTreeWidgetItem *> items;
- for (int i = 0; i < m_accounts->count(); i++)
- {
- MojangAccountPtr account = m_accounts->at(i);
- for (auto profile : account->profiles())
- {
- auto profileLabel = profile.name;
- if(account->isInUse())
- {
- profileLabel += tr(" (in use)");
- }
- auto item = new QTreeWidgetItem(view);
- item->setText(0, profileLabel);
- item->setIcon(0, SkinUtils::getFaceFromCache(profile.id));
- item->setData(0, MojangAccountList::PointerRole, QVariant::fromValue(account));
- items.append(item);
- }
- }
- view->addTopLevelItems(items);
-
- // Set the message label.
- ui->msgLabel->setVisible(!message.isEmpty());
- ui->msgLabel->setText(message);
-
- // Flags...
- ui->globalDefaultCheck->setVisible(flags & GlobalDefaultCheckbox);
- ui->instDefaultCheck->setVisible(flags & InstanceDefaultCheckbox);
- qDebug() << flags;
-
- // Select the first entry in the list.
- ui->listView->setCurrentIndex(ui->listView->model()->index(0, 0));
-
- connect(ui->listView, SIGNAL(doubleClicked(QModelIndex)), SLOT(on_buttonBox_accepted()));
+ ui->setupUi(this);
+
+ m_accounts = MMC->accounts();
+ auto view = ui->listView;
+ //view->setModel(m_accounts.get());
+ //view->hideColumn(MojangAccountList::ActiveColumn);
+ view->setColumnCount(1);
+ view->setRootIsDecorated(false);
+ if(QTreeWidgetItem* header = view->headerItem())
+ {
+ header->setText(0, tr("Name"));
+ }
+ else
+ {
+ view->setHeaderLabel(tr("Name"));
+ }
+ QList <QTreeWidgetItem *> items;
+ for (int i = 0; i < m_accounts->count(); i++)
+ {
+ MojangAccountPtr account = m_accounts->at(i);
+ for (auto profile : account->profiles())
+ {
+ auto profileLabel = profile.name;
+ if(account->isInUse())
+ {
+ profileLabel += tr(" (in use)");
+ }
+ auto item = new QTreeWidgetItem(view);
+ item->setText(0, profileLabel);
+ item->setIcon(0, SkinUtils::getFaceFromCache(profile.id));
+ item->setData(0, MojangAccountList::PointerRole, QVariant::fromValue(account));
+ items.append(item);
+ }
+ }
+ view->addTopLevelItems(items);
+
+ // Set the message label.
+ ui->msgLabel->setVisible(!message.isEmpty());
+ ui->msgLabel->setText(message);
+
+ // Flags...
+ ui->globalDefaultCheck->setVisible(flags & GlobalDefaultCheckbox);
+ ui->instDefaultCheck->setVisible(flags & InstanceDefaultCheckbox);
+ qDebug() << flags;
+
+ // Select the first entry in the list.
+ ui->listView->setCurrentIndex(ui->listView->model()->index(0, 0));
+
+ connect(ui->listView, SIGNAL(doubleClicked(QModelIndex)), SLOT(on_buttonBox_accepted()));
}
ProfileSelectDialog::~ProfileSelectDialog()
{
- delete ui;
+ delete ui;
}
MojangAccountPtr ProfileSelectDialog::selectedAccount() const
{
- return m_selected;
+ return m_selected;
}
bool ProfileSelectDialog::useAsGlobalDefault() const
{
- return ui->globalDefaultCheck->isChecked();
+ return ui->globalDefaultCheck->isChecked();
}
bool ProfileSelectDialog::useAsInstDefaullt() const
{
- return ui->instDefaultCheck->isChecked();
+ return ui->instDefaultCheck->isChecked();
}
void ProfileSelectDialog::on_buttonBox_accepted()
{
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.size() > 0)
- {
- QModelIndex selected = selection.first();
- m_selected = selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
- }
- close();
+ QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
+ if (selection.size() > 0)
+ {
+ QModelIndex selected = selection.first();
+ m_selected = selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
+ }
+ close();
}
void ProfileSelectDialog::on_buttonBox_rejected()
{
- close();
+ close();
}
diff --git a/application/dialogs/ProfileSelectDialog.h b/application/dialogs/ProfileSelectDialog.h
index b1268743..d4017eb3 100644
--- a/application/dialogs/ProfileSelectDialog.h
+++ b/application/dialogs/ProfileSelectDialog.h
@@ -28,63 +28,63 @@ class ProfileSelectDialog;
class ProfileSelectDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum Flags
- {
- NoFlags = 0,
-
- /*!
- * Shows a check box on the dialog that allows the user to specify that the account
- * they've selected should be used as the global default for all instances.
- */
- GlobalDefaultCheckbox,
-
- /*!
- * Shows a check box on the dialog that allows the user to specify that the account
- * they've selected should be used as the default for the instance they are currently launching.
- * This is not currently implemented.
- */
- InstanceDefaultCheckbox,
- };
-
- /*!
- * Constructs a new account select dialog with the given parent and message.
- * The message will be shown at the top of the dialog. It is an empty string by default.
- */
- explicit ProfileSelectDialog(const QString& message="", int flags=0, QWidget *parent = 0);
- ~ProfileSelectDialog();
-
- /*!
- * Gets a pointer to the account that the user selected.
- * This is null if the user clicked cancel or hasn't clicked OK yet.
- */
- MojangAccountPtr selectedAccount() const;
-
- /*!
- * Returns true if the user checked the "use as global default" checkbox.
- * If the checkbox wasn't shown, this function returns false.
- */
- bool useAsGlobalDefault() const;
-
- /*!
- * Returns true if the user checked the "use as instance default" checkbox.
- * If the checkbox wasn't shown, this function returns false.
- */
- bool useAsInstDefaullt() const;
+ enum Flags
+ {
+ NoFlags = 0,
+
+ /*!
+ * Shows a check box on the dialog that allows the user to specify that the account
+ * they've selected should be used as the global default for all instances.
+ */
+ GlobalDefaultCheckbox,
+
+ /*!
+ * Shows a check box on the dialog that allows the user to specify that the account
+ * they've selected should be used as the default for the instance they are currently launching.
+ * This is not currently implemented.
+ */
+ InstanceDefaultCheckbox,
+ };
+
+ /*!
+ * Constructs a new account select dialog with the given parent and message.
+ * The message will be shown at the top of the dialog. It is an empty string by default.
+ */
+ explicit ProfileSelectDialog(const QString& message="", int flags=0, QWidget *parent = 0);
+ ~ProfileSelectDialog();
+
+ /*!
+ * Gets a pointer to the account that the user selected.
+ * This is null if the user clicked cancel or hasn't clicked OK yet.
+ */
+ MojangAccountPtr selectedAccount() const;
+
+ /*!
+ * Returns true if the user checked the "use as global default" checkbox.
+ * If the checkbox wasn't shown, this function returns false.
+ */
+ bool useAsGlobalDefault() const;
+
+ /*!
+ * Returns true if the user checked the "use as instance default" checkbox.
+ * If the checkbox wasn't shown, this function returns false.
+ */
+ bool useAsInstDefaullt() const;
public
slots:
- void on_buttonBox_accepted();
+ void on_buttonBox_accepted();
- void on_buttonBox_rejected();
+ void on_buttonBox_rejected();
protected:
- std::shared_ptr<MojangAccountList> m_accounts;
+ std::shared_ptr<MojangAccountList> m_accounts;
- //! The account that was selected when the user clicked OK.
- MojangAccountPtr m_selected;
+ //! The account that was selected when the user clicked OK.
+ MojangAccountPtr m_selected;
private:
- Ui::ProfileSelectDialog *ui;
+ Ui::ProfileSelectDialog *ui;
};
diff --git a/application/dialogs/ProgressDialog.cpp b/application/dialogs/ProgressDialog.cpp
index 056a0ffb..0951607d 100644
--- a/application/dialogs/ProgressDialog.cpp
+++ b/application/dialogs/ProgressDialog.cpp
@@ -23,117 +23,117 @@
ProgressDialog::ProgressDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ProgressDialog)
{
- ui->setupUi(this);
- this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
- setSkipButton(false);
- changeProgress(0, 100);
+ ui->setupUi(this);
+ this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setSkipButton(false);
+ changeProgress(0, 100);
}
void ProgressDialog::setSkipButton(bool present, QString label)
{
- ui->skipButton->setAutoDefault(false);
- ui->skipButton->setDefault(false);
- ui->skipButton->setFocusPolicy(Qt::ClickFocus);
- ui->skipButton->setEnabled(present);
- ui->skipButton->setVisible(present);
- ui->skipButton->setText(label);
- updateSize();
+ ui->skipButton->setAutoDefault(false);
+ ui->skipButton->setDefault(false);
+ ui->skipButton->setFocusPolicy(Qt::ClickFocus);
+ ui->skipButton->setEnabled(present);
+ ui->skipButton->setVisible(present);
+ ui->skipButton->setText(label);
+ updateSize();
}
void ProgressDialog::on_skipButton_clicked(bool checked)
{
- Q_UNUSED(checked);
- task->abort();
+ Q_UNUSED(checked);
+ task->abort();
}
ProgressDialog::~ProgressDialog()
{
- delete ui;
+ delete ui;
}
void ProgressDialog::updateSize()
{
QSize qSize = QSize(480, minimumSizeHint().height());
- resize(qSize);
+ resize(qSize);
setFixedSize(qSize);
}
int ProgressDialog::execWithTask(Task *task)
{
- this->task = task;
- QDialog::DialogCode result;
-
- if(!task)
- {
- qDebug() << "Programmer error: progress dialog created with null task.";
- return Accepted;
- }
-
- if(handleImmediateResult(result))
- {
- return result;
- }
-
- // Connect signals.
- connect(task, SIGNAL(started()), SLOT(onTaskStarted()));
- connect(task, SIGNAL(failed(QString)), SLOT(onTaskFailed(QString)));
- connect(task, SIGNAL(succeeded()), SLOT(onTaskSucceeded()));
- connect(task, SIGNAL(status(QString)), SLOT(changeStatus(const QString &)));
- connect(task, SIGNAL(progress(qint64, qint64)), SLOT(changeProgress(qint64, qint64)));
-
- // if this didn't connect to an already running task, invoke start
- if(!task->isRunning())
- {
- task->start();
- }
- if(task->isRunning())
- {
- changeProgress(task->getProgress(), task->getTotalProgress());
- changeStatus(task->getStatus());
- return QDialog::exec();
- }
- else if(handleImmediateResult(result))
- {
- return result;
- }
- else
- {
- return QDialog::Rejected;
- }
+ this->task = task;
+ QDialog::DialogCode result;
+
+ if(!task)
+ {
+ qDebug() << "Programmer error: progress dialog created with null task.";
+ return Accepted;
+ }
+
+ if(handleImmediateResult(result))
+ {
+ return result;
+ }
+
+ // Connect signals.
+ connect(task, SIGNAL(started()), SLOT(onTaskStarted()));
+ connect(task, SIGNAL(failed(QString)), SLOT(onTaskFailed(QString)));
+ connect(task, SIGNAL(succeeded()), SLOT(onTaskSucceeded()));
+ connect(task, SIGNAL(status(QString)), SLOT(changeStatus(const QString &)));
+ connect(task, SIGNAL(progress(qint64, qint64)), SLOT(changeProgress(qint64, qint64)));
+
+ // if this didn't connect to an already running task, invoke start
+ if(!task->isRunning())
+ {
+ task->start();
+ }
+ if(task->isRunning())
+ {
+ changeProgress(task->getProgress(), task->getTotalProgress());
+ changeStatus(task->getStatus());
+ return QDialog::exec();
+ }
+ else if(handleImmediateResult(result))
+ {
+ return result;
+ }
+ else
+ {
+ return QDialog::Rejected;
+ }
}
// TODO: only provide the unique_ptr overloads
int ProgressDialog::execWithTask(std::unique_ptr<Task> &&task)
{
- connect(this, &ProgressDialog::destroyed, task.get(), &Task::deleteLater);
- return execWithTask(task.release());
+ connect(this, &ProgressDialog::destroyed, task.get(), &Task::deleteLater);
+ return execWithTask(task.release());
}
int ProgressDialog::execWithTask(std::unique_ptr<Task> &task)
{
- connect(this, &ProgressDialog::destroyed, task.get(), &Task::deleteLater);
- return execWithTask(task.release());
+ connect(this, &ProgressDialog::destroyed, task.get(), &Task::deleteLater);
+ return execWithTask(task.release());
}
bool ProgressDialog::handleImmediateResult(QDialog::DialogCode &result)
{
- if(task->isFinished())
- {
- if(task->wasSuccessful())
- {
- result = QDialog::Accepted;
- }
- else
- {
- result = QDialog::Rejected;
- }
- return true;
- }
- return false;
+ if(task->isFinished())
+ {
+ if(task->wasSuccessful())
+ {
+ result = QDialog::Accepted;
+ }
+ else
+ {
+ result = QDialog::Rejected;
+ }
+ return true;
+ }
+ return false;
}
Task *ProgressDialog::getTask()
{
- return task;
+ return task;
}
void ProgressDialog::onTaskStarted()
@@ -142,55 +142,55 @@ void ProgressDialog::onTaskStarted()
void ProgressDialog::onTaskFailed(QString failure)
{
- reject();
+ reject();
}
void ProgressDialog::onTaskSucceeded()
{
- accept();
+ accept();
}
void ProgressDialog::changeStatus(const QString &status)
{
- ui->statusLabel->setText(status);
- updateSize();
+ ui->statusLabel->setText(status);
+ updateSize();
}
void ProgressDialog::changeProgress(qint64 current, qint64 total)
{
- ui->taskProgressBar->setMaximum(total);
- ui->taskProgressBar->setValue(current);
+ ui->taskProgressBar->setMaximum(total);
+ ui->taskProgressBar->setValue(current);
}
void ProgressDialog::keyPressEvent(QKeyEvent *e)
{
- if(ui->skipButton->isVisible())
- {
- if (e->key() == Qt::Key_Escape)
- {
- on_skipButton_clicked(true);
- return;
- }
- else if(e->key() == Qt::Key_Tab)
- {
- ui->skipButton->setFocusPolicy(Qt::StrongFocus);
- ui->skipButton->setFocus();
- ui->skipButton->setAutoDefault(true);
- ui->skipButton->setDefault(true);
- return;
- }
- }
- QDialog::keyPressEvent(e);
+ if(ui->skipButton->isVisible())
+ {
+ if (e->key() == Qt::Key_Escape)
+ {
+ on_skipButton_clicked(true);
+ return;
+ }
+ else if(e->key() == Qt::Key_Tab)
+ {
+ ui->skipButton->setFocusPolicy(Qt::StrongFocus);
+ ui->skipButton->setFocus();
+ ui->skipButton->setAutoDefault(true);
+ ui->skipButton->setDefault(true);
+ return;
+ }
+ }
+ QDialog::keyPressEvent(e);
}
void ProgressDialog::closeEvent(QCloseEvent *e)
{
- if (task && task->isRunning())
- {
- e->ignore();
- }
- else
- {
- QDialog::closeEvent(e);
- }
+ if (task && task->isRunning())
+ {
+ e->ignore();
+ }
+ else
+ {
+ QDialog::closeEvent(e);
+ }
}
diff --git a/application/dialogs/ProgressDialog.h b/application/dialogs/ProgressDialog.h
index f27b71e1..6856f4c0 100644
--- a/application/dialogs/ProgressDialog.h
+++ b/application/dialogs/ProgressDialog.h
@@ -27,45 +27,45 @@ class ProgressDialog;
class ProgressDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ProgressDialog(QWidget *parent = 0);
- ~ProgressDialog();
+ explicit ProgressDialog(QWidget *parent = 0);
+ ~ProgressDialog();
- void updateSize();
+ void updateSize();
- int execWithTask(Task *task);
- int execWithTask(std::unique_ptr<Task> &&task);
- int execWithTask(std::unique_ptr<Task> &task);
+ int execWithTask(Task *task);
+ int execWithTask(std::unique_ptr<Task> &&task);
+ int execWithTask(std::unique_ptr<Task> &task);
- void setSkipButton(bool present, QString label = QString());
+ void setSkipButton(bool present, QString label = QString());
- Task *getTask();
+ Task *getTask();
public
slots:
- void onTaskStarted();
- void onTaskFailed(QString failure);
- void onTaskSucceeded();
+ void onTaskStarted();
+ void onTaskFailed(QString failure);
+ void onTaskSucceeded();
- void changeStatus(const QString &status);
- void changeProgress(qint64 current, qint64 total);
+ void changeStatus(const QString &status);
+ void changeProgress(qint64 current, qint64 total);
private
slots:
- void on_skipButton_clicked(bool checked);
+ void on_skipButton_clicked(bool checked);
protected:
- virtual void keyPressEvent(QKeyEvent *e);
- virtual void closeEvent(QCloseEvent *e);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void closeEvent(QCloseEvent *e);
private:
- bool handleImmediateResult(QDialog::DialogCode &result);
+ bool handleImmediateResult(QDialog::DialogCode &result);
private:
- Ui::ProgressDialog *ui;
+ Ui::ProgressDialog *ui;
- Task *task;
+ Task *task;
};
diff --git a/application/dialogs/SkinUploadDialog.cpp b/application/dialogs/SkinUploadDialog.cpp
index 93414c6e..7d2ff829 100644
--- a/application/dialogs/SkinUploadDialog.cpp
+++ b/application/dialogs/SkinUploadDialog.cpp
@@ -9,106 +9,106 @@
void SkinUploadDialog::on_buttonBox_rejected()
{
- close();
+ close();
}
void SkinUploadDialog::on_buttonBox_accepted()
{
- AuthSessionPtr session = std::make_shared<AuthSession>();
- auto login = m_acct->login(session);
- ProgressDialog prog(this);
- if (prog.execWithTask((Task*)login.get()) != QDialog::Accepted)
- {
- //FIXME: recover with password prompt
- CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to login!"), QMessageBox::Warning)->exec();
- close();
- return;
- }
- QString fileName;
- QString input = ui->skinPathTextBox->text();
- QRegExp urlPrefixMatcher("^([a-z]+)://.+$");
- bool isLocalFile = false;
- // it has an URL prefix -> it is an URL
- if(urlPrefixMatcher.exactMatch(input))
- {
- QUrl fileURL = input;
- if(fileURL.isValid())
- {
- // local?
- if(fileURL.isLocalFile())
- {
- isLocalFile = true;
- fileName = fileURL.toLocalFile();
- }
- else
- {
- CustomMessageBox::selectable(
- this,
- tr("Skin Upload"),
- tr("Using remote URLs for setting skins is not implemented yet."),
- QMessageBox::Warning
- )->exec();
- close();
- return;
- }
- }
- else
- {
- CustomMessageBox::selectable(
- this,
- tr("Skin Upload"),
- tr("You cannot use an invalid URL for uploading skins."),
- QMessageBox::Warning
- )->exec();
- close();
- return;
- }
- }
- else
- {
- // just assume it's a path then
- isLocalFile = true;
- fileName = ui->skinPathTextBox->text();
- }
- if (isLocalFile && !QFile::exists(fileName))
- {
- CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Skin file does not exist!"), QMessageBox::Warning)->exec();
- close();
- return;
- }
- SkinUpload::Model model = SkinUpload::STEVE;
- if (ui->steveBtn->isChecked())
- {
- model = SkinUpload::STEVE;
- }
- else if (ui->alexBtn->isChecked())
- {
- model = SkinUpload::ALEX;
- }
- SkinUploadPtr upload = std::make_shared<SkinUpload>(this, session, FS::read(fileName), model);
- if (prog.execWithTask((Task*)upload.get()) != QDialog::Accepted)
- {
- CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to upload skin!"), QMessageBox::Warning)->exec();
- close();
- return;
- }
- CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Success"), QMessageBox::Information)->exec();
- close();
+ AuthSessionPtr session = std::make_shared<AuthSession>();
+ auto login = m_acct->login(session);
+ ProgressDialog prog(this);
+ if (prog.execWithTask((Task*)login.get()) != QDialog::Accepted)
+ {
+ //FIXME: recover with password prompt
+ CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to login!"), QMessageBox::Warning)->exec();
+ close();
+ return;
+ }
+ QString fileName;
+ QString input = ui->skinPathTextBox->text();
+ QRegExp urlPrefixMatcher("^([a-z]+)://.+$");
+ bool isLocalFile = false;
+ // it has an URL prefix -> it is an URL
+ if(urlPrefixMatcher.exactMatch(input))
+ {
+ QUrl fileURL = input;
+ if(fileURL.isValid())
+ {
+ // local?
+ if(fileURL.isLocalFile())
+ {
+ isLocalFile = true;
+ fileName = fileURL.toLocalFile();
+ }
+ else
+ {
+ CustomMessageBox::selectable(
+ this,
+ tr("Skin Upload"),
+ tr("Using remote URLs for setting skins is not implemented yet."),
+ QMessageBox::Warning
+ )->exec();
+ close();
+ return;
+ }
+ }
+ else
+ {
+ CustomMessageBox::selectable(
+ this,
+ tr("Skin Upload"),
+ tr("You cannot use an invalid URL for uploading skins."),
+ QMessageBox::Warning
+ )->exec();
+ close();
+ return;
+ }
+ }
+ else
+ {
+ // just assume it's a path then
+ isLocalFile = true;
+ fileName = ui->skinPathTextBox->text();
+ }
+ if (isLocalFile && !QFile::exists(fileName))
+ {
+ CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Skin file does not exist!"), QMessageBox::Warning)->exec();
+ close();
+ return;
+ }
+ SkinUpload::Model model = SkinUpload::STEVE;
+ if (ui->steveBtn->isChecked())
+ {
+ model = SkinUpload::STEVE;
+ }
+ else if (ui->alexBtn->isChecked())
+ {
+ model = SkinUpload::ALEX;
+ }
+ SkinUploadPtr upload = std::make_shared<SkinUpload>(this, session, FS::read(fileName), model);
+ if (prog.execWithTask((Task*)upload.get()) != QDialog::Accepted)
+ {
+ CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to upload skin!"), QMessageBox::Warning)->exec();
+ close();
+ return;
+ }
+ CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Success"), QMessageBox::Information)->exec();
+ close();
}
void SkinUploadDialog::on_skinBrowseBtn_clicked()
{
- QString raw_path = QFileDialog::getOpenFileName(this, tr("Select Skin Texture"), QString(), "*.png");
- if (raw_path.isEmpty() || !QFileInfo::exists(raw_path))
- {
- return;
- }
- QString cooked_path = FS::NormalizePath(raw_path);
- ui->skinPathTextBox->setText(cooked_path);
+ QString raw_path = QFileDialog::getOpenFileName(this, tr("Select Skin Texture"), QString(), "*.png");
+ if (raw_path.isEmpty() || !QFileInfo::exists(raw_path))
+ {
+ return;
+ }
+ QString cooked_path = FS::NormalizePath(raw_path);
+ ui->skinPathTextBox->setText(cooked_path);
}
SkinUploadDialog::SkinUploadDialog(MojangAccountPtr acct, QWidget *parent)
- :QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog)
+ :QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog)
{
- ui->setupUi(this);
+ ui->setupUi(this);
}
diff --git a/application/dialogs/SkinUploadDialog.h b/application/dialogs/SkinUploadDialog.h
index 514eabc8..deb44eac 100644
--- a/application/dialogs/SkinUploadDialog.h
+++ b/application/dialogs/SkinUploadDialog.h
@@ -5,25 +5,25 @@
namespace Ui
{
- class SkinUploadDialog;
+ class SkinUploadDialog;
}
class SkinUploadDialog : public QDialog {
- Q_OBJECT
+ Q_OBJECT
public:
- explicit SkinUploadDialog(MojangAccountPtr acct, QWidget *parent = 0);
- virtual ~SkinUploadDialog() {};
+ explicit SkinUploadDialog(MojangAccountPtr acct, QWidget *parent = 0);
+ virtual ~SkinUploadDialog() {};
public slots:
- void on_buttonBox_accepted();
+ void on_buttonBox_accepted();
- void on_buttonBox_rejected();
+ void on_buttonBox_rejected();
- void on_skinBrowseBtn_clicked();
+ void on_skinBrowseBtn_clicked();
protected:
- MojangAccountPtr m_acct;
+ MojangAccountPtr m_acct;
private:
- Ui::SkinUploadDialog *ui;
+ Ui::SkinUploadDialog *ui;
};
diff --git a/application/dialogs/UpdateDialog.cpp b/application/dialogs/UpdateDialog.cpp
index 754338c6..242a5b70 100644
--- a/application/dialogs/UpdateDialog.cpp
+++ b/application/dialogs/UpdateDialog.cpp
@@ -10,20 +10,20 @@
UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDialog)
{
- ui->setupUi(this);
- auto channel = MMC->settings()->get("UpdateChannel").toString();
- if(hasUpdate)
- {
- ui->label->setText(tr("A new %1 update is available!").arg(channel));
- }
- else
- {
- ui->label->setText(tr("No %1 updates found. You are running the latest version.").arg(channel));
- ui->btnUpdateNow->setHidden(true);
- ui->btnUpdateLater->setText(tr("Close"));
- }
- loadChangelog();
- restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("UpdateDialogGeometry").toByteArray()));
+ ui->setupUi(this);
+ auto channel = MMC->settings()->get("UpdateChannel").toString();
+ if(hasUpdate)
+ {
+ ui->label->setText(tr("A new %1 update is available!").arg(channel));
+ }
+ else
+ {
+ ui->label->setText(tr("No %1 updates found. You are running the latest version.").arg(channel));
+ ui->btnUpdateNow->setHidden(true);
+ ui->btnUpdateLater->setText(tr("Close"));
+ }
+ loadChangelog();
+ restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("UpdateDialogGeometry").toByteArray()));
}
UpdateDialog::~UpdateDialog()
@@ -32,150 +32,150 @@ UpdateDialog::~UpdateDialog()
void UpdateDialog::loadChangelog()
{
- auto channel = MMC->settings()->get("UpdateChannel").toString();
- dljob.reset(new NetJob("Changelog"));
- QString url;
- if(channel == "stable")
- {
- url = QString("https://raw.githubusercontent.com/MultiMC/MultiMC5/%1/changelog.md").arg(channel);
- m_changelogType = CHANGELOG_MARKDOWN;
- }
- else
- {
- url = QString("https://api.github.com/repos/MultiMC/MultiMC5/compare/%1...%2").arg(BuildConfig.GIT_COMMIT, channel);
- m_changelogType = CHANGELOG_COMMITS;
- }
- dljob->addNetAction(Net::Download::makeByteArray(QUrl(url), &changelogData));
- connect(dljob.get(), &NetJob::succeeded, this, &UpdateDialog::changelogLoaded);
- connect(dljob.get(), &NetJob::failed, this, &UpdateDialog::changelogFailed);
- dljob->start();
+ auto channel = MMC->settings()->get("UpdateChannel").toString();
+ dljob.reset(new NetJob("Changelog"));
+ QString url;
+ if(channel == "stable")
+ {
+ url = QString("https://raw.githubusercontent.com/MultiMC/MultiMC5/%1/changelog.md").arg(channel);
+ m_changelogType = CHANGELOG_MARKDOWN;
+ }
+ else
+ {
+ url = QString("https://api.github.com/repos/MultiMC/MultiMC5/compare/%1...%2").arg(BuildConfig.GIT_COMMIT, channel);
+ m_changelogType = CHANGELOG_COMMITS;
+ }
+ dljob->addNetAction(Net::Download::makeByteArray(QUrl(url), &changelogData));
+ connect(dljob.get(), &NetJob::succeeded, this, &UpdateDialog::changelogLoaded);
+ connect(dljob.get(), &NetJob::failed, this, &UpdateDialog::changelogFailed);
+ dljob->start();
}
QString reprocessMarkdown(QByteArray markdown)
{
- HoeDown hoedown;
- QString output = hoedown.process(markdown);
+ HoeDown hoedown;
+ QString output = hoedown.process(markdown);
- // HACK: easier than customizing hoedown
- output.replace(QRegExp("GH-([0-9]+)"), "<a href=\"https://github.com/MultiMC/MultiMC5/issues/\\1\">GH-\\1</a>");
- qDebug() << output;
- return output;
+ // HACK: easier than customizing hoedown
+ output.replace(QRegExp("GH-([0-9]+)"), "<a href=\"https://github.com/MultiMC/MultiMC5/issues/\\1\">GH-\\1</a>");
+ qDebug() << output;
+ return output;
}
QString reprocessCommits(QByteArray json)
{
- auto channel = MMC->settings()->get("UpdateChannel").toString();
- try
- {
- QString result;
- auto document = Json::requireDocument(json);
- auto rootobject = Json::requireObject(document);
- auto status = Json::requireString(rootobject, "status");
- auto diff_url = Json::requireString(rootobject, "html_url");
+ auto channel = MMC->settings()->get("UpdateChannel").toString();
+ try
+ {
+ QString result;
+ auto document = Json::requireDocument(json);
+ auto rootobject = Json::requireObject(document);
+ auto status = Json::requireString(rootobject, "status");
+ auto diff_url = Json::requireString(rootobject, "html_url");
- auto print_commits = [&]()
- {
- result += "<table cellspacing=0 cellpadding=2 style='border-width: 1px; border-style: solid'>";
- auto commitarray = Json::requireArray(rootobject, "commits");
- for(int i = commitarray.size() - 1; i >= 0; i--)
- {
- const auto & commitval = commitarray[i];
- auto commitobj = Json::requireObject(commitval);
- auto parents_info = Json::ensureArray(commitobj, "parents");
- // NOTE: this ignores merge commits, because they have more than one parent
- if(parents_info.size() > 1)
- {
- continue;
- }
- auto commit_url = Json::requireString(commitobj, "html_url");
- auto commit_info = Json::requireObject(commitobj, "commit");
- auto commit_message = Json::requireString(commit_info, "message");
- auto lines = commit_message.split('\n');
- QRegularExpression regexp("(?<prefix>(GH-(?<issuenr>[0-9]+))|(NOISSUE)|(SCRATCH))? *(?<rest>.*) *");
- auto match = regexp.match(lines.takeFirst(), 0, QRegularExpression::NormalMatch);
- auto issuenr = match.captured("issuenr");
- auto prefix = match.captured("prefix");
- auto rest = match.captured("rest");
- result += "<tr><td>";
- if(issuenr.length())
- {
- result += QString("<a href=\"https://github.com/MultiMC/MultiMC5/issues/%1\">GH-%2</a>").arg(issuenr, issuenr);
- }
- else if(prefix.length())
- {
- result += QString("<a href=\"%1\">%2</a>").arg(commit_url, prefix);
- }
- else
- {
- result += QString("<a href=\"%1\">NOISSUE</a>").arg(commit_url);
- }
- result += "</td>";
- lines.prepend(rest);
- result += "<td><p>" + lines.join("<br />") + "</p></td></tr>";
- }
- result += "</table>";
- };
+ auto print_commits = [&]()
+ {
+ result += "<table cellspacing=0 cellpadding=2 style='border-width: 1px; border-style: solid'>";
+ auto commitarray = Json::requireArray(rootobject, "commits");
+ for(int i = commitarray.size() - 1; i >= 0; i--)
+ {
+ const auto & commitval = commitarray[i];
+ auto commitobj = Json::requireObject(commitval);
+ auto parents_info = Json::ensureArray(commitobj, "parents");
+ // NOTE: this ignores merge commits, because they have more than one parent
+ if(parents_info.size() > 1)
+ {
+ continue;
+ }
+ auto commit_url = Json::requireString(commitobj, "html_url");
+ auto commit_info = Json::requireObject(commitobj, "commit");
+ auto commit_message = Json::requireString(commit_info, "message");
+ auto lines = commit_message.split('\n');
+ QRegularExpression regexp("(?<prefix>(GH-(?<issuenr>[0-9]+))|(NOISSUE)|(SCRATCH))? *(?<rest>.*) *");
+ auto match = regexp.match(lines.takeFirst(), 0, QRegularExpression::NormalMatch);
+ auto issuenr = match.captured("issuenr");
+ auto prefix = match.captured("prefix");
+ auto rest = match.captured("rest");
+ result += "<tr><td>";
+ if(issuenr.length())
+ {
+ result += QString("<a href=\"https://github.com/MultiMC/MultiMC5/issues/%1\">GH-%2</a>").arg(issuenr, issuenr);
+ }
+ else if(prefix.length())
+ {
+ result += QString("<a href=\"%1\">%2</a>").arg(commit_url, prefix);
+ }
+ else
+ {
+ result += QString("<a href=\"%1\">NOISSUE</a>").arg(commit_url);
+ }
+ result += "</td>";
+ lines.prepend(rest);
+ result += "<td><p>" + lines.join("<br />") + "</p></td></tr>";
+ }
+ result += "</table>";
+ };
- if(status == "identical")
- {
- return QObject::tr("<p>There are no code changes between your current version and latest %1.</p>").arg(channel);
- }
- else if(status == "ahead")
- {
- result += QObject::tr("<p>Following commits were added since last update:</p>");
- print_commits();
- }
- else if(status == "diverged")
- {
- auto commit_ahead = Json::requireInteger(rootobject, "ahead_by");
- auto commit_behind = Json::requireInteger(rootobject, "behind_by");
- result += QObject::tr("<p>The update removes %1 commits and adds the following %2:</p>").arg(commit_behind).arg(commit_ahead);
- print_commits();
- }
- result += QObject::tr("<p>You can <a href=\"%1\">look at the changes on github</a>.</p>").arg(diff_url);
- return result;
- }
- catch (const JSONValidationError &e)
- {
- qWarning() << "Got an unparseable commit log from github:" << e.what();
- qDebug() << json;
- }
- return QString();
+ if(status == "identical")
+ {
+ return QObject::tr("<p>There are no code changes between your current version and latest %1.</p>").arg(channel);
+ }
+ else if(status == "ahead")
+ {
+ result += QObject::tr("<p>Following commits were added since last update:</p>");
+ print_commits();
+ }
+ else if(status == "diverged")
+ {
+ auto commit_ahead = Json::requireInteger(rootobject, "ahead_by");
+ auto commit_behind = Json::requireInteger(rootobject, "behind_by");
+ result += QObject::tr("<p>The update removes %1 commits and adds the following %2:</p>").arg(commit_behind).arg(commit_ahead);
+ print_commits();
+ }
+ result += QObject::tr("<p>You can <a href=\"%1\">look at the changes on github</a>.</p>").arg(diff_url);
+ return result;
+ }
+ catch (const JSONValidationError &e)
+ {
+ qWarning() << "Got an unparseable commit log from github:" << e.what();
+ qDebug() << json;
+ }
+ return QString();
}
void UpdateDialog::changelogLoaded()
{
- QString result;
- switch(m_changelogType)
- {
- case CHANGELOG_COMMITS:
- result = reprocessCommits(changelogData);
- break;
- case CHANGELOG_MARKDOWN:
- result = reprocessMarkdown(changelogData);
- break;
- }
- changelogData.clear();
- ui->changelogBrowser->setHtml(result);
+ QString result;
+ switch(m_changelogType)
+ {
+ case CHANGELOG_COMMITS:
+ result = reprocessCommits(changelogData);
+ break;
+ case CHANGELOG_MARKDOWN:
+ result = reprocessMarkdown(changelogData);
+ break;
+ }
+ changelogData.clear();
+ ui->changelogBrowser->setHtml(result);
}
void UpdateDialog::changelogFailed(QString reason)
{
- ui->changelogBrowser->setHtml(tr("<p align=\"center\" <span style=\"font-size:22pt;\">Failed to fetch changelog... Error: %1</span></p>").arg(reason));
+ ui->changelogBrowser->setHtml(tr("<p align=\"center\" <span style=\"font-size:22pt;\">Failed to fetch changelog... Error: %1</span></p>").arg(reason));
}
void UpdateDialog::on_btnUpdateLater_clicked()
{
- reject();
+ reject();
}
void UpdateDialog::on_btnUpdateNow_clicked()
{
- done(UPDATE_NOW);
+ done(UPDATE_NOW);
}
void UpdateDialog::closeEvent(QCloseEvent* evt)
{
- MMC->settings()->set("UpdateDialogGeometry", saveGeometry().toBase64());
- QDialog::closeEvent(evt);
+ MMC->settings()->set("UpdateDialogGeometry", saveGeometry().toBase64());
+ QDialog::closeEvent(evt);
}
diff --git a/application/dialogs/UpdateDialog.h b/application/dialogs/UpdateDialog.h
index 78960c99..6ee3df1d 100644
--- a/application/dialogs/UpdateDialog.h
+++ b/application/dialogs/UpdateDialog.h
@@ -25,43 +25,43 @@ class UpdateDialog;
enum UpdateAction
{
- UPDATE_LATER = QDialog::Rejected,
- UPDATE_NOW = QDialog::Accepted,
+ UPDATE_LATER = QDialog::Rejected,
+ UPDATE_NOW = QDialog::Accepted,
};
enum ChangelogType
{
- CHANGELOG_MARKDOWN,
- CHANGELOG_COMMITS
+ CHANGELOG_MARKDOWN,
+ CHANGELOG_COMMITS
};
class UpdateDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit UpdateDialog(bool hasUpdate = true, QWidget *parent = 0);
- ~UpdateDialog();
+ explicit UpdateDialog(bool hasUpdate = true, QWidget *parent = 0);
+ ~UpdateDialog();
public slots:
- void on_btnUpdateNow_clicked();
- void on_btnUpdateLater_clicked();
+ void on_btnUpdateNow_clicked();
+ void on_btnUpdateLater_clicked();
- /// Starts loading the changelog
- void loadChangelog();
+ /// Starts loading the changelog
+ void loadChangelog();
- /// Slot for when the chengelog loads successfully.
- void changelogLoaded();
+ /// Slot for when the chengelog loads successfully.
+ void changelogLoaded();
- /// Slot for when the chengelog fails to load...
- void changelogFailed(QString reason);
+ /// Slot for when the chengelog fails to load...
+ void changelogFailed(QString reason);
protected:
- void closeEvent(QCloseEvent * ) override;
+ void closeEvent(QCloseEvent * ) override;
private:
- Ui::UpdateDialog *ui;
- QByteArray changelogData;
- NetJobPtr dljob;
- ChangelogType m_changelogType = CHANGELOG_MARKDOWN;
+ Ui::UpdateDialog *ui;
+ QByteArray changelogData;
+ NetJobPtr dljob;
+ ChangelogType m_changelogType = CHANGELOG_MARKDOWN;
};
diff --git a/application/dialogs/VersionSelectDialog.cpp b/application/dialogs/VersionSelectDialog.cpp
index c7009497..59287ee9 100644
--- a/application/dialogs/VersionSelectDialog.cpp
+++ b/application/dialogs/VersionSelectDialog.cpp
@@ -33,109 +33,109 @@
#include <widgets/VersionSelectWidget.h>
VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent, bool cancelable)
- : QDialog(parent)
+ : QDialog(parent)
{
- setObjectName(QStringLiteral("VersionSelectDialog"));
- resize(400, 347);
- m_verticalLayout = new QVBoxLayout(this);
- m_verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ setObjectName(QStringLiteral("VersionSelectDialog"));
+ resize(400, 347);
+ m_verticalLayout = new QVBoxLayout(this);
+ m_verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
- m_versionWidget = new VersionSelectWidget(parent);
- m_verticalLayout->addWidget(m_versionWidget);
+ m_versionWidget = new VersionSelectWidget(parent);
+ m_verticalLayout->addWidget(m_versionWidget);
- m_horizontalLayout = new QHBoxLayout();
- m_horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ m_horizontalLayout = new QHBoxLayout();
+ m_horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
- m_refreshButton = new QPushButton(this);
- m_refreshButton->setObjectName(QStringLiteral("refreshButton"));
- m_horizontalLayout->addWidget(m_refreshButton);
+ m_refreshButton = new QPushButton(this);
+ m_refreshButton->setObjectName(QStringLiteral("refreshButton"));
+ m_horizontalLayout->addWidget(m_refreshButton);
- m_buttonBox = new QDialogButtonBox(this);
- m_buttonBox->setObjectName(QStringLiteral("buttonBox"));
- m_buttonBox->setOrientation(Qt::Horizontal);
- m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
- m_horizontalLayout->addWidget(m_buttonBox);
+ m_buttonBox = new QDialogButtonBox(this);
+ m_buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ m_buttonBox->setOrientation(Qt::Horizontal);
+ m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
+ m_horizontalLayout->addWidget(m_buttonBox);
- m_verticalLayout->addLayout(m_horizontalLayout);
+ m_verticalLayout->addLayout(m_horizontalLayout);
- retranslate();
+ retranslate();
- QObject::connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
- QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ QObject::connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
- QMetaObject::connectSlotsByName(this);
- setWindowModality(Qt::WindowModal);
- setWindowTitle(title);
+ QMetaObject::connectSlotsByName(this);
+ setWindowModality(Qt::WindowModal);
+ setWindowTitle(title);
- m_vlist = vlist;
+ m_vlist = vlist;
- if (!cancelable)
- {
- m_buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
- }
+ if (!cancelable)
+ {
+ m_buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
+ }
}
void VersionSelectDialog::retranslate()
{
- // FIXME: overrides custom title given in constructor!
- setWindowTitle(tr("Choose Version"));
- m_refreshButton->setToolTip(tr("Reloads the version list."));
- m_refreshButton->setText(tr("&Refresh"));
+ // FIXME: overrides custom title given in constructor!
+ setWindowTitle(tr("Choose Version"));
+ m_refreshButton->setToolTip(tr("Reloads the version list."));
+ m_refreshButton->setText(tr("&Refresh"));
}
void VersionSelectDialog::setCurrentVersion(const QString& version)
{
- m_currentVersion = version;
- m_versionWidget->setCurrentVersion(version);
+ m_currentVersion = version;
+ m_versionWidget->setCurrentVersion(version);
}
void VersionSelectDialog::setEmptyString(QString emptyString)
{
- m_versionWidget->setEmptyString(emptyString);
+ m_versionWidget->setEmptyString(emptyString);
}
void VersionSelectDialog::setEmptyErrorString(QString emptyErrorString)
{
- m_versionWidget->setEmptyErrorString(emptyErrorString);
+ m_versionWidget->setEmptyErrorString(emptyErrorString);
}
void VersionSelectDialog::setResizeOn(int column)
{
- resizeOnColumn = column;
+ resizeOnColumn = column;
}
int VersionSelectDialog::exec()
{
- QDialog::open();
- m_versionWidget->initialize(m_vlist);
- if(resizeOnColumn != -1)
- {
- m_versionWidget->setResizeOn(resizeOnColumn);
- }
- return QDialog::exec();
+ QDialog::open();
+ m_versionWidget->initialize(m_vlist);
+ if(resizeOnColumn != -1)
+ {
+ m_versionWidget->setResizeOn(resizeOnColumn);
+ }
+ return QDialog::exec();
}
void VersionSelectDialog::selectRecommended()
{
- m_versionWidget->selectRecommended();
+ m_versionWidget->selectRecommended();
}
BaseVersionPtr VersionSelectDialog::selectedVersion() const
{
- return m_versionWidget->selectedVersion();
+ return m_versionWidget->selectedVersion();
}
void VersionSelectDialog::on_refreshButton_clicked()
{
- m_versionWidget->loadList();
+ m_versionWidget->loadList();
}
void VersionSelectDialog::setExactFilter(BaseVersionList::ModelRoles role, QString filter)
{
- m_versionWidget->setExactFilter(role, filter);
+ m_versionWidget->setExactFilter(role, filter);
}
void VersionSelectDialog::setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter)
{
- m_versionWidget->setFuzzyFilter(role, filter);
+ m_versionWidget->setFuzzyFilter(role, filter);
}
diff --git a/application/dialogs/VersionSelectDialog.h b/application/dialogs/VersionSelectDialog.h
index 127a0ee9..8b5d108f 100644
--- a/application/dialogs/VersionSelectDialog.h
+++ b/application/dialogs/VersionSelectDialog.h
@@ -36,43 +36,43 @@ class VersionProxyModel;
class VersionSelectDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent = 0, bool cancelable = true);
- virtual ~VersionSelectDialog() {};
+ explicit VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent = 0, bool cancelable = true);
+ virtual ~VersionSelectDialog() {};
- int exec() override;
+ int exec() override;
- BaseVersionPtr selectedVersion() const;
+ BaseVersionPtr selectedVersion() const;
- void setCurrentVersion(const QString & version);
- void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter);
- void setExactFilter(BaseVersionList::ModelRoles role, QString filter);
- void setEmptyString(QString emptyString);
- void setEmptyErrorString(QString emptyErrorString);
- void setResizeOn(int column);
+ void setCurrentVersion(const QString & version);
+ void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter);
+ void setExactFilter(BaseVersionList::ModelRoles role, QString filter);
+ void setEmptyString(QString emptyString);
+ void setEmptyErrorString(QString emptyErrorString);
+ void setResizeOn(int column);
private slots:
- void on_refreshButton_clicked();
+ void on_refreshButton_clicked();
private:
- void retranslate();
- void selectRecommended();
+ void retranslate();
+ void selectRecommended();
private:
- QString m_currentVersion;
- VersionSelectWidget *m_versionWidget = nullptr;
- QVBoxLayout *m_verticalLayout = nullptr;
- QHBoxLayout *m_horizontalLayout = nullptr;
- QPushButton *m_refreshButton = nullptr;
- QDialogButtonBox *m_buttonBox = nullptr;
+ QString m_currentVersion;
+ VersionSelectWidget *m_versionWidget = nullptr;
+ QVBoxLayout *m_verticalLayout = nullptr;
+ QHBoxLayout *m_horizontalLayout = nullptr;
+ QPushButton *m_refreshButton = nullptr;
+ QDialogButtonBox *m_buttonBox = nullptr;
- BaseVersionList *m_vlist = nullptr;
+ BaseVersionList *m_vlist = nullptr;
- VersionProxyModel *m_proxyModel = nullptr;
+ VersionProxyModel *m_proxyModel = nullptr;
- int resizeOnColumn = -1;
+ int resizeOnColumn = -1;
- Task * loadTask = nullptr;
+ Task * loadTask = nullptr;
};
diff --git a/application/groupview/GroupView.cpp b/application/groupview/GroupView.cpp
index 0d6aa49e..a1b44e64 100644
--- a/application/groupview/GroupView.cpp
+++ b/application/groupview/GroupView.cpp
@@ -31,937 +31,937 @@
template <typename T> bool listsIntersect(const QList<T> &l1, const QList<T> t2)
{
- for (auto &item : l1)
- {
- if (t2.contains(item))
- {
- return true;
- }
- }
- return false;
+ for (auto &item : l1)
+ {
+ if (t2.contains(item))
+ {
+ return true;
+ }
+ }
+ return false;
}
GroupView::GroupView(QWidget *parent)
- : QAbstractItemView(parent)
+ : QAbstractItemView(parent)
{
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- setAcceptDrops(true);
- setAutoScroll(true);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ setAcceptDrops(true);
+ setAutoScroll(true);
}
GroupView::~GroupView()
{
- qDeleteAll(m_groups);
- m_groups.clear();
+ qDeleteAll(m_groups);
+ m_groups.clear();
}
void GroupView::setModel(QAbstractItemModel *model)
{
- QAbstractItemView::setModel(model);
- connect(model, &QAbstractItemModel::modelReset, this, &GroupView::modelReset);
- connect(model, &QAbstractItemModel::rowsRemoved, this, &GroupView::rowsRemoved);
+ QAbstractItemView::setModel(model);
+ connect(model, &QAbstractItemModel::modelReset, this, &GroupView::modelReset);
+ connect(model, &QAbstractItemModel::rowsRemoved, this, &GroupView::rowsRemoved);
}
void GroupView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
- const QVector<int> &roles)
+ const QVector<int> &roles)
{
- scheduleDelayedItemsLayout();
+ scheduleDelayedItemsLayout();
}
void GroupView::rowsInserted(const QModelIndex &parent, int start, int end)
{
- scheduleDelayedItemsLayout();
+ scheduleDelayedItemsLayout();
}
void GroupView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
- scheduleDelayedItemsLayout();
+ scheduleDelayedItemsLayout();
}
void GroupView::modelReset()
{
- scheduleDelayedItemsLayout();
+ scheduleDelayedItemsLayout();
}
void GroupView::rowsRemoved()
{
- scheduleDelayedItemsLayout();
+ scheduleDelayedItemsLayout();
}
class LocaleString : public QString
{
public:
- LocaleString(const char *s) : QString(s)
- {
- }
- LocaleString(const QString &s) : QString(s)
- {
- }
+ LocaleString(const char *s) : QString(s)
+ {
+ }
+ LocaleString(const QString &s) : QString(s)
+ {
+ }
};
inline bool operator<(const LocaleString &lhs, const LocaleString &rhs)
{
- return (QString::localeAwareCompare(lhs, rhs) < 0);
+ return (QString::localeAwareCompare(lhs, rhs) < 0);
}
void GroupView::updateScrollbar()
{
- int previousScroll = verticalScrollBar()->value();
- if (m_groups.isEmpty())
- {
- verticalScrollBar()->setRange(0, 0);
- }
- else
- {
- int totalHeight = 0;
- // top margin
- totalHeight += m_categoryMargin;
- int itemScroll = 0;
- for (auto category : m_groups)
- {
- category->m_verticalPosition = totalHeight;
- totalHeight += category->totalHeight() + m_categoryMargin;
- if(!itemScroll && category->totalHeight() != 0)
- {
- itemScroll = category->contentHeight() / category->numRows();
- }
- }
- // do not divide by zero
- if(itemScroll == 0)
- itemScroll = 64;
-
- totalHeight += m_bottomMargin;
- verticalScrollBar()->setSingleStep ( itemScroll );
- const int rowsPerPage = qMax ( viewport()->height() / itemScroll, 1 );
- verticalScrollBar()->setPageStep ( rowsPerPage * itemScroll );
-
- verticalScrollBar()->setRange(0, totalHeight - height());
- }
-
- verticalScrollBar()->setValue(qMin(previousScroll, verticalScrollBar()->maximum()));
+ int previousScroll = verticalScrollBar()->value();
+ if (m_groups.isEmpty())
+ {
+ verticalScrollBar()->setRange(0, 0);
+ }
+ else
+ {
+ int totalHeight = 0;
+ // top margin
+ totalHeight += m_categoryMargin;
+ int itemScroll = 0;
+ for (auto category : m_groups)
+ {
+ category->m_verticalPosition = totalHeight;
+ totalHeight += category->totalHeight() + m_categoryMargin;
+ if(!itemScroll && category->totalHeight() != 0)
+ {
+ itemScroll = category->contentHeight() / category->numRows();
+ }
+ }
+ // do not divide by zero
+ if(itemScroll == 0)
+ itemScroll = 64;
+
+ totalHeight += m_bottomMargin;
+ verticalScrollBar()->setSingleStep ( itemScroll );
+ const int rowsPerPage = qMax ( viewport()->height() / itemScroll, 1 );
+ verticalScrollBar()->setPageStep ( rowsPerPage * itemScroll );
+
+ verticalScrollBar()->setRange(0, totalHeight - height());
+ }
+
+ verticalScrollBar()->setValue(qMin(previousScroll, verticalScrollBar()->maximum()));
}
void GroupView::updateGeometries()
{
- geometryCache.clear();
-
- QMap<LocaleString, VisualGroup *> cats;
-
- for (int i = 0; i < model()->rowCount(); ++i)
- {
- const QString groupName = model()->index(i, 0).data(GroupViewRoles::GroupRole).toString();
- if (!cats.contains(groupName))
- {
- VisualGroup *old = this->category(groupName);
- if (old)
- {
- auto cat = new VisualGroup(old);
- cats.insert(groupName, cat);
- cat->update();
- }
- else
- {
- auto cat = new VisualGroup(groupName, this);
- cats.insert(groupName, cat);
- cat->update();
- }
- }
- }
-
- qDeleteAll(m_groups);
- m_groups = cats.values();
- updateScrollbar();
- viewport()->update();
+ geometryCache.clear();
+
+ QMap<LocaleString, VisualGroup *> cats;
+
+ for (int i = 0; i < model()->rowCount(); ++i)
+ {
+ const QString groupName = model()->index(i, 0).data(GroupViewRoles::GroupRole).toString();
+ if (!cats.contains(groupName))
+ {
+ VisualGroup *old = this->category(groupName);
+ if (old)
+ {
+ auto cat = new VisualGroup(old);
+ cats.insert(groupName, cat);
+ cat->update();
+ }
+ else
+ {
+ auto cat = new VisualGroup(groupName, this);
+ cats.insert(groupName, cat);
+ cat->update();
+ }
+ }
+ }
+
+ qDeleteAll(m_groups);
+ m_groups = cats.values();
+ updateScrollbar();
+ viewport()->update();
}
bool GroupView::isIndexHidden(const QModelIndex &index) const
{
- VisualGroup *cat = category(index);
- if (cat)
- {
- return cat->collapsed;
- }
- else
- {
- return false;
- }
+ VisualGroup *cat = category(index);
+ if (cat)
+ {
+ return cat->collapsed;
+ }
+ else
+ {
+ return false;
+ }
}
VisualGroup *GroupView::category(const QModelIndex &index) const
{
- return category(index.data(GroupViewRoles::GroupRole).toString());
+ return category(index.data(GroupViewRoles::GroupRole).toString());
}
VisualGroup *GroupView::category(const QString &cat) const
{
- for (auto group : m_groups)
- {
- if (group->text == cat)
- {
- return group;
- }
- }
- return nullptr;
+ for (auto group : m_groups)
+ {
+ if (group->text == cat)
+ {
+ return group;
+ }
+ }
+ return nullptr;
}
VisualGroup *GroupView::categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const
{
- for (auto group : m_groups)
- {
- result = group->hitScan(pos);
- if(result != VisualGroup::NoHit)
- {
- return group;
- }
- }
- result = VisualGroup::NoHit;
- return nullptr;
+ for (auto group : m_groups)
+ {
+ result = group->hitScan(pos);
+ if(result != VisualGroup::NoHit)
+ {
+ return group;
+ }
+ }
+ result = VisualGroup::NoHit;
+ return nullptr;
}
QString GroupView::groupNameAt(const QPoint &point)
{
- VisualGroup::HitResults hitresult;
- auto group = categoryAt(point + offset(), hitresult);
- if(group && (hitresult & (VisualGroup::HeaderHit | VisualGroup::BodyHit)))
- {
- return group->text;
- }
- return QString();
+ VisualGroup::HitResults hitresult;
+ auto group = categoryAt(point + offset(), hitresult);
+ if(group && (hitresult & (VisualGroup::HeaderHit | VisualGroup::BodyHit)))
+ {
+ return group->text;
+ }
+ return QString();
}
int GroupView::calculateItemsPerRow() const
{
- return qFloor((qreal)(contentWidth()) / (qreal)(itemWidth() + m_spacing));
+ return qFloor((qreal)(contentWidth()) / (qreal)(itemWidth() + m_spacing));
}
int GroupView::contentWidth() const
{
- return width() - m_leftMargin - m_rightMargin;
+ return width() - m_leftMargin - m_rightMargin;
}
int GroupView::itemWidth() const
{
- return m_itemWidth;
+ return m_itemWidth;
}
void GroupView::mousePressEvent(QMouseEvent *event)
{
- // endCategoryEditor();
-
- QPoint visualPos = event->pos();
- QPoint geometryPos = event->pos() + offset();
-
- QPersistentModelIndex index = indexAt(visualPos);
-
- m_pressedIndex = index;
- m_pressedAlreadySelected = selectionModel()->isSelected(m_pressedIndex);
- m_pressedPosition = geometryPos;
-
- VisualGroup::HitResults hitresult;
- m_pressedCategory = categoryAt(geometryPos, hitresult);
- if (m_pressedCategory && hitresult & VisualGroup::CheckboxHit)
- {
- setState(m_pressedCategory->collapsed ? ExpandingState : CollapsingState);
- event->accept();
- return;
- }
-
- if (index.isValid() && (index.flags() & Qt::ItemIsEnabled))
- {
- if(index != currentIndex())
- {
- // FIXME: better!
- m_currentCursorColumn = -1;
- }
- // we disable scrollTo for mouse press so the item doesn't change position
- // when the user is interacting with it (ie. clicking on it)
- bool autoScroll = hasAutoScroll();
- setAutoScroll(false);
- selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
-
- setAutoScroll(autoScroll);
- QRect rect(visualPos, visualPos);
- setSelection(rect, QItemSelectionModel::ClearAndSelect);
-
- // signal handlers may change the model
- emit pressed(index);
- }
- else
- {
- // Forces a finalize() even if mouse is pressed, but not on a item
- selectionModel()->select(QModelIndex(), QItemSelectionModel::Select);
- }
+ // endCategoryEditor();
+
+ QPoint visualPos = event->pos();
+ QPoint geometryPos = event->pos() + offset();
+
+ QPersistentModelIndex index = indexAt(visualPos);
+
+ m_pressedIndex = index;
+ m_pressedAlreadySelected = selectionModel()->isSelected(m_pressedIndex);
+ m_pressedPosition = geometryPos;
+
+ VisualGroup::HitResults hitresult;
+ m_pressedCategory = categoryAt(geometryPos, hitresult);
+ if (m_pressedCategory && hitresult & VisualGroup::CheckboxHit)
+ {
+ setState(m_pressedCategory->collapsed ? ExpandingState : CollapsingState);
+ event->accept();
+ return;
+ }
+
+ if (index.isValid() && (index.flags() & Qt::ItemIsEnabled))
+ {
+ if(index != currentIndex())
+ {
+ // FIXME: better!
+ m_currentCursorColumn = -1;
+ }
+ // we disable scrollTo for mouse press so the item doesn't change position
+ // when the user is interacting with it (ie. clicking on it)
+ bool autoScroll = hasAutoScroll();
+ setAutoScroll(false);
+ selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+
+ setAutoScroll(autoScroll);
+ QRect rect(visualPos, visualPos);
+ setSelection(rect, QItemSelectionModel::ClearAndSelect);
+
+ // signal handlers may change the model
+ emit pressed(index);
+ }
+ else
+ {
+ // Forces a finalize() even if mouse is pressed, but not on a item
+ selectionModel()->select(QModelIndex(), QItemSelectionModel::Select);
+ }
}
void GroupView::mouseMoveEvent(QMouseEvent *event)
{
- QPoint topLeft;
- QPoint visualPos = event->pos();
- QPoint geometryPos = event->pos() + offset();
-
- if (state() == ExpandingState || state() == CollapsingState)
- {
- return;
- }
-
- if (state() == DraggingState)
- {
- topLeft = m_pressedPosition - offset();
- if ((topLeft - event->pos()).manhattanLength() > QApplication::startDragDistance())
- {
- m_pressedIndex = QModelIndex();
- startDrag(model()->supportedDragActions());
- setState(NoState);
- stopAutoScroll();
- }
- return;
- }
-
- if (selectionMode() != SingleSelection)
- {
- topLeft = m_pressedPosition - offset();
- }
- else
- {
- topLeft = geometryPos;
- }
-
- if (m_pressedIndex.isValid() && (state() != DragSelectingState) &&
- (event->buttons() != Qt::NoButton) && !selectedIndexes().isEmpty())
- {
- setState(DraggingState);
- return;
- }
-
- if ((event->buttons() & Qt::LeftButton) && selectionModel())
- {
- setState(DragSelectingState);
-
- setSelection(QRect(visualPos, visualPos), QItemSelectionModel::ClearAndSelect);
- QModelIndex index = indexAt(visualPos);
-
- // set at the end because it might scroll the view
- if (index.isValid() && (index != selectionModel()->currentIndex()) &&
- (index.flags() & Qt::ItemIsEnabled))
- {
- selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- }
- }
+ QPoint topLeft;
+ QPoint visualPos = event->pos();
+ QPoint geometryPos = event->pos() + offset();
+
+ if (state() == ExpandingState || state() == CollapsingState)
+ {
+ return;
+ }
+
+ if (state() == DraggingState)
+ {
+ topLeft = m_pressedPosition - offset();
+ if ((topLeft - event->pos()).manhattanLength() > QApplication::startDragDistance())
+ {
+ m_pressedIndex = QModelIndex();
+ startDrag(model()->supportedDragActions());
+ setState(NoState);
+ stopAutoScroll();
+ }
+ return;
+ }
+
+ if (selectionMode() != SingleSelection)
+ {
+ topLeft = m_pressedPosition - offset();
+ }
+ else
+ {
+ topLeft = geometryPos;
+ }
+
+ if (m_pressedIndex.isValid() && (state() != DragSelectingState) &&
+ (event->buttons() != Qt::NoButton) && !selectedIndexes().isEmpty())
+ {
+ setState(DraggingState);
+ return;
+ }
+
+ if ((event->buttons() & Qt::LeftButton) && selectionModel())
+ {
+ setState(DragSelectingState);
+
+ setSelection(QRect(visualPos, visualPos), QItemSelectionModel::ClearAndSelect);
+ QModelIndex index = indexAt(visualPos);
+
+ // set at the end because it might scroll the view
+ if (index.isValid() && (index != selectionModel()->currentIndex()) &&
+ (index.flags() & Qt::ItemIsEnabled))
+ {
+ selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ }
+ }
}
void GroupView::mouseReleaseEvent(QMouseEvent *event)
{
- QPoint visualPos = event->pos();
- QPoint geometryPos = event->pos() + offset();
- QPersistentModelIndex index = indexAt(visualPos);
-
- VisualGroup::HitResults hitresult;
-
- bool click = (index == m_pressedIndex && index.isValid()) ||
- (m_pressedCategory && m_pressedCategory == categoryAt(geometryPos, hitresult));
-
- if (click && m_pressedCategory)
- {
- if (state() == ExpandingState)
- {
- m_pressedCategory->collapsed = false;
- updateGeometries();
- viewport()->update();
- event->accept();
- return;
- }
- else if (state() == CollapsingState)
- {
- m_pressedCategory->collapsed = true;
- updateGeometries();
- viewport()->update();
- event->accept();
- return;
- }
- }
-
- m_ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
-
- setState(NoState);
-
- if (click)
- {
- if (event->button() == Qt::LeftButton)
- {
- emit clicked(index);
- }
- QStyleOptionViewItem option = viewOptions();
- if (m_pressedAlreadySelected)
- {
- option.state |= QStyle::State_Selected;
- }
- if ((model()->flags(index) & Qt::ItemIsEnabled) &&
- style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this))
- {
- emit activated(index);
- }
- }
+ QPoint visualPos = event->pos();
+ QPoint geometryPos = event->pos() + offset();
+ QPersistentModelIndex index = indexAt(visualPos);
+
+ VisualGroup::HitResults hitresult;
+
+ bool click = (index == m_pressedIndex && index.isValid()) ||
+ (m_pressedCategory && m_pressedCategory == categoryAt(geometryPos, hitresult));
+
+ if (click && m_pressedCategory)
+ {
+ if (state() == ExpandingState)
+ {
+ m_pressedCategory->collapsed = false;
+ updateGeometries();
+ viewport()->update();
+ event->accept();
+ return;
+ }
+ else if (state() == CollapsingState)
+ {
+ m_pressedCategory->collapsed = true;
+ updateGeometries();
+ viewport()->update();
+ event->accept();
+ return;
+ }
+ }
+
+ m_ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
+
+ setState(NoState);
+
+ if (click)
+ {
+ if (event->button() == Qt::LeftButton)
+ {
+ emit clicked(index);
+ }
+ QStyleOptionViewItem option = viewOptions();
+ if (m_pressedAlreadySelected)
+ {
+ option.state |= QStyle::State_Selected;
+ }
+ if ((model()->flags(index) & Qt::ItemIsEnabled) &&
+ style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this))
+ {
+ emit activated(index);
+ }
+ }
}
void GroupView::mouseDoubleClickEvent(QMouseEvent *event)
{
- QModelIndex index = indexAt(event->pos());
- if (!index.isValid() || !(index.flags() & Qt::ItemIsEnabled) || (m_pressedIndex != index))
- {
- QMouseEvent me(QEvent::MouseButtonPress, event->localPos(), event->windowPos(),
- event->screenPos(), event->button(), event->buttons(),
- event->modifiers());
- mousePressEvent(&me);
- return;
- }
- // signal handlers may change the model
- QPersistentModelIndex persistent = index;
- emit doubleClicked(persistent);
+ QModelIndex index = indexAt(event->pos());
+ if (!index.isValid() || !(index.flags() & Qt::ItemIsEnabled) || (m_pressedIndex != index))
+ {
+ QMouseEvent me(QEvent::MouseButtonPress, event->localPos(), event->windowPos(),
+ event->screenPos(), event->button(), event->buttons(),
+ event->modifiers());
+ mousePressEvent(&me);
+ return;
+ }
+ // signal handlers may change the model
+ QPersistentModelIndex persistent = index;
+ emit doubleClicked(persistent);
}
void GroupView::paintEvent(QPaintEvent *event)
{
- executeDelayedItemsLayout();
-
- QPainter painter(this->viewport());
-
- QStyleOptionViewItem option(viewOptions());
- option.widget = this;
-
- int wpWidth = viewport()->width();
- option.rect.setWidth(wpWidth);
- for (int i = 0; i < m_groups.size(); ++i)
- {
- VisualGroup *category = m_groups.at(i);
- int y = category->verticalPosition();
- y -= verticalOffset();
- QRect backup = option.rect;
- int height = category->totalHeight();
- option.rect.setTop(y);
- option.rect.setHeight(height);
- option.rect.setLeft(m_leftMargin);
- option.rect.setRight(wpWidth - m_rightMargin);
- category->drawHeader(&painter, option);
- y += category->totalHeight() + m_categoryMargin;
- option.rect = backup;
- }
-
- for (int i = 0; i < model()->rowCount(); ++i)
- {
- const QModelIndex index = model()->index(i, 0);
- if (isIndexHidden(index))
- {
- continue;
- }
- Qt::ItemFlags flags = index.flags();
- option.rect = visualRect(index);
- option.features |= QStyleOptionViewItem::WrapText;
- if (flags & Qt::ItemIsSelectable && selectionModel()->isSelected(index))
- {
- option.state |= selectionModel()->isSelected(index) ? QStyle::State_Selected
- : QStyle::State_None;
- }
- else
- {
- option.state &= ~QStyle::State_Selected;
- }
- option.state |= (index == currentIndex()) ? QStyle::State_HasFocus : QStyle::State_None;
- if (!(flags & Qt::ItemIsEnabled))
- {
- option.state &= ~QStyle::State_Enabled;
- }
- itemDelegate()->paint(&painter, option, index);
- }
-
- /*
- * Drop indicators for manual reordering...
- */
+ executeDelayedItemsLayout();
+
+ QPainter painter(this->viewport());
+
+ QStyleOptionViewItem option(viewOptions());
+ option.widget = this;
+
+ int wpWidth = viewport()->width();
+ option.rect.setWidth(wpWidth);
+ for (int i = 0; i < m_groups.size(); ++i)
+ {
+ VisualGroup *category = m_groups.at(i);
+ int y = category->verticalPosition();
+ y -= verticalOffset();
+ QRect backup = option.rect;
+ int height = category->totalHeight();
+ option.rect.setTop(y);
+ option.rect.setHeight(height);
+ option.rect.setLeft(m_leftMargin);
+ option.rect.setRight(wpWidth - m_rightMargin);
+ category->drawHeader(&painter, option);
+ y += category->totalHeight() + m_categoryMargin;
+ option.rect = backup;
+ }
+
+ for (int i = 0; i < model()->rowCount(); ++i)
+ {
+ const QModelIndex index = model()->index(i, 0);
+ if (isIndexHidden(index))
+ {
+ continue;
+ }
+ Qt::ItemFlags flags = index.flags();
+ option.rect = visualRect(index);
+ option.features |= QStyleOptionViewItem::WrapText;
+ if (flags & Qt::ItemIsSelectable && selectionModel()->isSelected(index))
+ {
+ option.state |= selectionModel()->isSelected(index) ? QStyle::State_Selected
+ : QStyle::State_None;
+ }
+ else
+ {
+ option.state &= ~QStyle::State_Selected;
+ }
+ option.state |= (index == currentIndex()) ? QStyle::State_HasFocus : QStyle::State_None;
+ if (!(flags & Qt::ItemIsEnabled))
+ {
+ option.state &= ~QStyle::State_Enabled;
+ }
+ itemDelegate()->paint(&painter, option, index);
+ }
+
+ /*
+ * Drop indicators for manual reordering...
+ */
#if 0
- if (!m_lastDragPosition.isNull())
- {
- QPair<Group *, int> pair = rowDropPos(m_lastDragPosition);
- Group *category = pair.first;
- int row = pair.second;
- if (category)
- {
- int internalRow = row - category->firstItemIndex;
- QLine line;
- if (internalRow >= category->numItems())
- {
- QRect toTheRightOfRect = visualRect(category->lastItem());
- line = QLine(toTheRightOfRect.topRight(), toTheRightOfRect.bottomRight());
- }
- else
- {
- QRect toTheLeftOfRect = visualRect(model()->index(row, 0));
- line = QLine(toTheLeftOfRect.topLeft(), toTheLeftOfRect.bottomLeft());
- }
- painter.save();
- painter.setPen(QPen(Qt::black, 3));
- painter.drawLine(line);
- painter.restore();
- }
- }
+ if (!m_lastDragPosition.isNull())
+ {
+ QPair<Group *, int> pair = rowDropPos(m_lastDragPosition);
+ Group *category = pair.first;
+ int row = pair.second;
+ if (category)
+ {
+ int internalRow = row - category->firstItemIndex;
+ QLine line;
+ if (internalRow >= category->numItems())
+ {
+ QRect toTheRightOfRect = visualRect(category->lastItem());
+ line = QLine(toTheRightOfRect.topRight(), toTheRightOfRect.bottomRight());
+ }
+ else
+ {
+ QRect toTheLeftOfRect = visualRect(model()->index(row, 0));
+ line = QLine(toTheLeftOfRect.topLeft(), toTheLeftOfRect.bottomLeft());
+ }
+ painter.save();
+ painter.setPen(QPen(Qt::black, 3));
+ painter.drawLine(line);
+ painter.restore();
+ }
+ }
#endif
}
void GroupView::resizeEvent(QResizeEvent *event)
{
- int newItemsPerRow = calculateItemsPerRow();
- if(newItemsPerRow != m_currentItemsPerRow)
- {
- m_currentCursorColumn = -1;
- m_currentItemsPerRow = newItemsPerRow;
- updateGeometries();
- }
- else
- {
- updateScrollbar();
- }
+ int newItemsPerRow = calculateItemsPerRow();
+ if(newItemsPerRow != m_currentItemsPerRow)
+ {
+ m_currentCursorColumn = -1;
+ m_currentItemsPerRow = newItemsPerRow;
+ updateGeometries();
+ }
+ else
+ {
+ updateScrollbar();
+ }
}
void GroupView::dragEnterEvent(QDragEnterEvent *event)
{
- if (!isDragEventAccepted(event))
- {
- return;
- }
- m_lastDragPosition = event->pos() + offset();
- viewport()->update();
- event->accept();
+ if (!isDragEventAccepted(event))
+ {
+ return;
+ }
+ m_lastDragPosition = event->pos() + offset();
+ viewport()->update();
+ event->accept();
}
void GroupView::dragMoveEvent(QDragMoveEvent *event)
{
- if (!isDragEventAccepted(event))
- {
- return;
- }
- m_lastDragPosition = event->pos() + offset();
- viewport()->update();
- event->accept();
+ if (!isDragEventAccepted(event))
+ {
+ return;
+ }
+ m_lastDragPosition = event->pos() + offset();
+ viewport()->update();
+ event->accept();
}
void GroupView::dragLeaveEvent(QDragLeaveEvent *event)
{
- m_lastDragPosition = QPoint();
- viewport()->update();
+ m_lastDragPosition = QPoint();
+ viewport()->update();
}
void GroupView::dropEvent(QDropEvent *event)
{
- m_lastDragPosition = QPoint();
-
- stopAutoScroll();
- setState(NoState);
-
- if (event->source() == this)
- {
- if(event->possibleActions() & Qt::MoveAction)
- {
- QPair<VisualGroup *, int> dropPos = rowDropPos(event->pos() + offset());
- const VisualGroup *category = dropPos.first;
- const int row = dropPos.second;
-
- if (row == -1)
- {
- viewport()->update();
- return;
- }
-
- const QString categoryText = category->text;
- if (model()->dropMimeData(event->mimeData(), Qt::MoveAction, row, 0, QModelIndex()))
- {
- model()->setData(model()->index(row, 0), categoryText,
- GroupViewRoles::GroupRole);
- event->setDropAction(Qt::MoveAction);
- event->accept();
- }
- updateGeometries();
- viewport()->update();
- }
- }
- auto mimedata = event->mimeData();
-
- // check if the action is supported
- if (!mimedata)
- {
- return;
- }
-
- // files dropped from outside?
- if (mimedata->hasUrls())
- {
- auto urls = mimedata->urls();
- event->accept();
- emit droppedURLs(urls);
- }
+ m_lastDragPosition = QPoint();
+
+ stopAutoScroll();
+ setState(NoState);
+
+ if (event->source() == this)
+ {
+ if(event->possibleActions() & Qt::MoveAction)
+ {
+ QPair<VisualGroup *, int> dropPos = rowDropPos(event->pos() + offset());
+ const VisualGroup *category = dropPos.first;
+ const int row = dropPos.second;
+
+ if (row == -1)
+ {
+ viewport()->update();
+ return;
+ }
+
+ const QString categoryText = category->text;
+ if (model()->dropMimeData(event->mimeData(), Qt::MoveAction, row, 0, QModelIndex()))
+ {
+ model()->setData(model()->index(row, 0), categoryText,
+ GroupViewRoles::GroupRole);
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ }
+ updateGeometries();
+ viewport()->update();
+ }
+ }
+ auto mimedata = event->mimeData();
+
+ // check if the action is supported
+ if (!mimedata)
+ {
+ return;
+ }
+
+ // files dropped from outside?
+ if (mimedata->hasUrls())
+ {
+ auto urls = mimedata->urls();
+ event->accept();
+ emit droppedURLs(urls);
+ }
}
void GroupView::startDrag(Qt::DropActions supportedActions)
{
- QModelIndexList indexes = selectionModel()->selectedIndexes();
- if(indexes.count() == 0)
- return;
-
- QMimeData *data = model()->mimeData(indexes);
- if (!data)
- {
- return;
- }
- QRect rect;
- QPixmap pixmap = renderToPixmap(indexes, &rect);
- //rect.translate(offset());
- // rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
- QDrag *drag = new QDrag(this);
- drag->setPixmap(pixmap);
- drag->setMimeData(data);
- Qt::DropAction defaultDropAction = Qt::IgnoreAction;
- if (this->defaultDropAction() != Qt::IgnoreAction &&
- (supportedActions & this->defaultDropAction()))
- {
- defaultDropAction = this->defaultDropAction();
- }
- if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
- {
- const QItemSelection selection = selectionModel()->selection();
-
- for (auto it = selection.constBegin(); it != selection.constEnd(); ++it)
- {
- QModelIndex parent = (*it).parent();
- if ((*it).left() != 0)
- {
- continue;
- }
- if ((*it).right() != (model()->columnCount(parent) - 1))
- {
- continue;
- }
- int count = (*it).bottom() - (*it).top() + 1;
- model()->removeRows((*it).top(), count, parent);
- }
- }
+ QModelIndexList indexes = selectionModel()->selectedIndexes();
+ if(indexes.count() == 0)
+ return;
+
+ QMimeData *data = model()->mimeData(indexes);
+ if (!data)
+ {
+ return;
+ }
+ QRect rect;
+ QPixmap pixmap = renderToPixmap(indexes, &rect);
+ //rect.translate(offset());
+ // rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
+ QDrag *drag = new QDrag(this);
+ drag->setPixmap(pixmap);
+ drag->setMimeData(data);
+ Qt::DropAction defaultDropAction = Qt::IgnoreAction;
+ if (this->defaultDropAction() != Qt::IgnoreAction &&
+ (supportedActions & this->defaultDropAction()))
+ {
+ defaultDropAction = this->defaultDropAction();
+ }
+ if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
+ {
+ const QItemSelection selection = selectionModel()->selection();
+
+ for (auto it = selection.constBegin(); it != selection.constEnd(); ++it)
+ {
+ QModelIndex parent = (*it).parent();
+ if ((*it).left() != 0)
+ {
+ continue;
+ }
+ if ((*it).right() != (model()->columnCount(parent) - 1))
+ {
+ continue;
+ }
+ int count = (*it).bottom() - (*it).top() + 1;
+ model()->removeRows((*it).top(), count, parent);
+ }
+ }
}
QRect GroupView::visualRect(const QModelIndex &index) const
{
- return geometryRect(index).translated(-offset());
+ return geometryRect(index).translated(-offset());
}
QRect GroupView::geometryRect(const QModelIndex &index) const
{
- if (!index.isValid() || isIndexHidden(index) || index.column() > 0)
- {
- return QRect();
- }
+ if (!index.isValid() || isIndexHidden(index) || index.column() > 0)
+ {
+ return QRect();
+ }
- int row = index.row();
- if(geometryCache.contains(row))
- {
- return *geometryCache[row];
- }
+ int row = index.row();
+ if(geometryCache.contains(row))
+ {
+ return *geometryCache[row];
+ }
- const VisualGroup *cat = category(index);
- QPair<int, int> pos = cat->positionOf(index);
- int x = pos.first;
- // int y = pos.second;
+ const VisualGroup *cat = category(index);
+ QPair<int, int> pos = cat->positionOf(index);
+ int x = pos.first;
+ // int y = pos.second;
- QRect out;
- out.setTop(cat->verticalPosition() + cat->headerHeight() + 5 + cat->rowTopOf(index));
- out.setLeft(m_spacing + x * (itemWidth() + m_spacing));
- out.setSize(itemDelegate()->sizeHint(viewOptions(), index));
- geometryCache.insert(row, new QRect(out));
- return out;
+ QRect out;
+ out.setTop(cat->verticalPosition() + cat->headerHeight() + 5 + cat->rowTopOf(index));
+ out.setLeft(m_spacing + x * (itemWidth() + m_spacing));
+ out.setSize(itemDelegate()->sizeHint(viewOptions(), index));
+ geometryCache.insert(row, new QRect(out));
+ return out;
}
QModelIndex GroupView::indexAt(const QPoint &point) const
{
- const_cast<GroupView*>(this)->executeDelayedItemsLayout();
+ const_cast<GroupView*>(this)->executeDelayedItemsLayout();
- for (int i = 0; i < model()->rowCount(); ++i)
- {
- QModelIndex index = model()->index(i, 0);
- if (visualRect(index).contains(point))
- {
- return index;
- }
- }
- return QModelIndex();
+ for (int i = 0; i < model()->rowCount(); ++i)
+ {
+ QModelIndex index = model()->index(i, 0);
+ if (visualRect(index).contains(point))
+ {
+ return index;
+ }
+ }
+ return QModelIndex();
}
void GroupView::setSelection(const QRect &rect,
- const QItemSelectionModel::SelectionFlags commands)
+ const QItemSelectionModel::SelectionFlags commands)
{
- for (int i = 0; i < model()->rowCount(); ++i)
- {
- QModelIndex index = model()->index(i, 0);
- QRect itemRect = visualRect(index);
- if (itemRect.intersects(rect))
- {
- selectionModel()->select(index, commands);
- update(itemRect.translated(-offset()));
- }
- }
+ for (int i = 0; i < model()->rowCount(); ++i)
+ {
+ QModelIndex index = model()->index(i, 0);
+ QRect itemRect = visualRect(index);
+ if (itemRect.intersects(rect))
+ {
+ selectionModel()->select(index, commands);
+ update(itemRect.translated(-offset()));
+ }
+ }
}
QPixmap GroupView::renderToPixmap(const QModelIndexList &indices, QRect *r) const
{
- Q_ASSERT(r);
- auto paintPairs = draggablePaintPairs(indices, r);
- if (paintPairs.isEmpty())
- {
- return QPixmap();
- }
- QPixmap pixmap(r->size());
- pixmap.fill(Qt::transparent);
- QPainter painter(&pixmap);
- QStyleOptionViewItem option = viewOptions();
- option.state |= QStyle::State_Selected;
- for (int j = 0; j < paintPairs.count(); ++j)
- {
- option.rect = paintPairs.at(j).first.translated(-r->topLeft());
- const QModelIndex &current = paintPairs.at(j).second;
- itemDelegate()->paint(&painter, option, current);
- }
- return pixmap;
+ Q_ASSERT(r);
+ auto paintPairs = draggablePaintPairs(indices, r);
+ if (paintPairs.isEmpty())
+ {
+ return QPixmap();
+ }
+ QPixmap pixmap(r->size());
+ pixmap.fill(Qt::transparent);
+ QPainter painter(&pixmap);
+ QStyleOptionViewItem option = viewOptions();
+ option.state |= QStyle::State_Selected;
+ for (int j = 0; j < paintPairs.count(); ++j)
+ {
+ option.rect = paintPairs.at(j).first.translated(-r->topLeft());
+ const QModelIndex &current = paintPairs.at(j).second;
+ itemDelegate()->paint(&painter, option, current);
+ }
+ return pixmap;
}
QList<QPair<QRect, QModelIndex>> GroupView::draggablePaintPairs(const QModelIndexList &indices,
- QRect *r) const
+ QRect *r) const
{
- Q_ASSERT(r);
- QRect &rect = *r;
- QList<QPair<QRect, QModelIndex>> ret;
- for (int i = 0; i < indices.count(); ++i)
- {
- const QModelIndex &index = indices.at(i);
- const QRect current = geometryRect(index);
- ret += qMakePair(current, index);
- rect |= current;
- }
- return ret;
+ Q_ASSERT(r);
+ QRect &rect = *r;
+ QList<QPair<QRect, QModelIndex>> ret;
+ for (int i = 0; i < indices.count(); ++i)
+ {
+ const QModelIndex &index = indices.at(i);
+ const QRect current = geometryRect(index);
+ ret += qMakePair(current, index);
+ rect |= current;
+ }
+ return ret;
}
bool GroupView::isDragEventAccepted(QDropEvent *event)
{
- return true;
+ return true;
}
QPair<VisualGroup *, int> GroupView::rowDropPos(const QPoint &pos)
{
- return qMakePair<VisualGroup*, int>(nullptr, -1);
+ return qMakePair<VisualGroup*, int>(nullptr, -1);
}
QPoint GroupView::offset() const
{
- return QPoint(horizontalOffset(), verticalOffset());
+ return QPoint(horizontalOffset(), verticalOffset());
}
QRegion GroupView::visualRegionForSelection(const QItemSelection &selection) const
{
- QRegion region;
- for (auto &range : selection)
- {
- int start_row = range.top();
- int end_row = range.bottom();
- for (int row = start_row; row <= end_row; ++row)
- {
- int start_column = range.left();
- int end_column = range.right();
- for (int column = start_column; column <= end_column; ++column)
- {
- QModelIndex index = model()->index(row, column, rootIndex());
- region += visualRect(index); // OK
- }
- }
- }
- return region;
+ QRegion region;
+ for (auto &range : selection)
+ {
+ int start_row = range.top();
+ int end_row = range.bottom();
+ for (int row = start_row; row <= end_row; ++row)
+ {
+ int start_column = range.left();
+ int end_column = range.right();
+ for (int column = start_column; column <= end_column; ++column)
+ {
+ QModelIndex index = model()->index(row, column, rootIndex());
+ region += visualRect(index); // OK
+ }
+ }
+ }
+ return region;
}
QModelIndex GroupView::moveCursor(QAbstractItemView::CursorAction cursorAction,
- Qt::KeyboardModifiers modifiers)
-{
- auto current = currentIndex();
- if(!current.isValid())
- {
- return current;
- }
- auto cat = category(current);
- int group_index = m_groups.indexOf(cat);
- if(group_index < 0)
- return current;
-
- auto real_group = m_groups[group_index];
- int beginning_row = 0;
- for(auto group: m_groups)
- {
- if(group == real_group)
- break;
- beginning_row += group->numRows();
- }
-
- QPair<int, int> pos = cat->positionOf(current);
- int column = pos.first;
- int row = pos.second;
- if(m_currentCursorColumn < 0)
- {
- m_currentCursorColumn = column;
- }
- switch(cursorAction)
- {
- case MoveUp:
- {
- if(row == 0)
- {
- int prevgroupindex = group_index-1;
- while(prevgroupindex >= 0)
- {
- auto prevgroup = m_groups[prevgroupindex];
- if(prevgroup->collapsed)
- {
- prevgroupindex--;
- continue;
- }
- int newRow = prevgroup->numRows() - 1;
- int newRowSize = prevgroup->rows[newRow].size();
- int newColumn = m_currentCursorColumn;
- if (m_currentCursorColumn >= newRowSize)
- {
- newColumn = newRowSize - 1;
- }
- return prevgroup->rows[newRow][newColumn];
- }
- }
- else
- {
- int newRow = row - 1;
- int newRowSize = cat->rows[newRow].size();
- int newColumn = m_currentCursorColumn;
- if (m_currentCursorColumn >= newRowSize)
- {
- newColumn = newRowSize - 1;
- }
- return cat->rows[newRow][newColumn];
- }
- return current;
- }
- case MoveDown:
- {
- if(row == cat->rows.size() - 1)
- {
- int nextgroupindex = group_index+1;
- while (nextgroupindex < m_groups.size())
- {
- auto nextgroup = m_groups[nextgroupindex];
- if(nextgroup->collapsed)
- {
- nextgroupindex++;
- continue;
- }
- int newRowSize = nextgroup->rows[0].size();
- int newColumn = m_currentCursorColumn;
- if (m_currentCursorColumn >= newRowSize)
- {
- newColumn = newRowSize - 1;
- }
- return nextgroup->rows[0][newColumn];
- }
- }
- else
- {
- int newRow = row + 1;
- int newRowSize = cat->rows[newRow].size();
- int newColumn = m_currentCursorColumn;
- if (m_currentCursorColumn >= newRowSize)
- {
- newColumn = newRowSize - 1;
- }
- return cat->rows[newRow][newColumn];
- }
- return current;
- }
- case MoveLeft:
- {
- if(column > 0)
- {
- m_currentCursorColumn = column - 1;
- return cat->rows[row][column - 1];
- }
- // TODO: moving to previous line
- return current;
- }
- case MoveRight:
- {
- if(column < cat->rows[row].size() - 1)
- {
- m_currentCursorColumn = column + 1;
- return cat->rows[row][column + 1];
- }
- // TODO: moving to next line
- return current;
- }
- case MoveHome:
- {
- m_currentCursorColumn = 0;
- return cat->rows[row][0];
- }
- case MoveEnd:
- {
- auto last = cat->rows[row].size() - 1;
- m_currentCursorColumn = last;
- return cat->rows[row][last];
- }
- default:
- break;
- }
- return current;
+ Qt::KeyboardModifiers modifiers)
+{
+ auto current = currentIndex();
+ if(!current.isValid())
+ {
+ return current;
+ }
+ auto cat = category(current);
+ int group_index = m_groups.indexOf(cat);
+ if(group_index < 0)
+ return current;
+
+ auto real_group = m_groups[group_index];
+ int beginning_row = 0;
+ for(auto group: m_groups)
+ {
+ if(group == real_group)
+ break;
+ beginning_row += group->numRows();
+ }
+
+ QPair<int, int> pos = cat->positionOf(current);
+ int column = pos.first;
+ int row = pos.second;
+ if(m_currentCursorColumn < 0)
+ {
+ m_currentCursorColumn = column;
+ }
+ switch(cursorAction)
+ {
+ case MoveUp:
+ {
+ if(row == 0)
+ {
+ int prevgroupindex = group_index-1;
+ while(prevgroupindex >= 0)
+ {
+ auto prevgroup = m_groups[prevgroupindex];
+ if(prevgroup->collapsed)
+ {
+ prevgroupindex--;
+ continue;
+ }
+ int newRow = prevgroup->numRows() - 1;
+ int newRowSize = prevgroup->rows[newRow].size();
+ int newColumn = m_currentCursorColumn;
+ if (m_currentCursorColumn >= newRowSize)
+ {
+ newColumn = newRowSize - 1;
+ }
+ return prevgroup->rows[newRow][newColumn];
+ }
+ }
+ else
+ {
+ int newRow = row - 1;
+ int newRowSize = cat->rows[newRow].size();
+ int newColumn = m_currentCursorColumn;
+ if (m_currentCursorColumn >= newRowSize)
+ {
+ newColumn = newRowSize - 1;
+ }
+ return cat->rows[newRow][newColumn];
+ }
+ return current;
+ }
+ case MoveDown:
+ {
+ if(row == cat->rows.size() - 1)
+ {
+ int nextgroupindex = group_index+1;
+ while (nextgroupindex < m_groups.size())
+ {
+ auto nextgroup = m_groups[nextgroupindex];
+ if(nextgroup->collapsed)
+ {
+ nextgroupindex++;
+ continue;
+ }
+ int newRowSize = nextgroup->rows[0].size();
+ int newColumn = m_currentCursorColumn;
+ if (m_currentCursorColumn >= newRowSize)
+ {
+ newColumn = newRowSize - 1;
+ }
+ return nextgroup->rows[0][newColumn];
+ }
+ }
+ else
+ {
+ int newRow = row + 1;
+ int newRowSize = cat->rows[newRow].size();
+ int newColumn = m_currentCursorColumn;
+ if (m_currentCursorColumn >= newRowSize)
+ {
+ newColumn = newRowSize - 1;
+ }
+ return cat->rows[newRow][newColumn];
+ }
+ return current;
+ }
+ case MoveLeft:
+ {
+ if(column > 0)
+ {
+ m_currentCursorColumn = column - 1;
+ return cat->rows[row][column - 1];
+ }
+ // TODO: moving to previous line
+ return current;
+ }
+ case MoveRight:
+ {
+ if(column < cat->rows[row].size() - 1)
+ {
+ m_currentCursorColumn = column + 1;
+ return cat->rows[row][column + 1];
+ }
+ // TODO: moving to next line
+ return current;
+ }
+ case MoveHome:
+ {
+ m_currentCursorColumn = 0;
+ return cat->rows[row][0];
+ }
+ case MoveEnd:
+ {
+ auto last = cat->rows[row].size() - 1;
+ m_currentCursorColumn = last;
+ return cat->rows[row][last];
+ }
+ default:
+ break;
+ }
+ return current;
}
int GroupView::horizontalOffset() const
{
- return horizontalScrollBar()->value();
+ return horizontalScrollBar()->value();
}
int GroupView::verticalOffset() const
{
- return verticalScrollBar()->value();
+ return verticalScrollBar()->value();
}
void GroupView::scrollContentsBy(int dx, int dy)
{
- scrollDirtyRegion(dx, dy);
- viewport()->scroll(dx, dy);
+ scrollDirtyRegion(dx, dy);
+ viewport()->scroll(dx, dy);
}
void GroupView::scrollTo(const QModelIndex &index, ScrollHint hint)
{
- if (!index.isValid())
- return;
+ if (!index.isValid())
+ return;
- const QRect rect = visualRect(index);
- if (hint == EnsureVisible && viewport()->rect().contains(rect))
- {
- viewport()->update(rect);
- return;
- }
+ const QRect rect = visualRect(index);
+ if (hint == EnsureVisible && viewport()->rect().contains(rect))
+ {
+ viewport()->update(rect);
+ return;
+ }
- verticalScrollBar()->setValue(verticalScrollToValue(index, rect, hint));
+ verticalScrollBar()->setValue(verticalScrollToValue(index, rect, hint));
}
int GroupView::verticalScrollToValue(const QModelIndex &index, const QRect &rect,
QListView::ScrollHint hint) const
{
- const QRect area = viewport()->rect();
- const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top());
- const bool below = (hint == QListView::EnsureVisible && rect.bottom() > area.bottom());
-
- int verticalValue = verticalScrollBar()->value();
- QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing());
- if (hint == QListView::PositionAtTop || above)
- verticalValue += adjusted.top();
- else if (hint == QListView::PositionAtBottom || below)
- verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1);
- else if (hint == QListView::PositionAtCenter)
- verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2);
- return verticalValue;
+ const QRect area = viewport()->rect();
+ const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top());
+ const bool below = (hint == QListView::EnsureVisible && rect.bottom() > area.bottom());
+
+ int verticalValue = verticalScrollBar()->value();
+ QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing());
+ if (hint == QListView::PositionAtTop || above)
+ verticalValue += adjusted.top();
+ else if (hint == QListView::PositionAtBottom || below)
+ verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1);
+ else if (hint == QListView::PositionAtCenter)
+ verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2);
+ return verticalValue;
}
diff --git a/application/groupview/GroupView.h b/application/groupview/GroupView.h
index 07c65bb5..ceb602fc 100644
--- a/application/groupview/GroupView.h
+++ b/application/groupview/GroupView.h
@@ -23,126 +23,126 @@
struct GroupViewRoles
{
- enum
- {
- GroupRole = Qt::UserRole,
- ProgressValueRole,
- ProgressMaximumRole
- };
+ enum
+ {
+ GroupRole = Qt::UserRole,
+ ProgressValueRole,
+ ProgressMaximumRole
+ };
};
class GroupView : public QAbstractItemView
{
- Q_OBJECT
+ Q_OBJECT
public:
- GroupView(QWidget *parent = 0);
- ~GroupView();
+ GroupView(QWidget *parent = 0);
+ ~GroupView();
- void setModel(QAbstractItemModel *model) override;
+ void setModel(QAbstractItemModel *model) override;
- /// return geometry rectangle occupied by the specified model item
- QRect geometryRect(const QModelIndex &index) const;
- /// return visual rectangle occupied by the specified model item
- virtual QRect visualRect(const QModelIndex &index) const override;
- /// get the model index at the specified visual point
- virtual QModelIndex indexAt(const QPoint &point) const override;
- QString groupNameAt(const QPoint &point);
- void setSelection(const QRect &rect,
- const QItemSelectionModel::SelectionFlags commands) override;
+ /// return geometry rectangle occupied by the specified model item
+ QRect geometryRect(const QModelIndex &index) const;
+ /// return visual rectangle occupied by the specified model item
+ virtual QRect visualRect(const QModelIndex &index) const override;
+ /// get the model index at the specified visual point
+ virtual QModelIndex indexAt(const QPoint &point) const override;
+ QString groupNameAt(const QPoint &point);
+ void setSelection(const QRect &rect,
+ const QItemSelectionModel::SelectionFlags commands) override;
- virtual int horizontalOffset() const override;
- virtual int verticalOffset() const override;
- virtual void scrollContentsBy(int dx, int dy) override;
- virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override;
+ virtual int horizontalOffset() const override;
+ virtual int verticalOffset() const override;
+ virtual void scrollContentsBy(int dx, int dy) override;
+ virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override;
- virtual QModelIndex moveCursor(CursorAction cursorAction,
- Qt::KeyboardModifiers modifiers) override;
+ virtual QModelIndex moveCursor(CursorAction cursorAction,
+ Qt::KeyboardModifiers modifiers) override;
- virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override;
+ virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override;
- int spacing() const
- {
- return m_spacing;
- };
+ int spacing() const
+ {
+ return m_spacing;
+ };
public slots:
- virtual void updateGeometries() override;
+ virtual void updateGeometries() override;
protected slots:
- virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
- const QVector<int> &roles) override;
- virtual void rowsInserted(const QModelIndex &parent, int start, int end) override;
- virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override;
- void modelReset();
- void rowsRemoved();
+ virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
+ const QVector<int> &roles) override;
+ virtual void rowsInserted(const QModelIndex &parent, int start, int end) override;
+ virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override;
+ void modelReset();
+ void rowsRemoved();
signals:
- void droppedURLs(QList<QUrl> urls);
+ void droppedURLs(QList<QUrl> urls);
protected:
- virtual bool isIndexHidden(const QModelIndex &index) const override;
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- void mouseReleaseEvent(QMouseEvent *event) override;
- void mouseDoubleClickEvent(QMouseEvent *event) override;
- void paintEvent(QPaintEvent *event) override;
- void resizeEvent(QResizeEvent *event) override;
+ virtual bool isIndexHidden(const QModelIndex &index) const override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+ void paintEvent(QPaintEvent *event) override;
+ void resizeEvent(QResizeEvent *event) override;
- void dragEnterEvent(QDragEnterEvent *event) override;
- void dragMoveEvent(QDragMoveEvent *event) override;
- void dragLeaveEvent(QDragLeaveEvent *event) override;
- void dropEvent(QDropEvent *event) override;
+ void dragEnterEvent(QDragEnterEvent *event) override;
+ void dragMoveEvent(QDragMoveEvent *event) override;
+ void dragLeaveEvent(QDragLeaveEvent *event) override;
+ void dropEvent(QDropEvent *event) override;
- void startDrag(Qt::DropActions supportedActions) override;
+ void startDrag(Qt::DropActions supportedActions) override;
- void updateScrollbar();
+ void updateScrollbar();
private:
- friend struct VisualGroup;
- QList<VisualGroup *> m_groups;
-
- // geometry
- int m_leftMargin = 5;
- int m_rightMargin = 5;
- int m_bottomMargin = 5;
- int m_categoryMargin = 5;
- int m_spacing = 5;
- int m_itemWidth = 100;
- int m_currentItemsPerRow = -1;
- int m_currentCursorColumn= -1;
- mutable QCache<int, QRect> geometryCache;
-
- // point where the currently active mouse action started in geometry coordinates
- QPoint m_pressedPosition;
- QPersistentModelIndex m_pressedIndex;
- bool m_pressedAlreadySelected;
- VisualGroup *m_pressedCategory;
- QItemSelectionModel::SelectionFlag m_ctrlDragSelectionFlag;
- QPoint m_lastDragPosition;
-
- VisualGroup *category(const QModelIndex &index) const;
- VisualGroup *category(const QString &cat) const;
- VisualGroup *categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const;
-
- int itemsPerRow() const
- {
- return m_currentItemsPerRow;
- };
- int contentWidth() const;
+ friend struct VisualGroup;
+ QList<VisualGroup *> m_groups;
+
+ // geometry
+ int m_leftMargin = 5;
+ int m_rightMargin = 5;
+ int m_bottomMargin = 5;
+ int m_categoryMargin = 5;
+ int m_spacing = 5;
+ int m_itemWidth = 100;
+ int m_currentItemsPerRow = -1;
+ int m_currentCursorColumn= -1;
+ mutable QCache<int, QRect> geometryCache;
+
+ // point where the currently active mouse action started in geometry coordinates
+ QPoint m_pressedPosition;
+ QPersistentModelIndex m_pressedIndex;
+ bool m_pressedAlreadySelected;
+ VisualGroup *m_pressedCategory;
+ QItemSelectionModel::SelectionFlag m_ctrlDragSelectionFlag;
+ QPoint m_lastDragPosition;
+
+ VisualGroup *category(const QModelIndex &index) const;
+ VisualGroup *category(const QString &cat) const;
+ VisualGroup *categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const;
+
+ int itemsPerRow() const
+ {
+ return m_currentItemsPerRow;
+ };
+ int contentWidth() const;
private: /* methods */
- int itemWidth() const;
- int calculateItemsPerRow() const;
- int verticalScrollToValue(const QModelIndex &index, const QRect &rect,
- QListView::ScrollHint hint) const;
- QPixmap renderToPixmap(const QModelIndexList &indices, QRect *r) const;
- QList<QPair<QRect, QModelIndex>> draggablePaintPairs(const QModelIndexList &indices,
- QRect *r) const;
+ int itemWidth() const;
+ int calculateItemsPerRow() const;
+ int verticalScrollToValue(const QModelIndex &index, const QRect &rect,
+ QListView::ScrollHint hint) const;
+ QPixmap renderToPixmap(const QModelIndexList &indices, QRect *r) const;
+ QList<QPair<QRect, QModelIndex>> draggablePaintPairs(const QModelIndexList &indices,
+ QRect *r) const;
- bool isDragEventAccepted(QDropEvent *event);
+ bool isDragEventAccepted(QDropEvent *event);
- QPair<VisualGroup *, int> rowDropPos(const QPoint &pos);
+ QPair<VisualGroup *, int> rowDropPos(const QPoint &pos);
- QPoint offset() const;
+ QPoint offset() const;
};
diff --git a/application/groupview/GroupedProxyModel.cpp b/application/groupview/GroupedProxyModel.cpp
index c13f2411..5617a1ee 100644
--- a/application/groupview/GroupedProxyModel.cpp
+++ b/application/groupview/GroupedProxyModel.cpp
@@ -24,25 +24,25 @@ GroupedProxyModel::GroupedProxyModel(QObject *parent) : QSortFilterProxyModel(pa
bool GroupedProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
- const QString leftCategory = left.data(GroupViewRoles::GroupRole).toString();
- const QString rightCategory = right.data(GroupViewRoles::GroupRole).toString();
- if (leftCategory == rightCategory)
- {
- return subSortLessThan(left, right);
- }
- else
- {
- // FIXME: real group sorting happens in GroupView::updateGeometries(), see LocaleString
- auto result = leftCategory.localeAwareCompare(rightCategory);
- if(result == 0)
- {
- return subSortLessThan(left, right);
- }
- return result < 0;
- }
+ const QString leftCategory = left.data(GroupViewRoles::GroupRole).toString();
+ const QString rightCategory = right.data(GroupViewRoles::GroupRole).toString();
+ if (leftCategory == rightCategory)
+ {
+ return subSortLessThan(left, right);
+ }
+ else
+ {
+ // FIXME: real group sorting happens in GroupView::updateGeometries(), see LocaleString
+ auto result = leftCategory.localeAwareCompare(rightCategory);
+ if(result == 0)
+ {
+ return subSortLessThan(left, right);
+ }
+ return result < 0;
+ }
}
bool GroupedProxyModel::subSortLessThan(const QModelIndex &left, const QModelIndex &right) const
{
- return left.row() < right.row();
+ return left.row() < right.row();
}
diff --git a/application/groupview/GroupedProxyModel.h b/application/groupview/GroupedProxyModel.h
index babeb308..e1c51c0f 100644
--- a/application/groupview/GroupedProxyModel.h
+++ b/application/groupview/GroupedProxyModel.h
@@ -19,12 +19,12 @@
class GroupedProxyModel : public QSortFilterProxyModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- GroupedProxyModel(QObject *parent = 0);
+ GroupedProxyModel(QObject *parent = 0);
protected:
- virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
- virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const;
+ virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
+ virtual bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const;
};
diff --git a/application/groupview/InstanceDelegate.cpp b/application/groupview/InstanceDelegate.cpp
index 0855c04a..42860aef 100644
--- a/application/groupview/InstanceDelegate.cpp
+++ b/application/groupview/InstanceDelegate.cpp
@@ -27,25 +27,25 @@
// Origin: Qt
static void viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height,
- qreal &widthUsed)
+ qreal &widthUsed)
{
- height = 0;
- widthUsed = 0;
- textLayout.beginLayout();
- QString str = textLayout.text();
- while (true)
- {
- QTextLine line = textLayout.createLine();
- if (!line.isValid())
- break;
- if (line.textLength() == 0)
- break;
- line.setLineWidth(lineWidth);
- line.setPosition(QPointF(0, height));
- height += line.height();
- widthUsed = qMax(widthUsed, line.naturalTextWidth());
- }
- textLayout.endLayout();
+ height = 0;
+ widthUsed = 0;
+ textLayout.beginLayout();
+ QString str = textLayout.text();
+ while (true)
+ {
+ QTextLine line = textLayout.createLine();
+ if (!line.isValid())
+ break;
+ if (line.textLength() == 0)
+ break;
+ line.setLineWidth(lineWidth);
+ line.setPosition(QPointF(0, height));
+ height += line.height();
+ widthUsed = qMax(widthUsed, line.naturalTextWidth());
+ }
+ textLayout.endLayout();
}
ListViewDelegate::ListViewDelegate(QObject *parent) : QStyledItemDelegate(parent)
@@ -53,291 +53,291 @@ ListViewDelegate::ListViewDelegate(QObject *parent) : QStyledItemDelegate(parent
}
void drawSelectionRect(QPainter *painter, const QStyleOptionViewItem &option,
- const QRect &rect)
+ const QRect &rect)
{
- if ((option.state & QStyle::State_Selected))
- painter->fillRect(rect, option.palette.brush(QPalette::Highlight));
- else
- {
- QColor backgroundColor = option.palette.color(QPalette::Background);
- backgroundColor.setAlpha(160);
- painter->fillRect(rect, QBrush(backgroundColor));
- }
+ if ((option.state & QStyle::State_Selected))
+ painter->fillRect(rect, option.palette.brush(QPalette::Highlight));
+ else
+ {
+ QColor backgroundColor = option.palette.color(QPalette::Background);
+ backgroundColor.setAlpha(160);
+ painter->fillRect(rect, QBrush(backgroundColor));
+ }
}
void drawFocusRect(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect)
{
- if (!(option.state & QStyle::State_HasFocus))
- return;
- QStyleOptionFocusRect opt;
- opt.direction = option.direction;
- opt.fontMetrics = option.fontMetrics;
- opt.palette = option.palette;
- opt.rect = rect;
- // opt.state = option.state | QStyle::State_KeyboardFocusChange |
- // QStyle::State_Item;
- auto col = option.state & QStyle::State_Selected ? QPalette::Highlight : QPalette::Base;
- opt.backgroundColor = option.palette.color(col);
- // Apparently some widget styles expect this hint to not be set
- painter->setRenderHint(QPainter::Antialiasing, false);
-
- QStyle *style = option.widget ? option.widget->style() : QApplication::style();
-
- style->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, painter, option.widget);
-
- painter->setRenderHint(QPainter::Antialiasing);
+ if (!(option.state & QStyle::State_HasFocus))
+ return;
+ QStyleOptionFocusRect opt;
+ opt.direction = option.direction;
+ opt.fontMetrics = option.fontMetrics;
+ opt.palette = option.palette;
+ opt.rect = rect;
+ // opt.state = option.state | QStyle::State_KeyboardFocusChange |
+ // QStyle::State_Item;
+ auto col = option.state & QStyle::State_Selected ? QPalette::Highlight : QPalette::Base;
+ opt.backgroundColor = option.palette.color(col);
+ // Apparently some widget styles expect this hint to not be set
+ painter->setRenderHint(QPainter::Antialiasing, false);
+
+ QStyle *style = option.widget ? option.widget->style() : QApplication::style();
+
+ style->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, painter, option.widget);
+
+ painter->setRenderHint(QPainter::Antialiasing);
}
// TODO this can be made a lot prettier
void drawProgressOverlay(QPainter *painter, const QStyleOptionViewItem &option,
- const int value, const int maximum)
+ const int value, const int maximum)
{
- if (maximum == 0 || value == maximum)
- {
- return;
- }
+ if (maximum == 0 || value == maximum)
+ {
+ return;
+ }
- painter->save();
+ painter->save();
- qreal percent = (qreal)value / (qreal)maximum;
- QColor color = option.palette.color(QPalette::Dark);
- color.setAlphaF(0.70f);
- painter->setBrush(color);
- painter->setPen(QPen(QBrush(), 0));
- painter->drawPie(option.rect, 90 * 16, -percent * 360 * 16);
+ qreal percent = (qreal)value / (qreal)maximum;
+ QColor color = option.palette.color(QPalette::Dark);
+ color.setAlphaF(0.70f);
+ painter->setBrush(color);
+ painter->setPen(QPen(QBrush(), 0));
+ painter->drawPie(option.rect, 90 * 16, -percent * 360 * 16);
- painter->restore();
+ painter->restore();
}
void drawBadges(QPainter *painter, const QStyleOptionViewItem &option, BaseInstance *instance, QIcon::Mode mode, QIcon::State state)
{
- QList<QString> pixmaps;
- if (instance->isRunning())
- {
- pixmaps.append("status-running");
- }
- else if (instance->hasCrashed() || instance->hasVersionBroken())
- {
- pixmaps.append("status-bad");
- }
- if (instance->hasUpdateAvailable())
- {
- pixmaps.append("checkupdate");
- }
-
- static const int itemSide = 24;
- static const int spacing = 1;
- const int itemsPerRow = qMax(1, qFloor(double(option.rect.width() + spacing) / double(itemSide + spacing)));
- const int rows = qCeil((double)pixmaps.size() / (double)itemsPerRow);
- QListIterator<QString> it(pixmaps);
- painter->translate(option.rect.topLeft());
- for (int y = 0; y < rows; ++y)
- {
- for (int x = 0; x < itemsPerRow; ++x)
- {
- if (!it.hasNext())
- {
- return;
- }
- // FIXME: inject this.
- auto icon = XdgIcon::fromTheme(it.next());
- // opt.icon.paint(painter, iconbox, Qt::AlignCenter, mode, state);
- const QPixmap pixmap;
- // itemSide
- QRect badgeRect(
- option.rect.width() - x * itemSide + qMax(x - 1, 0) * spacing - itemSide,
- y * itemSide + qMax(y - 1, 0) * spacing,
- itemSide,
- itemSide
- );
- icon.paint(painter, badgeRect, Qt::AlignCenter, mode, state);
- }
- }
- painter->translate(-option.rect.topLeft());
+ QList<QString> pixmaps;
+ if (instance->isRunning())
+ {
+ pixmaps.append("status-running");
+ }
+ else if (instance->hasCrashed() || instance->hasVersionBroken())
+ {
+ pixmaps.append("status-bad");
+ }
+ if (instance->hasUpdateAvailable())
+ {
+ pixmaps.append("checkupdate");
+ }
+
+ static const int itemSide = 24;
+ static const int spacing = 1;
+ const int itemsPerRow = qMax(1, qFloor(double(option.rect.width() + spacing) / double(itemSide + spacing)));
+ const int rows = qCeil((double)pixmaps.size() / (double)itemsPerRow);
+ QListIterator<QString> it(pixmaps);
+ painter->translate(option.rect.topLeft());
+ for (int y = 0; y < rows; ++y)
+ {
+ for (int x = 0; x < itemsPerRow; ++x)
+ {
+ if (!it.hasNext())
+ {
+ return;
+ }
+ // FIXME: inject this.
+ auto icon = XdgIcon::fromTheme(it.next());
+ // opt.icon.paint(painter, iconbox, Qt::AlignCenter, mode, state);
+ const QPixmap pixmap;
+ // itemSide
+ QRect badgeRect(
+ option.rect.width() - x * itemSide + qMax(x - 1, 0) * spacing - itemSide,
+ y * itemSide + qMax(y - 1, 0) * spacing,
+ itemSide,
+ itemSide
+ );
+ icon.paint(painter, badgeRect, Qt::AlignCenter, mode, state);
+ }
+ }
+ painter->translate(-option.rect.topLeft());
}
static QSize viewItemTextSize(const QStyleOptionViewItem *option)
{
- QStyle *style = option->widget ? option->widget->style() : QApplication::style();
- QTextOption textOption;
- textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
- QTextLayout textLayout;
- textLayout.setTextOption(textOption);
- textLayout.setFont(option->font);
- textLayout.setText(option->text);
- const int textMargin =
- style->pixelMetric(QStyle::PM_FocusFrameHMargin, option, option->widget) + 1;
- QRect bounds(0, 0, 100 - 2 * textMargin, 600);
- qreal height = 0, widthUsed = 0;
- viewItemTextLayout(textLayout, bounds.width(), height, widthUsed);
- const QSize size(qCeil(widthUsed), qCeil(height));
- return QSize(size.width() + 2 * textMargin, size.height());
+ QStyle *style = option->widget ? option->widget->style() : QApplication::style();
+ QTextOption textOption;
+ textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+ QTextLayout textLayout;
+ textLayout.setTextOption(textOption);
+ textLayout.setFont(option->font);
+ textLayout.setText(option->text);
+ const int textMargin =
+ style->pixelMetric(QStyle::PM_FocusFrameHMargin, option, option->widget) + 1;
+ QRect bounds(0, 0, 100 - 2 * textMargin, 600);
+ qreal height = 0, widthUsed = 0;
+ viewItemTextLayout(textLayout, bounds.width(), height, widthUsed);
+ const QSize size(qCeil(widthUsed), qCeil(height));
+ return QSize(size.width() + 2 * textMargin, size.height());
}
void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
- const QModelIndex &index) const
+ const QModelIndex &index) const
{
- QStyleOptionViewItem opt = option;
- initStyleOption(&opt, index);
- painter->save();
- painter->setClipRect(opt.rect);
-
- opt.features |= QStyleOptionViewItem::WrapText;
- opt.text = index.data().toString();
- opt.textElideMode = Qt::ElideRight;
- opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
-
- QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
-
- // const int iconSize = style->pixelMetric(QStyle::PM_IconViewIconSize);
- const int iconSize = 48;
- QRect iconbox = opt.rect;
- const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, opt.widget) + 1;
- QRect textRect = opt.rect;
- QRect textHighlightRect = textRect;
- // clip the decoration on top, remove width padding
- textRect.adjust(textMargin, iconSize + textMargin + 5, -textMargin, 0);
-
- textHighlightRect.adjust(0, iconSize + 5, 0, 0);
-
- // draw background
- {
- // FIXME: unused
- // QSize textSize = viewItemTextSize ( &opt );
- QPalette::ColorGroup cg;
- QStyleOptionViewItem opt2(opt);
-
- if ((opt.widget && opt.widget->isEnabled()) || (opt.state & QStyle::State_Enabled))
- {
- if (!(opt.state & QStyle::State_Active))
- cg = QPalette::Inactive;
- else
- cg = QPalette::Normal;
- }
- else
- {
- cg = QPalette::Disabled;
- }
- opt2.palette.setCurrentColorGroup(cg);
-
- // fill in background, if any
-
- if (opt.backgroundBrush.style() != Qt::NoBrush)
- {
- QPointF oldBO = painter->brushOrigin();
- painter->setBrushOrigin(opt.rect.topLeft());
- painter->fillRect(opt.rect, opt.backgroundBrush);
- painter->setBrushOrigin(oldBO);
- }
-
- drawSelectionRect(painter, opt2, textHighlightRect);
-
- /*
- if (opt.showDecorationSelected)
- {
- drawSelectionRect(painter, opt2, opt.rect);
- drawFocusRect(painter, opt2, opt.rect);
- // painter->fillRect ( opt.rect, opt.palette.brush ( cg, QPalette::Highlight ) );
- }
- else
- {
-
- // if ( opt.state & QStyle::State_Selected )
- {
- // QRect textRect = subElementRect ( QStyle::SE_ItemViewItemText, opt,
- // opt.widget );
- // painter->fillRect ( textHighlightRect, opt.palette.brush ( cg,
- // QPalette::Highlight ) );
- drawSelectionRect(painter, opt2, textHighlightRect);
- drawFocusRect(painter, opt2, textHighlightRect);
- }
- }
- */
- }
-
- // icon mode and state, also used for badges
- QIcon::Mode mode = QIcon::Normal;
- if (!(opt.state & QStyle::State_Enabled))
- mode = QIcon::Disabled;
- else if (opt.state & QStyle::State_Selected)
- mode = QIcon::Selected;
- QIcon::State state = opt.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
-
- // draw the icon
- {
- iconbox.setHeight(iconSize);
- opt.icon.paint(painter, iconbox, Qt::AlignCenter, mode, state);
- }
- // set the text colors
- QPalette::ColorGroup cg =
- opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
- if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
- cg = QPalette::Inactive;
- if (opt.state & QStyle::State_Selected)
- {
- painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
- }
- else
- {
- painter->setPen(opt.palette.color(cg, QPalette::Text));
- }
-
- // draw the text
- QTextOption textOption;
- textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
- textOption.setTextDirection(opt.direction);
- textOption.setAlignment(QStyle::visualAlignment(opt.direction, opt.displayAlignment));
- QTextLayout textLayout;
- textLayout.setTextOption(textOption);
- textLayout.setFont(opt.font);
- textLayout.setText(opt.text);
-
- qreal width, height;
- viewItemTextLayout(textLayout, textRect.width(), height, width);
-
- const int lineCount = textLayout.lineCount();
-
- const QRect layoutRect = QStyle::alignedRect(
- opt.direction, opt.displayAlignment, QSize(textRect.width(), int(height)), textRect);
- const QPointF position = layoutRect.topLeft();
- for (int i = 0; i < lineCount; ++i)
- {
- const QTextLine line = textLayout.lineAt(i);
- line.draw(painter, position);
- }
-
- // FIXME: this really has no business of being here. Make generic.
- auto instance = (BaseInstance*)index.data(InstanceList::InstancePointerRole)
- .value<void *>();
- if (instance)
- {
- drawBadges(painter, opt, instance, mode, state);
- }
-
- drawProgressOverlay(painter, opt, index.data(GroupViewRoles::ProgressValueRole).toInt(),
- index.data(GroupViewRoles::ProgressMaximumRole).toInt());
-
- painter->restore();
+ QStyleOptionViewItem opt = option;
+ initStyleOption(&opt, index);
+ painter->save();
+ painter->setClipRect(opt.rect);
+
+ opt.features |= QStyleOptionViewItem::WrapText;
+ opt.text = index.data().toString();
+ opt.textElideMode = Qt::ElideRight;
+ opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
+
+ QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
+
+ // const int iconSize = style->pixelMetric(QStyle::PM_IconViewIconSize);
+ const int iconSize = 48;
+ QRect iconbox = opt.rect;
+ const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, opt.widget) + 1;
+ QRect textRect = opt.rect;
+ QRect textHighlightRect = textRect;
+ // clip the decoration on top, remove width padding
+ textRect.adjust(textMargin, iconSize + textMargin + 5, -textMargin, 0);
+
+ textHighlightRect.adjust(0, iconSize + 5, 0, 0);
+
+ // draw background
+ {
+ // FIXME: unused
+ // QSize textSize = viewItemTextSize ( &opt );
+ QPalette::ColorGroup cg;
+ QStyleOptionViewItem opt2(opt);
+
+ if ((opt.widget && opt.widget->isEnabled()) || (opt.state & QStyle::State_Enabled))
+ {
+ if (!(opt.state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+ else
+ cg = QPalette::Normal;
+ }
+ else
+ {
+ cg = QPalette::Disabled;
+ }
+ opt2.palette.setCurrentColorGroup(cg);
+
+ // fill in background, if any
+
+ if (opt.backgroundBrush.style() != Qt::NoBrush)
+ {
+ QPointF oldBO = painter->brushOrigin();
+ painter->setBrushOrigin(opt.rect.topLeft());
+ painter->fillRect(opt.rect, opt.backgroundBrush);
+ painter->setBrushOrigin(oldBO);
+ }
+
+ drawSelectionRect(painter, opt2, textHighlightRect);
+
+ /*
+ if (opt.showDecorationSelected)
+ {
+ drawSelectionRect(painter, opt2, opt.rect);
+ drawFocusRect(painter, opt2, opt.rect);
+ // painter->fillRect ( opt.rect, opt.palette.brush ( cg, QPalette::Highlight ) );
+ }
+ else
+ {
+
+ // if ( opt.state & QStyle::State_Selected )
+ {
+ // QRect textRect = subElementRect ( QStyle::SE_ItemViewItemText, opt,
+ // opt.widget );
+ // painter->fillRect ( textHighlightRect, opt.palette.brush ( cg,
+ // QPalette::Highlight ) );
+ drawSelectionRect(painter, opt2, textHighlightRect);
+ drawFocusRect(painter, opt2, textHighlightRect);
+ }
+ }
+ */
+ }
+
+ // icon mode and state, also used for badges
+ QIcon::Mode mode = QIcon::Normal;
+ if (!(opt.state & QStyle::State_Enabled))
+ mode = QIcon::Disabled;
+ else if (opt.state & QStyle::State_Selected)
+ mode = QIcon::Selected;
+ QIcon::State state = opt.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
+
+ // draw the icon
+ {
+ iconbox.setHeight(iconSize);
+ opt.icon.paint(painter, iconbox, Qt::AlignCenter, mode, state);
+ }
+ // set the text colors
+ QPalette::ColorGroup cg =
+ opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+ if (opt.state & QStyle::State_Selected)
+ {
+ painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
+ }
+ else
+ {
+ painter->setPen(opt.palette.color(cg, QPalette::Text));
+ }
+
+ // draw the text
+ QTextOption textOption;
+ textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+ textOption.setTextDirection(opt.direction);
+ textOption.setAlignment(QStyle::visualAlignment(opt.direction, opt.displayAlignment));
+ QTextLayout textLayout;
+ textLayout.setTextOption(textOption);
+ textLayout.setFont(opt.font);
+ textLayout.setText(opt.text);
+
+ qreal width, height;
+ viewItemTextLayout(textLayout, textRect.width(), height, width);
+
+ const int lineCount = textLayout.lineCount();
+
+ const QRect layoutRect = QStyle::alignedRect(
+ opt.direction, opt.displayAlignment, QSize(textRect.width(), int(height)), textRect);
+ const QPointF position = layoutRect.topLeft();
+ for (int i = 0; i < lineCount; ++i)
+ {
+ const QTextLine line = textLayout.lineAt(i);
+ line.draw(painter, position);
+ }
+
+ // FIXME: this really has no business of being here. Make generic.
+ auto instance = (BaseInstance*)index.data(InstanceList::InstancePointerRole)
+ .value<void *>();
+ if (instance)
+ {
+ drawBadges(painter, opt, instance, mode, state);
+ }
+
+ drawProgressOverlay(painter, opt, index.data(GroupViewRoles::ProgressValueRole).toInt(),
+ index.data(GroupViewRoles::ProgressMaximumRole).toInt());
+
+ painter->restore();
}
QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option,
- const QModelIndex &index) const
+ const QModelIndex &index) const
{
- QStyleOptionViewItem opt = option;
- initStyleOption(&opt, index);
- opt.features |= QStyleOptionViewItem::WrapText;
- opt.text = index.data().toString();
- opt.textElideMode = Qt::ElideRight;
- opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
-
- QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
- const int textMargin =
- style->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, opt.widget) + 1;
- int height = 48 + textMargin * 2 + 5; // TODO: turn constants into variables
- QSize szz = viewItemTextSize(&opt);
- height += szz.height();
- // FIXME: maybe the icon items could scale and keep proportions?
- QSize sz(100, height);
- return sz;
+ QStyleOptionViewItem opt = option;
+ initStyleOption(&opt, index);
+ opt.features |= QStyleOptionViewItem::WrapText;
+ opt.text = index.data().toString();
+ opt.textElideMode = Qt::ElideRight;
+ opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
+
+ QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
+ const int textMargin =
+ style->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, opt.widget) + 1;
+ int height = 48 + textMargin * 2 + 5; // TODO: turn constants into variables
+ QSize szz = viewItemTextSize(&opt);
+ height += szz.height();
+ // FIXME: maybe the icon items could scale and keep proportions?
+ QSize sz(100, height);
+ return sz;
}
diff --git a/application/groupview/InstanceDelegate.h b/application/groupview/InstanceDelegate.h
index c0148570..d0076e60 100644
--- a/application/groupview/InstanceDelegate.h
+++ b/application/groupview/InstanceDelegate.h
@@ -21,10 +21,10 @@
class ListViewDelegate : public QStyledItemDelegate
{
public:
- explicit ListViewDelegate(QObject *parent = 0);
+ explicit ListViewDelegate(QObject *parent = 0);
protected:
- void paint(QPainter *painter, const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
- QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
diff --git a/application/groupview/VisualGroup.cpp b/application/groupview/VisualGroup.cpp
index 940c7a8b..e08cb241 100644
--- a/application/groupview/VisualGroup.cpp
+++ b/application/groupview/VisualGroup.cpp
@@ -28,290 +28,290 @@ VisualGroup::VisualGroup(const QString &text, GroupView *view) : view(view), tex
}
VisualGroup::VisualGroup(const VisualGroup *other)
- : view(other->view), text(other->text), collapsed(other->collapsed)
+ : view(other->view), text(other->text), collapsed(other->collapsed)
{
}
void VisualGroup::update()
{
- auto temp_items = items();
- auto itemsPerRow = view->itemsPerRow();
-
- int numRows = qMax(1, qCeil((qreal)temp_items.size() / (qreal)itemsPerRow));
- rows = QVector<VisualRow>(numRows);
-
- int maxRowHeight = 0;
- int positionInRow = 0;
- int currentRow = 0;
- int offsetFromTop = 0;
- for (auto item: temp_items)
- {
- if(positionInRow == itemsPerRow)
- {
- rows[currentRow].height = maxRowHeight;
- rows[currentRow].top = offsetFromTop;
- currentRow ++;
- offsetFromTop += maxRowHeight + 5;
- positionInRow = 0;
- maxRowHeight = 0;
- }
- auto itemHeight = view->itemDelegate()->sizeHint(view->viewOptions(), item).height();
- if(itemHeight > maxRowHeight)
- {
- maxRowHeight = itemHeight;
- }
- rows[currentRow].items.append(item);
- positionInRow++;
- }
- rows[currentRow].height = maxRowHeight;
- rows[currentRow].top = offsetFromTop;
+ auto temp_items = items();
+ auto itemsPerRow = view->itemsPerRow();
+
+ int numRows = qMax(1, qCeil((qreal)temp_items.size() / (qreal)itemsPerRow));
+ rows = QVector<VisualRow>(numRows);
+
+ int maxRowHeight = 0;
+ int positionInRow = 0;
+ int currentRow = 0;
+ int offsetFromTop = 0;
+ for (auto item: temp_items)
+ {
+ if(positionInRow == itemsPerRow)
+ {
+ rows[currentRow].height = maxRowHeight;
+ rows[currentRow].top = offsetFromTop;
+ currentRow ++;
+ offsetFromTop += maxRowHeight + 5;
+ positionInRow = 0;
+ maxRowHeight = 0;
+ }
+ auto itemHeight = view->itemDelegate()->sizeHint(view->viewOptions(), item).height();
+ if(itemHeight > maxRowHeight)
+ {
+ maxRowHeight = itemHeight;
+ }
+ rows[currentRow].items.append(item);
+ positionInRow++;
+ }
+ rows[currentRow].height = maxRowHeight;
+ rows[currentRow].top = offsetFromTop;
}
QPair<int, int> VisualGroup::positionOf(const QModelIndex &index) const
{
- int y = 0;
- for (auto & row: rows)
- {
- for(auto x = 0; x < row.items.size(); x++)
- {
- if(row.items[x] == index)
- {
- return qMakePair(x,y);
- }
- }
- y++;
- }
- qWarning() << "Item" << index.row() << index.data(Qt::DisplayRole).toString() << "not found in visual group" << text;
- return qMakePair(0, 0);
+ int y = 0;
+ for (auto & row: rows)
+ {
+ for(auto x = 0; x < row.items.size(); x++)
+ {
+ if(row.items[x] == index)
+ {
+ return qMakePair(x,y);
+ }
+ }
+ y++;
+ }
+ qWarning() << "Item" << index.row() << index.data(Qt::DisplayRole).toString() << "not found in visual group" << text;
+ return qMakePair(0, 0);
}
int VisualGroup::rowTopOf(const QModelIndex &index) const
{
- auto position = positionOf(index);
- return rows[position.second].top;
+ auto position = positionOf(index);
+ return rows[position.second].top;
}
int VisualGroup::rowHeightOf(const QModelIndex &index) const
{
- auto position = positionOf(index);
- return rows[position.second].height;
+ auto position = positionOf(index);
+ return rows[position.second].height;
}
VisualGroup::HitResults VisualGroup::hitScan(const QPoint &pos) const
{
- VisualGroup::HitResults results = VisualGroup::NoHit;
- int y_start = verticalPosition();
- int body_start = y_start + headerHeight();
- int body_end = body_start + contentHeight() + 5; // FIXME: wtf is this 5?
- int y = pos.y();
- // int x = pos.x();
- if (y < y_start)
- {
- results = VisualGroup::NoHit;
- }
- else if (y < body_start)
- {
- results = VisualGroup::HeaderHit;
- int collapseSize = headerHeight() - 4;
-
- // the icon
- QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y_start, collapseSize, collapseSize);
- if (iconRect.contains(pos))
- {
- results |= VisualGroup::CheckboxHit;
- }
- }
- else if (y < body_end)
- {
- results |= VisualGroup::BodyHit;
- }
- return results;
+ VisualGroup::HitResults results = VisualGroup::NoHit;
+ int y_start = verticalPosition();
+ int body_start = y_start + headerHeight();
+ int body_end = body_start + contentHeight() + 5; // FIXME: wtf is this 5?
+ int y = pos.y();
+ // int x = pos.x();
+ if (y < y_start)
+ {
+ results = VisualGroup::NoHit;
+ }
+ else if (y < body_start)
+ {
+ results = VisualGroup::HeaderHit;
+ int collapseSize = headerHeight() - 4;
+
+ // the icon
+ QRect iconRect = QRect(view->m_leftMargin + 2, 2 + y_start, collapseSize, collapseSize);
+ if (iconRect.contains(pos))
+ {
+ results |= VisualGroup::CheckboxHit;
+ }
+ }
+ else if (y < body_end)
+ {
+ results |= VisualGroup::BodyHit;
+ }
+ return results;
}
void VisualGroup::drawHeader(QPainter *painter, const QStyleOptionViewItem &option)
{
- painter->setRenderHint(QPainter::Antialiasing);
-
- const QRect optRect = option.rect;
- QFont font(QApplication::font());
- font.setBold(true);
- const QFontMetrics fontMetrics = QFontMetrics(font);
-
- QColor outlineColor = option.palette.text().color();
- outlineColor.setAlphaF(0.35);
-
- //BEGIN: top left corner
- {
- painter->save();
- painter->setPen(outlineColor);
- const QPointF topLeft(optRect.topLeft());
- QRectF arc(topLeft, QSizeF(4, 4));
- arc.translate(0.5, 0.5);
- painter->drawArc(arc, 1440, 1440);
- painter->restore();
- }
- //END: top left corner
-
- //BEGIN: left vertical line
- {
- QPoint start(optRect.topLeft());
- start.ry() += 3;
- QPoint verticalGradBottom(optRect.topLeft());
- verticalGradBottom.ry() += fontMetrics.height() + 5;
- QLinearGradient gradient(start, verticalGradBottom);
- gradient.setColorAt(0, outlineColor);
- gradient.setColorAt(1, Qt::transparent);
- painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
- }
- //END: left vertical line
-
- //BEGIN: horizontal line
- {
- QPoint start(optRect.topLeft());
- start.rx() += 3;
- QPoint horizontalGradTop(optRect.topLeft());
- horizontalGradTop.rx() += optRect.width() - 6;
- painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor);
- }
- //END: horizontal line
-
- //BEGIN: top right corner
- {
- painter->save();
- painter->setPen(outlineColor);
- QPointF topRight(optRect.topRight());
- topRight.rx() -= 4;
- QRectF arc(topRight, QSizeF(4, 4));
- arc.translate(0.5, 0.5);
- painter->drawArc(arc, 0, 1440);
- painter->restore();
- }
- //END: top right corner
-
- //BEGIN: right vertical line
- {
- QPoint start(optRect.topRight());
- start.ry() += 3;
- QPoint verticalGradBottom(optRect.topRight());
- verticalGradBottom.ry() += fontMetrics.height() + 5;
- QLinearGradient gradient(start, verticalGradBottom);
- gradient.setColorAt(0, outlineColor);
- gradient.setColorAt(1, Qt::transparent);
- painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
- }
- //END: right vertical line
-
- //BEGIN: checkboxy thing
- {
- painter->save();
- painter->setRenderHint(QPainter::Antialiasing, false);
- painter->setFont(font);
- QColor penColor(option.palette.text().color());
- penColor.setAlphaF(0.6);
- painter->setPen(penColor);
- QRect iconSubRect(option.rect);
- iconSubRect.setTop(iconSubRect.top() + 7);
- iconSubRect.setLeft(iconSubRect.left() + 7);
-
- int sizing = fontMetrics.height();
- int even = ( (sizing - 1) % 2 );
-
- iconSubRect.setHeight(sizing - even);
- iconSubRect.setWidth(sizing - even);
- painter->drawRect(iconSubRect);
-
-
- /*
- if(collapsed)
- painter->drawText(iconSubRect, Qt::AlignHCenter | Qt::AlignVCenter, "+");
- else
- painter->drawText(iconSubRect, Qt::AlignHCenter | Qt::AlignVCenter, "-");
- */
- painter->setBrush(option.palette.text());
- painter->fillRect(iconSubRect.x(), iconSubRect.y() + iconSubRect.height() / 2,
- iconSubRect.width(), 2, penColor);
- if (collapsed)
- {
- painter->fillRect(iconSubRect.x() + iconSubRect.width() / 2, iconSubRect.y(), 2,
- iconSubRect.height(), penColor);
- }
-
- painter->restore();
- }
- //END: checkboxy thing
-
- //BEGIN: text
- {
- QRect textRect(option.rect);
- textRect.setTop(textRect.top() + 7);
- textRect.setLeft(textRect.left() + 7 + fontMetrics.height() + 7);
- textRect.setHeight(fontMetrics.height());
- textRect.setRight(textRect.right() - 7);
-
- painter->save();
- painter->setFont(font);
- QColor penColor(option.palette.text().color());
- penColor.setAlphaF(0.6);
- painter->setPen(penColor);
- painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text);
- painter->restore();
- }
- //END: text
+ painter->setRenderHint(QPainter::Antialiasing);
+
+ const QRect optRect = option.rect;
+ QFont font(QApplication::font());
+ font.setBold(true);
+ const QFontMetrics fontMetrics = QFontMetrics(font);
+
+ QColor outlineColor = option.palette.text().color();
+ outlineColor.setAlphaF(0.35);
+
+ //BEGIN: top left corner
+ {
+ painter->save();
+ painter->setPen(outlineColor);
+ const QPointF topLeft(optRect.topLeft());
+ QRectF arc(topLeft, QSizeF(4, 4));
+ arc.translate(0.5, 0.5);
+ painter->drawArc(arc, 1440, 1440);
+ painter->restore();
+ }
+ //END: top left corner
+
+ //BEGIN: left vertical line
+ {
+ QPoint start(optRect.topLeft());
+ start.ry() += 3;
+ QPoint verticalGradBottom(optRect.topLeft());
+ verticalGradBottom.ry() += fontMetrics.height() + 5;
+ QLinearGradient gradient(start, verticalGradBottom);
+ gradient.setColorAt(0, outlineColor);
+ gradient.setColorAt(1, Qt::transparent);
+ painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
+ }
+ //END: left vertical line
+
+ //BEGIN: horizontal line
+ {
+ QPoint start(optRect.topLeft());
+ start.rx() += 3;
+ QPoint horizontalGradTop(optRect.topLeft());
+ horizontalGradTop.rx() += optRect.width() - 6;
+ painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor);
+ }
+ //END: horizontal line
+
+ //BEGIN: top right corner
+ {
+ painter->save();
+ painter->setPen(outlineColor);
+ QPointF topRight(optRect.topRight());
+ topRight.rx() -= 4;
+ QRectF arc(topRight, QSizeF(4, 4));
+ arc.translate(0.5, 0.5);
+ painter->drawArc(arc, 0, 1440);
+ painter->restore();
+ }
+ //END: top right corner
+
+ //BEGIN: right vertical line
+ {
+ QPoint start(optRect.topRight());
+ start.ry() += 3;
+ QPoint verticalGradBottom(optRect.topRight());
+ verticalGradBottom.ry() += fontMetrics.height() + 5;
+ QLinearGradient gradient(start, verticalGradBottom);
+ gradient.setColorAt(0, outlineColor);
+ gradient.setColorAt(1, Qt::transparent);
+ painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient);
+ }
+ //END: right vertical line
+
+ //BEGIN: checkboxy thing
+ {
+ painter->save();
+ painter->setRenderHint(QPainter::Antialiasing, false);
+ painter->setFont(font);
+ QColor penColor(option.palette.text().color());
+ penColor.setAlphaF(0.6);
+ painter->setPen(penColor);
+ QRect iconSubRect(option.rect);
+ iconSubRect.setTop(iconSubRect.top() + 7);
+ iconSubRect.setLeft(iconSubRect.left() + 7);
+
+ int sizing = fontMetrics.height();
+ int even = ( (sizing - 1) % 2 );
+
+ iconSubRect.setHeight(sizing - even);
+ iconSubRect.setWidth(sizing - even);
+ painter->drawRect(iconSubRect);
+
+
+ /*
+ if(collapsed)
+ painter->drawText(iconSubRect, Qt::AlignHCenter | Qt::AlignVCenter, "+");
+ else
+ painter->drawText(iconSubRect, Qt::AlignHCenter | Qt::AlignVCenter, "-");
+ */
+ painter->setBrush(option.palette.text());
+ painter->fillRect(iconSubRect.x(), iconSubRect.y() + iconSubRect.height() / 2,
+ iconSubRect.width(), 2, penColor);
+ if (collapsed)
+ {
+ painter->fillRect(iconSubRect.x() + iconSubRect.width() / 2, iconSubRect.y(), 2,
+ iconSubRect.height(), penColor);
+ }
+
+ painter->restore();
+ }
+ //END: checkboxy thing
+
+ //BEGIN: text
+ {
+ QRect textRect(option.rect);
+ textRect.setTop(textRect.top() + 7);
+ textRect.setLeft(textRect.left() + 7 + fontMetrics.height() + 7);
+ textRect.setHeight(fontMetrics.height());
+ textRect.setRight(textRect.right() - 7);
+
+ painter->save();
+ painter->setFont(font);
+ QColor penColor(option.palette.text().color());
+ penColor.setAlphaF(0.6);
+ painter->setPen(penColor);
+ painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text);
+ painter->restore();
+ }
+ //END: text
}
int VisualGroup::totalHeight() const
{
- return headerHeight() + 5 + contentHeight(); // FIXME: wtf is that '5'?
+ return headerHeight() + 5 + contentHeight(); // FIXME: wtf is that '5'?
}
int VisualGroup::headerHeight() const
{
- QFont font(QApplication::font());
+ QFont font(QApplication::font());
font.setBold(true);
QFontMetrics fontMetrics(font);
const int height = fontMetrics.height() + 1 /* 1 pixel-width gradient */
+ 11 /* top and bottom separation */;
return height;
- /*
- int raw = view->viewport()->fontMetrics().height() + 4;
- // add english. maybe. depends on font height.
- if (raw % 2 == 0)
- raw++;
- return std::min(raw, 25);
- */
+ /*
+ int raw = view->viewport()->fontMetrics().height() + 4;
+ // add english. maybe. depends on font height.
+ if (raw % 2 == 0)
+ raw++;
+ return std::min(raw, 25);
+ */
}
int VisualGroup::contentHeight() const
{
- if (collapsed)
- {
- return 0;
- }
- auto last = rows[numRows() - 1];
- return last.top + last.height;
+ if (collapsed)
+ {
+ return 0;
+ }
+ auto last = rows[numRows() - 1];
+ return last.top + last.height;
}
int VisualGroup::numRows() const
{
- return rows.size();
+ return rows.size();
}
int VisualGroup::verticalPosition() const
{
- return m_verticalPosition;
+ return m_verticalPosition;
}
QList<QModelIndex> VisualGroup::items() const
{
- QList<QModelIndex> indices;
- for (int i = 0; i < view->model()->rowCount(); ++i)
- {
- const QModelIndex index = view->model()->index(i, 0);
- if (index.data(GroupViewRoles::GroupRole).toString() == text)
- {
- indices.append(index);
- }
- }
- return indices;
+ QList<QModelIndex> indices;
+ for (int i = 0; i < view->model()->rowCount(); ++i)
+ {
+ const QModelIndex index = view->model()->index(i, 0);
+ if (index.data(GroupViewRoles::GroupRole).toString() == text)
+ {
+ indices.append(index);
+ }
+ }
+ return indices;
}
diff --git a/application/groupview/VisualGroup.h b/application/groupview/VisualGroup.h
index 2caac49f..0ffcf236 100644
--- a/application/groupview/VisualGroup.h
+++ b/application/groupview/VisualGroup.h
@@ -26,81 +26,81 @@ class QModelIndex;
struct VisualRow
{
- QList<QModelIndex> items;
- int height = 0;
- int top = 0;
- inline int size() const
- {
- return items.size();
- }
- inline QModelIndex &operator[](int i)
- {
- return items[i];
- }
+ QList<QModelIndex> items;
+ int height = 0;
+ int top = 0;
+ inline int size() const
+ {
+ return items.size();
+ }
+ inline QModelIndex &operator[](int i)
+ {
+ return items[i];
+ }
};
struct VisualGroup
{
/* constructors */
- VisualGroup(const QString &text, GroupView *view);
- VisualGroup(const VisualGroup *other);
+ VisualGroup(const QString &text, GroupView *view);
+ VisualGroup(const VisualGroup *other);
/* data */
- GroupView *view = nullptr;
- QString text;
- bool collapsed = false;
- QVector<VisualRow> rows;
- int firstItemIndex = 0;
- int m_verticalPosition = 0;
+ GroupView *view = nullptr;
+ QString text;
+ bool collapsed = false;
+ QVector<VisualRow> rows;
+ int firstItemIndex = 0;
+ int m_verticalPosition = 0;
/* logic */
- /// update the internal list of items and flow them into the rows.
- void update();
+ /// update the internal list of items and flow them into the rows.
+ void update();
- /// draw the header at y-position.
- void drawHeader(QPainter *painter, const QStyleOptionViewItem &option);
+ /// draw the header at y-position.
+ void drawHeader(QPainter *painter, const QStyleOptionViewItem &option);
- /// height of the group, in total. includes a small bit of padding.
- int totalHeight() const;
+ /// height of the group, in total. includes a small bit of padding.
+ int totalHeight() const;
- /// height of the group header, in pixels
- int headerHeight() const;
+ /// height of the group header, in pixels
+ int headerHeight() const;
- /// height of the group content, in pixels
- int contentHeight() const;
+ /// height of the group content, in pixels
+ int contentHeight() const;
- /// the number of visual rows this group has
- int numRows() const;
+ /// the number of visual rows this group has
+ int numRows() const;
- /// actually calculate the above value
- int calculateNumRows() const;
+ /// actually calculate the above value
+ int calculateNumRows() const;
- /// the height at which this group starts, in pixels
- int verticalPosition() const;
+ /// the height at which this group starts, in pixels
+ int verticalPosition() const;
- /// relative geometry - top of the row of the given item
- int rowTopOf(const QModelIndex &index) const;
+ /// relative geometry - top of the row of the given item
+ int rowTopOf(const QModelIndex &index) const;
- /// height of the row of the given item
- int rowHeightOf(const QModelIndex &index) const;
+ /// height of the row of the given item
+ int rowHeightOf(const QModelIndex &index) const;
- /// x/y position of the given item inside the group (in items!)
- QPair<int, int> positionOf(const QModelIndex &index) const;
+ /// x/y position of the given item inside the group (in items!)
+ QPair<int, int> positionOf(const QModelIndex &index) const;
- enum HitResult
- {
- NoHit = 0x0,
- TextHit = 0x1,
- CheckboxHit = 0x2,
- HeaderHit = 0x4,
- BodyHit = 0x8
- };
- Q_DECLARE_FLAGS(HitResults, HitResult)
+ enum HitResult
+ {
+ NoHit = 0x0,
+ TextHit = 0x1,
+ CheckboxHit = 0x2,
+ HeaderHit = 0x4,
+ BodyHit = 0x8
+ };
+ Q_DECLARE_FLAGS(HitResults, HitResult)
- /// shoot! BANG! what did we hit?
- HitResults hitScan (const QPoint &pos) const;
+ /// shoot! BANG! what did we hit?
+ HitResults hitScan (const QPoint &pos) const;
- QList<QModelIndex> items() const;
+ QList<QModelIndex> items() const;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(VisualGroup::HitResults)
diff --git a/application/install_prereqs.cmake.in b/application/install_prereqs.cmake.in
index 2906a4ec..e4408d16 100644
--- a/application/install_prereqs.cmake.in
+++ b/application/install_prereqs.cmake.in
@@ -1,20 +1,20 @@
set(CMAKE_MODULE_PATH "@CMAKE_MODULE_PATH@")
-file(GLOB_RECURSE QTPLUGINS "${CMAKE_INSTALL_PREFIX}/@PLUGIN_DEST_DIR@/*@CMAKE_SHARED_LIBRARY_SUFFIX@")
+file(GLOB_RECURSE QTPLUGINS "${CMAKE_INSTALL_PREFIX}/@PLUGIN_DEST_DIR@/*@CMAKE_SHARED_LIBRARY_SUFFIX@")
function(gp_resolved_file_type_override resolved_file type_var)
- if(resolved_file MATCHES "^/(usr/)?lib/libQt")
- set(${type_var} other PARENT_SCOPE)
- elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libxcb-")
- set(${type_var} other PARENT_SCOPE)
- elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libicu")
- set(${type_var} other PARENT_SCOPE)
- elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libpng")
- set(${type_var} other PARENT_SCOPE)
- elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libproxy")
- set(${type_var} other PARENT_SCOPE)
- elseif((resolved_file MATCHES "^/(usr/)?lib(.+)?/libstdc\\+\\+") AND (UNIX AND NOT APPLE))
- set(${type_var} other PARENT_SCOPE)
- endif()
+ if(resolved_file MATCHES "^/(usr/)?lib/libQt")
+ set(${type_var} other PARENT_SCOPE)
+ elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libxcb-")
+ set(${type_var} other PARENT_SCOPE)
+ elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libicu")
+ set(${type_var} other PARENT_SCOPE)
+ elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libpng")
+ set(${type_var} other PARENT_SCOPE)
+ elseif(resolved_file MATCHES "^/(usr/)?lib(.+)?/libproxy")
+ set(${type_var} other PARENT_SCOPE)
+ elseif((resolved_file MATCHES "^/(usr/)?lib(.+)?/libstdc\\+\\+") AND (UNIX AND NOT APPLE))
+ set(${type_var} other PARENT_SCOPE)
+ endif()
endfunction()
set(gp_tool "@CMAKE_GP_TOOL@")
diff --git a/application/main.cpp b/application/main.cpp
index 2f90f2b3..f724845e 100644
--- a/application/main.cpp
+++ b/application/main.cpp
@@ -16,46 +16,46 @@
int main(int argc, char *argv[])
{
#ifdef BREAK_INFINITE_LOOP
- while(true)
- {
- std::this_thread::sleep_for(std::chrono::milliseconds(250));
- }
+ while(true)
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ }
#endif
#ifdef BREAK_EXCEPTION
- throw 42;
+ throw 42;
#endif
#ifdef BREAK_RETURN
- return 42;
+ return 42;
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
- QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
- // initialize Qt
- MultiMC app(argc, argv);
+ // initialize Qt
+ MultiMC app(argc, argv);
- switch (app.status())
- {
- case MultiMC::StartingUp:
- case MultiMC::Initialized:
- {
- Q_INIT_RESOURCE(multimc);
- Q_INIT_RESOURCE(backgrounds);
- Q_INIT_RESOURCE(assets);
+ switch (app.status())
+ {
+ case MultiMC::StartingUp:
+ case MultiMC::Initialized:
+ {
+ Q_INIT_RESOURCE(multimc);
+ Q_INIT_RESOURCE(backgrounds);
+ Q_INIT_RESOURCE(assets);
- Q_INIT_RESOURCE(pe_dark);
- Q_INIT_RESOURCE(pe_light);
- Q_INIT_RESOURCE(pe_blue);
- Q_INIT_RESOURCE(pe_colored);
- Q_INIT_RESOURCE(OSX);
- Q_INIT_RESOURCE(iOS);
- Q_INIT_RESOURCE(flat);
- return app.exec();
- }
- case MultiMC::Failed:
- return 1;
- case MultiMC::Succeeded:
- return 0;
- }
+ Q_INIT_RESOURCE(pe_dark);
+ Q_INIT_RESOURCE(pe_light);
+ Q_INIT_RESOURCE(pe_blue);
+ Q_INIT_RESOURCE(pe_colored);
+ Q_INIT_RESOURCE(OSX);
+ Q_INIT_RESOURCE(iOS);
+ Q_INIT_RESOURCE(flat);
+ return app.exec();
+ }
+ case MultiMC::Failed:
+ return 1;
+ case MultiMC::Succeeded:
+ return 0;
+ }
}
diff --git a/application/package/linux/MultiMC b/application/package/linux/MultiMC
index 2d4be9f0..da6373bc 100755
--- a/application/package/linux/MultiMC
+++ b/application/package/linux/MultiMC
@@ -2,10 +2,10 @@
# Basic start script for running MultiMC with the libs packaged with it.
function printerror {
- printf "$1"
- if which zenity >/dev/null; then zenity --error --text="$1" &>/dev/null;
- elif which kdialog >/dev/null; then kdialog --error "$1" &>/dev/null;
- fi
+ printf "$1"
+ if which zenity >/dev/null; then zenity --error --text="$1" &>/dev/null;
+ elif which kdialog >/dev/null; then kdialog --error "$1" &>/dev/null;
+ fi
}
if [[ $EUID -eq 0 ]]; then
@@ -28,66 +28,66 @@ export QT_FONTPATH="${MMC_DIR}/fonts"
# Detect missing dependencies...
DEPS_LIST=`ldd "${MMC_DIR}"/plugins/*/*.so 2>/dev/null | grep "not found" | sort -u | awk -vORS=", " '{ print $1 }'`
if [ "x$DEPS_LIST" = "x" ]; then
- # We have all our dependencies. Run MultiMC.
- echo "No missing dependencies found."
+ # We have all our dependencies. Run MultiMC.
+ echo "No missing dependencies found."
- # Just to be sure...
- chmod +x "${MMC_DIR}/bin/MultiMC"
+ # Just to be sure...
+ chmod +x "${MMC_DIR}/bin/MultiMC"
- # Run MultiMC
- "${MMC_DIR}/bin/MultiMC" -d "${MMC_DIR}" "$@"
+ # Run MultiMC
+ "${MMC_DIR}/bin/MultiMC" -d "${MMC_DIR}" "$@"
- # Run MultiMC in valgrind
- # valgrind --log-file="valgrind.log" --leak-check=full --track-origins=yes "${MMC_DIR}/bin/MultiMC" -d "${MMC_DIR}" "$@"
+ # Run MultiMC in valgrind
+ # valgrind --log-file="valgrind.log" --leak-check=full --track-origins=yes "${MMC_DIR}/bin/MultiMC" -d "${MMC_DIR}" "$@"
- # Run MultiMC with callgrind, delay instrumentation
- # valgrind --log-file="valgrind.log" --tool=callgrind --instr-atstart=no "${MMC_DIR}/bin/MultiMC" -d "${MMC_DIR}" "$@"
- # use callgrind_control -i on/off to profile actions
+ # Run MultiMC with callgrind, delay instrumentation
+ # valgrind --log-file="valgrind.log" --tool=callgrind --instr-atstart=no "${MMC_DIR}/bin/MultiMC" -d "${MMC_DIR}" "$@"
+ # use callgrind_control -i on/off to profile actions
- # Exit with MultiMC's exit code.
- exit $?
+ # Exit with MultiMC's exit code.
+ exit $?
else
- # apt
- if which apt-file &>/dev/null; then
- LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
- COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do apt-file -l search $LIBRARY; done`
- COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
- INSTALL_CMD="sudo apt-get install $COMMAND_LIBS"
- # pacman
- elif which pkgfile &>/dev/null; then
- LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
- COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do pkgfile $LIBRARY; done`
- COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
- INSTALL_CMD="sudo pacman -S $COMMAND_LIBS"
- # dnf
- elif which dnf &>/dev/null; then
- LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
- COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do dnf whatprovides -q $LIBRARY; done`
- COMMAND_LIBS=`echo "$COMMAND_LIBS" | grep -v 'Repo' | sort -u | awk -vORS=" " '{ print $1 }'`
- INSTALL_CMD="sudo dnf install $COMMAND_LIBS"
- # yum
- elif which yum &>/dev/null; then
- LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
- COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do yum whatprovides $LIBRARY; done`
- COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
- INSTALL_CMD="sudo yum install $COMMAND_LIBS"
- # zypper
- elif which zypper &>/dev/null; then
- LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
- COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do zypper wp $LIBRARY; done`
- COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
- INSTALL_CMD="sudo zypper install $COMMAND_LIBS"
- # emerge
- elif which pfl &>/dev/null; then
- LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
- COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do pfl $LIBRARY; done`
- COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
- INSTALL_CMD="sudo emerge $COMMAND_LIBS"
- fi
+ # apt
+ if which apt-file &>/dev/null; then
+ LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
+ COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do apt-file -l search $LIBRARY; done`
+ COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
+ INSTALL_CMD="sudo apt-get install $COMMAND_LIBS"
+ # pacman
+ elif which pkgfile &>/dev/null; then
+ LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
+ COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do pkgfile $LIBRARY; done`
+ COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
+ INSTALL_CMD="sudo pacman -S $COMMAND_LIBS"
+ # dnf
+ elif which dnf &>/dev/null; then
+ LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
+ COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do dnf whatprovides -q $LIBRARY; done`
+ COMMAND_LIBS=`echo "$COMMAND_LIBS" | grep -v 'Repo' | sort -u | awk -vORS=" " '{ print $1 }'`
+ INSTALL_CMD="sudo dnf install $COMMAND_LIBS"
+ # yum
+ elif which yum &>/dev/null; then
+ LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
+ COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do yum whatprovides $LIBRARY; done`
+ COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
+ INSTALL_CMD="sudo yum install $COMMAND_LIBS"
+ # zypper
+ elif which zypper &>/dev/null; then
+ LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
+ COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do zypper wp $LIBRARY; done`
+ COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
+ INSTALL_CMD="sudo zypper install $COMMAND_LIBS"
+ # emerge
+ elif which pfl &>/dev/null; then
+ LIBRARIES=`echo "$DEPS_LIST" | grep -oP "[^, ]*" | sort -u`
+ COMMAND_LIBS=`for LIBRARY in $LIBRARIES; do pfl $LIBRARY; done`
+ COMMAND_LIBS=`echo "$COMMAND_LIBS" | sort -u | awk -vORS=" " '{ print $1 }'`
+ INSTALL_CMD="sudo emerge $COMMAND_LIBS"
+ fi
- MESSAGE="Error: MultiMC is missing the following libraries that it needs to work correctly:\n\t${DEPS_LIST}\nPlease install them from your distribution's package manager."
- MESSAGE="$MESSAGE\n\nHint (please apply common sense): $INSTALL_CMD\n"
+ MESSAGE="Error: MultiMC is missing the following libraries that it needs to work correctly:\n\t${DEPS_LIST}\nPlease install them from your distribution's package manager."
+ MESSAGE="$MESSAGE\n\nHint (please apply common sense): $INSTALL_CMD\n"
- printerror "$MESSAGE"
- exit 1
+ printerror "$MESSAGE"
+ exit 1
fi
diff --git a/application/pagedialog/PageDialog.cpp b/application/pagedialog/PageDialog.cpp
index 1b5284d2..c9ee93d8 100644
--- a/application/pagedialog/PageDialog.cpp
+++ b/application/pagedialog/PageDialog.cpp
@@ -26,35 +26,35 @@
#include "widgets/PageContainer.h"
PageDialog::PageDialog(BasePageProvider *pageProvider, QString defaultId, QWidget *parent)
- : QDialog(parent)
+ : QDialog(parent)
{
- setWindowTitle(pageProvider->dialogTitle());
- m_container = new PageContainer(pageProvider, defaultId, this);
+ setWindowTitle(pageProvider->dialogTitle());
+ m_container = new PageContainer(pageProvider, defaultId, this);
- QVBoxLayout *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(m_container);
- mainLayout->setSpacing(0);
- mainLayout->setContentsMargins(0, 0, 0, 0);
- setLayout(mainLayout);
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(m_container);
+ mainLayout->setSpacing(0);
+ mainLayout->setContentsMargins(0, 0, 0, 0);
+ setLayout(mainLayout);
- QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close);
- buttons->button(QDialogButtonBox::Close)->setDefault(true);
- m_container->addButtons(buttons);
+ QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close);
+ buttons->button(QDialogButtonBox::Close)->setDefault(true);
+ m_container->addButtons(buttons);
- connect(buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(close()));
- connect(buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), m_container, SLOT(help()));
+ connect(buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(close()));
+ connect(buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), m_container, SLOT(help()));
- restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("PagedGeometry").toByteArray()));
+ restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("PagedGeometry").toByteArray()));
}
void PageDialog::closeEvent(QCloseEvent *event)
{
- qDebug() << "Paged dialog close requested";
- if (m_container->prepareToClose())
- {
- qDebug() << "Paged dialog close approved";
- MMC->settings()->set("PagedGeometry", saveGeometry().toBase64());
- qDebug() << "Paged dialog geometry saved";
- QDialog::closeEvent(event);
- }
+ qDebug() << "Paged dialog close requested";
+ if (m_container->prepareToClose())
+ {
+ qDebug() << "Paged dialog close approved";
+ MMC->settings()->set("PagedGeometry", saveGeometry().toBase64());
+ qDebug() << "Paged dialog geometry saved";
+ QDialog::closeEvent(event);
+ }
}
diff --git a/application/pagedialog/PageDialog.h b/application/pagedialog/PageDialog.h
index a287f9c9..4b7ea708 100644
--- a/application/pagedialog/PageDialog.h
+++ b/application/pagedialog/PageDialog.h
@@ -21,15 +21,15 @@
class PageContainer;
class PageDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit PageDialog(BasePageProvider *pageProvider, QString defaultId = QString(), QWidget *parent = 0);
- virtual ~PageDialog() {}
+ explicit PageDialog(BasePageProvider *pageProvider, QString defaultId = QString(), QWidget *parent = 0);
+ virtual ~PageDialog() {}
private
slots:
- virtual void closeEvent(QCloseEvent *event);
+ virtual void closeEvent(QCloseEvent *event);
private:
- PageContainer * m_container;
+ PageContainer * m_container;
};
diff --git a/application/pages/BasePage.h b/application/pages/BasePage.h
index d4547770..e1169c08 100644
--- a/application/pages/BasePage.h
+++ b/application/pages/BasePage.h
@@ -24,35 +24,35 @@
class BasePage
{
public:
- virtual ~BasePage() {}
- virtual QString id() const = 0;
- virtual QString displayName() const = 0;
- virtual QIcon icon() const = 0;
- virtual bool apply() { return true; }
- virtual bool shouldDisplay() const { return true; }
- virtual QString helpPage() const { return QString(); }
- void opened()
- {
- isOpened = true;
- openedImpl();
- }
- void closed()
- {
- isOpened = false;
- closedImpl();
- }
- virtual void openedImpl() {}
- virtual void closedImpl() {}
- virtual void setParentContainer(BasePageContainer * container)
- {
- m_container = container;
- };
+ virtual ~BasePage() {}
+ virtual QString id() const = 0;
+ virtual QString displayName() const = 0;
+ virtual QIcon icon() const = 0;
+ virtual bool apply() { return true; }
+ virtual bool shouldDisplay() const { return true; }
+ virtual QString helpPage() const { return QString(); }
+ void opened()
+ {
+ isOpened = true;
+ openedImpl();
+ }
+ void closed()
+ {
+ isOpened = false;
+ closedImpl();
+ }
+ virtual void openedImpl() {}
+ virtual void closedImpl() {}
+ virtual void setParentContainer(BasePageContainer * container)
+ {
+ m_container = container;
+ };
public:
- int stackIndex = -1;
- int listIndex = -1;
+ int stackIndex = -1;
+ int listIndex = -1;
protected:
- BasePageContainer * m_container = nullptr;
- bool isOpened = false;
+ BasePageContainer * m_container = nullptr;
+ bool isOpened = false;
};
typedef std::shared_ptr<BasePage> BasePagePtr;
diff --git a/application/pages/BasePageContainer.h b/application/pages/BasePageContainer.h
index ff7315c2..f8c7adeb 100644
--- a/application/pages/BasePageContainer.h
+++ b/application/pages/BasePageContainer.h
@@ -3,8 +3,8 @@
class BasePageContainer
{
public:
- virtual ~BasePageContainer(){};
- virtual bool selectPage(QString pageId) = 0;
- virtual void refreshContainer() = 0;
- virtual bool requestClose() = 0;
+ virtual ~BasePageContainer(){};
+ virtual bool selectPage(QString pageId) = 0;
+ virtual void refreshContainer() = 0;
+ virtual bool requestClose() = 0;
};
diff --git a/application/pages/BasePageProvider.h b/application/pages/BasePageProvider.h
index 05c38d23..e403800c 100644
--- a/application/pages/BasePageProvider.h
+++ b/application/pages/BasePageProvider.h
@@ -22,47 +22,47 @@
class BasePageProvider
{
public:
- virtual QList<BasePage *> getPages() = 0;
- virtual QString dialogTitle() = 0;
+ virtual QList<BasePage *> getPages() = 0;
+ virtual QString dialogTitle() = 0;
};
class GenericPageProvider : public BasePageProvider
{
- typedef std::function<BasePage *()> PageCreator;
+ typedef std::function<BasePage *()> PageCreator;
public:
- explicit GenericPageProvider(const QString &dialogTitle)
- : m_dialogTitle(dialogTitle)
- {
- }
- virtual ~GenericPageProvider() {}
+ explicit GenericPageProvider(const QString &dialogTitle)
+ : m_dialogTitle(dialogTitle)
+ {
+ }
+ virtual ~GenericPageProvider() {}
- QList<BasePage *> getPages() override
- {
- QList<BasePage *> pages;
- for (PageCreator creator : m_creators)
- {
- pages.append(creator());
- }
- return pages;
- }
- QString dialogTitle() override { return m_dialogTitle; }
+ QList<BasePage *> getPages() override
+ {
+ QList<BasePage *> pages;
+ for (PageCreator creator : m_creators)
+ {
+ pages.append(creator());
+ }
+ return pages;
+ }
+ QString dialogTitle() override { return m_dialogTitle; }
- void setDialogTitle(const QString &title)
- {
- m_dialogTitle = title;
- }
- void addPageCreator(PageCreator page)
- {
- m_creators.append(page);
- }
+ void setDialogTitle(const QString &title)
+ {
+ m_dialogTitle = title;
+ }
+ void addPageCreator(PageCreator page)
+ {
+ m_creators.append(page);
+ }
- template<typename PageClass>
- void addPage()
- {
- addPageCreator([](){return new PageClass();});
- }
+ template<typename PageClass>
+ void addPage()
+ {
+ addPageCreator([](){return new PageClass();});
+ }
private:
- QList<PageCreator> m_creators;
- QString m_dialogTitle;
+ QList<PageCreator> m_creators;
+ QString m_dialogTitle;
};
diff --git a/application/pages/global/AccountListPage.cpp b/application/pages/global/AccountListPage.cpp
index 63943174..b89c410f 100644
--- a/application/pages/global/AccountListPage.cpp
+++ b/application/pages/global/AccountListPage.cpp
@@ -34,120 +34,120 @@
#include "MultiMC.h"
AccountListPage::AccountListPage(QWidget *parent)
- : QWidget(parent), ui(new Ui::AccountListPage)
+ : QWidget(parent), ui(new Ui::AccountListPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
- m_accounts = MMC->accounts();
+ m_accounts = MMC->accounts();
- ui->listView->setModel(m_accounts.get());
- ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ ui->listView->setModel(m_accounts.get());
+ ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
- // Expand the account column
- ui->listView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
+ // Expand the account column
+ ui->listView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
- QItemSelectionModel *selectionModel = ui->listView->selectionModel();
+ QItemSelectionModel *selectionModel = ui->listView->selectionModel();
- connect(selectionModel, &QItemSelectionModel::selectionChanged,
- [this](const QItemSelection &sel, const QItemSelection &dsel)
- { updateButtonStates(); });
+ connect(selectionModel, &QItemSelectionModel::selectionChanged,
+ [this](const QItemSelection &sel, const QItemSelection &dsel)
+ { updateButtonStates(); });
- connect(m_accounts.get(), SIGNAL(listChanged()), SLOT(listChanged()));
- connect(m_accounts.get(), SIGNAL(activeAccountChanged()), SLOT(listChanged()));
+ connect(m_accounts.get(), SIGNAL(listChanged()), SLOT(listChanged()));
+ connect(m_accounts.get(), SIGNAL(activeAccountChanged()), SLOT(listChanged()));
- updateButtonStates();
+ updateButtonStates();
}
AccountListPage::~AccountListPage()
{
- delete ui;
+ delete ui;
}
void AccountListPage::listChanged()
{
- updateButtonStates();
+ updateButtonStates();
}
void AccountListPage::on_addAccountBtn_clicked()
{
- addAccount(tr("Please enter your Mojang or Minecraft account username and password to add "
- "your account."));
+ addAccount(tr("Please enter your Mojang or Minecraft account username and password to add "
+ "your account."));
}
void AccountListPage::on_rmAccountBtn_clicked()
{
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.size() > 0)
- {
- QModelIndex selected = selection.first();
- m_accounts->removeAccount(selected);
- }
+ QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
+ if (selection.size() > 0)
+ {
+ QModelIndex selected = selection.first();
+ m_accounts->removeAccount(selected);
+ }
}
void AccountListPage::on_setDefaultBtn_clicked()
{
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.size() > 0)
- {
- QModelIndex selected = selection.first();
- MojangAccountPtr account =
- selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
- m_accounts->setActiveAccount(account->username());
- }
+ QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
+ if (selection.size() > 0)
+ {
+ QModelIndex selected = selection.first();
+ MojangAccountPtr account =
+ selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
+ m_accounts->setActiveAccount(account->username());
+ }
}
void AccountListPage::on_noDefaultBtn_clicked()
{
- m_accounts->setActiveAccount("");
+ m_accounts->setActiveAccount("");
}
void AccountListPage::updateButtonStates()
{
- // If there is no selection, disable buttons that require something selected.
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
+ // If there is no selection, disable buttons that require something selected.
+ QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
- ui->rmAccountBtn->setEnabled(selection.size() > 0);
- ui->setDefaultBtn->setEnabled(selection.size() > 0);
- ui->uploadSkinBtn->setEnabled(selection.size() > 0);
+ ui->rmAccountBtn->setEnabled(selection.size() > 0);
+ ui->setDefaultBtn->setEnabled(selection.size() > 0);
+ ui->uploadSkinBtn->setEnabled(selection.size() > 0);
- ui->noDefaultBtn->setDown(m_accounts->activeAccount().get() == nullptr);
+ ui->noDefaultBtn->setDown(m_accounts->activeAccount().get() == nullptr);
}
void AccountListPage::addAccount(const QString &errMsg)
{
- // TODO: The login dialog isn't quite done yet
- MojangAccountPtr account = LoginDialog::newAccount(this, errMsg);
-
- if (account != nullptr)
- {
- m_accounts->addAccount(account);
- if (m_accounts->count() == 1)
- m_accounts->setActiveAccount(account->username());
-
- // Grab associated player skins
- auto job = new NetJob("Player skins: " + account->username());
-
- for (AccountProfile profile : account->profiles())
- {
- auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.id + ".png");
- auto action = Net::Download::makeCached(QUrl("https://" + URLConstants::SKINS_BASE + profile.id + ".png"), meta);
- job->addNetAction(action);
- meta->setStale(true);
- }
-
- job->start();
- }
+ // TODO: The login dialog isn't quite done yet
+ MojangAccountPtr account = LoginDialog::newAccount(this, errMsg);
+
+ if (account != nullptr)
+ {
+ m_accounts->addAccount(account);
+ if (m_accounts->count() == 1)
+ m_accounts->setActiveAccount(account->username());
+
+ // Grab associated player skins
+ auto job = new NetJob("Player skins: " + account->username());
+
+ for (AccountProfile profile : account->profiles())
+ {
+ auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.id + ".png");
+ auto action = Net::Download::makeCached(QUrl("https://" + URLConstants::SKINS_BASE + profile.id + ".png"), meta);
+ job->addNetAction(action);
+ meta->setStale(true);
+ }
+
+ job->start();
+ }
}
void AccountListPage::on_uploadSkinBtn_clicked()
{
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.size() > 0)
- {
- QModelIndex selected = selection.first();
- MojangAccountPtr account = selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
- SkinUploadDialog dialog(account, this);
- dialog.exec();
- }
+ QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
+ if (selection.size() > 0)
+ {
+ QModelIndex selected = selection.first();
+ MojangAccountPtr account = selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
+ SkinUploadDialog dialog(account, this);
+ dialog.exec();
+ }
}
diff --git a/application/pages/global/AccountListPage.h b/application/pages/global/AccountListPage.h
index fa5561fe..ad93c904 100644
--- a/application/pages/global/AccountListPage.h
+++ b/application/pages/global/AccountListPage.h
@@ -32,57 +32,57 @@ class AuthenticateTask;
class AccountListPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit AccountListPage(QWidget *parent = 0);
- ~AccountListPage();
-
- QString displayName() const override
- {
- return tr("Accounts");
- }
- QIcon icon() const override
- {
- auto icon = MMC->getThemedIcon("accounts");
- if(icon.isNull())
- {
- icon = MMC->getThemedIcon("noaccount");
- }
- return icon;
- }
- QString id() const override
- {
- return "accounts";
- }
- QString helpPage() const override
- {
- return "Getting-Started#adding-an-account";
- }
+ explicit AccountListPage(QWidget *parent = 0);
+ ~AccountListPage();
+
+ QString displayName() const override
+ {
+ return tr("Accounts");
+ }
+ QIcon icon() const override
+ {
+ auto icon = MMC->getThemedIcon("accounts");
+ if(icon.isNull())
+ {
+ icon = MMC->getThemedIcon("noaccount");
+ }
+ return icon;
+ }
+ QString id() const override
+ {
+ return "accounts";
+ }
+ QString helpPage() const override
+ {
+ return "Getting-Started#adding-an-account";
+ }
public
slots:
- void on_addAccountBtn_clicked();
+ void on_addAccountBtn_clicked();
- void on_rmAccountBtn_clicked();
+ void on_rmAccountBtn_clicked();
- void on_setDefaultBtn_clicked();
+ void on_setDefaultBtn_clicked();
- void on_noDefaultBtn_clicked();
+ void on_noDefaultBtn_clicked();
- void on_uploadSkinBtn_clicked();
+ void on_uploadSkinBtn_clicked();
- void listChanged();
+ void listChanged();
- //! Updates the states of the dialog's buttons.
- void updateButtonStates();
+ //! Updates the states of the dialog's buttons.
+ void updateButtonStates();
protected:
- std::shared_ptr<MojangAccountList> m_accounts;
+ std::shared_ptr<MojangAccountList> m_accounts;
protected
slots:
- void addAccount(const QString& errMsg="");
+ void addAccount(const QString& errMsg="");
private:
- Ui::AccountListPage *ui;
+ Ui::AccountListPage *ui;
};
diff --git a/application/pages/global/CustomCommandsPage.cpp b/application/pages/global/CustomCommandsPage.cpp
index 1352b6be..f2c3b185 100644
--- a/application/pages/global/CustomCommandsPage.cpp
+++ b/application/pages/global/CustomCommandsPage.cpp
@@ -6,17 +6,17 @@
CustomCommandsPage::CustomCommandsPage(QWidget* parent): QWidget(parent)
{
- auto verticalLayout = new QVBoxLayout(this);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
- verticalLayout->setContentsMargins(0, 0, 0, 0);
+ auto verticalLayout = new QVBoxLayout(this);
+ verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setContentsMargins(0, 0, 0, 0);
- auto tabWidget = new QTabWidget(this);
- tabWidget->setObjectName(QStringLiteral("tabWidget"));
- commands = new CustomCommands(this);
- tabWidget->addTab(commands, "Foo");
- tabWidget->tabBar()->hide();
- verticalLayout->addWidget(tabWidget);
- loadSettings();
+ auto tabWidget = new QTabWidget(this);
+ tabWidget->setObjectName(QStringLiteral("tabWidget"));
+ commands = new CustomCommands(this);
+ tabWidget->addTab(commands, "Foo");
+ tabWidget->tabBar()->hide();
+ verticalLayout->addWidget(tabWidget);
+ loadSettings();
}
CustomCommandsPage::~CustomCommandsPage()
@@ -25,26 +25,26 @@ CustomCommandsPage::~CustomCommandsPage()
bool CustomCommandsPage::apply()
{
- applySettings();
- return true;
+ applySettings();
+ return true;
}
void CustomCommandsPage::applySettings()
{
- auto s = MMC->settings();
- s->set("PreLaunchCommand", commands->prelaunchCommand());
- s->set("WrapperCommand", commands->wrapperCommand());
- s->set("PostExitCommand", commands->postexitCommand());
+ auto s = MMC->settings();
+ s->set("PreLaunchCommand", commands->prelaunchCommand());
+ s->set("WrapperCommand", commands->wrapperCommand());
+ s->set("PostExitCommand", commands->postexitCommand());
}
void CustomCommandsPage::loadSettings()
{
- auto s = MMC->settings();
- commands->initialize(
- false,
- true,
- s->get("PreLaunchCommand").toString(),
- s->get("WrapperCommand").toString(),
- s->get("PostExitCommand").toString()
- );
+ auto s = MMC->settings();
+ commands->initialize(
+ false,
+ true,
+ s->get("PreLaunchCommand").toString(),
+ s->get("WrapperCommand").toString(),
+ s->get("PostExitCommand").toString()
+ );
}
diff --git a/application/pages/global/CustomCommandsPage.h b/application/pages/global/CustomCommandsPage.h
index 52256ed3..d7206dfa 100644
--- a/application/pages/global/CustomCommandsPage.h
+++ b/application/pages/global/CustomCommandsPage.h
@@ -24,32 +24,32 @@
class CustomCommandsPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit CustomCommandsPage(QWidget *parent = 0);
- ~CustomCommandsPage();
+ explicit CustomCommandsPage(QWidget *parent = 0);
+ ~CustomCommandsPage();
- QString displayName() const override
- {
- return tr("Custom Commands");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("custom-commands");
- }
- QString id() const override
- {
- return "custom-commands";
- }
- QString helpPage() const override
- {
- return "Custom-commands";
- }
- bool apply() override;
+ QString displayName() const override
+ {
+ return tr("Custom Commands");
+ }
+ QIcon icon() const override
+ {
+ return MMC->getThemedIcon("custom-commands");
+ }
+ QString id() const override
+ {
+ return "custom-commands";
+ }
+ QString helpPage() const override
+ {
+ return "Custom-commands";
+ }
+ bool apply() override;
private:
- void applySettings();
- void loadSettings();
- CustomCommands * commands;
+ void applySettings();
+ void loadSettings();
+ CustomCommands * commands;
};
diff --git a/application/pages/global/ExternalToolsPage.cpp b/application/pages/global/ExternalToolsPage.cpp
index dd44e504..41ed3f7c 100644
--- a/application/pages/global/ExternalToolsPage.cpp
+++ b/application/pages/global/ExternalToolsPage.cpp
@@ -28,206 +28,206 @@
#include <tools/MCEditTool.h>
ExternalToolsPage::ExternalToolsPage(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::ExternalToolsPage)
+ QWidget(parent),
+ ui(new Ui::ExternalToolsPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
- #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
- ui->jsonEditorTextBox->setClearButtonEnabled(true);
- #endif
+ #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
+ ui->jsonEditorTextBox->setClearButtonEnabled(true);
+ #endif
- ui->mceditLink->setOpenExternalLinks(true);
- ui->jvisualvmLink->setOpenExternalLinks(true);
- ui->jprofilerLink->setOpenExternalLinks(true);
- loadSettings();
+ ui->mceditLink->setOpenExternalLinks(true);
+ ui->jvisualvmLink->setOpenExternalLinks(true);
+ ui->jprofilerLink->setOpenExternalLinks(true);
+ loadSettings();
}
ExternalToolsPage::~ExternalToolsPage()
{
- delete ui;
+ delete ui;
}
void ExternalToolsPage::loadSettings()
{
- auto s = MMC->settings();
- ui->jprofilerPathEdit->setText(s->get("JProfilerPath").toString());
- ui->jvisualvmPathEdit->setText(s->get("JVisualVMPath").toString());
- ui->mceditPathEdit->setText(s->get("MCEditPath").toString());
+ auto s = MMC->settings();
+ ui->jprofilerPathEdit->setText(s->get("JProfilerPath").toString());
+ ui->jvisualvmPathEdit->setText(s->get("JVisualVMPath").toString());
+ ui->mceditPathEdit->setText(s->get("MCEditPath").toString());
- // Editors
- ui->jsonEditorTextBox->setText(s->get("JsonEditor").toString());
+ // Editors
+ ui->jsonEditorTextBox->setText(s->get("JsonEditor").toString());
}
void ExternalToolsPage::applySettings()
{
- auto s = MMC->settings();
-
- s->set("JProfilerPath", ui->jprofilerPathEdit->text());
- s->set("JVisualVMPath", ui->jvisualvmPathEdit->text());
- s->set("MCEditPath", ui->mceditPathEdit->text());
-
- // Editors
- QString jsonEditor = ui->jsonEditorTextBox->text();
- if (!jsonEditor.isEmpty() &&
- (!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable()))
- {
- QString found = QStandardPaths::findExecutable(jsonEditor);
- if (!found.isEmpty())
- {
- jsonEditor = found;
- }
- }
- s->set("JsonEditor", jsonEditor);
+ auto s = MMC->settings();
+
+ s->set("JProfilerPath", ui->jprofilerPathEdit->text());
+ s->set("JVisualVMPath", ui->jvisualvmPathEdit->text());
+ s->set("MCEditPath", ui->mceditPathEdit->text());
+
+ // Editors
+ QString jsonEditor = ui->jsonEditorTextBox->text();
+ if (!jsonEditor.isEmpty() &&
+ (!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable()))
+ {
+ QString found = QStandardPaths::findExecutable(jsonEditor);
+ if (!found.isEmpty())
+ {
+ jsonEditor = found;
+ }
+ }
+ s->set("JsonEditor", jsonEditor);
}
void ExternalToolsPage::on_jprofilerPathBtn_clicked()
{
- QString raw_dir = ui->jprofilerPathEdit->text();
- QString error;
- do
- {
- raw_dir = QFileDialog::getExistingDirectory(this, tr("JProfiler Folder"), raw_dir);
- if (raw_dir.isEmpty())
- {
- break;
- }
- QString cooked_dir = FS::NormalizePath(raw_dir);
- if (!MMC->profilers()["jprofiler"]->check(cooked_dir, &error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
- continue;
- }
- else
- {
- ui->jprofilerPathEdit->setText(cooked_dir);
- break;
- }
- } while (1);
+ QString raw_dir = ui->jprofilerPathEdit->text();
+ QString error;
+ do
+ {
+ raw_dir = QFileDialog::getExistingDirectory(this, tr("JProfiler Folder"), raw_dir);
+ if (raw_dir.isEmpty())
+ {
+ break;
+ }
+ QString cooked_dir = FS::NormalizePath(raw_dir);
+ if (!MMC->profilers()["jprofiler"]->check(cooked_dir, &error))
+ {
+ QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
+ continue;
+ }
+ else
+ {
+ ui->jprofilerPathEdit->setText(cooked_dir);
+ break;
+ }
+ } while (1);
}
void ExternalToolsPage::on_jprofilerCheckBtn_clicked()
{
- QString error;
- if (!MMC->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
- }
- else
- {
- QMessageBox::information(this, tr("OK"), tr("JProfiler setup seems to be OK"));
- }
+ QString error;
+ if (!MMC->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error))
+ {
+ QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
+ }
+ else
+ {
+ QMessageBox::information(this, tr("OK"), tr("JProfiler setup seems to be OK"));
+ }
}
void ExternalToolsPage::on_jvisualvmPathBtn_clicked()
{
- QString raw_dir = ui->jvisualvmPathEdit->text();
- QString error;
- do
- {
- raw_dir = QFileDialog::getOpenFileName(this, tr("JVisualVM Executable"), raw_dir);
- if (raw_dir.isEmpty())
- {
- break;
- }
- QString cooked_dir = FS::NormalizePath(raw_dir);
- if (!MMC->profilers()["jvisualvm"]->check(cooked_dir, &error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
- continue;
- }
- else
- {
- ui->jvisualvmPathEdit->setText(cooked_dir);
- break;
- }
- } while (1);
+ QString raw_dir = ui->jvisualvmPathEdit->text();
+ QString error;
+ do
+ {
+ raw_dir = QFileDialog::getOpenFileName(this, tr("JVisualVM Executable"), raw_dir);
+ if (raw_dir.isEmpty())
+ {
+ break;
+ }
+ QString cooked_dir = FS::NormalizePath(raw_dir);
+ if (!MMC->profilers()["jvisualvm"]->check(cooked_dir, &error))
+ {
+ QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
+ continue;
+ }
+ else
+ {
+ ui->jvisualvmPathEdit->setText(cooked_dir);
+ break;
+ }
+ } while (1);
}
void ExternalToolsPage::on_jvisualvmCheckBtn_clicked()
{
- QString error;
- if (!MMC->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
- }
- else
- {
- QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK"));
- }
+ QString error;
+ if (!MMC->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error))
+ {
+ QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
+ }
+ else
+ {
+ QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK"));
+ }
}
void ExternalToolsPage::on_mceditPathBtn_clicked()
{
- QString raw_dir = ui->mceditPathEdit->text();
- QString error;
- do
- {
+ QString raw_dir = ui->mceditPathEdit->text();
+ QString error;
+ do
+ {
#ifdef Q_OS_OSX
- raw_dir = QFileDialog::getOpenFileName(this, tr("MCEdit Application"), raw_dir);
+ raw_dir = QFileDialog::getOpenFileName(this, tr("MCEdit Application"), raw_dir);
#else
- raw_dir = QFileDialog::getExistingDirectory(this, tr("MCEdit Folder"), raw_dir);
+ raw_dir = QFileDialog::getExistingDirectory(this, tr("MCEdit Folder"), raw_dir);
#endif
- if (raw_dir.isEmpty())
- {
- break;
- }
- QString cooked_dir = FS::NormalizePath(raw_dir);
- if (!MMC->mcedit()->check(cooked_dir, error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
- continue;
- }
- else
- {
- ui->mceditPathEdit->setText(cooked_dir);
- break;
- }
- } while (1);
+ if (raw_dir.isEmpty())
+ {
+ break;
+ }
+ QString cooked_dir = FS::NormalizePath(raw_dir);
+ if (!MMC->mcedit()->check(cooked_dir, error))
+ {
+ QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
+ continue;
+ }
+ else
+ {
+ ui->mceditPathEdit->setText(cooked_dir);
+ break;
+ }
+ } while (1);
}
void ExternalToolsPage::on_mceditCheckBtn_clicked()
{
- QString error;
- if (!MMC->mcedit()->check(ui->mceditPathEdit->text(), error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
- }
- else
- {
- QMessageBox::information(this, tr("OK"), tr("MCEdit setup seems to be OK"));
- }
+ QString error;
+ if (!MMC->mcedit()->check(ui->mceditPathEdit->text(), error))
+ {
+ QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
+ }
+ else
+ {
+ QMessageBox::information(this, tr("OK"), tr("MCEdit setup seems to be OK"));
+ }
}
void ExternalToolsPage::on_jsonEditorBrowseBtn_clicked()
{
- QString raw_file = QFileDialog::getOpenFileName(
- this, tr("JSON Editor"),
- ui->jsonEditorTextBox->text().isEmpty()
+ QString raw_file = QFileDialog::getOpenFileName(
+ this, tr("JSON Editor"),
+ ui->jsonEditorTextBox->text().isEmpty()
#if defined(Q_OS_LINUX)
- ? QString("/usr/bin")
+ ? QString("/usr/bin")
#else
- ? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first()
+ ? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first()
#endif
- : ui->jsonEditorTextBox->text());
-
- if (raw_file.isEmpty())
- {
- return;
- }
- QString cooked_file = FS::NormalizePath(raw_file);
-
- // it has to exist and be an executable
- if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable())
- {
- ui->jsonEditorTextBox->setText(cooked_file);
- }
- else
- {
- QMessageBox::warning(this, tr("Invalid"),
- tr("The file chosen does not seem to be an executable"));
- }
+ : ui->jsonEditorTextBox->text());
+
+ if (raw_file.isEmpty())
+ {
+ return;
+ }
+ QString cooked_file = FS::NormalizePath(raw_file);
+
+ // it has to exist and be an executable
+ if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable())
+ {
+ ui->jsonEditorTextBox->setText(cooked_file);
+ }
+ else
+ {
+ QMessageBox::warning(this, tr("Invalid"),
+ tr("The file chosen does not seem to be an executable"));
+ }
}
bool ExternalToolsPage::apply()
{
- applySettings();
- return true;
+ applySettings();
+ return true;
}
diff --git a/application/pages/global/ExternalToolsPage.h b/application/pages/global/ExternalToolsPage.h
index de46d8a6..bc42d2dd 100644
--- a/application/pages/global/ExternalToolsPage.h
+++ b/application/pages/global/ExternalToolsPage.h
@@ -26,49 +26,49 @@ class ExternalToolsPage;
class ExternalToolsPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ExternalToolsPage(QWidget *parent = 0);
- ~ExternalToolsPage();
+ explicit ExternalToolsPage(QWidget *parent = 0);
+ ~ExternalToolsPage();
- QString displayName() const override
- {
- return tr("External Tools");
- }
- QIcon icon() const override
- {
- auto icon = MMC->getThemedIcon("externaltools");
- if(icon.isNull())
- {
- icon = MMC->getThemedIcon("loadermods");
- }
- return icon;
- }
- QString id() const override
- {
- return "external-tools";
- }
- QString helpPage() const override
- {
- return "Tools";
- }
- virtual bool apply() override;
+ QString displayName() const override
+ {
+ return tr("External Tools");
+ }
+ QIcon icon() const override
+ {
+ auto icon = MMC->getThemedIcon("externaltools");
+ if(icon.isNull())
+ {
+ icon = MMC->getThemedIcon("loadermods");
+ }
+ return icon;
+ }
+ QString id() const override
+ {
+ return "external-tools";
+ }
+ QString helpPage() const override
+ {
+ return "Tools";
+ }
+ virtual bool apply() override;
private:
- void loadSettings();
- void applySettings();
+ void loadSettings();
+ void applySettings();
private:
- Ui::ExternalToolsPage *ui;
+ Ui::ExternalToolsPage *ui;
private
slots:
- void on_jprofilerPathBtn_clicked();
- void on_jprofilerCheckBtn_clicked();
- void on_jvisualvmPathBtn_clicked();
- void on_jvisualvmCheckBtn_clicked();
- void on_mceditPathBtn_clicked();
- void on_mceditCheckBtn_clicked();
- void on_jsonEditorBrowseBtn_clicked();
+ void on_jprofilerPathBtn_clicked();
+ void on_jprofilerCheckBtn_clicked();
+ void on_jvisualvmPathBtn_clicked();
+ void on_jvisualvmCheckBtn_clicked();
+ void on_mceditPathBtn_clicked();
+ void on_mceditCheckBtn_clicked();
+ void on_jsonEditorBrowseBtn_clicked();
};
diff --git a/application/pages/global/JavaPage.cpp b/application/pages/global/JavaPage.cpp
index b828a450..57e60ddf 100644
--- a/application/pages/global/JavaPage.cpp
+++ b/application/pages/global/JavaPage.cpp
@@ -34,120 +34,120 @@
JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
- auto sysMB = Sys::getSystemRam() / Sys::megabyte;
- ui->maxMemSpinBox->setMaximum(sysMB);
- loadSettings();
+ auto sysMB = Sys::getSystemRam() / Sys::megabyte;
+ ui->maxMemSpinBox->setMaximum(sysMB);
+ loadSettings();
}
JavaPage::~JavaPage()
{
- delete ui;
+ delete ui;
}
bool JavaPage::apply()
{
- applySettings();
- return true;
+ applySettings();
+ return true;
}
void JavaPage::applySettings()
{
- auto s = MMC->settings();
-
- // Memory
- int min = ui->minMemSpinBox->value();
- int max = ui->maxMemSpinBox->value();
- if(min < max)
- {
- s->set("MinMemAlloc", min);
- s->set("MaxMemAlloc", max);
- }
- else
- {
- s->set("MinMemAlloc", max);
- s->set("MaxMemAlloc", min);
- }
- s->set("PermGen", ui->permGenSpinBox->value());
-
- // Java Settings
- s->set("JavaPath", ui->javaPathTextBox->text());
- s->set("JvmArgs", ui->jvmArgsTextBox->text());
- JavaCommon::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget());
+ auto s = MMC->settings();
+
+ // Memory
+ int min = ui->minMemSpinBox->value();
+ int max = ui->maxMemSpinBox->value();
+ if(min < max)
+ {
+ s->set("MinMemAlloc", min);
+ s->set("MaxMemAlloc", max);
+ }
+ else
+ {
+ s->set("MinMemAlloc", max);
+ s->set("MaxMemAlloc", min);
+ }
+ s->set("PermGen", ui->permGenSpinBox->value());
+
+ // Java Settings
+ s->set("JavaPath", ui->javaPathTextBox->text());
+ s->set("JvmArgs", ui->jvmArgsTextBox->text());
+ JavaCommon::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget());
}
void JavaPage::loadSettings()
{
- auto s = MMC->settings();
- // Memory
- int min = s->get("MinMemAlloc").toInt();
- int max = s->get("MaxMemAlloc").toInt();
- if(min < max)
- {
- ui->minMemSpinBox->setValue(min);
- ui->maxMemSpinBox->setValue(max);
- }
- else
- {
- ui->minMemSpinBox->setValue(max);
- ui->maxMemSpinBox->setValue(min);
- }
- ui->permGenSpinBox->setValue(s->get("PermGen").toInt());
-
- // Java Settings
- ui->javaPathTextBox->setText(s->get("JavaPath").toString());
- ui->jvmArgsTextBox->setText(s->get("JvmArgs").toString());
+ auto s = MMC->settings();
+ // Memory
+ int min = s->get("MinMemAlloc").toInt();
+ int max = s->get("MaxMemAlloc").toInt();
+ if(min < max)
+ {
+ ui->minMemSpinBox->setValue(min);
+ ui->maxMemSpinBox->setValue(max);
+ }
+ else
+ {
+ ui->minMemSpinBox->setValue(max);
+ ui->maxMemSpinBox->setValue(min);
+ }
+ ui->permGenSpinBox->setValue(s->get("PermGen").toInt());
+
+ // Java Settings
+ ui->javaPathTextBox->setText(s->get("JavaPath").toString());
+ ui->jvmArgsTextBox->setText(s->get("JvmArgs").toString());
}
void JavaPage::on_javaDetectBtn_clicked()
{
- JavaInstallPtr java;
+ JavaInstallPtr java;
- VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true);
- vselect.setResizeOn(2);
- vselect.exec();
+ VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true);
+ vselect.setResizeOn(2);
+ vselect.exec();
- if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
- {
- java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
- ui->javaPathTextBox->setText(java->path);
- }
+ if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
+ {
+ java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
+ ui->javaPathTextBox->setText(java->path);
+ }
}
void JavaPage::on_javaBrowseBtn_clicked()
{
- QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if(raw_path.isEmpty())
- {
- return;
- }
-
- QString cooked_path = FS::NormalizePath(raw_path);
- QFileInfo javaInfo(cooked_path);;
- if(!javaInfo.exists() || !javaInfo.isExecutable())
- {
- return;
- }
- ui->javaPathTextBox->setText(cooked_path);
+ QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if(raw_path.isEmpty())
+ {
+ return;
+ }
+
+ QString cooked_path = FS::NormalizePath(raw_path);
+ QFileInfo javaInfo(cooked_path);;
+ if(!javaInfo.exists() || !javaInfo.isExecutable())
+ {
+ return;
+ }
+ ui->javaPathTextBox->setText(cooked_path);
}
void JavaPage::on_javaTestBtn_clicked()
{
- if(checker)
- {
- return;
- }
- checker.reset(new JavaCommon::TestCheck(
- this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->text(),
- ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
- connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
- checker->run();
+ if(checker)
+ {
+ return;
+ }
+ checker.reset(new JavaCommon::TestCheck(
+ this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->text(),
+ ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
+ connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
+ checker->run();
}
void JavaPage::checkerFinished()
{
- checker.reset();
+ checker.reset();
}
diff --git a/application/pages/global/JavaPage.h b/application/pages/global/JavaPage.h
index e3a9f37f..dc53402a 100644
--- a/application/pages/global/JavaPage.h
+++ b/application/pages/global/JavaPage.h
@@ -31,42 +31,42 @@ class JavaPage;
class JavaPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit JavaPage(QWidget *parent = 0);
- ~JavaPage();
+ explicit JavaPage(QWidget *parent = 0);
+ ~JavaPage();
- QString displayName() const override
- {
- return tr("Java");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("java");
- }
- QString id() const override
- {
- return "java-settings";
- }
- QString helpPage() const override
- {
- return "Java-settings";
- }
- bool apply() override;
+ QString displayName() const override
+ {
+ return tr("Java");
+ }
+ QIcon icon() const override
+ {
+ return MMC->getThemedIcon("java");
+ }
+ QString id() const override
+ {
+ return "java-settings";
+ }
+ QString helpPage() const override
+ {
+ return "Java-settings";
+ }
+ bool apply() override;
private:
- void applySettings();
- void loadSettings();
+ void applySettings();
+ void loadSettings();
private
slots:
- void on_javaDetectBtn_clicked();
- void on_javaTestBtn_clicked();
- void on_javaBrowseBtn_clicked();
- void checkerFinished();
+ void on_javaDetectBtn_clicked();
+ void on_javaTestBtn_clicked();
+ void on_javaBrowseBtn_clicked();
+ void checkerFinished();
private:
- Ui::JavaPage *ui;
- unique_qobject_ptr<JavaCommon::TestCheck> checker;
+ Ui::JavaPage *ui;
+ unique_qobject_ptr<JavaCommon::TestCheck> checker;
};
diff --git a/application/pages/global/MinecraftPage.cpp b/application/pages/global/MinecraftPage.cpp
index e6687cde..06429449 100644
--- a/application/pages/global/MinecraftPage.cpp
+++ b/application/pages/global/MinecraftPage.cpp
@@ -25,52 +25,52 @@
MinecraftPage::MinecraftPage(QWidget *parent) : QWidget(parent), ui(new Ui::MinecraftPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- loadSettings();
- updateCheckboxStuff();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ loadSettings();
+ updateCheckboxStuff();
}
MinecraftPage::~MinecraftPage()
{
- delete ui;
+ delete ui;
}
bool MinecraftPage::apply()
{
- applySettings();
- return true;
+ applySettings();
+ return true;
}
void MinecraftPage::updateCheckboxStuff()
{
- ui->windowWidthSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked());
- ui->windowHeightSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked());
+ ui->windowWidthSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked());
+ ui->windowHeightSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked());
}
void MinecraftPage::on_maximizedCheckBox_clicked(bool checked)
{
- Q_UNUSED(checked);
- updateCheckboxStuff();
+ Q_UNUSED(checked);
+ updateCheckboxStuff();
}
void MinecraftPage::applySettings()
{
- auto s = MMC->settings();
+ auto s = MMC->settings();
- // Window Size
- s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
- s->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
- s->set("MinecraftWinHeight", ui->windowHeightSpinBox->value());
+ // Window Size
+ s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
+ s->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
+ s->set("MinecraftWinHeight", ui->windowHeightSpinBox->value());
}
void MinecraftPage::loadSettings()
{
- auto s = MMC->settings();
+ auto s = MMC->settings();
- // Window Size
- ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool());
- ui->windowWidthSpinBox->setValue(s->get("MinecraftWinWidth").toInt());
- ui->windowHeightSpinBox->setValue(s->get("MinecraftWinHeight").toInt());
+ // Window Size
+ ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool());
+ ui->windowWidthSpinBox->setValue(s->get("MinecraftWinWidth").toInt());
+ ui->windowHeightSpinBox->setValue(s->get("MinecraftWinHeight").toInt());
}
diff --git a/application/pages/global/MinecraftPage.h b/application/pages/global/MinecraftPage.h
index d1abd6fe..e5d5f854 100644
--- a/application/pages/global/MinecraftPage.h
+++ b/application/pages/global/MinecraftPage.h
@@ -31,40 +31,40 @@ class MinecraftPage;
class MinecraftPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit MinecraftPage(QWidget *parent = 0);
- ~MinecraftPage();
+ explicit MinecraftPage(QWidget *parent = 0);
+ ~MinecraftPage();
- QString displayName() const override
- {
- return tr("Minecraft");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("minecraft");
- }
- QString id() const override
- {
- return "minecraft-settings";
- }
- QString helpPage() const override
- {
- return "Minecraft-settings";
- }
- bool apply() override;
+ QString displayName() const override
+ {
+ return tr("Minecraft");
+ }
+ QIcon icon() const override
+ {
+ return MMC->getThemedIcon("minecraft");
+ }
+ QString id() const override
+ {
+ return "minecraft-settings";
+ }
+ QString helpPage() const override
+ {
+ return "Minecraft-settings";
+ }
+ bool apply() override;
private:
- void updateCheckboxStuff();
- void applySettings();
- void loadSettings();
+ void updateCheckboxStuff();
+ void applySettings();
+ void loadSettings();
private
slots:
- void on_maximizedCheckBox_clicked(bool checked);
+ void on_maximizedCheckBox_clicked(bool checked);
private:
- Ui::MinecraftPage *ui;
+ Ui::MinecraftPage *ui;
};
diff --git a/application/pages/global/MultiMCPage.cpp b/application/pages/global/MultiMCPage.cpp
index 620fc3a3..1991c9ba 100644
--- a/application/pages/global/MultiMCPage.cpp
+++ b/application/pages/global/MultiMCPage.cpp
@@ -32,441 +32,441 @@
// FIXME: possibly move elsewhere
enum InstSortMode
{
- // Sort alphabetically by name.
- Sort_Name,
- // Sort by which instance was launched most recently.
- Sort_LastLaunch
+ // Sort alphabetically by name.
+ Sort_Name,
+ // Sort by which instance was launched most recently.
+ Sort_LastLaunch
};
MultiMCPage::MultiMCPage(QWidget *parent) : QWidget(parent), ui(new Ui::MultiMCPage)
{
- ui->setupUi(this);
- auto origForeground = ui->fontPreview->palette().color(ui->fontPreview->foregroundRole());
- auto origBackground = ui->fontPreview->palette().color(ui->fontPreview->backgroundRole());
- m_colors.reset(new LogColorCache(origForeground, origBackground));
-
- ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name);
- ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch);
-
- defaultFormat = new QTextCharFormat(ui->fontPreview->currentCharFormat());
-
- m_languageModel = MMC->translations();
- loadSettings();
-
- if(BuildConfig.UPDATER_ENABLED)
- {
- QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this,
- &MultiMCPage::refreshUpdateChannelList);
-
- if (MMC->updateChecker()->hasChannels())
- {
- refreshUpdateChannelList();
- }
- else
- {
- MMC->updateChecker()->updateChanList(false);
- }
- }
- else
- {
- ui->updateSettingsBox->setHidden(true);
- }
- // Analytics
- if(BuildConfig.ANALYTICS_ID.isEmpty())
- {
- ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->analyticsTab));
- }
- connect(ui->fontSizeBox, SIGNAL(valueChanged(int)), SLOT(refreshFontPreview()));
- connect(ui->consoleFont, SIGNAL(currentFontChanged(QFont)), SLOT(refreshFontPreview()));
- connect(ui->languageBox, SIGNAL(currentIndexChanged(int)), SLOT(languageIndexChanged(int)));
+ ui->setupUi(this);
+ auto origForeground = ui->fontPreview->palette().color(ui->fontPreview->foregroundRole());
+ auto origBackground = ui->fontPreview->palette().color(ui->fontPreview->backgroundRole());
+ m_colors.reset(new LogColorCache(origForeground, origBackground));
+
+ ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name);
+ ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch);
+
+ defaultFormat = new QTextCharFormat(ui->fontPreview->currentCharFormat());
+
+ m_languageModel = MMC->translations();
+ loadSettings();
+
+ if(BuildConfig.UPDATER_ENABLED)
+ {
+ QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this,
+ &MultiMCPage::refreshUpdateChannelList);
+
+ if (MMC->updateChecker()->hasChannels())
+ {
+ refreshUpdateChannelList();
+ }
+ else
+ {
+ MMC->updateChecker()->updateChanList(false);
+ }
+ }
+ else
+ {
+ ui->updateSettingsBox->setHidden(true);
+ }
+ // Analytics
+ if(BuildConfig.ANALYTICS_ID.isEmpty())
+ {
+ ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->analyticsTab));
+ }
+ connect(ui->fontSizeBox, SIGNAL(valueChanged(int)), SLOT(refreshFontPreview()));
+ connect(ui->consoleFont, SIGNAL(currentFontChanged(QFont)), SLOT(refreshFontPreview()));
+ connect(ui->languageBox, SIGNAL(currentIndexChanged(int)), SLOT(languageIndexChanged(int)));
}
MultiMCPage::~MultiMCPage()
{
- delete ui;
+ delete ui;
}
bool MultiMCPage::apply()
{
- applySettings();
- return true;
+ applySettings();
+ return true;
}
void MultiMCPage::on_instDirBrowseBtn_clicked()
{
- QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Folder"), ui->instDirTextBox->text());
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
- {
- QString cooked_dir = FS::NormalizePath(raw_dir);
- if (FS::checkProblemticPathJava(QDir(cooked_dir)))
- {
- QMessageBox warning;
- warning.setText(tr("You're trying to specify an instance folder which\'s path "
- "contains at least one \'!\'. "
- "Java is known to cause problems if that is the case, your "
- "instances (probably) won't start!"));
- warning.setInformativeText(
- tr("Do you really want to use this path? "
- "Selecting \"No\" will close this and not alter your instance path."));
- warning.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- int result = warning.exec();
- if (result == QMessageBox::Yes)
- {
- ui->instDirTextBox->setText(cooked_dir);
- }
- }
- else
- {
- ui->instDirTextBox->setText(cooked_dir);
- }
- }
+ QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Folder"), ui->instDirTextBox->text());
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
+ {
+ QString cooked_dir = FS::NormalizePath(raw_dir);
+ if (FS::checkProblemticPathJava(QDir(cooked_dir)))
+ {
+ QMessageBox warning;
+ warning.setText(tr("You're trying to specify an instance folder which\'s path "
+ "contains at least one \'!\'. "
+ "Java is known to cause problems if that is the case, your "
+ "instances (probably) won't start!"));
+ warning.setInformativeText(
+ tr("Do you really want to use this path? "
+ "Selecting \"No\" will close this and not alter your instance path."));
+ warning.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ int result = warning.exec();
+ if (result == QMessageBox::Yes)
+ {
+ ui->instDirTextBox->setText(cooked_dir);
+ }
+ }
+ else
+ {
+ ui->instDirTextBox->setText(cooked_dir);
+ }
+ }
}
void MultiMCPage::on_iconsDirBrowseBtn_clicked()
{
- QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Folder"), ui->iconsDirTextBox->text());
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
- {
- QString cooked_dir = FS::NormalizePath(raw_dir);
- ui->iconsDirTextBox->setText(cooked_dir);
- }
+ QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Folder"), ui->iconsDirTextBox->text());
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
+ {
+ QString cooked_dir = FS::NormalizePath(raw_dir);
+ ui->iconsDirTextBox->setText(cooked_dir);
+ }
}
void MultiMCPage::on_modsDirBrowseBtn_clicked()
{
- QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Folder"), ui->modsDirTextBox->text());
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
- {
- QString cooked_dir = FS::NormalizePath(raw_dir);
- ui->modsDirTextBox->setText(cooked_dir);
- }
+ QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Folder"), ui->modsDirTextBox->text());
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
+ {
+ QString cooked_dir = FS::NormalizePath(raw_dir);
+ ui->modsDirTextBox->setText(cooked_dir);
+ }
}
void MultiMCPage::languageIndexChanged(int index)
{
- auto languageCode = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString();
- if(languageCode.isEmpty())
- {
- qWarning() << "Unknown language at index" << index;
- return;
- }
- auto translations = MMC->translations();
- translations->selectLanguage(languageCode);
- translations->updateLanguage(languageCode);
+ auto languageCode = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString();
+ if(languageCode.isEmpty())
+ {
+ qWarning() << "Unknown language at index" << index;
+ return;
+ }
+ auto translations = MMC->translations();
+ translations->selectLanguage(languageCode);
+ translations->updateLanguage(languageCode);
}
void MultiMCPage::refreshUpdateChannelList()
{
- // Stop listening for selection changes. It's going to change a lot while we update it and
- // we don't need to update the
- // description label constantly.
- QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this,
- SLOT(updateChannelSelectionChanged(int)));
-
- QList<UpdateChecker::ChannelListEntry> channelList = MMC->updateChecker()->getChannelList();
- ui->updateChannelComboBox->clear();
- int selection = -1;
- for (int i = 0; i < channelList.count(); i++)
- {
- UpdateChecker::ChannelListEntry entry = channelList.at(i);
-
- // When it comes to selection, we'll rely on the indexes of a channel entry being the
- // same in the
- // combo box as it is in the update checker's channel list.
- // This probably isn't very safe, but the channel list doesn't change often enough (or
- // at all) for
- // this to be a big deal. Hope it doesn't break...
- ui->updateChannelComboBox->addItem(entry.name);
-
- // If the update channel we just added was the selected one, set the current index in
- // the combo box to it.
- if (entry.id == m_currentUpdateChannel)
- {
- qDebug() << "Selected index" << i << "channel id" << m_currentUpdateChannel;
- selection = i;
- }
- }
-
- ui->updateChannelComboBox->setCurrentIndex(selection);
-
- // Start listening for selection changes again and update the description label.
- QObject::connect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this,
- SLOT(updateChannelSelectionChanged(int)));
- refreshUpdateChannelDesc();
-
- // Now that we've updated the channel list, we can enable the combo box.
- // It starts off disabled so that if the channel list hasn't been loaded, it will be
- // disabled.
- ui->updateChannelComboBox->setEnabled(true);
+ // Stop listening for selection changes. It's going to change a lot while we update it and
+ // we don't need to update the
+ // description label constantly.
+ QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(updateChannelSelectionChanged(int)));
+
+ QList<UpdateChecker::ChannelListEntry> channelList = MMC->updateChecker()->getChannelList();
+ ui->updateChannelComboBox->clear();
+ int selection = -1;
+ for (int i = 0; i < channelList.count(); i++)
+ {
+ UpdateChecker::ChannelListEntry entry = channelList.at(i);
+
+ // When it comes to selection, we'll rely on the indexes of a channel entry being the
+ // same in the
+ // combo box as it is in the update checker's channel list.
+ // This probably isn't very safe, but the channel list doesn't change often enough (or
+ // at all) for
+ // this to be a big deal. Hope it doesn't break...
+ ui->updateChannelComboBox->addItem(entry.name);
+
+ // If the update channel we just added was the selected one, set the current index in
+ // the combo box to it.
+ if (entry.id == m_currentUpdateChannel)
+ {
+ qDebug() << "Selected index" << i << "channel id" << m_currentUpdateChannel;
+ selection = i;
+ }
+ }
+
+ ui->updateChannelComboBox->setCurrentIndex(selection);
+
+ // Start listening for selection changes again and update the description label.
+ QObject::connect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(updateChannelSelectionChanged(int)));
+ refreshUpdateChannelDesc();
+
+ // Now that we've updated the channel list, we can enable the combo box.
+ // It starts off disabled so that if the channel list hasn't been loaded, it will be
+ // disabled.
+ ui->updateChannelComboBox->setEnabled(true);
}
void MultiMCPage::updateChannelSelectionChanged(int index)
{
- refreshUpdateChannelDesc();
+ refreshUpdateChannelDesc();
}
void MultiMCPage::refreshUpdateChannelDesc()
{
- // Get the channel list.
- QList<UpdateChecker::ChannelListEntry> channelList = MMC->updateChecker()->getChannelList();
- int selectedIndex = ui->updateChannelComboBox->currentIndex();
- if (selectedIndex < 0)
- {
- return;
- }
- if (selectedIndex < channelList.count())
- {
- // Find the channel list entry with the given index.
- UpdateChecker::ChannelListEntry selected = channelList.at(selectedIndex);
-
- // Set the description text.
- ui->updateChannelDescLabel->setText(selected.description);
-
- // Set the currently selected channel ID.
- m_currentUpdateChannel = selected.id;
- }
+ // Get the channel list.
+ QList<UpdateChecker::ChannelListEntry> channelList = MMC->updateChecker()->getChannelList();
+ int selectedIndex = ui->updateChannelComboBox->currentIndex();
+ if (selectedIndex < 0)
+ {
+ return;
+ }
+ if (selectedIndex < channelList.count())
+ {
+ // Find the channel list entry with the given index.
+ UpdateChecker::ChannelListEntry selected = channelList.at(selectedIndex);
+
+ // Set the description text.
+ ui->updateChannelDescLabel->setText(selected.description);
+
+ // Set the currently selected channel ID.
+ m_currentUpdateChannel = selected.id;
+ }
}
void MultiMCPage::applySettings()
{
- auto s = MMC->settings();
-
- // Language
- s->set("Language", ui->languageBox->itemData(ui->languageBox->currentIndex()).toString());
-
- if (ui->resetNotificationsBtn->isChecked())
- {
- s->set("ShownNotifications", QString());
- }
-
- // Updates
- s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked());
- s->set("UpdateChannel", m_currentUpdateChannel);
- auto original = s->get("IconTheme").toString();
- //FIXME: make generic
- switch (ui->themeComboBox->currentIndex())
- {
- case 1:
- s->set("IconTheme", "pe_dark");
- break;
- case 2:
- s->set("IconTheme", "pe_light");
- break;
- case 3:
- s->set("IconTheme", "pe_blue");
- break;
- case 4:
- s->set("IconTheme", "pe_colored");
- break;
- case 5:
- s->set("IconTheme", "OSX");
- break;
- case 6:
- s->set("IconTheme", "iOS");
- break;
- case 7:
- s->set("IconTheme", "flat");
- break;
- case 8:
- s->set("IconTheme", "custom");
- break;
- case 0:
- default:
- s->set("IconTheme", "multimc");
- break;
- }
-
- if(original != s->get("IconTheme"))
- {
- MMC->setIconTheme(s->get("IconTheme").toString());
- }
-
- auto originalAppTheme = s->get("ApplicationTheme").toString();
- auto newAppTheme = ui->themeComboBoxColors->currentData().toString();
- if(originalAppTheme != newAppTheme)
- {
- s->set("ApplicationTheme", newAppTheme);
- MMC->setApplicationTheme(newAppTheme, false);
- }
-
- // Console settings
- s->set("ShowConsole", ui->showConsoleCheck->isChecked());
- s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
- s->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked());
- QString consoleFontFamily = ui->consoleFont->currentFont().family();
- s->set("ConsoleFont", consoleFontFamily);
- s->set("ConsoleFontSize", ui->fontSizeBox->value());
- s->set("ConsoleMaxLines", ui->lineLimitSpinBox->value());
- s->set("ConsoleOverflowStop", ui->checkStopLogging->checkState() != Qt::Unchecked);
-
- // Folders
- // TODO: Offer to move instances to new instance folder.
- s->set("InstanceDir", ui->instDirTextBox->text());
- s->set("CentralModsDir", ui->modsDirTextBox->text());
- s->set("IconsDir", ui->iconsDirTextBox->text());
-
- auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId();
- switch (sortMode)
- {
- case Sort_LastLaunch:
- s->set("InstSortMode", "LastLaunch");
- break;
- case Sort_Name:
- default:
- s->set("InstSortMode", "Name");
- break;
- }
-
- // Analytics
- if(!BuildConfig.ANALYTICS_ID.isEmpty())
- {
- s->set("Analytics", ui->analyticsCheck->isChecked());
- }
+ auto s = MMC->settings();
+
+ // Language
+ s->set("Language", ui->languageBox->itemData(ui->languageBox->currentIndex()).toString());
+
+ if (ui->resetNotificationsBtn->isChecked())
+ {
+ s->set("ShownNotifications", QString());
+ }
+
+ // Updates
+ s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked());
+ s->set("UpdateChannel", m_currentUpdateChannel);
+ auto original = s->get("IconTheme").toString();
+ //FIXME: make generic
+ switch (ui->themeComboBox->currentIndex())
+ {
+ case 1:
+ s->set("IconTheme", "pe_dark");
+ break;
+ case 2:
+ s->set("IconTheme", "pe_light");
+ break;
+ case 3:
+ s->set("IconTheme", "pe_blue");
+ break;
+ case 4:
+ s->set("IconTheme", "pe_colored");
+ break;
+ case 5:
+ s->set("IconTheme", "OSX");
+ break;
+ case 6:
+ s->set("IconTheme", "iOS");
+ break;
+ case 7:
+ s->set("IconTheme", "flat");
+ break;
+ case 8:
+ s->set("IconTheme", "custom");
+ break;
+ case 0:
+ default:
+ s->set("IconTheme", "multimc");
+ break;
+ }
+
+ if(original != s->get("IconTheme"))
+ {
+ MMC->setIconTheme(s->get("IconTheme").toString());
+ }
+
+ auto originalAppTheme = s->get("ApplicationTheme").toString();
+ auto newAppTheme = ui->themeComboBoxColors->currentData().toString();
+ if(originalAppTheme != newAppTheme)
+ {
+ s->set("ApplicationTheme", newAppTheme);
+ MMC->setApplicationTheme(newAppTheme, false);
+ }
+
+ // Console settings
+ s->set("ShowConsole", ui->showConsoleCheck->isChecked());
+ s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
+ s->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked());
+ QString consoleFontFamily = ui->consoleFont->currentFont().family();
+ s->set("ConsoleFont", consoleFontFamily);
+ s->set("ConsoleFontSize", ui->fontSizeBox->value());
+ s->set("ConsoleMaxLines", ui->lineLimitSpinBox->value());
+ s->set("ConsoleOverflowStop", ui->checkStopLogging->checkState() != Qt::Unchecked);
+
+ // Folders
+ // TODO: Offer to move instances to new instance folder.
+ s->set("InstanceDir", ui->instDirTextBox->text());
+ s->set("CentralModsDir", ui->modsDirTextBox->text());
+ s->set("IconsDir", ui->iconsDirTextBox->text());
+
+ auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId();
+ switch (sortMode)
+ {
+ case Sort_LastLaunch:
+ s->set("InstSortMode", "LastLaunch");
+ break;
+ case Sort_Name:
+ default:
+ s->set("InstSortMode", "Name");
+ break;
+ }
+
+ // Analytics
+ if(!BuildConfig.ANALYTICS_ID.isEmpty())
+ {
+ s->set("Analytics", ui->analyticsCheck->isChecked());
+ }
}
void MultiMCPage::loadSettings()
{
- auto s = MMC->settings();
- // Language
- {
- ui->languageBox->setModel(m_languageModel.get());
- ui->languageBox->setCurrentIndex(ui->languageBox->findData(s->get("Language").toString()));
- }
-
- // Updates
- ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool());
- m_currentUpdateChannel = s->get("UpdateChannel").toString();
- //FIXME: make generic
- auto theme = s->get("IconTheme").toString();
- if (theme == "pe_dark")
- {
- ui->themeComboBox->setCurrentIndex(1);
- }
- else if (theme == "pe_light")
- {
- ui->themeComboBox->setCurrentIndex(2);
- }
- else if (theme == "pe_blue")
- {
- ui->themeComboBox->setCurrentIndex(3);
- }
- else if (theme == "pe_colored")
- {
- ui->themeComboBox->setCurrentIndex(4);
- }
- else if (theme == "OSX")
- {
- ui->themeComboBox->setCurrentIndex(5);
- }
- else if (theme == "iOS")
- {
- ui->themeComboBox->setCurrentIndex(6);
- }
- else if (theme == "flat")
- {
- ui->themeComboBox->setCurrentIndex(7);
- }
- else if (theme == "custom")
- {
- ui->themeComboBox->setCurrentIndex(8);
- }
- else
- {
- ui->themeComboBox->setCurrentIndex(0);
- }
-
- {
- auto currentTheme = s->get("ApplicationTheme").toString();
- auto themes = MMC->getValidApplicationThemes();
- int idx = 0;
- for(auto &theme: themes)
- {
- ui->themeComboBoxColors->addItem(theme->name(), theme->id());
- if(currentTheme == theme->id())
- {
- ui->themeComboBoxColors->setCurrentIndex(idx);
- }
- idx++;
- }
- }
-
- // Console settings
- ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool());
- ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool());
- ui->showConsoleErrorCheck->setChecked(s->get("ShowConsoleOnError").toBool());
- QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
- QFont consoleFont(fontFamily);
- ui->consoleFont->setCurrentFont(consoleFont);
-
- bool conversionOk = true;
- int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
- if(!conversionOk)
- {
- fontSize = 11;
- }
- ui->fontSizeBox->setValue(fontSize);
- refreshFontPreview();
- ui->lineLimitSpinBox->setValue(s->get("ConsoleMaxLines").toInt());
- ui->checkStopLogging->setChecked(s->get("ConsoleOverflowStop").toBool());
-
- // Folders
- ui->instDirTextBox->setText(s->get("InstanceDir").toString());
- ui->modsDirTextBox->setText(s->get("CentralModsDir").toString());
- ui->iconsDirTextBox->setText(s->get("IconsDir").toString());
-
- QString sortMode = s->get("InstSortMode").toString();
-
- if (sortMode == "LastLaunch")
- {
- ui->sortLastLaunchedBtn->setChecked(true);
- }
- else
- {
- ui->sortByNameBtn->setChecked(true);
- }
-
- // Analytics
- if(!BuildConfig.ANALYTICS_ID.isEmpty())
- {
- ui->analyticsCheck->setChecked(s->get("Analytics").toBool());
- }
+ auto s = MMC->settings();
+ // Language
+ {
+ ui->languageBox->setModel(m_languageModel.get());
+ ui->languageBox->setCurrentIndex(ui->languageBox->findData(s->get("Language").toString()));
+ }
+
+ // Updates
+ ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool());
+ m_currentUpdateChannel = s->get("UpdateChannel").toString();
+ //FIXME: make generic
+ auto theme = s->get("IconTheme").toString();
+ if (theme == "pe_dark")
+ {
+ ui->themeComboBox->setCurrentIndex(1);
+ }
+ else if (theme == "pe_light")
+ {
+ ui->themeComboBox->setCurrentIndex(2);
+ }
+ else if (theme == "pe_blue")
+ {
+ ui->themeComboBox->setCurrentIndex(3);
+ }
+ else if (theme == "pe_colored")
+ {
+ ui->themeComboBox->setCurrentIndex(4);
+ }
+ else if (theme == "OSX")
+ {
+ ui->themeComboBox->setCurrentIndex(5);
+ }
+ else if (theme == "iOS")
+ {
+ ui->themeComboBox->setCurrentIndex(6);
+ }
+ else if (theme == "flat")
+ {
+ ui->themeComboBox->setCurrentIndex(7);
+ }
+ else if (theme == "custom")
+ {
+ ui->themeComboBox->setCurrentIndex(8);
+ }
+ else
+ {
+ ui->themeComboBox->setCurrentIndex(0);
+ }
+
+ {
+ auto currentTheme = s->get("ApplicationTheme").toString();
+ auto themes = MMC->getValidApplicationThemes();
+ int idx = 0;
+ for(auto &theme: themes)
+ {
+ ui->themeComboBoxColors->addItem(theme->name(), theme->id());
+ if(currentTheme == theme->id())
+ {
+ ui->themeComboBoxColors->setCurrentIndex(idx);
+ }
+ idx++;
+ }
+ }
+
+ // Console settings
+ ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool());
+ ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool());
+ ui->showConsoleErrorCheck->setChecked(s->get("ShowConsoleOnError").toBool());
+ QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
+ QFont consoleFont(fontFamily);
+ ui->consoleFont->setCurrentFont(consoleFont);
+
+ bool conversionOk = true;
+ int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
+ if(!conversionOk)
+ {
+ fontSize = 11;
+ }
+ ui->fontSizeBox->setValue(fontSize);
+ refreshFontPreview();
+ ui->lineLimitSpinBox->setValue(s->get("ConsoleMaxLines").toInt());
+ ui->checkStopLogging->setChecked(s->get("ConsoleOverflowStop").toBool());
+
+ // Folders
+ ui->instDirTextBox->setText(s->get("InstanceDir").toString());
+ ui->modsDirTextBox->setText(s->get("CentralModsDir").toString());
+ ui->iconsDirTextBox->setText(s->get("IconsDir").toString());
+
+ QString sortMode = s->get("InstSortMode").toString();
+
+ if (sortMode == "LastLaunch")
+ {
+ ui->sortLastLaunchedBtn->setChecked(true);
+ }
+ else
+ {
+ ui->sortByNameBtn->setChecked(true);
+ }
+
+ // Analytics
+ if(!BuildConfig.ANALYTICS_ID.isEmpty())
+ {
+ ui->analyticsCheck->setChecked(s->get("Analytics").toBool());
+ }
}
void MultiMCPage::refreshFontPreview()
{
- int fontSize = ui->fontSizeBox->value();
- QString fontFamily = ui->consoleFont->currentFont().family();
- ui->fontPreview->clear();
- defaultFormat->setFont(QFont(fontFamily, fontSize));
- {
- QTextCharFormat format(*defaultFormat);
- format.setForeground(m_colors->getFront(MessageLevel::Error));
- // append a paragraph/line
- auto workCursor = ui->fontPreview->textCursor();
- workCursor.movePosition(QTextCursor::End);
- workCursor.insertText(tr("[Something/ERROR] A spooky error!"), format);
- workCursor.insertBlock();
- }
- {
- QTextCharFormat format(*defaultFormat);
- format.setForeground(m_colors->getFront(MessageLevel::Message));
- // append a paragraph/line
- auto workCursor = ui->fontPreview->textCursor();
- workCursor.movePosition(QTextCursor::End);
- workCursor.insertText(tr("[Test/INFO] A harmless message..."), format);
- workCursor.insertBlock();
- }
- {
- QTextCharFormat format(*defaultFormat);
- format.setForeground(m_colors->getFront(MessageLevel::Warning));
- // append a paragraph/line
- auto workCursor = ui->fontPreview->textCursor();
- workCursor.movePosition(QTextCursor::End);
- workCursor.insertText(tr("[Something/WARN] A not so spooky warning."), format);
- workCursor.insertBlock();
- }
+ int fontSize = ui->fontSizeBox->value();
+ QString fontFamily = ui->consoleFont->currentFont().family();
+ ui->fontPreview->clear();
+ defaultFormat->setFont(QFont(fontFamily, fontSize));
+ {
+ QTextCharFormat format(*defaultFormat);
+ format.setForeground(m_colors->getFront(MessageLevel::Error));
+ // append a paragraph/line
+ auto workCursor = ui->fontPreview->textCursor();
+ workCursor.movePosition(QTextCursor::End);
+ workCursor.insertText(tr("[Something/ERROR] A spooky error!"), format);
+ workCursor.insertBlock();
+ }
+ {
+ QTextCharFormat format(*defaultFormat);
+ format.setForeground(m_colors->getFront(MessageLevel::Message));
+ // append a paragraph/line
+ auto workCursor = ui->fontPreview->textCursor();
+ workCursor.movePosition(QTextCursor::End);
+ workCursor.insertText(tr("[Test/INFO] A harmless message..."), format);
+ workCursor.insertBlock();
+ }
+ {
+ QTextCharFormat format(*defaultFormat);
+ format.setForeground(m_colors->getFront(MessageLevel::Warning));
+ // append a paragraph/line
+ auto workCursor = ui->fontPreview->textCursor();
+ workCursor.movePosition(QTextCursor::End);
+ workCursor.insertText(tr("[Something/WARN] A not so spooky warning."), format);
+ workCursor.insertBlock();
+ }
}
diff --git a/application/pages/global/MultiMCPage.h b/application/pages/global/MultiMCPage.h
index d5194c0e..bf21305e 100644
--- a/application/pages/global/MultiMCPage.h
+++ b/application/pages/global/MultiMCPage.h
@@ -34,71 +34,71 @@ class MultiMCPage;
class MultiMCPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit MultiMCPage(QWidget *parent = 0);
- ~MultiMCPage();
-
- QString displayName() const override
- {
- return "MultiMC";
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("multimc");
- }
- QString id() const override
- {
- return "multimc-settings";
- }
- QString helpPage() const override
- {
- return "MultiMC-settings";
- }
- bool apply() override;
+ explicit MultiMCPage(QWidget *parent = 0);
+ ~MultiMCPage();
+
+ QString displayName() const override
+ {
+ return "MultiMC";
+ }
+ QIcon icon() const override
+ {
+ return MMC->getThemedIcon("multimc");
+ }
+ QString id() const override
+ {
+ return "multimc-settings";
+ }
+ QString helpPage() const override
+ {
+ return "MultiMC-settings";
+ }
+ bool apply() override;
private:
- void applySettings();
- void loadSettings();
+ void applySettings();
+ void loadSettings();
private
slots:
- void on_instDirBrowseBtn_clicked();
- void on_modsDirBrowseBtn_clicked();
- void on_iconsDirBrowseBtn_clicked();
+ void on_instDirBrowseBtn_clicked();
+ void on_modsDirBrowseBtn_clicked();
+ void on_iconsDirBrowseBtn_clicked();
- void languageIndexChanged(int index);
+ void languageIndexChanged(int index);
- /*!
- * Updates the list of update channels in the combo box.
- */
- void refreshUpdateChannelList();
+ /*!
+ * Updates the list of update channels in the combo box.
+ */
+ void refreshUpdateChannelList();
- /*!
- * Updates the channel description label.
- */
- void refreshUpdateChannelDesc();
+ /*!
+ * Updates the channel description label.
+ */
+ void refreshUpdateChannelDesc();
- /*!
- * Updates the font preview
- */
- void refreshFontPreview();
+ /*!
+ * Updates the font preview
+ */
+ void refreshFontPreview();
- void updateChannelSelectionChanged(int index);
+ void updateChannelSelectionChanged(int index);
private:
- Ui::MultiMCPage *ui;
+ Ui::MultiMCPage *ui;
- /*!
- * Stores the currently selected update channel.
- */
- QString m_currentUpdateChannel;
+ /*!
+ * Stores the currently selected update channel.
+ */
+ QString m_currentUpdateChannel;
- // default format for the font preview...
- QTextCharFormat *defaultFormat;
+ // default format for the font preview...
+ QTextCharFormat *defaultFormat;
- std::unique_ptr<LogColorCache> m_colors;
+ std::unique_ptr<LogColorCache> m_colors;
- std::shared_ptr<TranslationsModel> m_languageModel;
+ std::shared_ptr<TranslationsModel> m_languageModel;
};
diff --git a/application/pages/global/PackagesPage.cpp b/application/pages/global/PackagesPage.cpp
index 7cf1e3f5..b6a7887b 100644
--- a/application/pages/global/PackagesPage.cpp
+++ b/application/pages/global/PackagesPage.cpp
@@ -33,192 +33,192 @@ using namespace Meta;
static QString formatRequires(const VersionPtr &version)
{
- QStringList lines;
- auto & reqs = version->requires();
- auto iter = reqs.begin();
- while (iter != reqs.end())
- {
- auto &uid = iter->uid;
- auto &version = iter->equalsVersion;
- const QString readable = ENV.metadataIndex()->hasUid(uid) ? ENV.metadataIndex()->get(uid)->humanReadable() : uid;
- if(!version.isEmpty())
- {
- lines.append(QString("%1 (%2)").arg(readable, version));
- }
- else
- {
- lines.append(QString("%1").arg(readable));
- }
- iter++;
- }
- return lines.join('\n');
+ QStringList lines;
+ auto & reqs = version->requires();
+ auto iter = reqs.begin();
+ while (iter != reqs.end())
+ {
+ auto &uid = iter->uid;
+ auto &version = iter->equalsVersion;
+ const QString readable = ENV.metadataIndex()->hasUid(uid) ? ENV.metadataIndex()->get(uid)->humanReadable() : uid;
+ if(!version.isEmpty())
+ {
+ lines.append(QString("%1 (%2)").arg(readable, version));
+ }
+ else
+ {
+ lines.append(QString("%1").arg(readable));
+ }
+ iter++;
+ }
+ return lines.join('\n');
}
PackagesPage::PackagesPage(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::PackagesPage)
+ QWidget(parent),
+ ui(new Ui::PackagesPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
-
- m_fileProxy = new QSortFilterProxyModel(this);
- m_fileProxy->setSortRole(Qt::DisplayRole);
- m_fileProxy->setSortCaseSensitivity(Qt::CaseInsensitive);
- m_fileProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
- m_fileProxy->setFilterRole(Qt::DisplayRole);
- m_fileProxy->setFilterKeyColumn(0);
- m_fileProxy->sort(0);
- m_fileProxy->setSourceModel(ENV.metadataIndex().get());
- ui->indexView->setModel(m_fileProxy);
-
- m_filterProxy = new QSortFilterProxyModel(this);
- m_filterProxy->setSortRole(VersionList::SortRole);
- m_filterProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
- m_filterProxy->setFilterRole(Qt::DisplayRole);
- m_filterProxy->setFilterKeyColumn(0);
- m_filterProxy->sort(0, Qt::DescendingOrder);
- ui->versionsView->setModel(m_filterProxy);
-
- m_versionProxy = new VersionProxyModel(this);
- m_filterProxy->setSourceModel(m_versionProxy);
-
- connect(ui->indexView->selectionModel(), &QItemSelectionModel::currentChanged, this, &PackagesPage::updateCurrentVersionList);
- connect(ui->versionsView->selectionModel(), &QItemSelectionModel::currentChanged, this, &PackagesPage::updateVersion);
- connect(m_filterProxy, &QSortFilterProxyModel::dataChanged, this, &PackagesPage::versionListDataChanged);
-
- updateCurrentVersionList(QModelIndex());
- updateVersion();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+
+ m_fileProxy = new QSortFilterProxyModel(this);
+ m_fileProxy->setSortRole(Qt::DisplayRole);
+ m_fileProxy->setSortCaseSensitivity(Qt::CaseInsensitive);
+ m_fileProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ m_fileProxy->setFilterRole(Qt::DisplayRole);
+ m_fileProxy->setFilterKeyColumn(0);
+ m_fileProxy->sort(0);
+ m_fileProxy->setSourceModel(ENV.metadataIndex().get());
+ ui->indexView->setModel(m_fileProxy);
+
+ m_filterProxy = new QSortFilterProxyModel(this);
+ m_filterProxy->setSortRole(VersionList::SortRole);
+ m_filterProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ m_filterProxy->setFilterRole(Qt::DisplayRole);
+ m_filterProxy->setFilterKeyColumn(0);
+ m_filterProxy->sort(0, Qt::DescendingOrder);
+ ui->versionsView->setModel(m_filterProxy);
+
+ m_versionProxy = new VersionProxyModel(this);
+ m_filterProxy->setSourceModel(m_versionProxy);
+
+ connect(ui->indexView->selectionModel(), &QItemSelectionModel::currentChanged, this, &PackagesPage::updateCurrentVersionList);
+ connect(ui->versionsView->selectionModel(), &QItemSelectionModel::currentChanged, this, &PackagesPage::updateVersion);
+ connect(m_filterProxy, &QSortFilterProxyModel::dataChanged, this, &PackagesPage::versionListDataChanged);
+
+ updateCurrentVersionList(QModelIndex());
+ updateVersion();
}
PackagesPage::~PackagesPage()
{
- delete ui;
+ delete ui;
}
QIcon PackagesPage::icon() const
{
- return MMC->getThemedIcon("packages");
+ return MMC->getThemedIcon("packages");
}
void PackagesPage::on_refreshIndexBtn_clicked()
{
- ENV.metadataIndex()->load(Net::Mode::Online);
+ ENV.metadataIndex()->load(Net::Mode::Online);
}
void PackagesPage::on_refreshFileBtn_clicked()
{
- VersionListPtr list = ui->indexView->currentIndex().data(Index::ListPtrRole).value<VersionListPtr>();
- if (!list)
- {
- return;
- }
- list->load(Net::Mode::Online);
+ VersionListPtr list = ui->indexView->currentIndex().data(Index::ListPtrRole).value<VersionListPtr>();
+ if (!list)
+ {
+ return;
+ }
+ list->load(Net::Mode::Online);
}
void PackagesPage::on_refreshVersionBtn_clicked()
{
- VersionPtr version = ui->versionsView->currentIndex().data(VersionList::VersionPtrRole).value<VersionPtr>();
- if (!version)
- {
- return;
- }
- version->load(Net::Mode::Online);
+ VersionPtr version = ui->versionsView->currentIndex().data(VersionList::VersionPtrRole).value<VersionPtr>();
+ if (!version)
+ {
+ return;
+ }
+ version->load(Net::Mode::Online);
}
void PackagesPage::on_fileSearchEdit_textChanged(const QString &search)
{
- if (search.isEmpty())
- {
- m_fileProxy->setFilterFixedString(QString());
- }
- else
- {
- QStringList parts = search.split(' ');
- std::transform(parts.begin(), parts.end(), parts.begin(), &QRegularExpression::escape);
- m_fileProxy->setFilterRegExp(".*" + parts.join(".*") + ".*");
- }
+ if (search.isEmpty())
+ {
+ m_fileProxy->setFilterFixedString(QString());
+ }
+ else
+ {
+ QStringList parts = search.split(' ');
+ std::transform(parts.begin(), parts.end(), parts.begin(), &QRegularExpression::escape);
+ m_fileProxy->setFilterRegExp(".*" + parts.join(".*") + ".*");
+ }
}
void PackagesPage::on_versionSearchEdit_textChanged(const QString &search)
{
- if (search.isEmpty())
- {
- m_filterProxy->setFilterFixedString(QString());
- }
- else
- {
- QStringList parts = search.split(' ');
- std::transform(parts.begin(), parts.end(), parts.begin(), &QRegularExpression::escape);
- m_filterProxy->setFilterRegExp(".*" + parts.join(".*") + ".*");
- }
+ if (search.isEmpty())
+ {
+ m_filterProxy->setFilterFixedString(QString());
+ }
+ else
+ {
+ QStringList parts = search.split(' ');
+ std::transform(parts.begin(), parts.end(), parts.begin(), &QRegularExpression::escape);
+ m_filterProxy->setFilterRegExp(".*" + parts.join(".*") + ".*");
+ }
}
void PackagesPage::updateCurrentVersionList(const QModelIndex &index)
{
- if (index.isValid())
- {
- VersionListPtr list = index.data(Index::ListPtrRole).value<VersionListPtr>();
- ui->versionsBox->setEnabled(true);
- ui->refreshFileBtn->setEnabled(true);
- ui->fileUidLabel->setEnabled(true);
- ui->fileUid->setText(list->uid());
- ui->fileNameLabel->setEnabled(true);
- ui->fileName->setText(list->name());
- m_versionProxy->setSourceModel(list.get());
- ui->refreshFileBtn->setText(tr("Refresh %1").arg(list->humanReadable()));
- list->load(Net::Mode::Offline);
- }
- else
- {
- ui->versionsBox->setEnabled(false);
- ui->refreshFileBtn->setEnabled(false);
- ui->fileUidLabel->setEnabled(false);
- ui->fileUid->clear();
- ui->fileNameLabel->setEnabled(false);
- ui->fileName->clear();
- m_versionProxy->setSourceModel(nullptr);
- ui->refreshFileBtn->setText(tr("Refresh"));
- }
+ if (index.isValid())
+ {
+ VersionListPtr list = index.data(Index::ListPtrRole).value<VersionListPtr>();
+ ui->versionsBox->setEnabled(true);
+ ui->refreshFileBtn->setEnabled(true);
+ ui->fileUidLabel->setEnabled(true);
+ ui->fileUid->setText(list->uid());
+ ui->fileNameLabel->setEnabled(true);
+ ui->fileName->setText(list->name());
+ m_versionProxy->setSourceModel(list.get());
+ ui->refreshFileBtn->setText(tr("Refresh %1").arg(list->humanReadable()));
+ list->load(Net::Mode::Offline);
+ }
+ else
+ {
+ ui->versionsBox->setEnabled(false);
+ ui->refreshFileBtn->setEnabled(false);
+ ui->fileUidLabel->setEnabled(false);
+ ui->fileUid->clear();
+ ui->fileNameLabel->setEnabled(false);
+ ui->fileName->clear();
+ m_versionProxy->setSourceModel(nullptr);
+ ui->refreshFileBtn->setText(tr("Refresh"));
+ }
}
void PackagesPage::versionListDataChanged(const QModelIndex &tl, const QModelIndex &br)
{
- if (QItemSelection(tl, br).contains(ui->versionsView->currentIndex()))
- {
- updateVersion();
- }
+ if (QItemSelection(tl, br).contains(ui->versionsView->currentIndex()))
+ {
+ updateVersion();
+ }
}
void PackagesPage::updateVersion()
{
- VersionPtr version = std::dynamic_pointer_cast<Version>(
- ui->versionsView->currentIndex().data(VersionList::VersionPointerRole).value<BaseVersionPtr>());
- if (version)
- {
- ui->refreshVersionBtn->setEnabled(true);
- ui->versionVersionLabel->setEnabled(true);
- ui->versionVersion->setText(version->version());
- ui->versionTimeLabel->setEnabled(true);
- ui->versionTime->setText(version->time().toString("yyyy-MM-dd HH:mm"));
- ui->versionTypeLabel->setEnabled(true);
- ui->versionType->setText(version->type());
- ui->versionRequiresLabel->setEnabled(true);
- ui->versionRequires->setText(formatRequires(version));
- ui->refreshVersionBtn->setText(tr("Refresh %1").arg(version->version()));
- }
- else
- {
- ui->refreshVersionBtn->setEnabled(false);
- ui->versionVersionLabel->setEnabled(false);
- ui->versionVersion->clear();
- ui->versionTimeLabel->setEnabled(false);
- ui->versionTime->clear();
- ui->versionTypeLabel->setEnabled(false);
- ui->versionType->clear();
- ui->versionRequiresLabel->setEnabled(false);
- ui->versionRequires->clear();
- ui->refreshVersionBtn->setText(tr("Refresh"));
- }
+ VersionPtr version = std::dynamic_pointer_cast<Version>(
+ ui->versionsView->currentIndex().data(VersionList::VersionPointerRole).value<BaseVersionPtr>());
+ if (version)
+ {
+ ui->refreshVersionBtn->setEnabled(true);
+ ui->versionVersionLabel->setEnabled(true);
+ ui->versionVersion->setText(version->version());
+ ui->versionTimeLabel->setEnabled(true);
+ ui->versionTime->setText(version->time().toString("yyyy-MM-dd HH:mm"));
+ ui->versionTypeLabel->setEnabled(true);
+ ui->versionType->setText(version->type());
+ ui->versionRequiresLabel->setEnabled(true);
+ ui->versionRequires->setText(formatRequires(version));
+ ui->refreshVersionBtn->setText(tr("Refresh %1").arg(version->version()));
+ }
+ else
+ {
+ ui->refreshVersionBtn->setEnabled(false);
+ ui->versionVersionLabel->setEnabled(false);
+ ui->versionVersion->clear();
+ ui->versionTimeLabel->setEnabled(false);
+ ui->versionTime->clear();
+ ui->versionTypeLabel->setEnabled(false);
+ ui->versionType->clear();
+ ui->versionRequiresLabel->setEnabled(false);
+ ui->versionRequires->clear();
+ ui->refreshVersionBtn->setText(tr("Refresh"));
+ }
}
void PackagesPage::openedImpl()
{
- ENV.metadataIndex()->load(Net::Mode::Offline);
+ ENV.metadataIndex()->load(Net::Mode::Offline);
}
diff --git a/application/pages/global/PackagesPage.h b/application/pages/global/PackagesPage.h
index ad155d9e..c8aa6da6 100644
--- a/application/pages/global/PackagesPage.h
+++ b/application/pages/global/PackagesPage.h
@@ -28,30 +28,30 @@ class VersionProxyModel;
class PackagesPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit PackagesPage(QWidget *parent = 0);
- ~PackagesPage();
+ explicit PackagesPage(QWidget *parent = 0);
+ ~PackagesPage();
- QString id() const override { return "packages-global"; }
- QString displayName() const override { return tr("Packages"); }
- QIcon icon() const override;
- void openedImpl() override;
+ QString id() const override { return "packages-global"; }
+ QString displayName() const override { return tr("Packages"); }
+ QIcon icon() const override;
+ void openedImpl() override;
private slots:
- void on_refreshIndexBtn_clicked();
- void on_refreshFileBtn_clicked();
- void on_refreshVersionBtn_clicked();
- void on_fileSearchEdit_textChanged(const QString &search);
- void on_versionSearchEdit_textChanged(const QString &search);
- void updateCurrentVersionList(const QModelIndex &index);
- void versionListDataChanged(const QModelIndex &tl, const QModelIndex &br);
+ void on_refreshIndexBtn_clicked();
+ void on_refreshFileBtn_clicked();
+ void on_refreshVersionBtn_clicked();
+ void on_fileSearchEdit_textChanged(const QString &search);
+ void on_versionSearchEdit_textChanged(const QString &search);
+ void updateCurrentVersionList(const QModelIndex &index);
+ void versionListDataChanged(const QModelIndex &tl, const QModelIndex &br);
private:
- Ui::PackagesPage *ui;
- QSortFilterProxyModel *m_fileProxy;
- QSortFilterProxyModel *m_filterProxy;
- VersionProxyModel *m_versionProxy;
+ Ui::PackagesPage *ui;
+ QSortFilterProxyModel *m_fileProxy;
+ QSortFilterProxyModel *m_filterProxy;
+ VersionProxyModel *m_versionProxy;
- void updateVersion();
+ void updateVersion();
};
diff --git a/application/pages/global/PasteEEPage.cpp b/application/pages/global/PasteEEPage.cpp
index 09d36cea..b144c832 100644
--- a/application/pages/global/PasteEEPage.cpp
+++ b/application/pages/global/PasteEEPage.cpp
@@ -26,56 +26,56 @@
#include "MultiMC.h"
PasteEEPage::PasteEEPage(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::PasteEEPage)
+ QWidget(parent),
+ ui(new Ui::PasteEEPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();\
- connect(ui->customAPIkeyEdit, &QLineEdit::textEdited, this, &PasteEEPage::textEdited);
- loadSettings();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();\
+ connect(ui->customAPIkeyEdit, &QLineEdit::textEdited, this, &PasteEEPage::textEdited);
+ loadSettings();
}
PasteEEPage::~PasteEEPage()
{
- delete ui;
+ delete ui;
}
void PasteEEPage::loadSettings()
{
- auto s = MMC->settings();
- QString keyToUse = s->get("PasteEEAPIKey").toString();
- if(keyToUse == "multimc")
- {
- ui->multimcButton->setChecked(true);
- }
- else
- {
- ui->customButton->setChecked(true);
- ui->customAPIkeyEdit->setText(keyToUse);
- }
+ auto s = MMC->settings();
+ QString keyToUse = s->get("PasteEEAPIKey").toString();
+ if(keyToUse == "multimc")
+ {
+ ui->multimcButton->setChecked(true);
+ }
+ else
+ {
+ ui->customButton->setChecked(true);
+ ui->customAPIkeyEdit->setText(keyToUse);
+ }
}
void PasteEEPage::applySettings()
{
- auto s = MMC->settings();
+ auto s = MMC->settings();
- QString pasteKeyToUse;
- if (ui->customButton->isChecked())
- pasteKeyToUse = ui->customAPIkeyEdit->text();
- else
- {
- pasteKeyToUse = "multimc";
- }
- s->set("PasteEEAPIKey", pasteKeyToUse);
+ QString pasteKeyToUse;
+ if (ui->customButton->isChecked())
+ pasteKeyToUse = ui->customAPIkeyEdit->text();
+ else
+ {
+ pasteKeyToUse = "multimc";
+ }
+ s->set("PasteEEAPIKey", pasteKeyToUse);
}
bool PasteEEPage::apply()
{
- applySettings();
- return true;
+ applySettings();
+ return true;
}
void PasteEEPage::textEdited(const QString& text)
{
- ui->customButton->setChecked(true);
+ ui->customButton->setChecked(true);
}
diff --git a/application/pages/global/PasteEEPage.h b/application/pages/global/PasteEEPage.h
index 1b152577..5d64d567 100644
--- a/application/pages/global/PasteEEPage.h
+++ b/application/pages/global/PasteEEPage.h
@@ -26,37 +26,37 @@ class PasteEEPage;
class PasteEEPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit PasteEEPage(QWidget *parent = 0);
- ~PasteEEPage();
-
- QString displayName() const override
- {
- return tr("Log Upload");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("log");
- }
- QString id() const override
- {
- return "log-upload";
- }
- QString helpPage() const override
- {
- return "Log-Upload";
- }
- virtual bool apply() override;
+ explicit PasteEEPage(QWidget *parent = 0);
+ ~PasteEEPage();
+
+ QString displayName() const override
+ {
+ return tr("Log Upload");
+ }
+ QIcon icon() const override
+ {
+ return MMC->getThemedIcon("log");
+ }
+ QString id() const override
+ {
+ return "log-upload";
+ }
+ QString helpPage() const override
+ {
+ return "Log-Upload";
+ }
+ virtual bool apply() override;
private:
- void loadSettings();
- void applySettings();
+ void loadSettings();
+ void applySettings();
private slots:
- void textEdited(const QString &text);
+ void textEdited(const QString &text);
private:
- Ui::PasteEEPage *ui;
+ Ui::PasteEEPage *ui;
};
diff --git a/application/pages/global/ProxyPage.cpp b/application/pages/global/ProxyPage.cpp
index e9882a85..6dbd0a5d 100644
--- a/application/pages/global/ProxyPage.cpp
+++ b/application/pages/global/ProxyPage.cpp
@@ -23,75 +23,75 @@
ProxyPage::ProxyPage(QWidget *parent) : QWidget(parent), ui(new Ui::ProxyPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- loadSettings();
- updateCheckboxStuff();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ loadSettings();
+ updateCheckboxStuff();
- connect(ui->proxyGroup, SIGNAL(buttonClicked(int)), SLOT(proxyChanged(int)));
+ connect(ui->proxyGroup, SIGNAL(buttonClicked(int)), SLOT(proxyChanged(int)));
}
ProxyPage::~ProxyPage()
{
- delete ui;
+ delete ui;
}
bool ProxyPage::apply()
{
- applySettings();
- return true;
+ applySettings();
+ return true;
}
void ProxyPage::updateCheckboxStuff()
{
- ui->proxyAddrBox->setEnabled(!ui->proxyNoneBtn->isChecked() &&
- !ui->proxyDefaultBtn->isChecked());
- ui->proxyAuthBox->setEnabled(!ui->proxyNoneBtn->isChecked() &&
- !ui->proxyDefaultBtn->isChecked());
+ ui->proxyAddrBox->setEnabled(!ui->proxyNoneBtn->isChecked() &&
+ !ui->proxyDefaultBtn->isChecked());
+ ui->proxyAuthBox->setEnabled(!ui->proxyNoneBtn->isChecked() &&
+ !ui->proxyDefaultBtn->isChecked());
}
void ProxyPage::proxyChanged(int)
{
- updateCheckboxStuff();
+ updateCheckboxStuff();
}
void ProxyPage::applySettings()
{
- auto s = MMC->settings();
+ auto s = MMC->settings();
- // Proxy
- QString proxyType = "None";
- if (ui->proxyDefaultBtn->isChecked())
- proxyType = "Default";
- else if (ui->proxyNoneBtn->isChecked())
- proxyType = "None";
- else if (ui->proxySOCKS5Btn->isChecked())
- proxyType = "SOCKS5";
- else if (ui->proxyHTTPBtn->isChecked())
- proxyType = "HTTP";
+ // Proxy
+ QString proxyType = "None";
+ if (ui->proxyDefaultBtn->isChecked())
+ proxyType = "Default";
+ else if (ui->proxyNoneBtn->isChecked())
+ proxyType = "None";
+ else if (ui->proxySOCKS5Btn->isChecked())
+ proxyType = "SOCKS5";
+ else if (ui->proxyHTTPBtn->isChecked())
+ proxyType = "HTTP";
- s->set("ProxyType", proxyType);
- s->set("ProxyAddr", ui->proxyAddrEdit->text());
- s->set("ProxyPort", ui->proxyPortEdit->value());
- s->set("ProxyUser", ui->proxyUserEdit->text());
- s->set("ProxyPass", ui->proxyPassEdit->text());
+ s->set("ProxyType", proxyType);
+ s->set("ProxyAddr", ui->proxyAddrEdit->text());
+ s->set("ProxyPort", ui->proxyPortEdit->value());
+ s->set("ProxyUser", ui->proxyUserEdit->text());
+ s->set("ProxyPass", ui->proxyPassEdit->text());
}
void ProxyPage::loadSettings()
{
- auto s = MMC->settings();
- // Proxy
- QString proxyType = s->get("ProxyType").toString();
- if (proxyType == "Default")
- ui->proxyDefaultBtn->setChecked(true);
- else if (proxyType == "None")
- ui->proxyNoneBtn->setChecked(true);
- else if (proxyType == "SOCKS5")
- ui->proxySOCKS5Btn->setChecked(true);
- else if (proxyType == "HTTP")
- ui->proxyHTTPBtn->setChecked(true);
+ auto s = MMC->settings();
+ // Proxy
+ QString proxyType = s->get("ProxyType").toString();
+ if (proxyType == "Default")
+ ui->proxyDefaultBtn->setChecked(true);
+ else if (proxyType == "None")
+ ui->proxyNoneBtn->setChecked(true);
+ else if (proxyType == "SOCKS5")
+ ui->proxySOCKS5Btn->setChecked(true);
+ else if (proxyType == "HTTP")
+ ui->proxyHTTPBtn->setChecked(true);
- ui->proxyAddrEdit->setText(s->get("ProxyAddr").toString());
- ui->proxyPortEdit->setValue(s->get("ProxyPort").value<qint16>());
- ui->proxyUserEdit->setText(s->get("ProxyUser").toString());
- ui->proxyPassEdit->setText(s->get("ProxyPass").toString());
+ ui->proxyAddrEdit->setText(s->get("ProxyAddr").toString());
+ ui->proxyPortEdit->setValue(s->get("ProxyPort").value<qint16>());
+ ui->proxyUserEdit->setText(s->get("ProxyUser").toString());
+ ui->proxyPassEdit->setText(s->get("ProxyPass").toString());
}
diff --git a/application/pages/global/ProxyPage.h b/application/pages/global/ProxyPage.h
index 565c2857..47b3004e 100644
--- a/application/pages/global/ProxyPage.h
+++ b/application/pages/global/ProxyPage.h
@@ -28,39 +28,39 @@ class ProxyPage;
class ProxyPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ProxyPage(QWidget *parent = 0);
- ~ProxyPage();
+ explicit ProxyPage(QWidget *parent = 0);
+ ~ProxyPage();
- QString displayName() const override
- {
- return tr("Proxy");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("proxy");
- }
- QString id() const override
- {
- return "proxy-settings";
- }
- QString helpPage() const override
- {
- return "Proxy-settings";
- }
- bool apply() override;
+ QString displayName() const override
+ {
+ return tr("Proxy");
+ }
+ QIcon icon() const override
+ {
+ return MMC->getThemedIcon("proxy");
+ }
+ QString id() const override
+ {
+ return "proxy-settings";
+ }
+ QString helpPage() const override
+ {
+ return "Proxy-settings";
+ }
+ bool apply() override;
private:
- void updateCheckboxStuff();
- void applySettings();
- void loadSettings();
+ void updateCheckboxStuff();
+ void applySettings();
+ void loadSettings();
private
slots:
- void proxyChanged(int);
+ void proxyChanged(int);
private:
- Ui::ProxyPage *ui;
+ Ui::ProxyPage *ui;
};
diff --git a/application/pages/instance/InstanceSettingsPage.cpp b/application/pages/instance/InstanceSettingsPage.cpp
index 71e90a32..0704ffc5 100644
--- a/application/pages/instance/InstanceSettingsPage.cpp
+++ b/application/pages/instance/InstanceSettingsPage.cpp
@@ -15,237 +15,237 @@
#include <widgets/CustomCommands.h>
InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent)
- : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst)
+ : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst)
{
- m_settings = inst->settings();
- ui->setupUi(this);
- auto sysMB = Sys::getSystemRam() / Sys::megabyte;
- ui->maxMemSpinBox->setMaximum(sysMB);
- loadSettings();
+ m_settings = inst->settings();
+ ui->setupUi(this);
+ auto sysMB = Sys::getSystemRam() / Sys::megabyte;
+ ui->maxMemSpinBox->setMaximum(sysMB);
+ loadSettings();
}
bool InstanceSettingsPage::shouldDisplay() const
{
- return !m_instance->isRunning();
+ return !m_instance->isRunning();
}
InstanceSettingsPage::~InstanceSettingsPage()
{
- delete ui;
+ delete ui;
}
bool InstanceSettingsPage::apply()
{
- applySettings();
- return true;
+ applySettings();
+ return true;
}
void InstanceSettingsPage::applySettings()
{
- SettingsObject::Lock lock(m_settings);
-
- // Console
- bool console = ui->consoleSettingsBox->isChecked();
- m_settings->set("OverrideConsole", console);
- if (console)
- {
- m_settings->set("ShowConsole", ui->showConsoleCheck->isChecked());
- m_settings->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
- m_settings->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked());
- }
- else
- {
- m_settings->reset("ShowConsole");
- m_settings->reset("AutoCloseConsole");
- m_settings->reset("ShowConsoleOnError");
- }
-
- // Window Size
- bool window = ui->windowSizeGroupBox->isChecked();
- m_settings->set("OverrideWindow", window);
- if (window)
- {
- m_settings->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
- m_settings->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
- m_settings->set("MinecraftWinHeight", ui->windowHeightSpinBox->value());
- }
- else
- {
- m_settings->reset("LaunchMaximized");
- m_settings->reset("MinecraftWinWidth");
- m_settings->reset("MinecraftWinHeight");
- }
-
- // Memory
- bool memory = ui->memoryGroupBox->isChecked();
- m_settings->set("OverrideMemory", memory);
- if (memory)
- {
- int min = ui->minMemSpinBox->value();
- int max = ui->maxMemSpinBox->value();
- if(min < max)
- {
- m_settings->set("MinMemAlloc", min);
- m_settings->set("MaxMemAlloc", max);
- }
- else
- {
- m_settings->set("MinMemAlloc", max);
- m_settings->set("MaxMemAlloc", min);
- }
- m_settings->set("PermGen", ui->permGenSpinBox->value());
- }
- else
- {
- m_settings->reset("MinMemAlloc");
- m_settings->reset("MaxMemAlloc");
- m_settings->reset("PermGen");
- }
-
- // Java Install Settings
- bool javaInstall = ui->javaSettingsGroupBox->isChecked();
- m_settings->set("OverrideJavaLocation", javaInstall);
- if (javaInstall)
- {
- m_settings->set("JavaPath", ui->javaPathTextBox->text());
- }
- else
- {
- m_settings->reset("JavaPath");
- }
-
- // Java arguments
- bool javaArgs = ui->javaArgumentsGroupBox->isChecked();
- m_settings->set("OverrideJavaArgs", javaArgs);
- if(javaArgs)
- {
- m_settings->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " "));
- JavaCommon::checkJVMArgs(m_settings->get("JvmArgs").toString(), this->parentWidget());
- }
- else
- {
- m_settings->reset("JvmArgs");
- }
-
- // old generic 'override both' is removed.
- m_settings->reset("OverrideJava");
-
- // Custom Commands
- bool custcmd = ui->customCommands->checked();
- m_settings->set("OverrideCommands", custcmd);
- if (custcmd)
- {
- m_settings->set("PreLaunchCommand", ui->customCommands->prelaunchCommand());
- m_settings->set("WrapperCommand", ui->customCommands->wrapperCommand());
- m_settings->set("PostExitCommand", ui->customCommands->postexitCommand());
- }
- else
- {
- m_settings->reset("PreLaunchCommand");
- m_settings->reset("WrapperCommand");
- m_settings->reset("PostExitCommand");
- }
+ SettingsObject::Lock lock(m_settings);
+
+ // Console
+ bool console = ui->consoleSettingsBox->isChecked();
+ m_settings->set("OverrideConsole", console);
+ if (console)
+ {
+ m_settings->set("ShowConsole", ui->showConsoleCheck->isChecked());
+ m_settings->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
+ m_settings->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked());
+ }
+ else
+ {
+ m_settings->reset("ShowConsole");
+ m_settings->reset("AutoCloseConsole");
+ m_settings->reset("ShowConsoleOnError");
+ }
+
+ // Window Size
+ bool window = ui->windowSizeGroupBox->isChecked();
+ m_settings->set("OverrideWindow", window);
+ if (window)
+ {
+ m_settings->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
+ m_settings->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
+ m_settings->set("MinecraftWinHeight", ui->windowHeightSpinBox->value());
+ }
+ else
+ {
+ m_settings->reset("LaunchMaximized");
+ m_settings->reset("MinecraftWinWidth");
+ m_settings->reset("MinecraftWinHeight");
+ }
+
+ // Memory
+ bool memory = ui->memoryGroupBox->isChecked();
+ m_settings->set("OverrideMemory", memory);
+ if (memory)
+ {
+ int min = ui->minMemSpinBox->value();
+ int max = ui->maxMemSpinBox->value();
+ if(min < max)
+ {
+ m_settings->set("MinMemAlloc", min);
+ m_settings->set("MaxMemAlloc", max);
+ }
+ else
+ {
+ m_settings->set("MinMemAlloc", max);
+ m_settings->set("MaxMemAlloc", min);
+ }
+ m_settings->set("PermGen", ui->permGenSpinBox->value());
+ }
+ else
+ {
+ m_settings->reset("MinMemAlloc");
+ m_settings->reset("MaxMemAlloc");
+ m_settings->reset("PermGen");
+ }
+
+ // Java Install Settings
+ bool javaInstall = ui->javaSettingsGroupBox->isChecked();
+ m_settings->set("OverrideJavaLocation", javaInstall);
+ if (javaInstall)
+ {
+ m_settings->set("JavaPath", ui->javaPathTextBox->text());
+ }
+ else
+ {
+ m_settings->reset("JavaPath");
+ }
+
+ // Java arguments
+ bool javaArgs = ui->javaArgumentsGroupBox->isChecked();
+ m_settings->set("OverrideJavaArgs", javaArgs);
+ if(javaArgs)
+ {
+ m_settings->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " "));
+ JavaCommon::checkJVMArgs(m_settings->get("JvmArgs").toString(), this->parentWidget());
+ }
+ else
+ {
+ m_settings->reset("JvmArgs");
+ }
+
+ // old generic 'override both' is removed.
+ m_settings->reset("OverrideJava");
+
+ // Custom Commands
+ bool custcmd = ui->customCommands->checked();
+ m_settings->set("OverrideCommands", custcmd);
+ if (custcmd)
+ {
+ m_settings->set("PreLaunchCommand", ui->customCommands->prelaunchCommand());
+ m_settings->set("WrapperCommand", ui->customCommands->wrapperCommand());
+ m_settings->set("PostExitCommand", ui->customCommands->postexitCommand());
+ }
+ else
+ {
+ m_settings->reset("PreLaunchCommand");
+ m_settings->reset("WrapperCommand");
+ m_settings->reset("PostExitCommand");
+ }
}
void InstanceSettingsPage::loadSettings()
{
- // Console
- ui->consoleSettingsBox->setChecked(m_settings->get("OverrideConsole").toBool());
- ui->showConsoleCheck->setChecked(m_settings->get("ShowConsole").toBool());
- ui->autoCloseConsoleCheck->setChecked(m_settings->get("AutoCloseConsole").toBool());
- ui->showConsoleErrorCheck->setChecked(m_settings->get("ShowConsoleOnError").toBool());
-
- // Window Size
- ui->windowSizeGroupBox->setChecked(m_settings->get("OverrideWindow").toBool());
- ui->maximizedCheckBox->setChecked(m_settings->get("LaunchMaximized").toBool());
- ui->windowWidthSpinBox->setValue(m_settings->get("MinecraftWinWidth").toInt());
- ui->windowHeightSpinBox->setValue(m_settings->get("MinecraftWinHeight").toInt());
-
- // Memory
- ui->memoryGroupBox->setChecked(m_settings->get("OverrideMemory").toBool());
- int min = m_settings->get("MinMemAlloc").toInt();
- int max = m_settings->get("MaxMemAlloc").toInt();
- if(min < max)
- {
- ui->minMemSpinBox->setValue(min);
- ui->maxMemSpinBox->setValue(max);
- }
- else
- {
- ui->minMemSpinBox->setValue(max);
- ui->maxMemSpinBox->setValue(min);
- }
- ui->permGenSpinBox->setValue(m_settings->get("PermGen").toInt());
-
- // Java Settings
- bool overrideJava = m_settings->get("OverrideJava").toBool();
- bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava;
- bool overrideArgs = m_settings->get("OverrideJavaArgs").toBool() || overrideJava;
-
- ui->javaSettingsGroupBox->setChecked(overrideLocation);
- ui->javaPathTextBox->setText(m_settings->get("JavaPath").toString());
-
- ui->javaArgumentsGroupBox->setChecked(overrideArgs);
- ui->jvmArgsTextBox->setPlainText(m_settings->get("JvmArgs").toString());
-
- // Custom commands
- ui->customCommands->initialize(
- true,
- m_settings->get("OverrideCommands").toBool(),
- m_settings->get("PreLaunchCommand").toString(),
- m_settings->get("WrapperCommand").toString(),
- m_settings->get("PostExitCommand").toString()
- );
+ // Console
+ ui->consoleSettingsBox->setChecked(m_settings->get("OverrideConsole").toBool());
+ ui->showConsoleCheck->setChecked(m_settings->get("ShowConsole").toBool());
+ ui->autoCloseConsoleCheck->setChecked(m_settings->get("AutoCloseConsole").toBool());
+ ui->showConsoleErrorCheck->setChecked(m_settings->get("ShowConsoleOnError").toBool());
+
+ // Window Size
+ ui->windowSizeGroupBox->setChecked(m_settings->get("OverrideWindow").toBool());
+ ui->maximizedCheckBox->setChecked(m_settings->get("LaunchMaximized").toBool());
+ ui->windowWidthSpinBox->setValue(m_settings->get("MinecraftWinWidth").toInt());
+ ui->windowHeightSpinBox->setValue(m_settings->get("MinecraftWinHeight").toInt());
+
+ // Memory
+ ui->memoryGroupBox->setChecked(m_settings->get("OverrideMemory").toBool());
+ int min = m_settings->get("MinMemAlloc").toInt();
+ int max = m_settings->get("MaxMemAlloc").toInt();
+ if(min < max)
+ {
+ ui->minMemSpinBox->setValue(min);
+ ui->maxMemSpinBox->setValue(max);
+ }
+ else
+ {
+ ui->minMemSpinBox->setValue(max);
+ ui->maxMemSpinBox->setValue(min);
+ }
+ ui->permGenSpinBox->setValue(m_settings->get("PermGen").toInt());
+
+ // Java Settings
+ bool overrideJava = m_settings->get("OverrideJava").toBool();
+ bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava;
+ bool overrideArgs = m_settings->get("OverrideJavaArgs").toBool() || overrideJava;
+
+ ui->javaSettingsGroupBox->setChecked(overrideLocation);
+ ui->javaPathTextBox->setText(m_settings->get("JavaPath").toString());
+
+ ui->javaArgumentsGroupBox->setChecked(overrideArgs);
+ ui->jvmArgsTextBox->setPlainText(m_settings->get("JvmArgs").toString());
+
+ // Custom commands
+ ui->customCommands->initialize(
+ true,
+ m_settings->get("OverrideCommands").toBool(),
+ m_settings->get("PreLaunchCommand").toString(),
+ m_settings->get("WrapperCommand").toString(),
+ m_settings->get("PostExitCommand").toString()
+ );
}
void InstanceSettingsPage::on_javaDetectBtn_clicked()
{
- JavaInstallPtr java;
+ JavaInstallPtr java;
- VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true);
- vselect.setResizeOn(2);
- vselect.exec();
+ VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true);
+ vselect.setResizeOn(2);
+ vselect.exec();
- if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
- {
- java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
- ui->javaPathTextBox->setText(java->path);
- }
+ if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
+ {
+ java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
+ ui->javaPathTextBox->setText(java->path);
+ }
}
void InstanceSettingsPage::on_javaBrowseBtn_clicked()
{
- QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if(raw_path.isEmpty())
- {
- return;
- }
- QString cooked_path = FS::NormalizePath(raw_path);
-
- QFileInfo javaInfo(cooked_path);;
- if(!javaInfo.exists() || !javaInfo.isExecutable())
- {
- return;
- }
- ui->javaPathTextBox->setText(cooked_path);
+ QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if(raw_path.isEmpty())
+ {
+ return;
+ }
+ QString cooked_path = FS::NormalizePath(raw_path);
+
+ QFileInfo javaInfo(cooked_path);;
+ if(!javaInfo.exists() || !javaInfo.isExecutable())
+ {
+ return;
+ }
+ ui->javaPathTextBox->setText(cooked_path);
}
void InstanceSettingsPage::on_javaTestBtn_clicked()
{
- if(checker)
- {
- return;
- }
- checker.reset(new JavaCommon::TestCheck(
- this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "),
- ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
- connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
- checker->run();
+ if(checker)
+ {
+ return;
+ }
+ checker.reset(new JavaCommon::TestCheck(
+ this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "),
+ ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
+ connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
+ checker->run();
}
void InstanceSettingsPage::checkerFinished()
{
- checker.reset();
+ checker.reset();
}
diff --git a/application/pages/instance/InstanceSettingsPage.h b/application/pages/instance/InstanceSettingsPage.h
index c5d7d3b6..cc35732e 100644
--- a/application/pages/instance/InstanceSettingsPage.h
+++ b/application/pages/instance/InstanceSettingsPage.h
@@ -32,43 +32,43 @@ class InstanceSettingsPage;
class InstanceSettingsPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0);
- virtual ~InstanceSettingsPage();
- virtual QString displayName() const override
- {
- return tr("Settings");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("instance-settings");
- }
- virtual QString id() const override
- {
- return "settings";
- }
- virtual bool apply() override;
- virtual QString helpPage() const override
- {
- return "Instance-settings";
- }
- virtual bool shouldDisplay() const override;
+ explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0);
+ virtual ~InstanceSettingsPage();
+ virtual QString displayName() const override
+ {
+ return tr("Settings");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("instance-settings");
+ }
+ virtual QString id() const override
+ {
+ return "settings";
+ }
+ virtual bool apply() override;
+ virtual QString helpPage() const override
+ {
+ return "Instance-settings";
+ }
+ virtual bool shouldDisplay() const override;
private slots:
- void on_javaDetectBtn_clicked();
- void on_javaTestBtn_clicked();
- void on_javaBrowseBtn_clicked();
+ void on_javaDetectBtn_clicked();
+ void on_javaTestBtn_clicked();
+ void on_javaBrowseBtn_clicked();
- void applySettings();
- void loadSettings();
+ void applySettings();
+ void loadSettings();
- void checkerFinished();
+ void checkerFinished();
private:
- Ui::InstanceSettingsPage *ui;
- BaseInstance *m_instance;
- SettingsObjectPtr m_settings;
- unique_qobject_ptr<JavaCommon::TestCheck> checker;
+ Ui::InstanceSettingsPage *ui;
+ BaseInstance *m_instance;
+ SettingsObjectPtr m_settings;
+ unique_qobject_ptr<JavaCommon::TestCheck> checker;
};
diff --git a/application/pages/instance/LegacyUpgradePage.cpp b/application/pages/instance/LegacyUpgradePage.cpp
index f808ab88..7cd29a62 100644
--- a/application/pages/instance/LegacyUpgradePage.cpp
+++ b/application/pages/instance/LegacyUpgradePage.cpp
@@ -9,42 +9,42 @@
#include "dialogs/ProgressDialog.h"
LegacyUpgradePage::LegacyUpgradePage(InstancePtr inst, QWidget *parent)
- : QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst)
+ : QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst)
{
- ui->setupUi(this);
+ ui->setupUi(this);
}
LegacyUpgradePage::~LegacyUpgradePage()
{
- delete ui;
+ delete ui;
}
void LegacyUpgradePage::runModalTask(Task *task)
{
- connect(task, &Task::failed, [this](QString reason)
- {
- CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Warning)->show();
- });
- ProgressDialog loadDialog(this);
- loadDialog.setSkipButton(true, tr("Abort"));
- if(loadDialog.execWithTask(task) == QDialog::Accepted)
- {
- m_container->requestClose();
- }
+ connect(task, &Task::failed, [this](QString reason)
+ {
+ CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Warning)->show();
+ });
+ ProgressDialog loadDialog(this);
+ loadDialog.setSkipButton(true, tr("Abort"));
+ if(loadDialog.execWithTask(task) == QDialog::Accepted)
+ {
+ m_container->requestClose();
+ }
}
void LegacyUpgradePage::on_upgradeButton_clicked()
{
- QString newName = tr("%1 (Migrated)").arg(m_inst->name());
- auto upgradeTask = new LegacyUpgradeTask(m_inst);
- upgradeTask->setName(newName);
- upgradeTask->setGroup(m_inst->group());
- upgradeTask->setIcon(m_inst->iconKey());
- std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(upgradeTask));
- runModalTask(task.get());
+ QString newName = tr("%1 (Migrated)").arg(m_inst->name());
+ auto upgradeTask = new LegacyUpgradeTask(m_inst);
+ upgradeTask->setName(newName);
+ upgradeTask->setGroup(m_inst->group());
+ upgradeTask->setIcon(m_inst->iconKey());
+ std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(upgradeTask));
+ runModalTask(task.get());
}
bool LegacyUpgradePage::shouldDisplay() const
{
- return !m_inst->isRunning();
+ return !m_inst->isRunning();
}
diff --git a/application/pages/instance/LegacyUpgradePage.h b/application/pages/instance/LegacyUpgradePage.h
index 3e1abe93..4136d703 100644
--- a/application/pages/instance/LegacyUpgradePage.h
+++ b/application/pages/instance/LegacyUpgradePage.h
@@ -29,36 +29,36 @@ class LegacyUpgradePage;
class LegacyUpgradePage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit LegacyUpgradePage(InstancePtr inst, QWidget *parent = 0);
- virtual ~LegacyUpgradePage();
- virtual QString displayName() const override
- {
- return tr("Upgrade");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("checkupdate");
- }
- virtual QString id() const override
- {
- return "upgrade";
- }
- virtual QString helpPage() const override
- {
- return "Legacy-upgrade";
- }
- virtual bool shouldDisplay() const override;
+ explicit LegacyUpgradePage(InstancePtr inst, QWidget *parent = 0);
+ virtual ~LegacyUpgradePage();
+ virtual QString displayName() const override
+ {
+ return tr("Upgrade");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("checkupdate");
+ }
+ virtual QString id() const override
+ {
+ return "upgrade";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Legacy-upgrade";
+ }
+ virtual bool shouldDisplay() const override;
private slots:
- void on_upgradeButton_clicked();
+ void on_upgradeButton_clicked();
private:
- void runModalTask(Task *task);
+ void runModalTask(Task *task);
private:
- Ui::LegacyUpgradePage *ui;
- InstancePtr m_inst;
+ Ui::LegacyUpgradePage *ui;
+ InstancePtr m_inst;
};
diff --git a/application/pages/instance/LogPage.cpp b/application/pages/instance/LogPage.cpp
index 0fa1ee67..0e480a3a 100644
--- a/application/pages/instance/LogPage.cpp
+++ b/application/pages/instance/LogPage.cpp
@@ -15,298 +15,298 @@
class LogFormatProxyModel : public QIdentityProxyModel
{
public:
- LogFormatProxyModel(QObject* parent = nullptr) : QIdentityProxyModel(parent)
- {
- }
- QVariant data(const QModelIndex &index, int role) const override
- {
- switch(role)
- {
- case Qt::FontRole:
- return m_font;
- case Qt::TextColorRole:
- {
- MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
- return m_colors->getFront(level);
- }
- case Qt::BackgroundRole:
- {
- MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
- return m_colors->getBack(level);
- }
- default:
- return QIdentityProxyModel::data(index, role);
- }
- }
-
- void setFont(QFont font)
- {
- m_font = font;
- }
-
- void setColors(LogColorCache* colors)
- {
- m_colors.reset(colors);
- }
-
- QModelIndex find(const QModelIndex &start, const QString &value, bool reverse) const
- {
- QModelIndex parentIndex = parent(start);
- auto compare = [&](int r) -> QModelIndex
- {
- QModelIndex idx = index(r, start.column(), parentIndex);
- if (!idx.isValid() || idx == start)
- {
- return QModelIndex();
- }
- QVariant v = data(idx, Qt::DisplayRole);
- QString t = v.toString();
- if (t.contains(value, Qt::CaseInsensitive))
- return idx;
- return QModelIndex();
- };
- if(reverse)
- {
- int from = start.row();
- int to = 0;
-
- for (int i = 0; i < 2; ++i)
- {
- for (int r = from; (r >= to); --r)
- {
- auto idx = compare(r);
- if(idx.isValid())
- return idx;
- }
- // prepare for the next iteration
- from = rowCount() - 1;
- to = start.row();
- }
- }
- else
- {
- int from = start.row();
- int to = rowCount(parentIndex);
-
- for (int i = 0; i < 2; ++i)
- {
- for (int r = from; (r < to); ++r)
- {
- auto idx = compare(r);
- if(idx.isValid())
- return idx;
- }
- // prepare for the next iteration
- from = 0;
- to = start.row();
- }
- }
- return QModelIndex();
- }
+ LogFormatProxyModel(QObject* parent = nullptr) : QIdentityProxyModel(parent)
+ {
+ }
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ switch(role)
+ {
+ case Qt::FontRole:
+ return m_font;
+ case Qt::TextColorRole:
+ {
+ MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
+ return m_colors->getFront(level);
+ }
+ case Qt::BackgroundRole:
+ {
+ MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
+ return m_colors->getBack(level);
+ }
+ default:
+ return QIdentityProxyModel::data(index, role);
+ }
+ }
+
+ void setFont(QFont font)
+ {
+ m_font = font;
+ }
+
+ void setColors(LogColorCache* colors)
+ {
+ m_colors.reset(colors);
+ }
+
+ QModelIndex find(const QModelIndex &start, const QString &value, bool reverse) const
+ {
+ QModelIndex parentIndex = parent(start);
+ auto compare = [&](int r) -> QModelIndex
+ {
+ QModelIndex idx = index(r, start.column(), parentIndex);
+ if (!idx.isValid() || idx == start)
+ {
+ return QModelIndex();
+ }
+ QVariant v = data(idx, Qt::DisplayRole);
+ QString t = v.toString();
+ if (t.contains(value, Qt::CaseInsensitive))
+ return idx;
+ return QModelIndex();
+ };
+ if(reverse)
+ {
+ int from = start.row();
+ int to = 0;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ for (int r = from; (r >= to); --r)
+ {
+ auto idx = compare(r);
+ if(idx.isValid())
+ return idx;
+ }
+ // prepare for the next iteration
+ from = rowCount() - 1;
+ to = start.row();
+ }
+ }
+ else
+ {
+ int from = start.row();
+ int to = rowCount(parentIndex);
+
+ for (int i = 0; i < 2; ++i)
+ {
+ for (int r = from; (r < to); ++r)
+ {
+ auto idx = compare(r);
+ if(idx.isValid())
+ return idx;
+ }
+ // prepare for the next iteration
+ from = 0;
+ to = start.row();
+ }
+ }
+ return QModelIndex();
+ }
private:
- QFont m_font;
- std::unique_ptr<LogColorCache> m_colors;
+ QFont m_font;
+ std::unique_ptr<LogColorCache> m_colors;
};
LogPage::LogPage(InstancePtr instance, QWidget *parent)
- : QWidget(parent), ui(new Ui::LogPage), m_instance(instance)
+ : QWidget(parent), ui(new Ui::LogPage), m_instance(instance)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
-
- m_proxy = new LogFormatProxyModel(this);
- // set up text colors in the log proxy and adapt them to the current theme foreground and background
- {
- auto origForeground = ui->text->palette().color(ui->text->foregroundRole());
- auto origBackground = ui->text->palette().color(ui->text->backgroundRole());
- m_proxy->setColors(new LogColorCache(origForeground, origBackground));
- }
-
- // set up fonts in the log proxy
- {
- QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
- bool conversionOk = false;
- int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
- if(!conversionOk)
- {
- fontSize = 11;
- }
- m_proxy->setFont(QFont(fontFamily, fontSize));
- }
-
- ui->text->setModel(m_proxy);
-
- // set up instance and launch process recognition
- {
- auto launchTask = m_instance->getLaunchTask();
- if(launchTask)
- {
- setInstanceLaunchTaskChanged(launchTask, true);
- }
- connect(m_instance.get(), &BaseInstance::launchTaskChanged, this, &LogPage::onInstanceLaunchTaskChanged);
- }
-
- auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
- connect(findShortcut, SIGNAL(activated()), SLOT(findActivated()));
- auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
- connect(findNextShortcut, SIGNAL(activated()), SLOT(findNextActivated()));
- connect(ui->searchBar, SIGNAL(returnPressed()), SLOT(on_findButton_clicked()));
- auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
- connect(findPreviousShortcut, SIGNAL(activated()), SLOT(findPreviousActivated()));
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+
+ m_proxy = new LogFormatProxyModel(this);
+ // set up text colors in the log proxy and adapt them to the current theme foreground and background
+ {
+ auto origForeground = ui->text->palette().color(ui->text->foregroundRole());
+ auto origBackground = ui->text->palette().color(ui->text->backgroundRole());
+ m_proxy->setColors(new LogColorCache(origForeground, origBackground));
+ }
+
+ // set up fonts in the log proxy
+ {
+ QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
+ bool conversionOk = false;
+ int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
+ if(!conversionOk)
+ {
+ fontSize = 11;
+ }
+ m_proxy->setFont(QFont(fontFamily, fontSize));
+ }
+
+ ui->text->setModel(m_proxy);
+
+ // set up instance and launch process recognition
+ {
+ auto launchTask = m_instance->getLaunchTask();
+ if(launchTask)
+ {
+ setInstanceLaunchTaskChanged(launchTask, true);
+ }
+ connect(m_instance.get(), &BaseInstance::launchTaskChanged, this, &LogPage::onInstanceLaunchTaskChanged);
+ }
+
+ auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
+ connect(findShortcut, SIGNAL(activated()), SLOT(findActivated()));
+ auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
+ connect(findNextShortcut, SIGNAL(activated()), SLOT(findNextActivated()));
+ connect(ui->searchBar, SIGNAL(returnPressed()), SLOT(on_findButton_clicked()));
+ auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
+ connect(findPreviousShortcut, SIGNAL(activated()), SLOT(findPreviousActivated()));
}
LogPage::~LogPage()
{
- delete ui;
+ delete ui;
}
void LogPage::modelStateToUI()
{
- if(m_model->wrapLines())
- {
- ui->text->setWordWrap(true);
- ui->wrapCheckbox->setCheckState(Qt::Checked);
- }
- else
- {
- ui->text->setWordWrap(false);
- ui->wrapCheckbox->setCheckState(Qt::Unchecked);
- }
- if(m_model->suspended())
- {
- ui->trackLogCheckbox->setCheckState(Qt::Unchecked);
- }
- else
- {
- ui->trackLogCheckbox->setCheckState(Qt::Checked);
- }
+ if(m_model->wrapLines())
+ {
+ ui->text->setWordWrap(true);
+ ui->wrapCheckbox->setCheckState(Qt::Checked);
+ }
+ else
+ {
+ ui->text->setWordWrap(false);
+ ui->wrapCheckbox->setCheckState(Qt::Unchecked);
+ }
+ if(m_model->suspended())
+ {
+ ui->trackLogCheckbox->setCheckState(Qt::Unchecked);
+ }
+ else
+ {
+ ui->trackLogCheckbox->setCheckState(Qt::Checked);
+ }
}
void LogPage::UIToModelState()
{
- if(!m_model)
- {
- return;
- }
- m_model->setLineWrap(ui->wrapCheckbox->checkState() == Qt::Checked);
- m_model->suspend(ui->trackLogCheckbox->checkState() != Qt::Checked);
+ if(!m_model)
+ {
+ return;
+ }
+ m_model->setLineWrap(ui->wrapCheckbox->checkState() == Qt::Checked);
+ m_model->suspend(ui->trackLogCheckbox->checkState() != Qt::Checked);
}
void LogPage::setInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc, bool initial)
{
- m_process = proc;
- if(m_process)
- {
- m_model = proc->getLogModel();
- m_proxy->setSourceModel(m_model.get());
- if(initial)
- {
- modelStateToUI();
- }
- else
- {
- UIToModelState();
- }
- }
- else
- {
- m_proxy->setSourceModel(nullptr);
- m_model.reset();
- }
+ m_process = proc;
+ if(m_process)
+ {
+ m_model = proc->getLogModel();
+ m_proxy->setSourceModel(m_model.get());
+ if(initial)
+ {
+ modelStateToUI();
+ }
+ else
+ {
+ UIToModelState();
+ }
+ }
+ else
+ {
+ m_proxy->setSourceModel(nullptr);
+ m_model.reset();
+ }
}
void LogPage::onInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc)
{
- setInstanceLaunchTaskChanged(proc, false);
+ setInstanceLaunchTaskChanged(proc, false);
}
bool LogPage::apply()
{
- return true;
+ return true;
}
bool LogPage::shouldDisplay() const
{
- return m_instance->isRunning() || m_proxy->rowCount() > 0;
+ return m_instance->isRunning() || m_proxy->rowCount() > 0;
}
void LogPage::on_btnPaste_clicked()
{
- if(!m_model)
- return;
-
- //FIXME: turn this into a proper task and move the upload logic out of GuiUtil!
- m_model->append(MessageLevel::MultiMC, tr("MultiMC: Log upload triggered at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
- auto url = GuiUtil::uploadPaste(m_model->toPlainText(), this);
- if(!url.isEmpty())
- {
- m_model->append(MessageLevel::MultiMC, tr("MultiMC: Log uploaded to: %1").arg(url));
- }
- else
- {
- m_model->append(MessageLevel::Error, tr("MultiMC: Log upload failed!"));
- }
+ if(!m_model)
+ return;
+
+ //FIXME: turn this into a proper task and move the upload logic out of GuiUtil!
+ m_model->append(MessageLevel::MultiMC, tr("MultiMC: Log upload triggered at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
+ auto url = GuiUtil::uploadPaste(m_model->toPlainText(), this);
+ if(!url.isEmpty())
+ {
+ m_model->append(MessageLevel::MultiMC, tr("MultiMC: Log uploaded to: %1").arg(url));
+ }
+ else
+ {
+ m_model->append(MessageLevel::Error, tr("MultiMC: Log upload failed!"));
+ }
}
void LogPage::on_btnCopy_clicked()
{
- if(!m_model)
- return;
- m_model->append(MessageLevel::MultiMC, QString("Clipboard copy at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
- GuiUtil::setClipboardText(m_model->toPlainText());
+ if(!m_model)
+ return;
+ m_model->append(MessageLevel::MultiMC, QString("Clipboard copy at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
+ GuiUtil::setClipboardText(m_model->toPlainText());
}
void LogPage::on_btnClear_clicked()
{
- if(!m_model)
- return;
- m_model->clear();
- m_container->refreshContainer();
+ if(!m_model)
+ return;
+ m_model->clear();
+ m_container->refreshContainer();
}
void LogPage::on_btnBottom_clicked()
{
- ui->text->scrollToBottom();
+ ui->text->scrollToBottom();
}
void LogPage::on_trackLogCheckbox_clicked(bool checked)
{
- if(!m_model)
- return;
- m_model->suspend(!checked);
+ if(!m_model)
+ return;
+ m_model->suspend(!checked);
}
void LogPage::on_wrapCheckbox_clicked(bool checked)
{
- ui->text->setWordWrap(checked);
- if(!m_model)
- return;
- m_model->setLineWrap(checked);
+ ui->text->setWordWrap(checked);
+ if(!m_model)
+ return;
+ m_model->setLineWrap(checked);
}
void LogPage::on_findButton_clicked()
{
- auto modifiers = QApplication::keyboardModifiers();
- bool reverse = modifiers & Qt::ShiftModifier;
- ui->text->findNext(ui->searchBar->text(), reverse);
+ auto modifiers = QApplication::keyboardModifiers();
+ bool reverse = modifiers & Qt::ShiftModifier;
+ ui->text->findNext(ui->searchBar->text(), reverse);
}
void LogPage::findNextActivated()
{
- ui->text->findNext(ui->searchBar->text(), false);
+ ui->text->findNext(ui->searchBar->text(), false);
}
void LogPage::findPreviousActivated()
{
- ui->text->findNext(ui->searchBar->text(), true);
+ ui->text->findNext(ui->searchBar->text(), true);
}
void LogPage::findActivated()
{
- // focus the search bar if it doesn't have focus
- if (!ui->searchBar->hasFocus())
- {
- ui->searchBar->setFocus();
- ui->searchBar->selectAll();
- }
+ // focus the search bar if it doesn't have focus
+ if (!ui->searchBar->hasFocus())
+ {
+ ui->searchBar->setFocus();
+ ui->searchBar->selectAll();
+ }
}
diff --git a/application/pages/instance/LogPage.h b/application/pages/instance/LogPage.h
index 2229418d..b9c4d302 100644
--- a/application/pages/instance/LogPage.h
+++ b/application/pages/instance/LogPage.h
@@ -31,56 +31,56 @@ class LogFormatProxyModel;
class LogPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit LogPage(InstancePtr instance, QWidget *parent = 0);
- virtual ~LogPage();
- virtual QString displayName() const override
- {
- return tr("Minecraft Log");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("log");
- }
- virtual QString id() const override
- {
- return "console";
- }
- virtual bool apply() override;
- virtual QString helpPage() const override
- {
- return "Minecraft-Logs";
- }
- virtual bool shouldDisplay() const override;
+ explicit LogPage(InstancePtr instance, QWidget *parent = 0);
+ virtual ~LogPage();
+ virtual QString displayName() const override
+ {
+ return tr("Minecraft Log");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("log");
+ }
+ virtual QString id() const override
+ {
+ return "console";
+ }
+ virtual bool apply() override;
+ virtual QString helpPage() const override
+ {
+ return "Minecraft-Logs";
+ }
+ virtual bool shouldDisplay() const override;
private slots:
- void on_btnPaste_clicked();
- void on_btnCopy_clicked();
- void on_btnClear_clicked();
- void on_btnBottom_clicked();
+ void on_btnPaste_clicked();
+ void on_btnCopy_clicked();
+ void on_btnClear_clicked();
+ void on_btnBottom_clicked();
- void on_trackLogCheckbox_clicked(bool checked);
- void on_wrapCheckbox_clicked(bool checked);
+ void on_trackLogCheckbox_clicked(bool checked);
+ void on_wrapCheckbox_clicked(bool checked);
- void on_findButton_clicked();
- void findActivated();
- void findNextActivated();
- void findPreviousActivated();
+ void on_findButton_clicked();
+ void findActivated();
+ void findNextActivated();
+ void findPreviousActivated();
- void onInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc);
+ void onInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc);
private:
- void modelStateToUI();
- void UIToModelState();
- void setInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc, bool initial);
+ void modelStateToUI();
+ void UIToModelState();
+ void setInstanceLaunchTaskChanged(std::shared_ptr<LaunchTask> proc, bool initial);
private:
- Ui::LogPage *ui;
- InstancePtr m_instance;
- std::shared_ptr<LaunchTask> m_process;
+ Ui::LogPage *ui;
+ InstancePtr m_instance;
+ std::shared_ptr<LaunchTask> m_process;
- LogFormatProxyModel * m_proxy;
- shared_qobject_ptr <LogModel> m_model;
+ LogFormatProxyModel * m_proxy;
+ shared_qobject_ptr <LogModel> m_model;
};
diff --git a/application/pages/instance/ModFolderPage.cpp b/application/pages/instance/ModFolderPage.cpp
index 0309383d..d891c068 100644
--- a/application/pages/instance/ModFolderPage.cpp
+++ b/application/pages/instance/ModFolderPage.cpp
@@ -32,179 +32,179 @@
#include <DesktopServices.h>
ModFolderPage::ModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
- QString iconName, QString displayName, QString helpPage,
- QWidget *parent)
- : QWidget(parent), ui(new Ui::ModFolderPage)
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- m_inst = inst;
- m_mods = mods;
- m_id = id;
- m_displayName = displayName;
- m_iconName = iconName;
- m_helpName = helpPage;
- m_fileSelectionFilter = "%1 (*.zip *.jar)";
- m_filterModel = new QSortFilterProxyModel(this);
- m_filterModel->setDynamicSortFilter(true);
- m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
- m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
- m_filterModel->setSourceModel(m_mods.get());
- m_filterModel->setFilterKeyColumn(-1);
- ui->modTreeView->setModel(m_filterModel);
- ui->modTreeView->installEventFilter(this);
- ui->modTreeView->sortByColumn(1, Qt::AscendingOrder);
- auto smodel = ui->modTreeView->selectionModel();
- connect(smodel, &QItemSelectionModel::currentChanged, this, &ModFolderPage::modCurrent);
- connect(ui->filterEdit, &QLineEdit::textChanged, this, &ModFolderPage::on_filterTextChanged );
+ QString iconName, QString displayName, QString helpPage,
+ QWidget *parent)
+ : QWidget(parent), ui(new Ui::ModFolderPage)
+{
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ m_inst = inst;
+ m_mods = mods;
+ m_id = id;
+ m_displayName = displayName;
+ m_iconName = iconName;
+ m_helpName = helpPage;
+ m_fileSelectionFilter = "%1 (*.zip *.jar)";
+ m_filterModel = new QSortFilterProxyModel(this);
+ m_filterModel->setDynamicSortFilter(true);
+ m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
+ m_filterModel->setSourceModel(m_mods.get());
+ m_filterModel->setFilterKeyColumn(-1);
+ ui->modTreeView->setModel(m_filterModel);
+ ui->modTreeView->installEventFilter(this);
+ ui->modTreeView->sortByColumn(1, Qt::AscendingOrder);
+ auto smodel = ui->modTreeView->selectionModel();
+ connect(smodel, &QItemSelectionModel::currentChanged, this, &ModFolderPage::modCurrent);
+ connect(ui->filterEdit, &QLineEdit::textChanged, this, &ModFolderPage::on_filterTextChanged );
}
void ModFolderPage::openedImpl()
{
- m_mods->startWatching();
+ m_mods->startWatching();
}
void ModFolderPage::closedImpl()
{
- m_mods->stopWatching();
+ m_mods->stopWatching();
}
void ModFolderPage::on_filterTextChanged(const QString& newContents)
{
- m_viewFilter = newContents;
- m_filterModel->setFilterFixedString(m_viewFilter);
+ m_viewFilter = newContents;
+ m_filterModel->setFilterFixedString(m_viewFilter);
}
CoreModFolderPage::CoreModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods,
- QString id, QString iconName, QString displayName,
- QString helpPage, QWidget *parent)
- : ModFolderPage(inst, mods, id, iconName, displayName, helpPage, parent)
+ QString id, QString iconName, QString displayName,
+ QString helpPage, QWidget *parent)
+ : ModFolderPage(inst, mods, id, iconName, displayName, helpPage, parent)
{
}
ModFolderPage::~ModFolderPage()
{
- m_mods->stopWatching();
- delete ui;
+ m_mods->stopWatching();
+ delete ui;
}
bool ModFolderPage::shouldDisplay() const
{
- if (m_inst)
- return !m_inst->isRunning();
- return true;
+ if (m_inst)
+ return !m_inst->isRunning();
+ return true;
}
bool CoreModFolderPage::shouldDisplay() const
{
- if (ModFolderPage::shouldDisplay())
- {
- auto inst = dynamic_cast<MinecraftInstance *>(m_inst);
- if (!inst)
- return true;
- auto version = inst->getComponentList();
- if (!version)
- return true;
- if(!version->getComponent("net.minecraftforge"))
- {
- return false;
- }
- if(!version->getComponent("net.minecraft"))
- {
- return false;
- }
- if(version->getComponent("net.minecraft")->getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate)
- {
- return true;
- }
- }
- return false;
+ if (ModFolderPage::shouldDisplay())
+ {
+ auto inst = dynamic_cast<MinecraftInstance *>(m_inst);
+ if (!inst)
+ return true;
+ auto version = inst->getComponentList();
+ if (!version)
+ return true;
+ if(!version->getComponent("net.minecraftforge"))
+ {
+ return false;
+ }
+ if(!version->getComponent("net.minecraft"))
+ {
+ return false;
+ }
+ if(version->getComponent("net.minecraft")->getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate)
+ {
+ return true;
+ }
+ }
+ return false;
}
bool ModFolderPage::modListFilter(QKeyEvent *keyEvent)
{
- switch (keyEvent->key())
- {
- case Qt::Key_Delete:
- on_rmModBtn_clicked();
- return true;
- case Qt::Key_Plus:
- on_addModBtn_clicked();
- return true;
- default:
- break;
- }
- return QWidget::eventFilter(ui->modTreeView, keyEvent);
+ switch (keyEvent->key())
+ {
+ case Qt::Key_Delete:
+ on_rmModBtn_clicked();
+ return true;
+ case Qt::Key_Plus:
+ on_addModBtn_clicked();
+ return true;
+ default:
+ break;
+ }
+ return QWidget::eventFilter(ui->modTreeView, keyEvent);
}
bool ModFolderPage::eventFilter(QObject *obj, QEvent *ev)
{
- if (ev->type() != QEvent::KeyPress)
- {
- return QWidget::eventFilter(obj, ev);
- }
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
- if (obj == ui->modTreeView)
- return modListFilter(keyEvent);
- return QWidget::eventFilter(obj, ev);
+ if (ev->type() != QEvent::KeyPress)
+ {
+ return QWidget::eventFilter(obj, ev);
+ }
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
+ if (obj == ui->modTreeView)
+ return modListFilter(keyEvent);
+ return QWidget::eventFilter(obj, ev);
}
void ModFolderPage::on_addModBtn_clicked()
{
- auto list = GuiUtil::BrowseForFiles(
- m_helpName,
- tr("Select %1",
- "Select whatever type of files the page contains. Example: 'Loader Mods'")
- .arg(m_displayName),
- m_fileSelectionFilter.arg(m_displayName), MMC->settings()->get("CentralModsDir").toString(),
- this->parentWidget());
- if (!list.empty())
- {
- for (auto filename : list)
- {
- m_mods->installMod(filename);
- }
- }
+ auto list = GuiUtil::BrowseForFiles(
+ m_helpName,
+ tr("Select %1",
+ "Select whatever type of files the page contains. Example: 'Loader Mods'")
+ .arg(m_displayName),
+ m_fileSelectionFilter.arg(m_displayName), MMC->settings()->get("CentralModsDir").toString(),
+ this->parentWidget());
+ if (!list.empty())
+ {
+ for (auto filename : list)
+ {
+ m_mods->installMod(filename);
+ }
+ }
}
void ModFolderPage::on_enableModBtn_clicked()
{
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->enableMods(selection.indexes(), true);
+ auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
+ m_mods->enableMods(selection.indexes(), true);
}
void ModFolderPage::on_disableModBtn_clicked()
{
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->enableMods(selection.indexes(), false);
+ auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
+ m_mods->enableMods(selection.indexes(), false);
}
void ModFolderPage::on_rmModBtn_clicked()
{
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->deleteMods(selection.indexes());
+ auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
+ m_mods->deleteMods(selection.indexes());
}
void ModFolderPage::on_configFolderBtn_clicked()
{
- DesktopServices::openDirectory(m_inst->instanceConfigFolder(), true);
+ DesktopServices::openDirectory(m_inst->instanceConfigFolder(), true);
}
void ModFolderPage::on_viewModBtn_clicked()
{
- DesktopServices::openDirectory(m_mods->dir().absolutePath(), true);
+ DesktopServices::openDirectory(m_mods->dir().absolutePath(), true);
}
void ModFolderPage::modCurrent(const QModelIndex &current, const QModelIndex &previous)
{
- if (!current.isValid())
- {
- ui->frame->clear();
- return;
- }
- auto sourceCurrent = m_filterModel->mapToSource(current);
- int row = sourceCurrent.row();
- Mod &m = m_mods->operator[](row);
- ui->frame->updateWithMod(m);
+ if (!current.isValid())
+ {
+ ui->frame->clear();
+ return;
+ }
+ auto sourceCurrent = m_filterModel->mapToSource(current);
+ int row = sourceCurrent.row();
+ Mod &m = m_mods->operator[](row);
+ ui->frame->updateWithMod(m);
}
diff --git a/application/pages/instance/ModFolderPage.h b/application/pages/instance/ModFolderPage.h
index 0242f1c9..52f19e87 100644
--- a/application/pages/instance/ModFolderPage.h
+++ b/application/pages/instance/ModFolderPage.h
@@ -29,80 +29,80 @@ class ModFolderPage;
class ModFolderPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
- QString iconName, QString displayName, QString helpPage = "",
- QWidget *parent = 0);
- virtual ~ModFolderPage();
+ explicit ModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
+ QString iconName, QString displayName, QString helpPage = "",
+ QWidget *parent = 0);
+ virtual ~ModFolderPage();
- void setFilter(const QString & filter)
- {
- m_fileSelectionFilter = filter;
- }
+ void setFilter(const QString & filter)
+ {
+ m_fileSelectionFilter = filter;
+ }
- virtual QString displayName() const override
- {
- return m_displayName;
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon(m_iconName);
- }
- virtual QString id() const override
- {
- return m_id;
- }
- virtual QString helpPage() const override
- {
- return m_helpName;
- }
- virtual bool shouldDisplay() const override;
+ virtual QString displayName() const override
+ {
+ return m_displayName;
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon(m_iconName);
+ }
+ virtual QString id() const override
+ {
+ return m_id;
+ }
+ virtual QString helpPage() const override
+ {
+ return m_helpName;
+ }
+ virtual bool shouldDisplay() const override;
- virtual void openedImpl() override;
- virtual void closedImpl() override;
+ virtual void openedImpl() override;
+ virtual void closedImpl() override;
protected:
- bool eventFilter(QObject *obj, QEvent *ev) override;
- bool modListFilter(QKeyEvent *ev);
+ bool eventFilter(QObject *obj, QEvent *ev) override;
+ bool modListFilter(QKeyEvent *ev);
protected:
- BaseInstance *m_inst;
+ BaseInstance *m_inst;
protected:
- Ui::ModFolderPage *ui;
- std::shared_ptr<SimpleModList> m_mods;
- QSortFilterProxyModel *m_filterModel;
- QString m_iconName;
- QString m_id;
- QString m_displayName;
- QString m_helpName;
- QString m_fileSelectionFilter;
- QString m_viewFilter;
+ Ui::ModFolderPage *ui;
+ std::shared_ptr<SimpleModList> m_mods;
+ QSortFilterProxyModel *m_filterModel;
+ QString m_iconName;
+ QString m_id;
+ QString m_displayName;
+ QString m_helpName;
+ QString m_fileSelectionFilter;
+ QString m_viewFilter;
public
slots:
- void modCurrent(const QModelIndex &current, const QModelIndex &previous);
+ void modCurrent(const QModelIndex &current, const QModelIndex &previous);
private
slots:
- void on_filterTextChanged(const QString & newContents);
- void on_addModBtn_clicked();
- void on_rmModBtn_clicked();
- void on_viewModBtn_clicked();
- void on_enableModBtn_clicked();
- void on_disableModBtn_clicked();
- void on_configFolderBtn_clicked();
+ void on_filterTextChanged(const QString & newContents);
+ void on_addModBtn_clicked();
+ void on_rmModBtn_clicked();
+ void on_viewModBtn_clicked();
+ void on_enableModBtn_clicked();
+ void on_disableModBtn_clicked();
+ void on_configFolderBtn_clicked();
};
class CoreModFolderPage : public ModFolderPage
{
public:
- explicit CoreModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
- QString iconName, QString displayName, QString helpPage = "",
- QWidget *parent = 0);
- virtual ~CoreModFolderPage()
- {
- }
- virtual bool shouldDisplay() const;
+ explicit CoreModFolderPage(BaseInstance *inst, std::shared_ptr<SimpleModList> mods, QString id,
+ QString iconName, QString displayName, QString helpPage = "",
+ QWidget *parent = 0);
+ virtual ~CoreModFolderPage()
+ {
+ }
+ virtual bool shouldDisplay() const;
};
diff --git a/application/pages/instance/NewModFolderPage.cpp b/application/pages/instance/NewModFolderPage.cpp
index 35972fba..da65bc9a 100644
--- a/application/pages/instance/NewModFolderPage.cpp
+++ b/application/pages/instance/NewModFolderPage.cpp
@@ -32,146 +32,146 @@
#include <DesktopServices.h>
NewModFolderPage::NewModFolderPage(BaseInstance *inst, std::shared_ptr<ModsModel> mods, QString id,
- QString iconName, QString displayName, QString helpPage,
- QWidget *parent)
- : QWidget(parent), ui(new Ui::NewModFolderPage)
+ QString iconName, QString displayName, QString helpPage,
+ QWidget *parent)
+ : QWidget(parent), ui(new Ui::NewModFolderPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- m_inst = inst;
- m_mods = mods;
- m_id = id;
- m_displayName = displayName;
- m_iconName = iconName;
- m_helpName = helpPage;
- m_fileSelectionFilter = "%1 (*.zip *.jar)";
- m_filterModel = new QSortFilterProxyModel(this);
- m_filterModel->setDynamicSortFilter(true);
- m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
- m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
- m_filterModel->setSourceModel(m_mods.get());
- m_filterModel->setFilterKeyColumn(-1);
- ui->modTreeView->setModel(m_filterModel);
- ui->modTreeView->installEventFilter(this);
- ui->modTreeView->sortByColumn(1, Qt::AscendingOrder);
- auto smodel = ui->modTreeView->selectionModel();
- connect(smodel, &QItemSelectionModel::currentChanged, this, &NewModFolderPage::modCurrent);
- connect(ui->filterEdit, &QLineEdit::textChanged, this, &NewModFolderPage::on_filterTextChanged );
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ m_inst = inst;
+ m_mods = mods;
+ m_id = id;
+ m_displayName = displayName;
+ m_iconName = iconName;
+ m_helpName = helpPage;
+ m_fileSelectionFilter = "%1 (*.zip *.jar)";
+ m_filterModel = new QSortFilterProxyModel(this);
+ m_filterModel->setDynamicSortFilter(true);
+ m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
+ m_filterModel->setSourceModel(m_mods.get());
+ m_filterModel->setFilterKeyColumn(-1);
+ ui->modTreeView->setModel(m_filterModel);
+ ui->modTreeView->installEventFilter(this);
+ ui->modTreeView->sortByColumn(1, Qt::AscendingOrder);
+ auto smodel = ui->modTreeView->selectionModel();
+ connect(smodel, &QItemSelectionModel::currentChanged, this, &NewModFolderPage::modCurrent);
+ connect(ui->filterEdit, &QLineEdit::textChanged, this, &NewModFolderPage::on_filterTextChanged );
}
void NewModFolderPage::openedImpl()
{
- m_mods->startWatching();
+ m_mods->startWatching();
}
void NewModFolderPage::closedImpl()
{
- m_mods->stopWatching();
+ m_mods->stopWatching();
}
void NewModFolderPage::on_filterTextChanged(const QString& newContents)
{
- m_viewFilter = newContents;
- m_filterModel->setFilterFixedString(m_viewFilter);
+ m_viewFilter = newContents;
+ m_filterModel->setFilterFixedString(m_viewFilter);
}
NewModFolderPage::~NewModFolderPage()
{
- m_mods->stopWatching();
- delete ui;
+ m_mods->stopWatching();
+ delete ui;
}
bool NewModFolderPage::shouldDisplay() const
{
- if (m_inst)
- return !m_inst->isRunning();
- return true;
+ if (m_inst)
+ return !m_inst->isRunning();
+ return true;
}
bool NewModFolderPage::modListFilter(QKeyEvent *keyEvent)
{
- switch (keyEvent->key())
- {
- case Qt::Key_Delete:
- on_rmModBtn_clicked();
- return true;
- case Qt::Key_Plus:
- on_addModBtn_clicked();
- return true;
- default:
- break;
- }
- return QWidget::eventFilter(ui->modTreeView, keyEvent);
+ switch (keyEvent->key())
+ {
+ case Qt::Key_Delete:
+ on_rmModBtn_clicked();
+ return true;
+ case Qt::Key_Plus:
+ on_addModBtn_clicked();
+ return true;
+ default:
+ break;
+ }
+ return QWidget::eventFilter(ui->modTreeView, keyEvent);
}
bool NewModFolderPage::eventFilter(QObject *obj, QEvent *ev)
{
- if (ev->type() != QEvent::KeyPress)
- {
- return QWidget::eventFilter(obj, ev);
- }
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
- if (obj == ui->modTreeView)
- return modListFilter(keyEvent);
- return QWidget::eventFilter(obj, ev);
+ if (ev->type() != QEvent::KeyPress)
+ {
+ return QWidget::eventFilter(obj, ev);
+ }
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
+ if (obj == ui->modTreeView)
+ return modListFilter(keyEvent);
+ return QWidget::eventFilter(obj, ev);
}
void NewModFolderPage::on_addModBtn_clicked()
{
- auto list = GuiUtil::BrowseForFiles(
- m_helpName,
- tr("Select %1",
- "Select whatever type of files the page contains. Example: 'Loader Mods'")
- .arg(m_displayName),
- m_fileSelectionFilter.arg(m_displayName), MMC->settings()->get("CentralModsDir").toString(),
- this->parentWidget());
- if (!list.empty())
- {
- for (auto filename : list)
- {
- m_mods->installMod(filename);
- }
- }
+ auto list = GuiUtil::BrowseForFiles(
+ m_helpName,
+ tr("Select %1",
+ "Select whatever type of files the page contains. Example: 'Loader Mods'")
+ .arg(m_displayName),
+ m_fileSelectionFilter.arg(m_displayName), MMC->settings()->get("CentralModsDir").toString(),
+ this->parentWidget());
+ if (!list.empty())
+ {
+ for (auto filename : list)
+ {
+ m_mods->installMod(filename);
+ }
+ }
}
void NewModFolderPage::on_enableModBtn_clicked()
{
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->enableMods(selection.indexes(), true);
+ auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
+ m_mods->enableMods(selection.indexes(), true);
}
void NewModFolderPage::on_disableModBtn_clicked()
{
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->enableMods(selection.indexes(), false);
+ auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
+ m_mods->enableMods(selection.indexes(), false);
}
void NewModFolderPage::on_rmModBtn_clicked()
{
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->deleteMods(selection.indexes());
+ auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
+ m_mods->deleteMods(selection.indexes());
}
void NewModFolderPage::on_configFolderBtn_clicked()
{
- DesktopServices::openDirectory(m_inst->instanceConfigFolder(), true);
+ DesktopServices::openDirectory(m_inst->instanceConfigFolder(), true);
}
void NewModFolderPage::on_viewModBtn_clicked()
{
- DesktopServices::openDirectory(m_mods->dir().absolutePath(), true);
+ DesktopServices::openDirectory(m_mods->dir().absolutePath(), true);
}
void NewModFolderPage::modCurrent(const QModelIndex &current, const QModelIndex &previous)
{
- if (!current.isValid())
- {
- ui->frame->clear();
- return;
- }
- auto sourceCurrent = m_filterModel->mapToSource(current);
- int row = sourceCurrent.row();
- Mod &m = m_mods->operator[](row);
- ui->frame->updateWithMod(m);
+ if (!current.isValid())
+ {
+ ui->frame->clear();
+ return;
+ }
+ auto sourceCurrent = m_filterModel->mapToSource(current);
+ int row = sourceCurrent.row();
+ Mod &m = m_mods->operator[](row);
+ ui->frame->updateWithMod(m);
}
diff --git a/application/pages/instance/NewModFolderPage.h b/application/pages/instance/NewModFolderPage.h
index 2a8136aa..5446a607 100644
--- a/application/pages/instance/NewModFolderPage.h
+++ b/application/pages/instance/NewModFolderPage.h
@@ -29,69 +29,69 @@ class NewModFolderPage;
class NewModFolderPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit NewModFolderPage(BaseInstance *inst, std::shared_ptr<ModsModel> mods, QString id,
- QString iconName, QString displayName, QString helpPage = "",
- QWidget *parent = 0);
- virtual ~NewModFolderPage();
+ explicit NewModFolderPage(BaseInstance *inst, std::shared_ptr<ModsModel> mods, QString id,
+ QString iconName, QString displayName, QString helpPage = "",
+ QWidget *parent = 0);
+ virtual ~NewModFolderPage();
- void setFilter(const QString & filter)
- {
- m_fileSelectionFilter = filter;
- }
+ void setFilter(const QString & filter)
+ {
+ m_fileSelectionFilter = filter;
+ }
- virtual QString displayName() const override
- {
- return m_displayName;
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon(m_iconName);
- }
- virtual QString id() const override
- {
- return m_id;
- }
- virtual QString helpPage() const override
- {
- return m_helpName;
- }
- virtual bool shouldDisplay() const override;
+ virtual QString displayName() const override
+ {
+ return m_displayName;
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon(m_iconName);
+ }
+ virtual QString id() const override
+ {
+ return m_id;
+ }
+ virtual QString helpPage() const override
+ {
+ return m_helpName;
+ }
+ virtual bool shouldDisplay() const override;
- virtual void openedImpl() override;
- virtual void closedImpl() override;
+ virtual void openedImpl() override;
+ virtual void closedImpl() override;
protected:
- bool eventFilter(QObject *obj, QEvent *ev) override;
- bool modListFilter(QKeyEvent *ev);
+ bool eventFilter(QObject *obj, QEvent *ev) override;
+ bool modListFilter(QKeyEvent *ev);
protected:
- BaseInstance *m_inst;
+ BaseInstance *m_inst;
protected:
- Ui::NewModFolderPage *ui;
- std::shared_ptr<ModsModel> m_mods;
- QSortFilterProxyModel *m_filterModel;
- QString m_iconName;
- QString m_id;
- QString m_displayName;
- QString m_helpName;
- QString m_fileSelectionFilter;
- QString m_viewFilter;
+ Ui::NewModFolderPage *ui;
+ std::shared_ptr<ModsModel> m_mods;
+ QSortFilterProxyModel *m_filterModel;
+ QString m_iconName;
+ QString m_id;
+ QString m_displayName;
+ QString m_helpName;
+ QString m_fileSelectionFilter;
+ QString m_viewFilter;
public
slots:
- void modCurrent(const QModelIndex &current, const QModelIndex &previous);
+ void modCurrent(const QModelIndex &current, const QModelIndex &previous);
private
slots:
- void on_filterTextChanged(const QString & newContents);
- void on_addModBtn_clicked();
- void on_rmModBtn_clicked();
- void on_viewModBtn_clicked();
- void on_enableModBtn_clicked();
- void on_disableModBtn_clicked();
- void on_configFolderBtn_clicked();
+ void on_filterTextChanged(const QString & newContents);
+ void on_addModBtn_clicked();
+ void on_rmModBtn_clicked();
+ void on_viewModBtn_clicked();
+ void on_enableModBtn_clicked();
+ void on_disableModBtn_clicked();
+ void on_configFolderBtn_clicked();
};
diff --git a/application/pages/instance/NotesPage.cpp b/application/pages/instance/NotesPage.cpp
index 3925fdfc..6cc2c2f4 100644
--- a/application/pages/instance/NotesPage.cpp
+++ b/application/pages/instance/NotesPage.cpp
@@ -3,20 +3,20 @@
#include <QTabBar>
NotesPage::NotesPage(BaseInstance *inst, QWidget *parent)
- : QWidget(parent), ui(new Ui::NotesPage), m_inst(inst)
+ : QWidget(parent), ui(new Ui::NotesPage), m_inst(inst)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- ui->noteEditor->setText(m_inst->notes());
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ ui->noteEditor->setText(m_inst->notes());
}
NotesPage::~NotesPage()
{
- delete ui;
+ delete ui;
}
bool NotesPage::apply()
{
- m_inst->setNotes(ui->noteEditor->toPlainText());
- return true;
+ m_inst->setNotes(ui->noteEditor->toPlainText());
+ return true;
}
diff --git a/application/pages/instance/NotesPage.h b/application/pages/instance/NotesPage.h
index 4a25f9b1..9941be4f 100644
--- a/application/pages/instance/NotesPage.h
+++ b/application/pages/instance/NotesPage.h
@@ -28,33 +28,33 @@ class NotesPage;
class NotesPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit NotesPage(BaseInstance *inst, QWidget *parent = 0);
- virtual ~NotesPage();
- virtual QString displayName() const override
- {
- return tr("Notes");
- }
- virtual QIcon icon() const override
- {
- auto icon = MMC->getThemedIcon("notes");
- if(icon.isNull())
- icon = MMC->getThemedIcon("news");
- return icon;
- }
- virtual QString id() const override
- {
- return "notes";
- }
- virtual bool apply() override;
- virtual QString helpPage() const override
- {
- return "Notes";
- }
+ explicit NotesPage(BaseInstance *inst, QWidget *parent = 0);
+ virtual ~NotesPage();
+ virtual QString displayName() const override
+ {
+ return tr("Notes");
+ }
+ virtual QIcon icon() const override
+ {
+ auto icon = MMC->getThemedIcon("notes");
+ if(icon.isNull())
+ icon = MMC->getThemedIcon("news");
+ return icon;
+ }
+ virtual QString id() const override
+ {
+ return "notes";
+ }
+ virtual bool apply() override;
+ virtual QString helpPage() const override
+ {
+ return "Notes";
+ }
private:
- Ui::NotesPage *ui;
- BaseInstance *m_inst;
+ Ui::NotesPage *ui;
+ BaseInstance *m_inst;
};
diff --git a/application/pages/instance/OtherLogsPage.cpp b/application/pages/instance/OtherLogsPage.cpp
index 10cb1145..69c33a85 100644
--- a/application/pages/instance/OtherLogsPage.cpp
+++ b/application/pages/instance/OtherLogsPage.cpp
@@ -25,289 +25,289 @@
#include <QShortcut>
OtherLogsPage::OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent)
- : QWidget(parent), ui(new Ui::OtherLogsPage), m_path(path), m_fileFilter(fileFilter),
- m_watcher(new RecursiveFileSystemWatcher(this))
+ : QWidget(parent), ui(new Ui::OtherLogsPage), m_path(path), m_fileFilter(fileFilter),
+ m_watcher(new RecursiveFileSystemWatcher(this))
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
- m_watcher->setMatcher(fileFilter);
- m_watcher->setRootDir(QDir::current().absoluteFilePath(m_path));
+ m_watcher->setMatcher(fileFilter);
+ m_watcher->setRootDir(QDir::current().absoluteFilePath(m_path));
- connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, this, &OtherLogsPage::populateSelectLogBox);
- populateSelectLogBox();
+ connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, this, &OtherLogsPage::populateSelectLogBox);
+ populateSelectLogBox();
- auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
- connect(findShortcut, &QShortcut::activated, this, &OtherLogsPage::findActivated);
+ auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
+ connect(findShortcut, &QShortcut::activated, this, &OtherLogsPage::findActivated);
- auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
- connect(findNextShortcut, &QShortcut::activated, this, &OtherLogsPage::findNextActivated);
+ auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
+ connect(findNextShortcut, &QShortcut::activated, this, &OtherLogsPage::findNextActivated);
- auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
- connect(findPreviousShortcut, &QShortcut::activated, this, &OtherLogsPage::findPreviousActivated);
+ auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
+ connect(findPreviousShortcut, &QShortcut::activated, this, &OtherLogsPage::findPreviousActivated);
- connect(ui->searchBar, &QLineEdit::returnPressed, this, &OtherLogsPage::on_findButton_clicked);
+ connect(ui->searchBar, &QLineEdit::returnPressed, this, &OtherLogsPage::on_findButton_clicked);
}
OtherLogsPage::~OtherLogsPage()
{
- delete ui;
+ delete ui;
}
void OtherLogsPage::openedImpl()
{
- m_watcher->enable();
+ m_watcher->enable();
}
void OtherLogsPage::closedImpl()
{
- m_watcher->disable();
+ m_watcher->disable();
}
void OtherLogsPage::populateSelectLogBox()
{
- ui->selectLogBox->clear();
- ui->selectLogBox->addItems(m_watcher->files());
- if (m_currentFile.isEmpty())
- {
- setControlsEnabled(false);
- ui->selectLogBox->setCurrentIndex(-1);
- }
- else
- {
- const int index = ui->selectLogBox->findText(m_currentFile);
- if (index != -1)
- {
- ui->selectLogBox->setCurrentIndex(index);
- setControlsEnabled(true);
- }
- else
- {
- setControlsEnabled(false);
- }
- }
+ ui->selectLogBox->clear();
+ ui->selectLogBox->addItems(m_watcher->files());
+ if (m_currentFile.isEmpty())
+ {
+ setControlsEnabled(false);
+ ui->selectLogBox->setCurrentIndex(-1);
+ }
+ else
+ {
+ const int index = ui->selectLogBox->findText(m_currentFile);
+ if (index != -1)
+ {
+ ui->selectLogBox->setCurrentIndex(index);
+ setControlsEnabled(true);
+ }
+ else
+ {
+ setControlsEnabled(false);
+ }
+ }
}
void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index)
{
- QString file;
- if (index != -1)
- {
- file = ui->selectLogBox->itemText(index);
- }
+ QString file;
+ if (index != -1)
+ {
+ file = ui->selectLogBox->itemText(index);
+ }
- if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file)))
- {
- m_currentFile = QString();
- ui->text->clear();
- setControlsEnabled(false);
- }
- else
- {
- m_currentFile = file;
- on_btnReload_clicked();
- setControlsEnabled(true);
- }
+ if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file)))
+ {
+ m_currentFile = QString();
+ ui->text->clear();
+ setControlsEnabled(false);
+ }
+ else
+ {
+ m_currentFile = file;
+ on_btnReload_clicked();
+ setControlsEnabled(true);
+ }
}
void OtherLogsPage::on_btnReload_clicked()
{
- if(m_currentFile.isEmpty())
- {
- setControlsEnabled(false);
- return;
- }
- QFile file(FS::PathCombine(m_path, m_currentFile));
- if (!file.open(QFile::ReadOnly))
- {
- setControlsEnabled(false);
- ui->btnReload->setEnabled(true); // allow reload
- m_currentFile = QString();
- QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2")
- .arg(m_currentFile, file.errorString()));
- }
- else
- {
- auto setPlainText = [&](const QString & text)
- {
- QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
- bool conversionOk = false;
- int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
- if(!conversionOk)
- {
- fontSize = 11;
- }
- QTextDocument *doc = ui->text->document();
- doc->setDefaultFont(QFont(fontFamily, fontSize));
- ui->text->setPlainText(text);
- };
- auto showTooBig = [&]()
- {
- setPlainText(
- tr("The file (%1) is too big. You may want to open it in a viewer optimized "
- "for large files.").arg(file.fileName()));
- };
- if(file.size() > (1024ll * 1024ll * 12ll))
- {
- showTooBig();
- return;
- }
- QString content;
- if(file.fileName().endsWith(".gz"))
- {
- QByteArray temp;
- if(!GZip::unzip(file.readAll(), temp))
- {
- setPlainText(
- tr("The file (%1) is not readable.").arg(file.fileName()));
- return;
- }
- content = QString::fromUtf8(temp);
- }
- else
- {
- content = QString::fromUtf8(file.readAll());
- }
- if (content.size() >= 50000000ll)
- {
- showTooBig();
- return;
- }
- setPlainText(content);
- }
+ if(m_currentFile.isEmpty())
+ {
+ setControlsEnabled(false);
+ return;
+ }
+ QFile file(FS::PathCombine(m_path, m_currentFile));
+ if (!file.open(QFile::ReadOnly))
+ {
+ setControlsEnabled(false);
+ ui->btnReload->setEnabled(true); // allow reload
+ m_currentFile = QString();
+ QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2")
+ .arg(m_currentFile, file.errorString()));
+ }
+ else
+ {
+ auto setPlainText = [&](const QString & text)
+ {
+ QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
+ bool conversionOk = false;
+ int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
+ if(!conversionOk)
+ {
+ fontSize = 11;
+ }
+ QTextDocument *doc = ui->text->document();
+ doc->setDefaultFont(QFont(fontFamily, fontSize));
+ ui->text->setPlainText(text);
+ };
+ auto showTooBig = [&]()
+ {
+ setPlainText(
+ tr("The file (%1) is too big. You may want to open it in a viewer optimized "
+ "for large files.").arg(file.fileName()));
+ };
+ if(file.size() > (1024ll * 1024ll * 12ll))
+ {
+ showTooBig();
+ return;
+ }
+ QString content;
+ if(file.fileName().endsWith(".gz"))
+ {
+ QByteArray temp;
+ if(!GZip::unzip(file.readAll(), temp))
+ {
+ setPlainText(
+ tr("The file (%1) is not readable.").arg(file.fileName()));
+ return;
+ }
+ content = QString::fromUtf8(temp);
+ }
+ else
+ {
+ content = QString::fromUtf8(file.readAll());
+ }
+ if (content.size() >= 50000000ll)
+ {
+ showTooBig();
+ return;
+ }
+ setPlainText(content);
+ }
}
void OtherLogsPage::on_btnPaste_clicked()
{
- GuiUtil::uploadPaste(ui->text->toPlainText(), this);
+ GuiUtil::uploadPaste(ui->text->toPlainText(), this);
}
void OtherLogsPage::on_btnCopy_clicked()
{
- GuiUtil::setClipboardText(ui->text->toPlainText());
+ GuiUtil::setClipboardText(ui->text->toPlainText());
}
void OtherLogsPage::on_btnDelete_clicked()
{
- if(m_currentFile.isEmpty())
- {
- setControlsEnabled(false);
- return;
- }
- if (QMessageBox::question(this, tr("Delete"),
- tr("Do you really want to delete %1?").arg(m_currentFile),
- QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
- {
- return;
- }
- QFile file(FS::PathCombine(m_path, m_currentFile));
- if (!file.remove())
- {
- QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2")
- .arg(m_currentFile, file.errorString()));
- }
+ if(m_currentFile.isEmpty())
+ {
+ setControlsEnabled(false);
+ return;
+ }
+ if (QMessageBox::question(this, tr("Delete"),
+ tr("Do you really want to delete %1?").arg(m_currentFile),
+ QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
+ {
+ return;
+ }
+ QFile file(FS::PathCombine(m_path, m_currentFile));
+ if (!file.remove())
+ {
+ QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2")
+ .arg(m_currentFile, file.errorString()));
+ }
}
void OtherLogsPage::on_btnClean_clicked()
{
- auto toDelete = m_watcher->files();
- if(toDelete.isEmpty())
- {
- return;
- }
- QMessageBox *messageBox = new QMessageBox(this);
- messageBox->setWindowTitle(tr("Clean up"));
- if(toDelete.size() > 5)
- {
- messageBox->setText(tr("Do you really want to delete all log files?"));
- messageBox->setDetailedText(toDelete.join('\n'));
- }
- else
- {
- messageBox->setText(tr("Do you really want to delete these files?\n%1").arg(toDelete.join('\n')));
- }
- messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
- messageBox->setDefaultButton(QMessageBox::Ok);
- messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
- messageBox->setIcon(QMessageBox::Question);
- messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ auto toDelete = m_watcher->files();
+ if(toDelete.isEmpty())
+ {
+ return;
+ }
+ QMessageBox *messageBox = new QMessageBox(this);
+ messageBox->setWindowTitle(tr("Clean up"));
+ if(toDelete.size() > 5)
+ {
+ messageBox->setText(tr("Do you really want to delete all log files?"));
+ messageBox->setDetailedText(toDelete.join('\n'));
+ }
+ else
+ {
+ messageBox->setText(tr("Do you really want to delete these files?\n%1").arg(toDelete.join('\n')));
+ }
+ messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ messageBox->setDefaultButton(QMessageBox::Ok);
+ messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ messageBox->setIcon(QMessageBox::Question);
+ messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
- if (messageBox->exec() != QMessageBox::Ok)
- {
- return;
- }
- QStringList failed;
- for(auto item: toDelete)
- {
- QFile file(FS::PathCombine(m_path, item));
- if (!file.remove())
- {
- failed.push_back(item);
- }
- }
- if(!failed.empty())
- {
- QMessageBox *messageBox = new QMessageBox(this);
- messageBox->setWindowTitle(tr("Error"));
- if(failed.size() > 5)
- {
- messageBox->setText(tr("Couldn't delete some files!"));
- messageBox->setDetailedText(failed.join('\n'));
- }
- else
- {
- messageBox->setText(tr("Couldn't delete some files:\n%1").arg(failed.join('\n')));
- }
- messageBox->setStandardButtons(QMessageBox::Ok);
- messageBox->setDefaultButton(QMessageBox::Ok);
- messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
- messageBox->setIcon(QMessageBox::Critical);
- messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
- messageBox->exec();
- }
+ if (messageBox->exec() != QMessageBox::Ok)
+ {
+ return;
+ }
+ QStringList failed;
+ for(auto item: toDelete)
+ {
+ QFile file(FS::PathCombine(m_path, item));
+ if (!file.remove())
+ {
+ failed.push_back(item);
+ }
+ }
+ if(!failed.empty())
+ {
+ QMessageBox *messageBox = new QMessageBox(this);
+ messageBox->setWindowTitle(tr("Error"));
+ if(failed.size() > 5)
+ {
+ messageBox->setText(tr("Couldn't delete some files!"));
+ messageBox->setDetailedText(failed.join('\n'));
+ }
+ else
+ {
+ messageBox->setText(tr("Couldn't delete some files:\n%1").arg(failed.join('\n')));
+ }
+ messageBox->setStandardButtons(QMessageBox::Ok);
+ messageBox->setDefaultButton(QMessageBox::Ok);
+ messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ messageBox->setIcon(QMessageBox::Critical);
+ messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ messageBox->exec();
+ }
}
void OtherLogsPage::setControlsEnabled(const bool enabled)
{
- ui->btnReload->setEnabled(enabled);
- ui->btnDelete->setEnabled(enabled);
- ui->btnCopy->setEnabled(enabled);
- ui->btnPaste->setEnabled(enabled);
- ui->text->setEnabled(enabled);
- ui->btnClean->setEnabled(enabled);
+ ui->btnReload->setEnabled(enabled);
+ ui->btnDelete->setEnabled(enabled);
+ ui->btnCopy->setEnabled(enabled);
+ ui->btnPaste->setEnabled(enabled);
+ ui->text->setEnabled(enabled);
+ ui->btnClean->setEnabled(enabled);
}
// FIXME: HACK, use LogView instead?
static void findNext(QPlainTextEdit * _this, const QString& what, bool reverse)
{
- _this->find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0));
+ _this->find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0));
}
void OtherLogsPage::on_findButton_clicked()
{
- auto modifiers = QApplication::keyboardModifiers();
- bool reverse = modifiers & Qt::ShiftModifier;
- findNext(ui->text, ui->searchBar->text(), reverse);
+ auto modifiers = QApplication::keyboardModifiers();
+ bool reverse = modifiers & Qt::ShiftModifier;
+ findNext(ui->text, ui->searchBar->text(), reverse);
}
void OtherLogsPage::findNextActivated()
{
- findNext(ui->text, ui->searchBar->text(), false);
+ findNext(ui->text, ui->searchBar->text(), false);
}
void OtherLogsPage::findPreviousActivated()
{
- findNext(ui->text, ui->searchBar->text(), true);
+ findNext(ui->text, ui->searchBar->text(), true);
}
void OtherLogsPage::findActivated()
{
- // focus the search bar if it doesn't have focus
- if (!ui->searchBar->hasFocus())
- {
- ui->searchBar->setFocus();
- ui->searchBar->selectAll();
- }
+ // focus the search bar if it doesn't have focus
+ if (!ui->searchBar->hasFocus())
+ {
+ ui->searchBar->setFocus();
+ ui->searchBar->selectAll();
+ }
}
diff --git a/application/pages/instance/OtherLogsPage.h b/application/pages/instance/OtherLogsPage.h
index ac01ef0a..15e9f422 100644
--- a/application/pages/instance/OtherLogsPage.h
+++ b/application/pages/instance/OtherLogsPage.h
@@ -30,52 +30,52 @@ class RecursiveFileSystemWatcher;
class OtherLogsPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent = 0);
- ~OtherLogsPage();
+ explicit OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent = 0);
+ ~OtherLogsPage();
- QString id() const override
- {
- return "logs";
- }
- QString displayName() const override
- {
- return tr("Other logs");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("log");
- }
- QString helpPage() const override
- {
- return "Minecraft-Logs";
- }
- void openedImpl() override;
- void closedImpl() override;
+ QString id() const override
+ {
+ return "logs";
+ }
+ QString displayName() const override
+ {
+ return tr("Other logs");
+ }
+ QIcon icon() const override
+ {
+ return MMC->getThemedIcon("log");
+ }
+ QString helpPage() const override
+ {
+ return "Minecraft-Logs";
+ }
+ void openedImpl() override;
+ void closedImpl() override;
private slots:
- void populateSelectLogBox();
- void on_selectLogBox_currentIndexChanged(const int index);
- void on_btnReload_clicked();
- void on_btnPaste_clicked();
- void on_btnCopy_clicked();
- void on_btnDelete_clicked();
- void on_btnClean_clicked();
+ void populateSelectLogBox();
+ void on_selectLogBox_currentIndexChanged(const int index);
+ void on_btnReload_clicked();
+ void on_btnPaste_clicked();
+ void on_btnCopy_clicked();
+ void on_btnDelete_clicked();
+ void on_btnClean_clicked();
- void on_findButton_clicked();
- void findActivated();
- void findNextActivated();
- void findPreviousActivated();
+ void on_findButton_clicked();
+ void findActivated();
+ void findNextActivated();
+ void findPreviousActivated();
private:
- void setControlsEnabled(const bool enabled);
+ void setControlsEnabled(const bool enabled);
private:
- Ui::OtherLogsPage *ui;
- QString m_path;
- QString m_currentFile;
- IPathMatcher::Ptr m_fileFilter;
- RecursiveFileSystemWatcher *m_watcher;
+ Ui::OtherLogsPage *ui;
+ QString m_path;
+ QString m_currentFile;
+ IPathMatcher::Ptr m_fileFilter;
+ RecursiveFileSystemWatcher *m_watcher;
};
diff --git a/application/pages/instance/ResourcePackPage.h b/application/pages/instance/ResourcePackPage.h
index 19dc78da..00e215da 100644
--- a/application/pages/instance/ResourcePackPage.h
+++ b/application/pages/instance/ResourcePackPage.h
@@ -5,17 +5,17 @@
class ResourcePackPage : public ModFolderPage
{
public:
- explicit ResourcePackPage(MinecraftInstance *instance, QWidget *parent = 0)
- : ModFolderPage(instance, instance->resourcePackList(), "resourcepacks",
- "resourcepacks", tr("Resource packs"), "Resource-packs", parent)
- {
- ui->configFolderBtn->setHidden(true);
- }
+ explicit ResourcePackPage(MinecraftInstance *instance, QWidget *parent = 0)
+ : ModFolderPage(instance, instance->resourcePackList(), "resourcepacks",
+ "resourcepacks", tr("Resource packs"), "Resource-packs", parent)
+ {
+ ui->configFolderBtn->setHidden(true);
+ }
- virtual ~ResourcePackPage() {}
- virtual bool shouldDisplay() const override
- {
- return !m_inst->traits().contains("no-texturepacks") &&
- !m_inst->traits().contains("texturepacks");
- }
+ virtual ~ResourcePackPage() {}
+ virtual bool shouldDisplay() const override
+ {
+ return !m_inst->traits().contains("no-texturepacks") &&
+ !m_inst->traits().contains("texturepacks");
+ }
};
diff --git a/application/pages/instance/ScreenshotsPage.cpp b/application/pages/instance/ScreenshotsPage.cpp
index 71458386..3420e86b 100644
--- a/application/pages/instance/ScreenshotsPage.cpp
+++ b/application/pages/instance/ScreenshotsPage.cpp
@@ -32,341 +32,341 @@ typedef std::shared_ptr<SharedIconCache> SharedIconCachePtr;
class ThumbnailingResult : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public slots:
- inline void emitResultsReady(const QString &path) { emit resultsReady(path); }
- inline void emitResultsFailed(const QString &path) { emit resultsFailed(path); }
+ inline void emitResultsReady(const QString &path) { emit resultsReady(path); }
+ inline void emitResultsFailed(const QString &path) { emit resultsFailed(path); }
signals:
- void resultsReady(const QString &path);
- void resultsFailed(const QString &path);
+ void resultsReady(const QString &path);
+ void resultsFailed(const QString &path);
};
class ThumbnailRunnable : public QRunnable
{
public:
- ThumbnailRunnable(QString path, SharedIconCachePtr cache)
- {
- m_path = path;
- m_cache = cache;
- }
- void run()
- {
- QFileInfo info(m_path);
- if (info.isDir())
- return;
- if ((info.suffix().compare("png", Qt::CaseInsensitive) != 0))
- return;
- int tries = 5;
- while (tries)
- {
- if (!m_cache->stale(m_path))
- return;
- QImage image(m_path);
- if (image.isNull())
- {
- QThread::msleep(500);
- tries--;
- continue;
- }
- QImage small;
- if (image.width() > image.height())
- small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation);
- else
- small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation);
- QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2);
- QImage square(QSize(256, 256), QImage::Format_ARGB32);
- square.fill(Qt::transparent);
+ ThumbnailRunnable(QString path, SharedIconCachePtr cache)
+ {
+ m_path = path;
+ m_cache = cache;
+ }
+ void run()
+ {
+ QFileInfo info(m_path);
+ if (info.isDir())
+ return;
+ if ((info.suffix().compare("png", Qt::CaseInsensitive) != 0))
+ return;
+ int tries = 5;
+ while (tries)
+ {
+ if (!m_cache->stale(m_path))
+ return;
+ QImage image(m_path);
+ if (image.isNull())
+ {
+ QThread::msleep(500);
+ tries--;
+ continue;
+ }
+ QImage small;
+ if (image.width() > image.height())
+ small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation);
+ else
+ small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation);
+ QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2);
+ QImage square(QSize(256, 256), QImage::Format_ARGB32);
+ square.fill(Qt::transparent);
- QPainter painter(&square);
- painter.drawImage(offset, small);
- painter.end();
+ QPainter painter(&square);
+ painter.drawImage(offset, small);
+ painter.end();
- QIcon icon(QPixmap::fromImage(square));
- m_cache->add(m_path, icon);
- m_resultEmitter.emitResultsReady(m_path);
- return;
- }
- m_resultEmitter.emitResultsFailed(m_path);
- }
- QString m_path;
- SharedIconCachePtr m_cache;
- ThumbnailingResult m_resultEmitter;
+ QIcon icon(QPixmap::fromImage(square));
+ m_cache->add(m_path, icon);
+ m_resultEmitter.emitResultsReady(m_path);
+ return;
+ }
+ m_resultEmitter.emitResultsFailed(m_path);
+ }
+ QString m_path;
+ SharedIconCachePtr m_cache;
+ ThumbnailingResult m_resultEmitter;
};
// this is about as elegant and well written as a bag of bricks with scribbles done by insane
// asylum patients.
class FilterModel : public QIdentityProxyModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit FilterModel(QObject *parent = 0) : QIdentityProxyModel(parent)
- {
- m_thumbnailingPool.setMaxThreadCount(4);
- m_thumbnailCache = std::make_shared<SharedIconCache>();
- m_thumbnailCache->add("placeholder", MMC->getThemedIcon("screenshot-placeholder"));
- connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString)));
- // FIXME: the watched file set is not updated when files are removed
- }
- virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); }
- virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const
- {
- auto model = sourceModel();
- if (!model)
- return QVariant();
- if (role == Qt::DisplayRole || role == Qt::EditRole)
- {
- QVariant result = sourceModel()->data(mapToSource(proxyIndex), role);
- return result.toString().remove(QRegExp("\\.png$"));
- }
- if (role == Qt::DecorationRole)
- {
- QVariant result =
- sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole);
- QString filePath = result.toString();
- QIcon temp;
- if (!watched.contains(filePath))
- {
- ((QFileSystemWatcher &)watcher).addPath(filePath);
- ((QSet<QString> &)watched).insert(filePath);
- }
- if (m_thumbnailCache->get(filePath, temp))
- {
- return temp;
- }
- if (!m_failed.contains(filePath))
- {
- ((FilterModel *)this)->thumbnailImage(filePath);
- }
- return (m_thumbnailCache->get("placeholder"));
- }
- return sourceModel()->data(mapToSource(proxyIndex), role);
- }
- virtual bool setData(const QModelIndex &index, const QVariant &value,
- int role = Qt::EditRole)
- {
- auto model = sourceModel();
- if (!model)
- return false;
- if (role != Qt::EditRole)
- return false;
- // FIXME: this is a workaround for a bug in QFileSystemModel, where it doesn't
- // sort after renames
- {
- ((QFileSystemModel *)model)->setNameFilterDisables(true);
- ((QFileSystemModel *)model)->setNameFilterDisables(false);
- }
- return model->setData(mapToSource(index), value.toString() + ".png", role);
- }
+ explicit FilterModel(QObject *parent = 0) : QIdentityProxyModel(parent)
+ {
+ m_thumbnailingPool.setMaxThreadCount(4);
+ m_thumbnailCache = std::make_shared<SharedIconCache>();
+ m_thumbnailCache->add("placeholder", MMC->getThemedIcon("screenshot-placeholder"));
+ connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString)));
+ // FIXME: the watched file set is not updated when files are removed
+ }
+ virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); }
+ virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const
+ {
+ auto model = sourceModel();
+ if (!model)
+ return QVariant();
+ if (role == Qt::DisplayRole || role == Qt::EditRole)
+ {
+ QVariant result = sourceModel()->data(mapToSource(proxyIndex), role);
+ return result.toString().remove(QRegExp("\\.png$"));
+ }
+ if (role == Qt::DecorationRole)
+ {
+ QVariant result =
+ sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole);
+ QString filePath = result.toString();
+ QIcon temp;
+ if (!watched.contains(filePath))
+ {
+ ((QFileSystemWatcher &)watcher).addPath(filePath);
+ ((QSet<QString> &)watched).insert(filePath);
+ }
+ if (m_thumbnailCache->get(filePath, temp))
+ {
+ return temp;
+ }
+ if (!m_failed.contains(filePath))
+ {
+ ((FilterModel *)this)->thumbnailImage(filePath);
+ }
+ return (m_thumbnailCache->get("placeholder"));
+ }
+ return sourceModel()->data(mapToSource(proxyIndex), role);
+ }
+ virtual bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole)
+ {
+ auto model = sourceModel();
+ if (!model)
+ return false;
+ if (role != Qt::EditRole)
+ return false;
+ // FIXME: this is a workaround for a bug in QFileSystemModel, where it doesn't
+ // sort after renames
+ {
+ ((QFileSystemModel *)model)->setNameFilterDisables(true);
+ ((QFileSystemModel *)model)->setNameFilterDisables(false);
+ }
+ return model->setData(mapToSource(index), value.toString() + ".png", role);
+ }
private:
- void thumbnailImage(QString path)
- {
- auto runnable = new ThumbnailRunnable(path, m_thumbnailCache);
- connect(&(runnable->m_resultEmitter), SIGNAL(resultsReady(QString)),
- SLOT(thumbnailReady(QString)));
- connect(&(runnable->m_resultEmitter), SIGNAL(resultsFailed(QString)),
- SLOT(thumbnailFailed(QString)));
- ((QThreadPool &)m_thumbnailingPool).start(runnable);
- }
+ void thumbnailImage(QString path)
+ {
+ auto runnable = new ThumbnailRunnable(path, m_thumbnailCache);
+ connect(&(runnable->m_resultEmitter), SIGNAL(resultsReady(QString)),
+ SLOT(thumbnailReady(QString)));
+ connect(&(runnable->m_resultEmitter), SIGNAL(resultsFailed(QString)),
+ SLOT(thumbnailFailed(QString)));
+ ((QThreadPool &)m_thumbnailingPool).start(runnable);
+ }
private slots:
- void thumbnailReady(QString path) { emit layoutChanged(); }
- void thumbnailFailed(QString path) { m_failed.insert(path); }
- void fileChanged(QString filepath)
- {
- m_thumbnailCache->setStale(filepath);
- thumbnailImage(filepath);
- // reinsert the path...
- watcher.removePath(filepath);
- watcher.addPath(filepath);
- }
+ void thumbnailReady(QString path) { emit layoutChanged(); }
+ void thumbnailFailed(QString path) { m_failed.insert(path); }
+ void fileChanged(QString filepath)
+ {
+ m_thumbnailCache->setStale(filepath);
+ thumbnailImage(filepath);
+ // reinsert the path...
+ watcher.removePath(filepath);
+ watcher.addPath(filepath);
+ }
private:
- SharedIconCachePtr m_thumbnailCache;
- QThreadPool m_thumbnailingPool;
- QSet<QString> m_failed;
- QSet<QString> watched;
- QFileSystemWatcher watcher;
+ SharedIconCachePtr m_thumbnailCache;
+ QThreadPool m_thumbnailingPool;
+ QSet<QString> m_failed;
+ QSet<QString> watched;
+ QFileSystemWatcher watcher;
};
class CenteredEditingDelegate : public QStyledItemDelegate
{
public:
- explicit CenteredEditingDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) {}
- virtual ~CenteredEditingDelegate() {}
- virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
- const QModelIndex &index) const
- {
- auto widget = QStyledItemDelegate::createEditor(parent, option, index);
- auto foo = dynamic_cast<QLineEdit *>(widget);
- if (foo)
- {
- foo->setAlignment(Qt::AlignHCenter);
- foo->setFrame(true);
- foo->setMaximumWidth(192);
- }
- return widget;
- }
+ explicit CenteredEditingDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) {}
+ virtual ~CenteredEditingDelegate() {}
+ virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+ {
+ auto widget = QStyledItemDelegate::createEditor(parent, option, index);
+ auto foo = dynamic_cast<QLineEdit *>(widget);
+ if (foo)
+ {
+ foo->setAlignment(Qt::AlignHCenter);
+ foo->setFrame(true);
+ foo->setMaximumWidth(192);
+ }
+ return widget;
+ }
};
ScreenshotsPage::ScreenshotsPage(QString path, QWidget *parent)
- : QWidget(parent), ui(new Ui::ScreenshotsPage)
+ : QWidget(parent), ui(new Ui::ScreenshotsPage)
{
- m_model.reset(new QFileSystemModel());
- m_filterModel.reset(new FilterModel());
- m_filterModel->setSourceModel(m_model.get());
- m_model->setFilter(QDir::Files | QDir::Writable | QDir::Readable);
- m_model->setReadOnly(false);
- m_model->setNameFilters({"*.png"});
- m_model->setNameFilterDisables(false);
- m_folder = path;
- m_valid = FS::ensureFolderPathExists(m_folder);
+ m_model.reset(new QFileSystemModel());
+ m_filterModel.reset(new FilterModel());
+ m_filterModel->setSourceModel(m_model.get());
+ m_model->setFilter(QDir::Files | QDir::Writable | QDir::Readable);
+ m_model->setReadOnly(false);
+ m_model->setNameFilters({"*.png"});
+ m_model->setNameFilterDisables(false);
+ m_folder = path;
+ m_valid = FS::ensureFolderPathExists(m_folder);
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- ui->listView->setIconSize(QSize(128, 128));
- ui->listView->setGridSize(QSize(192, 160));
- ui->listView->setSpacing(9);
- // ui->listView->setUniformItemSizes(true);
- ui->listView->setLayoutMode(QListView::Batched);
- ui->listView->setViewMode(QListView::IconMode);
- ui->listView->setResizeMode(QListView::Adjust);
- ui->listView->installEventFilter(this);
- ui->listView->setEditTriggers(0);
- ui->listView->setItemDelegate(new CenteredEditingDelegate(this));
- connect(ui->listView, SIGNAL(activated(QModelIndex)), SLOT(onItemActivated(QModelIndex)));
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ ui->listView->setIconSize(QSize(128, 128));
+ ui->listView->setGridSize(QSize(192, 160));
+ ui->listView->setSpacing(9);
+ // ui->listView->setUniformItemSizes(true);
+ ui->listView->setLayoutMode(QListView::Batched);
+ ui->listView->setViewMode(QListView::IconMode);
+ ui->listView->setResizeMode(QListView::Adjust);
+ ui->listView->installEventFilter(this);
+ ui->listView->setEditTriggers(0);
+ ui->listView->setItemDelegate(new CenteredEditingDelegate(this));
+ connect(ui->listView, SIGNAL(activated(QModelIndex)), SLOT(onItemActivated(QModelIndex)));
}
bool ScreenshotsPage::eventFilter(QObject *obj, QEvent *evt)
{
- if (obj != ui->listView)
- return QWidget::eventFilter(obj, evt);
- if (evt->type() != QEvent::KeyPress)
- {
- return QWidget::eventFilter(obj, evt);
- }
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
- switch (keyEvent->key())
- {
- case Qt::Key_Delete:
- on_deleteBtn_clicked();
- return true;
- case Qt::Key_F2:
- on_renameBtn_clicked();
- return true;
- default:
- break;
- }
- return QWidget::eventFilter(obj, evt);
+ if (obj != ui->listView)
+ return QWidget::eventFilter(obj, evt);
+ if (evt->type() != QEvent::KeyPress)
+ {
+ return QWidget::eventFilter(obj, evt);
+ }
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
+ switch (keyEvent->key())
+ {
+ case Qt::Key_Delete:
+ on_deleteBtn_clicked();
+ return true;
+ case Qt::Key_F2:
+ on_renameBtn_clicked();
+ return true;
+ default:
+ break;
+ }
+ return QWidget::eventFilter(obj, evt);
}
ScreenshotsPage::~ScreenshotsPage()
{
- delete ui;
+ delete ui;
}
void ScreenshotsPage::onItemActivated(QModelIndex index)
{
- if (!index.isValid())
- return;
- auto info = m_model->fileInfo(index);
- QString fileName = info.absoluteFilePath();
- DesktopServices::openFile(info.absoluteFilePath());
+ if (!index.isValid())
+ return;
+ auto info = m_model->fileInfo(index);
+ QString fileName = info.absoluteFilePath();
+ DesktopServices::openFile(info.absoluteFilePath());
}
void ScreenshotsPage::on_viewFolderBtn_clicked()
{
- DesktopServices::openDirectory(m_folder, true);
+ DesktopServices::openDirectory(m_folder, true);
}
void ScreenshotsPage::on_uploadBtn_clicked()
{
- auto selection = ui->listView->selectionModel()->selectedRows();
- if (selection.isEmpty())
- return;
+ auto selection = ui->listView->selectionModel()->selectedRows();
+ if (selection.isEmpty())
+ return;
- QList<ScreenshotPtr> uploaded;
- auto job = NetJobPtr(new NetJob("Screenshot Upload"));
- for (auto item : selection)
- {
- auto info = m_model->fileInfo(item);
- auto screenshot = std::make_shared<ScreenShot>(info);
- uploaded.push_back(screenshot);
- job->addNetAction(ImgurUpload::make(screenshot));
- }
- SequentialTask task;
- auto albumTask = NetJobPtr(new NetJob("Imgur Album Creation"));
- auto imgurAlbum = ImgurAlbumCreation::make(uploaded);
- albumTask->addNetAction(imgurAlbum);
- task.addTask(job.unwrap());
- task.addTask(albumTask.unwrap());
- m_uploadActive = true;
- ProgressDialog prog(this);
- if (prog.execWithTask(&task) != QDialog::Accepted)
- {
- CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
- tr("Unknown error"), QMessageBox::Warning)->exec();
- }
- else
- {
- auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id());
- QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(link);
- CustomMessageBox::selectable(
- this,
- tr("Upload finished"),
- tr("The <a href=\"%1\">link to the uploaded album</a> has been placed in your clipboard.") .arg(link),
- QMessageBox::Information
- )->exec();
- }
- m_uploadActive = false;
+ QList<ScreenshotPtr> uploaded;
+ auto job = NetJobPtr(new NetJob("Screenshot Upload"));
+ for (auto item : selection)
+ {
+ auto info = m_model->fileInfo(item);
+ auto screenshot = std::make_shared<ScreenShot>(info);
+ uploaded.push_back(screenshot);
+ job->addNetAction(ImgurUpload::make(screenshot));
+ }
+ SequentialTask task;
+ auto albumTask = NetJobPtr(new NetJob("Imgur Album Creation"));
+ auto imgurAlbum = ImgurAlbumCreation::make(uploaded);
+ albumTask->addNetAction(imgurAlbum);
+ task.addTask(job.unwrap());
+ task.addTask(albumTask.unwrap());
+ m_uploadActive = true;
+ ProgressDialog prog(this);
+ if (prog.execWithTask(&task) != QDialog::Accepted)
+ {
+ CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
+ tr("Unknown error"), QMessageBox::Warning)->exec();
+ }
+ else
+ {
+ auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id());
+ QClipboard *clipboard = QApplication::clipboard();
+ clipboard->setText(link);
+ CustomMessageBox::selectable(
+ this,
+ tr("Upload finished"),
+ tr("The <a href=\"%1\">link to the uploaded album</a> has been placed in your clipboard.") .arg(link),
+ QMessageBox::Information
+ )->exec();
+ }
+ m_uploadActive = false;
}
void ScreenshotsPage::on_deleteBtn_clicked()
{
- auto mbox = CustomMessageBox::selectable(
- this, tr("Are you sure?"), tr("This will delete all selected screenshots."),
- QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No);
- std::unique_ptr<QMessageBox> box(mbox);
+ auto mbox = CustomMessageBox::selectable(
+ this, tr("Are you sure?"), tr("This will delete all selected screenshots."),
+ QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No);
+ std::unique_ptr<QMessageBox> box(mbox);
- if (box->exec() != QMessageBox::Yes)
- return;
+ if (box->exec() != QMessageBox::Yes)
+ return;
- auto selected = ui->listView->selectionModel()->selectedIndexes();
- for (auto item : selected)
- {
- m_model->remove(item);
- }
+ auto selected = ui->listView->selectionModel()->selectedIndexes();
+ for (auto item : selected)
+ {
+ m_model->remove(item);
+ }
}
void ScreenshotsPage::on_renameBtn_clicked()
{
- auto selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.isEmpty())
- return;
- ui->listView->edit(selection[0]);
- // TODO: mass renaming
+ auto selection = ui->listView->selectionModel()->selectedIndexes();
+ if (selection.isEmpty())
+ return;
+ ui->listView->edit(selection[0]);
+ // TODO: mass renaming
}
void ScreenshotsPage::openedImpl()
{
- if(!m_valid)
- {
- m_valid = FS::ensureFolderPathExists(m_folder);
- }
- if (m_valid)
- {
- QString path = QDir(m_folder).absolutePath();
- auto idx = m_model->setRootPath(path);
- if(idx.isValid())
- {
- ui->listView->setModel(m_filterModel.get());
- ui->listView->setRootIndex(m_filterModel->mapFromSource(idx));
- }
- else
- {
- ui->listView->setModel(nullptr);
- }
- }
+ if(!m_valid)
+ {
+ m_valid = FS::ensureFolderPathExists(m_folder);
+ }
+ if (m_valid)
+ {
+ QString path = QDir(m_folder).absolutePath();
+ auto idx = m_model->setRootPath(path);
+ if(idx.isValid())
+ {
+ ui->listView->setModel(m_filterModel.get());
+ ui->listView->setRootIndex(m_filterModel->mapFromSource(idx));
+ }
+ else
+ {
+ ui->listView->setModel(nullptr);
+ }
+ }
}
#include "ScreenshotsPage.moc"
diff --git a/application/pages/instance/ScreenshotsPage.h b/application/pages/instance/ScreenshotsPage.h
index e31fb8b4..88a64dfb 100644
--- a/application/pages/instance/ScreenshotsPage.h
+++ b/application/pages/instance/ScreenshotsPage.h
@@ -33,52 +33,52 @@ class ImgurAlbumCreation;
class ScreenshotsPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ScreenshotsPage(QString path, QWidget *parent = 0);
- virtual ~ScreenshotsPage();
+ explicit ScreenshotsPage(QString path, QWidget *parent = 0);
+ virtual ~ScreenshotsPage();
- virtual void openedImpl() override;
+ virtual void openedImpl() override;
- enum
- {
- NothingDone = 0x42
- };
+ enum
+ {
+ NothingDone = 0x42
+ };
- virtual bool eventFilter(QObject *, QEvent *) override;
- virtual QString displayName() const override
- {
- return tr("Screenshots");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("screenshots");
- }
- virtual QString id() const override
- {
- return "screenshots";
- }
- virtual QString helpPage() const override
- {
- return "Screenshots-management";
- }
- virtual bool apply() override
- {
- return !m_uploadActive;
- }
+ virtual bool eventFilter(QObject *, QEvent *) override;
+ virtual QString displayName() const override
+ {
+ return tr("Screenshots");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("screenshots");
+ }
+ virtual QString id() const override
+ {
+ return "screenshots";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Screenshots-management";
+ }
+ virtual bool apply() override
+ {
+ return !m_uploadActive;
+ }
private slots:
- void on_uploadBtn_clicked();
- void on_deleteBtn_clicked();
- void on_renameBtn_clicked();
- void on_viewFolderBtn_clicked();
- void onItemActivated(QModelIndex);
+ void on_uploadBtn_clicked();
+ void on_deleteBtn_clicked();
+ void on_renameBtn_clicked();
+ void on_viewFolderBtn_clicked();
+ void onItemActivated(QModelIndex);
private:
- Ui::ScreenshotsPage *ui;
- std::shared_ptr<QFileSystemModel> m_model;
- std::shared_ptr<QIdentityProxyModel> m_filterModel;
- QString m_folder;
- bool m_valid = false;
- bool m_uploadActive = false;
+ Ui::ScreenshotsPage *ui;
+ std::shared_ptr<QFileSystemModel> m_model;
+ std::shared_ptr<QIdentityProxyModel> m_filterModel;
+ QString m_folder;
+ bool m_valid = false;
+ bool m_uploadActive = false;
};
diff --git a/application/pages/instance/ServersPage.cpp b/application/pages/instance/ServersPage.cpp
index 34e4af38..dfe21d5b 100644
--- a/application/pages/instance/ServersPage.cpp
+++ b/application/pages/instance/ServersPage.cpp
@@ -16,728 +16,728 @@ static const int COLUMN_COUNT = 2; // 3 , TBD: latency and other nice things.
struct Server
{
- // Types
- enum class AcceptsTextures : int
- {
- ASK = 0,
- ALWAYS = 1,
- NEVER = 2
- };
-
- // Methods
- Server()
- {
- m_name = QObject::tr("Minecraft Server");
- }
- Server(const QString & name, const QString & address)
- {
- m_name = name;
- m_address = address;
- }
- Server(nbt::tag_compound& server)
- {
- std::string addressStr(server["ip"]);
- m_address = QString::fromUtf8(addressStr.c_str());
-
- std::string nameStr(server["name"]);
- m_name = QString::fromUtf8(nameStr.c_str());
-
- if(server["icon"])
- {
- std::string base64str(server["icon"]);
- m_icon = QByteArray::fromBase64(base64str.c_str());
- }
-
- if(server.has_key("acceptTextures", nbt::tag_type::Byte))
- {
- bool value = server["acceptTextures"].as<nbt::tag_byte>().get();
- if(value)
- {
- m_acceptsTextures = AcceptsTextures::ALWAYS;
- }
- else
- {
- m_acceptsTextures = AcceptsTextures::NEVER;
- }
- }
- }
-
- void serialize(nbt::tag_compound& server)
- {
- server.insert("name", m_name.toUtf8().toStdString());
- server.insert("ip", m_address.toUtf8().toStdString());
- if(m_icon.size())
- {
- server.insert("icon", m_icon.toBase64().toStdString());
- }
- if(m_acceptsTextures != AcceptsTextures::ASK)
- {
- server.insert("acceptTextures", nbt::tag_byte(m_acceptsTextures == AcceptsTextures::ALWAYS));
- }
- }
-
- // Data - persistent and user changeable
- QString m_name;
- QString m_address;
- AcceptsTextures m_acceptsTextures = AcceptsTextures::ASK;
-
- // Data - persistent and automatically updated
- QByteArray m_icon;
-
- // Data - temporary
- bool m_checked = false;
- bool m_up = false;
- QString m_motd; // https://mctools.org/motd-creator
- int m_ping = 0;
- int m_currentPlayers = 0;
- int m_maxPlayers = 0;
+ // Types
+ enum class AcceptsTextures : int
+ {
+ ASK = 0,
+ ALWAYS = 1,
+ NEVER = 2
+ };
+
+ // Methods
+ Server()
+ {
+ m_name = QObject::tr("Minecraft Server");
+ }
+ Server(const QString & name, const QString & address)
+ {
+ m_name = name;
+ m_address = address;
+ }
+ Server(nbt::tag_compound& server)
+ {
+ std::string addressStr(server["ip"]);
+ m_address = QString::fromUtf8(addressStr.c_str());
+
+ std::string nameStr(server["name"]);
+ m_name = QString::fromUtf8(nameStr.c_str());
+
+ if(server["icon"])
+ {
+ std::string base64str(server["icon"]);
+ m_icon = QByteArray::fromBase64(base64str.c_str());
+ }
+
+ if(server.has_key("acceptTextures", nbt::tag_type::Byte))
+ {
+ bool value = server["acceptTextures"].as<nbt::tag_byte>().get();
+ if(value)
+ {
+ m_acceptsTextures = AcceptsTextures::ALWAYS;
+ }
+ else
+ {
+ m_acceptsTextures = AcceptsTextures::NEVER;
+ }
+ }
+ }
+
+ void serialize(nbt::tag_compound& server)
+ {
+ server.insert("name", m_name.toUtf8().toStdString());
+ server.insert("ip", m_address.toUtf8().toStdString());
+ if(m_icon.size())
+ {
+ server.insert("icon", m_icon.toBase64().toStdString());
+ }
+ if(m_acceptsTextures != AcceptsTextures::ASK)
+ {
+ server.insert("acceptTextures", nbt::tag_byte(m_acceptsTextures == AcceptsTextures::ALWAYS));
+ }
+ }
+
+ // Data - persistent and user changeable
+ QString m_name;
+ QString m_address;
+ AcceptsTextures m_acceptsTextures = AcceptsTextures::ASK;
+
+ // Data - persistent and automatically updated
+ QByteArray m_icon;
+
+ // Data - temporary
+ bool m_checked = false;
+ bool m_up = false;
+ QString m_motd; // https://mctools.org/motd-creator
+ int m_ping = 0;
+ int m_currentPlayers = 0;
+ int m_maxPlayers = 0;
};
static std::unique_ptr <nbt::tag_compound> parseServersDat(const QString& filename)
{
- try
- {
- QByteArray input = FS::read(filename);
- std::istringstream foo(std::string(input.constData(), input.size()));
- auto pair = nbt::io::read_compound(foo);
-
- if(pair.first != "")
- return nullptr;
-
- if(pair.second == nullptr)
- return nullptr;
-
- return std::move(pair.second);
- }
- catch (...)
- {
- return nullptr;
- }
+ try
+ {
+ QByteArray input = FS::read(filename);
+ std::istringstream foo(std::string(input.constData(), input.size()));
+ auto pair = nbt::io::read_compound(foo);
+
+ if(pair.first != "")
+ return nullptr;
+
+ if(pair.second == nullptr)
+ return nullptr;
+
+ return std::move(pair.second);
+ }
+ catch (...)
+ {
+ return nullptr;
+ }
}
static bool serializeServerDat(const QString& filename, nbt::tag_compound * levelInfo)
{
- try
- {
- if(!FS::ensureFilePathExists(filename))
- {
- return false;
- }
- std::ostringstream s;
- nbt::io::write_tag("", *levelInfo, s);
- QByteArray val(s.str().data(), (int) s.str().size() );
- FS::write(filename, val);
- return true;
- }
- catch (...)
- {
- return false;
- }
+ try
+ {
+ if(!FS::ensureFilePathExists(filename))
+ {
+ return false;
+ }
+ std::ostringstream s;
+ nbt::io::write_tag("", *levelInfo, s);
+ QByteArray val(s.str().data(), (int) s.str().size() );
+ FS::write(filename, val);
+ return true;
+ }
+ catch (...)
+ {
+ return false;
+ }
}
class ServersModel: public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- enum Roles
- {
- ServerPtrRole = Qt::UserRole,
- };
- explicit ServersModel(const QString &path, QObject *parent = 0)
- : QAbstractListModel(parent)
- {
- m_path = path;
- m_watcher = new QFileSystemWatcher(this);
- connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &ServersModel::fileChanged);
- connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &ServersModel::dirChanged);
- m_saveTimer.setSingleShot(true);
- m_saveTimer.setInterval(5000);
- connect(&m_saveTimer, &QTimer::timeout, this, &ServersModel::save_internal);
- }
- virtual ~ServersModel() {};
-
- void observe()
- {
- if(m_observed)
- {
- return;
- }
- m_observed = true;
-
- if(!m_loaded)
- {
- load();
- }
-
- updateFSObserver();
- }
-
- void unobserve()
- {
- if(!m_observed)
- {
- return;
- }
- m_observed = false;
-
- updateFSObserver();
- }
-
- void lock()
- {
- if(m_locked)
- {
- return;
- }
- saveNow();
-
- m_locked = true;
- updateFSObserver();
- }
-
- void unlock()
- {
- if(!m_locked)
- {
- return;
- }
- m_locked = false;
-
- updateFSObserver();
- }
-
- int addEmptyRow(int position)
- {
- if(m_locked)
- {
- return -1;
- }
- if(position < 0 || position >= rowCount())
- {
- position = rowCount();
- }
- beginInsertRows(QModelIndex(), position, position);
- m_servers.insert(position, Server());
- endInsertRows();
- scheduleSave();
- return position;
- }
-
- bool removeRow(int row)
- {
- if(m_locked)
- {
- return false;
- }
- if(row < 0 || row >= rowCount())
- {
- return false;
- }
- beginRemoveRows(QModelIndex(), row, row);
- m_servers.removeAt(row);
- endRemoveRows(); // does absolutely nothing, the selected server stays as the next line...
- scheduleSave();
- return true;
- }
-
- bool moveUp(int row)
- {
- if(m_locked)
- {
- return false;
- }
- if(row <= 0)
- {
- return false;
- }
- beginMoveRows(QModelIndex(), row, row, QModelIndex(), row - 1);
- m_servers.swap(row-1, row);
- endMoveRows();
- scheduleSave();
- return true;
- }
-
- bool moveDown(int row)
- {
- if(m_locked)
- {
- return false;
- }
- int count = rowCount();
- if(row + 1 >= count)
- {
- return false;
- }
- beginMoveRows(QModelIndex(), row, row, QModelIndex(), row + 2);
- m_servers.swap(row+1, row);
- endMoveRows();
- scheduleSave();
- return true;
- }
-
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override
- {
- if (section < 0 || section >= COLUMN_COUNT)
- return QVariant();
-
- if(role == Qt::DisplayRole)
- {
- switch(section)
- {
- case 0:
- return tr("Name");
- case 1:
- return tr("Address");
- case 2:
- return tr("Latency");
- }
- }
-
- return QAbstractListModel::headerData(section, orientation, role);
- }
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
- {
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
- if(column < 0 || column >= COLUMN_COUNT)
- return QVariant();
-
- if (row < 0 || row >= m_servers.size())
- return QVariant();
-
- switch(column)
- {
- case 0:
- switch (role)
- {
- case Qt::DecorationRole:
- {
- auto & bytes = m_servers[row].m_icon;
- if(bytes.size())
- {
- QPixmap px;
- if(px.loadFromData(bytes))
- return QIcon(px);
- }
- return MMC->getThemedIcon("unknown_server");
- }
- case Qt::DisplayRole:
- return m_servers[row].m_name;
- case ServerPtrRole:
- return QVariant::fromValue<void *>((void *)&m_servers[row]);
- default:
- return QVariant();
- }
- case 1:
- switch (role)
- {
- case Qt::DisplayRole:
- return m_servers[row].m_address;
- default:
- return QVariant();
- }
- case 2:
- switch (role)
- {
- case Qt::DisplayRole:
- return m_servers[row].m_ping;
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
- }
-
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override
- {
- return m_servers.size();
- }
- int columnCount(const QModelIndex & parent) const override
- {
- return COLUMN_COUNT;
- }
-
- Server * at(int index)
- {
- if(index < 0 || index >= rowCount())
- {
- return nullptr;
- }
- return &m_servers[index];
- }
-
- void setName(int row, const QString & name)
- {
- if(m_locked)
- {
- return;
- }
- auto server = at(row);
- if(!server || server->m_name == name)
- {
- return;
- }
- server->m_name = name;
- emit dataChanged(index(row, 0), index(row, COLUMN_COUNT - 1));
- scheduleSave();
- }
-
- void setAddress(int row, const QString & address)
- {
- if(m_locked)
- {
- return;
- }
- auto server = at(row);
- if(!server || server->m_address == address)
- {
- return;
- }
- server->m_address = address;
- emit dataChanged(index(row, 0), index(row, COLUMN_COUNT - 1));
- scheduleSave();
- }
-
- void setAcceptsTextures(int row, Server::AcceptsTextures textures)
- {
- if(m_locked)
- {
- return;
- }
- auto server = at(row);
- if(!server || server->m_acceptsTextures == textures)
- {
- return;
- }
- server->m_acceptsTextures = textures;
- emit dataChanged(index(row, 0), index(row, COLUMN_COUNT - 1));
- scheduleSave();
- }
-
- void load()
- {
- cancelSave();
- beginResetModel();
- QList<Server> servers;
- auto serversDat = parseServersDat(serversPath());
- if(serversDat)
- {
- auto &serversList = serversDat->at("servers").as<nbt::tag_list>();
- for(auto iter = serversList.begin(); iter != serversList.end(); iter++)
- {
- auto & serverTag = (*iter).as<nbt::tag_compound>();
- Server s(serverTag);
- servers.append(s);
- }
- }
- m_servers.swap(servers);
- m_loaded = true;
- endResetModel();
- }
-
- void saveNow()
- {
- if(saveIsScheduled())
- {
- save_internal();
- }
- }
+ enum Roles
+ {
+ ServerPtrRole = Qt::UserRole,
+ };
+ explicit ServersModel(const QString &path, QObject *parent = 0)
+ : QAbstractListModel(parent)
+ {
+ m_path = path;
+ m_watcher = new QFileSystemWatcher(this);
+ connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &ServersModel::fileChanged);
+ connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &ServersModel::dirChanged);
+ m_saveTimer.setSingleShot(true);
+ m_saveTimer.setInterval(5000);
+ connect(&m_saveTimer, &QTimer::timeout, this, &ServersModel::save_internal);
+ }
+ virtual ~ServersModel() {};
+
+ void observe()
+ {
+ if(m_observed)
+ {
+ return;
+ }
+ m_observed = true;
+
+ if(!m_loaded)
+ {
+ load();
+ }
+
+ updateFSObserver();
+ }
+
+ void unobserve()
+ {
+ if(!m_observed)
+ {
+ return;
+ }
+ m_observed = false;
+
+ updateFSObserver();
+ }
+
+ void lock()
+ {
+ if(m_locked)
+ {
+ return;
+ }
+ saveNow();
+
+ m_locked = true;
+ updateFSObserver();
+ }
+
+ void unlock()
+ {
+ if(!m_locked)
+ {
+ return;
+ }
+ m_locked = false;
+
+ updateFSObserver();
+ }
+
+ int addEmptyRow(int position)
+ {
+ if(m_locked)
+ {
+ return -1;
+ }
+ if(position < 0 || position >= rowCount())
+ {
+ position = rowCount();
+ }
+ beginInsertRows(QModelIndex(), position, position);
+ m_servers.insert(position, Server());
+ endInsertRows();
+ scheduleSave();
+ return position;
+ }
+
+ bool removeRow(int row)
+ {
+ if(m_locked)
+ {
+ return false;
+ }
+ if(row < 0 || row >= rowCount())
+ {
+ return false;
+ }
+ beginRemoveRows(QModelIndex(), row, row);
+ m_servers.removeAt(row);
+ endRemoveRows(); // does absolutely nothing, the selected server stays as the next line...
+ scheduleSave();
+ return true;
+ }
+
+ bool moveUp(int row)
+ {
+ if(m_locked)
+ {
+ return false;
+ }
+ if(row <= 0)
+ {
+ return false;
+ }
+ beginMoveRows(QModelIndex(), row, row, QModelIndex(), row - 1);
+ m_servers.swap(row-1, row);
+ endMoveRows();
+ scheduleSave();
+ return true;
+ }
+
+ bool moveDown(int row)
+ {
+ if(m_locked)
+ {
+ return false;
+ }
+ int count = rowCount();
+ if(row + 1 >= count)
+ {
+ return false;
+ }
+ beginMoveRows(QModelIndex(), row, row, QModelIndex(), row + 2);
+ m_servers.swap(row+1, row);
+ endMoveRows();
+ scheduleSave();
+ return true;
+ }
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override
+ {
+ if (section < 0 || section >= COLUMN_COUNT)
+ return QVariant();
+
+ if(role == Qt::DisplayRole)
+ {
+ switch(section)
+ {
+ case 0:
+ return tr("Name");
+ case 1:
+ return tr("Address");
+ case 2:
+ return tr("Latency");
+ }
+ }
+
+ return QAbstractListModel::headerData(section, orientation, role);
+ }
+
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
+ {
+ if (!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+ int column = index.column();
+ if(column < 0 || column >= COLUMN_COUNT)
+ return QVariant();
+
+ if (row < 0 || row >= m_servers.size())
+ return QVariant();
+
+ switch(column)
+ {
+ case 0:
+ switch (role)
+ {
+ case Qt::DecorationRole:
+ {
+ auto & bytes = m_servers[row].m_icon;
+ if(bytes.size())
+ {
+ QPixmap px;
+ if(px.loadFromData(bytes))
+ return QIcon(px);
+ }
+ return MMC->getThemedIcon("unknown_server");
+ }
+ case Qt::DisplayRole:
+ return m_servers[row].m_name;
+ case ServerPtrRole:
+ return QVariant::fromValue<void *>((void *)&m_servers[row]);
+ default:
+ return QVariant();
+ }
+ case 1:
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ return m_servers[row].m_address;
+ default:
+ return QVariant();
+ }
+ case 2:
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ return m_servers[row].m_ping;
+ default:
+ return QVariant();
+ }
+ default:
+ return QVariant();
+ }
+ }
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override
+ {
+ return m_servers.size();
+ }
+ int columnCount(const QModelIndex & parent) const override
+ {
+ return COLUMN_COUNT;
+ }
+
+ Server * at(int index)
+ {
+ if(index < 0 || index >= rowCount())
+ {
+ return nullptr;
+ }
+ return &m_servers[index];
+ }
+
+ void setName(int row, const QString & name)
+ {
+ if(m_locked)
+ {
+ return;
+ }
+ auto server = at(row);
+ if(!server || server->m_name == name)
+ {
+ return;
+ }
+ server->m_name = name;
+ emit dataChanged(index(row, 0), index(row, COLUMN_COUNT - 1));
+ scheduleSave();
+ }
+
+ void setAddress(int row, const QString & address)
+ {
+ if(m_locked)
+ {
+ return;
+ }
+ auto server = at(row);
+ if(!server || server->m_address == address)
+ {
+ return;
+ }
+ server->m_address = address;
+ emit dataChanged(index(row, 0), index(row, COLUMN_COUNT - 1));
+ scheduleSave();
+ }
+
+ void setAcceptsTextures(int row, Server::AcceptsTextures textures)
+ {
+ if(m_locked)
+ {
+ return;
+ }
+ auto server = at(row);
+ if(!server || server->m_acceptsTextures == textures)
+ {
+ return;
+ }
+ server->m_acceptsTextures = textures;
+ emit dataChanged(index(row, 0), index(row, COLUMN_COUNT - 1));
+ scheduleSave();
+ }
+
+ void load()
+ {
+ cancelSave();
+ beginResetModel();
+ QList<Server> servers;
+ auto serversDat = parseServersDat(serversPath());
+ if(serversDat)
+ {
+ auto &serversList = serversDat->at("servers").as<nbt::tag_list>();
+ for(auto iter = serversList.begin(); iter != serversList.end(); iter++)
+ {
+ auto & serverTag = (*iter).as<nbt::tag_compound>();
+ Server s(serverTag);
+ servers.append(s);
+ }
+ }
+ m_servers.swap(servers);
+ m_loaded = true;
+ endResetModel();
+ }
+
+ void saveNow()
+ {
+ if(saveIsScheduled())
+ {
+ save_internal();
+ }
+ }
public slots:
- void dirChanged(const QString& path)
- {
- qDebug() << "Changed:" << path;
- load();
- }
- void fileChanged(const QString& path)
- {
- qDebug() << "Changed:" << path;
- }
+ void dirChanged(const QString& path)
+ {
+ qDebug() << "Changed:" << path;
+ load();
+ }
+ void fileChanged(const QString& path)
+ {
+ qDebug() << "Changed:" << path;
+ }
private slots:
- void save_internal()
- {
- cancelSave();
- QString path = serversPath();
- qDebug() << "Server list about to be saved to" << path;
-
- nbt::tag_compound out;
- nbt::tag_list list;
- for(auto & server: m_servers)
- {
- nbt::tag_compound serverNbt;
- server.serialize(serverNbt);
- list.push_back(std::move(serverNbt));
- }
- out.insert("servers", nbt::value(std::move(list)));
-
- if(!serializeServerDat(path, &out))
- {
- qDebug() << "Failed to save server list:" << path << "Will try again.";
- scheduleSave();
- }
- }
+ void save_internal()
+ {
+ cancelSave();
+ QString path = serversPath();
+ qDebug() << "Server list about to be saved to" << path;
+
+ nbt::tag_compound out;
+ nbt::tag_list list;
+ for(auto & server: m_servers)
+ {
+ nbt::tag_compound serverNbt;
+ server.serialize(serverNbt);
+ list.push_back(std::move(serverNbt));
+ }
+ out.insert("servers", nbt::value(std::move(list)));
+
+ if(!serializeServerDat(path, &out))
+ {
+ qDebug() << "Failed to save server list:" << path << "Will try again.";
+ scheduleSave();
+ }
+ }
private:
- void scheduleSave()
- {
- if(!m_loaded)
- {
- qDebug() << "Server list should never save if it didn't successfully load, path:" << m_path;
- return;
- }
- if(!m_dirty)
- {
- m_dirty = true;
- qDebug() << "Server list save is scheduled for" << m_path;
- }
- m_saveTimer.start();
- }
-
- void cancelSave()
- {
- m_dirty = false;
- m_saveTimer.stop();
- }
-
- bool saveIsScheduled() const
- {
- return m_dirty;
- }
-
- void updateFSObserver()
- {
- bool observingFS = m_watcher->directories().contains(m_path);
- if(m_observed && m_locked)
- {
- if(!observingFS)
- {
- qWarning() << "Will watch" << m_path;
- if(!m_watcher->addPath(m_path))
- {
- qWarning() << "Failed to start watching" << m_path;
- }
- }
- }
- else
- {
- if(observingFS)
- {
- qWarning() << "Will stop watching" << m_path;
- if(!m_watcher->removePath(m_path))
- {
- qWarning() << "Failed to stop watching" << m_path;
- }
- }
- }
- }
-
- QString serversPath()
- {
- QFileInfo foo(FS::PathCombine(m_path, "servers.dat"));
- return foo.filePath();
- }
+ void scheduleSave()
+ {
+ if(!m_loaded)
+ {
+ qDebug() << "Server list should never save if it didn't successfully load, path:" << m_path;
+ return;
+ }
+ if(!m_dirty)
+ {
+ m_dirty = true;
+ qDebug() << "Server list save is scheduled for" << m_path;
+ }
+ m_saveTimer.start();
+ }
+
+ void cancelSave()
+ {
+ m_dirty = false;
+ m_saveTimer.stop();
+ }
+
+ bool saveIsScheduled() const
+ {
+ return m_dirty;
+ }
+
+ void updateFSObserver()
+ {
+ bool observingFS = m_watcher->directories().contains(m_path);
+ if(m_observed && m_locked)
+ {
+ if(!observingFS)
+ {
+ qWarning() << "Will watch" << m_path;
+ if(!m_watcher->addPath(m_path))
+ {
+ qWarning() << "Failed to start watching" << m_path;
+ }
+ }
+ }
+ else
+ {
+ if(observingFS)
+ {
+ qWarning() << "Will stop watching" << m_path;
+ if(!m_watcher->removePath(m_path))
+ {
+ qWarning() << "Failed to stop watching" << m_path;
+ }
+ }
+ }
+ }
+
+ QString serversPath()
+ {
+ QFileInfo foo(FS::PathCombine(m_path, "servers.dat"));
+ return foo.filePath();
+ }
private:
- bool m_loaded = false;
- bool m_locked = false;
- bool m_observed = false;
- bool m_dirty = false;
- QString m_path;
- QList<Server> m_servers;
- QFileSystemWatcher *m_watcher = nullptr;
- QTimer m_saveTimer;
+ bool m_loaded = false;
+ bool m_locked = false;
+ bool m_observed = false;
+ bool m_dirty = false;
+ QString m_path;
+ QList<Server> m_servers;
+ QFileSystemWatcher *m_watcher = nullptr;
+ QTimer m_saveTimer;
};
ServersPage::ServersPage(MinecraftInstance * inst, QWidget* parent)
- : QWidget(parent), ui(new Ui::ServersPage)
+ : QWidget(parent), ui(new Ui::ServersPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- m_inst = inst;
- m_model = new ServersModel(inst->minecraftRoot(), this);
- ui->serversView->setIconSize(QSize(64,64));
- ui->serversView->setModel(m_model);
- auto head = ui->serversView->header();
- if(head->count())
- {
- head->setSectionResizeMode(0, QHeaderView::Stretch);
- for(int i = 1; i < head->count(); i++)
- {
- head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- }
- }
-
- auto selectionModel = ui->serversView->selectionModel();
- connect(selectionModel, &QItemSelectionModel::currentChanged, this, &ServersPage::currentChanged);
- connect(m_inst, &MinecraftInstance::runningStatusChanged, this, &ServersPage::on_RunningState_changed);
- connect(ui->nameLine, &QLineEdit::textEdited, this, &ServersPage::nameEdited);
- connect(ui->addressLine, &QLineEdit::textEdited, this, &ServersPage::addressEdited);
- connect(ui->resourceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(resourceIndexChanged(int)));
- connect(m_model, &QAbstractItemModel::rowsRemoved, this, &ServersPage::rowsRemoved);
-
- m_locked = m_inst->isRunning();
- if(m_locked)
- {
- m_model->lock();
- }
-
- updateState();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ m_inst = inst;
+ m_model = new ServersModel(inst->minecraftRoot(), this);
+ ui->serversView->setIconSize(QSize(64,64));
+ ui->serversView->setModel(m_model);
+ auto head = ui->serversView->header();
+ if(head->count())
+ {
+ head->setSectionResizeMode(0, QHeaderView::Stretch);
+ for(int i = 1; i < head->count(); i++)
+ {
+ head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
+ }
+ }
+
+ auto selectionModel = ui->serversView->selectionModel();
+ connect(selectionModel, &QItemSelectionModel::currentChanged, this, &ServersPage::currentChanged);
+ connect(m_inst, &MinecraftInstance::runningStatusChanged, this, &ServersPage::on_RunningState_changed);
+ connect(ui->nameLine, &QLineEdit::textEdited, this, &ServersPage::nameEdited);
+ connect(ui->addressLine, &QLineEdit::textEdited, this, &ServersPage::addressEdited);
+ connect(ui->resourceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(resourceIndexChanged(int)));
+ connect(m_model, &QAbstractItemModel::rowsRemoved, this, &ServersPage::rowsRemoved);
+
+ m_locked = m_inst->isRunning();
+ if(m_locked)
+ {
+ m_model->lock();
+ }
+
+ updateState();
}
ServersPage::~ServersPage()
{
- m_model->saveNow();
+ m_model->saveNow();
}
void ServersPage::on_RunningState_changed(bool running)
{
- if(m_locked == running)
- {
- return;
- }
- m_locked = running;
- if(m_locked)
- {
- m_model->lock();
- }
- else
- {
- m_model->unlock();
- }
- updateState();
+ if(m_locked == running)
+ {
+ return;
+ }
+ m_locked = running;
+ if(m_locked)
+ {
+ m_model->lock();
+ }
+ else
+ {
+ m_model->unlock();
+ }
+ updateState();
}
void ServersPage::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
- int nextServer = -1;
- if (!current.isValid())
- {
- nextServer = -1;
- }
- else
- {
- nextServer = current.row();
- }
- currentServer = nextServer;
- updateState();
+ int nextServer = -1;
+ if (!current.isValid())
+ {
+ nextServer = -1;
+ }
+ else
+ {
+ nextServer = current.row();
+ }
+ currentServer = nextServer;
+ updateState();
}
// WARNING: this is here because currentChanged is not accurate when removing rows. the current item needs to be fixed up after removal.
void ServersPage::rowsRemoved(const QModelIndex& parent, int first, int last)
{
- if(currentServer < first)
- {
- // current was before the removal
- return;
- }
- else if(currentServer >= first && currentServer <= last)
- {
- // current got removed...
- return;
- }
- else
- {
- // current was past the removal
- int count = last - first + 1;
- currentServer -= count;
- }
+ if(currentServer < first)
+ {
+ // current was before the removal
+ return;
+ }
+ else if(currentServer >= first && currentServer <= last)
+ {
+ // current got removed...
+ return;
+ }
+ else
+ {
+ // current was past the removal
+ int count = last - first + 1;
+ currentServer -= count;
+ }
}
void ServersPage::nameEdited(const QString& name)
{
- m_model->setName(currentServer, name);
+ m_model->setName(currentServer, name);
}
void ServersPage::addressEdited(const QString& address)
{
- m_model->setAddress(currentServer, address);
+ m_model->setAddress(currentServer, address);
}
void ServersPage::resourceIndexChanged(int index)
{
- auto acceptsTextures = Server::AcceptsTextures(index);
- m_model->setAcceptsTextures(currentServer, acceptsTextures);
+ auto acceptsTextures = Server::AcceptsTextures(index);
+ m_model->setAcceptsTextures(currentServer, acceptsTextures);
}
void ServersPage::updateState()
{
- auto server = m_model->at(currentServer);
-
- bool serverEditEnabled = server && !m_locked;
- ui->addressLine->setEnabled(serverEditEnabled);
- ui->nameLine->setEnabled(serverEditEnabled);
- ui->resourceComboBox->setEnabled(serverEditEnabled);
- ui->moveDownBtn->setEnabled(serverEditEnabled);
- ui->moveUpBtn->setEnabled(serverEditEnabled);
- ui->removeBtn->setEnabled(serverEditEnabled);
-
- if(server)
- {
- ui->addressLine->setText(server->m_address);
- ui->nameLine->setText(server->m_name);
- ui->resourceComboBox->setCurrentIndex(int(server->m_acceptsTextures));
- }
- else
- {
- ui->addressLine->setText(QString());
- ui->nameLine->setText(QString());
- ui->resourceComboBox->setCurrentIndex(0);
- }
-
- ui->addBtn->setDisabled(m_locked);
+ auto server = m_model->at(currentServer);
+
+ bool serverEditEnabled = server && !m_locked;
+ ui->addressLine->setEnabled(serverEditEnabled);
+ ui->nameLine->setEnabled(serverEditEnabled);
+ ui->resourceComboBox->setEnabled(serverEditEnabled);
+ ui->moveDownBtn->setEnabled(serverEditEnabled);
+ ui->moveUpBtn->setEnabled(serverEditEnabled);
+ ui->removeBtn->setEnabled(serverEditEnabled);
+
+ if(server)
+ {
+ ui->addressLine->setText(server->m_address);
+ ui->nameLine->setText(server->m_name);
+ ui->resourceComboBox->setCurrentIndex(int(server->m_acceptsTextures));
+ }
+ else
+ {
+ ui->addressLine->setText(QString());
+ ui->nameLine->setText(QString());
+ ui->resourceComboBox->setCurrentIndex(0);
+ }
+
+ ui->addBtn->setDisabled(m_locked);
}
void ServersPage::openedImpl()
{
- m_model->observe();
+ m_model->observe();
}
void ServersPage::closedImpl()
{
- m_model->unobserve();
+ m_model->unobserve();
}
void ServersPage::on_addBtn_clicked()
{
- int position = m_model->addEmptyRow(currentServer + 1);
- if(position < 0)
- {
- return;
- }
- // select the new row
- ui->serversView->selectionModel()->setCurrentIndex(
- m_model->index(position),
- QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear | QItemSelectionModel::Rows
- );
- currentServer = position;
+ int position = m_model->addEmptyRow(currentServer + 1);
+ if(position < 0)
+ {
+ return;
+ }
+ // select the new row
+ ui->serversView->selectionModel()->setCurrentIndex(
+ m_model->index(position),
+ QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear | QItemSelectionModel::Rows
+ );
+ currentServer = position;
}
void ServersPage::on_removeBtn_clicked()
{
- m_model->removeRow(currentServer);
+ m_model->removeRow(currentServer);
}
void ServersPage::on_moveUpBtn_clicked()
{
- if(m_model->moveUp(currentServer))
- {
- currentServer --;
- }
+ if(m_model->moveUp(currentServer))
+ {
+ currentServer --;
+ }
}
void ServersPage::on_moveDownBtn_clicked()
{
- if(m_model->moveDown(currentServer))
- {
- currentServer ++;
- }
+ if(m_model->moveDown(currentServer))
+ {
+ currentServer ++;
+ }
}
#include "ServersPage.moc"
diff --git a/application/pages/instance/ServersPage.h b/application/pages/instance/ServersPage.h
index 538e5b8d..fd690e9e 100644
--- a/application/pages/instance/ServersPage.h
+++ b/application/pages/instance/ServersPage.h
@@ -32,55 +32,55 @@ class MinecraftInstance;
class ServersPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ServersPage(MinecraftInstance *inst, QWidget *parent = 0);
- virtual ~ServersPage();
+ explicit ServersPage(MinecraftInstance *inst, QWidget *parent = 0);
+ virtual ~ServersPage();
- void openedImpl() override;
- void closedImpl() override;
+ void openedImpl() override;
+ void closedImpl() override;
- virtual QString displayName() const override
- {
- return tr("Servers");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("unknown_server");
- }
- virtual QString id() const override
- {
- return "servers";
- }
- virtual QString helpPage() const override
- {
- return "Servers-management";
- }
+ virtual QString displayName() const override
+ {
+ return tr("Servers");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("unknown_server");
+ }
+ virtual QString id() const override
+ {
+ return "servers";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Servers-management";
+ }
private:
- void updateState();
- void scheduleSave();
- bool saveIsScheduled() const;
+ void updateState();
+ void scheduleSave();
+ bool saveIsScheduled() const;
private slots:
- void currentChanged(const QModelIndex &current, const QModelIndex &previous);
- void rowsRemoved(const QModelIndex &parent, int first, int last);
+ void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+ void rowsRemoved(const QModelIndex &parent, int first, int last);
- void on_addBtn_clicked();
- void on_removeBtn_clicked();
- void on_moveUpBtn_clicked();
- void on_moveDownBtn_clicked();
- void on_RunningState_changed(bool running);
+ void on_addBtn_clicked();
+ void on_removeBtn_clicked();
+ void on_moveUpBtn_clicked();
+ void on_moveDownBtn_clicked();
+ void on_RunningState_changed(bool running);
- void nameEdited(const QString & name);
- void addressEdited(const QString & address);
- void resourceIndexChanged(int index);
+ void nameEdited(const QString & name);
+ void addressEdited(const QString & address);
+ void resourceIndexChanged(int index);
private: // data
- int currentServer = -1;
- bool m_locked = true;
- Ui::ServersPage *ui = nullptr;
- ServersModel * m_model = nullptr;
- MinecraftInstance * m_inst = nullptr;
+ int currentServer = -1;
+ bool m_locked = true;
+ Ui::ServersPage *ui = nullptr;
+ ServersModel * m_model = nullptr;
+ MinecraftInstance * m_inst = nullptr;
};
diff --git a/application/pages/instance/TexturePackPage.h b/application/pages/instance/TexturePackPage.h
index b03614f0..094cc199 100644
--- a/application/pages/instance/TexturePackPage.h
+++ b/application/pages/instance/TexturePackPage.h
@@ -5,15 +5,15 @@
class TexturePackPage : public ModFolderPage
{
public:
- explicit TexturePackPage(MinecraftInstance *instance, QWidget *parent = 0)
- : ModFolderPage(instance, instance->texturePackList(), "texturepacks", "resourcepacks",
- tr("Texture packs"), "Texture-packs", parent)
- {
- ui->configFolderBtn->setHidden(true);
- }
- virtual ~TexturePackPage() {}
- virtual bool shouldDisplay() const override
- {
- return m_inst->traits().contains("texturepacks");
- }
+ explicit TexturePackPage(MinecraftInstance *instance, QWidget *parent = 0)
+ : ModFolderPage(instance, instance->texturePackList(), "texturepacks", "resourcepacks",
+ tr("Texture packs"), "Texture-packs", parent)
+ {
+ ui->configFolderBtn->setHidden(true);
+ }
+ virtual ~TexturePackPage() {}
+ virtual bool shouldDisplay() const override
+ {
+ return m_inst->traits().contains("texturepacks");
+ }
};
diff --git a/application/pages/instance/VersionPage.cpp b/application/pages/instance/VersionPage.cpp
index 981cbd8c..54a228a4 100644
--- a/application/pages/instance/VersionPage.cpp
+++ b/application/pages/instance/VersionPage.cpp
@@ -49,521 +49,521 @@
class IconProxy : public QIdentityProxyModel
{
- Q_OBJECT
+ Q_OBJECT
public:
- IconProxy(QWidget *parentWidget) : QIdentityProxyModel(parentWidget)
- {
- connect(parentWidget, &QObject::destroyed, this, &IconProxy::widgetGone);
- m_parentWidget = parentWidget;
- }
-
- virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override
- {
- QVariant var = QIdentityProxyModel::data(mapToSource(proxyIndex), role);
- int column = proxyIndex.column();
- if(column == 0 && role == Qt::DecorationRole && m_parentWidget)
- {
- if(!var.isNull())
- {
- auto string = var.toString();
- if(string == "warning")
- {
- return MMC->getThemedIcon("status-yellow");
- }
- else if(string == "error")
- {
- return MMC->getThemedIcon("status-bad");
- }
- }
- return MMC->getThemedIcon("status-good");
- }
- return var;
- }
+ IconProxy(QWidget *parentWidget) : QIdentityProxyModel(parentWidget)
+ {
+ connect(parentWidget, &QObject::destroyed, this, &IconProxy::widgetGone);
+ m_parentWidget = parentWidget;
+ }
+
+ virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override
+ {
+ QVariant var = QIdentityProxyModel::data(mapToSource(proxyIndex), role);
+ int column = proxyIndex.column();
+ if(column == 0 && role == Qt::DecorationRole && m_parentWidget)
+ {
+ if(!var.isNull())
+ {
+ auto string = var.toString();
+ if(string == "warning")
+ {
+ return MMC->getThemedIcon("status-yellow");
+ }
+ else if(string == "error")
+ {
+ return MMC->getThemedIcon("status-bad");
+ }
+ }
+ return MMC->getThemedIcon("status-good");
+ }
+ return var;
+ }
private slots:
- void widgetGone()
- {
- m_parentWidget = nullptr;
- }
+ void widgetGone()
+ {
+ m_parentWidget = nullptr;
+ }
private:
- QWidget *m_parentWidget = nullptr;
+ QWidget *m_parentWidget = nullptr;
};
QIcon VersionPage::icon() const
{
- return MMC->icons()->getIcon(m_inst->iconKey());
+ return MMC->icons()->getIcon(m_inst->iconKey());
}
bool VersionPage::shouldDisplay() const
{
- return !m_inst->isRunning();
+ return !m_inst->isRunning();
}
VersionPage::VersionPage(MinecraftInstance *inst, QWidget *parent)
- : QWidget(parent), ui(new Ui::VersionPage), m_inst(inst)
+ : QWidget(parent), ui(new Ui::VersionPage), m_inst(inst)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- m_profile = m_inst->getComponentList();
-
- reloadComponentList();
-
- if (m_profile)
- {
- auto proxy = new IconProxy(ui->packageView);
- proxy->setSourceModel(m_profile.get());
- ui->packageView->setModel(proxy);
- ui->packageView->installEventFilter(this);
- ui->packageView->setSelectionMode(QAbstractItemView::SingleSelection);
- connect(ui->packageView->selectionModel(), &QItemSelectionModel::currentChanged, this, &VersionPage::versionCurrent);
- auto smodel = ui->packageView->selectionModel();
- connect(smodel, &QItemSelectionModel::currentChanged, this, &VersionPage::packageCurrent);
- updateVersionControls();
- // select first item.
- preselect(0);
- }
- else
- {
- disableVersionControls();
- }
- connect(m_inst, &MinecraftInstance::versionReloaded, this,
- &VersionPage::updateVersionControls);
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ m_profile = m_inst->getComponentList();
+
+ reloadComponentList();
+
+ if (m_profile)
+ {
+ auto proxy = new IconProxy(ui->packageView);
+ proxy->setSourceModel(m_profile.get());
+ ui->packageView->setModel(proxy);
+ ui->packageView->installEventFilter(this);
+ ui->packageView->setSelectionMode(QAbstractItemView::SingleSelection);
+ connect(ui->packageView->selectionModel(), &QItemSelectionModel::currentChanged, this, &VersionPage::versionCurrent);
+ auto smodel = ui->packageView->selectionModel();
+ connect(smodel, &QItemSelectionModel::currentChanged, this, &VersionPage::packageCurrent);
+ updateVersionControls();
+ // select first item.
+ preselect(0);
+ }
+ else
+ {
+ disableVersionControls();
+ }
+ connect(m_inst, &MinecraftInstance::versionReloaded, this,
+ &VersionPage::updateVersionControls);
}
VersionPage::~VersionPage()
{
- delete ui;
+ delete ui;
}
void VersionPage::packageCurrent(const QModelIndex &current, const QModelIndex &previous)
{
- if (!current.isValid())
- {
- ui->frame->clear();
- return;
- }
- int row = current.row();
- auto patch = m_profile->getComponent(row);
- auto severity = patch->getProblemSeverity();
- switch(severity)
- {
- case ProblemSeverity::Warning:
- ui->frame->setModText(tr("%1 possibly has issues.").arg(patch->getName()));
- break;
- case ProblemSeverity::Error:
- ui->frame->setModText(tr("%1 has issues!").arg(patch->getName()));
- break;
- default:
- case ProblemSeverity::None:
- ui->frame->clear();
- return;
- }
-
- auto &problems = patch->getProblems();
- QString problemOut;
- for (auto &problem: problems)
- {
- if(problem.m_severity == ProblemSeverity::Error)
- {
- problemOut += tr("Error: ");
- }
- else if(problem.m_severity == ProblemSeverity::Warning)
- {
- problemOut += tr("Warning: ");
- }
- problemOut += problem.m_description;
- problemOut += "\n";
- }
- ui->frame->setModDescription(problemOut);
+ if (!current.isValid())
+ {
+ ui->frame->clear();
+ return;
+ }
+ int row = current.row();
+ auto patch = m_profile->getComponent(row);
+ auto severity = patch->getProblemSeverity();
+ switch(severity)
+ {
+ case ProblemSeverity::Warning:
+ ui->frame->setModText(tr("%1 possibly has issues.").arg(patch->getName()));
+ break;
+ case ProblemSeverity::Error:
+ ui->frame->setModText(tr("%1 has issues!").arg(patch->getName()));
+ break;
+ default:
+ case ProblemSeverity::None:
+ ui->frame->clear();
+ return;
+ }
+
+ auto &problems = patch->getProblems();
+ QString problemOut;
+ for (auto &problem: problems)
+ {
+ if(problem.m_severity == ProblemSeverity::Error)
+ {
+ problemOut += tr("Error: ");
+ }
+ else if(problem.m_severity == ProblemSeverity::Warning)
+ {
+ problemOut += tr("Warning: ");
+ }
+ problemOut += problem.m_description;
+ problemOut += "\n";
+ }
+ ui->frame->setModDescription(problemOut);
}
void VersionPage::updateVersionControls()
{
- ui->forgeBtn->setEnabled(true);
- ui->liteloaderBtn->setEnabled(true);
- updateButtons();
+ ui->forgeBtn->setEnabled(true);
+ ui->liteloaderBtn->setEnabled(true);
+ updateButtons();
}
void VersionPage::disableVersionControls()
{
- ui->forgeBtn->setEnabled(false);
- ui->liteloaderBtn->setEnabled(false);
- ui->reloadBtn->setEnabled(false);
- updateButtons();
+ ui->forgeBtn->setEnabled(false);
+ ui->liteloaderBtn->setEnabled(false);
+ ui->reloadBtn->setEnabled(false);
+ updateButtons();
}
bool VersionPage::reloadComponentList()
{
- try
- {
- m_profile->reload(Net::Mode::Online);
- return true;
- }
- catch (const Exception &e)
- {
- QMessageBox::critical(this, tr("Error"), e.cause());
- return false;
- }
- catch (...)
- {
- QMessageBox::critical(
- this, tr("Error"),
- tr("Couldn't load the instance profile."));
- return false;
- }
+ try
+ {
+ m_profile->reload(Net::Mode::Online);
+ return true;
+ }
+ catch (const Exception &e)
+ {
+ QMessageBox::critical(this, tr("Error"), e.cause());
+ return false;
+ }
+ catch (...)
+ {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Couldn't load the instance profile."));
+ return false;
+ }
}
void VersionPage::on_reloadBtn_clicked()
{
- reloadComponentList();
- m_container->refreshContainer();
+ reloadComponentList();
+ m_container->refreshContainer();
}
void VersionPage::on_removeBtn_clicked()
{
- if (ui->packageView->currentIndex().isValid())
- {
- // FIXME: use actual model, not reloading.
- if (!m_profile->remove(ui->packageView->currentIndex().row()))
- {
- QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file"));
- }
- }
- updateButtons();
- reloadComponentList();
- m_container->refreshContainer();
+ if (ui->packageView->currentIndex().isValid())
+ {
+ // FIXME: use actual model, not reloading.
+ if (!m_profile->remove(ui->packageView->currentIndex().row()))
+ {
+ QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file"));
+ }
+ }
+ updateButtons();
+ reloadComponentList();
+ m_container->refreshContainer();
}
void VersionPage::on_modBtn_clicked()
{
- if(m_container)
- {
- m_container->selectPage("mods");
- }
+ if(m_container)
+ {
+ m_container->selectPage("mods");
+ }
}
void VersionPage::on_jarmodBtn_clicked()
{
- auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
- if(!list.empty())
- {
- m_profile->installJarMods(list);
- }
- updateButtons();
+ auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
+ if(!list.empty())
+ {
+ m_profile->installJarMods(list);
+ }
+ updateButtons();
}
void VersionPage::on_jarBtn_clicked()
{
- auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
- if(!jarPath.isEmpty())
- {
- m_profile->installCustomJar(jarPath);
- }
- updateButtons();
+ auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
+ if(!jarPath.isEmpty())
+ {
+ m_profile->installCustomJar(jarPath);
+ }
+ updateButtons();
}
void VersionPage::on_moveUpBtn_clicked()
{
- try
- {
- m_profile->move(currentRow(), ComponentList::MoveUp);
- }
- catch (const Exception &e)
- {
- QMessageBox::critical(this, tr("Error"), e.cause());
- }
- updateButtons();
+ try
+ {
+ m_profile->move(currentRow(), ComponentList::MoveUp);
+ }
+ catch (const Exception &e)
+ {
+ QMessageBox::critical(this, tr("Error"), e.cause());
+ }
+ updateButtons();
}
void VersionPage::on_moveDownBtn_clicked()
{
- try
- {
- m_profile->move(currentRow(), ComponentList::MoveDown);
- }
- catch (const Exception &e)
- {
- QMessageBox::critical(this, tr("Error"), e.cause());
- }
- updateButtons();
+ try
+ {
+ m_profile->move(currentRow(), ComponentList::MoveDown);
+ }
+ catch (const Exception &e)
+ {
+ QMessageBox::critical(this, tr("Error"), e.cause());
+ }
+ updateButtons();
}
void VersionPage::on_changeVersionBtn_clicked()
{
- auto versionRow = currentRow();
- if(versionRow == -1)
- {
- return;
- }
- auto patch = m_profile->getComponent(versionRow);
- auto name = patch->getName();
- auto list = patch->getVersionList();
- if(!list)
- {
- return;
- }
- auto uid = list->uid();
- // FIXME: this is a horrible HACK. Get version filtering information from the actual metadata...
- if(uid == "net.minecraftforge")
- {
- on_forgeBtn_clicked();
- return;
- }
- else if (uid == "com.mumfrey.liteloader")
- {
- on_liteloaderBtn_clicked();
- return;
- }
- VersionSelectDialog vselect(list.get(), tr("Change %1 version").arg(name), this);
- auto currentVersion = patch->getVersion();
- if(!currentVersion.isEmpty())
- {
- vselect.setCurrentVersion(currentVersion);
- }
- if (!vselect.exec() || !vselect.selectedVersion())
- return;
-
- qDebug() << "Change" << uid << "to" << vselect.selectedVersion()->descriptor();
- bool important = false;
- if(uid == "net.minecraft")
- {
- important = true;
- }
- m_profile->setComponentVersion(uid, vselect.selectedVersion()->descriptor(), important);
- m_profile->resolve(Net::Mode::Online);
- m_container->refreshContainer();
+ auto versionRow = currentRow();
+ if(versionRow == -1)
+ {
+ return;
+ }
+ auto patch = m_profile->getComponent(versionRow);
+ auto name = patch->getName();
+ auto list = patch->getVersionList();
+ if(!list)
+ {
+ return;
+ }
+ auto uid = list->uid();
+ // FIXME: this is a horrible HACK. Get version filtering information from the actual metadata...
+ if(uid == "net.minecraftforge")
+ {
+ on_forgeBtn_clicked();
+ return;
+ }
+ else if (uid == "com.mumfrey.liteloader")
+ {
+ on_liteloaderBtn_clicked();
+ return;
+ }
+ VersionSelectDialog vselect(list.get(), tr("Change %1 version").arg(name), this);
+ auto currentVersion = patch->getVersion();
+ if(!currentVersion.isEmpty())
+ {
+ vselect.setCurrentVersion(currentVersion);
+ }
+ if (!vselect.exec() || !vselect.selectedVersion())
+ return;
+
+ qDebug() << "Change" << uid << "to" << vselect.selectedVersion()->descriptor();
+ bool important = false;
+ if(uid == "net.minecraft")
+ {
+ important = true;
+ }
+ m_profile->setComponentVersion(uid, vselect.selectedVersion()->descriptor(), important);
+ m_profile->resolve(Net::Mode::Online);
+ m_container->refreshContainer();
}
void VersionPage::on_downloadBtn_clicked()
{
- if (!MMC->accounts()->anyAccountIsValid())
- {
- CustomMessageBox::selectable(
- this, tr("Error"),
- tr("MultiMC cannot download Minecraft or update instances unless you have at least "
- "one account added.\nPlease add your Mojang or Minecraft account."),
- QMessageBox::Warning)->show();
- return;
- }
-
- auto updateTask = m_inst->createUpdateTask(Net::Mode::Online);
- if (!updateTask)
- {
- return;
- }
- ProgressDialog tDialog(this);
- connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString)));
- // FIXME: unused return value
- tDialog.execWithTask(updateTask.get());
- updateButtons();
- m_container->refreshContainer();
+ if (!MMC->accounts()->anyAccountIsValid())
+ {
+ CustomMessageBox::selectable(
+ this, tr("Error"),
+ tr("MultiMC cannot download Minecraft or update instances unless you have at least "
+ "one account added.\nPlease add your Mojang or Minecraft account."),
+ QMessageBox::Warning)->show();
+ return;
+ }
+
+ auto updateTask = m_inst->createUpdateTask(Net::Mode::Online);
+ if (!updateTask)
+ {
+ return;
+ }
+ ProgressDialog tDialog(this);
+ connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString)));
+ // FIXME: unused return value
+ tDialog.execWithTask(updateTask.get());
+ updateButtons();
+ m_container->refreshContainer();
}
void VersionPage::on_forgeBtn_clicked()
{
- auto vlist = ENV.metadataIndex()->get("net.minecraftforge");
- if(!vlist)
- {
- return;
- }
- VersionSelectDialog vselect(vlist.get(), tr("Select Forge version"), this);
- vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
- vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
- vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!"));
-
- auto currentVersion = m_profile->getComponentVersion("net.minecraftforge");
- if(!currentVersion.isEmpty())
- {
- vselect.setCurrentVersion(currentVersion);
- }
-
- if (vselect.exec() && vselect.selectedVersion())
- {
- auto vsn = vselect.selectedVersion();
- m_profile->setComponentVersion("net.minecraftforge", vsn->descriptor());
- m_profile->resolve(Net::Mode::Online);
- // m_profile->installVersion();
- preselect(m_profile->rowCount(QModelIndex())-1);
- m_container->refreshContainer();
- }
+ auto vlist = ENV.metadataIndex()->get("net.minecraftforge");
+ if(!vlist)
+ {
+ return;
+ }
+ VersionSelectDialog vselect(vlist.get(), tr("Select Forge version"), this);
+ vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
+ vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
+ vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!"));
+
+ auto currentVersion = m_profile->getComponentVersion("net.minecraftforge");
+ if(!currentVersion.isEmpty())
+ {
+ vselect.setCurrentVersion(currentVersion);
+ }
+
+ if (vselect.exec() && vselect.selectedVersion())
+ {
+ auto vsn = vselect.selectedVersion();
+ m_profile->setComponentVersion("net.minecraftforge", vsn->descriptor());
+ m_profile->resolve(Net::Mode::Online);
+ // m_profile->installVersion();
+ preselect(m_profile->rowCount(QModelIndex())-1);
+ m_container->refreshContainer();
+ }
}
void VersionPage::on_addEmptyBtn_clicked()
{
- NewComponentDialog compdialog(QString(), QString(), this);
- QStringList blacklist;
- for(int i = 0; i < m_profile->rowCount(); i++)
- {
- auto comp = m_profile->getComponent(i);
- blacklist.push_back(comp->getID());
- }
- compdialog.setBlacklist(blacklist);
- if (compdialog.exec())
- {
- qDebug() << "name:" << compdialog.name();
- qDebug() << "uid:" << compdialog.uid();
- m_profile->installEmpty(compdialog.uid(), compdialog.name());
- }
+ NewComponentDialog compdialog(QString(), QString(), this);
+ QStringList blacklist;
+ for(int i = 0; i < m_profile->rowCount(); i++)
+ {
+ auto comp = m_profile->getComponent(i);
+ blacklist.push_back(comp->getID());
+ }
+ compdialog.setBlacklist(blacklist);
+ if (compdialog.exec())
+ {
+ qDebug() << "name:" << compdialog.name();
+ qDebug() << "uid:" << compdialog.uid();
+ m_profile->installEmpty(compdialog.uid(), compdialog.name());
+ }
}
void VersionPage::on_liteloaderBtn_clicked()
{
- auto vlist = ENV.metadataIndex()->get("com.mumfrey.liteloader");
- if(!vlist)
- {
- return;
- }
- VersionSelectDialog vselect(vlist.get(), tr("Select LiteLoader version"), this);
- vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
- vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
- vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!"));
-
- auto currentVersion = m_profile->getComponentVersion("com.mumfrey.liteloader");
- if(!currentVersion.isEmpty())
- {
- vselect.setCurrentVersion(currentVersion);
- }
-
- if (vselect.exec() && vselect.selectedVersion())
- {
- auto vsn = vselect.selectedVersion();
- m_profile->setComponentVersion("com.mumfrey.liteloader", vsn->descriptor());
- m_profile->resolve(Net::Mode::Online);
- // m_profile->installVersion(vselect.selectedVersion());
- preselect(m_profile->rowCount(QModelIndex())-1);
- m_container->refreshContainer();
- }
+ auto vlist = ENV.metadataIndex()->get("com.mumfrey.liteloader");
+ if(!vlist)
+ {
+ return;
+ }
+ VersionSelectDialog vselect(vlist.get(), tr("Select LiteLoader version"), this);
+ vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
+ vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
+ vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!"));
+
+ auto currentVersion = m_profile->getComponentVersion("com.mumfrey.liteloader");
+ if(!currentVersion.isEmpty())
+ {
+ vselect.setCurrentVersion(currentVersion);
+ }
+
+ if (vselect.exec() && vselect.selectedVersion())
+ {
+ auto vsn = vselect.selectedVersion();
+ m_profile->setComponentVersion("com.mumfrey.liteloader", vsn->descriptor());
+ m_profile->resolve(Net::Mode::Online);
+ // m_profile->installVersion(vselect.selectedVersion());
+ preselect(m_profile->rowCount(QModelIndex())-1);
+ m_container->refreshContainer();
+ }
}
void VersionPage::versionCurrent(const QModelIndex &current, const QModelIndex &previous)
{
- currentIdx = current.row();
- updateButtons(currentIdx);
+ currentIdx = current.row();
+ updateButtons(currentIdx);
}
void VersionPage::preselect(int row)
{
- if(row < 0)
- {
- row = 0;
- }
- if(row >= m_profile->rowCount(QModelIndex()))
- {
- row = m_profile->rowCount(QModelIndex()) - 1;
- }
- if(row < 0)
- {
- return;
- }
- auto model_index = m_profile->index(row);
- ui->packageView->selectionModel()->select(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
- updateButtons(row);
+ if(row < 0)
+ {
+ row = 0;
+ }
+ if(row >= m_profile->rowCount(QModelIndex()))
+ {
+ row = m_profile->rowCount(QModelIndex()) - 1;
+ }
+ if(row < 0)
+ {
+ return;
+ }
+ auto model_index = m_profile->index(row);
+ ui->packageView->selectionModel()->select(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
+ updateButtons(row);
}
void VersionPage::updateButtons(int row)
{
- if(row == -1)
- row = currentRow();
- auto patch = m_profile->getComponent(row);
- if (!patch)
- {
- ui->removeBtn->setDisabled(true);
- ui->moveDownBtn->setDisabled(true);
- ui->moveUpBtn->setDisabled(true);
- ui->changeVersionBtn->setDisabled(true);
- ui->editBtn->setDisabled(true);
- ui->customizeBtn->setDisabled(true);
- ui->revertBtn->setDisabled(true);
- }
- else
- {
- ui->removeBtn->setEnabled(patch->isRemovable());
- ui->moveDownBtn->setEnabled(patch->isMoveable());
- ui->moveUpBtn->setEnabled(patch->isMoveable());
- ui->changeVersionBtn->setEnabled(patch->isVersionChangeable());
- ui->editBtn->setEnabled(patch->isCustom());
- ui->customizeBtn->setEnabled(patch->isCustomizable());
- ui->revertBtn->setEnabled(patch->isRevertible());
- }
+ if(row == -1)
+ row = currentRow();
+ auto patch = m_profile->getComponent(row);
+ if (!patch)
+ {
+ ui->removeBtn->setDisabled(true);
+ ui->moveDownBtn->setDisabled(true);
+ ui->moveUpBtn->setDisabled(true);
+ ui->changeVersionBtn->setDisabled(true);
+ ui->editBtn->setDisabled(true);
+ ui->customizeBtn->setDisabled(true);
+ ui->revertBtn->setDisabled(true);
+ }
+ else
+ {
+ ui->removeBtn->setEnabled(patch->isRemovable());
+ ui->moveDownBtn->setEnabled(patch->isMoveable());
+ ui->moveUpBtn->setEnabled(patch->isMoveable());
+ ui->changeVersionBtn->setEnabled(patch->isVersionChangeable());
+ ui->editBtn->setEnabled(patch->isCustom());
+ ui->customizeBtn->setEnabled(patch->isCustomizable());
+ ui->revertBtn->setEnabled(patch->isRevertible());
+ }
}
void VersionPage::onGameUpdateError(QString error)
{
- CustomMessageBox::selectable(this, tr("Error updating instance"), error,
- QMessageBox::Warning)->show();
+ CustomMessageBox::selectable(this, tr("Error updating instance"), error,
+ QMessageBox::Warning)->show();
}
Component * VersionPage::current()
{
- auto row = currentRow();
- if(row < 0)
- {
- return nullptr;
- }
- return m_profile->getComponent(row);
+ auto row = currentRow();
+ if(row < 0)
+ {
+ return nullptr;
+ }
+ return m_profile->getComponent(row);
}
int VersionPage::currentRow()
{
- if (ui->packageView->selectionModel()->selectedRows().isEmpty())
- {
- return -1;
- }
- return ui->packageView->selectionModel()->selectedRows().first().row();
+ if (ui->packageView->selectionModel()->selectedRows().isEmpty())
+ {
+ return -1;
+ }
+ return ui->packageView->selectionModel()->selectedRows().first().row();
}
void VersionPage::on_customizeBtn_clicked()
{
- auto version = currentRow();
- if(version == -1)
- {
- return;
- }
- auto patch = m_profile->getComponent(version);
- if(!patch->getVersionFile())
- {
- // TODO: wait for the update task to finish here...
- return;
- }
- if(!m_profile->customize(version))
- {
- // TODO: some error box here
- }
- updateButtons();
- preselect(currentIdx);
+ auto version = currentRow();
+ if(version == -1)
+ {
+ return;
+ }
+ auto patch = m_profile->getComponent(version);
+ if(!patch->getVersionFile())
+ {
+ // TODO: wait for the update task to finish here...
+ return;
+ }
+ if(!m_profile->customize(version))
+ {
+ // TODO: some error box here
+ }
+ updateButtons();
+ preselect(currentIdx);
}
void VersionPage::on_editBtn_clicked()
{
- auto version = current();
- if(!version)
- {
- return;
- }
- auto filename = version->getFilename();
- if(!QFileInfo::exists(filename))
- {
- qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!";
- return;
- }
- MMC->openJsonEditor(filename);
+ auto version = current();
+ if(!version)
+ {
+ return;
+ }
+ auto filename = version->getFilename();
+ if(!QFileInfo::exists(filename))
+ {
+ qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!";
+ return;
+ }
+ MMC->openJsonEditor(filename);
}
void VersionPage::on_revertBtn_clicked()
{
- auto version = currentRow();
- if(version == -1)
- {
- return;
- }
- if(!m_profile->revertToBase(version))
- {
- // TODO: some error box here
- }
- updateButtons();
- preselect(currentIdx);
- m_container->refreshContainer();
+ auto version = currentRow();
+ if(version == -1)
+ {
+ return;
+ }
+ if(!m_profile->revertToBase(version))
+ {
+ // TODO: some error box here
+ }
+ updateButtons();
+ preselect(currentIdx);
+ m_container->refreshContainer();
}
#include "VersionPage.moc"
diff --git a/application/pages/instance/VersionPage.h b/application/pages/instance/VersionPage.h
index 85304ea5..cc990614 100644
--- a/application/pages/instance/VersionPage.h
+++ b/application/pages/instance/VersionPage.h
@@ -28,68 +28,68 @@ class VersionPage;
class VersionPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit VersionPage(MinecraftInstance *inst, QWidget *parent = 0);
- virtual ~VersionPage();
- virtual QString displayName() const override
- {
- return tr("Version");
- }
- virtual QIcon icon() const override;
- virtual QString id() const override
- {
- return "version";
- }
- virtual QString helpPage() const override
- {
- return "Instance-Version";
- }
- virtual bool shouldDisplay() const override;
+ explicit VersionPage(MinecraftInstance *inst, QWidget *parent = 0);
+ virtual ~VersionPage();
+ virtual QString displayName() const override
+ {
+ return tr("Version");
+ }
+ virtual QIcon icon() const override;
+ virtual QString id() const override
+ {
+ return "version";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Instance-Version";
+ }
+ virtual bool shouldDisplay() const override;
private slots:
- void on_forgeBtn_clicked();
- void on_addEmptyBtn_clicked();
- void on_liteloaderBtn_clicked();
- void on_reloadBtn_clicked();
- void on_removeBtn_clicked();
- void on_moveUpBtn_clicked();
- void on_moveDownBtn_clicked();
- void on_jarmodBtn_clicked();
- void on_jarBtn_clicked();
- void on_revertBtn_clicked();
- void on_editBtn_clicked();
- void on_modBtn_clicked();
- void on_customizeBtn_clicked();
- void on_downloadBtn_clicked();
+ void on_forgeBtn_clicked();
+ void on_addEmptyBtn_clicked();
+ void on_liteloaderBtn_clicked();
+ void on_reloadBtn_clicked();
+ void on_removeBtn_clicked();
+ void on_moveUpBtn_clicked();
+ void on_moveDownBtn_clicked();
+ void on_jarmodBtn_clicked();
+ void on_jarBtn_clicked();
+ void on_revertBtn_clicked();
+ void on_editBtn_clicked();
+ void on_modBtn_clicked();
+ void on_customizeBtn_clicked();
+ void on_downloadBtn_clicked();
- void updateVersionControls();
- void disableVersionControls();
- void on_changeVersionBtn_clicked();
+ void updateVersionControls();
+ void disableVersionControls();
+ void on_changeVersionBtn_clicked();
private:
- Component * current();
- int currentRow();
- void updateButtons(int row = -1);
- void preselect(int row = 0);
- int doUpdate();
+ Component * current();
+ int currentRow();
+ void updateButtons(int row = -1);
+ void preselect(int row = 0);
+ int doUpdate();
protected:
- /// FIXME: this shouldn't be necessary!
- bool reloadComponentList();
+ /// FIXME: this shouldn't be necessary!
+ bool reloadComponentList();
private:
- Ui::VersionPage *ui;
- std::shared_ptr<ComponentList> m_profile;
- MinecraftInstance *m_inst;
- int currentIdx = 0;
+ Ui::VersionPage *ui;
+ std::shared_ptr<ComponentList> m_profile;
+ MinecraftInstance *m_inst;
+ int currentIdx = 0;
public slots:
- void versionCurrent(const QModelIndex &current, const QModelIndex &previous);
+ void versionCurrent(const QModelIndex &current, const QModelIndex &previous);
private slots:
- void onGameUpdateError(QString error);
- void packageCurrent(const QModelIndex &current, const QModelIndex &previous);
+ void onGameUpdateError(QString error);
+ void packageCurrent(const QModelIndex &current, const QModelIndex &previous);
};
diff --git a/application/pages/instance/WorldListPage.cpp b/application/pages/instance/WorldListPage.cpp
index 539d26a0..67a36fd9 100644
--- a/application/pages/instance/WorldListPage.cpp
+++ b/application/pages/instance/WorldListPage.cpp
@@ -32,299 +32,299 @@
#include <FileSystem.h>
WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QString id,
- QString iconName, QString displayName, QString helpPage,
- QWidget *parent)
- : QWidget(parent), m_inst(inst), ui(new Ui::WorldListPage), m_worlds(worlds), m_iconName(iconName), m_id(id), m_displayName(displayName), m_helpName(helpPage)
+ QString iconName, QString displayName, QString helpPage,
+ QWidget *parent)
+ : QWidget(parent), m_inst(inst), ui(new Ui::WorldListPage), m_worlds(worlds), m_iconName(iconName), m_id(id), m_displayName(displayName), m_helpName(helpPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- QSortFilterProxyModel * proxy = new QSortFilterProxyModel(this);
- proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
- proxy->setSourceModel(m_worlds.get());
- ui->worldTreeView->setSortingEnabled(true);
- ui->worldTreeView->setModel(proxy);
- ui->worldTreeView->installEventFilter(this);
-
- auto head = ui->worldTreeView->header();
-
- head->setSectionResizeMode(0, QHeaderView::Stretch);
- head->setSectionResizeMode(1, QHeaderView::ResizeToContents);
- connect(ui->worldTreeView->selectionModel(),
- SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this,
- SLOT(worldChanged(const QModelIndex &, const QModelIndex &)));
- worldChanged(QModelIndex(), QModelIndex());
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ QSortFilterProxyModel * proxy = new QSortFilterProxyModel(this);
+ proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
+ proxy->setSourceModel(m_worlds.get());
+ ui->worldTreeView->setSortingEnabled(true);
+ ui->worldTreeView->setModel(proxy);
+ ui->worldTreeView->installEventFilter(this);
+
+ auto head = ui->worldTreeView->header();
+
+ head->setSectionResizeMode(0, QHeaderView::Stretch);
+ head->setSectionResizeMode(1, QHeaderView::ResizeToContents);
+ connect(ui->worldTreeView->selectionModel(),
+ SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this,
+ SLOT(worldChanged(const QModelIndex &, const QModelIndex &)));
+ worldChanged(QModelIndex(), QModelIndex());
}
void WorldListPage::openedImpl()
{
- m_worlds->startWatching();
+ m_worlds->startWatching();
}
void WorldListPage::closedImpl()
{
- m_worlds->stopWatching();
+ m_worlds->stopWatching();
}
WorldListPage::~WorldListPage()
{
- m_worlds->stopWatching();
- delete ui;
+ m_worlds->stopWatching();
+ delete ui;
}
bool WorldListPage::shouldDisplay() const
{
- return true;
+ return true;
}
bool WorldListPage::worldListFilter(QKeyEvent *keyEvent)
{
- switch (keyEvent->key())
- {
- case Qt::Key_Delete:
- on_rmWorldBtn_clicked();
- return true;
- default:
- break;
- }
- return QWidget::eventFilter(ui->worldTreeView, keyEvent);
+ switch (keyEvent->key())
+ {
+ case Qt::Key_Delete:
+ on_rmWorldBtn_clicked();
+ return true;
+ default:
+ break;
+ }
+ return QWidget::eventFilter(ui->worldTreeView, keyEvent);
}
bool WorldListPage::eventFilter(QObject *obj, QEvent *ev)
{
- if (ev->type() != QEvent::KeyPress)
- {
- return QWidget::eventFilter(obj, ev);
- }
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
- if (obj == ui->worldTreeView)
- return worldListFilter(keyEvent);
- return QWidget::eventFilter(obj, ev);
+ if (ev->type() != QEvent::KeyPress)
+ {
+ return QWidget::eventFilter(obj, ev);
+ }
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
+ if (obj == ui->worldTreeView)
+ return worldListFilter(keyEvent);
+ return QWidget::eventFilter(obj, ev);
}
void WorldListPage::on_rmWorldBtn_clicked()
{
- auto proxiedIndex = getSelectedWorld();
-
- if(!proxiedIndex.isValid())
- return;
-
- auto result = QMessageBox::question(this,
- tr("Are you sure?"),
- tr("This will remove the selected world permenantly.\n"
- "The world will be gone forever (A LONG TIME).\n"
- "\n"
- "Do you want to continue?"));
- if(result != QMessageBox::Yes)
- {
- return;
- }
- m_worlds->stopWatching();
- m_worlds->deleteWorld(proxiedIndex.row());
- m_worlds->startWatching();
+ auto proxiedIndex = getSelectedWorld();
+
+ if(!proxiedIndex.isValid())
+ return;
+
+ auto result = QMessageBox::question(this,
+ tr("Are you sure?"),
+ tr("This will remove the selected world permenantly.\n"
+ "The world will be gone forever (A LONG TIME).\n"
+ "\n"
+ "Do you want to continue?"));
+ if(result != QMessageBox::Yes)
+ {
+ return;
+ }
+ m_worlds->stopWatching();
+ m_worlds->deleteWorld(proxiedIndex.row());
+ m_worlds->startWatching();
}
void WorldListPage::on_viewFolderBtn_clicked()
{
- DesktopServices::openDirectory(m_worlds->dir().absolutePath(), true);
+ DesktopServices::openDirectory(m_worlds->dir().absolutePath(), true);
}
QModelIndex WorldListPage::getSelectedWorld()
{
- auto index = ui->worldTreeView->selectionModel()->currentIndex();
+ auto index = ui->worldTreeView->selectionModel()->currentIndex();
- auto proxy = (QSortFilterProxyModel *) ui->worldTreeView->model();
- return proxy->mapToSource(index);
+ auto proxy = (QSortFilterProxyModel *) ui->worldTreeView->model();
+ return proxy->mapToSource(index);
}
void WorldListPage::on_copySeedBtn_clicked()
{
- QModelIndex index = getSelectedWorld();
-
- if (!index.isValid())
- {
- return;
- }
- int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong();
- MMC->clipboard()->setText(QString::number(seed));
+ QModelIndex index = getSelectedWorld();
+
+ if (!index.isValid())
+ {
+ return;
+ }
+ int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong();
+ MMC->clipboard()->setText(QString::number(seed));
}
void WorldListPage::on_mcEditBtn_clicked()
{
- if(m_mceditStarting)
- return;
+ if(m_mceditStarting)
+ return;
- auto mcedit = MMC->mcedit();
+ auto mcedit = MMC->mcedit();
- const QString mceditPath = mcedit->path();
+ const QString mceditPath = mcedit->path();
- QModelIndex index = getSelectedWorld();
+ QModelIndex index = getSelectedWorld();
- if (!index.isValid())
- {
- return;
- }
+ if (!index.isValid())
+ {
+ return;
+ }
- if(!worldSafetyNagQuestion())
- return;
+ if(!worldSafetyNagQuestion())
+ return;
- auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString();
+ auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString();
- auto program = mcedit->getProgramPath();
- if(program.size())
- {
+ auto program = mcedit->getProgramPath();
+ if(program.size())
+ {
#ifdef Q_OS_WIN32
- if(!QProcess::startDetached(program, {fullPath}, mceditPath))
- {
- mceditError();
- }
+ if(!QProcess::startDetached(program, {fullPath}, mceditPath))
+ {
+ mceditError();
+ }
#else
- m_mceditProcess.reset(new LoggedProcess());
- m_mceditProcess->setDetachable(true);
- connect(m_mceditProcess.get(), &LoggedProcess::stateChanged, this, &WorldListPage::mceditState);
- m_mceditProcess->start(program, {fullPath});
- m_mceditProcess->setWorkingDirectory(mceditPath);
- m_mceditStarting = true;
+ m_mceditProcess.reset(new LoggedProcess());
+ m_mceditProcess->setDetachable(true);
+ connect(m_mceditProcess.get(), &LoggedProcess::stateChanged, this, &WorldListPage::mceditState);
+ m_mceditProcess->start(program, {fullPath});
+ m_mceditProcess->setWorkingDirectory(mceditPath);
+ m_mceditStarting = true;
#endif
- }
- else
- {
- QMessageBox::warning(
- this->parentWidget(),
- tr("No MCEdit found or set up!"),
- tr("You do not have MCEdit set up or it was moved.\nYou can set it up in the global settings.")
- );
- }
+ }
+ else
+ {
+ QMessageBox::warning(
+ this->parentWidget(),
+ tr("No MCEdit found or set up!"),
+ tr("You do not have MCEdit set up or it was moved.\nYou can set it up in the global settings.")
+ );
+ }
}
void WorldListPage::mceditError()
{
- QMessageBox::warning(
- this->parentWidget(),
- tr("MCEdit failed to start!"),
- tr("MCEdit failed to start.\nIt may be necessary to reinstall it.")
- );
+ QMessageBox::warning(
+ this->parentWidget(),
+ tr("MCEdit failed to start!"),
+ tr("MCEdit failed to start.\nIt may be necessary to reinstall it.")
+ );
}
void WorldListPage::mceditState(LoggedProcess::State state)
{
- bool failed = false;
- switch(state)
- {
- case LoggedProcess::NotRunning:
- case LoggedProcess::Starting:
- return;
- case LoggedProcess::FailedToStart:
- case LoggedProcess::Crashed:
- case LoggedProcess::Aborted:
- {
- failed = true;
- }
- case LoggedProcess::Running:
- case LoggedProcess::Finished:
- {
- m_mceditStarting = false;
- break;
- }
- }
- if(failed)
- {
- mceditError();
- }
+ bool failed = false;
+ switch(state)
+ {
+ case LoggedProcess::NotRunning:
+ case LoggedProcess::Starting:
+ return;
+ case LoggedProcess::FailedToStart:
+ case LoggedProcess::Crashed:
+ case LoggedProcess::Aborted:
+ {
+ failed = true;
+ }
+ case LoggedProcess::Running:
+ case LoggedProcess::Finished:
+ {
+ m_mceditStarting = false;
+ break;
+ }
+ }
+ if(failed)
+ {
+ mceditError();
+ }
}
void WorldListPage::worldChanged(const QModelIndex &current, const QModelIndex &previous)
{
- QModelIndex index = getSelectedWorld();
- bool enable = index.isValid();
- ui->copySeedBtn->setEnabled(enable);
- ui->mcEditBtn->setEnabled(enable);
- ui->rmWorldBtn->setEnabled(enable);
- ui->copyBtn->setEnabled(enable);
- ui->renameBtn->setEnabled(enable);
+ QModelIndex index = getSelectedWorld();
+ bool enable = index.isValid();
+ ui->copySeedBtn->setEnabled(enable);
+ ui->mcEditBtn->setEnabled(enable);
+ ui->rmWorldBtn->setEnabled(enable);
+ ui->copyBtn->setEnabled(enable);
+ ui->renameBtn->setEnabled(enable);
}
void WorldListPage::on_addBtn_clicked()
{
- auto list = GuiUtil::BrowseForFiles(
- m_helpName,
- tr("Select a Minecraft world zip"),
- tr("Minecraft World Zip File (*.zip)"), QString(), this->parentWidget());
- if (!list.empty())
- {
- m_worlds->stopWatching();
- for (auto filename : list)
- {
- m_worlds->installWorld(QFileInfo(filename));
- }
- m_worlds->startWatching();
- }
+ auto list = GuiUtil::BrowseForFiles(
+ m_helpName,
+ tr("Select a Minecraft world zip"),
+ tr("Minecraft World Zip File (*.zip)"), QString(), this->parentWidget());
+ if (!list.empty())
+ {
+ m_worlds->stopWatching();
+ for (auto filename : list)
+ {
+ m_worlds->installWorld(QFileInfo(filename));
+ }
+ m_worlds->startWatching();
+ }
}
bool WorldListPage::isWorldSafe(QModelIndex)
{
- return !m_inst->isRunning();
+ return !m_inst->isRunning();
}
bool WorldListPage::worldSafetyNagQuestion()
{
- if(!isWorldSafe(getSelectedWorld()))
- {
- auto result = QMessageBox::question(this, tr("Copy World"), tr("Changing a world while Minecraft is running is potentially unsafe.\nDo you wish to proceed?"));
- if(result == QMessageBox::No)
- {
- return false;
- }
- }
- return true;
+ if(!isWorldSafe(getSelectedWorld()))
+ {
+ auto result = QMessageBox::question(this, tr("Copy World"), tr("Changing a world while Minecraft is running is potentially unsafe.\nDo you wish to proceed?"));
+ if(result == QMessageBox::No)
+ {
+ return false;
+ }
+ }
+ return true;
}
void WorldListPage::on_copyBtn_clicked()
{
- QModelIndex index = getSelectedWorld();
- if (!index.isValid())
- {
- return;
- }
-
- if(!worldSafetyNagQuestion())
- return;
-
- auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
- auto world = (World *) worldVariant.value<void *>();
- bool ok = false;
- QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new name for the copy."), QLineEdit::Normal, world->name(), &ok);
-
- if (ok && name.length() > 0)
- {
- world->install(m_worlds->dir().absolutePath(), name);
- }
+ QModelIndex index = getSelectedWorld();
+ if (!index.isValid())
+ {
+ return;
+ }
+
+ if(!worldSafetyNagQuestion())
+ return;
+
+ auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
+ auto world = (World *) worldVariant.value<void *>();
+ bool ok = false;
+ QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new name for the copy."), QLineEdit::Normal, world->name(), &ok);
+
+ if (ok && name.length() > 0)
+ {
+ world->install(m_worlds->dir().absolutePath(), name);
+ }
}
void WorldListPage::on_renameBtn_clicked()
{
- QModelIndex index = getSelectedWorld();
- if (!index.isValid())
- {
- return;
- }
+ QModelIndex index = getSelectedWorld();
+ if (!index.isValid())
+ {
+ return;
+ }
- if(!worldSafetyNagQuestion())
- return;
+ if(!worldSafetyNagQuestion())
+ return;
- auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
- auto world = (World *) worldVariant.value<void *>();
+ auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
+ auto world = (World *) worldVariant.value<void *>();
- bool ok = false;
- QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new world name."), QLineEdit::Normal, world->name(), &ok);
+ bool ok = false;
+ QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new world name."), QLineEdit::Normal, world->name(), &ok);
- if (ok && name.length() > 0)
- {
- world->rename(name);
- }
+ if (ok && name.length() > 0)
+ {
+ world->rename(name);
+ }
}
void WorldListPage::on_refreshBtn_clicked()
{
- m_worlds->update();
+ m_worlds->update();
}
diff --git a/application/pages/instance/WorldListPage.h b/application/pages/instance/WorldListPage.h
index 71b87bda..ae9ad4a3 100644
--- a/application/pages/instance/WorldListPage.h
+++ b/application/pages/instance/WorldListPage.h
@@ -30,67 +30,67 @@ class WorldListPage;
class WorldListPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QString id,
- QString iconName, QString displayName, QString helpPage = "",
- QWidget *parent = 0);
- virtual ~WorldListPage();
+ explicit WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QString id,
+ QString iconName, QString displayName, QString helpPage = "",
+ QWidget *parent = 0);
+ virtual ~WorldListPage();
- virtual QString displayName() const override
- {
- return m_displayName;
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon(m_iconName);
- }
- virtual QString id() const override
- {
- return m_id;
- }
- virtual QString helpPage() const override
- {
- return m_helpName;
- }
- virtual bool shouldDisplay() const override;
+ virtual QString displayName() const override
+ {
+ return m_displayName;
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon(m_iconName);
+ }
+ virtual QString id() const override
+ {
+ return m_id;
+ }
+ virtual QString helpPage() const override
+ {
+ return m_helpName;
+ }
+ virtual bool shouldDisplay() const override;
- virtual void openedImpl() override;
- virtual void closedImpl() override;
+ virtual void openedImpl() override;
+ virtual void closedImpl() override;
protected:
- bool eventFilter(QObject *obj, QEvent *ev) override;
- bool worldListFilter(QKeyEvent *ev);
+ bool eventFilter(QObject *obj, QEvent *ev) override;
+ bool worldListFilter(QKeyEvent *ev);
protected:
- BaseInstance *m_inst;
+ BaseInstance *m_inst;
private:
- QModelIndex getSelectedWorld();
- bool isWorldSafe(QModelIndex index);
- bool worldSafetyNagQuestion();
- void mceditError();
+ QModelIndex getSelectedWorld();
+ bool isWorldSafe(QModelIndex index);
+ bool worldSafetyNagQuestion();
+ void mceditError();
private:
- Ui::WorldListPage *ui;
- std::shared_ptr<WorldList> m_worlds;
- unique_qobject_ptr<LoggedProcess> m_mceditProcess;
- bool m_mceditStarting = false;
- QString m_iconName;
- QString m_id;
- QString m_displayName;
- QString m_helpName;
+ Ui::WorldListPage *ui;
+ std::shared_ptr<WorldList> m_worlds;
+ unique_qobject_ptr<LoggedProcess> m_mceditProcess;
+ bool m_mceditStarting = false;
+ QString m_iconName;
+ QString m_id;
+ QString m_displayName;
+ QString m_helpName;
private slots:
- void on_copySeedBtn_clicked();
- void on_mcEditBtn_clicked();
- void on_rmWorldBtn_clicked();
- void on_addBtn_clicked();
- void on_copyBtn_clicked();
- void on_renameBtn_clicked();
- void on_refreshBtn_clicked();
- void on_viewFolderBtn_clicked();
- void worldChanged(const QModelIndex &current, const QModelIndex &previous);
- void mceditState(LoggedProcess::State state);
+ void on_copySeedBtn_clicked();
+ void on_mcEditBtn_clicked();
+ void on_rmWorldBtn_clicked();
+ void on_addBtn_clicked();
+ void on_copyBtn_clicked();
+ void on_renameBtn_clicked();
+ void on_refreshBtn_clicked();
+ void on_viewFolderBtn_clicked();
+ void worldChanged(const QModelIndex &current, const QModelIndex &previous);
+ void mceditState(LoggedProcess::State state);
};
diff --git a/application/pages/modplatform/FTBPage.cpp b/application/pages/modplatform/FTBPage.cpp
index f438fce7..ae4dd92e 100644
--- a/application/pages/modplatform/FTBPage.cpp
+++ b/application/pages/modplatform/FTBPage.cpp
@@ -10,213 +10,213 @@
#include "FtbListModel.h"
FTBPage::FTBPage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), dialog(dialog), ui(new Ui::FTBPage)
+ : QWidget(parent), dialog(dialog), ui(new Ui::FTBPage)
{
- ftbFetchTask = new FtbPackFetchTask();
+ ftbFetchTask = new FtbPackFetchTask();
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
- {
- publicFilterModel = new FtbFilterModel(this);
- publicListModel = new FtbListModel(this);
- publicFilterModel->setSourceModel(publicListModel);
+ {
+ publicFilterModel = new FtbFilterModel(this);
+ publicListModel = new FtbListModel(this);
+ publicFilterModel->setSourceModel(publicListModel);
- ui->publicPackList->setModel(publicFilterModel);
- ui->publicPackList->setSortingEnabled(true);
- ui->publicPackList->header()->hide();
- ui->publicPackList->setIndentation(0);
- ui->publicPackList->setIconSize(QSize(42, 42));
+ ui->publicPackList->setModel(publicFilterModel);
+ ui->publicPackList->setSortingEnabled(true);
+ ui->publicPackList->header()->hide();
+ ui->publicPackList->setIndentation(0);
+ ui->publicPackList->setIconSize(QSize(42, 42));
- for(int i = 0; i < publicFilterModel->getAvailableSortings().size(); i++)
- {
- ui->sortByBox->addItem(publicFilterModel->getAvailableSortings().keys().at(i));
- }
+ for(int i = 0; i < publicFilterModel->getAvailableSortings().size(); i++)
+ {
+ ui->sortByBox->addItem(publicFilterModel->getAvailableSortings().keys().at(i));
+ }
- ui->sortByBox->setCurrentText(publicFilterModel->translateCurrentSorting());
- }
+ ui->sortByBox->setCurrentText(publicFilterModel->translateCurrentSorting());
+ }
- {
- thirdPartyFilterModel = new FtbFilterModel(this);
- thirdPartyModel = new FtbListModel(this);
- thirdPartyFilterModel->setSourceModel(thirdPartyModel);
+ {
+ thirdPartyFilterModel = new FtbFilterModel(this);
+ thirdPartyModel = new FtbListModel(this);
+ thirdPartyFilterModel->setSourceModel(thirdPartyModel);
- ui->thirdPartyPackList->setModel(thirdPartyFilterModel);
- ui->thirdPartyPackList->setSortingEnabled(true);
- ui->thirdPartyPackList->header()->hide();
- ui->thirdPartyPackList->setIndentation(0);
- ui->thirdPartyPackList->setIconSize(QSize(42, 42));
+ ui->thirdPartyPackList->setModel(thirdPartyFilterModel);
+ ui->thirdPartyPackList->setSortingEnabled(true);
+ ui->thirdPartyPackList->header()->hide();
+ ui->thirdPartyPackList->setIndentation(0);
+ ui->thirdPartyPackList->setIconSize(QSize(42, 42));
- thirdPartyFilterModel->setSorting(publicFilterModel->getCurrentSorting());
- }
+ thirdPartyFilterModel->setSorting(publicFilterModel->getCurrentSorting());
+ }
- ui->packVersionSelection->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- ui->packVersionSelection->view()->parentWidget()->setMaximumHeight(300);
+ ui->packVersionSelection->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ ui->packVersionSelection->view()->parentWidget()->setMaximumHeight(300);
- connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &FTBPage::onSortingSelectionChanged);
- connect(ui->packVersionSelection, &QComboBox::currentTextChanged, this, &FTBPage::onVersionSelectionItemChanged);
+ connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &FTBPage::onSortingSelectionChanged);
+ connect(ui->packVersionSelection, &QComboBox::currentTextChanged, this, &FTBPage::onVersionSelectionItemChanged);
- connect(ui->publicPackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &FTBPage::onPublicPackSelectionChanged);
- connect(ui->thirdPartyPackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &FTBPage::onThirdPartyPackSelectionChanged);
+ connect(ui->publicPackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &FTBPage::onPublicPackSelectionChanged);
+ connect(ui->thirdPartyPackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &FTBPage::onThirdPartyPackSelectionChanged);
- connect(ui->ftbTabWidget, &QTabWidget::currentChanged, this, &FTBPage::onTabChanged);
+ connect(ui->ftbTabWidget, &QTabWidget::currentChanged, this, &FTBPage::onTabChanged);
- ui->modpackInfo->setOpenExternalLinks(true);
+ ui->modpackInfo->setOpenExternalLinks(true);
- ui->publicPackList->selectionModel()->reset();
- ui->thirdPartyPackList->selectionModel()->reset();
+ ui->publicPackList->selectionModel()->reset();
+ ui->thirdPartyPackList->selectionModel()->reset();
}
FTBPage::~FTBPage()
{
- delete ui;
- if(ftbFetchTask) {
- ftbFetchTask->deleteLater();
- }
+ delete ui;
+ if(ftbFetchTask) {
+ ftbFetchTask->deleteLater();
+ }
}
bool FTBPage::shouldDisplay() const
{
- return true;
+ return true;
}
void FTBPage::openedImpl()
{
- if(!initialized)
- {
- connect(ftbFetchTask, &FtbPackFetchTask::finished, this, &FTBPage::ftbPackDataDownloadSuccessfully);
- connect(ftbFetchTask, &FtbPackFetchTask::failed, this, &FTBPage::ftbPackDataDownloadFailed);
- ftbFetchTask->fetch();
- initialized = true;
- }
- suggestCurrent();
+ if(!initialized)
+ {
+ connect(ftbFetchTask, &FtbPackFetchTask::finished, this, &FTBPage::ftbPackDataDownloadSuccessfully);
+ connect(ftbFetchTask, &FtbPackFetchTask::failed, this, &FTBPage::ftbPackDataDownloadFailed);
+ ftbFetchTask->fetch();
+ initialized = true;
+ }
+ suggestCurrent();
}
void FTBPage::suggestCurrent()
{
- if(isOpened)
- {
- if(!selected.broken)
- {
- dialog->setSuggestedPack(selected.name, new FtbPackInstallTask(selected, selectedVersion));
- if(selected.type == FtbPackType::Public) {
- publicListModel->getLogo(selected.logo, [this](QString logo){
- dialog->setSuggestedIconFromFile(logo, "ftb_" + selected.name);
- });
- } else if (selected.type == FtbPackType::ThirdParty) {
- thirdPartyModel->getLogo(selected.logo, [this](QString logo){
- dialog->setSuggestedIconFromFile(logo, "ftb_" + selected.name);
- });
- }
- }
- else
- {
- dialog->setSuggestedPack();
- }
- }
+ if(isOpened)
+ {
+ if(!selected.broken)
+ {
+ dialog->setSuggestedPack(selected.name, new FtbPackInstallTask(selected, selectedVersion));
+ if(selected.type == FtbPackType::Public) {
+ publicListModel->getLogo(selected.logo, [this](QString logo){
+ dialog->setSuggestedIconFromFile(logo, "ftb_" + selected.name);
+ });
+ } else if (selected.type == FtbPackType::ThirdParty) {
+ thirdPartyModel->getLogo(selected.logo, [this](QString logo){
+ dialog->setSuggestedIconFromFile(logo, "ftb_" + selected.name);
+ });
+ }
+ }
+ else
+ {
+ dialog->setSuggestedPack();
+ }
+ }
}
void FTBPage::ftbPackDataDownloadSuccessfully(FtbModpackList publicPacks, FtbModpackList thirdPartyPacks)
{
- publicListModel->fill(publicPacks);
- thirdPartyModel->fill(thirdPartyPacks);
+ publicListModel->fill(publicPacks);
+ thirdPartyModel->fill(thirdPartyPacks);
}
void FTBPage::ftbPackDataDownloadFailed(QString reason)
{
- //TODO: Display the error
+ //TODO: Display the error
}
void FTBPage::onPublicPackSelectionChanged(QModelIndex now, QModelIndex prev)
{
- if(!now.isValid())
- {
- onPackSelectionChanged();
- return;
- }
- FtbModpack selectedPack = publicFilterModel->data(now, Qt::UserRole).value<FtbModpack>();
- onPackSelectionChanged(&selectedPack);
+ if(!now.isValid())
+ {
+ onPackSelectionChanged();
+ return;
+ }
+ FtbModpack selectedPack = publicFilterModel->data(now, Qt::UserRole).value<FtbModpack>();
+ onPackSelectionChanged(&selectedPack);
}
void FTBPage::onThirdPartyPackSelectionChanged(QModelIndex now, QModelIndex prev)
{
- if(!now.isValid())
- {
- onPackSelectionChanged();
- return;
- }
- FtbModpack selectedPack = thirdPartyFilterModel->data(now, Qt::UserRole).value<FtbModpack>();
- onPackSelectionChanged(&selectedPack);
+ if(!now.isValid())
+ {
+ onPackSelectionChanged();
+ return;
+ }
+ FtbModpack selectedPack = thirdPartyFilterModel->data(now, Qt::UserRole).value<FtbModpack>();
+ onPackSelectionChanged(&selectedPack);
}
void FTBPage::onPackSelectionChanged(FtbModpack* pack)
{
- ui->packVersionSelection->clear();
- if(pack)
- {
- ui->modpackInfo->setHtml("Pack by <b>" + pack->author + "</b>" + "<br>Minecraft " + pack->mcVersion + "<br>"
- "<br>" + pack->description + "<ul><li>" + pack->mods.replace(";", "</li><li>") + "</li></ul>");
- bool currentAdded = false;
-
- for(int i = 0; i < pack->oldVersions.size(); i++)
- {
- if(pack->currentVersion == pack->oldVersions.at(i))
- {
- currentAdded = true;
- }
- ui->packVersionSelection->addItem(pack->oldVersions.at(i));
- }
-
- if(!currentAdded)
- {
- ui->packVersionSelection->addItem(pack->currentVersion);
- }
- selected = *pack;
- }
- suggestCurrent();
+ ui->packVersionSelection->clear();
+ if(pack)
+ {
+ ui->modpackInfo->setHtml("Pack by <b>" + pack->author + "</b>" + "<br>Minecraft " + pack->mcVersion + "<br>"
+ "<br>" + pack->description + "<ul><li>" + pack->mods.replace(";", "</li><li>") + "</li></ul>");
+ bool currentAdded = false;
+
+ for(int i = 0; i < pack->oldVersions.size(); i++)
+ {
+ if(pack->currentVersion == pack->oldVersions.at(i))
+ {
+ currentAdded = true;
+ }
+ ui->packVersionSelection->addItem(pack->oldVersions.at(i));
+ }
+
+ if(!currentAdded)
+ {
+ ui->packVersionSelection->addItem(pack->currentVersion);
+ }
+ selected = *pack;
+ }
+ suggestCurrent();
}
void FTBPage::onVersionSelectionItemChanged(QString data)
{
- if(data.isNull() || data.isEmpty())
- {
- selectedVersion = "";
- return;
- }
-
- selectedVersion = data;
- suggestCurrent();
+ if(data.isNull() || data.isEmpty())
+ {
+ selectedVersion = "";
+ return;
+ }
+
+ selectedVersion = data;
+ suggestCurrent();
}
void FTBPage::onSortingSelectionChanged(QString data)
{
- FtbFilterModel::Sorting toSet = publicFilterModel->getAvailableSortings().value(data);
- publicFilterModel->setSorting(toSet);
- thirdPartyFilterModel->setSorting(toSet);
+ FtbFilterModel::Sorting toSet = publicFilterModel->getAvailableSortings().value(data);
+ publicFilterModel->setSorting(toSet);
+ thirdPartyFilterModel->setSorting(toSet);
}
void FTBPage::onTabChanged(int tab)
{
- FtbFilterModel* currentModel = nullptr;
- QTreeView* currentList = nullptr;
- if (tab == 0)
- {
- currentModel = publicFilterModel;
- currentList = ui->publicPackList;
- }
- else
- {
- currentModel = thirdPartyFilterModel;
- currentList = ui->thirdPartyPackList;
- }
- QModelIndex idx = currentList->currentIndex();
- if(idx.isValid())
- {
- auto pack = currentModel->data(idx, Qt::UserRole).value<FtbModpack>();
- onPackSelectionChanged(&pack);
- }
- else
- {
- onPackSelectionChanged();
- }
+ FtbFilterModel* currentModel = nullptr;
+ QTreeView* currentList = nullptr;
+ if (tab == 0)
+ {
+ currentModel = publicFilterModel;
+ currentList = ui->publicPackList;
+ }
+ else
+ {
+ currentModel = thirdPartyFilterModel;
+ currentList = ui->thirdPartyPackList;
+ }
+ QModelIndex idx = currentList->currentIndex();
+ if(idx.isValid())
+ {
+ auto pack = currentModel->data(idx, Qt::UserRole).value<FtbModpack>();
+ onPackSelectionChanged(&pack);
+ }
+ else
+ {
+ onPackSelectionChanged();
+ }
}
diff --git a/application/pages/modplatform/FTBPage.h b/application/pages/modplatform/FTBPage.h
index 00c5e9c5..46c14c30 100644
--- a/application/pages/modplatform/FTBPage.h
+++ b/application/pages/modplatform/FTBPage.h
@@ -34,59 +34,59 @@ class NewInstanceDialog;
class FTBPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit FTBPage(NewInstanceDialog * dialog, QWidget *parent = 0);
- virtual ~FTBPage();
- QString displayName() const override
- {
- return tr("FTB Legacy");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("ftb_logo");
- }
- QString id() const override
- {
- return "ftb";
- }
- QString helpPage() const override
- {
- return "FTB-platform";
- }
- bool shouldDisplay() const override;
- void openedImpl() override;
+ explicit FTBPage(NewInstanceDialog * dialog, QWidget *parent = 0);
+ virtual ~FTBPage();
+ QString displayName() const override
+ {
+ return tr("FTB Legacy");
+ }
+ QIcon icon() const override
+ {
+ return MMC->getThemedIcon("ftb_logo");
+ }
+ QString id() const override
+ {
+ return "ftb";
+ }
+ QString helpPage() const override
+ {
+ return "FTB-platform";
+ }
+ bool shouldDisplay() const override;
+ void openedImpl() override;
private:
- void suggestCurrent();
- void onPackSelectionChanged(FtbModpack *pack = nullptr);
+ void suggestCurrent();
+ void onPackSelectionChanged(FtbModpack *pack = nullptr);
private slots:
- void ftbPackDataDownloadSuccessfully(FtbModpackList publicPacks, FtbModpackList thirdPartyPacks);
- void ftbPackDataDownloadFailed(QString reason);
+ void ftbPackDataDownloadSuccessfully(FtbModpackList publicPacks, FtbModpackList thirdPartyPacks);
+ void ftbPackDataDownloadFailed(QString reason);
- void onSortingSelectionChanged(QString data);
- void onVersionSelectionItemChanged(QString data);
+ void onSortingSelectionChanged(QString data);
+ void onVersionSelectionItemChanged(QString data);
- void onPublicPackSelectionChanged(QModelIndex first, QModelIndex second);
- void onThirdPartyPackSelectionChanged(QModelIndex first, QModelIndex second);
+ void onPublicPackSelectionChanged(QModelIndex first, QModelIndex second);
+ void onThirdPartyPackSelectionChanged(QModelIndex first, QModelIndex second);
- void onTabChanged(int tab);
+ void onTabChanged(int tab);
private:
- bool initialized = false;
- FtbModpack selected;
- QString selectedVersion;
+ bool initialized = false;
+ FtbModpack selected;
+ QString selectedVersion;
- FtbListModel* publicListModel = nullptr;
- FtbFilterModel* publicFilterModel = nullptr;
+ FtbListModel* publicListModel = nullptr;
+ FtbFilterModel* publicFilterModel = nullptr;
- FtbListModel *thirdPartyModel = nullptr;
- FtbFilterModel *thirdPartyFilterModel = nullptr;
+ FtbListModel *thirdPartyModel = nullptr;
+ FtbFilterModel *thirdPartyFilterModel = nullptr;
- FtbPackFetchTask *ftbFetchTask = nullptr;
- NewInstanceDialog* dialog = nullptr;
+ FtbPackFetchTask *ftbFetchTask = nullptr;
+ NewInstanceDialog* dialog = nullptr;
- Ui::FTBPage *ui = nullptr;
+ Ui::FTBPage *ui = nullptr;
};
diff --git a/application/pages/modplatform/FtbListModel.cpp b/application/pages/modplatform/FtbListModel.cpp
index c14907c6..0d0d4d5e 100644
--- a/application/pages/modplatform/FtbListModel.cpp
+++ b/application/pages/modplatform/FtbListModel.cpp
@@ -12,54 +12,54 @@
FtbFilterModel::FtbFilterModel(QObject *parent) : QSortFilterProxyModel(parent)
{
- currentSorting = Sorting::ByGameVersion;
- sortings.insert(tr("Sort by name"), Sorting::ByName);
- sortings.insert(tr("Sort by game version"), Sorting::ByGameVersion);
+ currentSorting = Sorting::ByGameVersion;
+ sortings.insert(tr("Sort by name"), Sorting::ByName);
+ sortings.insert(tr("Sort by game version"), Sorting::ByGameVersion);
}
bool FtbFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
- FtbModpack leftPack = sourceModel()->data(left, Qt::UserRole).value<FtbModpack>();
- FtbModpack rightPack = sourceModel()->data(right, Qt::UserRole).value<FtbModpack>();
+ FtbModpack leftPack = sourceModel()->data(left, Qt::UserRole).value<FtbModpack>();
+ FtbModpack rightPack = sourceModel()->data(right, Qt::UserRole).value<FtbModpack>();
- if(currentSorting == Sorting::ByGameVersion) {
- Version lv(leftPack.mcVersion);
- Version rv(rightPack.mcVersion);
- return lv < rv;
+ if(currentSorting == Sorting::ByGameVersion) {
+ Version lv(leftPack.mcVersion);
+ Version rv(rightPack.mcVersion);
+ return lv < rv;
- } else if(currentSorting == Sorting::ByName) {
- return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0;
- }
+ } else if(currentSorting == Sorting::ByName) {
+ return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0;
+ }
- //UHM, some inavlid value set?!
- qWarning() << "Invalid sorting set!";
- return true;
+ //UHM, some inavlid value set?!
+ qWarning() << "Invalid sorting set!";
+ return true;
}
bool FtbFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
- return true;
+ return true;
}
const QMap<QString, FtbFilterModel::Sorting> FtbFilterModel::getAvailableSortings()
{
- return sortings;
+ return sortings;
}
QString FtbFilterModel::translateCurrentSorting()
{
- return sortings.key(currentSorting);
+ return sortings.key(currentSorting);
}
void FtbFilterModel::setSorting(Sorting s)
{
- currentSorting = s;
- invalidate();
+ currentSorting = s;
+ invalidate();
}
FtbFilterModel::Sorting FtbFilterModel::getCurrentSorting()
{
- return currentSorting;
+ return currentSorting;
}
FtbListModel::FtbListModel(QObject *parent) : QAbstractListModel(parent)
@@ -72,128 +72,128 @@ FtbListModel::~FtbListModel()
QString FtbListModel::translatePackType(FtbPackType type) const
{
- if(type == FtbPackType::Public) {
- return tr("Public Modpack");
- } else if(type == FtbPackType::ThirdParty) {
- return tr("Third Party Modpack");
- } else if(type == FtbPackType::Private) {
- return tr("Private Modpack");
- } else {
- return tr("Unknown Type");
- }
+ if(type == FtbPackType::Public) {
+ return tr("Public Modpack");
+ } else if(type == FtbPackType::ThirdParty) {
+ return tr("Third Party Modpack");
+ } else if(type == FtbPackType::Private) {
+ return tr("Private Modpack");
+ } else {
+ return tr("Unknown Type");
+ }
}
int FtbListModel::rowCount(const QModelIndex &parent) const
{
- return modpacks.size();
+ return modpacks.size();
}
int FtbListModel::columnCount(const QModelIndex &parent) const
{
- return 1;
+ return 1;
}
QVariant FtbListModel::data(const QModelIndex &index, int role) const
{
- int pos = index.row();
- if(pos >= modpacks.size() || pos < 0 || !index.isValid()) {
- return QString("INVALID INDEX %1").arg(pos);
- }
-
- FtbModpack pack = modpacks.at(pos);
- if(role == Qt::DisplayRole) {
- return pack.name + "\n" + translatePackType(pack.type);
- } else if (role == Qt::ToolTipRole) {
- if(pack.description.length() > 100) {
- //some magic to prevent to long tooltips and replace html linebreaks
- QString edit = pack.description.left(97);
- edit = edit.left(edit.lastIndexOf("<br>")).left(edit.lastIndexOf(" ")).append("...");
- return edit;
-
- }
- return pack.description;
- } else if(role == Qt::DecorationRole) {
- if(m_logoMap.contains(pack.logo)) {
- return (m_logoMap.value(pack.logo));
- }
- QIcon icon = MMC->getThemedIcon("screenshot-placeholder");
- ((FtbListModel *)this)->requestLogo(pack.logo);
- return icon;
- } else if(role == Qt::TextColorRole) {
- if(pack.broken) {
- //FIXME: Hardcoded color
- return QColor(255, 0, 50);
- } else if(pack.bugged) {
- //FIXME: Hardcoded color
- //bugged pack, currently only indicates bugged xml
- return QColor(244, 229, 66);
- }
- } else if(role == Qt::UserRole) {
- QVariant v;
- v.setValue(pack);
- return v;
- }
-
- return QVariant();
+ int pos = index.row();
+ if(pos >= modpacks.size() || pos < 0 || !index.isValid()) {
+ return QString("INVALID INDEX %1").arg(pos);
+ }
+
+ FtbModpack pack = modpacks.at(pos);
+ if(role == Qt::DisplayRole) {
+ return pack.name + "\n" + translatePackType(pack.type);
+ } else if (role == Qt::ToolTipRole) {
+ if(pack.description.length() > 100) {
+ //some magic to prevent to long tooltips and replace html linebreaks
+ QString edit = pack.description.left(97);
+ edit = edit.left(edit.lastIndexOf("<br>")).left(edit.lastIndexOf(" ")).append("...");
+ return edit;
+
+ }
+ return pack.description;
+ } else if(role == Qt::DecorationRole) {
+ if(m_logoMap.contains(pack.logo)) {
+ return (m_logoMap.value(pack.logo));
+ }
+ QIcon icon = MMC->getThemedIcon("screenshot-placeholder");
+ ((FtbListModel *)this)->requestLogo(pack.logo);
+ return icon;
+ } else if(role == Qt::TextColorRole) {
+ if(pack.broken) {
+ //FIXME: Hardcoded color
+ return QColor(255, 0, 50);
+ } else if(pack.bugged) {
+ //FIXME: Hardcoded color
+ //bugged pack, currently only indicates bugged xml
+ return QColor(244, 229, 66);
+ }
+ } else if(role == Qt::UserRole) {
+ QVariant v;
+ v.setValue(pack);
+ return v;
+ }
+
+ return QVariant();
}
void FtbListModel::fill(FtbModpackList modpacks)
{
- beginResetModel();
- this->modpacks = modpacks;
- endResetModel();
+ beginResetModel();
+ this->modpacks = modpacks;
+ endResetModel();
}
FtbModpack FtbListModel::at(int row)
{
- return modpacks.at(row);
+ return modpacks.at(row);
}
void FtbListModel::logoLoaded(QString logo, QIcon out)
{
- m_loadingLogos.removeAll(logo);
- m_logoMap.insert(logo, out);
- emit dataChanged(createIndex(0, 0), createIndex(1, 0));
+ m_loadingLogos.removeAll(logo);
+ m_logoMap.insert(logo, out);
+ emit dataChanged(createIndex(0, 0), createIndex(1, 0));
}
void FtbListModel::logoFailed(QString logo)
{
- m_failedLogos.append(logo);
- m_loadingLogos.removeAll(logo);
+ m_failedLogos.append(logo);
+ m_loadingLogos.removeAll(logo);
}
void FtbListModel::requestLogo(QString file)
{
- if(m_loadingLogos.contains(file) || m_failedLogos.contains(file)) {
- return;
- }
+ if(m_loadingLogos.contains(file) || m_failedLogos.contains(file)) {
+ return;
+ }
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0)));
- NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file));
- job->addNetAction(Net::Download::makeCached(QUrl(QString("https://ftb.cursecdn.com/FTB2/static/%1").arg(file)), entry));
+ MetaEntryPtr entry = ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0)));
+ NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file));
+ job->addNetAction(Net::Download::makeCached(QUrl(QString("https://ftb.cursecdn.com/FTB2/static/%1").arg(file)), entry));
- auto fullPath = entry->getFullPath();
- QObject::connect(job, &NetJob::finished, this, [this, file, fullPath]{
- emit logoLoaded(file, QIcon(fullPath));
- if(waitingCallbacks.contains(file)) {
- waitingCallbacks.value(file)(fullPath);
- }
- });
+ auto fullPath = entry->getFullPath();
+ QObject::connect(job, &NetJob::finished, this, [this, file, fullPath]{
+ emit logoLoaded(file, QIcon(fullPath));
+ if(waitingCallbacks.contains(file)) {
+ waitingCallbacks.value(file)(fullPath);
+ }
+ });
- QObject::connect(job, &NetJob::failed, this, [this, file]{
- emit logoFailed(file);
- });
+ QObject::connect(job, &NetJob::failed, this, [this, file]{
+ emit logoFailed(file);
+ });
- job->start();
+ job->start();
- m_loadingLogos.append(file);
+ m_loadingLogos.append(file);
}
void FtbListModel::getLogo(const QString &logo, LogoCallback callback)
{
- if(m_logoMap.contains(logo)) {
- callback(ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath());
- } else {
- requestLogo(logo);
- }
+ if(m_logoMap.contains(logo)) {
+ callback(ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath());
+ } else {
+ requestLogo(logo);
+ }
}
diff --git a/application/pages/modplatform/FtbListModel.h b/application/pages/modplatform/FtbListModel.h
index d3a82b73..c85c04fa 100644
--- a/application/pages/modplatform/FtbListModel.h
+++ b/application/pages/modplatform/FtbListModel.h
@@ -16,53 +16,53 @@ typedef std::function<void(QString)> LogoCallback;
class FtbFilterModel : public QSortFilterProxyModel
{
public:
- FtbFilterModel(QObject* parent = Q_NULLPTR);
- enum Sorting {
- ByName,
- ByGameVersion
- };
- const QMap<QString, Sorting> getAvailableSortings();
- QString translateCurrentSorting();
- void setSorting(Sorting sorting);
- Sorting getCurrentSorting();
+ FtbFilterModel(QObject* parent = Q_NULLPTR);
+ enum Sorting {
+ ByName,
+ ByGameVersion
+ };
+ const QMap<QString, Sorting> getAvailableSortings();
+ QString translateCurrentSorting();
+ void setSorting(Sorting sorting);
+ Sorting getCurrentSorting();
protected:
- bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
- bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
+ bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
private:
- QMap<QString, Sorting> sortings;
- Sorting currentSorting;
+ QMap<QString, Sorting> sortings;
+ Sorting currentSorting;
};
class FtbListModel : public QAbstractListModel
{
- Q_OBJECT
+ Q_OBJECT
private:
- FtbModpackList modpacks;
- QStringList m_failedLogos;
- QStringList m_loadingLogos;
- FtbLogoMap m_logoMap;
- QMap<QString, LogoCallback> waitingCallbacks;
+ FtbModpackList modpacks;
+ QStringList m_failedLogos;
+ QStringList m_loadingLogos;
+ FtbLogoMap m_logoMap;
+ QMap<QString, LogoCallback> waitingCallbacks;
- void requestLogo(QString file);
- QString translatePackType(FtbPackType type) const;
+ void requestLogo(QString file);
+ QString translatePackType(FtbPackType type) const;
private slots:
- void logoFailed(QString logo);
- void logoLoaded(QString logo, QIcon out);
+ void logoFailed(QString logo);
+ void logoLoaded(QString logo, QIcon out);
public:
- FtbListModel(QObject *parent);
- ~FtbListModel();
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
+ FtbListModel(QObject *parent);
+ ~FtbListModel();
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
- void fill(FtbModpackList modpacks);
+ void fill(FtbModpackList modpacks);
- FtbModpack at(int row);
- void getLogo(const QString &logo, LogoCallback callback);
+ FtbModpack at(int row);
+ void getLogo(const QString &logo, LogoCallback callback);
};
diff --git a/application/pages/modplatform/ImportPage.cpp b/application/pages/modplatform/ImportPage.cpp
index f00c4811..5e476195 100644
--- a/application/pages/modplatform/ImportPage.cpp
+++ b/application/pages/modplatform/ImportPage.cpp
@@ -13,114 +13,114 @@
class UrlValidator : public QValidator
{
public:
- using QValidator::QValidator;
+ using QValidator::QValidator;
- State validate(QString &in, int &pos) const
- {
- const QUrl url(in);
- if (url.isValid() && !url.isRelative() && !url.isEmpty())
- {
- return Acceptable;
- }
- else if (QFile::exists(in))
- {
- return Acceptable;
- }
- else
- {
- return Intermediate;
- }
- }
+ State validate(QString &in, int &pos) const
+ {
+ const QUrl url(in);
+ if (url.isValid() && !url.isRelative() && !url.isEmpty())
+ {
+ return Acceptable;
+ }
+ else if (QFile::exists(in))
+ {
+ return Acceptable;
+ }
+ else
+ {
+ return Intermediate;
+ }
+ }
};
ImportPage::ImportPage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), ui(new Ui::ImportPage), dialog(dialog)
+ : QWidget(parent), ui(new Ui::ImportPage), dialog(dialog)
{
- ui->setupUi(this);
- ui->modpackEdit->setValidator(new UrlValidator(ui->modpackEdit));
- connect(ui->modpackEdit, &QLineEdit::textChanged, this, &ImportPage::updateState);
+ ui->setupUi(this);
+ ui->modpackEdit->setValidator(new UrlValidator(ui->modpackEdit));
+ connect(ui->modpackEdit, &QLineEdit::textChanged, this, &ImportPage::updateState);
}
ImportPage::~ImportPage()
{
- delete ui;
+ delete ui;
}
bool ImportPage::shouldDisplay() const
{
- return true;
+ return true;
}
void ImportPage::openedImpl()
{
- updateState();
+ updateState();
}
void ImportPage::updateState()
{
- if(!isOpened)
- {
- return;
- }
- if(ui->modpackEdit->hasAcceptableInput())
- {
- QString input = ui->modpackEdit->text();
- auto url = QUrl::fromUserInput(input);
- if(url.isLocalFile())
- {
- // FIXME: actually do some validation of what's inside here... this is fake AF
- QFileInfo fi(input);
- if(fi.exists() && fi.suffix() == "zip")
- {
- QFileInfo fi(url.fileName());
- dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
- }
- }
- else
- {
- // hook, line and sinker.
- QFileInfo fi(url.fileName());
- dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
- }
- }
- else
- {
- dialog->setSuggestedPack();
- }
+ if(!isOpened)
+ {
+ return;
+ }
+ if(ui->modpackEdit->hasAcceptableInput())
+ {
+ QString input = ui->modpackEdit->text();
+ auto url = QUrl::fromUserInput(input);
+ if(url.isLocalFile())
+ {
+ // FIXME: actually do some validation of what's inside here... this is fake AF
+ QFileInfo fi(input);
+ if(fi.exists() && fi.suffix() == "zip")
+ {
+ QFileInfo fi(url.fileName());
+ dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
+ }
+ }
+ else
+ {
+ // hook, line and sinker.
+ QFileInfo fi(url.fileName());
+ dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
+ }
+ }
+ else
+ {
+ dialog->setSuggestedPack();
+ }
}
void ImportPage::setUrl(const QString& url)
{
- ui->modpackEdit->setText(url);
- updateState();
+ ui->modpackEdit->setText(url);
+ updateState();
}
void ImportPage::on_modpackBtn_clicked()
{
- const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), tr("Zip (*.zip)"));
- if (url.isValid())
- {
- if (url.isLocalFile())
- {
- ui->modpackEdit->setText(url.toLocalFile());
- }
- else
- {
- ui->modpackEdit->setText(url.toString());
- }
- }
+ const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), tr("Zip (*.zip)"));
+ if (url.isValid())
+ {
+ if (url.isLocalFile())
+ {
+ ui->modpackEdit->setText(url.toLocalFile());
+ }
+ else
+ {
+ ui->modpackEdit->setText(url.toString());
+ }
+ }
}
QUrl ImportPage::modpackUrl() const
{
- const QUrl url(ui->modpackEdit->text());
- if (url.isValid() && !url.isRelative() && !url.host().isEmpty())
- {
- return url;
- }
- else
- {
- return QUrl::fromLocalFile(ui->modpackEdit->text());
- }
+ const QUrl url(ui->modpackEdit->text());
+ if (url.isValid() && !url.isRelative() && !url.host().isEmpty())
+ {
+ return url;
+ }
+ else
+ {
+ return QUrl::fromLocalFile(ui->modpackEdit->text());
+ }
}
diff --git a/application/pages/modplatform/ImportPage.h b/application/pages/modplatform/ImportPage.h
index 8f62e6b1..120e7b56 100644
--- a/application/pages/modplatform/ImportPage.h
+++ b/application/pages/modplatform/ImportPage.h
@@ -30,41 +30,41 @@ class NewInstanceDialog;
class ImportPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ImportPage(NewInstanceDialog* dialog, QWidget *parent = 0);
- virtual ~ImportPage();
- virtual QString displayName() const override
- {
- return tr("Import from zip");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("viewfolder");
- }
- virtual QString id() const override
- {
- return "import";
- }
- virtual QString helpPage() const override
- {
- return "Zip-import";
- }
- virtual bool shouldDisplay() const override;
+ explicit ImportPage(NewInstanceDialog* dialog, QWidget *parent = 0);
+ virtual ~ImportPage();
+ virtual QString displayName() const override
+ {
+ return tr("Import from zip");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("viewfolder");
+ }
+ virtual QString id() const override
+ {
+ return "import";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Zip-import";
+ }
+ virtual bool shouldDisplay() const override;
- void setUrl(const QString & url);
- void openedImpl() override;
+ void setUrl(const QString & url);
+ void openedImpl() override;
private slots:
- void on_modpackBtn_clicked();
- void updateState();
+ void on_modpackBtn_clicked();
+ void updateState();
private:
- QUrl modpackUrl() const;
+ QUrl modpackUrl() const;
private:
- Ui::ImportPage *ui = nullptr;
- NewInstanceDialog* dialog = nullptr;
+ Ui::ImportPage *ui = nullptr;
+ NewInstanceDialog* dialog = nullptr;
};
diff --git a/application/pages/modplatform/TechnicPage.cpp b/application/pages/modplatform/TechnicPage.cpp
index c0f4faa5..1ee3ca9e 100644
--- a/application/pages/modplatform/TechnicPage.cpp
+++ b/application/pages/modplatform/TechnicPage.cpp
@@ -8,22 +8,22 @@
#include "dialogs/NewInstanceDialog.h"
TechnicPage::TechnicPage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), ui(new Ui::TechnicPage), dialog(dialog)
+ : QWidget(parent), ui(new Ui::TechnicPage), dialog(dialog)
{
- ui->setupUi(this);
+ ui->setupUi(this);
}
TechnicPage::~TechnicPage()
{
- delete ui;
+ delete ui;
}
bool TechnicPage::shouldDisplay() const
{
- return true;
+ return true;
}
void TechnicPage::openedImpl()
{
- dialog->setSuggestedPack();
+ dialog->setSuggestedPack();
}
diff --git a/application/pages/modplatform/TechnicPage.h b/application/pages/modplatform/TechnicPage.h
index 5b0f16a6..84ea4636 100644
--- a/application/pages/modplatform/TechnicPage.h
+++ b/application/pages/modplatform/TechnicPage.h
@@ -30,32 +30,32 @@ class NewInstanceDialog;
class TechnicPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit TechnicPage(NewInstanceDialog* dialog, QWidget *parent = 0);
- virtual ~TechnicPage();
- virtual QString displayName() const override
- {
- return tr("Technic");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("technic");
- }
- virtual QString id() const override
- {
- return "technic";
- }
- virtual QString helpPage() const override
- {
- return "Technic-platform";
- }
- virtual bool shouldDisplay() const override;
-
- void openedImpl() override;
+ explicit TechnicPage(NewInstanceDialog* dialog, QWidget *parent = 0);
+ virtual ~TechnicPage();
+ virtual QString displayName() const override
+ {
+ return tr("Technic");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("technic");
+ }
+ virtual QString id() const override
+ {
+ return "technic";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Technic-platform";
+ }
+ virtual bool shouldDisplay() const override;
+
+ void openedImpl() override;
private:
- Ui::TechnicPage *ui = nullptr;
- NewInstanceDialog* dialog = nullptr;
+ Ui::TechnicPage *ui = nullptr;
+ NewInstanceDialog* dialog = nullptr;
};
diff --git a/application/pages/modplatform/TwitchPage.cpp b/application/pages/modplatform/TwitchPage.cpp
index 42aa46be..f9b326ae 100644
--- a/application/pages/modplatform/TwitchPage.cpp
+++ b/application/pages/modplatform/TwitchPage.cpp
@@ -8,22 +8,22 @@
#include "dialogs/NewInstanceDialog.h"
TwitchPage::TwitchPage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), ui(new Ui::TwitchPage), dialog(dialog)
+ : QWidget(parent), ui(new Ui::TwitchPage), dialog(dialog)
{
- ui->setupUi(this);
+ ui->setupUi(this);
}
TwitchPage::~TwitchPage()
{
- delete ui;
+ delete ui;
}
bool TwitchPage::shouldDisplay() const
{
- return false;
+ return false;
}
void TwitchPage::openedImpl()
{
- dialog->setSuggestedPack();
+ dialog->setSuggestedPack();
}
diff --git a/application/pages/modplatform/TwitchPage.h b/application/pages/modplatform/TwitchPage.h
index 8e072917..36080016 100644
--- a/application/pages/modplatform/TwitchPage.h
+++ b/application/pages/modplatform/TwitchPage.h
@@ -30,32 +30,32 @@ class NewInstanceDialog;
class TwitchPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit TwitchPage(NewInstanceDialog* dialog, QWidget *parent = 0);
- virtual ~TwitchPage();
- virtual QString displayName() const override
- {
- return tr("Twitch");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("twitch");
- }
- virtual QString id() const override
- {
- return "twitch";
- }
- virtual QString helpPage() const override
- {
- return "Twitch-platform";
- }
- virtual bool shouldDisplay() const override;
-
- void openedImpl() override;
+ explicit TwitchPage(NewInstanceDialog* dialog, QWidget *parent = 0);
+ virtual ~TwitchPage();
+ virtual QString displayName() const override
+ {
+ return tr("Twitch");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("twitch");
+ }
+ virtual QString id() const override
+ {
+ return "twitch";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Twitch-platform";
+ }
+ virtual bool shouldDisplay() const override;
+
+ void openedImpl() override;
private:
- Ui::TwitchPage *ui = nullptr;
- NewInstanceDialog* dialog = nullptr;
+ Ui::TwitchPage *ui = nullptr;
+ NewInstanceDialog* dialog = nullptr;
};
diff --git a/application/pages/modplatform/VanillaPage.cpp b/application/pages/modplatform/VanillaPage.cpp
index c355fccb..f0f2a95e 100644
--- a/application/pages/modplatform/VanillaPage.cpp
+++ b/application/pages/modplatform/VanillaPage.cpp
@@ -15,81 +15,81 @@
#include <QTabBar>
VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent)
- : QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage)
+ : QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage)
{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedVersion);
- filterChanged();
- connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->betaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->refreshBtn, &QPushButton::clicked, this, &VanillaPage::refresh);
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedVersion);
+ filterChanged();
+ connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
+ connect(ui->betaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
+ connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
+ connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
+ connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
+ connect(ui->refreshBtn, &QPushButton::clicked, this, &VanillaPage::refresh);
}
void VanillaPage::openedImpl()
{
- if(!initialized)
- {
- auto vlist = ENV.metadataIndex()->get("net.minecraft");
- ui->versionList->initialize(vlist.get());
- initialized = true;
- }
- else
- {
- suggestCurrent();
- }
+ if(!initialized)
+ {
+ auto vlist = ENV.metadataIndex()->get("net.minecraft");
+ ui->versionList->initialize(vlist.get());
+ initialized = true;
+ }
+ else
+ {
+ suggestCurrent();
+ }
}
void VanillaPage::refresh()
{
- ui->versionList->loadList();
+ ui->versionList->loadList();
}
void VanillaPage::filterChanged()
{
- QStringList out;
- if(ui->alphaFilter->isChecked())
- out << "(old_alpha)";
- if(ui->betaFilter->isChecked())
- out << "(old_beta)";
- if(ui->snapshotFilter->isChecked())
- out << "(snapshot)";
- if(ui->oldSnapshotFilter->isChecked())
- out << "(old_snapshot)";
- if(ui->releaseFilter->isChecked())
- out << "(release)";
- auto regexp = out.join('|');
- ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false));
+ QStringList out;
+ if(ui->alphaFilter->isChecked())
+ out << "(old_alpha)";
+ if(ui->betaFilter->isChecked())
+ out << "(old_beta)";
+ if(ui->snapshotFilter->isChecked())
+ out << "(snapshot)";
+ if(ui->oldSnapshotFilter->isChecked())
+ out << "(old_snapshot)";
+ if(ui->releaseFilter->isChecked())
+ out << "(release)";
+ auto regexp = out.join('|');
+ ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false));
}
VanillaPage::~VanillaPage()
{
- delete ui;
+ delete ui;
}
bool VanillaPage::shouldDisplay() const
{
- return true;
+ return true;
}
BaseVersionPtr VanillaPage::selectedVersion() const
{
- return m_selectedVersion;
+ return m_selectedVersion;
}
void VanillaPage::suggestCurrent()
{
- if(m_selectedVersion && isOpened)
- {
- dialog->setSuggestedPack(m_selectedVersion->descriptor(), new InstanceCreationTask(m_selectedVersion));
- }
+ if(m_selectedVersion && isOpened)
+ {
+ dialog->setSuggestedPack(m_selectedVersion->descriptor(), new InstanceCreationTask(m_selectedVersion));
+ }
}
void VanillaPage::setSelectedVersion(BaseVersionPtr version)
{
- m_selectedVersion = version;
- suggestCurrent();
+ m_selectedVersion = version;
+ suggestCurrent();
}
diff --git a/application/pages/modplatform/VanillaPage.h b/application/pages/modplatform/VanillaPage.h
index 91c65edf..2b292b01 100644
--- a/application/pages/modplatform/VanillaPage.h
+++ b/application/pages/modplatform/VanillaPage.h
@@ -30,46 +30,46 @@ class NewInstanceDialog;
class VanillaPage : public QWidget, public BasePage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit VanillaPage(NewInstanceDialog *dialog, QWidget *parent = 0);
- virtual ~VanillaPage();
- virtual QString displayName() const override
- {
- return tr("Vanilla");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("minecraft");
- }
- virtual QString id() const override
- {
- return "vanilla";
- }
- virtual QString helpPage() const override
- {
- return "Vanilla-platform";
- }
- virtual bool shouldDisplay() const override;
- void openedImpl() override;
+ explicit VanillaPage(NewInstanceDialog *dialog, QWidget *parent = 0);
+ virtual ~VanillaPage();
+ virtual QString displayName() const override
+ {
+ return tr("Vanilla");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("minecraft");
+ }
+ virtual QString id() const override
+ {
+ return "vanilla";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Vanilla-platform";
+ }
+ virtual bool shouldDisplay() const override;
+ void openedImpl() override;
- BaseVersionPtr selectedVersion() const;
+ BaseVersionPtr selectedVersion() const;
public slots:
- void setSelectedVersion(BaseVersionPtr version);
+ void setSelectedVersion(BaseVersionPtr version);
private slots:
- void filterChanged();
+ void filterChanged();
private:
- void refresh();
- void suggestCurrent();
+ void refresh();
+ void suggestCurrent();
private:
- bool initialized = false;
- NewInstanceDialog *dialog = nullptr;
- Ui::VanillaPage *ui = nullptr;
- bool m_versionSetByUser = false;
- BaseVersionPtr m_selectedVersion;
+ bool initialized = false;
+ NewInstanceDialog *dialog = nullptr;
+ Ui::VanillaPage *ui = nullptr;
+ bool m_versionSetByUser = false;
+ BaseVersionPtr m_selectedVersion;
};
diff --git a/application/resources/OSX/OSX.qrc b/application/resources/OSX/OSX.qrc
index a7d7be17..a5c40894 100644
--- a/application/resources/OSX/OSX.qrc
+++ b/application/resources/OSX/OSX.qrc
@@ -1,37 +1,37 @@
<!DOCTYPE RCC>
<RCC version="1.0">
- <qresource prefix="/icons/OSX">
- <file>index.theme</file>
- <file>scalable/about.svg</file>
- <file>scalable/accounts.svg</file>
- <file>scalable/bug.svg</file>
- <file>scalable/centralmods.svg</file>
- <file>scalable/checkupdate.svg</file>
- <file>scalable/copy.svg</file>
- <file>scalable/coremods.svg</file>
- <file>scalable/externaltools.svg</file>
- <file>scalable/help.svg</file>
+ <qresource prefix="/icons/OSX">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
<file>scalable/instance-settings.svg</file>
- <file>scalable/jarmods.svg</file>
- <file>scalable/java.svg</file>
- <file>scalable/loadermods.svg</file>
- <file>scalable/log.svg</file>
- <file>scalable/minecraft.svg</file>
- <file>scalable/multimc.svg</file>
- <file>scalable/new.svg</file>
- <file>scalable/news.svg</file>
- <file>scalable/notes.svg</file>
- <file>scalable/patreon.svg</file>
- <file>scalable/proxy.svg</file>
- <file>scalable/quickmods.svg</file>
- <file>scalable/refresh.svg</file>
- <file>scalable/resourcepacks.svg</file>
- <file>scalable/screenshots.svg</file>
- <file>scalable/settings.svg</file>
- <file>scalable/status-bad.svg</file>
- <file>scalable/status-good.svg</file>
- <file>scalable/status-yellow.svg</file>
- <file>scalable/viewfolder.svg</file>
- <file>scalable/worlds.svg</file>
- </qresource>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/multimc.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/patreon.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/quickmods.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ </qresource>
</RCC>
diff --git a/application/resources/assets/assets.qrc b/application/resources/assets/assets.qrc
index 8d213387..38638e7f 100644
--- a/application/resources/assets/assets.qrc
+++ b/application/resources/assets/assets.qrc
@@ -2,6 +2,6 @@
<RCC version="1.0">
<qresource prefix="/assets">
<file alias="underconstruction">underconstruction.png</file>
- <file alias="deadglitch">deadglitch.svg</file>
+ <file alias="deadglitch">deadglitch.svg</file>
</qresource>
</RCC>
diff --git a/application/resources/documents/documents.qrc b/application/resources/documents/documents.qrc
index 77fc0cf4..007efcde 100644
--- a/application/resources/documents/documents.qrc
+++ b/application/resources/documents/documents.qrc
@@ -1,7 +1,7 @@
<!DOCTYPE RCC>
<RCC version="1.0">
- <qresource prefix="/documents">
- <file>../../../COPYING.md</file>
- </qresource>
+ <qresource prefix="/documents">
+ <file>../../../COPYING.md</file>
+ </qresource>
</RCC>
diff --git a/application/resources/flat/flat.qrc b/application/resources/flat/flat.qrc
index aee2e30c..67c8d291 100644
--- a/application/resources/flat/flat.qrc
+++ b/application/resources/flat/flat.qrc
@@ -1,44 +1,44 @@
<!DOCTYPE RCC>
<RCC version="1.0">
- <qresource prefix="/icons/flat">
- <file>index.theme</file>
- <file>scalable/about.svg</file>
- <file>scalable/accounts.svg</file>
- <file>scalable/bug.svg</file>
- <file>scalable/cat.svg</file>
- <file>scalable/centralmods.svg</file>
- <file>scalable/checkupdate.svg</file>
- <file>scalable/copy.svg</file>
- <file>scalable/coremods.svg</file>
- <file>scalable/discord.svg</file>
- <file>scalable/externaltools.svg</file>
- <file>scalable/help.svg</file>
- <file>scalable/instance-settings.svg</file>
- <file>scalable/jarmods.svg</file>
- <file>scalable/java.svg</file>
- <file>scalable/loadermods.svg</file>
- <file>scalable/log.svg</file>
- <file>scalable/minecraft.svg</file>
- <file>scalable/multimc.svg</file>
- <file>scalable/new.svg</file>
- <file>scalable/news.svg</file>
- <file>scalable/notes.svg</file>
- <file>scalable/packages.svg</file>
- <file>scalable/patreon.svg</file>
- <file>scalable/proxy.svg</file>
- <file>scalable/quickmods.svg</file>
- <file>scalable/reddit-alien.svg</file>
- <file>scalable/refresh.svg</file>
- <file>scalable/resourcepacks.svg</file>
- <file>scalable/screenshot-placeholder.svg</file>
- <file>scalable/screenshots.svg</file>
- <file>scalable/settings.svg</file>
- <file>scalable/star.svg</file>
- <file>scalable/status-bad.svg</file>
- <file>scalable/status-good.svg</file>
- <file>scalable/status-running.svg</file>
- <file>scalable/status-yellow.svg</file>
- <file>scalable/viewfolder.svg</file>
- <file>scalable/worlds.svg</file>
- </qresource>
+ <qresource prefix="/icons/flat">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/cat.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/discord.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
+ <file>scalable/instance-settings.svg</file>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/multimc.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/packages.svg</file>
+ <file>scalable/patreon.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/quickmods.svg</file>
+ <file>scalable/reddit-alien.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/screenshot-placeholder.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/star.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-running.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ </qresource>
</RCC>
diff --git a/application/resources/iOS/iOS.qrc b/application/resources/iOS/iOS.qrc
index 0cb642f4..7212ce77 100644
--- a/application/resources/iOS/iOS.qrc
+++ b/application/resources/iOS/iOS.qrc
@@ -1,37 +1,37 @@
<!DOCTYPE RCC>
<RCC version="1.0">
- <qresource prefix="/icons/iOS">
- <file>index.theme</file>
- <file>scalable/about.svg</file>
- <file>scalable/accounts.svg</file>
- <file>scalable/bug.svg</file>
- <file>scalable/centralmods.svg</file>
- <file>scalable/checkupdate.svg</file>
- <file>scalable/copy.svg</file>
- <file>scalable/coremods.svg</file>
- <file>scalable/externaltools.svg</file>
- <file>scalable/help.svg</file>
- <file>scalable/instance-settings.svg</file>
- <file>scalable/jarmods.svg</file>
- <file>scalable/java.svg</file>
- <file>scalable/loadermods.svg</file>
- <file>scalable/log.svg</file>
- <file>scalable/minecraft.svg</file>
- <file>scalable/multimc.svg</file>
- <file>scalable/new.svg</file>
- <file>scalable/news.svg</file>
- <file>scalable/notes.svg</file>
- <file>scalable/patreon.svg</file>
- <file>scalable/proxy.svg</file>
- <file>scalable/quickmods.svg</file>
- <file>scalable/refresh.svg</file>
- <file>scalable/resourcepacks.svg</file>
- <file>scalable/screenshots.svg</file>
- <file>scalable/settings.svg</file>
- <file>scalable/status-bad.svg</file>
- <file>scalable/status-good.svg</file>
- <file>scalable/status-yellow.svg</file>
- <file>scalable/viewfolder.svg</file>
- <file>scalable/worlds.svg</file>
- </qresource>
+ <qresource prefix="/icons/iOS">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
+ <file>scalable/instance-settings.svg</file>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/multimc.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/patreon.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/quickmods.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ </qresource>
</RCC>
diff --git a/application/resources/multimc/multimc.qrc b/application/resources/multimc/multimc.qrc
index 55cc601e..f99cfca2 100644
--- a/application/resources/multimc/multimc.qrc
+++ b/application/resources/multimc/multimc.qrc
@@ -1,309 +1,309 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/icons/multimc">
- <file>index.theme</file>
- <!-- Logo. Our own. For use in branding. -->
- <file>scalable/logo.svg</file>
-
- <!-- Logo. Our own. For use within the application (Settings pages and similar). -->
- <file>scalable/multimc.svg</file>
-
- <!-- REDDIT logo icon, needs reddit license! -->
- <file>scalable/reddit-alien.svg</file>
-
- <!-- twitch logo icon -->
- <file>scalable/twitch.svg</file>
-
- <!-- technic logo icon -->
- <file>scalable/technic.svg</file>
-
- <!-- A proxy icon. Our own. SSSsss -->
- <file>scalable/proxy.svg</file>
-
- <!-- Java icon. From Oracle, fixed because it was derpy. -->
- <file>scalable/java.svg</file>
-
- <!-- Star, CC-BY-SA 3.0, Oxygen icons.-->
- <file>16x16/star.png</file>
- <file>24x24/star.png</file>
- <file>32x32/star.png</file>
- <file>48x48/star.png</file>
- <file>64x64/star.png</file>
-
- <!-- "folder-remote", CC-BY-SA 3.0, Oxygen icons. Used for the worlds folder-->
- <file>16x16/worlds.png</file>
- <file>22x22/worlds.png</file>
- <file>32x32/worlds.png</file>
- <file>48x48/worlds.png</file>
- <file>64x64/worlds.png</file>
-
- <!-- Minecraft icon. Source: http://www.minecraftforum.net/forums/show-your-creation/fan-art/1574882-icon-better-minecraft-icon -->
- <file>16x16/minecraft.png</file>
- <file>24x24/minecraft.png</file>
- <file>32x32/minecraft.png</file>
- <file>48x48/minecraft.png</file>
- <file>256x256/minecraft.png</file>
-
- <!-- About dialog. GPLv2, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/help-contents.png -->
- <file>16x16/about.png</file>
- <file>22x22/about.png</file>
- <file>32x32/about.png</file>
- <file>48x48/about.png</file>
- <file>64x64/about.png</file>
-
- <!-- Report bug. Our own. -->
- <file>scalable/bug.svg</file>
- <file>16x16/bug.png</file>
- <file>22x22/bug.png</file>
- <file>32x32/bug.png</file>
- <file>48x48/bug.png</file>
- <file>64x64/bug.png</file>
-
- <!-- Screenshots. Our own. -->
- <!-- frame is adapted and simplified from http://www.wpclipart.com/page_frames/picture_frames/golden_picture_frame.png.html -->
- <file>16x16/screenshots.png</file>
- <file>22x22/screenshots.png</file>
- <file>32x32/screenshots.png</file>
- <file>48x48/screenshots.png</file>
- <file>64x64/screenshots.png</file>
- <file>scalable/screenshots.svg</file>
-
- <!-- Custom commands. -->
- <file>scalable/custom-commands.svg</file>
-
- <!-- Patron logo. (C) 2014 Patreon, Inc., http://www.patreon.com/toolbox?ftyp=media -->
- <file>16x16/patreon.png</file>
- <file>22x22/patreon.png</file>
- <file>24x24/patreon.png</file>
- <file>32x32/patreon.png</file>
- <file>48x48/patreon.png</file>
- <file>64x64/patreon.png</file>
-
- <!-- The cat button. Freeware, http://findicons.com/icon/73096/black_cat -->
- <file>16x16/cat.png</file>
- <file>22x22/cat.png</file>
- <file>24x24/cat.png</file>
- <file>32x32/cat.png</file>
- <file>48x48/cat.png</file>
- <file>64x64/cat.png</file>
-
- <!-- Show mods folder. CC-BY-SA 3.0 http://openiconlibrary.sourceforge.net/gallery2/?./Icons/places/oxygen-style/folder-favorites.png -->
- <file>scalable/centralmods.svg</file>
- <file>16x16/centralmods.png</file>
- <file>22x22/centralmods.png</file>
- <file>32x32/centralmods.png</file>
- <file>48x48/centralmods.png</file>
- <file>64x64/centralmods.png</file>
-
- <!-- Update. GPLv2, https://code.google.com/p/gnome-colors/ -->
- <file>scalable/checkupdate.svg</file>
- <file>16x16/checkupdate.png</file>
- <file>22x22/checkupdate.png</file>
- <file>32x32/checkupdate.png</file>
- <file>48x48/checkupdate.png</file>
- <file>64x64/checkupdate.png</file>
-
- <!-- copy instance. CC-BY-SA 3.0, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/edit-copy-6.png -->
- <file>16x16/copy.png</file>
- <file>22x22/copy.png</file>
- <file>32x32/copy.png</file>
- <file>48x48/copy.png</file>
- <file>64x64/copy.png</file>
-
- <!-- Help. CC-BY-SA 3.0, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/help.png -->
- <file>16x16/help.png</file>
- <file>22x22/help.png</file>
- <file>32x32/help.png</file>
- <file>48x48/help.png</file>
- <file>64x64/help.png</file>
-
- <!-- New instance. GPLv2, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/document-new-3.png -->
- <file>16x16/new.png</file>
+ <file>index.theme</file>
+ <!-- Logo. Our own. For use in branding. -->
+ <file>scalable/logo.svg</file>
+
+ <!-- Logo. Our own. For use within the application (Settings pages and similar). -->
+ <file>scalable/multimc.svg</file>
+
+ <!-- REDDIT logo icon, needs reddit license! -->
+ <file>scalable/reddit-alien.svg</file>
+
+ <!-- twitch logo icon -->
+ <file>scalable/twitch.svg</file>
+
+ <!-- technic logo icon -->
+ <file>scalable/technic.svg</file>
+
+ <!-- A proxy icon. Our own. SSSsss -->
+ <file>scalable/proxy.svg</file>
+
+ <!-- Java icon. From Oracle, fixed because it was derpy. -->
+ <file>scalable/java.svg</file>
+
+ <!-- Star, CC-BY-SA 3.0, Oxygen icons.-->
+ <file>16x16/star.png</file>
+ <file>24x24/star.png</file>
+ <file>32x32/star.png</file>
+ <file>48x48/star.png</file>
+ <file>64x64/star.png</file>
+
+ <!-- "folder-remote", CC-BY-SA 3.0, Oxygen icons. Used for the worlds folder-->
+ <file>16x16/worlds.png</file>
+ <file>22x22/worlds.png</file>
+ <file>32x32/worlds.png</file>
+ <file>48x48/worlds.png</file>
+ <file>64x64/worlds.png</file>
+
+ <!-- Minecraft icon. Source: http://www.minecraftforum.net/forums/show-your-creation/fan-art/1574882-icon-better-minecraft-icon -->
+ <file>16x16/minecraft.png</file>
+ <file>24x24/minecraft.png</file>
+ <file>32x32/minecraft.png</file>
+ <file>48x48/minecraft.png</file>
+ <file>256x256/minecraft.png</file>
+
+ <!-- About dialog. GPLv2, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/help-contents.png -->
+ <file>16x16/about.png</file>
+ <file>22x22/about.png</file>
+ <file>32x32/about.png</file>
+ <file>48x48/about.png</file>
+ <file>64x64/about.png</file>
+
+ <!-- Report bug. Our own. -->
+ <file>scalable/bug.svg</file>
+ <file>16x16/bug.png</file>
+ <file>22x22/bug.png</file>
+ <file>32x32/bug.png</file>
+ <file>48x48/bug.png</file>
+ <file>64x64/bug.png</file>
+
+ <!-- Screenshots. Our own. -->
+ <!-- frame is adapted and simplified from http://www.wpclipart.com/page_frames/picture_frames/golden_picture_frame.png.html -->
+ <file>16x16/screenshots.png</file>
+ <file>22x22/screenshots.png</file>
+ <file>32x32/screenshots.png</file>
+ <file>48x48/screenshots.png</file>
+ <file>64x64/screenshots.png</file>
+ <file>scalable/screenshots.svg</file>
+
+ <!-- Custom commands. -->
+ <file>scalable/custom-commands.svg</file>
+
+ <!-- Patron logo. (C) 2014 Patreon, Inc., http://www.patreon.com/toolbox?ftyp=media -->
+ <file>16x16/patreon.png</file>
+ <file>22x22/patreon.png</file>
+ <file>24x24/patreon.png</file>
+ <file>32x32/patreon.png</file>
+ <file>48x48/patreon.png</file>
+ <file>64x64/patreon.png</file>
+
+ <!-- The cat button. Freeware, http://findicons.com/icon/73096/black_cat -->
+ <file>16x16/cat.png</file>
+ <file>22x22/cat.png</file>
+ <file>24x24/cat.png</file>
+ <file>32x32/cat.png</file>
+ <file>48x48/cat.png</file>
+ <file>64x64/cat.png</file>
+
+ <!-- Show mods folder. CC-BY-SA 3.0 http://openiconlibrary.sourceforge.net/gallery2/?./Icons/places/oxygen-style/folder-favorites.png -->
+ <file>scalable/centralmods.svg</file>
+ <file>16x16/centralmods.png</file>
+ <file>22x22/centralmods.png</file>
+ <file>32x32/centralmods.png</file>
+ <file>48x48/centralmods.png</file>
+ <file>64x64/centralmods.png</file>
+
+ <!-- Update. GPLv2, https://code.google.com/p/gnome-colors/ -->
+ <file>scalable/checkupdate.svg</file>
+ <file>16x16/checkupdate.png</file>
+ <file>22x22/checkupdate.png</file>
+ <file>32x32/checkupdate.png</file>
+ <file>48x48/checkupdate.png</file>
+ <file>64x64/checkupdate.png</file>
+
+ <!-- copy instance. CC-BY-SA 3.0, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/edit-copy-6.png -->
+ <file>16x16/copy.png</file>
+ <file>22x22/copy.png</file>
+ <file>32x32/copy.png</file>
+ <file>48x48/copy.png</file>
+ <file>64x64/copy.png</file>
+
+ <!-- Help. CC-BY-SA 3.0, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/help.png -->
+ <file>16x16/help.png</file>
+ <file>22x22/help.png</file>
+ <file>32x32/help.png</file>
+ <file>48x48/help.png</file>
+ <file>64x64/help.png</file>
+
+ <!-- New instance. GPLv2, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/document-new-3.png -->
+ <file>16x16/new.png</file>
<file>22x22/new.png</file>
<file>32x32/new.png</file>
- <file>48x48/new.png</file>
- <file>64x64/new.png</file>
-
- <!-- Open news. Our own. -->
- <file>scalable/news.svg</file>
- <file>16x16/news.png</file>
- <file>22x22/news.png</file>
- <file>32x32/news.png</file>
- <file>48x48/news.png</file>
- <file>64x64/news.png</file>
-
- <!-- Bad status. Our own. -->
- <file>16x16/status-bad.png</file>
- <file>24x24/status-bad.png</file>
- <file>22x22/status-bad.png</file>
- <file>32x32/status-bad.png</file>
- <file>48x48/status-bad.png</file>
- <file>64x64/status-bad.png</file>
-
- <!-- Good status. Our own. -->
- <file>16x16/status-good.png</file>
- <file>24x24/status-good.png</file>
- <file>22x22/status-good.png</file>
- <file>32x32/status-good.png</file>
- <file>48x48/status-good.png</file>
- <file>64x64/status-good.png</file>
-
- <!-- Yellow status. Whatever that means... Our own. -->
- <file>16x16/status-yellow.png</file>
- <file>24x24/status-yellow.png</file>
- <file>22x22/status-yellow.png</file>
- <file>32x32/status-yellow.png</file>
- <file>48x48/status-yellow.png</file>
- <file>64x64/status-yellow.png</file>
-
- <!-- A status icon for things that are in progress/running... Our own. -->
- <file>16x16/status-running.png</file>
- <file>24x24/status-running.png</file>
- <file>22x22/status-running.png</file>
- <file>32x32/status-running.png</file>
- <file>48x48/status-running.png</file>
- <file>64x64/status-running.png</file>
- <file>scalable/status-running.svg</file>
-
- <!-- Plugin (blue recolor), CC-BY-SA 3.0, Oxygen icons. -->
- <file>16x16/loadermods.png</file>
- <file>24x24/loadermods.png</file>
- <file>32x32/loadermods.png</file>
- <file>64x64/loadermods.png</file>
-
- <!-- Plugin (red recolor), CC-BY-SA 3.0, Oxygen icons. -->
- <file>16x16/jarmods.png</file>
- <file>24x24/jarmods.png</file>
- <file>32x32/jarmods.png</file>
- <file>64x64/jarmods.png</file>
-
- <!-- Plugin (green original), CC-BY-SA 3.0, Oxygen icons. -->
- <file>16x16/coremods.png</file>
- <file>24x24/coremods.png</file>
- <file>32x32/coremods.png</file>
- <file>64x64/coremods.png</file>
-
- <!-- Resource packs, CC-BY-SA 3.0, Oxygen icons. -->
- <file>16x16/resourcepacks.png</file>
- <file>24x24/resourcepacks.png</file>
- <file>32x32/resourcepacks.png</file>
- <file>64x64/resourcepacks.png</file>
-
- <!-- Refresh, CC-BY-SA 3.0, Oxygen icons. -->
- <file>16x16/refresh.png</file>
- <file>22x22/refresh.png</file>
- <file>32x32/refresh.png</file>
- <file>48x48/refresh.png</file>
- <file>64x64/refresh.png</file>
-
- <!-- Settings, LGPL-2.1, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/apps/system-settings-3.png -->
- <file>16x16/settings.png</file>
+ <file>48x48/new.png</file>
+ <file>64x64/new.png</file>
+
+ <!-- Open news. Our own. -->
+ <file>scalable/news.svg</file>
+ <file>16x16/news.png</file>
+ <file>22x22/news.png</file>
+ <file>32x32/news.png</file>
+ <file>48x48/news.png</file>
+ <file>64x64/news.png</file>
+
+ <!-- Bad status. Our own. -->
+ <file>16x16/status-bad.png</file>
+ <file>24x24/status-bad.png</file>
+ <file>22x22/status-bad.png</file>
+ <file>32x32/status-bad.png</file>
+ <file>48x48/status-bad.png</file>
+ <file>64x64/status-bad.png</file>
+
+ <!-- Good status. Our own. -->
+ <file>16x16/status-good.png</file>
+ <file>24x24/status-good.png</file>
+ <file>22x22/status-good.png</file>
+ <file>32x32/status-good.png</file>
+ <file>48x48/status-good.png</file>
+ <file>64x64/status-good.png</file>
+
+ <!-- Yellow status. Whatever that means... Our own. -->
+ <file>16x16/status-yellow.png</file>
+ <file>24x24/status-yellow.png</file>
+ <file>22x22/status-yellow.png</file>
+ <file>32x32/status-yellow.png</file>
+ <file>48x48/status-yellow.png</file>
+ <file>64x64/status-yellow.png</file>
+
+ <!-- A status icon for things that are in progress/running... Our own. -->
+ <file>16x16/status-running.png</file>
+ <file>24x24/status-running.png</file>
+ <file>22x22/status-running.png</file>
+ <file>32x32/status-running.png</file>
+ <file>48x48/status-running.png</file>
+ <file>64x64/status-running.png</file>
+ <file>scalable/status-running.svg</file>
+
+ <!-- Plugin (blue recolor), CC-BY-SA 3.0, Oxygen icons. -->
+ <file>16x16/loadermods.png</file>
+ <file>24x24/loadermods.png</file>
+ <file>32x32/loadermods.png</file>
+ <file>64x64/loadermods.png</file>
+
+ <!-- Plugin (red recolor), CC-BY-SA 3.0, Oxygen icons. -->
+ <file>16x16/jarmods.png</file>
+ <file>24x24/jarmods.png</file>
+ <file>32x32/jarmods.png</file>
+ <file>64x64/jarmods.png</file>
+
+ <!-- Plugin (green original), CC-BY-SA 3.0, Oxygen icons. -->
+ <file>16x16/coremods.png</file>
+ <file>24x24/coremods.png</file>
+ <file>32x32/coremods.png</file>
+ <file>64x64/coremods.png</file>
+
+ <!-- Resource packs, CC-BY-SA 3.0, Oxygen icons. -->
+ <file>16x16/resourcepacks.png</file>
+ <file>24x24/resourcepacks.png</file>
+ <file>32x32/resourcepacks.png</file>
+ <file>64x64/resourcepacks.png</file>
+
+ <!-- Refresh, CC-BY-SA 3.0, Oxygen icons. -->
+ <file>16x16/refresh.png</file>
+ <file>22x22/refresh.png</file>
+ <file>32x32/refresh.png</file>
+ <file>48x48/refresh.png</file>
+ <file>64x64/refresh.png</file>
+
+ <!-- Settings, LGPL-2.1, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/apps/system-settings-3.png -->
+ <file>16x16/settings.png</file>
<file>22x22/settings.png</file>
- <file>32x32/settings.png</file>
- <file>48x48/settings.png</file>
- <file>64x64/settings.png</file>
-
- <!-- Same, used for instance settings -->
- <file>16x16/instance-settings.png</file>
- <file>22x22/instance-settings.png</file>
- <file>32x32/instance-settings.png</file>
- <file>48x48/instance-settings.png</file>
- <file>64x64/instance-settings.png</file>
-
- <!-- View folder. CC-BY-SA 3.0, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/document-open-folder.png -->
- <file>scalable/viewfolder.svg</file>
- <file>16x16/viewfolder.png</file>
+ <file>32x32/settings.png</file>
+ <file>48x48/settings.png</file>
+ <file>64x64/settings.png</file>
+
+ <!-- Same, used for instance settings -->
+ <file>16x16/instance-settings.png</file>
+ <file>22x22/instance-settings.png</file>
+ <file>32x32/instance-settings.png</file>
+ <file>48x48/instance-settings.png</file>
+ <file>64x64/instance-settings.png</file>
+
+ <!-- View folder. CC-BY-SA 3.0, http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/document-open-folder.png -->
+ <file>scalable/viewfolder.svg</file>
+ <file>16x16/viewfolder.png</file>
<file>22x22/viewfolder.png</file>
- <file>32x32/viewfolder.png</file>
- <file>48x48/viewfolder.png</file>
- <file>64x64/viewfolder.png</file>
+ <file>32x32/viewfolder.png</file>
+ <file>48x48/viewfolder.png</file>
+ <file>64x64/viewfolder.png</file>
- <!-- Default minecraft skin, desaturated, cutout of head, Mojang -->
- <file>8x8/noaccount.png</file>
- <file>16x16/noaccount.png</file>
- <file>24x24/noaccount.png</file>
- <file>32x32/noaccount.png</file>
- <file>48x48/noaccount.png</file>
+ <!-- Default minecraft skin, desaturated, cutout of head, Mojang -->
+ <file>8x8/noaccount.png</file>
+ <file>16x16/noaccount.png</file>
+ <file>24x24/noaccount.png</file>
+ <file>32x32/noaccount.png</file>
+ <file>48x48/noaccount.png</file>
- <!-- and the same again. TODO: make a nice accounts icon -->
- <file alias="8x8/accounts.png">8x8/noaccount.png</file>
- <file alias="16x16/accounts.png">16x16/noaccount.png</file>
- <file alias="24x24/accounts.png">24x24/noaccount.png</file>
- <file alias="32x32/accounts.png">32x32/noaccount.png</file>
- <file alias="48x48/accounts.png">48x48/noaccount.png</file>
+ <!-- and the same again. TODO: make a nice accounts icon -->
+ <file alias="8x8/accounts.png">8x8/noaccount.png</file>
+ <file alias="16x16/accounts.png">16x16/noaccount.png</file>
+ <file alias="24x24/accounts.png">24x24/noaccount.png</file>
+ <file alias="32x32/accounts.png">32x32/noaccount.png</file>
+ <file alias="48x48/accounts.png">48x48/noaccount.png</file>
- <!-- Log file, LGPL, http://www.iconarchive.com/show/crystal-clear-icons-by-everaldo/Mimetype-text-icon.html -->
- <file>16x16/log.png</file>
- <file>24x24/log.png</file>
- <file>32x32/log.png</file>
- <file>48x48/log.png</file>
- <file>64x64/log.png</file>
+ <!-- Log file, LGPL, http://www.iconarchive.com/show/crystal-clear-icons-by-everaldo/Mimetype-text-icon.html -->
+ <file>16x16/log.png</file>
+ <file>24x24/log.png</file>
+ <file>32x32/log.png</file>
+ <file>48x48/log.png</file>
+ <file>64x64/log.png</file>
- <!-- placeholder for minecraft servers -->
- <file>128x128/unknown_server.png</file>
+ <!-- placeholder for minecraft servers -->
+ <file>128x128/unknown_server.png</file>
- <!-- placeholder when loading screenshot images -->
- <file>scalable/screenshot-placeholder.svg</file>
+ <!-- placeholder when loading screenshot images -->
+ <file>scalable/screenshot-placeholder.svg</file>
- <!-- discord logo icon thing. from discord. traced from bitmap -->
- <file>scalable/discord.svg</file>
+ <!-- discord logo icon thing. from discord. traced from bitmap -->
+ <file>scalable/discord.svg</file>
- <!-- instance icons -->
- <file>32x32/instances/chicken.png</file>
- <file>128x128/instances/chicken.png</file>
+ <!-- instance icons -->
+ <file>32x32/instances/chicken.png</file>
+ <file>128x128/instances/chicken.png</file>
- <file>32x32/instances/creeper.png</file>
- <file>128x128/instances/creeper.png</file>
+ <file>32x32/instances/creeper.png</file>
+ <file>128x128/instances/creeper.png</file>
- <file>32x32/instances/enderpearl.png</file>
- <file>128x128/instances/enderpearl.png</file>
+ <file>32x32/instances/enderpearl.png</file>
+ <file>128x128/instances/enderpearl.png</file>
- <file>32x32/instances/ftb_glow.png</file>
- <file>128x128/instances/ftb_glow.png</file>
+ <file>32x32/instances/ftb_glow.png</file>
+ <file>128x128/instances/ftb_glow.png</file>
- <file>32x32/instances/ftb_logo.png</file>
- <file>128x128/instances/ftb_logo.png</file>
+ <file>32x32/instances/ftb_logo.png</file>
+ <file>128x128/instances/ftb_logo.png</file>
- <file>32x32/instances/flame.png</file>
- <file>128x128/instances/flame.png</file>
+ <file>32x32/instances/flame.png</file>
+ <file>128x128/instances/flame.png</file>
- <file>32x32/instances/gear.png</file>
- <file>128x128/instances/gear.png</file>
+ <file>32x32/instances/gear.png</file>
+ <file>128x128/instances/gear.png</file>
- <file>32x32/instances/herobrine.png</file>
- <file>128x128/instances/herobrine.png</file>
+ <file>32x32/instances/herobrine.png</file>
+ <file>128x128/instances/herobrine.png</file>
- <file>32x32/instances/infinity.png</file>
- <file>128x128/instances/infinity.png</file>
+ <file>32x32/instances/infinity.png</file>
+ <file>128x128/instances/infinity.png</file>
- <file>32x32/instances/magitech.png</file>
- <file>128x128/instances/magitech.png</file>
+ <file>32x32/instances/magitech.png</file>
+ <file>128x128/instances/magitech.png</file>
- <file>32x32/instances/meat.png</file>
- <file>128x128/instances/meat.png</file>
+ <file>32x32/instances/meat.png</file>
+ <file>128x128/instances/meat.png</file>
- <file>32x32/instances/netherstar.png</file>
- <file>128x128/instances/netherstar.png</file>
+ <file>32x32/instances/netherstar.png</file>
+ <file>128x128/instances/netherstar.png</file>
- <file>32x32/instances/skeleton.png</file>
- <file>128x128/instances/skeleton.png</file>
+ <file>32x32/instances/skeleton.png</file>
+ <file>128x128/instances/skeleton.png</file>
- <file>32x32/instances/squarecreeper.png</file>
- <file>128x128/instances/squarecreeper.png</file>
+ <file>32x32/instances/squarecreeper.png</file>
+ <file>128x128/instances/squarecreeper.png</file>
- <file>32x32/instances/steve.png</file>
- <file>128x128/instances/steve.png</file>
+ <file>32x32/instances/steve.png</file>
+ <file>128x128/instances/steve.png</file>
- <file>32x32/instances/brick.png</file>
- <file>32x32/instances/diamond.png</file>
- <file>32x32/instances/dirt.png</file>
- <file>32x32/instances/gold.png</file>
- <file>32x32/instances/grass.png</file>
- <file>32x32/instances/iron.png</file>
- <file>32x32/instances/planks.png</file>
- <file>32x32/instances/stone.png</file>
- <file>32x32/instances/tnt.png</file>
+ <file>32x32/instances/brick.png</file>
+ <file>32x32/instances/diamond.png</file>
+ <file>32x32/instances/dirt.png</file>
+ <file>32x32/instances/gold.png</file>
+ <file>32x32/instances/grass.png</file>
+ <file>32x32/instances/iron.png</file>
+ <file>32x32/instances/planks.png</file>
+ <file>32x32/instances/stone.png</file>
+ <file>32x32/instances/tnt.png</file>
- <file>50x50/instances/enderman.png</file>
- </qresource>
+ <file>50x50/instances/enderman.png</file>
+ </qresource>
</RCC>
diff --git a/application/resources/pe_blue/pe_blue.qrc b/application/resources/pe_blue/pe_blue.qrc
index 1706371a..7d28d3d7 100644
--- a/application/resources/pe_blue/pe_blue.qrc
+++ b/application/resources/pe_blue/pe_blue.qrc
@@ -1,37 +1,37 @@
<!DOCTYPE RCC>
<RCC version="1.0">
- <qresource prefix="/icons/pe_blue">
- <file>index.theme</file>
- <file>scalable/about.svg</file>
- <file>scalable/accounts.svg</file>
- <file>scalable/bug.svg</file>
- <file>scalable/centralmods.svg</file>
- <file>scalable/checkupdate.svg</file>
- <file>scalable/copy.svg</file>
- <file>scalable/coremods.svg</file>
- <file>scalable/externaltools.svg</file>
- <file>scalable/help.svg</file>
- <file>scalable/instance-settings.svg</file>
- <file>scalable/jarmods.svg</file>
- <file>scalable/java.svg</file>
- <file>scalable/loadermods.svg</file>
- <file>scalable/log.svg</file>
- <file>scalable/minecraft.svg</file>
- <file>scalable/multimc.svg</file>
- <file>scalable/new.svg</file>
- <file>scalable/news.svg</file>
- <file>scalable/notes.svg</file>
- <file>scalable/patreon.svg</file>
- <file>scalable/proxy.svg</file>
- <file>scalable/quickmods.svg</file>
- <file>scalable/refresh.svg</file>
- <file>scalable/resourcepacks.svg</file>
- <file>scalable/screenshots.svg</file>
- <file>scalable/settings.svg</file>
- <file>scalable/status-bad.svg</file>
- <file>scalable/status-good.svg</file>
- <file>scalable/status-yellow.svg</file>
- <file>scalable/viewfolder.svg</file>
- <file>scalable/worlds.svg</file>
- </qresource>
+ <qresource prefix="/icons/pe_blue">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
+ <file>scalable/instance-settings.svg</file>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/multimc.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/patreon.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/quickmods.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ </qresource>
</RCC>
diff --git a/application/resources/pe_colored/pe_colored.qrc b/application/resources/pe_colored/pe_colored.qrc
index 588e3ac0..9a7a89cc 100644
--- a/application/resources/pe_colored/pe_colored.qrc
+++ b/application/resources/pe_colored/pe_colored.qrc
@@ -1,37 +1,37 @@
<!DOCTYPE RCC>
<RCC version="1.0">
- <qresource prefix="/icons/pe_colored">
- <file>index.theme</file>
- <file>scalable/about.svg</file>
- <file>scalable/accounts.svg</file>
- <file>scalable/bug.svg</file>
- <file>scalable/centralmods.svg</file>
- <file>scalable/checkupdate.svg</file>
- <file>scalable/copy.svg</file>
- <file>scalable/coremods.svg</file>
- <file>scalable/externaltools.svg</file>
- <file>scalable/help.svg</file>
- <file>scalable/instance-settings.svg</file>
- <file>scalable/jarmods.svg</file>
- <file>scalable/java.svg</file>
- <file>scalable/loadermods.svg</file>
- <file>scalable/log.svg</file>
- <file>scalable/minecraft.svg</file>
- <file>scalable/multimc.svg</file>
- <file>scalable/new.svg</file>
- <file>scalable/news.svg</file>
- <file>scalable/notes.svg</file>
- <file>scalable/patreon.svg</file>
- <file>scalable/proxy.svg</file>
- <file>scalable/quickmods.svg</file>
- <file>scalable/refresh.svg</file>
- <file>scalable/resourcepacks.svg</file>
- <file>scalable/screenshots.svg</file>
- <file>scalable/settings.svg</file>
- <file>scalable/status-bad.svg</file>
- <file>scalable/status-good.svg</file>
- <file>scalable/status-yellow.svg</file>
- <file>scalable/viewfolder.svg</file>
- <file>scalable/worlds.svg</file>
- </qresource>
+ <qresource prefix="/icons/pe_colored">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
+ <file>scalable/instance-settings.svg</file>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/multimc.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/patreon.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/quickmods.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ </qresource>
</RCC>
diff --git a/application/resources/pe_dark/pe_dark.qrc b/application/resources/pe_dark/pe_dark.qrc
index 3543f590..0a49b0bb 100644
--- a/application/resources/pe_dark/pe_dark.qrc
+++ b/application/resources/pe_dark/pe_dark.qrc
@@ -1,37 +1,37 @@
<!DOCTYPE RCC>
<RCC version="1.0">
- <qresource prefix="/icons/pe_dark">
- <file>index.theme</file>
- <file>scalable/about.svg</file>
- <file>scalable/accounts.svg</file>
- <file>scalable/bug.svg</file>
- <file>scalable/centralmods.svg</file>
- <file>scalable/checkupdate.svg</file>
- <file>scalable/copy.svg</file>
- <file>scalable/coremods.svg</file>
- <file>scalable/externaltools.svg</file>
- <file>scalable/help.svg</file>
- <file>scalable/instance-settings.svg</file>
- <file>scalable/jarmods.svg</file>
- <file>scalable/java.svg</file>
- <file>scalable/loadermods.svg</file>
- <file>scalable/log.svg</file>
- <file>scalable/minecraft.svg</file>
- <file>scalable/multimc.svg</file>
- <file>scalable/new.svg</file>
- <file>scalable/news.svg</file>
- <file>scalable/notes.svg</file>
- <file>scalable/patreon.svg</file>
- <file>scalable/proxy.svg</file>
- <file>scalable/quickmods.svg</file>
- <file>scalable/refresh.svg</file>
- <file>scalable/resourcepacks.svg</file>
- <file>scalable/screenshots.svg</file>
- <file>scalable/settings.svg</file>
- <file>scalable/status-bad.svg</file>
- <file>scalable/status-good.svg</file>
- <file>scalable/status-yellow.svg</file>
- <file>scalable/viewfolder.svg</file>
- <file>scalable/worlds.svg</file>
- </qresource>
+ <qresource prefix="/icons/pe_dark">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
+ <file>scalable/instance-settings.svg</file>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/multimc.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/patreon.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/quickmods.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ </qresource>
</RCC>
diff --git a/application/resources/pe_light/pe_light.qrc b/application/resources/pe_light/pe_light.qrc
index f83d6eba..98c29e9e 100644
--- a/application/resources/pe_light/pe_light.qrc
+++ b/application/resources/pe_light/pe_light.qrc
@@ -1,38 +1,38 @@
<!DOCTYPE RCC>
<RCC version="1.0">
- <qresource prefix="/icons/pe_light">
- <file>index.theme</file>
- <file>scalable/about.svg</file>
- <file>scalable/accounts.svg</file>
- <file>scalable/bug.svg</file>
- <file>scalable/centralmods.svg</file>
- <file>scalable/checkupdate.svg</file>
- <file>scalable/copy.svg</file>
- <file>scalable/coremods.svg</file>
- <file>scalable/externaltools.svg</file>
- <file>scalable/help.svg</file>
- <file>scalable/instance-settings.svg</file>
- <file>scalable/jarmods.svg</file>
- <file>scalable/java.svg</file>
- <file>scalable/loadermods.svg</file>
- <file>scalable/log.svg</file>
- <file>scalable/minecraft.svg</file>
- <file>scalable/multimc.svg</file>
- <file>scalable/new.svg</file>
- <file>scalable/news.svg</file>
- <file>scalable/notes.svg</file>
- <file>scalable/patreon.svg</file>
- <file>scalable/proxy.svg</file>
- <file>scalable/quickmods.svg</file>
- <file>scalable/refresh.svg</file>
- <file>scalable/resourcepacks.svg</file>
- <file>scalable/screenshots.svg</file>
- <file>scalable/settings.svg</file>
- <file>scalable/status-bad.svg</file>
- <file>scalable/status-good.svg</file>
- <file>scalable/status-yellow.svg</file>
- <file>scalable/viewfolder.svg</file>
- <file>scalable/worlds.svg</file>
- </qresource>
+ <qresource prefix="/icons/pe_light">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
+ <file>scalable/instance-settings.svg</file>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/multimc.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/patreon.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/quickmods.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ </qresource>
</RCC>
diff --git a/application/setupwizard/AnalyticsWizardPage.cpp b/application/setupwizard/AnalyticsWizardPage.cpp
index f32bfcf6..4fb0bcca 100644
--- a/application/setupwizard/AnalyticsWizardPage.cpp
+++ b/application/setupwizard/AnalyticsWizardPage.cpp
@@ -9,22 +9,22 @@
#include <BuildConfig.h>
AnalyticsWizardPage::AnalyticsWizardPage(QWidget *parent)
- : BaseWizardPage(parent)
+ : BaseWizardPage(parent)
{
- setObjectName(QStringLiteral("analyticsPage"));
- verticalLayout_3 = new QVBoxLayout(this);
- verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3"));
- textBrowser = new QTextBrowser(this);
- textBrowser->setObjectName(QStringLiteral("textBrowser"));
- textBrowser->setAcceptRichText(false);
- textBrowser->setOpenExternalLinks(true);
- verticalLayout_3->addWidget(textBrowser);
+ setObjectName(QStringLiteral("analyticsPage"));
+ verticalLayout_3 = new QVBoxLayout(this);
+ verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3"));
+ textBrowser = new QTextBrowser(this);
+ textBrowser->setObjectName(QStringLiteral("textBrowser"));
+ textBrowser->setAcceptRichText(false);
+ textBrowser->setOpenExternalLinks(true);
+ verticalLayout_3->addWidget(textBrowser);
- checkBox = new QCheckBox(this);
- checkBox->setObjectName(QStringLiteral("checkBox"));
- checkBox->setChecked(true);
- verticalLayout_3->addWidget(checkBox);
- retranslate();
+ checkBox = new QCheckBox(this);
+ checkBox->setObjectName(QStringLiteral("checkBox"));
+ checkBox->setChecked(true);
+ verticalLayout_3->addWidget(checkBox);
+ retranslate();
}
AnalyticsWizardPage::~AnalyticsWizardPage()
@@ -33,31 +33,31 @@ AnalyticsWizardPage::~AnalyticsWizardPage()
bool AnalyticsWizardPage::validatePage()
{
- auto settings = MMC->settings();
- auto analytics = MMC->analytics();
- auto status = checkBox->isChecked();
- settings->set("AnalyticsSeen", analytics->version());
- settings->set("Analytics", status);
- return true;
+ auto settings = MMC->settings();
+ auto analytics = MMC->analytics();
+ auto status = checkBox->isChecked();
+ settings->set("AnalyticsSeen", analytics->version());
+ settings->set("Analytics", status);
+ return true;
}
void AnalyticsWizardPage::retranslate()
{
- setTitle(tr("Analytics"));
- setSubTitle(tr("We track some anonymous statistics about users."));
- textBrowser->setHtml(tr(
- "<html><body>"
- "<p>MultiMC sends anonymous usage statistics on every start of the application. This helps us decide what platforms and issues to focus on.</p>"
- "<p>The data is processed by Google Analytics, see their <a href=\"https://support.google.com/analytics/answer/6004245?hl=en\">article on the "
- "matter</a>.</p>"
- "<p>The following data is collected:</p>"
- "<ul><li>A random unique ID of the MultiMC installation.<br />It is stored in the application settings (multimc.cfg).</li>"
- "<li>Anonymized (partial) IP address.</li>"
- "<li>MultiMC version.</li>"
- "<li>Operating system name, version and architecture.</li>"
- "<li>CPU architecture (kernel architecture on linux).</li>"
- "<li>Size of system memory.</li>"
- "<li>Java version, architecture and memory settings.</li></ul>"
- "<p>If we change the tracked information, you will see this page again.</p></body></html>"));
- checkBox->setText(tr("Enable Analytics"));
+ setTitle(tr("Analytics"));
+ setSubTitle(tr("We track some anonymous statistics about users."));
+ textBrowser->setHtml(tr(
+ "<html><body>"
+ "<p>MultiMC sends anonymous usage statistics on every start of the application. This helps us decide what platforms and issues to focus on.</p>"
+ "<p>The data is processed by Google Analytics, see their <a href=\"https://support.google.com/analytics/answer/6004245?hl=en\">article on the "
+ "matter</a>.</p>"
+ "<p>The following data is collected:</p>"
+ "<ul><li>A random unique ID of the MultiMC installation.<br />It is stored in the application settings (multimc.cfg).</li>"
+ "<li>Anonymized (partial) IP address.</li>"
+ "<li>MultiMC version.</li>"
+ "<li>Operating system name, version and architecture.</li>"
+ "<li>CPU architecture (kernel architecture on linux).</li>"
+ "<li>Size of system memory.</li>"
+ "<li>Java version, architecture and memory settings.</li></ul>"
+ "<p>If we change the tracked information, you will see this page again.</p></body></html>"));
+ checkBox->setText(tr("Enable Analytics"));
}
diff --git a/application/setupwizard/AnalyticsWizardPage.h b/application/setupwizard/AnalyticsWizardPage.h
index 0234f02a..c451db2c 100644
--- a/application/setupwizard/AnalyticsWizardPage.h
+++ b/application/setupwizard/AnalyticsWizardPage.h
@@ -8,18 +8,18 @@ class QCheckBox;
class AnalyticsWizardPage : public BaseWizardPage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit AnalyticsWizardPage(QWidget *parent = Q_NULLPTR);
- virtual ~AnalyticsWizardPage();
+ explicit AnalyticsWizardPage(QWidget *parent = Q_NULLPTR);
+ virtual ~AnalyticsWizardPage();
- bool validatePage() override;
+ bool validatePage() override;
protected:
- void retranslate() override;
+ void retranslate() override;
private:
- QVBoxLayout *verticalLayout_3 = nullptr;
- QTextBrowser *textBrowser = nullptr;
- QCheckBox *checkBox = nullptr;
+ QVBoxLayout *verticalLayout_3 = nullptr;
+ QTextBrowser *textBrowser = nullptr;
+ QCheckBox *checkBox = nullptr;
}; \ No newline at end of file
diff --git a/application/setupwizard/BaseWizardPage.h b/application/setupwizard/BaseWizardPage.h
index 9ad54e09..72dbecfd 100644
--- a/application/setupwizard/BaseWizardPage.h
+++ b/application/setupwizard/BaseWizardPage.h
@@ -6,28 +6,28 @@
class BaseWizardPage : public QWizardPage
{
public:
- explicit BaseWizardPage(QWidget *parent = Q_NULLPTR)
- : QWizardPage(parent)
- {
- }
- virtual ~BaseWizardPage() {};
+ explicit BaseWizardPage(QWidget *parent = Q_NULLPTR)
+ : QWizardPage(parent)
+ {
+ }
+ virtual ~BaseWizardPage() {};
- virtual bool wantsRefreshButton()
- {
- return false;
- }
- virtual void refresh()
- {
- }
+ virtual bool wantsRefreshButton()
+ {
+ return false;
+ }
+ virtual void refresh()
+ {
+ }
protected:
- virtual void retranslate() = 0;
- void changeEvent(QEvent * event) override
- {
- if (event->type() == QEvent::LanguageChange)
- {
- retranslate();
- }
- QWizardPage::changeEvent(event);
- }
+ virtual void retranslate() = 0;
+ void changeEvent(QEvent * event) override
+ {
+ if (event->type() == QEvent::LanguageChange)
+ {
+ retranslate();
+ }
+ QWizardPage::changeEvent(event);
+ }
};
diff --git a/application/setupwizard/JavaWizardPage.cpp b/application/setupwizard/JavaWizardPage.cpp
index cd2bca46..ad571c09 100644
--- a/application/setupwizard/JavaWizardPage.cpp
+++ b/application/setupwizard/JavaWizardPage.cpp
@@ -21,76 +21,76 @@
JavaWizardPage::JavaWizardPage(QWidget *parent)
- :BaseWizardPage(parent)
+ :BaseWizardPage(parent)
{
- setupUi();
+ setupUi();
}
void JavaWizardPage::setupUi()
{
- setObjectName(QStringLiteral("javaPage"));
- QVBoxLayout * layout = new QVBoxLayout(this);
+ setObjectName(QStringLiteral("javaPage"));
+ QVBoxLayout * layout = new QVBoxLayout(this);
- m_java_widget = new JavaSettingsWidget(this);
- layout->addWidget(m_java_widget);
- setLayout(layout);
+ m_java_widget = new JavaSettingsWidget(this);
+ layout->addWidget(m_java_widget);
+ setLayout(layout);
- retranslate();
+ retranslate();
}
void JavaWizardPage::refresh()
{
- m_java_widget->refresh();
+ m_java_widget->refresh();
}
void JavaWizardPage::initializePage()
{
- m_java_widget->initialize();
+ m_java_widget->initialize();
}
bool JavaWizardPage::wantsRefreshButton()
{
- return true;
+ return true;
}
bool JavaWizardPage::validatePage()
{
- auto settings = MMC->settings();
- auto result = m_java_widget->validate();
- switch(result)
- {
- default:
- case JavaSettingsWidget::ValidationStatus::Bad:
- {
- return false;
- }
- case JavaSettingsWidget::ValidationStatus::AllOK:
- {
- settings->set("JavaPath", m_java_widget->javaPath());
- }
- case JavaSettingsWidget::ValidationStatus::JavaBad:
- {
- // Memory
- auto s = MMC->settings();
- s->set("MinMemAlloc", m_java_widget->minHeapSize());
- s->set("MaxMemAlloc", m_java_widget->maxHeapSize());
- if (m_java_widget->permGenEnabled())
- {
- s->set("PermGen", m_java_widget->permGenSize());
- }
- else
- {
- s->reset("PermGen");
- }
- return true;
- }
- }
+ auto settings = MMC->settings();
+ auto result = m_java_widget->validate();
+ switch(result)
+ {
+ default:
+ case JavaSettingsWidget::ValidationStatus::Bad:
+ {
+ return false;
+ }
+ case JavaSettingsWidget::ValidationStatus::AllOK:
+ {
+ settings->set("JavaPath", m_java_widget->javaPath());
+ }
+ case JavaSettingsWidget::ValidationStatus::JavaBad:
+ {
+ // Memory
+ auto s = MMC->settings();
+ s->set("MinMemAlloc", m_java_widget->minHeapSize());
+ s->set("MaxMemAlloc", m_java_widget->maxHeapSize());
+ if (m_java_widget->permGenEnabled())
+ {
+ s->set("PermGen", m_java_widget->permGenSize());
+ }
+ else
+ {
+ s->reset("PermGen");
+ }
+ return true;
+ }
+ }
}
void JavaWizardPage::retranslate()
{
- setTitle(tr("Java"));
- setSubTitle(tr("You do not have a working Java set up yet or it went missing.\n"
- "Please select one of the following or browse for a java executable."));
- m_java_widget->retranslate();
+ setTitle(tr("Java"));
+ setSubTitle(tr("You do not have a working Java set up yet or it went missing.\n"
+ "Please select one of the following or browse for a java executable."));
+ m_java_widget->retranslate();
}
diff --git a/application/setupwizard/JavaWizardPage.h b/application/setupwizard/JavaWizardPage.h
index 592fa24c..0d749039 100644
--- a/application/setupwizard/JavaWizardPage.h
+++ b/application/setupwizard/JavaWizardPage.h
@@ -6,24 +6,24 @@ class JavaSettingsWidget;
class JavaWizardPage : public BaseWizardPage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit JavaWizardPage(QWidget *parent = Q_NULLPTR);
+ explicit JavaWizardPage(QWidget *parent = Q_NULLPTR);
- virtual ~JavaWizardPage()
- {
- };
+ virtual ~JavaWizardPage()
+ {
+ };
- bool wantsRefreshButton() override;
- void refresh() override;
- void initializePage() override;
- bool validatePage() override;
+ bool wantsRefreshButton() override;
+ void refresh() override;
+ void initializePage() override;
+ bool validatePage() override;
protected: /* methods */
- void setupUi();
- void retranslate() override;
+ void setupUi();
+ void retranslate() override;
private: /* data */
- JavaSettingsWidget *m_java_widget = nullptr;
+ JavaSettingsWidget *m_java_widget = nullptr;
};
diff --git a/application/setupwizard/LanguageWizardPage.cpp b/application/setupwizard/LanguageWizardPage.cpp
index b884c91a..dbbe5e7f 100644
--- a/application/setupwizard/LanguageWizardPage.cpp
+++ b/application/setupwizard/LanguageWizardPage.cpp
@@ -6,21 +6,21 @@
#include <QListView>
LanguageWizardPage::LanguageWizardPage(QWidget *parent)
- : BaseWizardPage(parent)
+ : BaseWizardPage(parent)
{
- setObjectName(QStringLiteral("languagePage"));
- verticalLayout = new QVBoxLayout(this);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
- languageView = new QListView(this);
- languageView->setObjectName(QStringLiteral("languageView"));
- verticalLayout->addWidget(languageView);
- retranslate();
+ setObjectName(QStringLiteral("languagePage"));
+ verticalLayout = new QVBoxLayout(this);
+ verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ languageView = new QListView(this);
+ languageView->setObjectName(QStringLiteral("languageView"));
+ verticalLayout->addWidget(languageView);
+ retranslate();
- auto translations = MMC->translations();
- auto index = translations->selectedIndex();
- languageView->setModel(translations.get());
- languageView->setCurrentIndex(index);
- connect(languageView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &LanguageWizardPage::languageRowChanged);
+ auto translations = MMC->translations();
+ auto index = translations->selectedIndex();
+ languageView->setModel(translations.get());
+ languageView->setCurrentIndex(index);
+ connect(languageView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &LanguageWizardPage::languageRowChanged);
}
LanguageWizardPage::~LanguageWizardPage()
@@ -29,38 +29,38 @@ LanguageWizardPage::~LanguageWizardPage()
bool LanguageWizardPage::wantsRefreshButton()
{
- return true;
+ return true;
}
void LanguageWizardPage::refresh()
{
- auto translations = MMC->translations();
- translations->downloadIndex();
+ auto translations = MMC->translations();
+ translations->downloadIndex();
}
bool LanguageWizardPage::validatePage()
{
- auto settings = MMC->settings();
- auto translations = MMC->translations();
- QString key = translations->data(languageView->currentIndex(), Qt::UserRole).toString();
- settings->set("Language", key);
- return true;
+ auto settings = MMC->settings();
+ auto translations = MMC->translations();
+ QString key = translations->data(languageView->currentIndex(), Qt::UserRole).toString();
+ settings->set("Language", key);
+ return true;
}
void LanguageWizardPage::retranslate()
{
- setTitle(tr("Language"));
- setSubTitle(tr("Select the language to use in MultiMC"));
+ setTitle(tr("Language"));
+ setSubTitle(tr("Select the language to use in MultiMC"));
}
void LanguageWizardPage::languageRowChanged(const QModelIndex &current, const QModelIndex &previous)
{
- if (current == previous)
- {
- return;
- }
- auto translations = MMC->translations();
- QString key = translations->data(current, Qt::UserRole).toString();
- translations->selectLanguage(key);
- translations->updateLanguage(key);
+ if (current == previous)
+ {
+ return;
+ }
+ auto translations = MMC->translations();
+ QString key = translations->data(current, Qt::UserRole).toString();
+ translations->selectLanguage(key);
+ translations->updateLanguage(key);
}
diff --git a/application/setupwizard/LanguageWizardPage.h b/application/setupwizard/LanguageWizardPage.h
index 5a9e882d..866f81c3 100644
--- a/application/setupwizard/LanguageWizardPage.h
+++ b/application/setupwizard/LanguageWizardPage.h
@@ -7,25 +7,25 @@ class QListView;
class LanguageWizardPage : public BaseWizardPage
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit LanguageWizardPage(QWidget *parent = Q_NULLPTR);
+ explicit LanguageWizardPage(QWidget *parent = Q_NULLPTR);
- virtual ~LanguageWizardPage();
+ virtual ~LanguageWizardPage();
- bool wantsRefreshButton() override;
+ bool wantsRefreshButton() override;
- void refresh() override;
+ void refresh() override;
- bool validatePage() override;
+ bool validatePage() override;
protected:
- void retranslate() override;
+ void retranslate() override;
protected slots:
- void languageRowChanged(const QModelIndex &current, const QModelIndex &previous);
+ void languageRowChanged(const QModelIndex &current, const QModelIndex &previous);
private:
- QVBoxLayout *verticalLayout = nullptr;
- QListView *languageView = nullptr;
+ QVBoxLayout *verticalLayout = nullptr;
+ QListView *languageView = nullptr;
};
diff --git a/application/setupwizard/SetupWizard.cpp b/application/setupwizard/SetupWizard.cpp
index c13f15ee..60a78b8d 100644
--- a/application/setupwizard/SetupWizard.cpp
+++ b/application/setupwizard/SetupWizard.cpp
@@ -13,74 +13,74 @@
SetupWizard::SetupWizard(QWidget *parent) : QWizard(parent)
{
- setObjectName(QStringLiteral("SetupWizard"));
- resize(615, 659);
- // make it ugly everywhere to avoid variability in theming
- setWizardStyle(QWizard::ClassicStyle);
- setOptions(QWizard::NoCancelButton | QWizard::IndependentPages | QWizard::HaveCustomButton1);
+ setObjectName(QStringLiteral("SetupWizard"));
+ resize(615, 659);
+ // make it ugly everywhere to avoid variability in theming
+ setWizardStyle(QWizard::ClassicStyle);
+ setOptions(QWizard::NoCancelButton | QWizard::IndependentPages | QWizard::HaveCustomButton1);
- retranslate();
+ retranslate();
- connect(this, &QWizard::currentIdChanged, this, &SetupWizard::pageChanged);
+ connect(this, &QWizard::currentIdChanged, this, &SetupWizard::pageChanged);
}
void SetupWizard::retranslate()
{
- setButtonText(QWizard::NextButton, tr("&Next >"));
- setButtonText(QWizard::BackButton, tr("< &Back"));
- setButtonText(QWizard::FinishButton, tr("&Finish"));
- setButtonText(QWizard::CustomButton1, tr("&Refresh"));
- setWindowTitle(tr("MultiMC Quick Setup"));
+ setButtonText(QWizard::NextButton, tr("&Next >"));
+ setButtonText(QWizard::BackButton, tr("< &Back"));
+ setButtonText(QWizard::FinishButton, tr("&Finish"));
+ setButtonText(QWizard::CustomButton1, tr("&Refresh"));
+ setWindowTitle(tr("MultiMC Quick Setup"));
}
BaseWizardPage * SetupWizard::getBasePage(int id)
{
- if(id == -1)
- return nullptr;
- auto pagePtr = page(id);
- if(!pagePtr)
- return nullptr;
- return dynamic_cast<BaseWizardPage *>(pagePtr);
+ if(id == -1)
+ return nullptr;
+ auto pagePtr = page(id);
+ if(!pagePtr)
+ return nullptr;
+ return dynamic_cast<BaseWizardPage *>(pagePtr);
}
BaseWizardPage * SetupWizard::getCurrentBasePage()
{
- return getBasePage(currentId());
+ return getBasePage(currentId());
}
void SetupWizard::pageChanged(int id)
{
- auto basePagePtr = getBasePage(id);
- if(!basePagePtr)
- {
- return;
- }
- if(basePagePtr->wantsRefreshButton())
- {
- setButtonLayout({QWizard::CustomButton1, QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton});
- auto customButton = button(QWizard::CustomButton1);
- connect(customButton, &QAbstractButton::pressed, [&](){
- auto basePagePtr = getCurrentBasePage();
- if(basePagePtr)
- {
- basePagePtr->refresh();
- }
- });
- }
- else
- {
- setButtonLayout({QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton});
- }
+ auto basePagePtr = getBasePage(id);
+ if(!basePagePtr)
+ {
+ return;
+ }
+ if(basePagePtr->wantsRefreshButton())
+ {
+ setButtonLayout({QWizard::CustomButton1, QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton});
+ auto customButton = button(QWizard::CustomButton1);
+ connect(customButton, &QAbstractButton::pressed, [&](){
+ auto basePagePtr = getCurrentBasePage();
+ if(basePagePtr)
+ {
+ basePagePtr->refresh();
+ }
+ });
+ }
+ else
+ {
+ setButtonLayout({QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton});
+ }
}
void SetupWizard::changeEvent(QEvent *event)
{
- if (event->type() == QEvent::LanguageChange)
- {
- retranslate();
- }
- QWizard::changeEvent(event);
+ if (event->type() == QEvent::LanguageChange)
+ {
+ retranslate();
+ }
+ QWizard::changeEvent(event);
}
SetupWizard::~SetupWizard()
diff --git a/application/setupwizard/SetupWizard.h b/application/setupwizard/SetupWizard.h
index e3292997..aa3fb32c 100644
--- a/application/setupwizard/SetupWizard.h
+++ b/application/setupwizard/SetupWizard.h
@@ -26,20 +26,20 @@ class BaseWizardPage;
class SetupWizard : public QWizard
{
- Q_OBJECT
+ Q_OBJECT
public: /* con/destructors */
- explicit SetupWizard(QWidget *parent = 0);
- virtual ~SetupWizard();
+ explicit SetupWizard(QWidget *parent = 0);
+ virtual ~SetupWizard();
- void changeEvent(QEvent * event) override;
- BaseWizardPage *getBasePage(int id);
- BaseWizardPage *getCurrentBasePage();
+ void changeEvent(QEvent * event) override;
+ BaseWizardPage *getBasePage(int id);
+ BaseWizardPage *getCurrentBasePage();
private slots:
- void pageChanged(int id);
+ void pageChanged(int id);
private: /* methods */
- void retranslate();
+ void retranslate();
};
diff --git a/application/themes/BrightTheme.cpp b/application/themes/BrightTheme.cpp
index 2763c982..b9188bdd 100644
--- a/application/themes/BrightTheme.cpp
+++ b/application/themes/BrightTheme.cpp
@@ -2,55 +2,55 @@
QString BrightTheme::id()
{
- return "bright";
+ return "bright";
}
QString BrightTheme::name()
{
- return QObject::tr("Bright");
+ return QObject::tr("Bright");
}
bool BrightTheme::hasColorScheme()
{
- return true;
+ return true;
}
QPalette BrightTheme::colorScheme()
{
- QPalette brightPalette;
- brightPalette.setColor(QPalette::Window, QColor(239,240,241));
- brightPalette.setColor(QPalette::WindowText, QColor(49,54,59));
- brightPalette.setColor(QPalette::Base, QColor(252,252,252));
- brightPalette.setColor(QPalette::AlternateBase, QColor(239,240,241));
- brightPalette.setColor(QPalette::ToolTipBase, QColor(49,54,59));
- brightPalette.setColor(QPalette::ToolTipText, QColor(239,240,241));
- brightPalette.setColor(QPalette::Text, QColor(49,54,59));
- brightPalette.setColor(QPalette::Button, QColor(239,240,241));
- brightPalette.setColor(QPalette::ButtonText, QColor(49,54,59));
- brightPalette.setColor(QPalette::BrightText, Qt::red);
- brightPalette.setColor(QPalette::Link, QColor(41, 128, 185));
- brightPalette.setColor(QPalette::Highlight, QColor(61, 174, 233));
- brightPalette.setColor(QPalette::HighlightedText, QColor(239,240,241));
- return fadeInactive(brightPalette, fadeAmount(), fadeColor());
+ QPalette brightPalette;
+ brightPalette.setColor(QPalette::Window, QColor(239,240,241));
+ brightPalette.setColor(QPalette::WindowText, QColor(49,54,59));
+ brightPalette.setColor(QPalette::Base, QColor(252,252,252));
+ brightPalette.setColor(QPalette::AlternateBase, QColor(239,240,241));
+ brightPalette.setColor(QPalette::ToolTipBase, QColor(49,54,59));
+ brightPalette.setColor(QPalette::ToolTipText, QColor(239,240,241));
+ brightPalette.setColor(QPalette::Text, QColor(49,54,59));
+ brightPalette.setColor(QPalette::Button, QColor(239,240,241));
+ brightPalette.setColor(QPalette::ButtonText, QColor(49,54,59));
+ brightPalette.setColor(QPalette::BrightText, Qt::red);
+ brightPalette.setColor(QPalette::Link, QColor(41, 128, 185));
+ brightPalette.setColor(QPalette::Highlight, QColor(61, 174, 233));
+ brightPalette.setColor(QPalette::HighlightedText, QColor(239,240,241));
+ return fadeInactive(brightPalette, fadeAmount(), fadeColor());
}
double BrightTheme::fadeAmount()
{
- return 0.5;
+ return 0.5;
}
QColor BrightTheme::fadeColor()
{
- return QColor(239,240,241);
+ return QColor(239,240,241);
}
bool BrightTheme::hasStyleSheet()
{
- return false;
+ return false;
}
QString BrightTheme::appStyleSheet()
{
- return QString();
+ return QString();
}
diff --git a/application/themes/BrightTheme.h b/application/themes/BrightTheme.h
index 31b31b2d..c61f52d5 100644
--- a/application/themes/BrightTheme.h
+++ b/application/themes/BrightTheme.h
@@ -5,15 +5,15 @@
class BrightTheme: public FusionTheme
{
public:
- virtual ~BrightTheme() {}
+ virtual ~BrightTheme() {}
- QString id() override;
- QString name() override;
- bool hasStyleSheet() override;
- QString appStyleSheet() override;
- bool hasColorScheme() override;
- QPalette colorScheme() override;
- double fadeAmount() override;
- QColor fadeColor() override;
+ QString id() override;
+ QString name() override;
+ bool hasStyleSheet() override;
+ QString appStyleSheet() override;
+ bool hasColorScheme() override;
+ QPalette colorScheme() override;
+ double fadeAmount() override;
+ QColor fadeColor() override;
};
diff --git a/application/themes/CustomTheme.cpp b/application/themes/CustomTheme.cpp
index 28e8c5c0..3e3e27de 100644
--- a/application/themes/CustomTheme.cpp
+++ b/application/themes/CustomTheme.cpp
@@ -8,237 +8,237 @@ const char * styleFile = "themeStyle.css";
static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAmount, QColor &fadeColor, QString &name, QString &widgets)
{
- QFileInfo pathInfo(path);
- if(pathInfo.exists() && pathInfo.isFile())
- {
- try
- {
- auto doc = Json::requireDocument(path, "Theme JSON file");
- const QJsonObject root = doc.object();
- name = Json::requireString(root, "name", "Theme name");
- widgets = Json::requireString(root, "widgets", "Qt widget theme");
- auto colorsRoot = Json::requireObject(root, "colors", "colors object");
- auto readColor = [&](QString colorName) -> QColor
- {
- auto colorValue = Json::ensureString(colorsRoot, colorName, QString());
- if(!colorValue.isEmpty())
- {
- QColor color(colorValue);
- if(!color.isValid())
- {
- qWarning() << "Color value" << colorValue << "for" << colorName << "was not recognized.";
- return QColor();
- }
- return color;
- }
- return QColor();
- };
- auto readAndSetColor = [&](QPalette::ColorRole role, QString colorName)
- {
- auto color = readColor(colorName);
- if(color.isValid())
- {
- palette.setColor(role, color);
- }
- else
- {
- qDebug() << "Color value for" << colorName << "was not present.";
- }
- };
-
- // palette
- readAndSetColor(QPalette::Window, "Window");
- readAndSetColor(QPalette::WindowText, "WindowText");
- readAndSetColor(QPalette::Base, "Base");
- readAndSetColor(QPalette::AlternateBase, "AlternateBase");
- readAndSetColor(QPalette::ToolTipBase, "ToolTipBase");
- readAndSetColor(QPalette::ToolTipText, "ToolTipText");
- readAndSetColor(QPalette::Text, "Text");
- readAndSetColor(QPalette::Button, "Button");
- readAndSetColor(QPalette::ButtonText, "ButtonText");
- readAndSetColor(QPalette::BrightText, "BrightText");
- readAndSetColor(QPalette::Link, "Link");
- readAndSetColor(QPalette::Highlight, "Highlight");
- readAndSetColor(QPalette::HighlightedText, "HighlightedText");
-
- //fade
- fadeColor = readColor("fadeColor");
- fadeAmount = Json::ensureDouble(colorsRoot, "fadeAmount", 0.5, "fade amount");
-
- }
- catch (const Exception &e)
- {
- qWarning() << "Couldn't load theme json: " << e.cause();
- return false;
- }
- }
- else
- {
- qDebug() << "No theme json present.";
- return false;
- }
- return true;
+ QFileInfo pathInfo(path);
+ if(pathInfo.exists() && pathInfo.isFile())
+ {
+ try
+ {
+ auto doc = Json::requireDocument(path, "Theme JSON file");
+ const QJsonObject root = doc.object();
+ name = Json::requireString(root, "name", "Theme name");
+ widgets = Json::requireString(root, "widgets", "Qt widget theme");
+ auto colorsRoot = Json::requireObject(root, "colors", "colors object");
+ auto readColor = [&](QString colorName) -> QColor
+ {
+ auto colorValue = Json::ensureString(colorsRoot, colorName, QString());
+ if(!colorValue.isEmpty())
+ {
+ QColor color(colorValue);
+ if(!color.isValid())
+ {
+ qWarning() << "Color value" << colorValue << "for" << colorName << "was not recognized.";
+ return QColor();
+ }
+ return color;
+ }
+ return QColor();
+ };
+ auto readAndSetColor = [&](QPalette::ColorRole role, QString colorName)
+ {
+ auto color = readColor(colorName);
+ if(color.isValid())
+ {
+ palette.setColor(role, color);
+ }
+ else
+ {
+ qDebug() << "Color value for" << colorName << "was not present.";
+ }
+ };
+
+ // palette
+ readAndSetColor(QPalette::Window, "Window");
+ readAndSetColor(QPalette::WindowText, "WindowText");
+ readAndSetColor(QPalette::Base, "Base");
+ readAndSetColor(QPalette::AlternateBase, "AlternateBase");
+ readAndSetColor(QPalette::ToolTipBase, "ToolTipBase");
+ readAndSetColor(QPalette::ToolTipText, "ToolTipText");
+ readAndSetColor(QPalette::Text, "Text");
+ readAndSetColor(QPalette::Button, "Button");
+ readAndSetColor(QPalette::ButtonText, "ButtonText");
+ readAndSetColor(QPalette::BrightText, "BrightText");
+ readAndSetColor(QPalette::Link, "Link");
+ readAndSetColor(QPalette::Highlight, "Highlight");
+ readAndSetColor(QPalette::HighlightedText, "HighlightedText");
+
+ //fade
+ fadeColor = readColor("fadeColor");
+ fadeAmount = Json::ensureDouble(colorsRoot, "fadeAmount", 0.5, "fade amount");
+
+ }
+ catch (const Exception &e)
+ {
+ qWarning() << "Couldn't load theme json: " << e.cause();
+ return false;
+ }
+ }
+ else
+ {
+ qDebug() << "No theme json present.";
+ return false;
+ }
+ return true;
}
static bool writeThemeJson(const QString &path, const QPalette &palette, double fadeAmount, QColor fadeColor, QString name, QString widgets)
{
- QJsonObject rootObj;
- rootObj.insert("name", name);
- rootObj.insert("widgets", widgets);
-
- QJsonObject colorsObj;
- auto insertColor = [&](QPalette::ColorRole role, QString colorName)
- {
- colorsObj.insert(colorName, palette.color(role).name());
- };
-
- // palette
- insertColor(QPalette::Window, "Window");
- insertColor(QPalette::WindowText, "WindowText");
- insertColor(QPalette::Base, "Base");
- insertColor(QPalette::AlternateBase, "AlternateBase");
- insertColor(QPalette::ToolTipBase, "ToolTipBase");
- insertColor(QPalette::ToolTipText, "ToolTipText");
- insertColor(QPalette::Text, "Text");
- insertColor(QPalette::Button, "Button");
- insertColor(QPalette::ButtonText, "ButtonText");
- insertColor(QPalette::BrightText, "BrightText");
- insertColor(QPalette::Link, "Link");
- insertColor(QPalette::Highlight, "Highlight");
- insertColor(QPalette::HighlightedText, "HighlightedText");
-
- // fade
- colorsObj.insert("fadeColor", fadeColor.name());
- colorsObj.insert("fadeAmount", fadeAmount);
-
- rootObj.insert("colors", colorsObj);
- try
- {
- Json::write(rootObj, path);
- return true;
- }
- catch (const Exception &e)
- {
- qWarning() << "Failed to write theme json to" << path;
- return false;
- }
+ QJsonObject rootObj;
+ rootObj.insert("name", name);
+ rootObj.insert("widgets", widgets);
+
+ QJsonObject colorsObj;
+ auto insertColor = [&](QPalette::ColorRole role, QString colorName)
+ {
+ colorsObj.insert(colorName, palette.color(role).name());
+ };
+
+ // palette
+ insertColor(QPalette::Window, "Window");
+ insertColor(QPalette::WindowText, "WindowText");
+ insertColor(QPalette::Base, "Base");
+ insertColor(QPalette::AlternateBase, "AlternateBase");
+ insertColor(QPalette::ToolTipBase, "ToolTipBase");
+ insertColor(QPalette::ToolTipText, "ToolTipText");
+ insertColor(QPalette::Text, "Text");
+ insertColor(QPalette::Button, "Button");
+ insertColor(QPalette::ButtonText, "ButtonText");
+ insertColor(QPalette::BrightText, "BrightText");
+ insertColor(QPalette::Link, "Link");
+ insertColor(QPalette::Highlight, "Highlight");
+ insertColor(QPalette::HighlightedText, "HighlightedText");
+
+ // fade
+ colorsObj.insert("fadeColor", fadeColor.name());
+ colorsObj.insert("fadeAmount", fadeAmount);
+
+ rootObj.insert("colors", colorsObj);
+ try
+ {
+ Json::write(rootObj, path);
+ return true;
+ }
+ catch (const Exception &e)
+ {
+ qWarning() << "Failed to write theme json to" << path;
+ return false;
+ }
}
CustomTheme::CustomTheme(ITheme* baseTheme, QString folder)
{
- m_id = folder;
- QString path = FS::PathCombine("themes", m_id);
- QString pathResources = FS::PathCombine("themes", m_id, "resources");
-
- qDebug() << "Loading theme" << m_id;
-
- if(!FS::ensureFolderPathExists(path) || !FS::ensureFolderPathExists(pathResources))
- {
- qWarning() << "couldn't create folder for theme!";
- m_palette = baseTheme->colorScheme();
- m_styleSheet = baseTheme->appStyleSheet();
- return;
- }
-
- auto themeFilePath = FS::PathCombine(path, themeFile);
-
- m_palette = baseTheme->colorScheme();
- if (!readThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets))
- {
- m_name = "Custom";
- m_palette = baseTheme->colorScheme();
- m_fadeColor = baseTheme->fadeColor();
- m_fadeAmount = baseTheme->fadeAmount();
- m_widgets = baseTheme->qtTheme();
-
- QFileInfo info(themeFilePath);
- if(!info.exists())
- {
- writeThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, "Custom", m_widgets);
- }
- }
- else
- {
- m_palette = fadeInactive(m_palette, m_fadeAmount, m_fadeColor);
- }
-
- auto cssFilePath = FS::PathCombine(path, styleFile);
- QFileInfo info (cssFilePath);
- if(info.isFile())
- {
- try
- {
- // TODO: validate css?
- m_styleSheet = QString::fromUtf8(FS::read(cssFilePath));
- }
- catch (const Exception &e)
- {
- qWarning() << "Couldn't load css:" << e.cause() << "from" << cssFilePath;
- m_styleSheet = baseTheme->appStyleSheet();
- }
- }
- else
- {
- qDebug() << "No theme css present.";
- m_styleSheet = baseTheme->appStyleSheet();
- try
- {
- FS::write(cssFilePath, m_styleSheet.toUtf8());
- }
- catch (const Exception &e)
- {
- qWarning() << "Couldn't write css:" << e.cause() << "to" << cssFilePath;
- }
- }
+ m_id = folder;
+ QString path = FS::PathCombine("themes", m_id);
+ QString pathResources = FS::PathCombine("themes", m_id, "resources");
+
+ qDebug() << "Loading theme" << m_id;
+
+ if(!FS::ensureFolderPathExists(path) || !FS::ensureFolderPathExists(pathResources))
+ {
+ qWarning() << "couldn't create folder for theme!";
+ m_palette = baseTheme->colorScheme();
+ m_styleSheet = baseTheme->appStyleSheet();
+ return;
+ }
+
+ auto themeFilePath = FS::PathCombine(path, themeFile);
+
+ m_palette = baseTheme->colorScheme();
+ if (!readThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets))
+ {
+ m_name = "Custom";
+ m_palette = baseTheme->colorScheme();
+ m_fadeColor = baseTheme->fadeColor();
+ m_fadeAmount = baseTheme->fadeAmount();
+ m_widgets = baseTheme->qtTheme();
+
+ QFileInfo info(themeFilePath);
+ if(!info.exists())
+ {
+ writeThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, "Custom", m_widgets);
+ }
+ }
+ else
+ {
+ m_palette = fadeInactive(m_palette, m_fadeAmount, m_fadeColor);
+ }
+
+ auto cssFilePath = FS::PathCombine(path, styleFile);
+ QFileInfo info (cssFilePath);
+ if(info.isFile())
+ {
+ try
+ {
+ // TODO: validate css?
+ m_styleSheet = QString::fromUtf8(FS::read(cssFilePath));
+ }
+ catch (const Exception &e)
+ {
+ qWarning() << "Couldn't load css:" << e.cause() << "from" << cssFilePath;
+ m_styleSheet = baseTheme->appStyleSheet();
+ }
+ }
+ else
+ {
+ qDebug() << "No theme css present.";
+ m_styleSheet = baseTheme->appStyleSheet();
+ try
+ {
+ FS::write(cssFilePath, m_styleSheet.toUtf8());
+ }
+ catch (const Exception &e)
+ {
+ qWarning() << "Couldn't write css:" << e.cause() << "to" << cssFilePath;
+ }
+ }
}
QStringList CustomTheme::searchPaths()
{
- return { FS::PathCombine("themes", m_id, "resources") };
+ return { FS::PathCombine("themes", m_id, "resources") };
}
QString CustomTheme::id()
{
- return m_id;
+ return m_id;
}
QString CustomTheme::name()
{
- return m_name;
+ return m_name;
}
bool CustomTheme::hasColorScheme()
{
- return true;
+ return true;
}
QPalette CustomTheme::colorScheme()
{
- return m_palette;
+ return m_palette;
}
bool CustomTheme::hasStyleSheet()
{
- return true;
+ return true;
}
QString CustomTheme::appStyleSheet()
{
- return m_styleSheet;
+ return m_styleSheet;
}
double CustomTheme::fadeAmount()
{
- return m_fadeAmount;
+ return m_fadeAmount;
}
QColor CustomTheme::fadeColor()
{
- return m_fadeColor;
+ return m_fadeColor;
}
QString CustomTheme::qtTheme()
{
- return m_widgets;
+ return m_widgets;
}
diff --git a/application/themes/CustomTheme.h b/application/themes/CustomTheme.h
index 9023b13e..d216895d 100644
--- a/application/themes/CustomTheme.h
+++ b/application/themes/CustomTheme.h
@@ -5,27 +5,27 @@
class CustomTheme: public ITheme
{
public:
- CustomTheme(ITheme * baseTheme, QString folder);
- virtual ~CustomTheme() {}
+ CustomTheme(ITheme * baseTheme, QString folder);
+ virtual ~CustomTheme() {}
- QString id() override;
- QString name() override;
- bool hasStyleSheet() override;
- QString appStyleSheet() override;
- bool hasColorScheme() override;
- QPalette colorScheme() override;
- double fadeAmount() override;
- QColor fadeColor() override;
- QString qtTheme() override;
- QStringList searchPaths() override;
+ QString id() override;
+ QString name() override;
+ bool hasStyleSheet() override;
+ QString appStyleSheet() override;
+ bool hasColorScheme() override;
+ QPalette colorScheme() override;
+ double fadeAmount() override;
+ QColor fadeColor() override;
+ QString qtTheme() override;
+ QStringList searchPaths() override;
private: /* data */
- QPalette m_palette;
- QColor m_fadeColor;
- double m_fadeAmount;
- QString m_styleSheet;
- QString m_name;
- QString m_id;
- QString m_widgets;
+ QPalette m_palette;
+ QColor m_fadeColor;
+ double m_fadeAmount;
+ QString m_styleSheet;
+ QString m_name;
+ QString m_id;
+ QString m_widgets;
};
diff --git a/application/themes/DarkTheme.cpp b/application/themes/DarkTheme.cpp
index cf4a81e1..31ecd559 100644
--- a/application/themes/DarkTheme.cpp
+++ b/application/themes/DarkTheme.cpp
@@ -2,54 +2,54 @@
QString DarkTheme::id()
{
- return "dark";
+ return "dark";
}
QString DarkTheme::name()
{
- return QObject::tr("Dark");
+ return QObject::tr("Dark");
}
bool DarkTheme::hasColorScheme()
{
- return true;
+ return true;
}
QPalette DarkTheme::colorScheme()
{
- QPalette darkPalette;
- darkPalette.setColor(QPalette::Window, QColor(49,54,59));
- darkPalette.setColor(QPalette::WindowText, Qt::white);
- darkPalette.setColor(QPalette::Base, QColor(35,38,41));
- darkPalette.setColor(QPalette::AlternateBase, QColor(49,54,59));
- darkPalette.setColor(QPalette::ToolTipBase, Qt::white);
- darkPalette.setColor(QPalette::ToolTipText, Qt::white);
- darkPalette.setColor(QPalette::Text, Qt::white);
- darkPalette.setColor(QPalette::Button, QColor(49,54,59));
- darkPalette.setColor(QPalette::ButtonText, Qt::white);
- darkPalette.setColor(QPalette::BrightText, Qt::red);
- darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
- darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
- darkPalette.setColor(QPalette::HighlightedText, Qt::black);
- return fadeInactive(darkPalette, fadeAmount(), fadeColor());
+ QPalette darkPalette;
+ darkPalette.setColor(QPalette::Window, QColor(49,54,59));
+ darkPalette.setColor(QPalette::WindowText, Qt::white);
+ darkPalette.setColor(QPalette::Base, QColor(35,38,41));
+ darkPalette.setColor(QPalette::AlternateBase, QColor(49,54,59));
+ darkPalette.setColor(QPalette::ToolTipBase, Qt::white);
+ darkPalette.setColor(QPalette::ToolTipText, Qt::white);
+ darkPalette.setColor(QPalette::Text, Qt::white);
+ darkPalette.setColor(QPalette::Button, QColor(49,54,59));
+ darkPalette.setColor(QPalette::ButtonText, Qt::white);
+ darkPalette.setColor(QPalette::BrightText, Qt::red);
+ darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
+ darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
+ darkPalette.setColor(QPalette::HighlightedText, Qt::black);
+ return fadeInactive(darkPalette, fadeAmount(), fadeColor());
}
double DarkTheme::fadeAmount()
{
- return 0.5;
+ return 0.5;
}
QColor DarkTheme::fadeColor()
{
- return QColor(49,54,59);
+ return QColor(49,54,59);
}
bool DarkTheme::hasStyleSheet()
{
- return true;
+ return true;
}
QString DarkTheme::appStyleSheet()
{
- return "QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }";
+ return "QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }";
}
diff --git a/application/themes/DarkTheme.h b/application/themes/DarkTheme.h
index f3c18e22..9bd2f343 100644
--- a/application/themes/DarkTheme.h
+++ b/application/themes/DarkTheme.h
@@ -5,14 +5,14 @@
class DarkTheme: public FusionTheme
{
public:
- virtual ~DarkTheme() {}
+ virtual ~DarkTheme() {}
- QString id() override;
- QString name() override;
- bool hasStyleSheet() override;
- QString appStyleSheet() override;
- bool hasColorScheme() override;
- QPalette colorScheme() override;
- double fadeAmount() override;
- QColor fadeColor() override;
+ QString id() override;
+ QString name() override;
+ bool hasStyleSheet() override;
+ QString appStyleSheet() override;
+ bool hasColorScheme() override;
+ QPalette colorScheme() override;
+ double fadeAmount() override;
+ QColor fadeColor() override;
};
diff --git a/application/themes/FusionTheme.cpp b/application/themes/FusionTheme.cpp
index aaf7b3d5..cf3286ba 100644
--- a/application/themes/FusionTheme.cpp
+++ b/application/themes/FusionTheme.cpp
@@ -2,5 +2,5 @@
QString FusionTheme::qtTheme()
{
- return "Fusion";
+ return "Fusion";
}
diff --git a/application/themes/FusionTheme.h b/application/themes/FusionTheme.h
index e2d9014c..ee34245a 100644
--- a/application/themes/FusionTheme.h
+++ b/application/themes/FusionTheme.h
@@ -5,7 +5,7 @@
class FusionTheme: public ITheme
{
public:
- virtual ~FusionTheme() {}
+ virtual ~FusionTheme() {}
- QString qtTheme() override;
+ QString qtTheme() override;
};
diff --git a/application/themes/ITheme.cpp b/application/themes/ITheme.cpp
index b1cecf57..bfec87e7 100644
--- a/application/themes/ITheme.cpp
+++ b/application/themes/ITheme.cpp
@@ -6,42 +6,42 @@
void ITheme::apply(bool)
{
- QApplication::setStyle(QStyleFactory::create(qtTheme()));
- if(hasColorScheme())
- {
- QApplication::setPalette(colorScheme());
- }
- if(hasStyleSheet())
- {
- MMC->setStyleSheet(appStyleSheet());
- }
- else
- {
- MMC->setStyleSheet(QString());
- }
- QDir::setSearchPaths("theme", searchPaths());
+ QApplication::setStyle(QStyleFactory::create(qtTheme()));
+ if(hasColorScheme())
+ {
+ QApplication::setPalette(colorScheme());
+ }
+ if(hasStyleSheet())
+ {
+ MMC->setStyleSheet(appStyleSheet());
+ }
+ else
+ {
+ MMC->setStyleSheet(QString());
+ }
+ QDir::setSearchPaths("theme", searchPaths());
}
QPalette ITheme::fadeInactive(QPalette in, qreal bias, QColor color)
{
- auto blend = [&in, bias, color](QPalette::ColorRole role)
- {
- QColor from = in.color(QPalette::Active, role);
- QColor blended = Rainbow::mix(from, color, bias);
- in.setColor(QPalette::Disabled, role, blended);
- };
- blend(QPalette::Window);
- blend(QPalette::WindowText);
- blend(QPalette::Base);
- blend(QPalette::AlternateBase);
- blend(QPalette::ToolTipBase);
- blend(QPalette::ToolTipText);
- blend(QPalette::Text);
- blend(QPalette::Button);
- blend(QPalette::ButtonText);
- blend(QPalette::BrightText);
- blend(QPalette::Link);
- blend(QPalette::Highlight);
- blend(QPalette::HighlightedText);
- return in;
+ auto blend = [&in, bias, color](QPalette::ColorRole role)
+ {
+ QColor from = in.color(QPalette::Active, role);
+ QColor blended = Rainbow::mix(from, color, bias);
+ in.setColor(QPalette::Disabled, role, blended);
+ };
+ blend(QPalette::Window);
+ blend(QPalette::WindowText);
+ blend(QPalette::Base);
+ blend(QPalette::AlternateBase);
+ blend(QPalette::ToolTipBase);
+ blend(QPalette::ToolTipText);
+ blend(QPalette::Text);
+ blend(QPalette::Button);
+ blend(QPalette::ButtonText);
+ blend(QPalette::BrightText);
+ blend(QPalette::Link);
+ blend(QPalette::Highlight);
+ blend(QPalette::HighlightedText);
+ return in;
}
diff --git a/application/themes/ITheme.h b/application/themes/ITheme.h
index b75001c2..c2347cf6 100644
--- a/application/themes/ITheme.h
+++ b/application/themes/ITheme.h
@@ -7,21 +7,21 @@ class QStyle;
class ITheme
{
public:
- virtual ~ITheme() {}
- virtual void apply(bool initial);
- virtual QString id() = 0;
- virtual QString name() = 0;
- virtual bool hasStyleSheet() = 0;
- virtual QString appStyleSheet() = 0;
- virtual QString qtTheme() = 0;
- virtual bool hasColorScheme() = 0;
- virtual QPalette colorScheme() = 0;
- virtual QColor fadeColor() = 0;
- virtual double fadeAmount() = 0;
- virtual QStringList searchPaths()
- {
- return {};
- }
+ virtual ~ITheme() {}
+ virtual void apply(bool initial);
+ virtual QString id() = 0;
+ virtual QString name() = 0;
+ virtual bool hasStyleSheet() = 0;
+ virtual QString appStyleSheet() = 0;
+ virtual QString qtTheme() = 0;
+ virtual bool hasColorScheme() = 0;
+ virtual QPalette colorScheme() = 0;
+ virtual QColor fadeColor() = 0;
+ virtual double fadeAmount() = 0;
+ virtual QStringList searchPaths()
+ {
+ return {};
+ }
- static QPalette fadeInactive(QPalette in, qreal bias, QColor color);
+ static QPalette fadeInactive(QPalette in, qreal bias, QColor color);
};
diff --git a/application/themes/SystemTheme.cpp b/application/themes/SystemTheme.cpp
index a9ee853a..00b2300d 100644
--- a/application/themes/SystemTheme.cpp
+++ b/application/themes/SystemTheme.cpp
@@ -6,75 +6,75 @@
SystemTheme::SystemTheme()
{
- const auto & style = QApplication::style();
- systemPalette = style->standardPalette();
- QString lowerThemeName = style->objectName();
- qDebug() << systemTheme;
- QStringList styles = QStyleFactory::keys();
- for(auto &st: styles)
- {
- if(st.toLower() == lowerThemeName)
- {
- systemTheme = st;
- return;
- }
- }
- // fall back to fusion if we can't find the current theme.
- systemTheme = "Fusion";
- qDebug() << "System theme not found, defaulted to Fusion";
+ const auto & style = QApplication::style();
+ systemPalette = style->standardPalette();
+ QString lowerThemeName = style->objectName();
+ qDebug() << systemTheme;
+ QStringList styles = QStyleFactory::keys();
+ for(auto &st: styles)
+ {
+ if(st.toLower() == lowerThemeName)
+ {
+ systemTheme = st;
+ return;
+ }
+ }
+ // fall back to fusion if we can't find the current theme.
+ systemTheme = "Fusion";
+ qDebug() << "System theme not found, defaulted to Fusion";
}
void SystemTheme::apply(bool initial)
{
- // if we are applying the system theme as the first theme, just don't touch anything. it's for the better...
- if(initial)
- {
- return;
- }
- ITheme::apply(initial);
+ // if we are applying the system theme as the first theme, just don't touch anything. it's for the better...
+ if(initial)
+ {
+ return;
+ }
+ ITheme::apply(initial);
}
QString SystemTheme::id()
{
- return "system";
+ return "system";
}
QString SystemTheme::name()
{
- return QObject::tr("System");
+ return QObject::tr("System");
}
QString SystemTheme::qtTheme()
{
- return systemTheme;
+ return systemTheme;
}
QPalette SystemTheme::colorScheme()
{
- return systemPalette;
+ return systemPalette;
}
QString SystemTheme::appStyleSheet()
{
- return QString();
+ return QString();
}
double SystemTheme::fadeAmount()
{
- return 0.5;
+ return 0.5;
}
QColor SystemTheme::fadeColor()
{
- return QColor(128,128,128);
+ return QColor(128,128,128);
}
bool SystemTheme::hasStyleSheet()
{
- return false;
+ return false;
}
bool SystemTheme::hasColorScheme()
{
- return true;
+ return true;
}
diff --git a/application/themes/SystemTheme.h b/application/themes/SystemTheme.h
index 18291b68..fe450600 100644
--- a/application/themes/SystemTheme.h
+++ b/application/themes/SystemTheme.h
@@ -5,20 +5,20 @@
class SystemTheme: public ITheme
{
public:
- SystemTheme();
- virtual ~SystemTheme() {}
- void apply(bool initial) override;
+ SystemTheme();
+ virtual ~SystemTheme() {}
+ void apply(bool initial) override;
- QString id() override;
- QString name() override;
- QString qtTheme() override;
- bool hasStyleSheet() override;
- QString appStyleSheet() override;
- bool hasColorScheme() override;
- QPalette colorScheme() override;
- double fadeAmount() override;
- QColor fadeColor() override;
+ QString id() override;
+ QString name() override;
+ QString qtTheme() override;
+ bool hasStyleSheet() override;
+ QString appStyleSheet() override;
+ bool hasColorScheme() override;
+ QPalette colorScheme() override;
+ double fadeAmount() override;
+ QColor fadeColor() override;
private:
- QPalette systemPalette;
- QString systemTheme;
+ QPalette systemPalette;
+ QString systemTheme;
};
diff --git a/application/widgets/Common.cpp b/application/widgets/Common.cpp
index 9b730d6c..f72f3596 100644
--- a/application/widgets/Common.cpp
+++ b/application/widgets/Common.cpp
@@ -2,26 +2,26 @@
// Origin: Qt
QStringList viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height,
- qreal &widthUsed)
+ qreal &widthUsed)
{
- QStringList lines;
- height = 0;
- widthUsed = 0;
- textLayout.beginLayout();
- QString str = textLayout.text();
- while (true)
- {
- QTextLine line = textLayout.createLine();
- if (!line.isValid())
- break;
- if (line.textLength() == 0)
- break;
- line.setLineWidth(lineWidth);
- line.setPosition(QPointF(0, height));
- height += line.height();
- lines.append(str.mid(line.textStart(), line.textLength()));
- widthUsed = qMax(widthUsed, line.naturalTextWidth());
- }
- textLayout.endLayout();
- return lines;
+ QStringList lines;
+ height = 0;
+ widthUsed = 0;
+ textLayout.beginLayout();
+ QString str = textLayout.text();
+ while (true)
+ {
+ QTextLine line = textLayout.createLine();
+ if (!line.isValid())
+ break;
+ if (line.textLength() == 0)
+ break;
+ line.setLineWidth(lineWidth);
+ line.setPosition(QPointF(0, height));
+ height += line.height();
+ lines.append(str.mid(line.textStart(), line.textLength()));
+ widthUsed = qMax(widthUsed, line.naturalTextWidth());
+ }
+ textLayout.endLayout();
+ return lines;
}
diff --git a/application/widgets/Common.h b/application/widgets/Common.h
index fc46e08f..b3fbe1a0 100644
--- a/application/widgets/Common.h
+++ b/application/widgets/Common.h
@@ -3,4 +3,4 @@
#include <QTextLayout>
QStringList viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height,
- qreal &widthUsed); \ No newline at end of file
+ qreal &widthUsed); \ No newline at end of file
diff --git a/application/widgets/CustomCommands.cpp b/application/widgets/CustomCommands.cpp
index 9f11e344..9e7673fd 100644
--- a/application/widgets/CustomCommands.cpp
+++ b/application/widgets/CustomCommands.cpp
@@ -6,43 +6,43 @@ CustomCommands::~CustomCommands()
}
CustomCommands::CustomCommands(QWidget* parent):
- QWidget(parent),
- ui(new Ui::CustomCommands)
+ QWidget(parent),
+ ui(new Ui::CustomCommands)
{
- ui->setupUi(this);
+ ui->setupUi(this);
}
void CustomCommands::initialize(bool checkable, bool checked, const QString& prelaunch, const QString& wrapper, const QString& postexit)
{
- ui->customCommandsGroupBox->setCheckable(checkable);
- if(checkable)
- {
- ui->customCommandsGroupBox->setChecked(checked);
- }
- ui->preLaunchCmdTextBox->setText(prelaunch);
- ui->wrapperCmdTextBox->setText(wrapper);
- ui->postExitCmdTextBox->setText(postexit);
+ ui->customCommandsGroupBox->setCheckable(checkable);
+ if(checkable)
+ {
+ ui->customCommandsGroupBox->setChecked(checked);
+ }
+ ui->preLaunchCmdTextBox->setText(prelaunch);
+ ui->wrapperCmdTextBox->setText(wrapper);
+ ui->postExitCmdTextBox->setText(postexit);
}
bool CustomCommands::checked() const
{
- if(!ui->customCommandsGroupBox->isCheckable())
- return true;
- return ui->customCommandsGroupBox->isChecked();
+ if(!ui->customCommandsGroupBox->isCheckable())
+ return true;
+ return ui->customCommandsGroupBox->isChecked();
}
QString CustomCommands::prelaunchCommand() const
{
- return ui->preLaunchCmdTextBox->text();
+ return ui->preLaunchCmdTextBox->text();
}
QString CustomCommands::wrapperCommand() const
{
- return ui->wrapperCmdTextBox->text();
+ return ui->wrapperCmdTextBox->text();
}
QString CustomCommands::postexitCommand() const
{
- return ui->postExitCmdTextBox->text();
+ return ui->postExitCmdTextBox->text();
}
diff --git a/application/widgets/CustomCommands.h b/application/widgets/CustomCommands.h
index 2bc7cb1a..07041479 100644
--- a/application/widgets/CustomCommands.h
+++ b/application/widgets/CustomCommands.h
@@ -24,20 +24,20 @@ class CustomCommands;
class CustomCommands : public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit CustomCommands(QWidget *parent = 0);
- ~CustomCommands();
- void initialize(bool checkable, bool checked, const QString & prelaunch, const QString & wrapper, const QString & postexit);
+ explicit CustomCommands(QWidget *parent = 0);
+ ~CustomCommands();
+ void initialize(bool checkable, bool checked, const QString & prelaunch, const QString & wrapper, const QString & postexit);
- bool checked() const;
- QString prelaunchCommand() const;
- QString wrapperCommand() const;
- QString postexitCommand() const;
+ bool checked() const;
+ QString prelaunchCommand() const;
+ QString wrapperCommand() const;
+ QString postexitCommand() const;
private:
- Ui::CustomCommands *ui;
+ Ui::CustomCommands *ui;
};
diff --git a/application/widgets/FocusLineEdit.cpp b/application/widgets/FocusLineEdit.cpp
index 139126c8..b272100c 100644
--- a/application/widgets/FocusLineEdit.cpp
+++ b/application/widgets/FocusLineEdit.cpp
@@ -3,23 +3,23 @@
FocusLineEdit::FocusLineEdit(QWidget *parent) : QLineEdit(parent)
{
- _selectOnMousePress = false;
+ _selectOnMousePress = false;
}
void FocusLineEdit::focusInEvent(QFocusEvent *e)
{
- QLineEdit::focusInEvent(e);
- selectAll();
- _selectOnMousePress = true;
+ QLineEdit::focusInEvent(e);
+ selectAll();
+ _selectOnMousePress = true;
}
void FocusLineEdit::mousePressEvent(QMouseEvent *me)
{
- QLineEdit::mousePressEvent(me);
- if (_selectOnMousePress)
- {
- selectAll();
- _selectOnMousePress = false;
- }
- qDebug() << selectedText();
+ QLineEdit::mousePressEvent(me);
+ if (_selectOnMousePress)
+ {
+ selectAll();
+ _selectOnMousePress = false;
+ }
+ qDebug() << selectedText();
}
diff --git a/application/widgets/FocusLineEdit.h b/application/widgets/FocusLineEdit.h
index 6d1c78a8..71b4f140 100644
--- a/application/widgets/FocusLineEdit.h
+++ b/application/widgets/FocusLineEdit.h
@@ -2,16 +2,16 @@
class FocusLineEdit : public QLineEdit
{
- Q_OBJECT
+ Q_OBJECT
public:
- FocusLineEdit(QWidget *parent);
- virtual ~FocusLineEdit()
- {
- }
+ FocusLineEdit(QWidget *parent);
+ virtual ~FocusLineEdit()
+ {
+ }
protected:
- void focusInEvent(QFocusEvent *e);
- void mousePressEvent(QMouseEvent *me);
+ void focusInEvent(QFocusEvent *e);
+ void mousePressEvent(QMouseEvent *me);
- bool _selectOnMousePress;
+ bool _selectOnMousePress;
};
diff --git a/application/widgets/IconLabel.cpp b/application/widgets/IconLabel.cpp
index 86c8a431..bf1c2358 100644
--- a/application/widgets/IconLabel.cpp
+++ b/application/widgets/IconLabel.cpp
@@ -7,37 +7,37 @@
#include <QRect>
IconLabel::IconLabel(QWidget *parent, QIcon icon, QSize size)
- : QWidget(parent), m_size(size), m_icon(icon)
+ : QWidget(parent), m_size(size), m_icon(icon)
{
- setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
}
QSize IconLabel::sizeHint() const
{
- return m_size;
+ return m_size;
}
void IconLabel::setIcon(QIcon icon)
{
- m_icon = icon;
- update();
+ m_icon = icon;
+ update();
}
void IconLabel::paintEvent(QPaintEvent *)
{
- QPainter p(this);
- QRect rect = contentsRect();
- int width = rect.width();
- int height = rect.height();
- if(width < height)
- {
- rect.setHeight(width);
- rect.translate(0, (height - width) / 2);
- }
- else if (width > height)
- {
- rect.setWidth(height);
- rect.translate((width - height) / 2, 0);
- }
- m_icon.paint(&p, rect);
+ QPainter p(this);
+ QRect rect = contentsRect();
+ int width = rect.width();
+ int height = rect.height();
+ if(width < height)
+ {
+ rect.setHeight(width);
+ rect.translate(0, (height - width) / 2);
+ }
+ else if (width > height)
+ {
+ rect.setWidth(height);
+ rect.translate((width - height) / 2, 0);
+ }
+ m_icon.paint(&p, rect);
}
diff --git a/application/widgets/IconLabel.h b/application/widgets/IconLabel.h
index a2f1eef3..6d212c4c 100644
--- a/application/widgets/IconLabel.h
+++ b/application/widgets/IconLabel.h
@@ -9,18 +9,18 @@ class QStyleOption;
*/
class IconLabel : public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
- /// Create a line separator. orientation is the orientation of the line.
- explicit IconLabel(QWidget *parent, QIcon icon, QSize size);
+ /// Create a line separator. orientation is the orientation of the line.
+ explicit IconLabel(QWidget *parent, QIcon icon, QSize size);
- virtual QSize sizeHint() const;
- virtual void paintEvent(QPaintEvent *);
+ virtual QSize sizeHint() const;
+ virtual void paintEvent(QPaintEvent *);
- void setIcon(QIcon icon);
+ void setIcon(QIcon icon);
private:
- QSize m_size;
- QIcon m_icon;
+ QSize m_size;
+ QIcon m_icon;
};
diff --git a/application/widgets/JavaSettingsWidget.cpp b/application/widgets/JavaSettingsWidget.cpp
index 1e9d5546..a11dd1aa 100644
--- a/application/widgets/JavaSettingsWidget.cpp
+++ b/application/widgets/JavaSettingsWidget.cpp
@@ -19,410 +19,410 @@
JavaSettingsWidget::JavaSettingsWidget(QWidget* parent) : QWidget(parent)
{
- m_availableMemory = Sys::getSystemRam() / Sys::megabyte;
-
- goodIcon = MMC->getThemedIcon("status-good");
- yellowIcon = MMC->getThemedIcon("status-yellow");
- badIcon = MMC->getThemedIcon("status-bad");
- setupUi();
-
- connect(m_minMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int)));
- connect(m_maxMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int)));
- connect(m_permGenSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int)));
- connect(m_versionWidget, &VersionSelectWidget::selectedVersionChanged, this, &JavaSettingsWidget::javaVersionSelected);
- connect(m_javaBrowseBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaBrowseBtn_clicked);
- connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited);
- connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked);
+ m_availableMemory = Sys::getSystemRam() / Sys::megabyte;
+
+ goodIcon = MMC->getThemedIcon("status-good");
+ yellowIcon = MMC->getThemedIcon("status-yellow");
+ badIcon = MMC->getThemedIcon("status-bad");
+ setupUi();
+
+ connect(m_minMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int)));
+ connect(m_maxMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int)));
+ connect(m_permGenSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int)));
+ connect(m_versionWidget, &VersionSelectWidget::selectedVersionChanged, this, &JavaSettingsWidget::javaVersionSelected);
+ connect(m_javaBrowseBtn, &QPushButton::clicked, this, &JavaSettingsWidget::on_javaBrowseBtn_clicked);
+ connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaSettingsWidget::javaPathEdited);
+ connect(m_javaStatusBtn, &QToolButton::clicked, this, &JavaSettingsWidget::on_javaStatusBtn_clicked);
}
void JavaSettingsWidget::setupUi()
{
- setObjectName(QStringLiteral("javaSettingsWidget"));
- m_verticalLayout = new QVBoxLayout(this);
- m_verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
-
- m_versionWidget = new VersionSelectWidget(this);
- m_verticalLayout->addWidget(m_versionWidget);
-
- m_horizontalLayout = new QHBoxLayout();
- m_horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
- m_javaPathTextBox = new QLineEdit(this);
- m_javaPathTextBox->setObjectName(QStringLiteral("javaPathTextBox"));
-
- m_horizontalLayout->addWidget(m_javaPathTextBox);
-
- m_javaBrowseBtn = new QPushButton(this);
- m_javaBrowseBtn->setObjectName(QStringLiteral("javaBrowseBtn"));
-
- m_horizontalLayout->addWidget(m_javaBrowseBtn);
-
- m_javaStatusBtn = new QToolButton(this);
- m_javaStatusBtn->setIcon(yellowIcon);
- m_horizontalLayout->addWidget(m_javaStatusBtn);
-
- m_verticalLayout->addLayout(m_horizontalLayout);
-
- m_memoryGroupBox = new QGroupBox(this);
- m_memoryGroupBox->setObjectName(QStringLiteral("memoryGroupBox"));
- m_gridLayout_2 = new QGridLayout(m_memoryGroupBox);
- m_gridLayout_2->setObjectName(QStringLiteral("gridLayout_2"));
-
- m_labelMinMem = new QLabel(m_memoryGroupBox);
- m_labelMinMem->setObjectName(QStringLiteral("labelMinMem"));
- m_gridLayout_2->addWidget(m_labelMinMem, 0, 0, 1, 1);
-
- m_minMemSpinBox = new QSpinBox(m_memoryGroupBox);
- m_minMemSpinBox->setObjectName(QStringLiteral("minMemSpinBox"));
- m_minMemSpinBox->setSuffix(QStringLiteral(" MB"));
- m_minMemSpinBox->setMinimum(128);
- m_minMemSpinBox->setMaximum(m_availableMemory);
- m_minMemSpinBox->setSingleStep(128);
- m_labelMinMem->setBuddy(m_minMemSpinBox);
- m_gridLayout_2->addWidget(m_minMemSpinBox, 0, 1, 1, 1);
-
- m_labelMaxMem = new QLabel(m_memoryGroupBox);
- m_labelMaxMem->setObjectName(QStringLiteral("labelMaxMem"));
- m_gridLayout_2->addWidget(m_labelMaxMem, 1, 0, 1, 1);
-
- m_maxMemSpinBox = new QSpinBox(m_memoryGroupBox);
- m_maxMemSpinBox->setObjectName(QStringLiteral("maxMemSpinBox"));
- m_maxMemSpinBox->setSuffix(QStringLiteral(" MB"));
- m_maxMemSpinBox->setMinimum(128);
- m_maxMemSpinBox->setMaximum(m_availableMemory);
- m_maxMemSpinBox->setSingleStep(128);
- m_labelMaxMem->setBuddy(m_maxMemSpinBox);
- m_gridLayout_2->addWidget(m_maxMemSpinBox, 1, 1, 1, 1);
-
- m_labelPermGen = new QLabel(m_memoryGroupBox);
- m_labelPermGen->setObjectName(QStringLiteral("labelPermGen"));
- m_labelPermGen->setText(QStringLiteral("PermGen:"));
- m_gridLayout_2->addWidget(m_labelPermGen, 2, 0, 1, 1);
- m_labelPermGen->setVisible(false);
-
- m_permGenSpinBox = new QSpinBox(m_memoryGroupBox);
- m_permGenSpinBox->setObjectName(QStringLiteral("permGenSpinBox"));
- m_permGenSpinBox->setSuffix(QStringLiteral(" MB"));
- m_permGenSpinBox->setMinimum(64);
- m_permGenSpinBox->setMaximum(m_availableMemory);
- m_permGenSpinBox->setSingleStep(8);
- m_gridLayout_2->addWidget(m_permGenSpinBox, 2, 1, 1, 1);
- m_permGenSpinBox->setVisible(false);
-
- m_verticalLayout->addWidget(m_memoryGroupBox);
-
- retranslate();
+ setObjectName(QStringLiteral("javaSettingsWidget"));
+ m_verticalLayout = new QVBoxLayout(this);
+ m_verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+
+ m_versionWidget = new VersionSelectWidget(this);
+ m_verticalLayout->addWidget(m_versionWidget);
+
+ m_horizontalLayout = new QHBoxLayout();
+ m_horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ m_javaPathTextBox = new QLineEdit(this);
+ m_javaPathTextBox->setObjectName(QStringLiteral("javaPathTextBox"));
+
+ m_horizontalLayout->addWidget(m_javaPathTextBox);
+
+ m_javaBrowseBtn = new QPushButton(this);
+ m_javaBrowseBtn->setObjectName(QStringLiteral("javaBrowseBtn"));
+
+ m_horizontalLayout->addWidget(m_javaBrowseBtn);
+
+ m_javaStatusBtn = new QToolButton(this);
+ m_javaStatusBtn->setIcon(yellowIcon);
+ m_horizontalLayout->addWidget(m_javaStatusBtn);
+
+ m_verticalLayout->addLayout(m_horizontalLayout);
+
+ m_memoryGroupBox = new QGroupBox(this);
+ m_memoryGroupBox->setObjectName(QStringLiteral("memoryGroupBox"));
+ m_gridLayout_2 = new QGridLayout(m_memoryGroupBox);
+ m_gridLayout_2->setObjectName(QStringLiteral("gridLayout_2"));
+
+ m_labelMinMem = new QLabel(m_memoryGroupBox);
+ m_labelMinMem->setObjectName(QStringLiteral("labelMinMem"));
+ m_gridLayout_2->addWidget(m_labelMinMem, 0, 0, 1, 1);
+
+ m_minMemSpinBox = new QSpinBox(m_memoryGroupBox);
+ m_minMemSpinBox->setObjectName(QStringLiteral("minMemSpinBox"));
+ m_minMemSpinBox->setSuffix(QStringLiteral(" MB"));
+ m_minMemSpinBox->setMinimum(128);
+ m_minMemSpinBox->setMaximum(m_availableMemory);
+ m_minMemSpinBox->setSingleStep(128);
+ m_labelMinMem->setBuddy(m_minMemSpinBox);
+ m_gridLayout_2->addWidget(m_minMemSpinBox, 0, 1, 1, 1);
+
+ m_labelMaxMem = new QLabel(m_memoryGroupBox);
+ m_labelMaxMem->setObjectName(QStringLiteral("labelMaxMem"));
+ m_gridLayout_2->addWidget(m_labelMaxMem, 1, 0, 1, 1);
+
+ m_maxMemSpinBox = new QSpinBox(m_memoryGroupBox);
+ m_maxMemSpinBox->setObjectName(QStringLiteral("maxMemSpinBox"));
+ m_maxMemSpinBox->setSuffix(QStringLiteral(" MB"));
+ m_maxMemSpinBox->setMinimum(128);
+ m_maxMemSpinBox->setMaximum(m_availableMemory);
+ m_maxMemSpinBox->setSingleStep(128);
+ m_labelMaxMem->setBuddy(m_maxMemSpinBox);
+ m_gridLayout_2->addWidget(m_maxMemSpinBox, 1, 1, 1, 1);
+
+ m_labelPermGen = new QLabel(m_memoryGroupBox);
+ m_labelPermGen->setObjectName(QStringLiteral("labelPermGen"));
+ m_labelPermGen->setText(QStringLiteral("PermGen:"));
+ m_gridLayout_2->addWidget(m_labelPermGen, 2, 0, 1, 1);
+ m_labelPermGen->setVisible(false);
+
+ m_permGenSpinBox = new QSpinBox(m_memoryGroupBox);
+ m_permGenSpinBox->setObjectName(QStringLiteral("permGenSpinBox"));
+ m_permGenSpinBox->setSuffix(QStringLiteral(" MB"));
+ m_permGenSpinBox->setMinimum(64);
+ m_permGenSpinBox->setMaximum(m_availableMemory);
+ m_permGenSpinBox->setSingleStep(8);
+ m_gridLayout_2->addWidget(m_permGenSpinBox, 2, 1, 1, 1);
+ m_permGenSpinBox->setVisible(false);
+
+ m_verticalLayout->addWidget(m_memoryGroupBox);
+
+ retranslate();
}
void JavaSettingsWidget::initialize()
{
- m_versionWidget->initialize(MMC->javalist().get());
- m_versionWidget->setResizeOn(2);
- auto s = MMC->settings();
- // Memory
- observedMinMemory = s->get("MinMemAlloc").toInt();
- observedMaxMemory = s->get("MaxMemAlloc").toInt();
- observedPermGenMemory = s->get("PermGen").toInt();
- m_minMemSpinBox->setValue(observedMinMemory);
- m_maxMemSpinBox->setValue(observedMaxMemory);
- m_permGenSpinBox->setValue(observedPermGenMemory);
+ m_versionWidget->initialize(MMC->javalist().get());
+ m_versionWidget->setResizeOn(2);
+ auto s = MMC->settings();
+ // Memory
+ observedMinMemory = s->get("MinMemAlloc").toInt();
+ observedMaxMemory = s->get("MaxMemAlloc").toInt();
+ observedPermGenMemory = s->get("PermGen").toInt();
+ m_minMemSpinBox->setValue(observedMinMemory);
+ m_maxMemSpinBox->setValue(observedMaxMemory);
+ m_permGenSpinBox->setValue(observedPermGenMemory);
}
void JavaSettingsWidget::refresh()
{
- m_versionWidget->loadList();
+ m_versionWidget->loadList();
}
JavaSettingsWidget::ValidationStatus JavaSettingsWidget::validate()
{
- switch(javaStatus)
- {
- default:
- case JavaStatus::NotSet:
- case JavaStatus::DoesNotExist:
- case JavaStatus::DoesNotStart:
- case JavaStatus::ReturnedInvalidData:
- {
- int button = CustomMessageBox::selectable(
- this,
- tr("No Java version selected"),
- tr("You didn't select a Java version or selected something that doesn't work.\n"
- "MultiMC will not be able to start Minecraft.\n"
- "Do you wish to proceed without any Java?"
- "\n\n"
- "You can change the Java version in the settings later.\n"
- ),
- QMessageBox::Warning,
- QMessageBox::Yes | QMessageBox::No,
- QMessageBox::NoButton
- )->exec();
- if(button == QMessageBox::No)
- {
- return ValidationStatus::Bad;
- }
- return ValidationStatus::JavaBad;
- }
- break;
- case JavaStatus::Pending:
- {
- return ValidationStatus::Bad;
- }
- case JavaStatus::Good:
- {
- return ValidationStatus::AllOK;
- }
- }
+ switch(javaStatus)
+ {
+ default:
+ case JavaStatus::NotSet:
+ case JavaStatus::DoesNotExist:
+ case JavaStatus::DoesNotStart:
+ case JavaStatus::ReturnedInvalidData:
+ {
+ int button = CustomMessageBox::selectable(
+ this,
+ tr("No Java version selected"),
+ tr("You didn't select a Java version or selected something that doesn't work.\n"
+ "MultiMC will not be able to start Minecraft.\n"
+ "Do you wish to proceed without any Java?"
+ "\n\n"
+ "You can change the Java version in the settings later.\n"
+ ),
+ QMessageBox::Warning,
+ QMessageBox::Yes | QMessageBox::No,
+ QMessageBox::NoButton
+ )->exec();
+ if(button == QMessageBox::No)
+ {
+ return ValidationStatus::Bad;
+ }
+ return ValidationStatus::JavaBad;
+ }
+ break;
+ case JavaStatus::Pending:
+ {
+ return ValidationStatus::Bad;
+ }
+ case JavaStatus::Good:
+ {
+ return ValidationStatus::AllOK;
+ }
+ }
}
QString JavaSettingsWidget::javaPath() const
{
- return m_javaPathTextBox->text();
+ return m_javaPathTextBox->text();
}
int JavaSettingsWidget::maxHeapSize() const
{
- return m_maxMemSpinBox->value();
+ return m_maxMemSpinBox->value();
}
int JavaSettingsWidget::minHeapSize() const
{
- return m_minMemSpinBox->value();
+ return m_minMemSpinBox->value();
}
bool JavaSettingsWidget::permGenEnabled() const
{
- return m_permGenSpinBox->isVisible();
+ return m_permGenSpinBox->isVisible();
}
int JavaSettingsWidget::permGenSize() const
{
- return m_permGenSpinBox->value();
+ return m_permGenSpinBox->value();
}
void JavaSettingsWidget::memoryValueChanged(int)
{
- bool actuallyChanged = false;
- int min = m_minMemSpinBox->value();
- int max = m_maxMemSpinBox->value();
- int permgen = m_permGenSpinBox->value();
- QObject *obj = sender();
- if (obj == m_minMemSpinBox && min != observedMinMemory)
- {
- observedMinMemory = min;
- actuallyChanged = true;
- if (min > max)
- {
- observedMaxMemory = min;
- m_maxMemSpinBox->setValue(min);
- }
- }
- else if (obj == m_maxMemSpinBox && max != observedMaxMemory)
- {
- observedMaxMemory = max;
- actuallyChanged = true;
- if (min > max)
- {
- observedMinMemory = max;
- m_minMemSpinBox->setValue(max);
- }
- }
- else if (obj == m_permGenSpinBox && permgen != observedPermGenMemory)
- {
- observedPermGenMemory = permgen;
- actuallyChanged = true;
- }
- if(actuallyChanged)
- {
- checkJavaPathOnEdit(m_javaPathTextBox->text());
- }
+ bool actuallyChanged = false;
+ int min = m_minMemSpinBox->value();
+ int max = m_maxMemSpinBox->value();
+ int permgen = m_permGenSpinBox->value();
+ QObject *obj = sender();
+ if (obj == m_minMemSpinBox && min != observedMinMemory)
+ {
+ observedMinMemory = min;
+ actuallyChanged = true;
+ if (min > max)
+ {
+ observedMaxMemory = min;
+ m_maxMemSpinBox->setValue(min);
+ }
+ }
+ else if (obj == m_maxMemSpinBox && max != observedMaxMemory)
+ {
+ observedMaxMemory = max;
+ actuallyChanged = true;
+ if (min > max)
+ {
+ observedMinMemory = max;
+ m_minMemSpinBox->setValue(max);
+ }
+ }
+ else if (obj == m_permGenSpinBox && permgen != observedPermGenMemory)
+ {
+ observedPermGenMemory = permgen;
+ actuallyChanged = true;
+ }
+ if(actuallyChanged)
+ {
+ checkJavaPathOnEdit(m_javaPathTextBox->text());
+ }
}
void JavaSettingsWidget::javaVersionSelected(BaseVersionPtr version)
{
- auto java = std::dynamic_pointer_cast<JavaInstall>(version);
- if(!java)
- {
- return;
- }
- auto visible = java->id.requiresPermGen();
- m_labelPermGen->setVisible(visible);
- m_permGenSpinBox->setVisible(visible);
- m_javaPathTextBox->setText(java->path);
- checkJavaPath(java->path);
+ auto java = std::dynamic_pointer_cast<JavaInstall>(version);
+ if(!java)
+ {
+ return;
+ }
+ auto visible = java->id.requiresPermGen();
+ m_labelPermGen->setVisible(visible);
+ m_permGenSpinBox->setVisible(visible);
+ m_javaPathTextBox->setText(java->path);
+ checkJavaPath(java->path);
}
void JavaSettingsWidget::on_javaBrowseBtn_clicked()
{
- QString filter;
+ QString filter;
#if defined Q_OS_WIN32
- filter = "Java (javaw.exe)";
+ filter = "Java (javaw.exe)";
#else
- filter = "Java (java)";
+ filter = "Java (java)";
#endif
- QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"), QString(), filter);
- if(raw_path.isEmpty())
- {
- return;
- }
- QString cooked_path = FS::NormalizePath(raw_path);
- m_javaPathTextBox->setText(cooked_path);
- checkJavaPath(cooked_path);
+ QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"), QString(), filter);
+ if(raw_path.isEmpty())
+ {
+ return;
+ }
+ QString cooked_path = FS::NormalizePath(raw_path);
+ m_javaPathTextBox->setText(cooked_path);
+ checkJavaPath(cooked_path);
}
void JavaSettingsWidget::on_javaStatusBtn_clicked()
{
- QString text;
- bool failed = false;
- switch(javaStatus)
- {
- case JavaStatus::NotSet:
- checkJavaPath(m_javaPathTextBox->text());
- return;
- case JavaStatus::DoesNotExist:
- text += QObject::tr("The specified file either doesn't exist or is not a proper executable.");
- failed = true;
- break;
- case JavaStatus::DoesNotStart:
- {
- text += QObject::tr("The specified java binary didn't start properly.<br />");
- auto htmlError = m_result.errorLog;
- if(!htmlError.isEmpty())
- {
- htmlError.replace('\n', "<br />");
- text += QString("<font color=\"red\">%1</font>").arg(htmlError);
- }
- failed = true;
- break;
- }
- case JavaStatus::ReturnedInvalidData:
- {
- text += QObject::tr("The specified java binary returned unexpected results:<br />");
- auto htmlOut = m_result.outLog;
- if(!htmlOut.isEmpty())
- {
- htmlOut.replace('\n', "<br />");
- text += QString("<font color=\"red\">%1</font>").arg(htmlOut);
- }
- failed = true;
- break;
- }
- case JavaStatus::Good:
- text += QObject::tr("Java test succeeded!<br />Platform reported: %1<br />Java version "
- "reported: %2<br />").arg(m_result.realPlatform, m_result.javaVersion.toString());
- break;
- case JavaStatus::Pending:
- // TODO: abort here?
- return;
- }
- CustomMessageBox::selectable(
- this,
- failed ? QObject::tr("Java test success") : QObject::tr("Java test failure"),
- text,
- failed ? QMessageBox::Critical : QMessageBox::Information
- )->show();
+ QString text;
+ bool failed = false;
+ switch(javaStatus)
+ {
+ case JavaStatus::NotSet:
+ checkJavaPath(m_javaPathTextBox->text());
+ return;
+ case JavaStatus::DoesNotExist:
+ text += QObject::tr("The specified file either doesn't exist or is not a proper executable.");
+ failed = true;
+ break;
+ case JavaStatus::DoesNotStart:
+ {
+ text += QObject::tr("The specified java binary didn't start properly.<br />");
+ auto htmlError = m_result.errorLog;
+ if(!htmlError.isEmpty())
+ {
+ htmlError.replace('\n', "<br />");
+ text += QString("<font color=\"red\">%1</font>").arg(htmlError);
+ }
+ failed = true;
+ break;
+ }
+ case JavaStatus::ReturnedInvalidData:
+ {
+ text += QObject::tr("The specified java binary returned unexpected results:<br />");
+ auto htmlOut = m_result.outLog;
+ if(!htmlOut.isEmpty())
+ {
+ htmlOut.replace('\n', "<br />");
+ text += QString("<font color=\"red\">%1</font>").arg(htmlOut);
+ }
+ failed = true;
+ break;
+ }
+ case JavaStatus::Good:
+ text += QObject::tr("Java test succeeded!<br />Platform reported: %1<br />Java version "
+ "reported: %2<br />").arg(m_result.realPlatform, m_result.javaVersion.toString());
+ break;
+ case JavaStatus::Pending:
+ // TODO: abort here?
+ return;
+ }
+ CustomMessageBox::selectable(
+ this,
+ failed ? QObject::tr("Java test success") : QObject::tr("Java test failure"),
+ text,
+ failed ? QMessageBox::Critical : QMessageBox::Information
+ )->show();
}
void JavaSettingsWidget::setJavaStatus(JavaSettingsWidget::JavaStatus status)
{
- javaStatus = status;
- switch(javaStatus)
- {
- case JavaStatus::Good:
- m_javaStatusBtn->setIcon(goodIcon);
- break;
- case JavaStatus::NotSet:
- case JavaStatus::Pending:
- m_javaStatusBtn->setIcon(yellowIcon);
- break;
- default:
- m_javaStatusBtn->setIcon(badIcon);
- break;
- }
+ javaStatus = status;
+ switch(javaStatus)
+ {
+ case JavaStatus::Good:
+ m_javaStatusBtn->setIcon(goodIcon);
+ break;
+ case JavaStatus::NotSet:
+ case JavaStatus::Pending:
+ m_javaStatusBtn->setIcon(yellowIcon);
+ break;
+ default:
+ m_javaStatusBtn->setIcon(badIcon);
+ break;
+ }
}
void JavaSettingsWidget::javaPathEdited(const QString& path)
{
- checkJavaPathOnEdit(path);
+ checkJavaPathOnEdit(path);
}
void JavaSettingsWidget::checkJavaPathOnEdit(const QString& path)
{
- auto realPath = FS::ResolveExecutable(path);
- QFileInfo pathInfo(realPath);
- if (pathInfo.baseName().toLower().contains("java"))
- {
- checkJavaPath(path);
- }
- else
- {
- if(!m_checker)
- {
- setJavaStatus(JavaStatus::NotSet);
- }
- }
+ auto realPath = FS::ResolveExecutable(path);
+ QFileInfo pathInfo(realPath);
+ if (pathInfo.baseName().toLower().contains("java"))
+ {
+ checkJavaPath(path);
+ }
+ else
+ {
+ if(!m_checker)
+ {
+ setJavaStatus(JavaStatus::NotSet);
+ }
+ }
}
void JavaSettingsWidget::checkJavaPath(const QString &path)
{
- if(m_checker)
- {
- queuedCheck = path;
- return;
- }
- auto realPath = FS::ResolveExecutable(path);
- if(realPath.isNull())
- {
- setJavaStatus(JavaStatus::DoesNotExist);
- return;
- }
- setJavaStatus(JavaStatus::Pending);
- m_checker.reset(new JavaChecker());
- m_checker->m_path = path;
- m_checker->m_minMem = m_minMemSpinBox->value();
- m_checker->m_maxMem = m_maxMemSpinBox->value();
- if(m_permGenSpinBox->isVisible())
- {
- m_checker->m_permGen = m_permGenSpinBox->value();
- }
- connect(m_checker.get(), &JavaChecker::checkFinished, this, &JavaSettingsWidget::checkFinished);
- m_checker->performCheck();
+ if(m_checker)
+ {
+ queuedCheck = path;
+ return;
+ }
+ auto realPath = FS::ResolveExecutable(path);
+ if(realPath.isNull())
+ {
+ setJavaStatus(JavaStatus::DoesNotExist);
+ return;
+ }
+ setJavaStatus(JavaStatus::Pending);
+ m_checker.reset(new JavaChecker());
+ m_checker->m_path = path;
+ m_checker->m_minMem = m_minMemSpinBox->value();
+ m_checker->m_maxMem = m_maxMemSpinBox->value();
+ if(m_permGenSpinBox->isVisible())
+ {
+ m_checker->m_permGen = m_permGenSpinBox->value();
+ }
+ connect(m_checker.get(), &JavaChecker::checkFinished, this, &JavaSettingsWidget::checkFinished);
+ m_checker->performCheck();
}
void JavaSettingsWidget::checkFinished(JavaCheckResult result)
{
- m_result = result;
- switch(result.validity)
- {
- case JavaCheckResult::Validity::Valid:
- {
- setJavaStatus(JavaStatus::Good);
- break;
- }
- case JavaCheckResult::Validity::ReturnedInvalidData:
- {
- setJavaStatus(JavaStatus::ReturnedInvalidData);
- break;
- }
- case JavaCheckResult::Validity::Errored:
- {
- setJavaStatus(JavaStatus::DoesNotStart);
- break;
- }
- }
- m_checker.reset();
- if(!queuedCheck.isNull())
- {
- checkJavaPath(queuedCheck);
- queuedCheck.clear();
- }
+ m_result = result;
+ switch(result.validity)
+ {
+ case JavaCheckResult::Validity::Valid:
+ {
+ setJavaStatus(JavaStatus::Good);
+ break;
+ }
+ case JavaCheckResult::Validity::ReturnedInvalidData:
+ {
+ setJavaStatus(JavaStatus::ReturnedInvalidData);
+ break;
+ }
+ case JavaCheckResult::Validity::Errored:
+ {
+ setJavaStatus(JavaStatus::DoesNotStart);
+ break;
+ }
+ }
+ m_checker.reset();
+ if(!queuedCheck.isNull())
+ {
+ checkJavaPath(queuedCheck);
+ queuedCheck.clear();
+ }
}
void JavaSettingsWidget::retranslate()
{
- m_memoryGroupBox->setTitle(tr("Memory"));
- m_maxMemSpinBox->setToolTip(tr("The maximum amount of memory Minecraft is allowed to use."));
- m_labelMinMem->setText(tr("Minimum memory allocation:"));
- m_labelMaxMem->setText(tr("Maximum memory allocation:"));
- m_minMemSpinBox->setToolTip(tr("The amount of memory Minecraft is started with."));
- m_permGenSpinBox->setToolTip(tr("The amount of memory available to store loaded Java classes."));
- m_javaBrowseBtn->setText(tr("Browse"));
+ m_memoryGroupBox->setTitle(tr("Memory"));
+ m_maxMemSpinBox->setToolTip(tr("The maximum amount of memory Minecraft is allowed to use."));
+ m_labelMinMem->setText(tr("Minimum memory allocation:"));
+ m_labelMaxMem->setText(tr("Maximum memory allocation:"));
+ m_minMemSpinBox->setToolTip(tr("The amount of memory Minecraft is started with."));
+ m_permGenSpinBox->setToolTip(tr("The amount of memory available to store loaded Java classes."));
+ m_javaBrowseBtn->setText(tr("Browse"));
}
diff --git a/application/widgets/JavaSettingsWidget.h b/application/widgets/JavaSettingsWidget.h
index 3a94f851..0d280daf 100644
--- a/application/widgets/JavaSettingsWidget.h
+++ b/application/widgets/JavaSettingsWidget.h
@@ -22,81 +22,81 @@ class QToolButton;
*/
class JavaSettingsWidget : public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit JavaSettingsWidget(QWidget *parent);
- virtual ~JavaSettingsWidget() {};
+ explicit JavaSettingsWidget(QWidget *parent);
+ virtual ~JavaSettingsWidget() {};
- enum class JavaStatus
- {
- NotSet,
- Pending,
- Good,
- DoesNotExist,
- DoesNotStart,
- ReturnedInvalidData
- } javaStatus = JavaStatus::NotSet;
+ enum class JavaStatus
+ {
+ NotSet,
+ Pending,
+ Good,
+ DoesNotExist,
+ DoesNotStart,
+ ReturnedInvalidData
+ } javaStatus = JavaStatus::NotSet;
- enum class ValidationStatus
- {
- Bad,
- JavaBad,
- AllOK
- };
+ enum class ValidationStatus
+ {
+ Bad,
+ JavaBad,
+ AllOK
+ };
- void refresh();
- void initialize();
- ValidationStatus validate();
- void retranslate();
+ void refresh();
+ void initialize();
+ ValidationStatus validate();
+ void retranslate();
- bool permGenEnabled() const;
- int permGenSize() const;
- int minHeapSize() const;
- int maxHeapSize() const;
- QString javaPath() const;
+ bool permGenEnabled() const;
+ int permGenSize() const;
+ int minHeapSize() const;
+ int maxHeapSize() const;
+ QString javaPath() const;
protected slots:
- void memoryValueChanged(int);
- void javaPathEdited(const QString &path);
- void javaVersionSelected(BaseVersionPtr version);
- void on_javaBrowseBtn_clicked();
- void on_javaStatusBtn_clicked();
- void checkFinished(JavaCheckResult result);
+ void memoryValueChanged(int);
+ void javaPathEdited(const QString &path);
+ void javaVersionSelected(BaseVersionPtr version);
+ void on_javaBrowseBtn_clicked();
+ void on_javaStatusBtn_clicked();
+ void checkFinished(JavaCheckResult result);
protected: /* methods */
- void checkJavaPathOnEdit(const QString &path);
- void checkJavaPath(const QString &path);
- void setJavaStatus(JavaStatus status);
- void setupUi();
+ void checkJavaPathOnEdit(const QString &path);
+ void checkJavaPath(const QString &path);
+ void setJavaStatus(JavaStatus status);
+ void setupUi();
private: /* data */
- VersionSelectWidget *m_versionWidget = nullptr;
- QVBoxLayout *m_verticalLayout = nullptr;
+ VersionSelectWidget *m_versionWidget = nullptr;
+ QVBoxLayout *m_verticalLayout = nullptr;
- QLineEdit * m_javaPathTextBox = nullptr;
- QPushButton * m_javaBrowseBtn = nullptr;
- QToolButton * m_javaStatusBtn = nullptr;
- QHBoxLayout *m_horizontalLayout = nullptr;
+ QLineEdit * m_javaPathTextBox = nullptr;
+ QPushButton * m_javaBrowseBtn = nullptr;
+ QToolButton * m_javaStatusBtn = nullptr;
+ QHBoxLayout *m_horizontalLayout = nullptr;
- QGroupBox *m_memoryGroupBox = nullptr;
- QGridLayout *m_gridLayout_2 = nullptr;
- QSpinBox *m_maxMemSpinBox = nullptr;
- QLabel *m_labelMinMem = nullptr;
- QLabel *m_labelMaxMem = nullptr;
- QSpinBox *m_minMemSpinBox = nullptr;
- QLabel *m_labelPermGen = nullptr;
- QSpinBox *m_permGenSpinBox = nullptr;
- QIcon goodIcon;
- QIcon yellowIcon;
- QIcon badIcon;
+ QGroupBox *m_memoryGroupBox = nullptr;
+ QGridLayout *m_gridLayout_2 = nullptr;
+ QSpinBox *m_maxMemSpinBox = nullptr;
+ QLabel *m_labelMinMem = nullptr;
+ QLabel *m_labelMaxMem = nullptr;
+ QSpinBox *m_minMemSpinBox = nullptr;
+ QLabel *m_labelPermGen = nullptr;
+ QSpinBox *m_permGenSpinBox = nullptr;
+ QIcon goodIcon;
+ QIcon yellowIcon;
+ QIcon badIcon;
- int observedMinMemory = 0;
- int observedMaxMemory = 0;
- int observedPermGenMemory = 0;
- QString queuedCheck;
- uint64_t m_availableMemory = 0ull;
- shared_qobject_ptr<JavaChecker> m_checker;
- JavaCheckResult m_result;
+ int observedMinMemory = 0;
+ int observedMaxMemory = 0;
+ int observedPermGenMemory = 0;
+ QString queuedCheck;
+ uint64_t m_availableMemory = 0ull;
+ shared_qobject_ptr<JavaChecker> m_checker;
+ JavaCheckResult m_result;
};
diff --git a/application/widgets/LabeledToolButton.cpp b/application/widgets/LabeledToolButton.cpp
index 744d2e00..ae79fd99 100644
--- a/application/widgets/LabeledToolButton.cpp
+++ b/application/widgets/LabeledToolButton.cpp
@@ -28,32 +28,32 @@
*/
LabeledToolButton::LabeledToolButton(QWidget * parent)
- : QToolButton(parent)
- , m_label(new QLabel(this))
+ : QToolButton(parent)
+ , m_label(new QLabel(this))
{
- //QToolButton::setText(" ");
- m_label->setWordWrap(true);
- m_label->setMouseTracking(false);
- m_label->setAlignment(Qt::AlignCenter);
- m_label->setTextInteractionFlags(Qt::NoTextInteraction);
- // somehow, this makes word wrap work in the QLabel. yay.
- //m_label->setMinimumWidth(100);
+ //QToolButton::setText(" ");
+ m_label->setWordWrap(true);
+ m_label->setMouseTracking(false);
+ m_label->setAlignment(Qt::AlignCenter);
+ m_label->setTextInteractionFlags(Qt::NoTextInteraction);
+ // somehow, this makes word wrap work in the QLabel. yay.
+ //m_label->setMinimumWidth(100);
}
QString LabeledToolButton::text() const
{
- return m_label->text();
+ return m_label->text();
}
void LabeledToolButton::setText(const QString & text)
{
- m_label->setText(text);
+ m_label->setText(text);
}
void LabeledToolButton::setIcon(QIcon icon)
{
- m_icon = icon;
- resetIcon();
+ m_icon = icon;
+ resetIcon();
}
@@ -62,54 +62,54 @@ void LabeledToolButton::setIcon(QIcon icon)
*/
QSize LabeledToolButton::sizeHint() const
{
- /*
- Q_D(const QToolButton);
- if (d->sizeHint.isValid())
- return d->sizeHint;
- */
- ensurePolished();
+ /*
+ Q_D(const QToolButton);
+ if (d->sizeHint.isValid())
+ return d->sizeHint;
+ */
+ ensurePolished();
- int w = 0, h = 0;
- QStyleOptionToolButton opt;
- initStyleOption(&opt);
- QSize sz =m_label->sizeHint();
- w = sz.width();
- h = sz.height();
+ int w = 0, h = 0;
+ QStyleOptionToolButton opt;
+ initStyleOption(&opt);
+ QSize sz =m_label->sizeHint();
+ w = sz.width();
+ h = sz.height();
- opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height
- if (popupMode() == MenuButtonPopup)
- w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this);
-
- QSize rawSize = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), this);
- QSize sizeHint = rawSize.expandedTo(QApplication::globalStrut());
- return sizeHint;
+ opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height
+ if (popupMode() == MenuButtonPopup)
+ w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this);
+
+ QSize rawSize = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), this);
+ QSize sizeHint = rawSize.expandedTo(QApplication::globalStrut());
+ return sizeHint;
}
void LabeledToolButton::resizeEvent(QResizeEvent * event)
{
- m_label->setGeometry(QRect(4, 4, width()-8, height()-8));
- if(!m_icon.isNull())
- {
- resetIcon();
- }
- QWidget::resizeEvent(event);
+ m_label->setGeometry(QRect(4, 4, width()-8, height()-8));
+ if(!m_icon.isNull())
+ {
+ resetIcon();
+ }
+ QWidget::resizeEvent(event);
}
void LabeledToolButton::resetIcon()
{
- auto iconSz = m_icon.actualSize(QSize(160, 80));
- float w = iconSz.width();
- float h = iconSz.height();
- float ar = w/h;
- // FIXME: hardcoded max size of 160x80
- int newW = 80 * ar;
- if(newW > 160)
- newW = 160;
- QSize newSz (newW, 80);
- auto pixmap = m_icon.pixmap(newSz);
- m_label->setPixmap(pixmap);
- m_label->setMinimumHeight(80);
- m_label->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
+ auto iconSz = m_icon.actualSize(QSize(160, 80));
+ float w = iconSz.width();
+ float h = iconSz.height();
+ float ar = w/h;
+ // FIXME: hardcoded max size of 160x80
+ int newW = 80 * ar;
+ if(newW > 160)
+ newW = 160;
+ QSize newSz (newW, 80);
+ auto pixmap = m_icon.pixmap(newSz);
+ m_label->setPixmap(pixmap);
+ m_label->setMinimumHeight(80);
+ m_label->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
}
diff --git a/application/widgets/LabeledToolButton.h b/application/widgets/LabeledToolButton.h
index 151a5c2c..e7ba5924 100644
--- a/application/widgets/LabeledToolButton.h
+++ b/application/widgets/LabeledToolButton.h
@@ -22,19 +22,19 @@ class QLabel;
class LabeledToolButton : public QToolButton
{
- Q_OBJECT
+ Q_OBJECT
- QLabel * m_label;
- QIcon m_icon;
+ QLabel * m_label;
+ QIcon m_icon;
public:
- LabeledToolButton(QWidget * parent = 0);
+ LabeledToolButton(QWidget * parent = 0);
- QString text() const;
- void setText(const QString & text);
- void setIcon(QIcon icon);
- virtual QSize sizeHint() const;
+ QString text() const;
+ void setText(const QString & text);
+ void setIcon(QIcon icon);
+ virtual QSize sizeHint() const;
protected:
- void resizeEvent(QResizeEvent * event);
- void resetIcon();
+ void resizeEvent(QResizeEvent * event);
+ void resetIcon();
};
diff --git a/application/widgets/LineSeparator.cpp b/application/widgets/LineSeparator.cpp
index f4ee173d..d03e6762 100644
--- a/application/widgets/LineSeparator.cpp
+++ b/application/widgets/LineSeparator.cpp
@@ -7,31 +7,31 @@
void LineSeparator::initStyleOption(QStyleOption *option) const
{
- option->initFrom(this);
- // in a horizontal layout, the line is vertical (and vice versa)
- if (m_orientation == Qt::Vertical)
- option->state |= QStyle::State_Horizontal;
+ option->initFrom(this);
+ // in a horizontal layout, the line is vertical (and vice versa)
+ if (m_orientation == Qt::Vertical)
+ option->state |= QStyle::State_Horizontal;
}
LineSeparator::LineSeparator(QWidget *parent, Qt::Orientation orientation)
- : QWidget(parent), m_orientation(orientation)
+ : QWidget(parent), m_orientation(orientation)
{
- setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
}
QSize LineSeparator::sizeHint() const
{
- QStyleOption opt;
- initStyleOption(&opt);
- const int extent =
- style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, parentWidget());
- return QSize(extent, extent);
+ QStyleOption opt;
+ initStyleOption(&opt);
+ const int extent =
+ style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, parentWidget());
+ return QSize(extent, extent);
}
void LineSeparator::paintEvent(QPaintEvent *)
{
- QPainter p(this);
- QStyleOption opt;
- initStyleOption(&opt);
- style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, &p, parentWidget());
+ QPainter p(this);
+ QStyleOption opt;
+ initStyleOption(&opt);
+ style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, &p, parentWidget());
}
diff --git a/application/widgets/LineSeparator.h b/application/widgets/LineSeparator.h
index 9546e747..22927b68 100644
--- a/application/widgets/LineSeparator.h
+++ b/application/widgets/LineSeparator.h
@@ -5,14 +5,14 @@ class QStyleOption;
class LineSeparator : public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
- /// Create a line separator. orientation is the orientation of the line.
- explicit LineSeparator(QWidget *parent, Qt::Orientation orientation = Qt::Horizontal);
- QSize sizeHint() const;
- void paintEvent(QPaintEvent *);
- void initStyleOption(QStyleOption *option) const;
+ /// Create a line separator. orientation is the orientation of the line.
+ explicit LineSeparator(QWidget *parent, Qt::Orientation orientation = Qt::Horizontal);
+ QSize sizeHint() const;
+ void paintEvent(QPaintEvent *);
+ void initStyleOption(QStyleOption *option) const;
private:
- Qt::Orientation m_orientation = Qt::Horizontal;
+ Qt::Orientation m_orientation = Qt::Horizontal;
};
diff --git a/application/widgets/LogView.cpp b/application/widgets/LogView.cpp
index 8e0346fa..26a2a527 100644
--- a/application/widgets/LogView.cpp
+++ b/application/widgets/LogView.cpp
@@ -4,141 +4,141 @@
LogView::LogView(QWidget* parent) : QPlainTextEdit(parent)
{
- setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
- m_defaultFormat = new QTextCharFormat(currentCharFormat());
+ setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+ m_defaultFormat = new QTextCharFormat(currentCharFormat());
}
LogView::~LogView()
{
- delete m_defaultFormat;
+ delete m_defaultFormat;
}
void LogView::setWordWrap(bool wrapping)
{
- if(wrapping)
- {
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setLineWrapMode(QPlainTextEdit::WidgetWidth);
- }
- else
- {
- setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- setLineWrapMode(QPlainTextEdit::NoWrap);
- }
+ if(wrapping)
+ {
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setLineWrapMode(QPlainTextEdit::WidgetWidth);
+ }
+ else
+ {
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ setLineWrapMode(QPlainTextEdit::NoWrap);
+ }
}
void LogView::setModel(QAbstractItemModel* model)
{
- if(m_model)
- {
- disconnect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate);
- disconnect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted);
- disconnect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted);
- disconnect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved);
- }
- m_model = model;
- if(m_model)
- {
- connect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate);
- connect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted);
- connect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted);
- connect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved);
- connect(m_model, &QAbstractItemModel::destroyed, this, &LogView::modelDestroyed);
- }
- repopulate();
+ if(m_model)
+ {
+ disconnect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate);
+ disconnect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted);
+ disconnect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted);
+ disconnect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved);
+ }
+ m_model = model;
+ if(m_model)
+ {
+ connect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate);
+ connect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted);
+ connect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted);
+ connect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved);
+ connect(m_model, &QAbstractItemModel::destroyed, this, &LogView::modelDestroyed);
+ }
+ repopulate();
}
QAbstractItemModel * LogView::model() const
{
- return m_model;
+ return m_model;
}
void LogView::modelDestroyed(QObject* model)
{
- if(m_model == model)
- {
- setModel(nullptr);
- }
+ if(m_model == model)
+ {
+ setModel(nullptr);
+ }
}
void LogView::repopulate()
{
- auto doc = document();
- doc->clear();
- if(!m_model)
- {
- return;
- }
- rowsInserted(QModelIndex(), 0, m_model->rowCount() - 1);
+ auto doc = document();
+ doc->clear();
+ if(!m_model)
+ {
+ return;
+ }
+ rowsInserted(QModelIndex(), 0, m_model->rowCount() - 1);
}
void LogView::rowsAboutToBeInserted(const QModelIndex& parent, int first, int last)
{
- Q_UNUSED(parent)
- Q_UNUSED(first)
- Q_UNUSED(last)
- QScrollBar *bar = verticalScrollBar();
- int max_bar = bar->maximum();
- int val_bar = bar->value();
- if (m_scroll)
- {
- m_scroll = (max_bar - val_bar) <= 1;
- }
- else
- {
- m_scroll = val_bar == max_bar;
- }
+ Q_UNUSED(parent)
+ Q_UNUSED(first)
+ Q_UNUSED(last)
+ QScrollBar *bar = verticalScrollBar();
+ int max_bar = bar->maximum();
+ int val_bar = bar->value();
+ if (m_scroll)
+ {
+ m_scroll = (max_bar - val_bar) <= 1;
+ }
+ else
+ {
+ m_scroll = val_bar == max_bar;
+ }
}
void LogView::rowsInserted(const QModelIndex& parent, int first, int last)
{
- for(int i = first; i <= last; i++)
- {
- auto idx = m_model->index(i, 0, parent);
- auto text = m_model->data(idx, Qt::DisplayRole).toString();
- QTextCharFormat format(*m_defaultFormat);
- auto font = m_model->data(idx, Qt::FontRole);
- if(font.isValid())
- {
- format.setFont(font.value<QFont>());
- }
- auto fg = m_model->data(idx, Qt::TextColorRole);
- if(fg.isValid())
- {
- format.setForeground(fg.value<QColor>());
- }
- auto bg = m_model->data(idx, Qt::BackgroundRole);
- if(bg.isValid())
- {
- format.setBackground(bg.value<QColor>());
- }
- auto workCursor = textCursor();
- workCursor.movePosition(QTextCursor::End);
- workCursor.insertText(text, format);
- workCursor.insertBlock();
- }
- if(m_scroll && !m_scrolling)
- {
- m_scrolling = true;
- QMetaObject::invokeMethod( this, "scrollToBottom", Qt::QueuedConnection);
- }
+ for(int i = first; i <= last; i++)
+ {
+ auto idx = m_model->index(i, 0, parent);
+ auto text = m_model->data(idx, Qt::DisplayRole).toString();
+ QTextCharFormat format(*m_defaultFormat);
+ auto font = m_model->data(idx, Qt::FontRole);
+ if(font.isValid())
+ {
+ format.setFont(font.value<QFont>());
+ }
+ auto fg = m_model->data(idx, Qt::TextColorRole);
+ if(fg.isValid())
+ {
+ format.setForeground(fg.value<QColor>());
+ }
+ auto bg = m_model->data(idx, Qt::BackgroundRole);
+ if(bg.isValid())
+ {
+ format.setBackground(bg.value<QColor>());
+ }
+ auto workCursor = textCursor();
+ workCursor.movePosition(QTextCursor::End);
+ workCursor.insertText(text, format);
+ workCursor.insertBlock();
+ }
+ if(m_scroll && !m_scrolling)
+ {
+ m_scrolling = true;
+ QMetaObject::invokeMethod( this, "scrollToBottom", Qt::QueuedConnection);
+ }
}
void LogView::rowsRemoved(const QModelIndex& parent, int first, int last)
{
- // TODO: some day... maybe
- Q_UNUSED(parent)
- Q_UNUSED(first)
- Q_UNUSED(last)
+ // TODO: some day... maybe
+ Q_UNUSED(parent)
+ Q_UNUSED(first)
+ Q_UNUSED(last)
}
void LogView::scrollToBottom()
{
- m_scrolling = false;
- verticalScrollBar()->setSliderPosition(verticalScrollBar()->maximum());
+ m_scrolling = false;
+ verticalScrollBar()->setSliderPosition(verticalScrollBar()->maximum());
}
void LogView::findNext(const QString& what, bool reverse)
{
- find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0));
+ find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0));
}
diff --git a/application/widgets/LogView.h b/application/widgets/LogView.h
index bb6747cd..3143360a 100644
--- a/application/widgets/LogView.h
+++ b/application/widgets/LogView.h
@@ -6,31 +6,31 @@ class QAbstractItemModel;
class LogView: public QPlainTextEdit
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit LogView(QWidget *parent = nullptr);
- virtual ~LogView();
+ explicit LogView(QWidget *parent = nullptr);
+ virtual ~LogView();
- virtual void setModel(QAbstractItemModel *model);
- QAbstractItemModel *model() const;
+ virtual void setModel(QAbstractItemModel *model);
+ QAbstractItemModel *model() const;
public slots:
- void setWordWrap(bool wrapping);
- void findNext(const QString & what, bool reverse);
- void scrollToBottom();
+ void setWordWrap(bool wrapping);
+ void findNext(const QString & what, bool reverse);
+ void scrollToBottom();
protected slots:
- void repopulate();
- // note: this supports only appending
- void rowsInserted(const QModelIndex &parent, int first, int last);
- void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
- // note: this supports only removing from front
- void rowsRemoved(const QModelIndex &parent, int first, int last);
- void modelDestroyed(QObject * model);
+ void repopulate();
+ // note: this supports only appending
+ void rowsInserted(const QModelIndex &parent, int first, int last);
+ void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
+ // note: this supports only removing from front
+ void rowsRemoved(const QModelIndex &parent, int first, int last);
+ void modelDestroyed(QObject * model);
protected:
- QAbstractItemModel *m_model = nullptr;
- QTextCharFormat *m_defaultFormat = nullptr;
- bool m_scroll = false;
- bool m_scrolling = false;
+ QAbstractItemModel *m_model = nullptr;
+ QTextCharFormat *m_defaultFormat = nullptr;
+ bool m_scroll = false;
+ bool m_scrolling = false;
};
diff --git a/application/widgets/MCModInfoFrame.cpp b/application/widgets/MCModInfoFrame.cpp
index 629c17e7..3bd2af1e 100644
--- a/application/widgets/MCModInfoFrame.cpp
+++ b/application/widgets/MCModInfoFrame.cpp
@@ -22,145 +22,145 @@
void MCModInfoFrame::updateWithMod(Mod &m)
{
- if (m.type() == m.MOD_FOLDER)
- {
- clear();
- return;
- }
+ if (m.type() == m.MOD_FOLDER)
+ {
+ clear();
+ return;
+ }
- QString text = "";
- QString name = "";
- if (m.name().isEmpty())
- name = m.mmc_id();
- else
- name = m.name();
+ QString text = "";
+ QString name = "";
+ if (m.name().isEmpty())
+ name = m.mmc_id();
+ else
+ name = m.name();
- if (m.homeurl().isEmpty())
- text = name;
- else
- text = "<a href=\"" + m.homeurl() + "\">" + name + "</a>";
- if (!m.authors().isEmpty())
- text += " by " + m.authors();
+ if (m.homeurl().isEmpty())
+ text = name;
+ else
+ text = "<a href=\"" + m.homeurl() + "\">" + name + "</a>";
+ if (!m.authors().isEmpty())
+ text += " by " + m.authors();
- setModText(text);
+ setModText(text);
- if (m.description().isEmpty())
- {
- setModDescription(QString());
- }
- else
- {
- setModDescription(m.description());
- }
+ if (m.description().isEmpty())
+ {
+ setModDescription(QString());
+ }
+ else
+ {
+ setModDescription(m.description());
+ }
}
void MCModInfoFrame::clear()
{
- setModText(QString());
- setModDescription(QString());
+ setModText(QString());
+ setModDescription(QString());
}
MCModInfoFrame::MCModInfoFrame(QWidget *parent) :
- QFrame(parent),
- ui(new Ui::MCModInfoFrame)
+ QFrame(parent),
+ ui(new Ui::MCModInfoFrame)
{
- ui->setupUi(this);
- ui->label_ModDescription->setHidden(true);
- ui->label_ModText->setHidden(true);
- updateHiddenState();
+ ui->setupUi(this);
+ ui->label_ModDescription->setHidden(true);
+ ui->label_ModText->setHidden(true);
+ updateHiddenState();
}
MCModInfoFrame::~MCModInfoFrame()
{
- delete ui;
+ delete ui;
}
void MCModInfoFrame::updateHiddenState()
{
- if(ui->label_ModDescription->isHidden() && ui->label_ModText->isHidden())
- {
- setHidden(true);
- }
- else
- {
- setHidden(false);
- }
+ if(ui->label_ModDescription->isHidden() && ui->label_ModText->isHidden())
+ {
+ setHidden(true);
+ }
+ else
+ {
+ setHidden(false);
+ }
}
void MCModInfoFrame::setModText(QString text)
{
- if(text.isEmpty())
- {
- ui->label_ModText->setHidden(true);
- }
- else
- {
- ui->label_ModText->setText(text);
- ui->label_ModText->setHidden(false);
- }
- updateHiddenState();
+ if(text.isEmpty())
+ {
+ ui->label_ModText->setHidden(true);
+ }
+ else
+ {
+ ui->label_ModText->setText(text);
+ ui->label_ModText->setHidden(false);
+ }
+ updateHiddenState();
}
void MCModInfoFrame::setModDescription(QString text)
{
- if(text.isEmpty())
- {
- ui->label_ModDescription->setHidden(true);
- updateHiddenState();
- return;
- }
- else
- {
- ui->label_ModDescription->setHidden(false);
- updateHiddenState();
- }
- ui->label_ModDescription->setToolTip("");
- QString intermediatetext = text.trimmed();
- bool prev(false);
- QChar rem('\n');
- QString finaltext;
- finaltext.reserve(intermediatetext.size());
- foreach(const QChar& c, intermediatetext)
- {
- if(c == rem && prev){
- continue;
- }
- prev = c == rem;
- finaltext += c;
- }
- QString labeltext;
- labeltext.reserve(300);
- if(finaltext.length() > 290)
- {
- ui->label_ModDescription->setOpenExternalLinks(false);
- ui->label_ModDescription->setTextFormat(Qt::TextFormat::RichText);
- desc = text;
- labeltext.append("<html><body>" + finaltext.left(287) + "<a href=\"#mod_desc\">...</a></body></html>");
- QObject::connect(ui->label_ModDescription, &QLabel::linkActivated, this, &MCModInfoFrame::modDescEllipsisHandler);
- }
- else
- {
- ui->label_ModDescription->setTextFormat(Qt::TextFormat::PlainText);
- labeltext.append(finaltext);
- }
- ui->label_ModDescription->setText(labeltext);
+ if(text.isEmpty())
+ {
+ ui->label_ModDescription->setHidden(true);
+ updateHiddenState();
+ return;
+ }
+ else
+ {
+ ui->label_ModDescription->setHidden(false);
+ updateHiddenState();
+ }
+ ui->label_ModDescription->setToolTip("");
+ QString intermediatetext = text.trimmed();
+ bool prev(false);
+ QChar rem('\n');
+ QString finaltext;
+ finaltext.reserve(intermediatetext.size());
+ foreach(const QChar& c, intermediatetext)
+ {
+ if(c == rem && prev){
+ continue;
+ }
+ prev = c == rem;
+ finaltext += c;
+ }
+ QString labeltext;
+ labeltext.reserve(300);
+ if(finaltext.length() > 290)
+ {
+ ui->label_ModDescription->setOpenExternalLinks(false);
+ ui->label_ModDescription->setTextFormat(Qt::TextFormat::RichText);
+ desc = text;
+ labeltext.append("<html><body>" + finaltext.left(287) + "<a href=\"#mod_desc\">...</a></body></html>");
+ QObject::connect(ui->label_ModDescription, &QLabel::linkActivated, this, &MCModInfoFrame::modDescEllipsisHandler);
+ }
+ else
+ {
+ ui->label_ModDescription->setTextFormat(Qt::TextFormat::PlainText);
+ labeltext.append(finaltext);
+ }
+ ui->label_ModDescription->setText(labeltext);
}
void MCModInfoFrame::modDescEllipsisHandler(const QString &link)
{
- if(!currentBox)
- {
- currentBox = CustomMessageBox::selectable(this, QString(), desc);
- connect(currentBox, &QMessageBox::finished, this, &MCModInfoFrame::boxClosed);
- currentBox->show();
- }
- else
- {
- currentBox->setText(desc);
- }
+ if(!currentBox)
+ {
+ currentBox = CustomMessageBox::selectable(this, QString(), desc);
+ connect(currentBox, &QMessageBox::finished, this, &MCModInfoFrame::boxClosed);
+ currentBox->show();
+ }
+ else
+ {
+ currentBox->setText(desc);
+ }
}
void MCModInfoFrame::boxClosed(int result)
{
- currentBox = nullptr;
+ currentBox = nullptr;
}
diff --git a/application/widgets/MCModInfoFrame.h b/application/widgets/MCModInfoFrame.h
index 6bcd345c..5d27449a 100644
--- a/application/widgets/MCModInfoFrame.h
+++ b/application/widgets/MCModInfoFrame.h
@@ -25,28 +25,28 @@ class MCModInfoFrame;
class MCModInfoFrame : public QFrame
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit MCModInfoFrame(QWidget *parent = 0);
- ~MCModInfoFrame();
+ explicit MCModInfoFrame(QWidget *parent = 0);
+ ~MCModInfoFrame();
- void setModText(QString text);
- void setModDescription(QString text);
+ void setModText(QString text);
+ void setModDescription(QString text);
- void updateWithMod(Mod &m);
- void clear();
+ void updateWithMod(Mod &m);
+ void clear();
public slots:
- void modDescEllipsisHandler(const QString& link );
- void boxClosed(int result);
+ void modDescEllipsisHandler(const QString& link );
+ void boxClosed(int result);
private:
- void updateHiddenState();
+ void updateHiddenState();
private:
- Ui::MCModInfoFrame *ui;
- QString desc;
- class QMessageBox * currentBox = nullptr;
+ Ui::MCModInfoFrame *ui;
+ QString desc;
+ class QMessageBox * currentBox = nullptr;
};
diff --git a/application/widgets/ModListView.cpp b/application/widgets/ModListView.cpp
index 96e8d91b..6f084ba7 100644
--- a/application/widgets/ModListView.cpp
+++ b/application/widgets/ModListView.cpp
@@ -21,46 +21,46 @@
#include <QRect>
ModListView::ModListView ( QWidget* parent )
- :QTreeView ( parent )
+ :QTreeView ( parent )
{
- setAllColumnsShowFocus ( true );
- setExpandsOnDoubleClick ( false );
- setRootIsDecorated ( false );
- setSortingEnabled ( true );
- setAlternatingRowColors ( true );
- setSelectionMode ( QAbstractItemView::ExtendedSelection );
- setHeaderHidden ( false );
- setSelectionBehavior(QAbstractItemView::SelectRows);
- setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn );
- setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded );
- setDropIndicatorShown(true);
- setDragEnabled(true);
- setDragDropMode(QAbstractItemView::DropOnly);
- viewport()->setAcceptDrops(true);
+ setAllColumnsShowFocus ( true );
+ setExpandsOnDoubleClick ( false );
+ setRootIsDecorated ( false );
+ setSortingEnabled ( true );
+ setAlternatingRowColors ( true );
+ setSelectionMode ( QAbstractItemView::ExtendedSelection );
+ setHeaderHidden ( false );
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn );
+ setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded );
+ setDropIndicatorShown(true);
+ setDragEnabled(true);
+ setDragDropMode(QAbstractItemView::DropOnly);
+ viewport()->setAcceptDrops(true);
}
void ModListView::setModel ( QAbstractItemModel* model )
{
- QTreeView::setModel ( model );
- auto head = header();
- head->setStretchLastSection(false);
- // HACK: this is true for the checkbox column of mod lists
- auto string = model->headerData(0,head->orientation()).toString();
- if(head->count() < 1)
- {
- return;
- }
- if(!string.size())
- {
- head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
- head->setSectionResizeMode(1, QHeaderView::Stretch);
- for(int i = 2; i < head->count(); i++)
- head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- }
- else
- {
- head->setSectionResizeMode(0, QHeaderView::Stretch);
- for(int i = 1; i < head->count(); i++)
- head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- }
+ QTreeView::setModel ( model );
+ auto head = header();
+ head->setStretchLastSection(false);
+ // HACK: this is true for the checkbox column of mod lists
+ auto string = model->headerData(0,head->orientation()).toString();
+ if(head->count() < 1)
+ {
+ return;
+ }
+ if(!string.size())
+ {
+ head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+ head->setSectionResizeMode(1, QHeaderView::Stretch);
+ for(int i = 2; i < head->count(); i++)
+ head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
+ }
+ else
+ {
+ head->setSectionResizeMode(0, QHeaderView::Stretch);
+ for(int i = 1; i < head->count(); i++)
+ head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
+ }
}
diff --git a/application/widgets/ModListView.h b/application/widgets/ModListView.h
index baca23f4..ee88d634 100644
--- a/application/widgets/ModListView.h
+++ b/application/widgets/ModListView.h
@@ -20,8 +20,8 @@ class Mod;
class ModListView: public QTreeView
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ModListView ( QWidget* parent = 0 );
- virtual void setModel ( QAbstractItemModel* model );
+ explicit ModListView ( QWidget* parent = 0 );
+ virtual void setModel ( QAbstractItemModel* model );
};
diff --git a/application/widgets/PageContainer.cpp b/application/widgets/PageContainer.cpp
index c8c2b57a..7e681592 100644
--- a/application/widgets/PageContainer.cpp
+++ b/application/widgets/PageContainer.cpp
@@ -36,205 +36,205 @@
class PageEntryFilterModel : public QSortFilterProxyModel
{
public:
- explicit PageEntryFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent)
- {
- }
+ explicit PageEntryFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent)
+ {
+ }
protected:
- bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
- {
- const QString pattern = filterRegExp().pattern();
- const auto model = static_cast<PageModel *>(sourceModel());
- const auto page = model->pages().at(sourceRow);
- if (!page->shouldDisplay())
- return false;
- // Regular contents check, then check page-filter.
- return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
- }
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+ {
+ const QString pattern = filterRegExp().pattern();
+ const auto model = static_cast<PageModel *>(sourceModel());
+ const auto page = model->pages().at(sourceRow);
+ if (!page->shouldDisplay())
+ return false;
+ // Regular contents check, then check page-filter.
+ return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
+ }
};
PageContainer::PageContainer(BasePageProvider *pageProvider, QString defaultId,
- QWidget *parent)
- : QWidget(parent)
+ QWidget *parent)
+ : QWidget(parent)
{
- createUI();
- m_model = new PageModel(this);
- m_proxyModel = new PageEntryFilterModel(this);
- int counter = 0;
- auto pages = pageProvider->getPages();
- for (auto page : pages)
- {
- page->stackIndex = m_pageStack->addWidget(dynamic_cast<QWidget *>(page));
- page->listIndex = counter;
- page->setParentContainer(this);
- counter++;
- }
- m_model->setPages(pages);
-
- m_proxyModel->setSourceModel(m_model);
- m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
-
- m_pageList->setIconSize(QSize(pageIconSize, pageIconSize));
- m_pageList->setSelectionMode(QAbstractItemView::SingleSelection);
- m_pageList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
- m_pageList->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
- m_pageList->setModel(m_proxyModel);
- connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)),
- this, SLOT(currentChanged(QModelIndex)));
- m_pageStack->setStackingMode(QStackedLayout::StackOne);
- m_pageList->setFocus();
- selectPage(defaultId);
+ createUI();
+ m_model = new PageModel(this);
+ m_proxyModel = new PageEntryFilterModel(this);
+ int counter = 0;
+ auto pages = pageProvider->getPages();
+ for (auto page : pages)
+ {
+ page->stackIndex = m_pageStack->addWidget(dynamic_cast<QWidget *>(page));
+ page->listIndex = counter;
+ page->setParentContainer(this);
+ counter++;
+ }
+ m_model->setPages(pages);
+
+ m_proxyModel->setSourceModel(m_model);
+ m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+
+ m_pageList->setIconSize(QSize(pageIconSize, pageIconSize));
+ m_pageList->setSelectionMode(QAbstractItemView::SingleSelection);
+ m_pageList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
+ m_pageList->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
+ m_pageList->setModel(m_proxyModel);
+ connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)),
+ this, SLOT(currentChanged(QModelIndex)));
+ m_pageStack->setStackingMode(QStackedLayout::StackOne);
+ m_pageList->setFocus();
+ selectPage(defaultId);
}
bool PageContainer::selectPage(QString pageId)
{
- // now find what we want to have selected...
- auto page = m_model->findPageEntryById(pageId);
- QModelIndex index;
- if (page)
- {
- index = m_proxyModel->mapFromSource(m_model->index(page->listIndex));
- }
- if(!index.isValid())
- {
- index = m_proxyModel->index(0, 0);
- }
- if (index.isValid())
- {
- m_pageList->setCurrentIndex(index);
- return true;
- }
- return false;
+ // now find what we want to have selected...
+ auto page = m_model->findPageEntryById(pageId);
+ QModelIndex index;
+ if (page)
+ {
+ index = m_proxyModel->mapFromSource(m_model->index(page->listIndex));
+ }
+ if(!index.isValid())
+ {
+ index = m_proxyModel->index(0, 0);
+ }
+ if (index.isValid())
+ {
+ m_pageList->setCurrentIndex(index);
+ return true;
+ }
+ return false;
}
void PageContainer::refreshContainer()
{
- m_proxyModel->invalidate();
- if(!m_currentPage->shouldDisplay())
- {
- auto index = m_proxyModel->index(0, 0);
- if(index.isValid())
- {
- m_pageList->setCurrentIndex(index);
- }
- else
- {
- // FIXME: unhandled corner case: what to do when there's no page to select?
- }
- }
+ m_proxyModel->invalidate();
+ if(!m_currentPage->shouldDisplay())
+ {
+ auto index = m_proxyModel->index(0, 0);
+ if(index.isValid())
+ {
+ m_pageList->setCurrentIndex(index);
+ }
+ else
+ {
+ // FIXME: unhandled corner case: what to do when there's no page to select?
+ }
+ }
}
void PageContainer::createUI()
{
- m_pageStack = new QStackedLayout;
- m_pageList = new PageView;
- m_header = new QLabel();
- m_iconHeader = new IconLabel(this, QIcon(), QSize(24, 24));
-
- QFont headerLabelFont = m_header->font();
- headerLabelFont.setBold(true);
- const int pointSize = headerLabelFont.pointSize();
- if (pointSize > 0)
- headerLabelFont.setPointSize(pointSize + 2);
- m_header->setFont(headerLabelFont);
-
- QHBoxLayout *headerHLayout = new QHBoxLayout;
- const int leftMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
- headerHLayout->addSpacerItem(
- new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
- headerHLayout->addWidget(m_header);
- headerHLayout->addSpacerItem(
- new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
- headerHLayout->addWidget(m_iconHeader);
- const int rightMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutRightMargin);
- headerHLayout->addSpacerItem(
- new QSpacerItem(rightMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
-
- m_pageStack->setMargin(0);
- m_pageStack->addWidget(new QWidget(this));
-
- m_layout = new QGridLayout;
- m_layout->addLayout(headerHLayout, 0, 1, 1, 1);
- m_layout->addWidget(m_pageList, 0, 0, 2, 1);
- m_layout->addLayout(m_pageStack, 1, 1, 1, 1);
- m_layout->setColumnStretch(1, 4);
- setLayout(m_layout);
+ m_pageStack = new QStackedLayout;
+ m_pageList = new PageView;
+ m_header = new QLabel();
+ m_iconHeader = new IconLabel(this, QIcon(), QSize(24, 24));
+
+ QFont headerLabelFont = m_header->font();
+ headerLabelFont.setBold(true);
+ const int pointSize = headerLabelFont.pointSize();
+ if (pointSize > 0)
+ headerLabelFont.setPointSize(pointSize + 2);
+ m_header->setFont(headerLabelFont);
+
+ QHBoxLayout *headerHLayout = new QHBoxLayout;
+ const int leftMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
+ headerHLayout->addSpacerItem(
+ new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
+ headerHLayout->addWidget(m_header);
+ headerHLayout->addSpacerItem(
+ new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
+ headerHLayout->addWidget(m_iconHeader);
+ const int rightMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutRightMargin);
+ headerHLayout->addSpacerItem(
+ new QSpacerItem(rightMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
+
+ m_pageStack->setMargin(0);
+ m_pageStack->addWidget(new QWidget(this));
+
+ m_layout = new QGridLayout;
+ m_layout->addLayout(headerHLayout, 0, 1, 1, 1);
+ m_layout->addWidget(m_pageList, 0, 0, 2, 1);
+ m_layout->addLayout(m_pageStack, 1, 1, 1, 1);
+ m_layout->setColumnStretch(1, 4);
+ setLayout(m_layout);
}
void PageContainer::addButtons(QWidget *buttons)
{
- m_layout->addWidget(buttons, 2, 0, 1, 2);
+ m_layout->addWidget(buttons, 2, 0, 1, 2);
}
void PageContainer::addButtons(QLayout *buttons)
{
- m_layout->addLayout(buttons, 2, 0, 1, 2);
+ m_layout->addLayout(buttons, 2, 0, 1, 2);
}
void PageContainer::showPage(int row)
{
- if (m_currentPage)
- {
- m_currentPage->closed();
- }
- if (row != -1)
- {
- m_currentPage = m_model->pages().at(row);
- }
- else
- {
- m_currentPage = nullptr;
- }
- if (m_currentPage)
- {
- m_pageStack->setCurrentIndex(m_currentPage->stackIndex);
- m_header->setText(m_currentPage->displayName());
- m_iconHeader->setIcon(m_currentPage->icon());
- m_currentPage->opened();
- }
- else
- {
- m_pageStack->setCurrentIndex(0);
- m_header->setText(QString());
- m_iconHeader->setIcon(MMC->getThemedIcon("bug"));
- }
+ if (m_currentPage)
+ {
+ m_currentPage->closed();
+ }
+ if (row != -1)
+ {
+ m_currentPage = m_model->pages().at(row);
+ }
+ else
+ {
+ m_currentPage = nullptr;
+ }
+ if (m_currentPage)
+ {
+ m_pageStack->setCurrentIndex(m_currentPage->stackIndex);
+ m_header->setText(m_currentPage->displayName());
+ m_iconHeader->setIcon(m_currentPage->icon());
+ m_currentPage->opened();
+ }
+ else
+ {
+ m_pageStack->setCurrentIndex(0);
+ m_header->setText(QString());
+ m_iconHeader->setIcon(MMC->getThemedIcon("bug"));
+ }
}
void PageContainer::help()
{
- if (m_currentPage)
- {
- QString pageId = m_currentPage->helpPage();
- if (pageId.isEmpty())
- return;
- DesktopServices::openUrl(QUrl("https://github.com/MultiMC/MultiMC5/wiki/" + pageId));
- }
+ if (m_currentPage)
+ {
+ QString pageId = m_currentPage->helpPage();
+ if (pageId.isEmpty())
+ return;
+ DesktopServices::openUrl(QUrl("https://github.com/MultiMC/MultiMC5/wiki/" + pageId));
+ }
}
void PageContainer::currentChanged(const QModelIndex &current)
{
- showPage(current.isValid() ? m_proxyModel->mapToSource(current).row() : -1);
+ showPage(current.isValid() ? m_proxyModel->mapToSource(current).row() : -1);
}
bool PageContainer::prepareToClose()
{
- if(!saveAll())
- {
- return false;
- }
- if (m_currentPage)
- {
- m_currentPage->closed();
- }
- return true;
+ if(!saveAll())
+ {
+ return false;
+ }
+ if (m_currentPage)
+ {
+ m_currentPage->closed();
+ }
+ return true;
}
bool PageContainer::saveAll()
{
- for (auto page : m_model->pages())
- {
- if (!page->apply())
- return false;
- }
- return true;
+ for (auto page : m_model->pages())
+ {
+ if (!page->apply())
+ return false;
+ }
+ return true;
}
diff --git a/application/widgets/PageContainer.h b/application/widgets/PageContainer.h
index a05e74c4..9aa1ebb0 100644
--- a/application/widgets/PageContainer.h
+++ b/application/widgets/PageContainer.h
@@ -33,57 +33,57 @@ class QGridLayout;
class PageContainer : public QWidget, public BasePageContainer
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit PageContainer(BasePageProvider *pageProvider, QString defaultId = QString(),
- QWidget *parent = 0);
- virtual ~PageContainer() {}
+ explicit PageContainer(BasePageProvider *pageProvider, QString defaultId = QString(),
+ QWidget *parent = 0);
+ virtual ~PageContainer() {}
- void addButtons(QWidget * buttons);
- void addButtons(QLayout * buttons);
- /*
- * Save any unsaved state and prepare to be closed.
- * @return true if everything can be saved, false if there is something that requires attention
- */
- bool prepareToClose();
- bool saveAll();
+ void addButtons(QWidget * buttons);
+ void addButtons(QLayout * buttons);
+ /*
+ * Save any unsaved state and prepare to be closed.
+ * @return true if everything can be saved, false if there is something that requires attention
+ */
+ bool prepareToClose();
+ bool saveAll();
- /* request close - used by individual pages */
- bool requestClose() override
- {
- if(m_container)
- {
- return m_container->requestClose();
- }
- return false;
- }
+ /* request close - used by individual pages */
+ bool requestClose() override
+ {
+ if(m_container)
+ {
+ return m_container->requestClose();
+ }
+ return false;
+ }
- virtual bool selectPage(QString pageId) override;
+ virtual bool selectPage(QString pageId) override;
- void refreshContainer() override;
- virtual void setParentContainer(BasePageContainer * container)
- {
- m_container = container;
- };
+ void refreshContainer() override;
+ virtual void setParentContainer(BasePageContainer * container)
+ {
+ m_container = container;
+ };
private:
- void createUI();
+ void createUI();
public slots:
- void help();
+ void help();
private slots:
- void currentChanged(const QModelIndex &current);
- void showPage(int row);
+ void currentChanged(const QModelIndex &current);
+ void showPage(int row);
private:
- BasePageContainer * m_container = nullptr;
- BasePage * m_currentPage = 0;
- QSortFilterProxyModel *m_proxyModel;
- PageModel *m_model;
- QStackedLayout *m_pageStack;
- QListView *m_pageList;
- QLabel *m_header;
- IconLabel *m_iconHeader;
- QGridLayout *m_layout;
+ BasePageContainer * m_container = nullptr;
+ BasePage * m_currentPage = 0;
+ QSortFilterProxyModel *m_proxyModel;
+ PageModel *m_model;
+ QStackedLayout *m_pageStack;
+ QListView *m_pageList;
+ QLabel *m_header;
+ IconLabel *m_iconHeader;
+ QGridLayout *m_layout;
};
diff --git a/application/widgets/PageContainer_p.h b/application/widgets/PageContainer_p.h
index ed8171f1..8f1c52ea 100644
--- a/application/widgets/PageContainer_p.h
+++ b/application/widgets/PageContainer_p.h
@@ -26,98 +26,98 @@ const int pageIconSize = 24;
class PageViewDelegate : public QStyledItemDelegate
{
public:
- PageViewDelegate(QObject *parent) : QStyledItemDelegate(parent)
- {
- }
- QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
- {
- QSize size = QStyledItemDelegate::sizeHint(option, index);
- size.setHeight(qMax(size.height(), 32));
- return size;
- }
+ PageViewDelegate(QObject *parent) : QStyledItemDelegate(parent)
+ {
+ }
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
+ {
+ QSize size = QStyledItemDelegate::sizeHint(option, index);
+ size.setHeight(qMax(size.height(), 32));
+ return size;
+ }
};
class PageModel : public QAbstractListModel
{
public:
- PageModel(QObject *parent = 0) : QAbstractListModel(parent)
- {
- QPixmap empty(pageIconSize, pageIconSize);
- empty.fill(Qt::transparent);
- m_emptyIcon = QIcon(empty);
- }
- virtual ~PageModel() {}
+ PageModel(QObject *parent = 0) : QAbstractListModel(parent)
+ {
+ QPixmap empty(pageIconSize, pageIconSize);
+ empty.fill(Qt::transparent);
+ m_emptyIcon = QIcon(empty);
+ }
+ virtual ~PageModel() {}
- int rowCount(const QModelIndex &parent = QModelIndex()) const
- {
- return parent.isValid() ? 0 : m_pages.size();
- }
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
- {
- switch (role)
- {
- case Qt::DisplayRole:
- return m_pages.at(index.row())->displayName();
- case Qt::DecorationRole:
- {
- QIcon icon = m_pages.at(index.row())->icon();
- if (icon.isNull())
- icon = m_emptyIcon;
- // HACK: fixes icon stretching on windows. TODO: report Qt bug for this
- return QIcon(icon.pixmap(QSize(48,48)));
- }
- }
- return QVariant();
- }
+ int rowCount(const QModelIndex &parent = QModelIndex()) const
+ {
+ return parent.isValid() ? 0 : m_pages.size();
+ }
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
+ {
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ return m_pages.at(index.row())->displayName();
+ case Qt::DecorationRole:
+ {
+ QIcon icon = m_pages.at(index.row())->icon();
+ if (icon.isNull())
+ icon = m_emptyIcon;
+ // HACK: fixes icon stretching on windows. TODO: report Qt bug for this
+ return QIcon(icon.pixmap(QSize(48,48)));
+ }
+ }
+ return QVariant();
+ }
- void setPages(const QList<BasePage *> &pages)
- {
- beginResetModel();
- m_pages = pages;
- endResetModel();
- }
- const QList<BasePage *> &pages() const
- {
- return m_pages;
- }
+ void setPages(const QList<BasePage *> &pages)
+ {
+ beginResetModel();
+ m_pages = pages;
+ endResetModel();
+ }
+ const QList<BasePage *> &pages() const
+ {
+ return m_pages;
+ }
- BasePage * findPageEntryById(QString id)
- {
- for(auto page: m_pages)
- {
- if (page->id() == id)
- return page;
- }
- return nullptr;
- }
+ BasePage * findPageEntryById(QString id)
+ {
+ for(auto page: m_pages)
+ {
+ if (page->id() == id)
+ return page;
+ }
+ return nullptr;
+ }
- QList<BasePage *> m_pages;
- QIcon m_emptyIcon;
+ QList<BasePage *> m_pages;
+ QIcon m_emptyIcon;
};
class PageView : public QListView
{
public:
- PageView(QWidget *parent = 0) : QListView(parent)
- {
- setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
- setItemDelegate(new PageViewDelegate(this));
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- }
+ PageView(QWidget *parent = 0) : QListView(parent)
+ {
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
+ setItemDelegate(new PageViewDelegate(this));
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ }
- virtual QSize sizeHint() const
- {
- int width = sizeHintForColumn(0) + frameWidth() * 2 + 5;
- if (verticalScrollBar()->isVisible())
- width += verticalScrollBar()->width();
- return QSize(width, 100);
- }
+ virtual QSize sizeHint() const
+ {
+ int width = sizeHintForColumn(0) + frameWidth() * 2 + 5;
+ if (verticalScrollBar()->isVisible())
+ width += verticalScrollBar()->width();
+ return QSize(width, 100);
+ }
- virtual bool eventFilter(QObject *obj, QEvent *event)
- {
- if (obj == verticalScrollBar() &&
- (event->type() == QEvent::Show || event->type() == QEvent::Hide))
- updateGeometry();
- return QListView::eventFilter(obj, event);
- }
+ virtual bool eventFilter(QObject *obj, QEvent *event)
+ {
+ if (obj == verticalScrollBar() &&
+ (event->type() == QEvent::Show || event->type() == QEvent::Hide))
+ updateGeometry();
+ return QListView::eventFilter(obj, event);
+ }
};
diff --git a/application/widgets/ProgressWidget.cpp b/application/widgets/ProgressWidget.cpp
index fab099a9..911e555d 100644
--- a/application/widgets/ProgressWidget.cpp
+++ b/application/widgets/ProgressWidget.cpp
@@ -9,65 +9,65 @@
#include "tasks/Task.h"
ProgressWidget::ProgressWidget(QWidget *parent)
- : QWidget(parent)
+ : QWidget(parent)
{
- m_label = new QLabel(this);
- m_label->setWordWrap(true);
- m_bar = new QProgressBar(this);
- m_bar->setMinimum(0);
- m_bar->setMaximum(100);
- QVBoxLayout *layout = new QVBoxLayout(this);
- layout->addWidget(m_label);
- layout->addWidget(m_bar);
- layout->addStretch();
- setLayout(layout);
+ m_label = new QLabel(this);
+ m_label->setWordWrap(true);
+ m_bar = new QProgressBar(this);
+ m_bar->setMinimum(0);
+ m_bar->setMaximum(100);
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addWidget(m_label);
+ layout->addWidget(m_bar);
+ layout->addStretch();
+ setLayout(layout);
}
void ProgressWidget::start(std::shared_ptr<Task> task)
{
- if (m_task)
- {
- disconnect(m_task.get(), 0, this, 0);
- }
- m_task = task;
- connect(m_task.get(), &Task::finished, this, &ProgressWidget::handleTaskFinish);
- connect(m_task.get(), &Task::status, this, &ProgressWidget::handleTaskStatus);
- connect(m_task.get(), &Task::progress, this, &ProgressWidget::handleTaskProgress);
- connect(m_task.get(), &Task::destroyed, this, &ProgressWidget::taskDestroyed);
- if (!m_task->isRunning())
- {
- QMetaObject::invokeMethod(m_task.get(), "start", Qt::QueuedConnection);
- }
+ if (m_task)
+ {
+ disconnect(m_task.get(), 0, this, 0);
+ }
+ m_task = task;
+ connect(m_task.get(), &Task::finished, this, &ProgressWidget::handleTaskFinish);
+ connect(m_task.get(), &Task::status, this, &ProgressWidget::handleTaskStatus);
+ connect(m_task.get(), &Task::progress, this, &ProgressWidget::handleTaskProgress);
+ connect(m_task.get(), &Task::destroyed, this, &ProgressWidget::taskDestroyed);
+ if (!m_task->isRunning())
+ {
+ QMetaObject::invokeMethod(m_task.get(), "start", Qt::QueuedConnection);
+ }
}
bool ProgressWidget::exec(std::shared_ptr<Task> task)
{
- QEventLoop loop;
- connect(task.get(), &Task::finished, &loop, &QEventLoop::quit);
- start(task);
- if (task->isRunning())
- {
- loop.exec();
- }
- return task->wasSuccessful();
+ QEventLoop loop;
+ connect(task.get(), &Task::finished, &loop, &QEventLoop::quit);
+ start(task);
+ if (task->isRunning())
+ {
+ loop.exec();
+ }
+ return task->wasSuccessful();
}
void ProgressWidget::handleTaskFinish()
{
- if (!m_task->wasSuccessful())
- {
- m_label->setText(m_task->failReason());
- }
+ if (!m_task->wasSuccessful())
+ {
+ m_label->setText(m_task->failReason());
+ }
}
void ProgressWidget::handleTaskStatus(const QString &status)
{
- m_label->setText(status);
+ m_label->setText(status);
}
void ProgressWidget::handleTaskProgress(qint64 current, qint64 total)
{
- m_bar->setMaximum(total);
- m_bar->setValue(current);
+ m_bar->setMaximum(total);
+ m_bar->setValue(current);
}
void ProgressWidget::taskDestroyed()
{
- m_task = nullptr;
+ m_task = nullptr;
}
diff --git a/application/widgets/ProgressWidget.h b/application/widgets/ProgressWidget.h
index 08d8a157..fa67748a 100644
--- a/application/widgets/ProgressWidget.h
+++ b/application/widgets/ProgressWidget.h
@@ -11,22 +11,22 @@ class QLabel;
class ProgressWidget : public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ProgressWidget(QWidget *parent = nullptr);
+ explicit ProgressWidget(QWidget *parent = nullptr);
public slots:
- void start(std::shared_ptr<Task> task);
- bool exec(std::shared_ptr<Task> task);
+ void start(std::shared_ptr<Task> task);
+ bool exec(std::shared_ptr<Task> task);
private slots:
- void handleTaskFinish();
- void handleTaskStatus(const QString &status);
- void handleTaskProgress(qint64 current, qint64 total);
- void taskDestroyed();
+ void handleTaskFinish();
+ void handleTaskStatus(const QString &status);
+ void handleTaskProgress(qint64 current, qint64 total);
+ void taskDestroyed();
private:
- QLabel *m_label;
- QProgressBar *m_bar;
- std::shared_ptr<Task> m_task;
+ QLabel *m_label;
+ QProgressBar *m_bar;
+ std::shared_ptr<Task> m_task;
};
diff --git a/application/widgets/ServerStatus.cpp b/application/widgets/ServerStatus.cpp
index f1963b68..a7016c0c 100644
--- a/application/widgets/ServerStatus.cpp
+++ b/application/widgets/ServerStatus.cpp
@@ -15,80 +15,80 @@
class ClickableLabel : public QLabel
{
- Q_OBJECT
+ Q_OBJECT
public:
- ClickableLabel(QWidget *parent) : QLabel(parent)
- {
- setCursor(Qt::PointingHandCursor);
- }
+ ClickableLabel(QWidget *parent) : QLabel(parent)
+ {
+ setCursor(Qt::PointingHandCursor);
+ }
- ~ClickableLabel(){};
+ ~ClickableLabel(){};
signals:
- void clicked();
+ void clicked();
protected:
- void mousePressEvent(QMouseEvent *event)
- {
- emit clicked();
- }
+ void mousePressEvent(QMouseEvent *event)
+ {
+ emit clicked();
+ }
};
class ClickableIconLabel : public IconLabel
{
- Q_OBJECT
+ Q_OBJECT
public:
- ClickableIconLabel(QWidget *parent, QIcon icon, QSize size) : IconLabel(parent, icon, size)
- {
- setCursor(Qt::PointingHandCursor);
- }
+ ClickableIconLabel(QWidget *parent, QIcon icon, QSize size) : IconLabel(parent, icon, size)
+ {
+ setCursor(Qt::PointingHandCursor);
+ }
- ~ClickableIconLabel(){};
+ ~ClickableIconLabel(){};
signals:
- void clicked();
+ void clicked();
protected:
- void mousePressEvent(QMouseEvent *event)
- {
- emit clicked();
- }
+ void mousePressEvent(QMouseEvent *event)
+ {
+ emit clicked();
+ }
};
ServerStatus::ServerStatus(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
{
- layout = new QHBoxLayout(this);
- layout->setContentsMargins(0, 0, 0, 0);
- goodIcon = MMC->getThemedIcon("status-good");
- yellowIcon = MMC->getThemedIcon("status-yellow");
- badIcon = MMC->getThemedIcon("status-bad");
-
- addStatus("authserver.mojang.com", tr("Auth"));
- addLine();
- addStatus("sessionserver.mojang.com", tr("Session"));
- addLine();
- addStatus("textures.minecraft.net", tr("Skins"));
- addLine();
- addStatus("api.mojang.com", tr("API"));
-
- m_statusRefresh = new QToolButton(this);
- m_statusRefresh->setCheckable(true);
- m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly);
- m_statusRefresh->setIcon(MMC->getThemedIcon("refresh"));
- layout->addWidget(m_statusRefresh);
-
- setLayout(layout);
-
- // Start status checker
- m_statusChecker.reset(new StatusChecker());
- {
- auto reloader = m_statusChecker.get();
- connect(reloader, &StatusChecker::statusChanged, this, &ServerStatus::StatusChanged);
- connect(reloader, &StatusChecker::statusLoading, this, &ServerStatus::StatusReloading);
- connect(m_statusRefresh, &QAbstractButton::clicked, this, &ServerStatus::reloadStatus);
- m_statusChecker->startTimer(60000);
- reloadStatus();
- }
+ layout = new QHBoxLayout(this);
+ layout->setContentsMargins(0, 0, 0, 0);
+ goodIcon = MMC->getThemedIcon("status-good");
+ yellowIcon = MMC->getThemedIcon("status-yellow");
+ badIcon = MMC->getThemedIcon("status-bad");
+
+ addStatus("authserver.mojang.com", tr("Auth"));
+ addLine();
+ addStatus("sessionserver.mojang.com", tr("Session"));
+ addLine();
+ addStatus("textures.minecraft.net", tr("Skins"));
+ addLine();
+ addStatus("api.mojang.com", tr("API"));
+
+ m_statusRefresh = new QToolButton(this);
+ m_statusRefresh->setCheckable(true);
+ m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly);
+ m_statusRefresh->setIcon(MMC->getThemedIcon("refresh"));
+ layout->addWidget(m_statusRefresh);
+
+ setLayout(layout);
+
+ // Start status checker
+ m_statusChecker.reset(new StatusChecker());
+ {
+ auto reloader = m_statusChecker.get();
+ connect(reloader, &StatusChecker::statusChanged, this, &ServerStatus::StatusChanged);
+ connect(reloader, &StatusChecker::statusLoading, this, &ServerStatus::StatusReloading);
+ connect(m_statusRefresh, &QAbstractButton::clicked, this, &ServerStatus::reloadStatus);
+ m_statusChecker->startTimer(60000);
+ reloadStatus();
+ }
}
ServerStatus::~ServerStatus()
@@ -97,83 +97,83 @@ ServerStatus::~ServerStatus()
void ServerStatus::reloadStatus()
{
- m_statusChecker->reloadStatus();
+ m_statusChecker->reloadStatus();
}
void ServerStatus::addLine()
{
- layout->addWidget(new LineSeparator(this, Qt::Vertical));
+ layout->addWidget(new LineSeparator(this, Qt::Vertical));
}
void ServerStatus::addStatus(QString key, QString name)
{
- {
- auto label = new ClickableIconLabel(this, badIcon, QSize(16, 16));
- label->setToolTip(key);
- serverLabels[key] = label;
- layout->addWidget(label);
- connect(label,SIGNAL(clicked()),SLOT(clicked()));
- }
- {
- auto label = new ClickableLabel(this);
- label->setText(name);
- label->setToolTip(key);
- layout->addWidget(label);
- connect(label,SIGNAL(clicked()),SLOT(clicked()));
- }
+ {
+ auto label = new ClickableIconLabel(this, badIcon, QSize(16, 16));
+ label->setToolTip(key);
+ serverLabels[key] = label;
+ layout->addWidget(label);
+ connect(label,SIGNAL(clicked()),SLOT(clicked()));
+ }
+ {
+ auto label = new ClickableLabel(this);
+ label->setText(name);
+ label->setToolTip(key);
+ layout->addWidget(label);
+ connect(label,SIGNAL(clicked()),SLOT(clicked()));
+ }
}
void ServerStatus::clicked()
{
- DesktopServices::openUrl(QUrl("https://help.mojang.com/"));
+ DesktopServices::openUrl(QUrl("https://help.mojang.com/"));
}
void ServerStatus::setStatus(QString key, int value)
{
- if (!serverLabels.contains(key))
- return;
- IconLabel *label = serverLabels[key];
- switch(value)
- {
- case 0:
- label->setIcon(goodIcon);
- break;
- case 1:
- label->setIcon(yellowIcon);
- break;
- default:
- case 2:
- label->setIcon(badIcon);
- break;
- }
+ if (!serverLabels.contains(key))
+ return;
+ IconLabel *label = serverLabels[key];
+ switch(value)
+ {
+ case 0:
+ label->setIcon(goodIcon);
+ break;
+ case 1:
+ label->setIcon(yellowIcon);
+ break;
+ default:
+ case 2:
+ label->setIcon(badIcon);
+ break;
+ }
}
void ServerStatus::StatusChanged(const QMap<QString, QString> statusEntries)
{
- auto convertStatus = [&](QString status)->int
- {
- if (status == "green")
- return 0;
- else if (status == "yellow")
- return 1;
- else if (status == "red")
- return 2;
- return 2;
- }
- ;
- auto iter = statusEntries.begin();
- while (iter != statusEntries.end())
- {
- QString key = iter.key();
- auto value = convertStatus(iter.value());
- setStatus(key, value);
- iter++;
- }
+ auto convertStatus = [&](QString status)->int
+ {
+ if (status == "green")
+ return 0;
+ else if (status == "yellow")
+ return 1;
+ else if (status == "red")
+ return 2;
+ return 2;
+ }
+ ;
+ auto iter = statusEntries.begin();
+ while (iter != statusEntries.end())
+ {
+ QString key = iter.key();
+ auto value = convertStatus(iter.value());
+ setStatus(key, value);
+ iter++;
+ }
}
void ServerStatus::StatusReloading(bool is_reloading)
{
- m_statusRefresh->setChecked(is_reloading);
+ m_statusRefresh->setChecked(is_reloading);
}
#include "ServerStatus.moc"
diff --git a/application/widgets/ServerStatus.h b/application/widgets/ServerStatus.h
index 9beb8e4f..e1e70dfb 100644
--- a/application/widgets/ServerStatus.h
+++ b/application/widgets/ServerStatus.h
@@ -12,29 +12,29 @@ class StatusChecker;
class ServerStatus: public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit ServerStatus(QWidget *parent = nullptr, Qt::WindowFlags f = 0);
- virtual ~ServerStatus();
+ explicit ServerStatus(QWidget *parent = nullptr, Qt::WindowFlags f = 0);
+ virtual ~ServerStatus();
public slots:
- void reloadStatus();
- void StatusChanged(const QMap<QString, QString> statuses);
- void StatusReloading(bool is_reloading);
+ void reloadStatus();
+ void StatusChanged(const QMap<QString, QString> statuses);
+ void StatusReloading(bool is_reloading);
private slots:
- void clicked();
+ void clicked();
private: /* methods */
- void addLine();
- void addStatus(QString key, QString name);
- void setStatus(QString key, int value);
+ void addLine();
+ void addStatus(QString key, QString name);
+ void setStatus(QString key, int value);
private: /* data */
- QHBoxLayout * layout = nullptr;
- QToolButton *m_statusRefresh = nullptr;
- QMap<QString, IconLabel *> serverLabels;
- QIcon goodIcon;
- QIcon yellowIcon;
- QIcon badIcon;
- std::shared_ptr<StatusChecker> m_statusChecker;
+ QHBoxLayout * layout = nullptr;
+ QToolButton *m_statusRefresh = nullptr;
+ QMap<QString, IconLabel *> serverLabels;
+ QIcon goodIcon;
+ QIcon yellowIcon;
+ QIcon badIcon;
+ std::shared_ptr<StatusChecker> m_statusChecker;
};
diff --git a/application/widgets/VersionListView.cpp b/application/widgets/VersionListView.cpp
index 8c80ecf3..215905f5 100644
--- a/application/widgets/VersionListView.cpp
+++ b/application/widgets/VersionListView.cpp
@@ -22,113 +22,113 @@
#include "Common.h"
VersionListView::VersionListView(QWidget *parent)
- :QTreeView ( parent )
+ :QTreeView ( parent )
{
- m_emptyString = tr("No versions are currently available.");
+ m_emptyString = tr("No versions are currently available.");
}
void VersionListView::rowsInserted(const QModelIndex &parent, int start, int end)
{
- if(!m_itemCount)
- viewport()->update();
- m_itemCount += end-start+1;
- QTreeView::rowsInserted(parent, start, end);
+ if(!m_itemCount)
+ viewport()->update();
+ m_itemCount += end-start+1;
+ QTreeView::rowsInserted(parent, start, end);
}
void VersionListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
- m_itemCount -= end-start+1;
- if(!m_itemCount)
- viewport()->update();
- QTreeView::rowsInserted(parent, start, end);
+ m_itemCount -= end-start+1;
+ if(!m_itemCount)
+ viewport()->update();
+ QTreeView::rowsInserted(parent, start, end);
}
void VersionListView::setModel(QAbstractItemModel *model)
{
- m_itemCount = model->rowCount();
- if(!m_itemCount)
- viewport()->update();
- QTreeView::setModel(model);
+ m_itemCount = model->rowCount();
+ if(!m_itemCount)
+ viewport()->update();
+ QTreeView::setModel(model);
}
void VersionListView::reset()
{
- if(model())
- {
- m_itemCount = model()->rowCount();
- }
- viewport()->update();
- QTreeView::reset();
+ if(model())
+ {
+ m_itemCount = model()->rowCount();
+ }
+ viewport()->update();
+ QTreeView::reset();
}
void VersionListView::setEmptyString(QString emptyString)
{
- m_emptyString = emptyString;
- updateEmptyViewPort();
+ m_emptyString = emptyString;
+ updateEmptyViewPort();
}
void VersionListView::setEmptyErrorString(QString emptyErrorString)
{
- m_emptyErrorString = emptyErrorString;
- updateEmptyViewPort();
+ m_emptyErrorString = emptyErrorString;
+ updateEmptyViewPort();
}
void VersionListView::setEmptyMode(VersionListView::EmptyMode mode)
{
- m_emptyMode = mode;
- updateEmptyViewPort();
+ m_emptyMode = mode;
+ updateEmptyViewPort();
}
void VersionListView::updateEmptyViewPort()
{
- if(!m_itemCount)
- {
- viewport()->update();
- }
+ if(!m_itemCount)
+ {
+ viewport()->update();
+ }
}
void VersionListView::paintEvent(QPaintEvent *event)
{
- if(m_itemCount)
- {
- QTreeView::paintEvent(event);
- }
- else
- {
- paintInfoLabel(event);
- }
+ if(m_itemCount)
+ {
+ QTreeView::paintEvent(event);
+ }
+ else
+ {
+ paintInfoLabel(event);
+ }
}
void VersionListView::paintInfoLabel(QPaintEvent *event)
{
- QString emptyString;
- switch(m_emptyMode)
- {
- case VersionListView::Empty:
- return;
- case VersionListView::String:
- emptyString = m_emptyString;
- break;
- case VersionListView::ErrorString:
- emptyString = m_emptyErrorString;
- break;
- }
+ QString emptyString;
+ switch(m_emptyMode)
+ {
+ case VersionListView::Empty:
+ return;
+ case VersionListView::String:
+ emptyString = m_emptyString;
+ break;
+ case VersionListView::ErrorString:
+ emptyString = m_emptyErrorString;
+ break;
+ }
//calculate the rect for the overlay
QPainter painter(viewport());
painter.setRenderHint(QPainter::Antialiasing, true);
- QFont font("sans", 20);
+ QFont font("sans", 20);
font.setBold(true);
-
- QRect bounds = viewport()->geometry();
- bounds.moveTop(0);
- QTextLayout layout(emptyString, font);
- qreal height = 0.0;
- qreal widthUsed = 0.0;
- QStringList lines = viewItemTextLayout(layout, bounds.width() - 20, height, widthUsed);
- QRect rect (0,0, widthUsed, height);
- rect.setWidth(rect.width()+20);
- rect.setHeight(rect.height()+20);
+
+ QRect bounds = viewport()->geometry();
+ bounds.moveTop(0);
+ QTextLayout layout(emptyString, font);
+ qreal height = 0.0;
+ qreal widthUsed = 0.0;
+ QStringList lines = viewItemTextLayout(layout, bounds.width() - 20, height, widthUsed);
+ QRect rect (0,0, widthUsed, height);
+ rect.setWidth(rect.width()+20);
+ rect.setHeight(rect.height()+20);
rect.moveCenter(bounds.center());
//check if we are allowed to draw in our area
if (!event->rect().intersects(rect)) {
@@ -137,7 +137,7 @@ void VersionListView::paintInfoLabel(QPaintEvent *event)
//draw the letter of the topmost item semitransparent in the middle
QColor background = QApplication::palette().color(QPalette::Foreground);
QColor foreground = QApplication::palette().color(QPalette::Base);
- /*
+ /*
background.setAlpha(128 - scrollFade);
foreground.setAlpha(128 - scrollFade);
*/
@@ -148,29 +148,29 @@ void VersionListView::paintInfoLabel(QPaintEvent *event)
painter.setPen(foreground);
painter.setFont(font);
painter.drawText(rect, Qt::AlignCenter, lines.join("\n"));
-
+
}
/*
void ModListView::setModel ( QAbstractItemModel* model )
{
- QTreeView::setModel ( model );
- auto head = header();
- head->setStretchLastSection(false);
- // HACK: this is true for the checkbox column of mod lists
- auto string = model->headerData(0,head->orientation()).toString();
- if(!string.size())
- {
- head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
- head->setSectionResizeMode(1, QHeaderView::Stretch);
- for(int i = 2; i < head->count(); i++)
- head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- }
- else
- {
- head->setSectionResizeMode(0, QHeaderView::Stretch);
- for(int i = 1; i < head->count(); i++)
- head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- }
+ QTreeView::setModel ( model );
+ auto head = header();
+ head->setStretchLastSection(false);
+ // HACK: this is true for the checkbox column of mod lists
+ auto string = model->headerData(0,head->orientation()).toString();
+ if(!string.size())
+ {
+ head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+ head->setSectionResizeMode(1, QHeaderView::Stretch);
+ for(int i = 2; i < head->count(); i++)
+ head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
+ }
+ else
+ {
+ head->setSectionResizeMode(0, QHeaderView::Stretch);
+ for(int i = 1; i < head->count(); i++)
+ head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
+ }
}
*/
diff --git a/application/widgets/VersionListView.h b/application/widgets/VersionListView.h
index b7a881e9..a7195b38 100644
--- a/application/widgets/VersionListView.h
+++ b/application/widgets/VersionListView.h
@@ -20,38 +20,38 @@ class Mod;
class VersionListView : public QTreeView
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit VersionListView(QWidget *parent = 0);
- virtual void paintEvent(QPaintEvent *event) override;
- virtual void setModel(QAbstractItemModel* model) override;
+ explicit VersionListView(QWidget *parent = 0);
+ virtual void paintEvent(QPaintEvent *event) override;
+ virtual void setModel(QAbstractItemModel* model) override;
- enum EmptyMode
- {
- Empty,
- String,
- ErrorString
- };
+ enum EmptyMode
+ {
+ Empty,
+ String,
+ ErrorString
+ };
- void setEmptyString(QString emptyString);
- void setEmptyErrorString(QString emptyErrorString);
- void setEmptyMode(EmptyMode mode);
+ void setEmptyString(QString emptyString);
+ void setEmptyErrorString(QString emptyErrorString);
+ void setEmptyMode(EmptyMode mode);
public slots:
- virtual void reset() override;
+ virtual void reset() override;
protected slots:
- virtual void rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end) override;
- virtual void rowsInserted(const QModelIndex &parent, int start, int end) override;
+ virtual void rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end) override;
+ virtual void rowsInserted(const QModelIndex &parent, int start, int end) override;
private: /* methods */
- void paintInfoLabel(QPaintEvent *event);
- void updateEmptyViewPort();
+ void paintInfoLabel(QPaintEvent *event);
+ void updateEmptyViewPort();
private: /* variables */
- int m_itemCount = 0;
- QString m_emptyString;
- QString m_emptyErrorString;
- EmptyMode m_emptyMode = Empty;
+ int m_itemCount = 0;
+ QString m_emptyString;
+ QString m_emptyErrorString;
+ EmptyMode m_emptyMode = Empty;
};
diff --git a/application/widgets/VersionSelectWidget.cpp b/application/widgets/VersionSelectWidget.cpp
index ce1141b6..8e7a0953 100644
--- a/application/widgets/VersionSelectWidget.cpp
+++ b/application/widgets/VersionSelectWidget.cpp
@@ -7,50 +7,50 @@
#include <dialogs/CustomMessageBox.h>
VersionSelectWidget::VersionSelectWidget(QWidget* parent)
- : QWidget(parent)
+ : QWidget(parent)
{
- setObjectName(QStringLiteral("VersionSelectWidget"));
- verticalLayout = new QVBoxLayout(this);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
- verticalLayout->setContentsMargins(0, 0, 0, 0);
+ setObjectName(QStringLiteral("VersionSelectWidget"));
+ verticalLayout = new QVBoxLayout(this);
+ verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setContentsMargins(0, 0, 0, 0);
- m_proxyModel = new VersionProxyModel(this);
+ m_proxyModel = new VersionProxyModel(this);
- listView = new VersionListView(this);
- listView->setObjectName(QStringLiteral("listView"));
- listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- listView->setAlternatingRowColors(true);
- listView->setRootIsDecorated(false);
- listView->setItemsExpandable(false);
- listView->setWordWrap(true);
- listView->header()->setCascadingSectionResizes(true);
- listView->header()->setStretchLastSection(false);
- listView->setModel(m_proxyModel);
- verticalLayout->addWidget(listView);
+ listView = new VersionListView(this);
+ listView->setObjectName(QStringLiteral("listView"));
+ listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ listView->setAlternatingRowColors(true);
+ listView->setRootIsDecorated(false);
+ listView->setItemsExpandable(false);
+ listView->setWordWrap(true);
+ listView->header()->setCascadingSectionResizes(true);
+ listView->header()->setStretchLastSection(false);
+ listView->setModel(m_proxyModel);
+ verticalLayout->addWidget(listView);
- sneakyProgressBar = new QProgressBar(this);
- sneakyProgressBar->setObjectName(QStringLiteral("sneakyProgressBar"));
- sneakyProgressBar->setFormat(QStringLiteral("%p%"));
- verticalLayout->addWidget(sneakyProgressBar);
- sneakyProgressBar->setHidden(true);
- connect(listView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &VersionSelectWidget::currentRowChanged);
+ sneakyProgressBar = new QProgressBar(this);
+ sneakyProgressBar->setObjectName(QStringLiteral("sneakyProgressBar"));
+ sneakyProgressBar->setFormat(QStringLiteral("%p%"));
+ verticalLayout->addWidget(sneakyProgressBar);
+ sneakyProgressBar->setHidden(true);
+ connect(listView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &VersionSelectWidget::currentRowChanged);
- QMetaObject::connectSlotsByName(this);
+ QMetaObject::connectSlotsByName(this);
}
void VersionSelectWidget::setCurrentVersion(const QString& version)
{
- m_currentVersion = version;
+ m_currentVersion = version;
}
void VersionSelectWidget::setEmptyString(QString emptyString)
{
- listView->setEmptyString(emptyString);
+ listView->setEmptyString(emptyString);
}
void VersionSelectWidget::setEmptyErrorString(QString emptyErrorString)
{
- listView->setEmptyErrorString(emptyErrorString);
+ listView->setEmptyErrorString(emptyErrorString);
}
VersionSelectWidget::~VersionSelectWidget()
@@ -59,143 +59,143 @@ VersionSelectWidget::~VersionSelectWidget()
void VersionSelectWidget::setResizeOn(int column)
{
- listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::ResizeToContents);
- resizeOnColumn = column;
- listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch);
+ listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::ResizeToContents);
+ resizeOnColumn = column;
+ listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch);
}
void VersionSelectWidget::initialize(BaseVersionList *vlist)
{
- m_vlist = vlist;
- m_proxyModel->setSourceModel(vlist);
- listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
- listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch);
-
- if (!m_vlist->isLoaded())
- {
- loadList();
- }
- else
- {
- if (m_proxyModel->rowCount() == 0)
- {
- listView->setEmptyMode(VersionListView::String);
- }
- preselect();
- }
+ m_vlist = vlist;
+ m_proxyModel->setSourceModel(vlist);
+ listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch);
+
+ if (!m_vlist->isLoaded())
+ {
+ loadList();
+ }
+ else
+ {
+ if (m_proxyModel->rowCount() == 0)
+ {
+ listView->setEmptyMode(VersionListView::String);
+ }
+ preselect();
+ }
}
void VersionSelectWidget::closeEvent(QCloseEvent * event)
{
- QWidget::closeEvent(event);
+ QWidget::closeEvent(event);
}
void VersionSelectWidget::loadList()
{
- auto newTask = m_vlist->getLoadTask();
- if (!newTask)
- {
- return;
- }
- loadTask = newTask.get();
- connect(loadTask, &Task::succeeded, this, &VersionSelectWidget::onTaskSucceeded);
- connect(loadTask, &Task::failed, this, &VersionSelectWidget::onTaskFailed);
- connect(loadTask, &Task::progress, this, &VersionSelectWidget::changeProgress);
- if(!loadTask->isRunning())
- {
- loadTask->start();
- }
- sneakyProgressBar->setHidden(false);
+ auto newTask = m_vlist->getLoadTask();
+ if (!newTask)
+ {
+ return;
+ }
+ loadTask = newTask.get();
+ connect(loadTask, &Task::succeeded, this, &VersionSelectWidget::onTaskSucceeded);
+ connect(loadTask, &Task::failed, this, &VersionSelectWidget::onTaskFailed);
+ connect(loadTask, &Task::progress, this, &VersionSelectWidget::changeProgress);
+ if(!loadTask->isRunning())
+ {
+ loadTask->start();
+ }
+ sneakyProgressBar->setHidden(false);
}
void VersionSelectWidget::onTaskSucceeded()
{
- if (m_proxyModel->rowCount() == 0)
- {
- listView->setEmptyMode(VersionListView::String);
- }
- sneakyProgressBar->setHidden(true);
- preselect();
- loadTask = nullptr;
+ if (m_proxyModel->rowCount() == 0)
+ {
+ listView->setEmptyMode(VersionListView::String);
+ }
+ sneakyProgressBar->setHidden(true);
+ preselect();
+ loadTask = nullptr;
}
void VersionSelectWidget::onTaskFailed(const QString& reason)
{
- CustomMessageBox::selectable(this, tr("Error"), tr("List update failed:\n%1").arg(reason), QMessageBox::Warning)->show();
- onTaskSucceeded();
+ CustomMessageBox::selectable(this, tr("Error"), tr("List update failed:\n%1").arg(reason), QMessageBox::Warning)->show();
+ onTaskSucceeded();
}
void VersionSelectWidget::changeProgress(qint64 current, qint64 total)
{
- sneakyProgressBar->setMaximum(total);
- sneakyProgressBar->setValue(current);
+ sneakyProgressBar->setMaximum(total);
+ sneakyProgressBar->setValue(current);
}
void VersionSelectWidget::currentRowChanged(const QModelIndex& current, const QModelIndex&)
{
- auto variant = m_proxyModel->data(current, BaseVersionList::VersionPointerRole);
- emit selectedVersionChanged(variant.value<BaseVersionPtr>());
+ auto variant = m_proxyModel->data(current, BaseVersionList::VersionPointerRole);
+ emit selectedVersionChanged(variant.value<BaseVersionPtr>());
}
void VersionSelectWidget::preselect()
{
- if(preselectedAlready)
- return;
- selectCurrent();
- if(preselectedAlready)
- return;
- selectRecommended();
+ if(preselectedAlready)
+ return;
+ selectCurrent();
+ if(preselectedAlready)
+ return;
+ selectRecommended();
}
void VersionSelectWidget::selectCurrent()
{
- if(m_currentVersion.isEmpty())
- {
- return;
- }
- auto idx = m_proxyModel->getVersion(m_currentVersion);
- if(idx.isValid())
- {
- preselectedAlready = true;
- listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
- listView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
- }
+ if(m_currentVersion.isEmpty())
+ {
+ return;
+ }
+ auto idx = m_proxyModel->getVersion(m_currentVersion);
+ if(idx.isValid())
+ {
+ preselectedAlready = true;
+ listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
+ listView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
+ }
}
void VersionSelectWidget::selectRecommended()
{
- auto idx = m_proxyModel->getRecommended();
- if(idx.isValid())
- {
- preselectedAlready = true;
- listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
- listView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
- }
+ auto idx = m_proxyModel->getRecommended();
+ if(idx.isValid())
+ {
+ preselectedAlready = true;
+ listView->selectionModel()->setCurrentIndex(idx,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
+ listView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
+ }
}
bool VersionSelectWidget::hasVersions() const
{
- return m_proxyModel->rowCount(QModelIndex()) != 0;
+ return m_proxyModel->rowCount(QModelIndex()) != 0;
}
BaseVersionPtr VersionSelectWidget::selectedVersion() const
{
- auto currentIndex = listView->selectionModel()->currentIndex();
- auto variant = m_proxyModel->data(currentIndex, BaseVersionList::VersionPointerRole);
- return variant.value<BaseVersionPtr>();
+ auto currentIndex = listView->selectionModel()->currentIndex();
+ auto variant = m_proxyModel->data(currentIndex, BaseVersionList::VersionPointerRole);
+ return variant.value<BaseVersionPtr>();
}
void VersionSelectWidget::setExactFilter(BaseVersionList::ModelRoles role, QString filter)
{
- m_proxyModel->setFilter(role, new ExactFilter(filter));
+ m_proxyModel->setFilter(role, new ExactFilter(filter));
}
void VersionSelectWidget::setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter)
{
- m_proxyModel->setFilter(role, new ContainsFilter(filter));
+ m_proxyModel->setFilter(role, new ContainsFilter(filter));
}
void VersionSelectWidget::setFilter(BaseVersionList::ModelRoles role, Filter *filter)
{
- m_proxyModel->setFilter(role, filter);
+ m_proxyModel->setFilter(role, filter);
}
diff --git a/application/widgets/VersionSelectWidget.h b/application/widgets/VersionSelectWidget.h
index c134887f..32b56c60 100644
--- a/application/widgets/VersionSelectWidget.h
+++ b/application/widgets/VersionSelectWidget.h
@@ -27,55 +27,55 @@ class Filter;
class VersionSelectWidget: public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit VersionSelectWidget(QWidget *parent = 0);
- ~VersionSelectWidget();
+ explicit VersionSelectWidget(QWidget *parent = 0);
+ ~VersionSelectWidget();
- //! loads the list if needed.
- void initialize(BaseVersionList *vlist);
+ //! loads the list if needed.
+ void initialize(BaseVersionList *vlist);
- //! Starts a task that loads the list.
- void loadList();
+ //! Starts a task that loads the list.
+ void loadList();
- bool hasVersions() const;
- BaseVersionPtr selectedVersion() const;
- void selectRecommended();
- void selectCurrent();
+ bool hasVersions() const;
+ BaseVersionPtr selectedVersion() const;
+ void selectRecommended();
+ void selectCurrent();
- void setCurrentVersion(const QString & version);
- void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter);
- void setExactFilter(BaseVersionList::ModelRoles role, QString filter);
- void setFilter(BaseVersionList::ModelRoles role, Filter *filter);
- void setEmptyString(QString emptyString);
- void setEmptyErrorString(QString emptyErrorString);
- void setResizeOn(int column);
+ void setCurrentVersion(const QString & version);
+ void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter);
+ void setExactFilter(BaseVersionList::ModelRoles role, QString filter);
+ void setFilter(BaseVersionList::ModelRoles role, Filter *filter);
+ void setEmptyString(QString emptyString);
+ void setEmptyErrorString(QString emptyErrorString);
+ void setResizeOn(int column);
signals:
- void selectedVersionChanged(BaseVersionPtr version);
+ void selectedVersionChanged(BaseVersionPtr version);
protected:
- virtual void closeEvent ( QCloseEvent* );
+ virtual void closeEvent ( QCloseEvent* );
private slots:
- void onTaskSucceeded();
- void onTaskFailed(const QString &reason);
- void changeProgress(qint64 current, qint64 total);
- void currentRowChanged(const QModelIndex &current, const QModelIndex &);
+ void onTaskSucceeded();
+ void onTaskFailed(const QString &reason);
+ void changeProgress(qint64 current, qint64 total);
+ void currentRowChanged(const QModelIndex &current, const QModelIndex &);
private:
- void preselect();
+ void preselect();
private:
- QString m_currentVersion;
- BaseVersionList *m_vlist = nullptr;
- VersionProxyModel *m_proxyModel = nullptr;
- int resizeOnColumn = 0;
- Task * loadTask;
- bool preselectedAlready = false;
+ QString m_currentVersion;
+ BaseVersionList *m_vlist = nullptr;
+ VersionProxyModel *m_proxyModel = nullptr;
+ int resizeOnColumn = 0;
+ Task * loadTask;
+ bool preselectedAlready = false;
private:
- QVBoxLayout *verticalLayout = nullptr;
- VersionListView *listView = nullptr;
- QProgressBar *sneakyProgressBar = nullptr;
+ QVBoxLayout *verticalLayout = nullptr;
+ VersionListView *listView = nullptr;
+ QProgressBar *sneakyProgressBar = nullptr;
};
diff --git a/libraries/LocalPeer/CMakeLists.txt b/libraries/LocalPeer/CMakeLists.txt
index 3d2a1e62..f476da38 100644
--- a/libraries/LocalPeer/CMakeLists.txt
+++ b/libraries/LocalPeer/CMakeLists.txt
@@ -12,15 +12,15 @@ include/LocalPeer.h
)
if(UNIX)
- list(APPEND SINGLE_SOURCES
- src/LockedFile_unix.cpp
- )
+ list(APPEND SINGLE_SOURCES
+ src/LockedFile_unix.cpp
+ )
endif()
if(WIN32)
- list(APPEND SINGLE_SOURCES
- src/LockedFile_win.cpp
- )
+ list(APPEND SINGLE_SOURCES
+ src/LockedFile_win.cpp
+ )
endif()
add_library(LocalPeer STATIC ${SINGLE_SOURCES})
diff --git a/libraries/LocalPeer/include/LocalPeer.h b/libraries/LocalPeer/include/LocalPeer.h
index 7558f18e..a24e4775 100644
--- a/libraries/LocalPeer/include/LocalPeer.h
+++ b/libraries/LocalPeer/include/LocalPeer.h
@@ -50,51 +50,51 @@ class LockedFile;
class ApplicationId
{
public: /* methods */
- // traditional app = installed system wide and used in a multi-user environment
- static ApplicationId fromTraditionalApp();
- // ID based on a path with all the application data (no two instances with the same data path should run)
- static ApplicationId fromPathAndVersion(const QString & dataPath, const QString & version);
- // custom ID
- static ApplicationId fromCustomId(const QString & id);
- // custom ID, based on a raw string previously acquired from 'toString'
- static ApplicationId fromRawString(const QString & id);
+ // traditional app = installed system wide and used in a multi-user environment
+ static ApplicationId fromTraditionalApp();
+ // ID based on a path with all the application data (no two instances with the same data path should run)
+ static ApplicationId fromPathAndVersion(const QString & dataPath, const QString & version);
+ // custom ID
+ static ApplicationId fromCustomId(const QString & id);
+ // custom ID, based on a raw string previously acquired from 'toString'
+ static ApplicationId fromRawString(const QString & id);
- QString toString()
- {
- return m_id;
- }
+ QString toString()
+ {
+ return m_id;
+ }
private: /* methods */
- ApplicationId(const QString & value)
- {
- m_id = value;
- }
+ ApplicationId(const QString & value)
+ {
+ m_id = value;
+ }
private: /* data */
- QString m_id;
+ QString m_id;
};
class LocalPeer : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- LocalPeer(QObject *parent, const ApplicationId &appId);
- ~LocalPeer();
- bool isClient();
- bool sendMessage(const QString &message, int timeout);
- ApplicationId applicationId() const;
+ LocalPeer(QObject *parent, const ApplicationId &appId);
+ ~LocalPeer();
+ bool isClient();
+ bool sendMessage(const QString &message, int timeout);
+ ApplicationId applicationId() const;
Q_SIGNALS:
- void messageReceived(const QString &message);
+ void messageReceived(const QString &message);
protected Q_SLOTS:
- void receiveConnection();
+ void receiveConnection();
protected:
- ApplicationId id;
- QString socketName;
- std::unique_ptr<QLocalServer> server;
- std::unique_ptr<LockedFile> lockFile;
+ ApplicationId id;
+ QString socketName;
+ std::unique_ptr<QLocalServer> server;
+ std::unique_ptr<LockedFile> lockFile;
};
diff --git a/libraries/LocalPeer/src/LocalPeer.cpp b/libraries/LocalPeer/src/LocalPeer.cpp
index f71c62d8..129f3abc 100644
--- a/libraries/LocalPeer/src/LocalPeer.cpp
+++ b/libraries/LocalPeer/src/LocalPeer.cpp
@@ -67,60 +67,60 @@ static const char* ack = "ack";
ApplicationId ApplicationId::fromTraditionalApp()
{
- QString protoId = QCoreApplication::applicationFilePath();
+ QString protoId = QCoreApplication::applicationFilePath();
#if defined(Q_OS_WIN)
- protoId = protoId.toLower();
+ protoId = protoId.toLower();
#endif
- auto prefix = protoId.section(QLatin1Char('/'), -1);
- prefix.remove(QRegExp("[^a-zA-Z]"));
- prefix.truncate(6);
- QByteArray idc = protoId.toUtf8();
- quint16 idNum = qChecksum(idc.constData(), idc.size());
- auto socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16);
+ auto prefix = protoId.section(QLatin1Char('/'), -1);
+ prefix.remove(QRegExp("[^a-zA-Z]"));
+ prefix.truncate(6);
+ QByteArray idc = protoId.toUtf8();
+ quint16 idNum = qChecksum(idc.constData(), idc.size());
+ auto socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16);
#if defined(Q_OS_WIN)
- if (!pProcessIdToSessionId)
- {
- QLibrary lib("kernel32");
- pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
- }
- if (pProcessIdToSessionId)
- {
- DWORD sessionId = 0;
- pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
- socketName += QLatin1Char('-') + QString::number(sessionId, 16);
- }
+ if (!pProcessIdToSessionId)
+ {
+ QLibrary lib("kernel32");
+ pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
+ }
+ if (pProcessIdToSessionId)
+ {
+ DWORD sessionId = 0;
+ pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
+ socketName += QLatin1Char('-') + QString::number(sessionId, 16);
+ }
#else
- socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
+ socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
#endif
- return ApplicationId(socketName);
+ return ApplicationId(socketName);
}
ApplicationId ApplicationId::fromPathAndVersion(const QString& dataPath, const QString& version)
{
- QCryptographicHash shasum(QCryptographicHash::Algorithm::Sha1);
- QString result = dataPath + QLatin1Char('-') + version;
- shasum.addData(result.toUtf8());
- return ApplicationId(QLatin1String("qtsingleapp-") + QString::fromLatin1(shasum.result().toHex()));
+ QCryptographicHash shasum(QCryptographicHash::Algorithm::Sha1);
+ QString result = dataPath + QLatin1Char('-') + version;
+ shasum.addData(result.toUtf8());
+ return ApplicationId(QLatin1String("qtsingleapp-") + QString::fromLatin1(shasum.result().toHex()));
}
ApplicationId ApplicationId::fromCustomId(const QString& id)
{
- return ApplicationId(QLatin1String("qtsingleapp-") + id);
+ return ApplicationId(QLatin1String("qtsingleapp-") + id);
}
ApplicationId ApplicationId::fromRawString(const QString& id)
{
- return ApplicationId(id);
+ return ApplicationId(id);
}
LocalPeer::LocalPeer(QObject * parent, const ApplicationId &appId)
- : QObject(parent), id(appId)
+ : QObject(parent), id(appId)
{
- socketName = id.toString();
- server.reset(new QLocalServer());
- QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile");
- lockFile.reset(new LockedFile(lockName));
- lockFile->open(QIODevice::ReadWrite);
+ socketName = id.toString();
+ server.reset(new QLocalServer());
+ QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile");
+ lockFile.reset(new LockedFile(lockName));
+ lockFile->open(QIODevice::ReadWrite);
}
LocalPeer::~LocalPeer()
@@ -129,113 +129,113 @@ LocalPeer::~LocalPeer()
ApplicationId LocalPeer::applicationId() const
{
- return id;
+ return id;
}
bool LocalPeer::isClient()
{
- if (lockFile->isLocked())
- return false;
+ if (lockFile->isLocked())
+ return false;
- if (!lockFile->lock(LockedFile::WriteLock, false))
- return true;
+ if (!lockFile->lock(LockedFile::WriteLock, false))
+ return true;
- bool res = server->listen(socketName);
+ bool res = server->listen(socketName);
#if defined(Q_OS_UNIX)
- // ### Workaround
- if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
- QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
- res = server->listen(socketName);
- }
+ // ### Workaround
+ if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
+ QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
+ res = server->listen(socketName);
+ }
#endif
- if (!res)
- qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
- QObject::connect(server.get(), SIGNAL(newConnection()), SLOT(receiveConnection()));
- return false;
+ if (!res)
+ qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
+ QObject::connect(server.get(), SIGNAL(newConnection()), SLOT(receiveConnection()));
+ return false;
}
bool LocalPeer::sendMessage(const QString &message, int timeout)
{
- if (!isClient())
- return false;
-
- QLocalSocket socket;
- bool connOk = false;
- for(int i = 0; i < 2; i++) {
- // Try twice, in case the other instance is just starting up
- socket.connectToServer(socketName);
- connOk = socket.waitForConnected(timeout/2);
- if (connOk || i)
- {
- break;
- }
- std::this_thread::sleep_for(std::chrono::milliseconds(250));
- }
- if (!connOk)
- {
- return false;
- }
-
- QByteArray uMsg(message.toUtf8());
- QDataStream ds(&socket);
-
- ds.writeBytes(uMsg.constData(), uMsg.size());
- if(!socket.waitForBytesWritten(timeout))
- {
- return false;
- }
-
- // wait for 'ack'
- if(!socket.waitForReadyRead(timeout))
- {
- return false;
- }
-
- // make sure we got 'ack'
- if(!(socket.read(qstrlen(ack)) == ack))
- {
- return false;
- }
- return true;
+ if (!isClient())
+ return false;
+
+ QLocalSocket socket;
+ bool connOk = false;
+ for(int i = 0; i < 2; i++) {
+ // Try twice, in case the other instance is just starting up
+ socket.connectToServer(socketName);
+ connOk = socket.waitForConnected(timeout/2);
+ if (connOk || i)
+ {
+ break;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ }
+ if (!connOk)
+ {
+ return false;
+ }
+
+ QByteArray uMsg(message.toUtf8());
+ QDataStream ds(&socket);
+
+ ds.writeBytes(uMsg.constData(), uMsg.size());
+ if(!socket.waitForBytesWritten(timeout))
+ {
+ return false;
+ }
+
+ // wait for 'ack'
+ if(!socket.waitForReadyRead(timeout))
+ {
+ return false;
+ }
+
+ // make sure we got 'ack'
+ if(!(socket.read(qstrlen(ack)) == ack))
+ {
+ return false;
+ }
+ return true;
}
void LocalPeer::receiveConnection()
{
- QLocalSocket* socket = server->nextPendingConnection();
- if (!socket)
- {
- return;
- }
-
- while (socket->bytesAvailable() < (int)sizeof(quint32))
- {
- socket->waitForReadyRead();
- }
- QDataStream ds(socket);
- QByteArray uMsg;
- quint32 remaining;
- ds >> remaining;
- uMsg.resize(remaining);
- int got = 0;
- char* uMsgBuf = uMsg.data();
- do
- {
- got = ds.readRawData(uMsgBuf, remaining);
- remaining -= got;
- uMsgBuf += got;
- } while (remaining && got >= 0 && socket->waitForReadyRead(2000));
- if (got < 0)
- {
- qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
- delete socket;
- return;
- }
- QString message(QString::fromUtf8(uMsg));
- socket->write(ack, qstrlen(ack));
- socket->waitForBytesWritten(1000);
- socket->waitForDisconnected(1000); // make sure client reads ack
- delete socket;
- emit messageReceived(message); //### (might take a long time to return)
+ QLocalSocket* socket = server->nextPendingConnection();
+ if (!socket)
+ {
+ return;
+ }
+
+ while (socket->bytesAvailable() < (int)sizeof(quint32))
+ {
+ socket->waitForReadyRead();
+ }
+ QDataStream ds(socket);
+ QByteArray uMsg;
+ quint32 remaining;
+ ds >> remaining;
+ uMsg.resize(remaining);
+ int got = 0;
+ char* uMsgBuf = uMsg.data();
+ do
+ {
+ got = ds.readRawData(uMsgBuf, remaining);
+ remaining -= got;
+ uMsgBuf += got;
+ } while (remaining && got >= 0 && socket->waitForReadyRead(2000));
+ if (got < 0)
+ {
+ qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
+ delete socket;
+ return;
+ }
+ QString message(QString::fromUtf8(uMsg));
+ socket->write(ack, qstrlen(ack));
+ socket->waitForBytesWritten(1000);
+ socket->waitForDisconnected(1000); // make sure client reads ack
+ delete socket;
+ emit messageReceived(message); //### (might take a long time to return)
}
diff --git a/libraries/LocalPeer/src/LockedFile.cpp b/libraries/LocalPeer/src/LockedFile.cpp
index a4951bfe..73294a16 100644
--- a/libraries/LocalPeer/src/LockedFile.cpp
+++ b/libraries/LocalPeer/src/LockedFile.cpp
@@ -41,70 +41,70 @@
#include "LockedFile.h"
/*!
- \class QtLockedFile
-
- \brief The QtLockedFile class extends QFile with advisory locking
- functions.
-
- A file may be locked in read or write mode. Multiple instances of
- \e QtLockedFile, created in multiple processes running on the same
- machine, may have a file locked in read mode. Exactly one instance
- may have it locked in write mode. A read and a write lock cannot
- exist simultaneously on the same file.
-
- The file locks are advisory. This means that nothing prevents
- another process from manipulating a locked file using QFile or
- file system functions offered by the OS. Serialization is only
- guaranteed if all processes that access the file use
- QLockedFile. Also, while holding a lock on a file, a process
- must not open the same file again (through any API), or locks
- can be unexpectedly lost.
-
- The lock provided by an instance of \e QtLockedFile is released
- whenever the program terminates. This is true even when the
- program crashes and no destructors are called.
+ \class QtLockedFile
+
+ \brief The QtLockedFile class extends QFile with advisory locking
+ functions.
+
+ A file may be locked in read or write mode. Multiple instances of
+ \e QtLockedFile, created in multiple processes running on the same
+ machine, may have a file locked in read mode. Exactly one instance
+ may have it locked in write mode. A read and a write lock cannot
+ exist simultaneously on the same file.
+
+ The file locks are advisory. This means that nothing prevents
+ another process from manipulating a locked file using QFile or
+ file system functions offered by the OS. Serialization is only
+ guaranteed if all processes that access the file use
+ QLockedFile. Also, while holding a lock on a file, a process
+ must not open the same file again (through any API), or locks
+ can be unexpectedly lost.
+
+ The lock provided by an instance of \e QtLockedFile is released
+ whenever the program terminates. This is true even when the
+ program crashes and no destructors are called.
*/
/*! \enum QtLockedFile::LockMode
- This enum describes the available lock modes.
+ This enum describes the available lock modes.
- \value ReadLock A read lock.
- \value WriteLock A write lock.
- \value NoLock Neither a read lock nor a write lock.
+ \value ReadLock A read lock.
+ \value WriteLock A write lock.
+ \value NoLock Neither a read lock nor a write lock.
*/
/*!
- Constructs an unlocked \e QtLockedFile object. This constructor
- behaves in the same way as \e QFile::QFile().
+ Constructs an unlocked \e QtLockedFile object. This constructor
+ behaves in the same way as \e QFile::QFile().
- \sa QFile::QFile()
+ \sa QFile::QFile()
*/
LockedFile::LockedFile()
- : QFile()
+ : QFile()
{
#ifdef Q_OS_WIN
- wmutex = 0;
- rmutex = 0;
+ wmutex = 0;
+ rmutex = 0;
#endif
- m_lock_mode = NoLock;
+ m_lock_mode = NoLock;
}
/*!
- Constructs an unlocked QtLockedFile object with file \a name. This
- constructor behaves in the same way as \e QFile::QFile(const
- QString&).
+ Constructs an unlocked QtLockedFile object with file \a name. This
+ constructor behaves in the same way as \e QFile::QFile(const
+ QString&).
- \sa QFile::QFile()
+ \sa QFile::QFile()
*/
LockedFile::LockedFile(const QString &name)
- : QFile(name)
+ : QFile(name)
{
#ifdef Q_OS_WIN
- wmutex = 0;
- rmutex = 0;
+ wmutex = 0;
+ rmutex = 0;
#endif
- m_lock_mode = NoLock;
+ m_lock_mode = NoLock;
}
/*!
@@ -122,72 +122,72 @@ Returns true if successful; otherwise false.
*/
bool LockedFile::open(OpenMode mode)
{
- if (mode & QIODevice::Truncate) {
- qWarning("QtLockedFile::open(): Truncate mode not allowed.");
- return false;
- }
- return QFile::open(mode);
+ if (mode & QIODevice::Truncate) {
+ qWarning("QtLockedFile::open(): Truncate mode not allowed.");
+ return false;
+ }
+ return QFile::open(mode);
}
/*!
- Returns \e true if this object has a in read or write lock;
- otherwise returns \e false.
+ Returns \e true if this object has a in read or write lock;
+ otherwise returns \e false.
- \sa lockMode()
+ \sa lockMode()
*/
bool LockedFile::isLocked() const
{
- return m_lock_mode != NoLock;
+ return m_lock_mode != NoLock;
}
/*!
- Returns the type of lock currently held by this object, or \e
- QtLockedFile::NoLock.
+ Returns the type of lock currently held by this object, or \e
+ QtLockedFile::NoLock.
- \sa isLocked()
+ \sa isLocked()
*/
LockedFile::LockMode LockedFile::lockMode() const
{
- return m_lock_mode;
+ return m_lock_mode;
}
/*!
- \fn bool QtLockedFile::lock(LockMode mode, bool block = true)
+ \fn bool QtLockedFile::lock(LockMode mode, bool block = true)
- Obtains a lock of type \a mode. The file must be opened before it
- can be locked.
+ Obtains a lock of type \a mode. The file must be opened before it
+ can be locked.
- If \a block is true, this function will block until the lock is
- aquired. If \a block is false, this function returns \e false
- immediately if the lock cannot be aquired.
+ If \a block is true, this function will block until the lock is
+ aquired. If \a block is false, this function returns \e false
+ immediately if the lock cannot be aquired.
- If this object already has a lock of type \a mode, this function
- returns \e true immediately. If this object has a lock of a
- different type than \a mode, the lock is first released and then a
- new lock is obtained.
+ If this object already has a lock of type \a mode, this function
+ returns \e true immediately. If this object has a lock of a
+ different type than \a mode, the lock is first released and then a
+ new lock is obtained.
- This function returns \e true if, after it executes, the file is
- locked by this object, and \e false otherwise.
+ This function returns \e true if, after it executes, the file is
+ locked by this object, and \e false otherwise.
- \sa unlock(), isLocked(), lockMode()
+ \sa unlock(), isLocked(), lockMode()
*/
/*!
- \fn bool QtLockedFile::unlock()
+ \fn bool QtLockedFile::unlock()
- Releases a lock.
+ Releases a lock.
- If the object has no lock, this function returns immediately.
+ If the object has no lock, this function returns immediately.
- This function returns \e true if, after it executes, the file is
- not locked by this object, and \e false otherwise.
+ This function returns \e true if, after it executes, the file is
+ not locked by this object, and \e false otherwise.
- \sa lock(), isLocked(), lockMode()
+ \sa lock(), isLocked(), lockMode()
*/
/*!
- \fn QtLockedFile::~QtLockedFile()
+ \fn QtLockedFile::~QtLockedFile()
- Destroys the \e QtLockedFile object. If any locks were held, they
- are released.
+ Destroys the \e QtLockedFile object. If any locks were held, they
+ are released.
*/
diff --git a/libraries/LocalPeer/src/LockedFile.h b/libraries/LocalPeer/src/LockedFile.h
index 8c178250..2f29ee20 100644
--- a/libraries/LocalPeer/src/LockedFile.h
+++ b/libraries/LocalPeer/src/LockedFile.h
@@ -48,30 +48,30 @@
class LockedFile : public QFile
{
public:
- enum LockMode { NoLock = 0, ReadLock, WriteLock };
+ enum LockMode { NoLock = 0, ReadLock, WriteLock };
- LockedFile();
- LockedFile(const QString &name);
- ~LockedFile();
+ LockedFile();
+ LockedFile(const QString &name);
+ ~LockedFile();
- bool open(OpenMode mode);
+ bool open(OpenMode mode);
- bool lock(LockMode mode, bool block = true);
- bool unlock();
- bool isLocked() const;
- LockMode lockMode() const;
+ bool lock(LockMode mode, bool block = true);
+ bool unlock();
+ bool isLocked() const;
+ LockMode lockMode() const;
- private:
+ private:
#ifdef Q_OS_WIN
- Qt::HANDLE wmutex;
- Qt::HANDLE rmutex;
- QVector<Qt::HANDLE> rmutexes;
- QString mutexname;
+ Qt::HANDLE wmutex;
+ Qt::HANDLE rmutex;
+ QVector<Qt::HANDLE> rmutexes;
+ QString mutexname;
- Qt::HANDLE getMutexHandle(int idx, bool doCreate);
- bool waitMutex(Qt::HANDLE mutex, bool doBlock);
+ Qt::HANDLE getMutexHandle(int idx, bool doCreate);
+ bool waitMutex(Qt::HANDLE mutex, bool doBlock);
#endif
- LockMode m_lock_mode;
+ LockMode m_lock_mode;
};
diff --git a/libraries/LocalPeer/src/LockedFile_unix.cpp b/libraries/LocalPeer/src/LockedFile_unix.cpp
index 4b68916c..6becc89e 100644
--- a/libraries/LocalPeer/src/LockedFile_unix.cpp
+++ b/libraries/LocalPeer/src/LockedFile_unix.cpp
@@ -47,68 +47,68 @@
bool LockedFile::lock(LockMode mode, bool block)
{
- if (!isOpen()) {
- qWarning("QtLockedFile::lock(): file is not opened");
- return false;
- }
+ if (!isOpen()) {
+ qWarning("QtLockedFile::lock(): file is not opened");
+ return false;
+ }
- if (mode == NoLock)
- return unlock();
+ if (mode == NoLock)
+ return unlock();
- if (mode == m_lock_mode)
- return true;
+ if (mode == m_lock_mode)
+ return true;
- if (m_lock_mode != NoLock)
- unlock();
+ if (m_lock_mode != NoLock)
+ unlock();
- struct flock fl;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
- int cmd = block ? F_SETLKW : F_SETLK;
- int ret = fcntl(handle(), cmd, &fl);
+ struct flock fl;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
+ int cmd = block ? F_SETLKW : F_SETLK;
+ int ret = fcntl(handle(), cmd, &fl);
- if (ret == -1) {
- if (errno != EINTR && errno != EAGAIN)
- qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
- return false;
- }
+ if (ret == -1) {
+ if (errno != EINTR && errno != EAGAIN)
+ qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
+ return false;
+ }
- m_lock_mode = mode;
- return true;
+ m_lock_mode = mode;
+ return true;
}
bool LockedFile::unlock()
{
- if (!isOpen()) {
- qWarning("QtLockedFile::unlock(): file is not opened");
- return false;
- }
-
- if (!isLocked())
- return true;
-
- struct flock fl;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_type = F_UNLCK;
- int ret = fcntl(handle(), F_SETLKW, &fl);
-
- if (ret == -1) {
- qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
- return false;
- }
-
- m_lock_mode = NoLock;
- return true;
+ if (!isOpen()) {
+ qWarning("QtLockedFile::unlock(): file is not opened");
+ return false;
+ }
+
+ if (!isLocked())
+ return true;
+
+ struct flock fl;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_type = F_UNLCK;
+ int ret = fcntl(handle(), F_SETLKW, &fl);
+
+ if (ret == -1) {
+ qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
+ return false;
+ }
+
+ m_lock_mode = NoLock;
+ return true;
}
LockedFile::~LockedFile()
{
- if (isOpen())
- unlock();
+ if (isOpen())
+ unlock();
}
diff --git a/libraries/LocalPeer/src/LockedFile_win.cpp b/libraries/LocalPeer/src/LockedFile_win.cpp
index 31238190..93d2c73b 100644
--- a/libraries/LocalPeer/src/LockedFile_win.cpp
+++ b/libraries/LocalPeer/src/LockedFile_win.cpp
@@ -48,158 +48,158 @@
Qt::HANDLE LockedFile::getMutexHandle(int idx, bool doCreate)
{
- if (mutexname.isEmpty()) {
- QFileInfo fi(*this);
- mutexname = QString::fromLatin1(MUTEX_PREFIX)
- + fi.absoluteFilePath().toLower();
- }
- QString mname(mutexname);
- if (idx >= 0)
- mname += QString::number(idx);
-
- Qt::HANDLE mutex;
- if (doCreate) {
- mutex = CreateMutexW(NULL, FALSE, (LPCWSTR)mname.utf16());
- if (!mutex) {
- qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
- return 0;
- }
- }
- else {
- mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (LPCWSTR)mname.utf16());
- if (!mutex) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND)
- qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
- return 0;
- }
- }
- return mutex;
+ if (mutexname.isEmpty()) {
+ QFileInfo fi(*this);
+ mutexname = QString::fromLatin1(MUTEX_PREFIX)
+ + fi.absoluteFilePath().toLower();
+ }
+ QString mname(mutexname);
+ if (idx >= 0)
+ mname += QString::number(idx);
+
+ Qt::HANDLE mutex;
+ if (doCreate) {
+ mutex = CreateMutexW(NULL, FALSE, (LPCWSTR)mname.utf16());
+ if (!mutex) {
+ qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
+ return 0;
+ }
+ }
+ else {
+ mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (LPCWSTR)mname.utf16());
+ if (!mutex) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
+ return 0;
+ }
+ }
+ return mutex;
}
bool LockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock)
{
- Q_ASSERT(mutex);
- DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
- switch (res) {
- case WAIT_OBJECT_0:
- case WAIT_ABANDONED:
- return true;
- break;
- case WAIT_TIMEOUT:
- break;
- default:
- qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed");
- }
- return false;
+ Q_ASSERT(mutex);
+ DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
+ switch (res) {
+ case WAIT_OBJECT_0:
+ case WAIT_ABANDONED:
+ return true;
+ break;
+ case WAIT_TIMEOUT:
+ break;
+ default:
+ qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed");
+ }
+ return false;
}
bool LockedFile::lock(LockMode mode, bool block)
{
- if (!isOpen()) {
- qWarning("QtLockedFile::lock(): file is not opened");
- return false;
- }
-
- if (mode == NoLock)
- return unlock();
-
- if (mode == m_lock_mode)
- return true;
-
- if (m_lock_mode != NoLock)
- unlock();
-
- if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
- return false;
-
- if (!waitMutex(wmutex, block))
- return false;
-
- if (mode == ReadLock) {
- int idx = 0;
- for (; idx < MAX_READERS; idx++) {
- rmutex = getMutexHandle(idx, false);
- if (!rmutex || waitMutex(rmutex, false))
- break;
- CloseHandle(rmutex);
- }
- bool ok = true;
- if (idx >= MAX_READERS) {
- qWarning("QtLockedFile::lock(): too many readers");
- rmutex = 0;
- ok = false;
- }
- else if (!rmutex) {
- rmutex = getMutexHandle(idx, true);
- if (!rmutex || !waitMutex(rmutex, false))
- ok = false;
- }
- if (!ok && rmutex) {
- CloseHandle(rmutex);
- rmutex = 0;
- }
- ReleaseMutex(wmutex);
- if (!ok)
- return false;
- }
- else {
- Q_ASSERT(rmutexes.isEmpty());
- for (int i = 0; i < MAX_READERS; i++) {
- Qt::HANDLE mutex = getMutexHandle(i, false);
- if (mutex)
- rmutexes.append(mutex);
- }
- if (rmutexes.size()) {
- DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
- TRUE, block ? INFINITE : 0);
- if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
- if (res != WAIT_TIMEOUT)
- qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
- m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky
- unlock();
- return false;
- }
- }
- }
-
- m_lock_mode = mode;
- return true;
+ if (!isOpen()) {
+ qWarning("QtLockedFile::lock(): file is not opened");
+ return false;
+ }
+
+ if (mode == NoLock)
+ return unlock();
+
+ if (mode == m_lock_mode)
+ return true;
+
+ if (m_lock_mode != NoLock)
+ unlock();
+
+ if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
+ return false;
+
+ if (!waitMutex(wmutex, block))
+ return false;
+
+ if (mode == ReadLock) {
+ int idx = 0;
+ for (; idx < MAX_READERS; idx++) {
+ rmutex = getMutexHandle(idx, false);
+ if (!rmutex || waitMutex(rmutex, false))
+ break;
+ CloseHandle(rmutex);
+ }
+ bool ok = true;
+ if (idx >= MAX_READERS) {
+ qWarning("QtLockedFile::lock(): too many readers");
+ rmutex = 0;
+ ok = false;
+ }
+ else if (!rmutex) {
+ rmutex = getMutexHandle(idx, true);
+ if (!rmutex || !waitMutex(rmutex, false))
+ ok = false;
+ }
+ if (!ok && rmutex) {
+ CloseHandle(rmutex);
+ rmutex = 0;
+ }
+ ReleaseMutex(wmutex);
+ if (!ok)
+ return false;
+ }
+ else {
+ Q_ASSERT(rmutexes.isEmpty());
+ for (int i = 0; i < MAX_READERS; i++) {
+ Qt::HANDLE mutex = getMutexHandle(i, false);
+ if (mutex)
+ rmutexes.append(mutex);
+ }
+ if (rmutexes.size()) {
+ DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
+ TRUE, block ? INFINITE : 0);
+ if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
+ if (res != WAIT_TIMEOUT)
+ qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
+ m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky
+ unlock();
+ return false;
+ }
+ }
+ }
+
+ m_lock_mode = mode;
+ return true;
}
bool LockedFile::unlock()
{
- if (!isOpen()) {
- qWarning("QtLockedFile::unlock(): file is not opened");
- return false;
- }
-
- if (!isLocked())
- return true;
-
- if (m_lock_mode == ReadLock) {
- ReleaseMutex(rmutex);
- CloseHandle(rmutex);
- rmutex = 0;
- }
- else {
- foreach(Qt::HANDLE mutex, rmutexes) {
- ReleaseMutex(mutex);
- CloseHandle(mutex);
- }
- rmutexes.clear();
- ReleaseMutex(wmutex);
- }
-
- m_lock_mode = LockedFile::NoLock;
- return true;
+ if (!isOpen()) {
+ qWarning("QtLockedFile::unlock(): file is not opened");
+ return false;
+ }
+
+ if (!isLocked())
+ return true;
+
+ if (m_lock_mode == ReadLock) {
+ ReleaseMutex(rmutex);
+ CloseHandle(rmutex);
+ rmutex = 0;
+ }
+ else {
+ foreach(Qt::HANDLE mutex, rmutexes) {
+ ReleaseMutex(mutex);
+ CloseHandle(mutex);
+ }
+ rmutexes.clear();
+ ReleaseMutex(wmutex);
+ }
+
+ m_lock_mode = LockedFile::NoLock;
+ return true;
}
LockedFile::~LockedFile()
{
- if (isOpen())
- unlock();
- if (wmutex)
- CloseHandle(wmutex);
+ if (isOpen())
+ unlock();
+ if (wmutex)
+ CloseHandle(wmutex);
}
diff --git a/libraries/classparser/CMakeLists.txt b/libraries/classparser/CMakeLists.txt
index e9606258..3fe7591d 100644
--- a/libraries/classparser/CMakeLists.txt
+++ b/libraries/classparser/CMakeLists.txt
@@ -6,7 +6,7 @@ set(CMAKE_AUTOMOC ON)
include(TestBigEndian)
test_big_endian(BIGENDIAN)
if(${BIGENDIAN})
- add_definitions(-DMULTIMC_BIG_ENDIAN)
+ add_definitions(-DMULTIMC_BIG_ENDIAN)
endif(${BIGENDIAN})
# Find Qt
diff --git a/libraries/classparser/src/annotations.cpp b/libraries/classparser/src/annotations.cpp
index d1a7c046..18a9e880 100644
--- a/libraries/classparser/src/annotations.cpp
+++ b/libraries/classparser/src/annotations.cpp
@@ -6,80 +6,80 @@ namespace java
{
std::string annotation::toString()
{
- std::ostringstream ss;
- ss << "Annotation type : " << type_index << " - " << pool[type_index].str_data << std::endl;
- ss << "Contains " << name_val_pairs.size() << " pairs:" << std::endl;
- for (unsigned i = 0; i < name_val_pairs.size(); i++)
- {
- std::pair<uint16_t, element_value *> &val = name_val_pairs[i];
- auto name_idx = val.first;
- ss << pool[name_idx].str_data << "(" << name_idx << ")"
- << " = " << val.second->toString() << std::endl;
- }
- return ss.str();
+ std::ostringstream ss;
+ ss << "Annotation type : " << type_index << " - " << pool[type_index].str_data << std::endl;
+ ss << "Contains " << name_val_pairs.size() << " pairs:" << std::endl;
+ for (unsigned i = 0; i < name_val_pairs.size(); i++)
+ {
+ std::pair<uint16_t, element_value *> &val = name_val_pairs[i];
+ auto name_idx = val.first;
+ ss << pool[name_idx].str_data << "(" << name_idx << ")"
+ << " = " << val.second->toString() << std::endl;
+ }
+ return ss.str();
}
annotation *annotation::read(util::membuffer &input, constant_pool &pool)
{
- uint16_t type_index = 0;
- input.read_be(type_index);
- annotation *ann = new annotation(type_index, pool);
+ uint16_t type_index = 0;
+ input.read_be(type_index);
+ annotation *ann = new annotation(type_index, pool);
- uint16_t num_pairs = 0;
- input.read_be(num_pairs);
- while (num_pairs)
- {
- uint16_t name_idx = 0;
- // read name index
- input.read_be(name_idx);
- auto elem = element_value::readElementValue(input, pool);
- // read value
- ann->add_pair(name_idx, elem);
- num_pairs--;
- }
- return ann;
+ uint16_t num_pairs = 0;
+ input.read_be(num_pairs);
+ while (num_pairs)
+ {
+ uint16_t name_idx = 0;
+ // read name index
+ input.read_be(name_idx);
+ auto elem = element_value::readElementValue(input, pool);
+ // read value
+ ann->add_pair(name_idx, elem);
+ num_pairs--;
+ }
+ return ann;
}
element_value *element_value::readElementValue(util::membuffer &input,
- java::constant_pool &pool)
+ java::constant_pool &pool)
{
- element_value_type type = INVALID;
- input.read(type);
- uint16_t index = 0;
- uint16_t index2 = 0;
- std::vector<element_value *> vals;
- switch (type)
- {
- case PRIMITIVE_BYTE:
- case PRIMITIVE_CHAR:
- case PRIMITIVE_DOUBLE:
- case PRIMITIVE_FLOAT:
- case PRIMITIVE_INT:
- case PRIMITIVE_LONG:
- case PRIMITIVE_SHORT:
- case PRIMITIVE_BOOLEAN:
- case STRING:
- input.read_be(index);
- return new element_value_simple(type, index, pool);
- case ENUM_CONSTANT:
- input.read_be(index);
- input.read_be(index2);
- return new element_value_enum(type, index, index2, pool);
- case CLASS: // Class
- input.read_be(index);
- return new element_value_class(type, index, pool);
- case ANNOTATION: // Annotation
- // FIXME: runtime visibility info needs to be passed from parent
- return new element_value_annotation(ANNOTATION, annotation::read(input, pool), pool);
- case ARRAY: // Array
- input.read_be(index);
- for (int i = 0; i < index; i++)
- {
- vals.push_back(element_value::readElementValue(input, pool));
- }
- return new element_value_array(ARRAY, vals, pool);
- default:
- throw new java::classfile_exception();
- }
+ element_value_type type = INVALID;
+ input.read(type);
+ uint16_t index = 0;
+ uint16_t index2 = 0;
+ std::vector<element_value *> vals;
+ switch (type)
+ {
+ case PRIMITIVE_BYTE:
+ case PRIMITIVE_CHAR:
+ case PRIMITIVE_DOUBLE:
+ case PRIMITIVE_FLOAT:
+ case PRIMITIVE_INT:
+ case PRIMITIVE_LONG:
+ case PRIMITIVE_SHORT:
+ case PRIMITIVE_BOOLEAN:
+ case STRING:
+ input.read_be(index);
+ return new element_value_simple(type, index, pool);
+ case ENUM_CONSTANT:
+ input.read_be(index);
+ input.read_be(index2);
+ return new element_value_enum(type, index, index2, pool);
+ case CLASS: // Class
+ input.read_be(index);
+ return new element_value_class(type, index, pool);
+ case ANNOTATION: // Annotation
+ // FIXME: runtime visibility info needs to be passed from parent
+ return new element_value_annotation(ANNOTATION, annotation::read(input, pool), pool);
+ case ARRAY: // Array
+ input.read_be(index);
+ for (int i = 0; i < index; i++)
+ {
+ vals.push_back(element_value::readElementValue(input, pool));
+ }
+ return new element_value_array(ARRAY, vals, pool);
+ default:
+ throw new java::classfile_exception();
+ }
}
} \ No newline at end of file
diff --git a/libraries/classparser/src/annotations.h b/libraries/classparser/src/annotations.h
index dd603af3..15bf05a4 100644
--- a/libraries/classparser/src/annotations.h
+++ b/libraries/classparser/src/annotations.h
@@ -7,21 +7,21 @@ namespace java
{
enum element_value_type : uint8_t
{
- INVALID = 0,
- STRING = 's',
- ENUM_CONSTANT = 'e',
- CLASS = 'c',
- ANNOTATION = '@',
- ARRAY = '[', // one array dimension
- PRIMITIVE_INT = 'I', // integer
- PRIMITIVE_BYTE = 'B', // signed byte
- PRIMITIVE_CHAR = 'C', // Unicode character code point in the Basic Multilingual Plane,
- // encoded with UTF-16
- PRIMITIVE_DOUBLE = 'D', // double-precision floating-point value
- PRIMITIVE_FLOAT = 'F', // single-precision floating-point value
- PRIMITIVE_LONG = 'J', // long integer
- PRIMITIVE_SHORT = 'S', // signed short
- PRIMITIVE_BOOLEAN = 'Z' // true or false
+ INVALID = 0,
+ STRING = 's',
+ ENUM_CONSTANT = 'e',
+ CLASS = 'c',
+ ANNOTATION = '@',
+ ARRAY = '[', // one array dimension
+ PRIMITIVE_INT = 'I', // integer
+ PRIMITIVE_BYTE = 'B', // signed byte
+ PRIMITIVE_CHAR = 'C', // Unicode character code point in the Basic Multilingual Plane,
+ // encoded with UTF-16
+ PRIMITIVE_DOUBLE = 'D', // double-precision floating-point value
+ PRIMITIVE_FLOAT = 'F', // single-precision floating-point value
+ PRIMITIVE_LONG = 'J', // long integer
+ PRIMITIVE_SHORT = 'S', // signed short
+ PRIMITIVE_BOOLEAN = 'Z' // true or false
};
/**
* The element_value structure is a discriminated union representing the value of an
@@ -37,21 +37,21 @@ enum element_value_type : uint8_t
class element_value
{
protected:
- element_value_type type;
- constant_pool &pool;
+ element_value_type type;
+ constant_pool &pool;
public:
- element_value(element_value_type type, constant_pool &pool) : type(type), pool(pool) {};
- virtual ~element_value() {}
+ element_value(element_value_type type, constant_pool &pool) : type(type), pool(pool) {};
+ virtual ~element_value() {}
- element_value_type getElementValueType()
- {
- return type;
- }
+ element_value_type getElementValueType()
+ {
+ return type;
+ }
- virtual std::string toString() = 0;
+ virtual std::string toString() = 0;
- static element_value *readElementValue(util::membuffer &input, constant_pool &pool);
+ static element_value *readElementValue(util::membuffer &input, constant_pool &pool);
};
/**
@@ -62,58 +62,58 @@ public:
class annotation
{
public:
- typedef std::vector<std::pair<uint16_t, element_value *>> value_list;
+ typedef std::vector<std::pair<uint16_t, element_value *>> value_list;
protected:
- /**
- * The value of the type_index item must be a valid index into the constant_pool table.
- * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
- * representing a field descriptor representing the annotation type corresponding
- * to the annotation represented by this annotation structure.
- */
- uint16_t type_index;
- /**
- * map between element_name_index and value.
- *
- * The value of the element_name_index item must be a valid index into the constant_pool
- *table.
- * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
- *representing
- * a valid field descriptor (§4.3.2) that denotes the name of the annotation type element
- *represented
- * by this element_value_pairs entry.
- */
- value_list name_val_pairs;
- /**
- * Reference to the parent constant pool
- */
- constant_pool &pool;
+ /**
+ * The value of the type_index item must be a valid index into the constant_pool table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
+ * representing a field descriptor representing the annotation type corresponding
+ * to the annotation represented by this annotation structure.
+ */
+ uint16_t type_index;
+ /**
+ * map between element_name_index and value.
+ *
+ * The value of the element_name_index item must be a valid index into the constant_pool
+ *table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
+ *representing
+ * a valid field descriptor (§4.3.2) that denotes the name of the annotation type element
+ *represented
+ * by this element_value_pairs entry.
+ */
+ value_list name_val_pairs;
+ /**
+ * Reference to the parent constant pool
+ */
+ constant_pool &pool;
public:
- annotation(uint16_t type_index, constant_pool &pool)
- : type_index(type_index), pool(pool) {};
- ~annotation()
- {
- for (unsigned i = 0; i < name_val_pairs.size(); i++)
- {
- delete name_val_pairs[i].second;
- }
- }
- void add_pair(uint16_t key, element_value *value)
- {
- name_val_pairs.push_back(std::make_pair(key, value));
- }
- ;
- value_list::const_iterator begin()
- {
- return name_val_pairs.cbegin();
- }
- value_list::const_iterator end()
- {
- return name_val_pairs.cend();
- }
- std::string toString();
- static annotation *read(util::membuffer &input, constant_pool &pool);
+ annotation(uint16_t type_index, constant_pool &pool)
+ : type_index(type_index), pool(pool) {};
+ ~annotation()
+ {
+ for (unsigned i = 0; i < name_val_pairs.size(); i++)
+ {
+ delete name_val_pairs[i].second;
+ }
+ }
+ void add_pair(uint16_t key, element_value *value)
+ {
+ name_val_pairs.push_back(std::make_pair(key, value));
+ }
+ ;
+ value_list::const_iterator begin()
+ {
+ return name_val_pairs.cbegin();
+ }
+ value_list::const_iterator end()
+ {
+ return name_val_pairs.cend();
+ }
+ std::string toString();
+ static annotation *read(util::membuffer &input, constant_pool &pool);
};
typedef std::vector<annotation *> annotation_table;
@@ -121,158 +121,158 @@ typedef std::vector<annotation *> annotation_table;
class element_value_simple : public element_value
{
protected:
- /// index of the constant in the constant pool
- uint16_t index;
+ /// index of the constant in the constant pool
+ uint16_t index;
public:
- element_value_simple(element_value_type type, uint16_t index, constant_pool &pool)
- : element_value(type, pool), index(index) {
- // TODO: verify consistency
- };
- uint16_t getIndex()
- {
- return index;
- }
- virtual std::string toString()
- {
- return pool[index].toString();
- }
- ;
+ element_value_simple(element_value_type type, uint16_t index, constant_pool &pool)
+ : element_value(type, pool), index(index) {
+ // TODO: verify consistency
+ };
+ uint16_t getIndex()
+ {
+ return index;
+ }
+ virtual std::string toString()
+ {
+ return pool[index].toString();
+ }
+ ;
};
/// The enum_const_value item is used if the tag item is 'e'.
class element_value_enum : public element_value
{
protected:
- /**
- * The value of the type_name_index item must be a valid index into the constant_pool table.
- * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
- * representing a valid field descriptor (§4.3.2) that denotes the internal form of the
- * binary
- * name (§4.2.1) of the type of the enum constant represented by this element_value
- * structure.
- */
- uint16_t typeIndex;
- /**
- * The value of the const_name_index item must be a valid index into the constant_pool
- * table.
- * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
- * representing the simple name of the enum constant represented by this element_value
- * structure.
- */
- uint16_t valueIndex;
+ /**
+ * The value of the type_name_index item must be a valid index into the constant_pool table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
+ * representing a valid field descriptor (§4.3.2) that denotes the internal form of the
+ * binary
+ * name (§4.2.1) of the type of the enum constant represented by this element_value
+ * structure.
+ */
+ uint16_t typeIndex;
+ /**
+ * The value of the const_name_index item must be a valid index into the constant_pool
+ * table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
+ * representing the simple name of the enum constant represented by this element_value
+ * structure.
+ */
+ uint16_t valueIndex;
public:
- element_value_enum(element_value_type type, uint16_t typeIndex, uint16_t valueIndex,
- constant_pool &pool)
- : element_value(type, pool), typeIndex(typeIndex), valueIndex(valueIndex)
- {
- // TODO: verify consistency
- }
- uint16_t getValueIndex()
- {
- return valueIndex;
- }
- uint16_t getTypeIndex()
- {
- return typeIndex;
- }
- virtual std::string toString()
- {
- return "enum value";
- }
- ;
+ element_value_enum(element_value_type type, uint16_t typeIndex, uint16_t valueIndex,
+ constant_pool &pool)
+ : element_value(type, pool), typeIndex(typeIndex), valueIndex(valueIndex)
+ {
+ // TODO: verify consistency
+ }
+ uint16_t getValueIndex()
+ {
+ return valueIndex;
+ }
+ uint16_t getTypeIndex()
+ {
+ return typeIndex;
+ }
+ virtual std::string toString()
+ {
+ return "enum value";
+ }
+ ;
};
class element_value_class : public element_value
{
protected:
- /**
- * The class_info_index item must be a valid index into the constant_pool table.
- * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
- * representing the return descriptor (§4.3.3) of the type that is reified by the class
- * represented by this element_value structure.
- *
- * For example, 'V' for Void.class, 'Ljava/lang/Object;' for Object, etc.
- *
- * Or in plain english, you can store type information in annotations. Yay.
- */
- uint16_t classIndex;
+ /**
+ * The class_info_index item must be a valid index into the constant_pool table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
+ * representing the return descriptor (§4.3.3) of the type that is reified by the class
+ * represented by this element_value structure.
+ *
+ * For example, 'V' for Void.class, 'Ljava/lang/Object;' for Object, etc.
+ *
+ * Or in plain english, you can store type information in annotations. Yay.
+ */
+ uint16_t classIndex;
public:
- element_value_class(element_value_type type, uint16_t classIndex, constant_pool &pool)
- : element_value(type, pool), classIndex(classIndex)
- {
- // TODO: verify consistency
- }
- uint16_t getIndex()
- {
- return classIndex;
- }
- virtual std::string toString()
- {
- return "class";
- }
- ;
+ element_value_class(element_value_type type, uint16_t classIndex, constant_pool &pool)
+ : element_value(type, pool), classIndex(classIndex)
+ {
+ // TODO: verify consistency
+ }
+ uint16_t getIndex()
+ {
+ return classIndex;
+ }
+ virtual std::string toString()
+ {
+ return "class";
+ }
+ ;
};
/// nested annotations... yay
class element_value_annotation : public element_value
{
private:
- annotation *nestedAnnotation;
+ annotation *nestedAnnotation;
public:
- element_value_annotation(element_value_type type, annotation *nestedAnnotation,
- constant_pool &pool)
- : element_value(type, pool), nestedAnnotation(nestedAnnotation) {};
- ~element_value_annotation()
- {
- if (nestedAnnotation)
- {
- delete nestedAnnotation;
- nestedAnnotation = nullptr;
- }
- }
- virtual std::string toString()
- {
- return "nested annotation";
- }
- ;
+ element_value_annotation(element_value_type type, annotation *nestedAnnotation,
+ constant_pool &pool)
+ : element_value(type, pool), nestedAnnotation(nestedAnnotation) {};
+ ~element_value_annotation()
+ {
+ if (nestedAnnotation)
+ {
+ delete nestedAnnotation;
+ nestedAnnotation = nullptr;
+ }
+ }
+ virtual std::string toString()
+ {
+ return "nested annotation";
+ }
+ ;
};
/// and arrays!
class element_value_array : public element_value
{
public:
- typedef std::vector<element_value *> elem_vec;
+ typedef std::vector<element_value *> elem_vec;
protected:
- elem_vec values;
+ elem_vec values;
public:
- element_value_array(element_value_type type, std::vector<element_value *> &values,
- constant_pool &pool)
- : element_value(type, pool), values(values) {};
- ~element_value_array()
- {
- for (unsigned i = 0; i < values.size(); i++)
- {
- delete values[i];
- }
- }
- ;
- elem_vec::const_iterator begin()
- {
- return values.cbegin();
- }
- elem_vec::const_iterator end()
- {
- return values.cend();
- }
- virtual std::string toString()
- {
- return "array";
- }
- ;
+ element_value_array(element_value_type type, std::vector<element_value *> &values,
+ constant_pool &pool)
+ : element_value(type, pool), values(values) {};
+ ~element_value_array()
+ {
+ for (unsigned i = 0; i < values.size(); i++)
+ {
+ delete values[i];
+ }
+ }
+ ;
+ elem_vec::const_iterator begin()
+ {
+ return values.cbegin();
+ }
+ elem_vec::const_iterator end()
+ {
+ return values.cend();
+ }
+ virtual std::string toString()
+ {
+ return "array";
+ }
+ ;
};
} \ No newline at end of file
diff --git a/libraries/classparser/src/classfile.h b/libraries/classparser/src/classfile.h
index a5e7ee50..1616a828 100644
--- a/libraries/classparser/src/classfile.h
+++ b/libraries/classparser/src/classfile.h
@@ -11,146 +11,146 @@ namespace java
class classfile : public util::membuffer
{
public:
- classfile(char *data, std::size_t size) : membuffer(data, size)
- {
- valid = false;
- is_synthetic = false;
- read_be(magic);
- if (magic != 0xCAFEBABE)
- throw new classfile_exception();
- read_be(minor_version);
- read_be(major_version);
- constants.load(*this);
- read_be(access_flags);
- read_be(this_class);
- read_be(super_class);
+ classfile(char *data, std::size_t size) : membuffer(data, size)
+ {
+ valid = false;
+ is_synthetic = false;
+ read_be(magic);
+ if (magic != 0xCAFEBABE)
+ throw new classfile_exception();
+ read_be(minor_version);
+ read_be(major_version);
+ constants.load(*this);
+ read_be(access_flags);
+ read_be(this_class);
+ read_be(super_class);
- // Interfaces
- uint16_t iface_count = 0;
- read_be(iface_count);
- while (iface_count)
- {
- uint16_t iface;
- read_be(iface);
- interfaces.push_back(iface);
- iface_count--;
- }
+ // Interfaces
+ uint16_t iface_count = 0;
+ read_be(iface_count);
+ while (iface_count)
+ {
+ uint16_t iface;
+ read_be(iface);
+ interfaces.push_back(iface);
+ iface_count--;
+ }
- // Fields
- // read fields (and attributes from inside fields) (and possible inner classes. yay for
- // recursion!)
- // for now though, we will ignore all attributes
- /*
- * field_info
- * {
- * u2 access_flags;
- * u2 name_index;
- * u2 descriptor_index;
- * u2 attributes_count;
- * attribute_info attributes[attributes_count];
- * }
- */
- uint16_t field_count = 0;
- read_be(field_count);
- while (field_count)
- {
- // skip field stuff
- skip(6);
- // and skip field attributes
- uint16_t attr_count = 0;
- read_be(attr_count);
- while (attr_count)
- {
- skip(2);
- uint32_t attr_length = 0;
- read_be(attr_length);
- skip(attr_length);
- attr_count--;
- }
- field_count--;
- }
+ // Fields
+ // read fields (and attributes from inside fields) (and possible inner classes. yay for
+ // recursion!)
+ // for now though, we will ignore all attributes
+ /*
+ * field_info
+ * {
+ * u2 access_flags;
+ * u2 name_index;
+ * u2 descriptor_index;
+ * u2 attributes_count;
+ * attribute_info attributes[attributes_count];
+ * }
+ */
+ uint16_t field_count = 0;
+ read_be(field_count);
+ while (field_count)
+ {
+ // skip field stuff
+ skip(6);
+ // and skip field attributes
+ uint16_t attr_count = 0;
+ read_be(attr_count);
+ while (attr_count)
+ {
+ skip(2);
+ uint32_t attr_length = 0;
+ read_be(attr_length);
+ skip(attr_length);
+ attr_count--;
+ }
+ field_count--;
+ }
- // class methods
- /*
- * method_info
- * {
- * u2 access_flags;
- * u2 name_index;
- * u2 descriptor_index;
- * u2 attributes_count;
- * attribute_info attributes[attributes_count];
- * }
- */
- uint16_t method_count = 0;
- read_be(method_count);
- while (method_count)
- {
- skip(6);
- // and skip method attributes
- uint16_t attr_count = 0;
- read_be(attr_count);
- while (attr_count)
- {
- skip(2);
- uint32_t attr_length = 0;
- read_be(attr_length);
- skip(attr_length);
- attr_count--;
- }
- method_count--;
- }
+ // class methods
+ /*
+ * method_info
+ * {
+ * u2 access_flags;
+ * u2 name_index;
+ * u2 descriptor_index;
+ * u2 attributes_count;
+ * attribute_info attributes[attributes_count];
+ * }
+ */
+ uint16_t method_count = 0;
+ read_be(method_count);
+ while (method_count)
+ {
+ skip(6);
+ // and skip method attributes
+ uint16_t attr_count = 0;
+ read_be(attr_count);
+ while (attr_count)
+ {
+ skip(2);
+ uint32_t attr_length = 0;
+ read_be(attr_length);
+ skip(attr_length);
+ attr_count--;
+ }
+ method_count--;
+ }
- // class attributes
- // there are many kinds of attributes. this is just the generic wrapper structure.
- // type is decided by attribute name. extensions to the standard are *possible*
- // class annotations are one kind of a attribute (one per class)
- /*
- * attribute_info
- * {
- * u2 attribute_name_index;
- * u4 attribute_length;
- * u1 info[attribute_length];
- * }
- */
- uint16_t class_attr_count = 0;
- read_be(class_attr_count);
- while (class_attr_count)
- {
- uint16_t name_idx = 0;
- read_be(name_idx);
- uint32_t attr_length = 0;
- read_be(attr_length);
+ // class attributes
+ // there are many kinds of attributes. this is just the generic wrapper structure.
+ // type is decided by attribute name. extensions to the standard are *possible*
+ // class annotations are one kind of a attribute (one per class)
+ /*
+ * attribute_info
+ * {
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ * u1 info[attribute_length];
+ * }
+ */
+ uint16_t class_attr_count = 0;
+ read_be(class_attr_count);
+ while (class_attr_count)
+ {
+ uint16_t name_idx = 0;
+ read_be(name_idx);
+ uint32_t attr_length = 0;
+ read_be(attr_length);
- auto name = constants[name_idx];
- if (name.str_data == "RuntimeVisibleAnnotations")
- {
- uint16_t num_annotations = 0;
- read_be(num_annotations);
- while (num_annotations)
- {
- visible_class_annotations.push_back(annotation::read(*this, constants));
- num_annotations--;
- }
- }
- else
- skip(attr_length);
- class_attr_count--;
- }
- valid = true;
- }
- ;
- bool valid;
- bool is_synthetic;
- uint32_t magic;
- uint16_t minor_version;
- uint16_t major_version;
- constant_pool constants;
- uint16_t access_flags;
- uint16_t this_class;
- uint16_t super_class;
- // interfaces this class implements ? must be. investigate.
- std::vector<uint16_t> interfaces;
- // FIXME: doesn't free up memory on delete
- java::annotation_table visible_class_annotations;
+ auto name = constants[name_idx];
+ if (name.str_data == "RuntimeVisibleAnnotations")
+ {
+ uint16_t num_annotations = 0;
+ read_be(num_annotations);
+ while (num_annotations)
+ {
+ visible_class_annotations.push_back(annotation::read(*this, constants));
+ num_annotations--;
+ }
+ }
+ else
+ skip(attr_length);
+ class_attr_count--;
+ }
+ valid = true;
+ }
+ ;
+ bool valid;
+ bool is_synthetic;
+ uint32_t magic;
+ uint16_t minor_version;
+ uint16_t major_version;
+ constant_pool constants;
+ uint16_t access_flags;
+ uint16_t this_class;
+ uint16_t super_class;
+ // interfaces this class implements ? must be. investigate.
+ std::vector<uint16_t> interfaces;
+ // FIXME: doesn't free up memory on delete
+ java::annotation_table visible_class_annotations;
};
} \ No newline at end of file
diff --git a/libraries/classparser/src/classparser.cpp b/libraries/classparser/src/classparser.cpp
index 955686e1..b5197d7c 100644
--- a/libraries/classparser/src/classparser.cpp
+++ b/libraries/classparser/src/classparser.cpp
@@ -26,58 +26,58 @@ namespace classparser
QString GetMinecraftJarVersion(QString jarName)
{
- QString version;
+ QString version;
- // check if minecraft.jar exists
- QFile jar(jarName);
- if (!jar.exists())
- return version;
+ // check if minecraft.jar exists
+ QFile jar(jarName);
+ if (!jar.exists())
+ return version;
- // open minecraft.jar
- QuaZip zip(&jar);
- if (!zip.open(QuaZip::mdUnzip))
- return version;
+ // open minecraft.jar
+ QuaZip zip(&jar);
+ if (!zip.open(QuaZip::mdUnzip))
+ return version;
- // open Minecraft.class
- zip.setCurrentFile("net/minecraft/client/Minecraft.class", QuaZip::csSensitive);
- QuaZipFile Minecraft(&zip);
- if (!Minecraft.open(QuaZipFile::ReadOnly))
- return version;
+ // open Minecraft.class
+ zip.setCurrentFile("net/minecraft/client/Minecraft.class", QuaZip::csSensitive);
+ QuaZipFile Minecraft(&zip);
+ if (!Minecraft.open(QuaZipFile::ReadOnly))
+ return version;
- // read Minecraft.class
- qint64 size = Minecraft.size();
- char *classfile = new char[size];
- Minecraft.read(classfile, size);
+ // read Minecraft.class
+ qint64 size = Minecraft.size();
+ char *classfile = new char[size];
+ Minecraft.read(classfile, size);
- // parse Minecraft.class
- try
- {
- char *temp = classfile;
- java::classfile MinecraftClass(temp, size);
- java::constant_pool constants = MinecraftClass.constants;
- for (java::constant_pool::container_type::const_iterator iter = constants.begin();
- iter != constants.end(); iter++)
- {
- const java::constant &constant = *iter;
- if (constant.type != java::constant_type_t::j_string_data)
- continue;
- const std::string &str = constant.str_data;
- qDebug() << QString::fromStdString(str);
- if (str.compare(0, 20, "Minecraft Minecraft ") == 0)
- {
- version = str.substr(20).data();
- break;
- }
- }
- }
- catch (const java::classfile_exception &) { }
+ // parse Minecraft.class
+ try
+ {
+ char *temp = classfile;
+ java::classfile MinecraftClass(temp, size);
+ java::constant_pool constants = MinecraftClass.constants;
+ for (java::constant_pool::container_type::const_iterator iter = constants.begin();
+ iter != constants.end(); iter++)
+ {
+ const java::constant &constant = *iter;
+ if (constant.type != java::constant_type_t::j_string_data)
+ continue;
+ const std::string &str = constant.str_data;
+ qDebug() << QString::fromStdString(str);
+ if (str.compare(0, 20, "Minecraft Minecraft ") == 0)
+ {
+ version = str.substr(20).data();
+ break;
+ }
+ }
+ }
+ catch (const java::classfile_exception &) { }
- // clean up
- delete[] classfile;
- Minecraft.close();
- zip.close();
- jar.close();
+ // clean up
+ delete[] classfile;
+ Minecraft.close();
+ zip.close();
+ jar.close();
- return version;
+ return version;
}
}
diff --git a/libraries/classparser/src/constants.h b/libraries/classparser/src/constants.h
index 4f7e9299..3b6c3b7a 100644
--- a/libraries/classparser/src/constants.h
+++ b/libraries/classparser/src/constants.h
@@ -6,159 +6,159 @@ namespace java
{
enum class constant_type_t : uint8_t
{
- j_hole = 0, // HACK: this is a hole in the array, because java is crazy
- j_string_data = 1,
- j_int = 3,
- j_float = 4,
- j_long = 5,
- j_double = 6,
- j_class = 7,
- j_string = 8,
- j_fieldref = 9,
- j_methodref = 10,
- j_interface_methodref = 11,
- j_nameandtype = 12
- // FIXME: missing some constant types, see https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4
+ j_hole = 0, // HACK: this is a hole in the array, because java is crazy
+ j_string_data = 1,
+ j_int = 3,
+ j_float = 4,
+ j_long = 5,
+ j_double = 6,
+ j_class = 7,
+ j_string = 8,
+ j_fieldref = 9,
+ j_methodref = 10,
+ j_interface_methodref = 11,
+ j_nameandtype = 12
+ // FIXME: missing some constant types, see https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4
};
struct ref_type_t
{
- /**
- * Class reference:
- * an index within the constant pool to a UTF-8 string containing
- * the fully qualified class name (in internal format)
- * Used for j_class, j_fieldref, j_methodref and j_interface_methodref
- */
- uint16_t class_idx;
- // used for j_fieldref, j_methodref and j_interface_methodref
- uint16_t name_and_type_idx;
+ /**
+ * Class reference:
+ * an index within the constant pool to a UTF-8 string containing
+ * the fully qualified class name (in internal format)
+ * Used for j_class, j_fieldref, j_methodref and j_interface_methodref
+ */
+ uint16_t class_idx;
+ // used for j_fieldref, j_methodref and j_interface_methodref
+ uint16_t name_and_type_idx;
};
struct name_and_type_t
{
- uint16_t name_index;
- uint16_t descriptor_index;
+ uint16_t name_index;
+ uint16_t descriptor_index;
};
class constant
{
public:
- constant_type_t type = constant_type_t::j_hole;
+ constant_type_t type = constant_type_t::j_hole;
- constant(util::membuffer &buf)
- {
- buf.read(type);
+ constant(util::membuffer &buf)
+ {
+ buf.read(type);
- // load data depending on type
- switch (type)
- {
- case constant_type_t::j_float:
- buf.read_be(data.int_data);
- break;
- case constant_type_t::j_int:
- buf.read_be(data.int_data); // same as float data really
- break;
- case constant_type_t::j_double:
- buf.read_be(data.long_data);
- break;
- case constant_type_t::j_long:
- buf.read_be(data.long_data); // same as double
- break;
- case constant_type_t::j_class:
- buf.read_be(data.ref_type.class_idx);
- break;
- case constant_type_t::j_fieldref:
- case constant_type_t::j_methodref:
- case constant_type_t::j_interface_methodref:
- buf.read_be(data.ref_type.class_idx);
- buf.read_be(data.ref_type.name_and_type_idx);
- break;
- case constant_type_t::j_string:
- buf.read_be(data.index);
- break;
- case constant_type_t::j_string_data:
- // HACK HACK: for now, we call these UTF-8 and do no further processing.
- // Later, we should do some decoding. It's really modified UTF-8
- // * U+0000 is represented as 0xC0,0x80 invalid character
- // * any single zero byte ends the string
- // * characters above U+10000 are encoded like in CESU-8
- buf.read_jstr(str_data);
- break;
- case constant_type_t::j_nameandtype:
- buf.read_be(data.name_and_type.name_index);
- buf.read_be(data.name_and_type.descriptor_index);
- break;
- default:
- // invalid constant type!
- throw new classfile_exception();
- }
- }
- constant(int)
- {
- }
+ // load data depending on type
+ switch (type)
+ {
+ case constant_type_t::j_float:
+ buf.read_be(data.int_data);
+ break;
+ case constant_type_t::j_int:
+ buf.read_be(data.int_data); // same as float data really
+ break;
+ case constant_type_t::j_double:
+ buf.read_be(data.long_data);
+ break;
+ case constant_type_t::j_long:
+ buf.read_be(data.long_data); // same as double
+ break;
+ case constant_type_t::j_class:
+ buf.read_be(data.ref_type.class_idx);
+ break;
+ case constant_type_t::j_fieldref:
+ case constant_type_t::j_methodref:
+ case constant_type_t::j_interface_methodref:
+ buf.read_be(data.ref_type.class_idx);
+ buf.read_be(data.ref_type.name_and_type_idx);
+ break;
+ case constant_type_t::j_string:
+ buf.read_be(data.index);
+ break;
+ case constant_type_t::j_string_data:
+ // HACK HACK: for now, we call these UTF-8 and do no further processing.
+ // Later, we should do some decoding. It's really modified UTF-8
+ // * U+0000 is represented as 0xC0,0x80 invalid character
+ // * any single zero byte ends the string
+ // * characters above U+10000 are encoded like in CESU-8
+ buf.read_jstr(str_data);
+ break;
+ case constant_type_t::j_nameandtype:
+ buf.read_be(data.name_and_type.name_index);
+ buf.read_be(data.name_and_type.descriptor_index);
+ break;
+ default:
+ // invalid constant type!
+ throw new classfile_exception();
+ }
+ }
+ constant(int)
+ {
+ }
- std::string toString()
- {
- std::ostringstream ss;
- switch (type)
- {
- case constant_type_t::j_hole:
- ss << "Fake legacy entry";
- break;
- case constant_type_t::j_float:
- ss << "Float: " << data.float_data;
- break;
- case constant_type_t::j_double:
- ss << "Double: " << data.double_data;
- break;
- case constant_type_t::j_int:
- ss << "Int: " << data.int_data;
- break;
- case constant_type_t::j_long:
- ss << "Long: " << data.long_data;
- break;
- case constant_type_t::j_string_data:
- ss << "StrData: " << str_data;
- break;
- case constant_type_t::j_string:
- ss << "Str: " << data.index;
- break;
- case constant_type_t::j_fieldref:
- ss << "FieldRef: " << data.ref_type.class_idx << " " << data.ref_type.name_and_type_idx;
- break;
- case constant_type_t::j_methodref:
- ss << "MethodRef: " << data.ref_type.class_idx << " " << data.ref_type.name_and_type_idx;
- break;
- case constant_type_t::j_interface_methodref:
- ss << "IfMethodRef: " << data.ref_type.class_idx << " " << data.ref_type.name_and_type_idx;
- break;
- case constant_type_t::j_class:
- ss << "Class: " << data.ref_type.class_idx;
- break;
- case constant_type_t::j_nameandtype:
- ss << "NameAndType: " << data.name_and_type.name_index << " "
- << data.name_and_type.descriptor_index;
- break;
- default:
- ss << "Invalid entry (" << int(type) << ")";
- break;
- }
- return ss.str();
- }
+ std::string toString()
+ {
+ std::ostringstream ss;
+ switch (type)
+ {
+ case constant_type_t::j_hole:
+ ss << "Fake legacy entry";
+ break;
+ case constant_type_t::j_float:
+ ss << "Float: " << data.float_data;
+ break;
+ case constant_type_t::j_double:
+ ss << "Double: " << data.double_data;
+ break;
+ case constant_type_t::j_int:
+ ss << "Int: " << data.int_data;
+ break;
+ case constant_type_t::j_long:
+ ss << "Long: " << data.long_data;
+ break;
+ case constant_type_t::j_string_data:
+ ss << "StrData: " << str_data;
+ break;
+ case constant_type_t::j_string:
+ ss << "Str: " << data.index;
+ break;
+ case constant_type_t::j_fieldref:
+ ss << "FieldRef: " << data.ref_type.class_idx << " " << data.ref_type.name_and_type_idx;
+ break;
+ case constant_type_t::j_methodref:
+ ss << "MethodRef: " << data.ref_type.class_idx << " " << data.ref_type.name_and_type_idx;
+ break;
+ case constant_type_t::j_interface_methodref:
+ ss << "IfMethodRef: " << data.ref_type.class_idx << " " << data.ref_type.name_and_type_idx;
+ break;
+ case constant_type_t::j_class:
+ ss << "Class: " << data.ref_type.class_idx;
+ break;
+ case constant_type_t::j_nameandtype:
+ ss << "NameAndType: " << data.name_and_type.name_index << " "
+ << data.name_and_type.descriptor_index;
+ break;
+ default:
+ ss << "Invalid entry (" << int(type) << ")";
+ break;
+ }
+ return ss.str();
+ }
- std::string str_data; /** String data in 'modified utf-8'.*/
+ std::string str_data; /** String data in 'modified utf-8'.*/
- // store everything here.
- union
- {
- int32_t int_data;
- int64_t long_data;
- float float_data;
- double double_data;
- uint16_t index;
- ref_type_t ref_type;
- name_and_type_t name_and_type;
- } data = {0};
+ // store everything here.
+ union
+ {
+ int32_t int_data;
+ int64_t long_data;
+ float float_data;
+ double double_data;
+ uint16_t index;
+ ref_type_t ref_type;
+ name_and_type_t name_and_type;
+ } data = {0};
};
/**
@@ -168,64 +168,64 @@ public:
class constant_pool
{
public:
- /**
- * Create a pool of constants
- */
- constant_pool()
- {
- }
- /**
- * Load a java constant pool
- */
- void load(util::membuffer &buf)
- {
- // FIXME: @SANITY this should check for the end of buffer.
- uint16_t length = 0;
- buf.read_be(length);
- length--;
- const constant *last_constant = nullptr;
- while (length)
- {
- const constant &cnst = constant(buf);
- constants.push_back(cnst);
- last_constant = &constants[constants.size() - 1];
- if (last_constant->type == constant_type_t::j_double ||
- last_constant->type == constant_type_t::j_long)
- {
- // push in a fake constant to preserve indexing
- constants.push_back(constant(0));
- length -= 2;
- }
- else
- {
- length--;
- }
- }
- }
- typedef std::vector<java::constant> container_type;
- /**
- * Access constants based on jar file index numbers (index of the first element is 1)
- */
- java::constant &operator[](std::size_t constant_index)
- {
- if (constant_index == 0 || constant_index > constants.size())
- {
- throw new classfile_exception();
- }
- return constants[constant_index - 1];
- }
- ;
- container_type::const_iterator begin() const
- {
- return constants.begin();
- }
- ;
- container_type::const_iterator end() const
- {
- return constants.end();
- }
+ /**
+ * Create a pool of constants
+ */
+ constant_pool()
+ {
+ }
+ /**
+ * Load a java constant pool
+ */
+ void load(util::membuffer &buf)
+ {
+ // FIXME: @SANITY this should check for the end of buffer.
+ uint16_t length = 0;
+ buf.read_be(length);
+ length--;
+ const constant *last_constant = nullptr;
+ while (length)
+ {
+ const constant &cnst = constant(buf);
+ constants.push_back(cnst);
+ last_constant = &constants[constants.size() - 1];
+ if (last_constant->type == constant_type_t::j_double ||
+ last_constant->type == constant_type_t::j_long)
+ {
+ // push in a fake constant to preserve indexing
+ constants.push_back(constant(0));
+ length -= 2;
+ }
+ else
+ {
+ length--;
+ }
+ }
+ }
+ typedef std::vector<java::constant> container_type;
+ /**
+ * Access constants based on jar file index numbers (index of the first element is 1)
+ */
+ java::constant &operator[](std::size_t constant_index)
+ {
+ if (constant_index == 0 || constant_index > constants.size())
+ {
+ throw new classfile_exception();
+ }
+ return constants[constant_index - 1];
+ }
+ ;
+ container_type::const_iterator begin() const
+ {
+ return constants.begin();
+ }
+ ;
+ container_type::const_iterator end() const
+ {
+ return constants.end();
+ }
private:
- container_type constants;
+ container_type constants;
};
}
diff --git a/libraries/classparser/src/javaendian.h b/libraries/classparser/src/javaendian.h
index 5e6fff55..076bff5e 100644
--- a/libraries/classparser/src/javaendian.h
+++ b/libraries/classparser/src/javaendian.h
@@ -9,67 +9,67 @@ namespace util
#ifdef MULTIMC_BIG_ENDIAN
inline uint64_t bigswap(uint64_t x)
{
- return x;
+ return x;
}
;
inline uint32_t bigswap(uint32_t x)
{
- return x;
+ return x;
}
;
inline uint16_t bigswap(uint16_t x)
{
- return x;
+ return x;
}
;
inline int64_t bigswap(int64_t x)
{
- return x;
+ return x;
}
;
inline int32_t bigswap(int32_t x)
{
- return x;
+ return x;
}
;
inline int16_t bigswap(int16_t x)
{
- return x;
+ return x;
}
;
#else
inline uint64_t bigswap(uint64_t x)
{
- return (x >> 56) | ((x << 40) & 0x00FF000000000000) | ((x << 24) & 0x0000FF0000000000) |
- ((x << 8) & 0x000000FF00000000) | ((x >> 8) & 0x00000000FF000000) |
- ((x >> 24) & 0x0000000000FF0000) | ((x >> 40) & 0x000000000000FF00) | (x << 56);
+ return (x >> 56) | ((x << 40) & 0x00FF000000000000) | ((x << 24) & 0x0000FF0000000000) |
+ ((x << 8) & 0x000000FF00000000) | ((x >> 8) & 0x00000000FF000000) |
+ ((x >> 24) & 0x0000000000FF0000) | ((x >> 40) & 0x000000000000FF00) | (x << 56);
}
inline uint32_t bigswap(uint32_t x)
{
- return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
+ return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
}
inline uint16_t bigswap(uint16_t x)
{
- return (x >> 8) | (x << 8);
+ return (x >> 8) | (x << 8);
}
inline int64_t bigswap(int64_t x)
{
- return (x >> 56) | ((x << 40) & 0x00FF000000000000) | ((x << 24) & 0x0000FF0000000000) |
- ((x << 8) & 0x000000FF00000000) | ((x >> 8) & 0x00000000FF000000) |
- ((x >> 24) & 0x0000000000FF0000) | ((x >> 40) & 0x000000000000FF00) | (x << 56);
+ return (x >> 56) | ((x << 40) & 0x00FF000000000000) | ((x << 24) & 0x0000FF0000000000) |
+ ((x << 8) & 0x000000FF00000000) | ((x >> 8) & 0x00000000FF000000) |
+ ((x >> 24) & 0x0000000000FF0000) | ((x >> 40) & 0x000000000000FF00) | (x << 56);
}
inline int32_t bigswap(int32_t x)
{
- return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
+ return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
}
inline int16_t bigswap(int16_t x)
{
- return (x >> 8) | (x << 8);
+ return (x >> 8) | (x << 8);
}
#endif
diff --git a/libraries/classparser/src/membuffer.h b/libraries/classparser/src/membuffer.h
index ab83412a..f81c9705 100644
--- a/libraries/classparser/src/membuffer.h
+++ b/libraries/classparser/src/membuffer.h
@@ -10,54 +10,54 @@ namespace util
class membuffer
{
public:
- membuffer(char *buffer, std::size_t size)
- {
- current = start = buffer;
- end = start + size;
- }
- ~membuffer()
- {
- // maybe? possibly? left out to avoid confusion. for now.
- // delete start;
- }
- /**
- * Read some value. That's all ;)
- */
- template <class T> void read(T &val)
- {
- val = *(T *)current;
- current += sizeof(T);
- }
- /**
- * Read a big-endian number
- * valid for 2-byte, 4-byte and 8-byte variables
- */
- template <class T> void read_be(T &val)
- {
- val = util::bigswap(*(T *)current);
- current += sizeof(T);
- }
- /**
- * Read a string in the format:
- * 2B length (big endian, unsigned)
- * length bytes data
- */
- void read_jstr(std::string &str)
- {
- uint16_t length = 0;
- read_be(length);
- str.append(current, length);
- current += length;
- }
- /**
- * Skip N bytes
- */
- void skip(std::size_t N)
- {
- current += N;
- }
+ membuffer(char *buffer, std::size_t size)
+ {
+ current = start = buffer;
+ end = start + size;
+ }
+ ~membuffer()
+ {
+ // maybe? possibly? left out to avoid confusion. for now.
+ // delete start;
+ }
+ /**
+ * Read some value. That's all ;)
+ */
+ template <class T> void read(T &val)
+ {
+ val = *(T *)current;
+ current += sizeof(T);
+ }
+ /**
+ * Read a big-endian number
+ * valid for 2-byte, 4-byte and 8-byte variables
+ */
+ template <class T> void read_be(T &val)
+ {
+ val = util::bigswap(*(T *)current);
+ current += sizeof(T);
+ }
+ /**
+ * Read a string in the format:
+ * 2B length (big endian, unsigned)
+ * length bytes data
+ */
+ void read_jstr(std::string &str)
+ {
+ uint16_t length = 0;
+ read_be(length);
+ str.append(current, length);
+ current += length;
+ }
+ /**
+ * Skip N bytes
+ */
+ void skip(std::size_t N)
+ {
+ current += N;
+ }
private:
- char *start, *end, *current;
+ char *start, *end, *current;
};
}
diff --git a/libraries/ganalytics/include/ganalytics.h b/libraries/ganalytics/include/ganalytics.h
index bfca6d37..ba422457 100644
--- a/libraries/ganalytics/include/ganalytics.h
+++ b/libraries/ganalytics/include/ganalytics.h
@@ -8,59 +8,59 @@ class GAnalyticsWorker;
class GAnalytics : public QObject
{
- Q_OBJECT
- Q_ENUMS(LogLevel)
+ Q_OBJECT
+ Q_ENUMS(LogLevel)
public:
- explicit GAnalytics(const QString &trackingID, const QString &clientID, const int version, QObject *parent = 0);
- ~GAnalytics();
+ explicit GAnalytics(const QString &trackingID, const QString &clientID, const int version, QObject *parent = 0);
+ ~GAnalytics();
public:
- enum LogLevel
- {
- Debug,
- Info,
- Error
- };
+ enum LogLevel
+ {
+ Debug,
+ Info,
+ Error
+ };
- int version();
+ int version();
- void setLogLevel(LogLevel logLevel);
- LogLevel logLevel() const;
+ void setLogLevel(LogLevel logLevel);
+ LogLevel logLevel() const;
- // Getter and Setters
- void setViewportSize(const QString &viewportSize);
- QString viewportSize() const;
+ // Getter and Setters
+ void setViewportSize(const QString &viewportSize);
+ QString viewportSize() const;
- void setLanguage(const QString &language);
- QString language() const;
+ void setLanguage(const QString &language);
+ QString language() const;
- void setAnonymizeIPs(bool anonymize);
- bool anonymizeIPs();
+ void setAnonymizeIPs(bool anonymize);
+ bool anonymizeIPs();
- void setSendInterval(int milliseconds);
- int sendInterval() const;
+ void setSendInterval(int milliseconds);
+ int sendInterval() const;
- void enable(bool state = true);
- bool isEnabled();
+ void enable(bool state = true);
+ bool isEnabled();
- /// Get or set the network access manager. If none is set, the class creates its own on the first request
- void setNetworkAccessManager(QNetworkAccessManager *networkAccessManager);
- QNetworkAccessManager *networkAccessManager() const;
+ /// Get or set the network access manager. If none is set, the class creates its own on the first request
+ void setNetworkAccessManager(QNetworkAccessManager *networkAccessManager);
+ QNetworkAccessManager *networkAccessManager() const;
public slots:
- void sendScreenView(const QString &screenName, const QVariantMap &customValues = QVariantMap());
- void sendEvent(const QString &category, const QString &action, const QString &label = QString(), const QVariant &value = QVariant(),
- const QVariantMap &customValues = QVariantMap());
- void sendException(const QString &exceptionDescription, bool exceptionFatal = true, const QVariantMap &customValues = QVariantMap());
- void startSession();
- void endSession();
+ void sendScreenView(const QString &screenName, const QVariantMap &customValues = QVariantMap());
+ void sendEvent(const QString &category, const QString &action, const QString &label = QString(), const QVariant &value = QVariant(),
+ const QVariantMap &customValues = QVariantMap());
+ void sendException(const QString &exceptionDescription, bool exceptionFatal = true, const QVariantMap &customValues = QVariantMap());
+ void startSession();
+ void endSession();
private:
- GAnalyticsWorker *d;
+ GAnalyticsWorker *d;
- friend QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics);
- friend QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics);
+ friend QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics);
+ friend QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics);
};
QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics);
diff --git a/libraries/ganalytics/src/ganalytics.cpp b/libraries/ganalytics/src/ganalytics.cpp
index 5f2d1484..a4b7394f 100644
--- a/libraries/ganalytics/src/ganalytics.cpp
+++ b/libraries/ganalytics/src/ganalytics.cpp
@@ -16,10 +16,10 @@
GAnalytics::GAnalytics(const QString &trackingID, const QString &clientID, const int version, QObject *parent) : QObject(parent)
{
- d = new GAnalyticsWorker(this);
- d->m_trackingID = trackingID;
- d->m_clientID = clientID;
- d->m_version = version;
+ d = new GAnalyticsWorker(this);
+ d->m_trackingID = trackingID;
+ d->m_clientID = clientID;
+ d->m_version = version;
}
/**
@@ -27,100 +27,100 @@ GAnalytics::GAnalytics(const QString &trackingID, const QString &clientID, const
*/
GAnalytics::~GAnalytics()
{
- delete d;
+ delete d;
}
void GAnalytics::setLogLevel(GAnalytics::LogLevel logLevel)
{
- d->m_logLevel = logLevel;
+ d->m_logLevel = logLevel;
}
GAnalytics::LogLevel GAnalytics::logLevel() const
{
- return d->m_logLevel;
+ return d->m_logLevel;
}
// SETTER and GETTER
void GAnalytics::setViewportSize(const QString &viewportSize)
{
- d->m_viewportSize = viewportSize;
+ d->m_viewportSize = viewportSize;
}
QString GAnalytics::viewportSize() const
{
- return d->m_viewportSize;
+ return d->m_viewportSize;
}
void GAnalytics::setLanguage(const QString &language)
{
- d->m_language = language;
+ d->m_language = language;
}
QString GAnalytics::language() const
{
- return d->m_language;
+ return d->m_language;
}
void GAnalytics::setAnonymizeIPs(bool anonymize)
{
- d->m_anonymizeIPs = anonymize;
+ d->m_anonymizeIPs = anonymize;
}
bool GAnalytics::anonymizeIPs()
{
- return d->m_anonymizeIPs;
+ return d->m_anonymizeIPs;
}
void GAnalytics::setSendInterval(int milliseconds)
{
- d->m_timer.setInterval(milliseconds);
+ d->m_timer.setInterval(milliseconds);
}
int GAnalytics::sendInterval() const
{
- return (d->m_timer.interval());
+ return (d->m_timer.interval());
}
bool GAnalytics::isEnabled()
{
- return d->m_isEnabled;
+ return d->m_isEnabled;
}
void GAnalytics::enable(bool state)
{
- d->enable(state);
+ d->enable(state);
}
int GAnalytics::version()
{
- return d->m_version;
+ return d->m_version;
}
void GAnalytics::setNetworkAccessManager(QNetworkAccessManager *networkAccessManager)
{
- if (d->networkManager != networkAccessManager)
- {
- // Delete the old network manager if it was our child
- if (d->networkManager && d->networkManager->parent() == this)
- {
- d->networkManager->deleteLater();
- }
+ if (d->networkManager != networkAccessManager)
+ {
+ // Delete the old network manager if it was our child
+ if (d->networkManager && d->networkManager->parent() == this)
+ {
+ d->networkManager->deleteLater();
+ }
- d->networkManager = networkAccessManager;
- }
+ d->networkManager = networkAccessManager;
+ }
}
QNetworkAccessManager *GAnalytics::networkAccessManager() const
{
- return d->networkManager;
+ return d->networkManager;
}
static void appendCustomValues(QUrlQuery &query, const QVariantMap &customValues)
{
- for (QVariantMap::const_iterator iter = customValues.begin(); iter != customValues.end(); ++iter)
- {
- query.addQueryItem(iter.key(), iter.value().toString());
- }
+ for (QVariantMap::const_iterator iter = customValues.begin(); iter != customValues.end(); ++iter)
+ {
+ query.addQueryItem(iter.key(), iter.value().toString());
+ }
}
/**
@@ -131,15 +131,15 @@ static void appendCustomValues(QUrlQuery &query, const QVariantMap &customValues
*/
void GAnalytics::sendScreenView(const QString &screenName, const QVariantMap &customValues)
{
- d->logMessage(Info, QString("ScreenView: %1").arg(screenName));
+ d->logMessage(Info, QString("ScreenView: %1").arg(screenName));
- QUrlQuery query = d->buildStandardPostQuery("screenview");
- query.addQueryItem("cd", screenName);
- query.addQueryItem("an", d->m_appName);
- query.addQueryItem("av", d->m_appVersion);
- appendCustomValues(query, customValues);
+ QUrlQuery query = d->buildStandardPostQuery("screenview");
+ query.addQueryItem("cd", screenName);
+ query.addQueryItem("an", d->m_appName);
+ query.addQueryItem("av", d->m_appVersion);
+ appendCustomValues(query, customValues);
- d->enqueQueryWithCurrentTime(query);
+ d->enqueQueryWithCurrentTime(query);
}
/**
@@ -149,19 +149,19 @@ void GAnalytics::sendScreenView(const QString &screenName, const QVariantMap &cu
*/
void GAnalytics::sendEvent(const QString &category, const QString &action, const QString &label, const QVariant &value, const QVariantMap &customValues)
{
- QUrlQuery query = d->buildStandardPostQuery("event");
- query.addQueryItem("an", d->m_appName);
- query.addQueryItem("av", d->m_appVersion);
- query.addQueryItem("ec", category);
- query.addQueryItem("ea", action);
- if (!label.isEmpty())
- query.addQueryItem("el", label);
- if (value.isValid())
- query.addQueryItem("ev", value.toString());
+ QUrlQuery query = d->buildStandardPostQuery("event");
+ query.addQueryItem("an", d->m_appName);
+ query.addQueryItem("av", d->m_appVersion);
+ query.addQueryItem("ec", category);
+ query.addQueryItem("ea", action);
+ if (!label.isEmpty())
+ query.addQueryItem("el", label);
+ if (value.isValid())
+ query.addQueryItem("ev", value.toString());
- appendCustomValues(query, customValues);
+ appendCustomValues(query, customValues);
- d->enqueQueryWithCurrentTime(query);
+ d->enqueQueryWithCurrentTime(query);
}
/**
@@ -171,23 +171,23 @@ void GAnalytics::sendEvent(const QString &category, const QString &action, const
*/
void GAnalytics::sendException(const QString &exceptionDescription, bool exceptionFatal, const QVariantMap &customValues)
{
- QUrlQuery query = d->buildStandardPostQuery("exception");
- query.addQueryItem("an", d->m_appName);
- query.addQueryItem("av", d->m_appVersion);
+ QUrlQuery query = d->buildStandardPostQuery("exception");
+ query.addQueryItem("an", d->m_appName);
+ query.addQueryItem("av", d->m_appVersion);
- query.addQueryItem("exd", exceptionDescription);
+ query.addQueryItem("exd", exceptionDescription);
- if (exceptionFatal)
- {
- query.addQueryItem("exf", "1");
- }
- else
- {
- query.addQueryItem("exf", "0");
- }
- appendCustomValues(query, customValues);
+ if (exceptionFatal)
+ {
+ query.addQueryItem("exf", "1");
+ }
+ else
+ {
+ query.addQueryItem("exf", "0");
+ }
+ appendCustomValues(query, customValues);
- d->enqueQueryWithCurrentTime(query);
+ d->enqueQueryWithCurrentTime(query);
}
/**
@@ -197,9 +197,9 @@ void GAnalytics::sendException(const QString &exceptionDescription, bool excepti
*/
void GAnalytics::startSession()
{
- QVariantMap customValues;
- customValues.insert("sc", "start");
- sendEvent("Session", "Start", QString(), QVariant(), customValues);
+ QVariantMap customValues;
+ customValues.insert("sc", "start");
+ sendEvent("Session", "Start", QString(), QVariant(), customValues);
}
/**
@@ -209,9 +209,9 @@ void GAnalytics::startSession()
*/
void GAnalytics::endSession()
{
- QVariantMap customValues;
- customValues.insert("sc", "end");
- sendEvent("Session", "End", QString(), QVariant(), customValues);
+ QVariantMap customValues;
+ customValues.insert("sc", "end");
+ sendEvent("Session", "End", QString(), QVariant(), customValues);
}
/**
@@ -219,9 +219,9 @@ void GAnalytics::endSession()
*/
QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics)
{
- outStream << analytics.d->persistMessageQueue();
+ outStream << analytics.d->persistMessageQueue();
- return outStream;
+ return outStream;
}
/**
@@ -229,9 +229,9 @@ QDataStream &operator<<(QDataStream &outStream, const GAnalytics &analytics)
*/
QDataStream &operator>>(QDataStream &inStream, GAnalytics &analytics)
{
- QList<QString> dataList;
- inStream >> dataList;
- analytics.d->readMessagesFromFile(dataList);
+ QList<QString> dataList;
+ inStream >> dataList;
+ analytics.d->readMessagesFromFile(dataList);
- return inStream;
+ return inStream;
}
diff --git a/libraries/ganalytics/src/ganalytics_worker.cpp b/libraries/ganalytics/src/ganalytics_worker.cpp
index f55a4d09..5980d3bd 100644
--- a/libraries/ganalytics/src/ganalytics_worker.cpp
+++ b/libraries/ganalytics/src/ganalytics_worker.cpp
@@ -12,50 +12,50 @@
const QLatin1String GAnalyticsWorker::dateTimeFormat("yyyy,MM,dd-hh:mm::ss:zzz");
GAnalyticsWorker::GAnalyticsWorker(GAnalytics *parent)
- : QObject(parent), q(parent), m_logLevel(GAnalytics::Error)
+ : QObject(parent), q(parent), m_logLevel(GAnalytics::Error)
{
- m_appName = QCoreApplication::instance()->applicationName();
- m_appVersion = QCoreApplication::instance()->applicationVersion();
- m_request.setUrl(QUrl("https://www.google-analytics.com/collect"));
- m_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
- m_request.setHeader(QNetworkRequest::UserAgentHeader, getUserAgent());
+ m_appName = QCoreApplication::instance()->applicationName();
+ m_appVersion = QCoreApplication::instance()->applicationVersion();
+ m_request.setUrl(QUrl("https://www.google-analytics.com/collect"));
+ m_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+ m_request.setHeader(QNetworkRequest::UserAgentHeader, getUserAgent());
- m_language = QLocale::system().name().toLower().replace("_", "-");
- m_screenResolution = getScreenResolution();
+ m_language = QLocale::system().name().toLower().replace("_", "-");
+ m_screenResolution = getScreenResolution();
- m_timer.setInterval(m_timerInterval);
- connect(&m_timer, &QTimer::timeout, this, &GAnalyticsWorker::postMessage);
+ m_timer.setInterval(m_timerInterval);
+ connect(&m_timer, &QTimer::timeout, this, &GAnalyticsWorker::postMessage);
}
void GAnalyticsWorker::enable(bool state)
{
- // state change to the same is not valid.
- if(m_isEnabled == state)
- {
- return;
- }
-
- m_isEnabled = state;
- if(m_isEnabled)
- {
- // enable -> start doing things :)
- m_timer.start();
- }
- else
- {
- // disable -> stop the timer
- m_timer.stop();
- }
+ // state change to the same is not valid.
+ if(m_isEnabled == state)
+ {
+ return;
+ }
+
+ m_isEnabled = state;
+ if(m_isEnabled)
+ {
+ // enable -> start doing things :)
+ m_timer.start();
+ }
+ else
+ {
+ // disable -> stop the timer
+ m_timer.stop();
+ }
}
void GAnalyticsWorker::logMessage(GAnalytics::LogLevel level, const QString &message)
{
- if (m_logLevel > level)
- {
- return;
- }
+ if (m_logLevel > level)
+ {
+ return;
+ }
- qDebug() << "[Analytics]" << message;
+ qDebug() << "[Analytics]" << message;
}
/**
@@ -66,23 +66,23 @@ void GAnalyticsWorker::logMessage(GAnalytics::LogLevel level, const QString &mes
*/
QUrlQuery GAnalyticsWorker::buildStandardPostQuery(const QString &type)
{
- QUrlQuery query;
- query.addQueryItem("v", "1");
- query.addQueryItem("tid", m_trackingID);
- query.addQueryItem("cid", m_clientID);
- if (!m_userID.isEmpty())
- {
- query.addQueryItem("uid", m_userID);
- }
- query.addQueryItem("t", type);
- query.addQueryItem("ul", m_language);
- query.addQueryItem("vp", m_viewportSize);
- query.addQueryItem("sr", m_screenResolution);
- if(m_anonymizeIPs)
- {
- query.addQueryItem("aip", "1");
- }
- return query;
+ QUrlQuery query;
+ query.addQueryItem("v", "1");
+ query.addQueryItem("tid", m_trackingID);
+ query.addQueryItem("cid", m_clientID);
+ if (!m_userID.isEmpty())
+ {
+ query.addQueryItem("uid", m_userID);
+ }
+ query.addQueryItem("t", type);
+ query.addQueryItem("ul", m_language);
+ query.addQueryItem("vp", m_viewportSize);
+ query.addQueryItem("sr", m_screenResolution);
+ if(m_anonymizeIPs)
+ {
+ query.addQueryItem("aip", "1");
+ }
+ return query;
}
/**
@@ -91,10 +91,10 @@ QUrlQuery GAnalyticsWorker::buildStandardPostQuery(const QString &type)
*/
QString GAnalyticsWorker::getScreenResolution()
{
- QScreen *screen = QGuiApplication::primaryScreen();
- QSize size = screen->size();
+ QScreen *screen = QGuiApplication::primaryScreen();
+ QSize size = screen->size();
- return QString("%1x%2").arg(size.width()).arg(size.height());
+ return QString("%1x%2").arg(size.width()).arg(size.height());
}
/**
@@ -106,7 +106,7 @@ QString GAnalyticsWorker::getScreenResolution()
*/
QString GAnalyticsWorker::getUserAgent()
{
- return QString("%1/%2").arg(m_appName).arg(m_appVersion);
+ return QString("%1/%2").arg(m_appName).arg(m_appVersion);
}
/**
@@ -118,13 +118,13 @@ QString GAnalyticsWorker::getUserAgent()
*/
QList<QString> GAnalyticsWorker::persistMessageQueue()
{
- QList<QString> dataList;
- foreach (QueryBuffer buffer, m_messageQueue)
- {
- dataList << buffer.postQuery.toString();
- dataList << buffer.time.toString(dateTimeFormat);
- }
- return dataList;
+ QList<QString> dataList;
+ foreach (QueryBuffer buffer, m_messageQueue)
+ {
+ dataList << buffer.postQuery.toString();
+ dataList << buffer.time.toString(dateTimeFormat);
+ }
+ return dataList;
}
/**
@@ -134,19 +134,19 @@ QList<QString> GAnalyticsWorker::persistMessageQueue()
*/
void GAnalyticsWorker::readMessagesFromFile(const QList<QString> &dataList)
{
- QListIterator<QString> iter(dataList);
- while (iter.hasNext())
- {
- QString queryString = iter.next();
- QString dateString = iter.next();
- QUrlQuery query;
- query.setQuery(queryString);
- QDateTime dateTime = QDateTime::fromString(dateString, dateTimeFormat);
- QueryBuffer buffer;
- buffer.postQuery = query;
- buffer.time = dateTime;
- m_messageQueue.enqueue(buffer);
- }
+ QListIterator<QString> iter(dataList);
+ while (iter.hasNext())
+ {
+ QString queryString = iter.next();
+ QString dateString = iter.next();
+ QUrlQuery query;
+ query.setQuery(queryString);
+ QDateTime dateTime = QDateTime::fromString(dateString, dateTimeFormat);
+ QueryBuffer buffer;
+ buffer.postQuery = query;
+ buffer.time = dateTime;
+ m_messageQueue.enqueue(buffer);
+ }
}
/**
@@ -156,11 +156,11 @@ void GAnalyticsWorker::readMessagesFromFile(const QList<QString> &dataList)
*/
void GAnalyticsWorker::enqueQueryWithCurrentTime(const QUrlQuery &query)
{
- QueryBuffer buffer;
- buffer.postQuery = query;
- buffer.time = QDateTime::currentDateTime();
+ QueryBuffer buffer;
+ buffer.postQuery = query;
+ buffer.time = QDateTime::currentDateTime();
- m_messageQueue.enqueue(buffer);
+ m_messageQueue.enqueue(buffer);
}
/**
@@ -175,50 +175,50 @@ void GAnalyticsWorker::enqueQueryWithCurrentTime(const QUrlQuery &query)
*/
void GAnalyticsWorker::postMessage()
{
- if (m_messageQueue.isEmpty())
- {
- // queue empty -> try sending later
- m_timer.start();
- return;
- }
- else
- {
- // queue has messages -> stop timer and start sending
- m_timer.stop();
- }
-
- QString connection = "close";
- if (m_messageQueue.count() > 1)
- {
- connection = "keep-alive";
- }
-
- QueryBuffer buffer = m_messageQueue.head();
- QDateTime sendTime = QDateTime::currentDateTime();
- qint64 timeDiff = buffer.time.msecsTo(sendTime);
-
- if (timeDiff > fourHours)
- {
- // too old.
- m_messageQueue.dequeue();
- emit postMessage();
- return;
- }
-
- buffer.postQuery.addQueryItem("qt", QString::number(timeDiff));
- m_request.setRawHeader("Connection", connection.toUtf8());
- m_request.setHeader(QNetworkRequest::ContentLengthHeader, buffer.postQuery.toString().length());
-
- logMessage(GAnalytics::Debug, "Query string = " + buffer.postQuery.toString());
-
- // Create a new network access manager if we don't have one yet
- if (networkManager == NULL)
- {
- networkManager = new QNetworkAccessManager(this);
- }
-
- QNetworkReply *reply = networkManager->post(m_request, buffer.postQuery.query(QUrl::EncodeUnicode).toUtf8());
- connect(reply, SIGNAL(finished()), this, SLOT(postMessageFinished()));
+ if (m_messageQueue.isEmpty())
+ {
+ // queue empty -> try sending later
+ m_timer.start();
+ return;
+ }
+ else
+ {
+ // queue has messages -> stop timer and start sending
+ m_timer.stop();
+ }
+
+ QString connection = "close";
+ if (m_messageQueue.count() > 1)
+ {
+ connection = "keep-alive";
+ }
+
+ QueryBuffer buffer = m_messageQueue.head();
+ QDateTime sendTime = QDateTime::currentDateTime();
+ qint64 timeDiff = buffer.time.msecsTo(sendTime);
+
+ if (timeDiff > fourHours)
+ {
+ // too old.
+ m_messageQueue.dequeue();
+ emit postMessage();
+ return;
+ }
+
+ buffer.postQuery.addQueryItem("qt", QString::number(timeDiff));
+ m_request.setRawHeader("Connection", connection.toUtf8());
+ m_request.setHeader(QNetworkRequest::ContentLengthHeader, buffer.postQuery.toString().length());
+
+ logMessage(GAnalytics::Debug, "Query string = " + buffer.postQuery.toString());
+
+ // Create a new network access manager if we don't have one yet
+ if (networkManager == NULL)
+ {
+ networkManager = new QNetworkAccessManager(this);
+ }
+
+ QNetworkReply *reply = networkManager->post(m_request, buffer.postQuery.query(QUrl::EncodeUnicode).toUtf8());
+ connect(reply, SIGNAL(finished()), this, SLOT(postMessageFinished()));
}
/**
@@ -232,23 +232,23 @@ void GAnalyticsWorker::postMessage()
*/
void GAnalyticsWorker::postMessageFinished()
{
- QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
-
- int httpStausCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- if (httpStausCode < 200 || httpStausCode > 299)
- {
- logMessage(GAnalytics::Error, QString("Error posting message: %s").arg(reply->errorString()));
-
- // An error ocurred. Try sending later.
- m_timer.start();
- return;
- }
- else
- {
- logMessage(GAnalytics::Debug, "Message sent");
- }
-
- m_messageQueue.dequeue();
- postMessage();
- reply->deleteLater();
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+
+ int httpStausCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ if (httpStausCode < 200 || httpStausCode > 299)
+ {
+ logMessage(GAnalytics::Error, QString("Error posting message: %s").arg(reply->errorString()));
+
+ // An error ocurred. Try sending later.
+ m_timer.start();
+ return;
+ }
+ else
+ {
+ logMessage(GAnalytics::Debug, "Message sent");
+ }
+
+ m_messageQueue.dequeue();
+ postMessage();
+ reply->deleteLater();
}
diff --git a/libraries/ganalytics/src/ganalytics_worker.h b/libraries/ganalytics/src/ganalytics_worker.h
index 559e0eb6..1962f799 100644
--- a/libraries/ganalytics/src/ganalytics_worker.h
+++ b/libraries/ganalytics/src/ganalytics_worker.h
@@ -8,58 +8,58 @@
struct QueryBuffer
{
- QUrlQuery postQuery;
- QDateTime time;
+ QUrlQuery postQuery;
+ QDateTime time;
};
class GAnalyticsWorker : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit GAnalyticsWorker(GAnalytics *parent = 0);
+ explicit GAnalyticsWorker(GAnalytics *parent = 0);
- GAnalytics *q;
+ GAnalytics *q;
- QNetworkAccessManager *networkManager = nullptr;
+ QNetworkAccessManager *networkManager = nullptr;
- QQueue<QueryBuffer> m_messageQueue;
- QTimer m_timer;
- QNetworkRequest m_request;
- GAnalytics::LogLevel m_logLevel;
+ QQueue<QueryBuffer> m_messageQueue;
+ QTimer m_timer;
+ QNetworkRequest m_request;
+ GAnalytics::LogLevel m_logLevel;
- QString m_trackingID;
- QString m_clientID;
- QString m_userID;
- QString m_appName;
- QString m_appVersion;
- QString m_language;
- QString m_screenResolution;
- QString m_viewportSize;
+ QString m_trackingID;
+ QString m_clientID;
+ QString m_userID;
+ QString m_appName;
+ QString m_appVersion;
+ QString m_language;
+ QString m_screenResolution;
+ QString m_viewportSize;
- bool m_anonymizeIPs = false;
- bool m_isEnabled = false;
- int m_timerInterval = 30000;
- int m_version = 0;
+ bool m_anonymizeIPs = false;
+ bool m_isEnabled = false;
+ int m_timerInterval = 30000;
+ int m_version = 0;
- const static int fourHours = 4 * 60 * 60 * 1000;
- const static QLatin1String dateTimeFormat;
+ const static int fourHours = 4 * 60 * 60 * 1000;
+ const static QLatin1String dateTimeFormat;
public:
- void logMessage(GAnalytics::LogLevel level, const QString &message);
+ void logMessage(GAnalytics::LogLevel level, const QString &message);
- QUrlQuery buildStandardPostQuery(const QString &type);
- QString getScreenResolution();
- QString getUserAgent();
- QList<QString> persistMessageQueue();
- void readMessagesFromFile(const QList<QString> &dataList);
+ QUrlQuery buildStandardPostQuery(const QString &type);
+ QString getScreenResolution();
+ QString getUserAgent();
+ QList<QString> persistMessageQueue();
+ void readMessagesFromFile(const QList<QString> &dataList);
- void enqueQueryWithCurrentTime(const QUrlQuery &query);
- void setIsSending(bool doSend);
- void enable(bool state);
+ void enqueQueryWithCurrentTime(const QUrlQuery &query);
+ void setIsSending(bool doSend);
+ void enable(bool state);
public slots:
- void postMessage();
- void postMessageFinished();
+ void postMessage();
+ void postMessageFinished();
};
diff --git a/libraries/hoedown/include/hoedown/autolink.h b/libraries/hoedown/include/hoedown/autolink.h
index 528885c9..953e7807 100644
--- a/libraries/hoedown/include/hoedown/autolink.h
+++ b/libraries/hoedown/include/hoedown/autolink.h
@@ -15,7 +15,7 @@ extern "C" {
*************/
typedef enum hoedown_autolink_flags {
- HOEDOWN_AUTOLINK_SHORT_DOMAINS = (1 << 0)
+ HOEDOWN_AUTOLINK_SHORT_DOMAINS = (1 << 0)
} hoedown_autolink_flags;
@@ -28,15 +28,15 @@ int hoedown_autolink_is_safe(const uint8_t *data, size_t size);
/* hoedown_autolink__www: search for the next www link in data */
size_t hoedown_autolink__www(size_t *rewind_p, hoedown_buffer *link,
- uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags);
+ uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags);
/* hoedown_autolink__email: search for the next email in data */
size_t hoedown_autolink__email(size_t *rewind_p, hoedown_buffer *link,
- uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags);
+ uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags);
/* hoedown_autolink__url: search for the next URL in data */
size_t hoedown_autolink__url(size_t *rewind_p, hoedown_buffer *link,
- uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags);
+ uint8_t *data, size_t offset, size_t size, hoedown_autolink_flags flags);
#ifdef __cplusplus
diff --git a/libraries/hoedown/include/hoedown/buffer.h b/libraries/hoedown/include/hoedown/buffer.h
index d7703f8d..062d86ce 100644
--- a/libraries/hoedown/include/hoedown/buffer.h
+++ b/libraries/hoedown/include/hoedown/buffer.h
@@ -28,14 +28,14 @@ typedef void *(*hoedown_realloc_callback)(void *, size_t);
typedef void (*hoedown_free_callback)(void *);
struct hoedown_buffer {
- uint8_t *data; /* actual character data */
- size_t size; /* size of the string */
- size_t asize; /* allocated size (0 = volatile buffer) */
- size_t unit; /* reallocation unit size (0 = read-only buffer) */
-
- hoedown_realloc_callback data_realloc;
- hoedown_free_callback data_free;
- hoedown_free_callback buffer_free;
+ uint8_t *data; /* actual character data */
+ size_t size; /* size of the string */
+ size_t asize; /* allocated size (0 = volatile buffer) */
+ size_t unit; /* reallocation unit size (0 = read-only buffer) */
+
+ hoedown_realloc_callback data_realloc;
+ hoedown_free_callback data_free;
+ hoedown_free_callback buffer_free;
};
typedef struct hoedown_buffer hoedown_buffer;
@@ -52,11 +52,11 @@ void *hoedown_realloc(void *ptr, size_t size) __attribute__ ((malloc));
/* hoedown_buffer_init: initialize a buffer with custom allocators */
void hoedown_buffer_init(
- hoedown_buffer *buffer,
- size_t unit,
- hoedown_realloc_callback data_realloc,
- hoedown_free_callback data_free,
- hoedown_free_callback buffer_free
+ hoedown_buffer *buffer,
+ size_t unit,
+ hoedown_realloc_callback data_realloc,
+ hoedown_free_callback data_free,
+ hoedown_free_callback buffer_free
);
/* hoedown_buffer_uninit: uninitialize an existing buffer */
@@ -116,15 +116,15 @@ void hoedown_buffer_free(hoedown_buffer *buf);
/* HOEDOWN_BUFPUTSL: optimized hoedown_buffer_puts of a string literal */
#define HOEDOWN_BUFPUTSL(output, literal) \
- hoedown_buffer_put(output, (const uint8_t *)literal, sizeof(literal) - 1)
+ hoedown_buffer_put(output, (const uint8_t *)literal, sizeof(literal) - 1)
/* HOEDOWN_BUFSETSL: optimized hoedown_buffer_sets of a string literal */
#define HOEDOWN_BUFSETSL(output, literal) \
- hoedown_buffer_set(output, (const uint8_t *)literal, sizeof(literal) - 1)
+ hoedown_buffer_set(output, (const uint8_t *)literal, sizeof(literal) - 1)
/* HOEDOWN_BUFEQSL: optimized hoedown_buffer_eqs of a string literal */
#define HOEDOWN_BUFEQSL(output, literal) \
- hoedown_buffer_eq(output, (const uint8_t *)literal, sizeof(literal) - 1)
+ hoedown_buffer_eq(output, (const uint8_t *)literal, sizeof(literal) - 1)
#ifdef __cplusplus
diff --git a/libraries/hoedown/include/hoedown/document.h b/libraries/hoedown/include/hoedown/document.h
index a8178fec..210c565e 100644
--- a/libraries/hoedown/include/hoedown/document.h
+++ b/libraries/hoedown/include/hoedown/document.h
@@ -16,68 +16,68 @@ extern "C" {
*************/
typedef enum hoedown_extensions {
- /* block-level extensions */
- HOEDOWN_EXT_TABLES = (1 << 0),
- HOEDOWN_EXT_FENCED_CODE = (1 << 1),
- HOEDOWN_EXT_FOOTNOTES = (1 << 2),
-
- /* span-level extensions */
- HOEDOWN_EXT_AUTOLINK = (1 << 3),
- HOEDOWN_EXT_STRIKETHROUGH = (1 << 4),
- HOEDOWN_EXT_UNDERLINE = (1 << 5),
- HOEDOWN_EXT_HIGHLIGHT = (1 << 6),
- HOEDOWN_EXT_QUOTE = (1 << 7),
- HOEDOWN_EXT_SUPERSCRIPT = (1 << 8),
- HOEDOWN_EXT_MATH = (1 << 9),
-
- /* other flags */
- HOEDOWN_EXT_NO_INTRA_EMPHASIS = (1 << 11),
- HOEDOWN_EXT_SPACE_HEADERS = (1 << 12),
- HOEDOWN_EXT_MATH_EXPLICIT = (1 << 13),
-
- /* negative flags */
- HOEDOWN_EXT_DISABLE_INDENTED_CODE = (1 << 14)
+ /* block-level extensions */
+ HOEDOWN_EXT_TABLES = (1 << 0),
+ HOEDOWN_EXT_FENCED_CODE = (1 << 1),
+ HOEDOWN_EXT_FOOTNOTES = (1 << 2),
+
+ /* span-level extensions */
+ HOEDOWN_EXT_AUTOLINK = (1 << 3),
+ HOEDOWN_EXT_STRIKETHROUGH = (1 << 4),
+ HOEDOWN_EXT_UNDERLINE = (1 << 5),
+ HOEDOWN_EXT_HIGHLIGHT = (1 << 6),
+ HOEDOWN_EXT_QUOTE = (1 << 7),
+ HOEDOWN_EXT_SUPERSCRIPT = (1 << 8),
+ HOEDOWN_EXT_MATH = (1 << 9),
+
+ /* other flags */
+ HOEDOWN_EXT_NO_INTRA_EMPHASIS = (1 << 11),
+ HOEDOWN_EXT_SPACE_HEADERS = (1 << 12),
+ HOEDOWN_EXT_MATH_EXPLICIT = (1 << 13),
+
+ /* negative flags */
+ HOEDOWN_EXT_DISABLE_INDENTED_CODE = (1 << 14)
} hoedown_extensions;
#define HOEDOWN_EXT_BLOCK (\
- HOEDOWN_EXT_TABLES |\
- HOEDOWN_EXT_FENCED_CODE |\
- HOEDOWN_EXT_FOOTNOTES )
+ HOEDOWN_EXT_TABLES |\
+ HOEDOWN_EXT_FENCED_CODE |\
+ HOEDOWN_EXT_FOOTNOTES )
#define HOEDOWN_EXT_SPAN (\
- HOEDOWN_EXT_AUTOLINK |\
- HOEDOWN_EXT_STRIKETHROUGH |\
- HOEDOWN_EXT_UNDERLINE |\
- HOEDOWN_EXT_HIGHLIGHT |\
- HOEDOWN_EXT_QUOTE |\
- HOEDOWN_EXT_SUPERSCRIPT |\
- HOEDOWN_EXT_MATH )
+ HOEDOWN_EXT_AUTOLINK |\
+ HOEDOWN_EXT_STRIKETHROUGH |\
+ HOEDOWN_EXT_UNDERLINE |\
+ HOEDOWN_EXT_HIGHLIGHT |\
+ HOEDOWN_EXT_QUOTE |\
+ HOEDOWN_EXT_SUPERSCRIPT |\
+ HOEDOWN_EXT_MATH )
#define HOEDOWN_EXT_FLAGS (\
- HOEDOWN_EXT_NO_INTRA_EMPHASIS |\
- HOEDOWN_EXT_SPACE_HEADERS |\
- HOEDOWN_EXT_MATH_EXPLICIT )
+ HOEDOWN_EXT_NO_INTRA_EMPHASIS |\
+ HOEDOWN_EXT_SPACE_HEADERS |\
+ HOEDOWN_EXT_MATH_EXPLICIT )
#define HOEDOWN_EXT_NEGATIVE (\
- HOEDOWN_EXT_DISABLE_INDENTED_CODE )
+ HOEDOWN_EXT_DISABLE_INDENTED_CODE )
typedef enum hoedown_list_flags {
- HOEDOWN_LIST_ORDERED = (1 << 0),
- HOEDOWN_LI_BLOCK = (1 << 1) /* <li> containing block data */
+ HOEDOWN_LIST_ORDERED = (1 << 0),
+ HOEDOWN_LI_BLOCK = (1 << 1) /* <li> containing block data */
} hoedown_list_flags;
typedef enum hoedown_table_flags {
- HOEDOWN_TABLE_ALIGN_LEFT = 1,
- HOEDOWN_TABLE_ALIGN_RIGHT = 2,
- HOEDOWN_TABLE_ALIGN_CENTER = 3,
- HOEDOWN_TABLE_ALIGNMASK = 3,
- HOEDOWN_TABLE_HEADER = 4
+ HOEDOWN_TABLE_ALIGN_LEFT = 1,
+ HOEDOWN_TABLE_ALIGN_RIGHT = 2,
+ HOEDOWN_TABLE_ALIGN_CENTER = 3,
+ HOEDOWN_TABLE_ALIGNMASK = 3,
+ HOEDOWN_TABLE_HEADER = 4
} hoedown_table_flags;
typedef enum hoedown_autolink_type {
- HOEDOWN_AUTOLINK_NONE, /* used internally when it is not an autolink*/
- HOEDOWN_AUTOLINK_NORMAL, /* normal http/http/ftp/mailto/etc link */
- HOEDOWN_AUTOLINK_EMAIL /* e-mail link without explit mailto: */
+ HOEDOWN_AUTOLINK_NONE, /* used internally when it is not an autolink*/
+ HOEDOWN_AUTOLINK_NORMAL, /* normal http/http/ftp/mailto/etc link */
+ HOEDOWN_AUTOLINK_EMAIL /* e-mail link without explit mailto: */
} hoedown_autolink_type;
@@ -89,57 +89,57 @@ struct hoedown_document;
typedef struct hoedown_document hoedown_document;
struct hoedown_renderer_data {
- void *opaque;
+ void *opaque;
};
typedef struct hoedown_renderer_data hoedown_renderer_data;
/* hoedown_renderer - functions for rendering parsed data */
struct hoedown_renderer {
- /* state object */
- void *opaque;
-
- /* block level callbacks - NULL skips the block */
- void (*blockcode)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, const hoedown_renderer_data *data);
- void (*blockquote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- void (*header)(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data);
- void (*hrule)(hoedown_buffer *ob, const hoedown_renderer_data *data);
- void (*list)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data);
- void (*listitem)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data);
- void (*paragraph)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- void (*table)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- void (*table_header)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- void (*table_body)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- void (*table_row)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- void (*table_cell)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_table_flags flags, const hoedown_renderer_data *data);
- void (*footnotes)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- void (*footnote_def)(hoedown_buffer *ob, const hoedown_buffer *content, unsigned int num, const hoedown_renderer_data *data);
- void (*blockhtml)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
-
- /* span level callbacks - NULL or return 0 prints the span verbatim */
- int (*autolink)(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, const hoedown_renderer_data *data);
- int (*codespan)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
- int (*double_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- int (*emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- int (*underline)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- int (*highlight)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- int (*quote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- int (*image)(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, const hoedown_renderer_data *data);
- int (*linebreak)(hoedown_buffer *ob, const hoedown_renderer_data *data);
- int (*link)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data);
- int (*triple_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- int (*strikethrough)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- int (*superscript)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
- int (*footnote_ref)(hoedown_buffer *ob, unsigned int num, const hoedown_renderer_data *data);
- int (*math)(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, const hoedown_renderer_data *data);
- int (*raw_html)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
-
- /* low level callbacks - NULL copies input directly into the output */
- void (*entity)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
- void (*normal_text)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
-
- /* miscellaneous callbacks */
- void (*doc_header)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data);
- void (*doc_footer)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data);
+ /* state object */
+ void *opaque;
+
+ /* block level callbacks - NULL skips the block */
+ void (*blockcode)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, const hoedown_renderer_data *data);
+ void (*blockquote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ void (*header)(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data);
+ void (*hrule)(hoedown_buffer *ob, const hoedown_renderer_data *data);
+ void (*list)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data);
+ void (*listitem)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data);
+ void (*paragraph)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ void (*table)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ void (*table_header)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ void (*table_body)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ void (*table_row)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ void (*table_cell)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_table_flags flags, const hoedown_renderer_data *data);
+ void (*footnotes)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ void (*footnote_def)(hoedown_buffer *ob, const hoedown_buffer *content, unsigned int num, const hoedown_renderer_data *data);
+ void (*blockhtml)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
+
+ /* span level callbacks - NULL or return 0 prints the span verbatim */
+ int (*autolink)(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, const hoedown_renderer_data *data);
+ int (*codespan)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
+ int (*double_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ int (*emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ int (*underline)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ int (*highlight)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ int (*quote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ int (*image)(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, const hoedown_renderer_data *data);
+ int (*linebreak)(hoedown_buffer *ob, const hoedown_renderer_data *data);
+ int (*link)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data);
+ int (*triple_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ int (*strikethrough)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ int (*superscript)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data);
+ int (*footnote_ref)(hoedown_buffer *ob, unsigned int num, const hoedown_renderer_data *data);
+ int (*math)(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, const hoedown_renderer_data *data);
+ int (*raw_html)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
+
+ /* low level callbacks - NULL copies input directly into the output */
+ void (*entity)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
+ void (*normal_text)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);
+
+ /* miscellaneous callbacks */
+ void (*doc_header)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data);
+ void (*doc_footer)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data);
};
typedef struct hoedown_renderer hoedown_renderer;
@@ -150,9 +150,9 @@ typedef struct hoedown_renderer hoedown_renderer;
/* hoedown_document_new: allocate a new document processor instance */
hoedown_document *hoedown_document_new(
- const hoedown_renderer *renderer,
- hoedown_extensions extensions,
- size_t max_nesting
+ const hoedown_renderer *renderer,
+ hoedown_extensions extensions,
+ size_t max_nesting
) __attribute__ ((malloc));
/* hoedown_document_render: render regular Markdown using the document processor */
diff --git a/libraries/hoedown/include/hoedown/html.h b/libraries/hoedown/include/hoedown/html.h
index e46e7fd6..7c68809a 100644
--- a/libraries/hoedown/include/hoedown/html.h
+++ b/libraries/hoedown/include/hoedown/html.h
@@ -16,16 +16,16 @@ extern "C" {
*************/
typedef enum hoedown_html_flags {
- HOEDOWN_HTML_SKIP_HTML = (1 << 0),
- HOEDOWN_HTML_ESCAPE = (1 << 1),
- HOEDOWN_HTML_HARD_WRAP = (1 << 2),
- HOEDOWN_HTML_USE_XHTML = (1 << 3)
+ HOEDOWN_HTML_SKIP_HTML = (1 << 0),
+ HOEDOWN_HTML_ESCAPE = (1 << 1),
+ HOEDOWN_HTML_HARD_WRAP = (1 << 2),
+ HOEDOWN_HTML_USE_XHTML = (1 << 3)
} hoedown_html_flags;
typedef enum hoedown_html_tag {
- HOEDOWN_HTML_TAG_NONE = 0,
- HOEDOWN_HTML_TAG_OPEN,
- HOEDOWN_HTML_TAG_CLOSE
+ HOEDOWN_HTML_TAG_NONE = 0,
+ HOEDOWN_HTML_TAG_OPEN,
+ HOEDOWN_HTML_TAG_CLOSE
} hoedown_html_tag;
@@ -34,19 +34,19 @@ typedef enum hoedown_html_tag {
*********/
struct hoedown_html_renderer_state {
- void *opaque;
+ void *opaque;
- struct {
- int header_count;
- int current_level;
- int level_offset;
- int nesting_level;
- } toc_data;
+ struct {
+ int header_count;
+ int current_level;
+ int level_offset;
+ int nesting_level;
+ } toc_data;
- hoedown_html_flags flags;
+ hoedown_html_flags flags;
- /* extra callbacks */
- void (*link_attributes)(hoedown_buffer *ob, const hoedown_buffer *url, const hoedown_renderer_data *data);
+ /* extra callbacks */
+ void (*link_attributes)(hoedown_buffer *ob, const hoedown_buffer *url, const hoedown_renderer_data *data);
};
typedef struct hoedown_html_renderer_state hoedown_html_renderer_state;
@@ -64,13 +64,13 @@ hoedown_html_tag hoedown_html_is_tag(const uint8_t *data, size_t size, const cha
/* hoedown_html_renderer_new: allocates a regular HTML renderer */
hoedown_renderer *hoedown_html_renderer_new(
- hoedown_html_flags render_flags,
- int nesting_level
+ hoedown_html_flags render_flags,
+ int nesting_level
) __attribute__ ((malloc));
/* hoedown_html_toc_renderer_new: like hoedown_html_renderer_new, but the returned renderer produces the Table of Contents */
hoedown_renderer *hoedown_html_toc_renderer_new(
- int nesting_level
+ int nesting_level
) __attribute__ ((malloc));
/* hoedown_html_renderer_free: deallocate an HTML renderer */
diff --git a/libraries/hoedown/include/hoedown/stack.h b/libraries/hoedown/include/hoedown/stack.h
index bf9b439b..d1855f4f 100644
--- a/libraries/hoedown/include/hoedown/stack.h
+++ b/libraries/hoedown/include/hoedown/stack.h
@@ -15,9 +15,9 @@ extern "C" {
*********/
struct hoedown_stack {
- void **item;
- size_t size;
- size_t asize;
+ void **item;
+ size_t size;
+ size_t asize;
};
typedef struct hoedown_stack hoedown_stack;
diff --git a/libraries/hoedown/src/autolink.c b/libraries/hoedown/src/autolink.c
index 9bc7fad5..3063b1a0 100644
--- a/libraries/hoedown/src/autolink.c
+++ b/libraries/hoedown/src/autolink.c
@@ -8,274 +8,274 @@
#ifndef _MSC_VER
#include <strings.h>
#else
-#define strncasecmp _strnicmp
+#define strncasecmp _strnicmp
#endif
int
hoedown_autolink_is_safe(const uint8_t *data, size_t size)
{
- static const size_t valid_uris_count = 6;
- static const char *valid_uris[] = {
- "http://", "https://", "/", "#", "ftp://", "mailto:"
- };
- static const size_t valid_uris_size[] = { 7, 8, 1, 1, 6, 7 };
- size_t i;
-
- for (i = 0; i < valid_uris_count; ++i) {
- size_t len = valid_uris_size[i];
-
- if (size > len &&
- strncasecmp((char *)data, valid_uris[i], len) == 0 &&
- isalnum(data[len]))
- return 1;
- }
-
- return 0;
+ static const size_t valid_uris_count = 6;
+ static const char *valid_uris[] = {
+ "http://", "https://", "/", "#", "ftp://", "mailto:"
+ };
+ static const size_t valid_uris_size[] = { 7, 8, 1, 1, 6, 7 };
+ size_t i;
+
+ for (i = 0; i < valid_uris_count; ++i) {
+ size_t len = valid_uris_size[i];
+
+ if (size > len &&
+ strncasecmp((char *)data, valid_uris[i], len) == 0 &&
+ isalnum(data[len]))
+ return 1;
+ }
+
+ return 0;
}
static size_t
autolink_delim(uint8_t *data, size_t link_end, size_t max_rewind, size_t size)
{
- uint8_t cclose, copen = 0;
- size_t i;
-
- for (i = 0; i < link_end; ++i)
- if (data[i] == '<') {
- link_end = i;
- break;
- }
-
- while (link_end > 0) {
- if (strchr("?!.,:", data[link_end - 1]) != NULL)
- link_end--;
-
- else if (data[link_end - 1] == ';') {
- size_t new_end = link_end - 2;
-
- while (new_end > 0 && isalpha(data[new_end]))
- new_end--;
-
- if (new_end < link_end - 2 && data[new_end] == '&')
- link_end = new_end;
- else
- link_end--;
- }
- else break;
- }
-
- if (link_end == 0)
- return 0;
-
- cclose = data[link_end - 1];
-
- switch (cclose) {
- case '"': copen = '"'; break;
- case '\'': copen = '\''; break;
- case ')': copen = '('; break;
- case ']': copen = '['; break;
- case '}': copen = '{'; break;
- }
-
- if (copen != 0) {
- size_t closing = 0;
- size_t opening = 0;
- size_t i = 0;
-
- /* Try to close the final punctuation sign in this same line;
- * if we managed to close it outside of the URL, that means that it's
- * not part of the URL. If it closes inside the URL, that means it
- * is part of the URL.
- *
- * Examples:
- *
- * foo http://www.pokemon.com/Pikachu_(Electric) bar
- * => http://www.pokemon.com/Pikachu_(Electric)
- *
- * foo (http://www.pokemon.com/Pikachu_(Electric)) bar
- * => http://www.pokemon.com/Pikachu_(Electric)
- *
- * foo http://www.pokemon.com/Pikachu_(Electric)) bar
- * => http://www.pokemon.com/Pikachu_(Electric))
- *
- * (foo http://www.pokemon.com/Pikachu_(Electric)) bar
- * => foo http://www.pokemon.com/Pikachu_(Electric)
- */
-
- while (i < link_end) {
- if (data[i] == copen)
- opening++;
- else if (data[i] == cclose)
- closing++;
-
- i++;
- }
-
- if (closing != opening)
- link_end--;
- }
-
- return link_end;
+ uint8_t cclose, copen = 0;
+ size_t i;
+
+ for (i = 0; i < link_end; ++i)
+ if (data[i] == '<') {
+ link_end = i;
+ break;
+ }
+
+ while (link_end > 0) {
+ if (strchr("?!.,:", data[link_end - 1]) != NULL)
+ link_end--;
+
+ else if (data[link_end - 1] == ';') {
+ size_t new_end = link_end - 2;
+
+ while (new_end > 0 && isalpha(data[new_end]))
+ new_end--;
+
+ if (new_end < link_end - 2 && data[new_end] == '&')
+ link_end = new_end;
+ else
+ link_end--;
+ }
+ else break;
+ }
+
+ if (link_end == 0)
+ return 0;
+
+ cclose = data[link_end - 1];
+
+ switch (cclose) {
+ case '"': copen = '"'; break;
+ case '\'': copen = '\''; break;
+ case ')': copen = '('; break;
+ case ']': copen = '['; break;
+ case '}': copen = '{'; break;
+ }
+
+ if (copen != 0) {
+ size_t closing = 0;
+ size_t opening = 0;
+ size_t i = 0;
+
+ /* Try to close the final punctuation sign in this same line;
+ * if we managed to close it outside of the URL, that means that it's
+ * not part of the URL. If it closes inside the URL, that means it
+ * is part of the URL.
+ *
+ * Examples:
+ *
+ * foo http://www.pokemon.com/Pikachu_(Electric) bar
+ * => http://www.pokemon.com/Pikachu_(Electric)
+ *
+ * foo (http://www.pokemon.com/Pikachu_(Electric)) bar
+ * => http://www.pokemon.com/Pikachu_(Electric)
+ *
+ * foo http://www.pokemon.com/Pikachu_(Electric)) bar
+ * => http://www.pokemon.com/Pikachu_(Electric))
+ *
+ * (foo http://www.pokemon.com/Pikachu_(Electric)) bar
+ * => foo http://www.pokemon.com/Pikachu_(Electric)
+ */
+
+ while (i < link_end) {
+ if (data[i] == copen)
+ opening++;
+ else if (data[i] == cclose)
+ closing++;
+
+ i++;
+ }
+
+ if (closing != opening)
+ link_end--;
+ }
+
+ return link_end;
}
static size_t
check_domain(uint8_t *data, size_t size, int allow_short)
{
- size_t i, np = 0;
-
- if (!isalnum(data[0]))
- return 0;
-
- for (i = 1; i < size - 1; ++i) {
- if (strchr(".:", data[i]) != NULL) np++;
- else if (!isalnum(data[i]) && data[i] != '-') break;
- }
-
- if (allow_short) {
- /* We don't need a valid domain in the strict sense (with
- * least one dot; so just make sure it's composed of valid
- * domain characters and return the length of the the valid
- * sequence. */
- return i;
- } else {
- /* a valid domain needs to have at least a dot.
- * that's as far as we get */
- return np ? i : 0;
- }
+ size_t i, np = 0;
+
+ if (!isalnum(data[0]))
+ return 0;
+
+ for (i = 1; i < size - 1; ++i) {
+ if (strchr(".:", data[i]) != NULL) np++;
+ else if (!isalnum(data[i]) && data[i] != '-') break;
+ }
+
+ if (allow_short) {
+ /* We don't need a valid domain in the strict sense (with
+ * least one dot; so just make sure it's composed of valid
+ * domain characters and return the length of the the valid
+ * sequence. */
+ return i;
+ } else {
+ /* a valid domain needs to have at least a dot.
+ * that's as far as we get */
+ return np ? i : 0;
+ }
}
size_t
hoedown_autolink__www(
- size_t *rewind_p,
- hoedown_buffer *link,
- uint8_t *data,
- size_t max_rewind,
- size_t size,
- unsigned int flags)
+ size_t *rewind_p,
+ hoedown_buffer *link,
+ uint8_t *data,
+ size_t max_rewind,
+ size_t size,
+ unsigned int flags)
{
- size_t link_end;
+ size_t link_end;
- if (max_rewind > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
- return 0;
+ if (max_rewind > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
+ return 0;
- if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
- return 0;
+ if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
+ return 0;
- link_end = check_domain(data, size, 0);
+ link_end = check_domain(data, size, 0);
- if (link_end == 0)
- return 0;
+ if (link_end == 0)
+ return 0;
- while (link_end < size && !isspace(data[link_end]))
- link_end++;
+ while (link_end < size && !isspace(data[link_end]))
+ link_end++;
- link_end = autolink_delim(data, link_end, max_rewind, size);
+ link_end = autolink_delim(data, link_end, max_rewind, size);
- if (link_end == 0)
- return 0;
+ if (link_end == 0)
+ return 0;
- hoedown_buffer_put(link, data, link_end);
- *rewind_p = 0;
+ hoedown_buffer_put(link, data, link_end);
+ *rewind_p = 0;
- return (int)link_end;
+ return (int)link_end;
}
size_t
hoedown_autolink__email(
- size_t *rewind_p,
- hoedown_buffer *link,
- uint8_t *data,
- size_t max_rewind,
- size_t size,
- unsigned int flags)
+ size_t *rewind_p,
+ hoedown_buffer *link,
+ uint8_t *data,
+ size_t max_rewind,
+ size_t size,
+ unsigned int flags)
{
- size_t link_end, rewind;
- int nb = 0, np = 0;
+ size_t link_end, rewind;
+ int nb = 0, np = 0;
- for (rewind = 0; rewind < max_rewind; ++rewind) {
- uint8_t c = data[-1 - rewind];
+ for (rewind = 0; rewind < max_rewind; ++rewind) {
+ uint8_t c = data[-1 - rewind];
- if (isalnum(c))
- continue;
+ if (isalnum(c))
+ continue;
- if (strchr(".+-_", c) != NULL)
- continue;
+ if (strchr(".+-_", c) != NULL)
+ continue;
- break;
- }
+ break;
+ }
- if (rewind == 0)
- return 0;
+ if (rewind == 0)
+ return 0;
- for (link_end = 0; link_end < size; ++link_end) {
- uint8_t c = data[link_end];
+ for (link_end = 0; link_end < size; ++link_end) {
+ uint8_t c = data[link_end];
- if (isalnum(c))
- continue;
+ if (isalnum(c))
+ continue;
- if (c == '@')
- nb++;
- else if (c == '.' && link_end < size - 1)
- np++;
- else if (c != '-' && c != '_')
- break;
- }
+ if (c == '@')
+ nb++;
+ else if (c == '.' && link_end < size - 1)
+ np++;
+ else if (c != '-' && c != '_')
+ break;
+ }
- if (link_end < 2 || nb != 1 || np == 0 ||
- !isalpha(data[link_end - 1]))
- return 0;
+ if (link_end < 2 || nb != 1 || np == 0 ||
+ !isalpha(data[link_end - 1]))
+ return 0;
- link_end = autolink_delim(data, link_end, max_rewind, size);
+ link_end = autolink_delim(data, link_end, max_rewind, size);
- if (link_end == 0)
- return 0;
+ if (link_end == 0)
+ return 0;
- hoedown_buffer_put(link, data - rewind, link_end + rewind);
- *rewind_p = rewind;
+ hoedown_buffer_put(link, data - rewind, link_end + rewind);
+ *rewind_p = rewind;
- return link_end;
+ return link_end;
}
size_t
hoedown_autolink__url(
- size_t *rewind_p,
- hoedown_buffer *link,
- uint8_t *data,
- size_t max_rewind,
- size_t size,
- unsigned int flags)
+ size_t *rewind_p,
+ hoedown_buffer *link,
+ uint8_t *data,
+ size_t max_rewind,
+ size_t size,
+ unsigned int flags)
{
- size_t link_end, rewind = 0, domain_len;
+ size_t link_end, rewind = 0, domain_len;
- if (size < 4 || data[1] != '/' || data[2] != '/')
- return 0;
+ if (size < 4 || data[1] != '/' || data[2] != '/')
+ return 0;
- while (rewind < max_rewind && isalpha(data[-1 - rewind]))
- rewind++;
+ while (rewind < max_rewind && isalpha(data[-1 - rewind]))
+ rewind++;
- if (!hoedown_autolink_is_safe(data - rewind, size + rewind))
- return 0;
+ if (!hoedown_autolink_is_safe(data - rewind, size + rewind))
+ return 0;
- link_end = strlen("://");
+ link_end = strlen("://");
- domain_len = check_domain(
- data + link_end,
- size - link_end,
- flags & HOEDOWN_AUTOLINK_SHORT_DOMAINS);
+ domain_len = check_domain(
+ data + link_end,
+ size - link_end,
+ flags & HOEDOWN_AUTOLINK_SHORT_DOMAINS);
- if (domain_len == 0)
- return 0;
+ if (domain_len == 0)
+ return 0;
- link_end += domain_len;
- while (link_end < size && !isspace(data[link_end]))
- link_end++;
+ link_end += domain_len;
+ while (link_end < size && !isspace(data[link_end]))
+ link_end++;
- link_end = autolink_delim(data, link_end, max_rewind, size);
+ link_end = autolink_delim(data, link_end, max_rewind, size);
- if (link_end == 0)
- return 0;
+ if (link_end == 0)
+ return 0;
- hoedown_buffer_put(link, data - rewind, link_end + rewind);
- *rewind_p = rewind;
+ hoedown_buffer_put(link, data - rewind, link_end + rewind);
+ *rewind_p = rewind;
- return link_end;
+ return link_end;
}
diff --git a/libraries/hoedown/src/buffer.c b/libraries/hoedown/src/buffer.c
index 1c7ba55a..024a8bcc 100644
--- a/libraries/hoedown/src/buffer.c
+++ b/libraries/hoedown/src/buffer.c
@@ -8,301 +8,301 @@
void *
hoedown_malloc(size_t size)
{
- void *ret = malloc(size);
+ void *ret = malloc(size);
- if (!ret) {
- fprintf(stderr, "Allocation failed.\n");
- abort();
- }
+ if (!ret) {
+ fprintf(stderr, "Allocation failed.\n");
+ abort();
+ }
- return ret;
+ return ret;
}
void *
hoedown_calloc(size_t nmemb, size_t size)
{
- void *ret = calloc(nmemb, size);
+ void *ret = calloc(nmemb, size);
- if (!ret) {
- fprintf(stderr, "Allocation failed.\n");
- abort();
- }
+ if (!ret) {
+ fprintf(stderr, "Allocation failed.\n");
+ abort();
+ }
- return ret;
+ return ret;
}
void *
hoedown_realloc(void *ptr, size_t size)
{
- void *ret = realloc(ptr, size);
+ void *ret = realloc(ptr, size);
- if (!ret) {
- fprintf(stderr, "Allocation failed.\n");
- abort();
- }
+ if (!ret) {
+ fprintf(stderr, "Allocation failed.\n");
+ abort();
+ }
- return ret;
+ return ret;
}
void
hoedown_buffer_init(
- hoedown_buffer *buf,
- size_t unit,
- hoedown_realloc_callback data_realloc,
- hoedown_free_callback data_free,
- hoedown_free_callback buffer_free)
+ hoedown_buffer *buf,
+ size_t unit,
+ hoedown_realloc_callback data_realloc,
+ hoedown_free_callback data_free,
+ hoedown_free_callback buffer_free)
{
- assert(buf);
-
- buf->data = NULL;
- buf->size = buf->asize = 0;
- buf->unit = unit;
- buf->data_realloc = data_realloc;
- buf->data_free = data_free;
- buf->buffer_free = buffer_free;
+ assert(buf);
+
+ buf->data = NULL;
+ buf->size = buf->asize = 0;
+ buf->unit = unit;
+ buf->data_realloc = data_realloc;
+ buf->data_free = data_free;
+ buf->buffer_free = buffer_free;
}
void
hoedown_buffer_uninit(hoedown_buffer *buf)
{
- assert(buf && buf->unit);
- buf->data_free(buf->data);
+ assert(buf && buf->unit);
+ buf->data_free(buf->data);
}
hoedown_buffer *
hoedown_buffer_new(size_t unit)
{
- hoedown_buffer *ret = hoedown_malloc(sizeof (hoedown_buffer));
- hoedown_buffer_init(ret, unit, hoedown_realloc, free, free);
- return ret;
+ hoedown_buffer *ret = hoedown_malloc(sizeof (hoedown_buffer));
+ hoedown_buffer_init(ret, unit, hoedown_realloc, free, free);
+ return ret;
}
void
hoedown_buffer_free(hoedown_buffer *buf)
{
- if (!buf) return;
- assert(buf && buf->unit);
+ if (!buf) return;
+ assert(buf && buf->unit);
- buf->data_free(buf->data);
+ buf->data_free(buf->data);
- if (buf->buffer_free)
- buf->buffer_free(buf);
+ if (buf->buffer_free)
+ buf->buffer_free(buf);
}
void
hoedown_buffer_reset(hoedown_buffer *buf)
{
- assert(buf && buf->unit);
+ assert(buf && buf->unit);
- buf->data_free(buf->data);
- buf->data = NULL;
- buf->size = buf->asize = 0;
+ buf->data_free(buf->data);
+ buf->data = NULL;
+ buf->size = buf->asize = 0;
}
void
hoedown_buffer_grow(hoedown_buffer *buf, size_t neosz)
{
- size_t neoasz;
- assert(buf && buf->unit);
+ size_t neoasz;
+ assert(buf && buf->unit);
- if (buf->asize >= neosz)
- return;
+ if (buf->asize >= neosz)
+ return;
- neoasz = buf->asize + buf->unit;
- while (neoasz < neosz)
- neoasz += buf->unit;
+ neoasz = buf->asize + buf->unit;
+ while (neoasz < neosz)
+ neoasz += buf->unit;
- buf->data = (uint8_t *) buf->data_realloc(buf->data, neoasz);
- buf->asize = neoasz;
+ buf->data = (uint8_t *) buf->data_realloc(buf->data, neoasz);
+ buf->asize = neoasz;
}
void
hoedown_buffer_put(hoedown_buffer *buf, const uint8_t *data, size_t size)
{
- assert(buf && buf->unit);
+ assert(buf && buf->unit);
- if (buf->size + size > buf->asize)
- hoedown_buffer_grow(buf, buf->size + size);
+ if (buf->size + size > buf->asize)
+ hoedown_buffer_grow(buf, buf->size + size);
- memcpy(buf->data + buf->size, data, size);
- buf->size += size;
+ memcpy(buf->data + buf->size, data, size);
+ buf->size += size;
}
void
hoedown_buffer_puts(hoedown_buffer *buf, const char *str)
{
- hoedown_buffer_put(buf, (const uint8_t *)str, strlen(str));
+ hoedown_buffer_put(buf, (const uint8_t *)str, strlen(str));
}
void
hoedown_buffer_putc(hoedown_buffer *buf, uint8_t c)
{
- assert(buf && buf->unit);
+ assert(buf && buf->unit);
- if (buf->size >= buf->asize)
- hoedown_buffer_grow(buf, buf->size + 1);
+ if (buf->size >= buf->asize)
+ hoedown_buffer_grow(buf, buf->size + 1);
- buf->data[buf->size] = c;
- buf->size += 1;
+ buf->data[buf->size] = c;
+ buf->size += 1;
}
int
hoedown_buffer_putf(hoedown_buffer *buf, FILE *file)
{
- assert(buf && buf->unit);
+ assert(buf && buf->unit);
- while (!(feof(file) || ferror(file))) {
- hoedown_buffer_grow(buf, buf->size + buf->unit);
- buf->size += fread(buf->data + buf->size, 1, buf->unit, file);
- }
+ while (!(feof(file) || ferror(file))) {
+ hoedown_buffer_grow(buf, buf->size + buf->unit);
+ buf->size += fread(buf->data + buf->size, 1, buf->unit, file);
+ }
- return ferror(file);
+ return ferror(file);
}
void
hoedown_buffer_set(hoedown_buffer *buf, const uint8_t *data, size_t size)
{
- assert(buf && buf->unit);
+ assert(buf && buf->unit);
- if (size > buf->asize)
- hoedown_buffer_grow(buf, size);
+ if (size > buf->asize)
+ hoedown_buffer_grow(buf, size);
- memcpy(buf->data, data, size);
- buf->size = size;
+ memcpy(buf->data, data, size);
+ buf->size = size;
}
void
hoedown_buffer_sets(hoedown_buffer *buf, const char *str)
{
- hoedown_buffer_set(buf, (const uint8_t *)str, strlen(str));
+ hoedown_buffer_set(buf, (const uint8_t *)str, strlen(str));
}
int
hoedown_buffer_eq(const hoedown_buffer *buf, const uint8_t *data, size_t size)
{
- if (buf->size != size) return 0;
- return memcmp(buf->data, data, size) == 0;
+ if (buf->size != size) return 0;
+ return memcmp(buf->data, data, size) == 0;
}
int
hoedown_buffer_eqs(const hoedown_buffer *buf, const char *str)
{
- return hoedown_buffer_eq(buf, (const uint8_t *)str, strlen(str));
+ return hoedown_buffer_eq(buf, (const uint8_t *)str, strlen(str));
}
int
hoedown_buffer_prefix(const hoedown_buffer *buf, const char *prefix)
{
- size_t i;
+ size_t i;
- for (i = 0; i < buf->size; ++i) {
- if (prefix[i] == 0)
- return 0;
+ for (i = 0; i < buf->size; ++i) {
+ if (prefix[i] == 0)
+ return 0;
- if (buf->data[i] != prefix[i])
- return buf->data[i] - prefix[i];
- }
+ if (buf->data[i] != prefix[i])
+ return buf->data[i] - prefix[i];
+ }
- return 0;
+ return 0;
}
void
hoedown_buffer_slurp(hoedown_buffer *buf, size_t size)
{
- assert(buf && buf->unit);
+ assert(buf && buf->unit);
- if (size >= buf->size) {
- buf->size = 0;
- return;
- }
+ if (size >= buf->size) {
+ buf->size = 0;
+ return;
+ }
- buf->size -= size;
- memmove(buf->data, buf->data + size, buf->size);
+ buf->size -= size;
+ memmove(buf->data, buf->data + size, buf->size);
}
const char *
hoedown_buffer_cstr(hoedown_buffer *buf)
{
- assert(buf && buf->unit);
+ assert(buf && buf->unit);
- if (buf->size < buf->asize && buf->data[buf->size] == 0)
- return (char *)buf->data;
+ if (buf->size < buf->asize && buf->data[buf->size] == 0)
+ return (char *)buf->data;
- hoedown_buffer_grow(buf, buf->size + 1);
- buf->data[buf->size] = 0;
+ hoedown_buffer_grow(buf, buf->size + 1);
+ buf->data[buf->size] = 0;
- return (char *)buf->data;
+ return (char *)buf->data;
}
void
hoedown_buffer_printf(hoedown_buffer *buf, const char *fmt, ...)
{
- va_list ap;
- int n;
+ va_list ap;
+ int n;
- assert(buf && buf->unit);
+ assert(buf && buf->unit);
- if (buf->size >= buf->asize)
- hoedown_buffer_grow(buf, buf->size + 1);
+ if (buf->size >= buf->asize)
+ hoedown_buffer_grow(buf, buf->size + 1);
- va_start(ap, fmt);
- n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
- va_end(ap);
+ va_start(ap, fmt);
+ n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
+ va_end(ap);
- if (n < 0) {
+ if (n < 0) {
#ifndef _MSC_VER
- return;
+ return;
#else
- va_start(ap, fmt);
- n = _vscprintf(fmt, ap);
- va_end(ap);
+ va_start(ap, fmt);
+ n = _vscprintf(fmt, ap);
+ va_end(ap);
#endif
- }
+ }
- if ((size_t)n >= buf->asize - buf->size) {
- hoedown_buffer_grow(buf, buf->size + n + 1);
+ if ((size_t)n >= buf->asize - buf->size) {
+ hoedown_buffer_grow(buf, buf->size + n + 1);
- va_start(ap, fmt);
- n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
- va_end(ap);
- }
+ va_start(ap, fmt);
+ n = vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
+ va_end(ap);
+ }
- if (n < 0)
- return;
+ if (n < 0)
+ return;
- buf->size += n;
+ buf->size += n;
}
void hoedown_buffer_put_utf8(hoedown_buffer *buf, unsigned int c) {
- unsigned char unichar[4];
-
- assert(buf && buf->unit);
-
- if (c < 0x80) {
- hoedown_buffer_putc(buf, c);
- }
- else if (c < 0x800) {
- unichar[0] = 192 + (c / 64);
- unichar[1] = 128 + (c % 64);
- hoedown_buffer_put(buf, unichar, 2);
- }
- else if (c - 0xd800u < 0x800) {
- HOEDOWN_BUFPUTSL(buf, "\xef\xbf\xbd");
- }
- else if (c < 0x10000) {
- unichar[0] = 224 + (c / 4096);
- unichar[1] = 128 + (c / 64) % 64;
- unichar[2] = 128 + (c % 64);
- hoedown_buffer_put(buf, unichar, 3);
- }
- else if (c < 0x110000) {
- unichar[0] = 240 + (c / 262144);
- unichar[1] = 128 + (c / 4096) % 64;
- unichar[2] = 128 + (c / 64) % 64;
- unichar[3] = 128 + (c % 64);
- hoedown_buffer_put(buf, unichar, 4);
- }
- else {
- HOEDOWN_BUFPUTSL(buf, "\xef\xbf\xbd");
- }
+ unsigned char unichar[4];
+
+ assert(buf && buf->unit);
+
+ if (c < 0x80) {
+ hoedown_buffer_putc(buf, c);
+ }
+ else if (c < 0x800) {
+ unichar[0] = 192 + (c / 64);
+ unichar[1] = 128 + (c % 64);
+ hoedown_buffer_put(buf, unichar, 2);
+ }
+ else if (c - 0xd800u < 0x800) {
+ HOEDOWN_BUFPUTSL(buf, "\xef\xbf\xbd");
+ }
+ else if (c < 0x10000) {
+ unichar[0] = 224 + (c / 4096);
+ unichar[1] = 128 + (c / 64) % 64;
+ unichar[2] = 128 + (c % 64);
+ hoedown_buffer_put(buf, unichar, 3);
+ }
+ else if (c < 0x110000) {
+ unichar[0] = 240 + (c / 262144);
+ unichar[1] = 128 + (c / 4096) % 64;
+ unichar[2] = 128 + (c / 64) % 64;
+ unichar[3] = 128 + (c % 64);
+ hoedown_buffer_put(buf, unichar, 4);
+ }
+ else {
+ HOEDOWN_BUFPUTSL(buf, "\xef\xbf\xbd");
+ }
}
diff --git a/libraries/hoedown/src/document.c b/libraries/hoedown/src/document.c
index 8ba82e47..e9e2ab11 100644
--- a/libraries/hoedown/src/document.c
+++ b/libraries/hoedown/src/document.c
@@ -10,7 +10,7 @@
#ifndef _MSC_VER
#include <strings.h>
#else
-#define strncasecmp _strnicmp
+#define strncasecmp _strnicmp
#endif
#define REF_TABLE_SIZE 8
@@ -18,7 +18,7 @@
#define BUFFER_BLOCK 0
#define BUFFER_SPAN 1
-#define HOEDOWN_LI_END 8 /* internal list flag */
+#define HOEDOWN_LI_END 8 /* internal list flag */
const char *hoedown_find_block_tag(const char *str, unsigned int len);
@@ -28,35 +28,35 @@ const char *hoedown_find_block_tag(const char *str, unsigned int len);
/* link_ref: reference to a link */
struct link_ref {
- unsigned int id;
+ unsigned int id;
- hoedown_buffer *link;
- hoedown_buffer *title;
+ hoedown_buffer *link;
+ hoedown_buffer *title;
- struct link_ref *next;
+ struct link_ref *next;
};
/* footnote_ref: reference to a footnote */
struct footnote_ref {
- unsigned int id;
+ unsigned int id;
- int is_used;
- unsigned int num;
+ int is_used;
+ unsigned int num;
- hoedown_buffer *contents;
+ hoedown_buffer *contents;
};
/* footnote_item: an item in a footnote_list */
struct footnote_item {
- struct footnote_ref *ref;
- struct footnote_item *next;
+ struct footnote_ref *ref;
+ struct footnote_item *next;
};
/* footnote_list: linked list of footnote_item */
struct footnote_list {
- unsigned int count;
- struct footnote_item *head;
- struct footnote_item *tail;
+ unsigned int count;
+ struct footnote_item *head;
+ struct footnote_item *tail;
};
/* char_trigger: function pointer to render active chars */
@@ -81,51 +81,51 @@ static size_t char_superscript(hoedown_buffer *ob, hoedown_document *doc, uint8_
static size_t char_math(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size);
enum markdown_char_t {
- MD_CHAR_NONE = 0,
- MD_CHAR_EMPHASIS,
- MD_CHAR_CODESPAN,
- MD_CHAR_LINEBREAK,
- MD_CHAR_LINK,
- MD_CHAR_LANGLE,
- MD_CHAR_ESCAPE,
- MD_CHAR_ENTITY,
- MD_CHAR_AUTOLINK_URL,
- MD_CHAR_AUTOLINK_EMAIL,
- MD_CHAR_AUTOLINK_WWW,
- MD_CHAR_SUPERSCRIPT,
- MD_CHAR_QUOTE,
- MD_CHAR_MATH
+ MD_CHAR_NONE = 0,
+ MD_CHAR_EMPHASIS,
+ MD_CHAR_CODESPAN,
+ MD_CHAR_LINEBREAK,
+ MD_CHAR_LINK,
+ MD_CHAR_LANGLE,
+ MD_CHAR_ESCAPE,
+ MD_CHAR_ENTITY,
+ MD_CHAR_AUTOLINK_URL,
+ MD_CHAR_AUTOLINK_EMAIL,
+ MD_CHAR_AUTOLINK_WWW,
+ MD_CHAR_SUPERSCRIPT,
+ MD_CHAR_QUOTE,
+ MD_CHAR_MATH
};
static char_trigger markdown_char_ptrs[] = {
- NULL,
- &char_emphasis,
- &char_codespan,
- &char_linebreak,
- &char_link,
- &char_langle_tag,
- &char_escape,
- &char_entity,
- &char_autolink_url,
- &char_autolink_email,
- &char_autolink_www,
- &char_superscript,
- &char_quote,
- &char_math
+ NULL,
+ &char_emphasis,
+ &char_codespan,
+ &char_linebreak,
+ &char_link,
+ &char_langle_tag,
+ &char_escape,
+ &char_entity,
+ &char_autolink_url,
+ &char_autolink_email,
+ &char_autolink_www,
+ &char_superscript,
+ &char_quote,
+ &char_math
};
struct hoedown_document {
- hoedown_renderer md;
- hoedown_renderer_data data;
-
- struct link_ref *refs[REF_TABLE_SIZE];
- struct footnote_list footnotes_found;
- struct footnote_list footnotes_used;
- uint8_t active_char[256];
- hoedown_stack work_bufs[2];
- hoedown_extensions ext_flags;
- size_t max_nesting;
- int in_link_body;
+ hoedown_renderer md;
+ hoedown_renderer_data data;
+
+ struct link_ref *refs[REF_TABLE_SIZE];
+ struct footnote_list footnotes_found;
+ struct footnote_list footnotes_used;
+ uint8_t active_char[256];
+ hoedown_stack work_bufs[2];
+ hoedown_extensions ext_flags;
+ size_t max_nesting;
+ int in_link_body;
};
/***************************
@@ -135,177 +135,177 @@ struct hoedown_document {
static hoedown_buffer *
newbuf(hoedown_document *doc, int type)
{
- static const size_t buf_size[2] = {256, 64};
- hoedown_buffer *work = NULL;
- hoedown_stack *pool = &doc->work_bufs[type];
+ static const size_t buf_size[2] = {256, 64};
+ hoedown_buffer *work = NULL;
+ hoedown_stack *pool = &doc->work_bufs[type];
- if (pool->size < pool->asize &&
- pool->item[pool->size] != NULL) {
- work = pool->item[pool->size++];
- work->size = 0;
- } else {
- work = hoedown_buffer_new(buf_size[type]);
- hoedown_stack_push(pool, work);
- }
+ if (pool->size < pool->asize &&
+ pool->item[pool->size] != NULL) {
+ work = pool->item[pool->size++];
+ work->size = 0;
+ } else {
+ work = hoedown_buffer_new(buf_size[type]);
+ hoedown_stack_push(pool, work);
+ }
- return work;
+ return work;
}
static void
popbuf(hoedown_document *doc, int type)
{
- doc->work_bufs[type].size--;
+ doc->work_bufs[type].size--;
}
static void
unscape_text(hoedown_buffer *ob, hoedown_buffer *src)
{
- size_t i = 0, org;
- while (i < src->size) {
- org = i;
- while (i < src->size && src->data[i] != '\\')
- i++;
+ size_t i = 0, org;
+ while (i < src->size) {
+ org = i;
+ while (i < src->size && src->data[i] != '\\')
+ i++;
- if (i > org)
- hoedown_buffer_put(ob, src->data + org, i - org);
+ if (i > org)
+ hoedown_buffer_put(ob, src->data + org, i - org);
- if (i + 1 >= src->size)
- break;
+ if (i + 1 >= src->size)
+ break;
- hoedown_buffer_putc(ob, src->data[i + 1]);
- i += 2;
- }
+ hoedown_buffer_putc(ob, src->data[i + 1]);
+ i += 2;
+ }
}
static unsigned int
hash_link_ref(const uint8_t *link_ref, size_t length)
{
- size_t i;
- unsigned int hash = 0;
+ size_t i;
+ unsigned int hash = 0;
- for (i = 0; i < length; ++i)
- hash = tolower(link_ref[i]) + (hash << 6) + (hash << 16) - hash;
+ for (i = 0; i < length; ++i)
+ hash = tolower(link_ref[i]) + (hash << 6) + (hash << 16) - hash;
- return hash;
+ return hash;
}
static struct link_ref *
add_link_ref(
- struct link_ref **references,
- const uint8_t *name, size_t name_size)
+ struct link_ref **references,
+ const uint8_t *name, size_t name_size)
{
- struct link_ref *ref = hoedown_calloc(1, sizeof(struct link_ref));
+ struct link_ref *ref = hoedown_calloc(1, sizeof(struct link_ref));
- ref->id = hash_link_ref(name, name_size);
- ref->next = references[ref->id % REF_TABLE_SIZE];
+ ref->id = hash_link_ref(name, name_size);
+ ref->next = references[ref->id % REF_TABLE_SIZE];
- references[ref->id % REF_TABLE_SIZE] = ref;
- return ref;
+ references[ref->id % REF_TABLE_SIZE] = ref;
+ return ref;
}
static struct link_ref *
find_link_ref(struct link_ref **references, uint8_t *name, size_t length)
{
- unsigned int hash = hash_link_ref(name, length);
- struct link_ref *ref = NULL;
+ unsigned int hash = hash_link_ref(name, length);
+ struct link_ref *ref = NULL;
- ref = references[hash % REF_TABLE_SIZE];
+ ref = references[hash % REF_TABLE_SIZE];
- while (ref != NULL) {
- if (ref->id == hash)
- return ref;
+ while (ref != NULL) {
+ if (ref->id == hash)
+ return ref;
- ref = ref->next;
- }
+ ref = ref->next;
+ }
- return NULL;
+ return NULL;
}
static void
free_link_refs(struct link_ref **references)
{
- size_t i;
+ size_t i;
- for (i = 0; i < REF_TABLE_SIZE; ++i) {
- struct link_ref *r = references[i];
- struct link_ref *next;
+ for (i = 0; i < REF_TABLE_SIZE; ++i) {
+ struct link_ref *r = references[i];
+ struct link_ref *next;
- while (r) {
- next = r->next;
- hoedown_buffer_free(r->link);
- hoedown_buffer_free(r->title);
- free(r);
- r = next;
- }
- }
+ while (r) {
+ next = r->next;
+ hoedown_buffer_free(r->link);
+ hoedown_buffer_free(r->title);
+ free(r);
+ r = next;
+ }
+ }
}
static struct footnote_ref *
create_footnote_ref(struct footnote_list *list, const uint8_t *name, size_t name_size)
{
- struct footnote_ref *ref = hoedown_calloc(1, sizeof(struct footnote_ref));
+ struct footnote_ref *ref = hoedown_calloc(1, sizeof(struct footnote_ref));
- ref->id = hash_link_ref(name, name_size);
+ ref->id = hash_link_ref(name, name_size);
- return ref;
+ return ref;
}
static int
add_footnote_ref(struct footnote_list *list, struct footnote_ref *ref)
{
- struct footnote_item *item = hoedown_calloc(1, sizeof(struct footnote_item));
- if (!item)
- return 0;
- item->ref = ref;
+ struct footnote_item *item = hoedown_calloc(1, sizeof(struct footnote_item));
+ if (!item)
+ return 0;
+ item->ref = ref;
- if (list->head == NULL) {
- list->head = list->tail = item;
- } else {
- list->tail->next = item;
- list->tail = item;
- }
- list->count++;
+ if (list->head == NULL) {
+ list->head = list->tail = item;
+ } else {
+ list->tail->next = item;
+ list->tail = item;
+ }
+ list->count++;
- return 1;
+ return 1;
}
static struct footnote_ref *
find_footnote_ref(struct footnote_list *list, uint8_t *name, size_t length)
{
- unsigned int hash = hash_link_ref(name, length);
- struct footnote_item *item = NULL;
+ unsigned int hash = hash_link_ref(name, length);
+ struct footnote_item *item = NULL;
- item = list->head;
+ item = list->head;
- while (item != NULL) {
- if (item->ref->id == hash)
- return item->ref;
- item = item->next;
- }
+ while (item != NULL) {
+ if (item->ref->id == hash)
+ return item->ref;
+ item = item->next;
+ }
- return NULL;
+ return NULL;
}
static void
free_footnote_ref(struct footnote_ref *ref)
{
- hoedown_buffer_free(ref->contents);
- free(ref);
+ hoedown_buffer_free(ref->contents);
+ free(ref);
}
static void
free_footnote_list(struct footnote_list *list, int free_refs)
{
- struct footnote_item *item = list->head;
- struct footnote_item *next;
+ struct footnote_item *item = list->head;
+ struct footnote_item *next;
- while (item) {
- next = item->next;
- if (free_refs)
- free_footnote_ref(item->ref);
- free(item);
- item = next;
- }
+ while (item) {
+ next = item->next;
+ if (free_refs)
+ free_footnote_ref(item->ref);
+ free(item);
+ item = next;
+ }
}
@@ -323,16 +323,16 @@ free_footnote_list(struct footnote_list *list, int free_refs)
static int
_isspace(int c)
{
- return c == ' ' || c == '\n';
+ return c == ' ' || c == '\n';
}
/* is_empty_all: verify that all the data is spacing */
static int
is_empty_all(const uint8_t *data, size_t size)
{
- size_t i = 0;
- while (i < size && _isspace(data[i])) i++;
- return i == size;
+ size_t i = 0;
+ while (i < size && _isspace(data[i])) i++;
+ return i == size;
}
/*
@@ -342,19 +342,19 @@ is_empty_all(const uint8_t *data, size_t size)
static void
replace_spacing(hoedown_buffer *ob, const uint8_t *data, size_t size)
{
- size_t i = 0, mark;
- hoedown_buffer_grow(ob, size);
- while (1) {
- mark = i;
- while (i < size && data[i] != '\n') i++;
- hoedown_buffer_put(ob, data + mark, i - mark);
+ size_t i = 0, mark;
+ hoedown_buffer_grow(ob, size);
+ while (1) {
+ mark = i;
+ while (i < size && data[i] != '\n') i++;
+ hoedown_buffer_put(ob, data + mark, i - mark);
- if (i >= size) break;
+ if (i >= size) break;
- if (!(i > 0 && data[i-1] == ' '))
- hoedown_buffer_putc(ob, ' ');
- i++;
- }
+ if (!(i > 0 && data[i-1] == ' '))
+ hoedown_buffer_putc(ob, ' ');
+ i++;
+ }
}
/****************************
@@ -366,237 +366,237 @@ replace_spacing(hoedown_buffer *ob, const uint8_t *data, size_t size)
static size_t
is_mail_autolink(uint8_t *data, size_t size)
{
- size_t i = 0, nb = 0;
+ size_t i = 0, nb = 0;
- /* address is assumed to be: [-@._a-zA-Z0-9]+ with exactly one '@' */
- for (i = 0; i < size; ++i) {
- if (isalnum(data[i]))
- continue;
+ /* address is assumed to be: [-@._a-zA-Z0-9]+ with exactly one '@' */
+ for (i = 0; i < size; ++i) {
+ if (isalnum(data[i]))
+ continue;
- switch (data[i]) {
- case '@':
- nb++;
+ switch (data[i]) {
+ case '@':
+ nb++;
- case '-':
- case '.':
- case '_':
- break;
+ case '-':
+ case '.':
+ case '_':
+ break;
- case '>':
- return (nb == 1) ? i + 1 : 0;
+ case '>':
+ return (nb == 1) ? i + 1 : 0;
- default:
- return 0;
- }
- }
+ default:
+ return 0;
+ }
+ }
- return 0;
+ return 0;
}
/* tag_length • returns the length of the given tag, or 0 is it's not valid */
static size_t
tag_length(uint8_t *data, size_t size, hoedown_autolink_type *autolink)
{
- size_t i, j;
+ size_t i, j;
- /* a valid tag can't be shorter than 3 chars */
- if (size < 3) return 0;
+ /* a valid tag can't be shorter than 3 chars */
+ if (size < 3) return 0;
- /* begins with a '<' optionally followed by '/', followed by letter or number */
- if (data[0] != '<') return 0;
- i = (data[1] == '/') ? 2 : 1;
+ /* begins with a '<' optionally followed by '/', followed by letter or number */
+ if (data[0] != '<') return 0;
+ i = (data[1] == '/') ? 2 : 1;
- if (!isalnum(data[i]))
- return 0;
+ if (!isalnum(data[i]))
+ return 0;
- /* scheme test */
- *autolink = HOEDOWN_AUTOLINK_NONE;
+ /* scheme test */
+ *autolink = HOEDOWN_AUTOLINK_NONE;
- /* try to find the beginning of an URI */
- while (i < size && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-'))
- i++;
+ /* try to find the beginning of an URI */
+ while (i < size && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-'))
+ i++;
- if (i > 1 && data[i] == '@') {
- if ((j = is_mail_autolink(data + i, size - i)) != 0) {
- *autolink = HOEDOWN_AUTOLINK_EMAIL;
- return i + j;
- }
- }
+ if (i > 1 && data[i] == '@') {
+ if ((j = is_mail_autolink(data + i, size - i)) != 0) {
+ *autolink = HOEDOWN_AUTOLINK_EMAIL;
+ return i + j;
+ }
+ }
- if (i > 2 && data[i] == ':') {
- *autolink = HOEDOWN_AUTOLINK_NORMAL;
- i++;
- }
+ if (i > 2 && data[i] == ':') {
+ *autolink = HOEDOWN_AUTOLINK_NORMAL;
+ i++;
+ }
- /* completing autolink test: no spacing or ' or " */
- if (i >= size)
- *autolink = HOEDOWN_AUTOLINK_NONE;
+ /* completing autolink test: no spacing or ' or " */
+ if (i >= size)
+ *autolink = HOEDOWN_AUTOLINK_NONE;
- else if (*autolink) {
- j = i;
+ else if (*autolink) {
+ j = i;
- while (i < size) {
- if (data[i] == '\\') i += 2;
- else if (data[i] == '>' || data[i] == '\'' ||
- data[i] == '"' || data[i] == ' ' || data[i] == '\n')
- break;
- else i++;
- }
+ while (i < size) {
+ if (data[i] == '\\') i += 2;
+ else if (data[i] == '>' || data[i] == '\'' ||
+ data[i] == '"' || data[i] == ' ' || data[i] == '\n')
+ break;
+ else i++;
+ }
- if (i >= size) return 0;
- if (i > j && data[i] == '>') return i + 1;
- /* one of the forbidden chars has been found */
- *autolink = HOEDOWN_AUTOLINK_NONE;
- }
+ if (i >= size) return 0;
+ if (i > j && data[i] == '>') return i + 1;
+ /* one of the forbidden chars has been found */
+ *autolink = HOEDOWN_AUTOLINK_NONE;
+ }
- /* looking for something looking like a tag end */
- while (i < size && data[i] != '>') i++;
- if (i >= size) return 0;
- return i + 1;
+ /* looking for something looking like a tag end */
+ while (i < size && data[i] != '>') i++;
+ if (i >= size) return 0;
+ return i + 1;
}
/* parse_inline • parses inline markdown elements */
static void
parse_inline(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size)
{
- size_t i = 0, end = 0, consumed = 0;
- hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL };
- uint8_t *active_char = doc->active_char;
-
- if (doc->work_bufs[BUFFER_SPAN].size +
- doc->work_bufs[BUFFER_BLOCK].size > doc->max_nesting)
- return;
-
- while (i < size) {
- /* copying inactive chars into the output */
- while (end < size && active_char[data[end]] == 0)
- end++;
-
- if (doc->md.normal_text) {
- work.data = data + i;
- work.size = end - i;
- doc->md.normal_text(ob, &work, &doc->data);
- }
- else
- hoedown_buffer_put(ob, data + i, end - i);
-
- if (end >= size) break;
- i = end;
-
- end = markdown_char_ptrs[ (int)active_char[data[end]] ](ob, doc, data + i, i - consumed, size - i);
- if (!end) /* no action from the callback */
- end = i + 1;
- else {
- i += end;
- end = i;
- consumed = i;
- }
- }
+ size_t i = 0, end = 0, consumed = 0;
+ hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL };
+ uint8_t *active_char = doc->active_char;
+
+ if (doc->work_bufs[BUFFER_SPAN].size +
+ doc->work_bufs[BUFFER_BLOCK].size > doc->max_nesting)
+ return;
+
+ while (i < size) {
+ /* copying inactive chars into the output */
+ while (end < size && active_char[data[end]] == 0)
+ end++;
+
+ if (doc->md.normal_text) {
+ work.data = data + i;
+ work.size = end - i;
+ doc->md.normal_text(ob, &work, &doc->data);
+ }
+ else
+ hoedown_buffer_put(ob, data + i, end - i);
+
+ if (end >= size) break;
+ i = end;
+
+ end = markdown_char_ptrs[ (int)active_char[data[end]] ](ob, doc, data + i, i - consumed, size - i);
+ if (!end) /* no action from the callback */
+ end = i + 1;
+ else {
+ i += end;
+ end = i;
+ consumed = i;
+ }
+ }
}
/* is_escaped • returns whether special char at data[loc] is escaped by '\\' */
static int
is_escaped(uint8_t *data, size_t loc)
{
- size_t i = loc;
- while (i >= 1 && data[i - 1] == '\\')
- i--;
+ size_t i = loc;
+ while (i >= 1 && data[i - 1] == '\\')
+ i--;
- /* odd numbers of backslashes escapes data[loc] */
- return (loc - i) % 2;
+ /* odd numbers of backslashes escapes data[loc] */
+ return (loc - i) % 2;
}
/* find_emph_char • looks for the next emph uint8_t, skipping other constructs */
static size_t
find_emph_char(uint8_t *data, size_t size, uint8_t c)
{
- size_t i = 0;
+ size_t i = 0;
- while (i < size) {
- while (i < size && data[i] != c && data[i] != '[' && data[i] != '`')
- i++;
+ while (i < size) {
+ while (i < size && data[i] != c && data[i] != '[' && data[i] != '`')
+ i++;
- if (i == size)
- return 0;
+ if (i == size)
+ return 0;
- /* not counting escaped chars */
- if (is_escaped(data, i)) {
- i++; continue;
- }
+ /* not counting escaped chars */
+ if (is_escaped(data, i)) {
+ i++; continue;
+ }
- if (data[i] == c)
- return i;
+ if (data[i] == c)
+ return i;
- /* skipping a codespan */
- if (data[i] == '`') {
- size_t span_nb = 0, bt;
- size_t tmp_i = 0;
+ /* skipping a codespan */
+ if (data[i] == '`') {
+ size_t span_nb = 0, bt;
+ size_t tmp_i = 0;
- /* counting the number of opening backticks */
- while (i < size && data[i] == '`') {
- i++; span_nb++;
- }
+ /* counting the number of opening backticks */
+ while (i < size && data[i] == '`') {
+ i++; span_nb++;
+ }
- if (i >= size) return 0;
+ if (i >= size) return 0;
- /* finding the matching closing sequence */
- bt = 0;
- while (i < size && bt < span_nb) {
- if (!tmp_i && data[i] == c) tmp_i = i;
- if (data[i] == '`') bt++;
- else bt = 0;
- i++;
- }
+ /* finding the matching closing sequence */
+ bt = 0;
+ while (i < size && bt < span_nb) {
+ if (!tmp_i && data[i] == c) tmp_i = i;
+ if (data[i] == '`') bt++;
+ else bt = 0;
+ i++;
+ }
- /* not a well-formed codespan; use found matching emph char */
- if (i >= size) return tmp_i;
- }
- /* skipping a link */
- else if (data[i] == '[') {
- size_t tmp_i = 0;
- uint8_t cc;
+ /* not a well-formed codespan; use found matching emph char */
+ if (i >= size) return tmp_i;
+ }
+ /* skipping a link */
+ else if (data[i] == '[') {
+ size_t tmp_i = 0;
+ uint8_t cc;
- i++;
- while (i < size && data[i] != ']') {
- if (!tmp_i && data[i] == c) tmp_i = i;
- i++;
- }
+ i++;
+ while (i < size && data[i] != ']') {
+ if (!tmp_i && data[i] == c) tmp_i = i;
+ i++;
+ }
- i++;
- while (i < size && _isspace(data[i]))
- i++;
+ i++;
+ while (i < size && _isspace(data[i]))
+ i++;
- if (i >= size)
- return tmp_i;
+ if (i >= size)
+ return tmp_i;
- switch (data[i]) {
- case '[':
- cc = ']'; break;
+ switch (data[i]) {
+ case '[':
+ cc = ']'; break;
- case '(':
- cc = ')'; break;
+ case '(':
+ cc = ')'; break;
- default:
- if (tmp_i)
- return tmp_i;
- else
- continue;
- }
+ default:
+ if (tmp_i)
+ return tmp_i;
+ else
+ continue;
+ }
- i++;
- while (i < size && data[i] != cc) {
- if (!tmp_i && data[i] == c) tmp_i = i;
- i++;
- }
+ i++;
+ while (i < size && data[i] != cc) {
+ if (!tmp_i && data[i] == c) tmp_i = i;
+ i++;
+ }
- if (i >= size)
- return tmp_i;
+ if (i >= size)
+ return tmp_i;
- i++;
- }
- }
+ i++;
+ }
+ }
- return 0;
+ return 0;
}
/* parse_emph1 • parsing single emphase */
@@ -604,72 +604,72 @@ find_emph_char(uint8_t *data, size_t size, uint8_t c)
static size_t
parse_emph1(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, uint8_t c)
{
- size_t i = 0, len;
- hoedown_buffer *work = 0;
- int r;
+ size_t i = 0, len;
+ hoedown_buffer *work = 0;
+ int r;
- /* skipping one symbol if coming from emph3 */
- if (size > 1 && data[0] == c && data[1] == c) i = 1;
+ /* skipping one symbol if coming from emph3 */
+ if (size > 1 && data[0] == c && data[1] == c) i = 1;
- while (i < size) {
- len = find_emph_char(data + i, size - i, c);
- if (!len) return 0;
- i += len;
- if (i >= size) return 0;
+ while (i < size) {
+ len = find_emph_char(data + i, size - i, c);
+ if (!len) return 0;
+ i += len;
+ if (i >= size) return 0;
- if (data[i] == c && !_isspace(data[i - 1])) {
+ if (data[i] == c && !_isspace(data[i - 1])) {
- if (doc->ext_flags & HOEDOWN_EXT_NO_INTRA_EMPHASIS) {
- if (i + 1 < size && isalnum(data[i + 1]))
- continue;
- }
+ if (doc->ext_flags & HOEDOWN_EXT_NO_INTRA_EMPHASIS) {
+ if (i + 1 < size && isalnum(data[i + 1]))
+ continue;
+ }
- work = newbuf(doc, BUFFER_SPAN);
- parse_inline(work, doc, data, i);
+ work = newbuf(doc, BUFFER_SPAN);
+ parse_inline(work, doc, data, i);
- if (doc->ext_flags & HOEDOWN_EXT_UNDERLINE && c == '_')
- r = doc->md.underline(ob, work, &doc->data);
- else
- r = doc->md.emphasis(ob, work, &doc->data);
+ if (doc->ext_flags & HOEDOWN_EXT_UNDERLINE && c == '_')
+ r = doc->md.underline(ob, work, &doc->data);
+ else
+ r = doc->md.emphasis(ob, work, &doc->data);
- popbuf(doc, BUFFER_SPAN);
- return r ? i + 1 : 0;
- }
- }
+ popbuf(doc, BUFFER_SPAN);
+ return r ? i + 1 : 0;
+ }
+ }
- return 0;
+ return 0;
}
/* parse_emph2 • parsing single emphase */
static size_t
parse_emph2(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, uint8_t c)
{
- size_t i = 0, len;
- hoedown_buffer *work = 0;
- int r;
+ size_t i = 0, len;
+ hoedown_buffer *work = 0;
+ int r;
- while (i < size) {
- len = find_emph_char(data + i, size - i, c);
- if (!len) return 0;
- i += len;
+ while (i < size) {
+ len = find_emph_char(data + i, size - i, c);
+ if (!len) return 0;
+ i += len;
- if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !_isspace(data[i - 1])) {
- work = newbuf(doc, BUFFER_SPAN);
- parse_inline(work, doc, data, i);
+ if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !_isspace(data[i - 1])) {
+ work = newbuf(doc, BUFFER_SPAN);
+ parse_inline(work, doc, data, i);
- if (c == '~')
- r = doc->md.strikethrough(ob, work, &doc->data);
- else if (c == '=')
- r = doc->md.highlight(ob, work, &doc->data);
- else
- r = doc->md.double_emphasis(ob, work, &doc->data);
+ if (c == '~')
+ r = doc->md.strikethrough(ob, work, &doc->data);
+ else if (c == '=')
+ r = doc->md.highlight(ob, work, &doc->data);
+ else
+ r = doc->md.double_emphasis(ob, work, &doc->data);
- popbuf(doc, BUFFER_SPAN);
- return r ? i + 2 : 0;
- }
- i++;
- }
- return 0;
+ popbuf(doc, BUFFER_SPAN);
+ return r ? i + 2 : 0;
+ }
+ i++;
+ }
+ return 0;
}
/* parse_emph3 • parsing single emphase */
@@ -677,121 +677,121 @@ parse_emph2(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t siz
static size_t
parse_emph3(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, uint8_t c)
{
- size_t i = 0, len;
- int r;
+ size_t i = 0, len;
+ int r;
- while (i < size) {
- len = find_emph_char(data + i, size - i, c);
- if (!len) return 0;
- i += len;
+ while (i < size) {
+ len = find_emph_char(data + i, size - i, c);
+ if (!len) return 0;
+ i += len;
- /* skip spacing preceded symbols */
- if (data[i] != c || _isspace(data[i - 1]))
- continue;
+ /* skip spacing preceded symbols */
+ if (data[i] != c || _isspace(data[i - 1]))
+ continue;
- if (i + 2 < size && data[i + 1] == c && data[i + 2] == c && doc->md.triple_emphasis) {
- /* triple symbol found */
- hoedown_buffer *work = newbuf(doc, BUFFER_SPAN);
+ if (i + 2 < size && data[i + 1] == c && data[i + 2] == c && doc->md.triple_emphasis) {
+ /* triple symbol found */
+ hoedown_buffer *work = newbuf(doc, BUFFER_SPAN);
- parse_inline(work, doc, data, i);
- r = doc->md.triple_emphasis(ob, work, &doc->data);
- popbuf(doc, BUFFER_SPAN);
- return r ? i + 3 : 0;
+ parse_inline(work, doc, data, i);
+ r = doc->md.triple_emphasis(ob, work, &doc->data);
+ popbuf(doc, BUFFER_SPAN);
+ return r ? i + 3 : 0;
- } else if (i + 1 < size && data[i + 1] == c) {
- /* double symbol found, handing over to emph1 */
- len = parse_emph1(ob, doc, data - 2, size + 2, c);
- if (!len) return 0;
- else return len - 2;
+ } else if (i + 1 < size && data[i + 1] == c) {
+ /* double symbol found, handing over to emph1 */
+ len = parse_emph1(ob, doc, data - 2, size + 2, c);
+ if (!len) return 0;
+ else return len - 2;
- } else {
- /* single symbol found, handing over to emph2 */
- len = parse_emph2(ob, doc, data - 1, size + 1, c);
- if (!len) return 0;
- else return len - 1;
- }
- }
- return 0;
+ } else {
+ /* single symbol found, handing over to emph2 */
+ len = parse_emph2(ob, doc, data - 1, size + 1, c);
+ if (!len) return 0;
+ else return len - 1;
+ }
+ }
+ return 0;
}
/* parse_math • parses a math span until the given ending delimiter */
static size_t
parse_math(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size, const char *end, size_t delimsz, int displaymode)
{
- hoedown_buffer text = { NULL, 0, 0, 0, NULL, NULL, NULL };
- size_t i = delimsz;
+ hoedown_buffer text = { NULL, 0, 0, 0, NULL, NULL, NULL };
+ size_t i = delimsz;
- if (!doc->md.math)
- return 0;
+ if (!doc->md.math)
+ return 0;
- /* find ending delimiter */
- while (1) {
- while (i < size && data[i] != (uint8_t)end[0])
- i++;
+ /* find ending delimiter */
+ while (1) {
+ while (i < size && data[i] != (uint8_t)end[0])
+ i++;
- if (i >= size)
- return 0;
+ if (i >= size)
+ return 0;
- if (!is_escaped(data, i) && !(i + delimsz > size)
- && memcmp(data + i, end, delimsz) == 0)
- break;
+ if (!is_escaped(data, i) && !(i + delimsz > size)
+ && memcmp(data + i, end, delimsz) == 0)
+ break;
- i++;
- }
+ i++;
+ }
- /* prepare buffers */
- text.data = data + delimsz;
- text.size = i - delimsz;
+ /* prepare buffers */
+ text.data = data + delimsz;
+ text.size = i - delimsz;
- /* if this is a $$ and MATH_EXPLICIT is not active,
- * guess whether displaymode should be enabled from the context */
- i += delimsz;
- if (delimsz == 2 && !(doc->ext_flags & HOEDOWN_EXT_MATH_EXPLICIT))
- displaymode = is_empty_all(data - offset, offset) && is_empty_all(data + i, size - i);
+ /* if this is a $$ and MATH_EXPLICIT is not active,
+ * guess whether displaymode should be enabled from the context */
+ i += delimsz;
+ if (delimsz == 2 && !(doc->ext_flags & HOEDOWN_EXT_MATH_EXPLICIT))
+ displaymode = is_empty_all(data - offset, offset) && is_empty_all(data + i, size - i);
- /* call callback */
- if (doc->md.math(ob, &text, displaymode, &doc->data))
- return i;
+ /* call callback */
+ if (doc->md.math(ob, &text, displaymode, &doc->data))
+ return i;
- return 0;
+ return 0;
}
/* char_emphasis • single and double emphasis parsing */
static size_t
char_emphasis(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- uint8_t c = data[0];
- size_t ret;
+ uint8_t c = data[0];
+ size_t ret;
- if (doc->ext_flags & HOEDOWN_EXT_NO_INTRA_EMPHASIS) {
- if (offset > 0 && !_isspace(data[-1]) && data[-1] != '>' && data[-1] != '(')
- return 0;
- }
+ if (doc->ext_flags & HOEDOWN_EXT_NO_INTRA_EMPHASIS) {
+ if (offset > 0 && !_isspace(data[-1]) && data[-1] != '>' && data[-1] != '(')
+ return 0;
+ }
- if (size > 2 && data[1] != c) {
- /* spacing cannot follow an opening emphasis;
- * strikethrough and highlight only takes two characters '~~' */
- if (c == '~' || c == '=' || _isspace(data[1]) || (ret = parse_emph1(ob, doc, data + 1, size - 1, c)) == 0)
- return 0;
+ if (size > 2 && data[1] != c) {
+ /* spacing cannot follow an opening emphasis;
+ * strikethrough and highlight only takes two characters '~~' */
+ if (c == '~' || c == '=' || _isspace(data[1]) || (ret = parse_emph1(ob, doc, data + 1, size - 1, c)) == 0)
+ return 0;
- return ret + 1;
- }
+ return ret + 1;
+ }
- if (size > 3 && data[1] == c && data[2] != c) {
- if (_isspace(data[2]) || (ret = parse_emph2(ob, doc, data + 2, size - 2, c)) == 0)
- return 0;
+ if (size > 3 && data[1] == c && data[2] != c) {
+ if (_isspace(data[2]) || (ret = parse_emph2(ob, doc, data + 2, size - 2, c)) == 0)
+ return 0;
- return ret + 2;
- }
+ return ret + 2;
+ }
- if (size > 4 && data[1] == c && data[2] == c && data[3] != c) {
- if (c == '~' || c == '=' || _isspace(data[3]) || (ret = parse_emph3(ob, doc, data + 3, size - 3, c)) == 0)
- return 0;
+ if (size > 4 && data[1] == c && data[2] == c && data[3] != c) {
+ if (c == '~' || c == '=' || _isspace(data[3]) || (ret = parse_emph3(ob, doc, data + 3, size - 3, c)) == 0)
+ return 0;
- return ret + 3;
- }
+ return ret + 3;
+ }
- return 0;
+ return 0;
}
@@ -799,14 +799,14 @@ char_emphasis(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t o
static size_t
char_linebreak(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- if (offset < 2 || data[-1] != ' ' || data[-2] != ' ')
- return 0;
+ if (offset < 2 || data[-1] != ' ' || data[-2] != ' ')
+ return 0;
- /* removing the last space from ob and rendering */
- while (ob->size && ob->data[ob->size - 1] == ' ')
- ob->size--;
+ /* removing the last space from ob and rendering */
+ while (ob->size && ob->data[ob->size - 1] == ' ')
+ ob->size--;
- return doc->md.linebreak(ob, &doc->data) ? 1 : 0;
+ return doc->md.linebreak(ob, &doc->data) ? 1 : 0;
}
@@ -814,91 +814,91 @@ char_linebreak(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
static size_t
char_codespan(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL };
- size_t end, nb = 0, i, f_begin, f_end;
+ hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL };
+ size_t end, nb = 0, i, f_begin, f_end;
- /* counting the number of backticks in the delimiter */
- while (nb < size && data[nb] == '`')
- nb++;
+ /* counting the number of backticks in the delimiter */
+ while (nb < size && data[nb] == '`')
+ nb++;
- /* finding the next delimiter */
- i = 0;
- for (end = nb; end < size && i < nb; end++) {
- if (data[end] == '`') i++;
- else i = 0;
- }
+ /* finding the next delimiter */
+ i = 0;
+ for (end = nb; end < size && i < nb; end++) {
+ if (data[end] == '`') i++;
+ else i = 0;
+ }
- if (i < nb && end >= size)
- return 0; /* no matching delimiter */
+ if (i < nb && end >= size)
+ return 0; /* no matching delimiter */
- /* trimming outside spaces */
- f_begin = nb;
- while (f_begin < end && data[f_begin] == ' ')
- f_begin++;
+ /* trimming outside spaces */
+ f_begin = nb;
+ while (f_begin < end && data[f_begin] == ' ')
+ f_begin++;
- f_end = end - nb;
- while (f_end > nb && data[f_end-1] == ' ')
- f_end--;
+ f_end = end - nb;
+ while (f_end > nb && data[f_end-1] == ' ')
+ f_end--;
- /* real code span */
- if (f_begin < f_end) {
- work.data = data + f_begin;
- work.size = f_end - f_begin;
+ /* real code span */
+ if (f_begin < f_end) {
+ work.data = data + f_begin;
+ work.size = f_end - f_begin;
- if (!doc->md.codespan(ob, &work, &doc->data))
- end = 0;
- } else {
- if (!doc->md.codespan(ob, 0, &doc->data))
- end = 0;
- }
+ if (!doc->md.codespan(ob, &work, &doc->data))
+ end = 0;
+ } else {
+ if (!doc->md.codespan(ob, 0, &doc->data))
+ end = 0;
+ }
- return end;
+ return end;
}
/* char_quote • '"' parsing a quote */
static size_t
char_quote(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- size_t end, nq = 0, i, f_begin, f_end;
+ size_t end, nq = 0, i, f_begin, f_end;
- /* counting the number of quotes in the delimiter */
- while (nq < size && data[nq] == '"')
- nq++;
+ /* counting the number of quotes in the delimiter */
+ while (nq < size && data[nq] == '"')
+ nq++;
- /* finding the next delimiter */
- end = nq;
- while (1) {
- i = end;
- end += find_emph_char(data + end, size - end, '"');
- if (end == i) return 0; /* no matching delimiter */
- i = end;
- while (end < size && data[end] == '"' && end - i < nq) end++;
- if (end - i >= nq) break;
- }
+ /* finding the next delimiter */
+ end = nq;
+ while (1) {
+ i = end;
+ end += find_emph_char(data + end, size - end, '"');
+ if (end == i) return 0; /* no matching delimiter */
+ i = end;
+ while (end < size && data[end] == '"' && end - i < nq) end++;
+ if (end - i >= nq) break;
+ }
- /* trimming outside spaces */
- f_begin = nq;
- while (f_begin < end && data[f_begin] == ' ')
- f_begin++;
+ /* trimming outside spaces */
+ f_begin = nq;
+ while (f_begin < end && data[f_begin] == ' ')
+ f_begin++;
- f_end = end - nq;
- while (f_end > nq && data[f_end-1] == ' ')
- f_end--;
+ f_end = end - nq;
+ while (f_end > nq && data[f_end-1] == ' ')
+ f_end--;
- /* real quote */
- if (f_begin < f_end) {
- hoedown_buffer *work = newbuf(doc, BUFFER_SPAN);
- parse_inline(work, doc, data + f_begin, f_end - f_begin);
+ /* real quote */
+ if (f_begin < f_end) {
+ hoedown_buffer *work = newbuf(doc, BUFFER_SPAN);
+ parse_inline(work, doc, data + f_begin, f_end - f_begin);
- if (!doc->md.quote(ob, work, &doc->data))
- end = 0;
- popbuf(doc, BUFFER_SPAN);
- } else {
- if (!doc->md.quote(ob, 0, &doc->data))
- end = 0;
- }
+ if (!doc->md.quote(ob, work, &doc->data))
+ end = 0;
+ popbuf(doc, BUFFER_SPAN);
+ } else {
+ if (!doc->md.quote(ob, 0, &doc->data))
+ end = 0;
+ }
- return end;
+ return end;
}
@@ -906,32 +906,32 @@ char_quote(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offs
static size_t
char_escape(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>^~=\"$";
- hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL };
- size_t w;
+ static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>^~=\"$";
+ hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL };
+ size_t w;
- if (size > 1) {
- if (data[1] == '\\' && (doc->ext_flags & HOEDOWN_EXT_MATH) &&
- size > 2 && (data[2] == '(' || data[2] == '[')) {
- const char *end = (data[2] == '[') ? "\\\\]" : "\\\\)";
- w = parse_math(ob, doc, data, offset, size, end, 3, data[2] == '[');
- if (w) return w;
- }
+ if (size > 1) {
+ if (data[1] == '\\' && (doc->ext_flags & HOEDOWN_EXT_MATH) &&
+ size > 2 && (data[2] == '(' || data[2] == '[')) {
+ const char *end = (data[2] == '[') ? "\\\\]" : "\\\\)";
+ w = parse_math(ob, doc, data, offset, size, end, 3, data[2] == '[');
+ if (w) return w;
+ }
- if (strchr(escape_chars, data[1]) == NULL)
- return 0;
+ if (strchr(escape_chars, data[1]) == NULL)
+ return 0;
- if (doc->md.normal_text) {
- work.data = data + 1;
- work.size = 1;
- doc->md.normal_text(ob, &work, &doc->data);
- }
- else hoedown_buffer_putc(ob, data[1]);
- } else if (size == 1) {
- hoedown_buffer_putc(ob, data[0]);
- }
+ if (doc->md.normal_text) {
+ work.data = data + 1;
+ work.size = 1;
+ doc->md.normal_text(ob, &work, &doc->data);
+ }
+ else hoedown_buffer_putc(ob, data[1]);
+ } else if (size == 1) {
+ hoedown_buffer_putc(ob, data[0]);
+ }
- return 2;
+ return 2;
}
/* char_entity • '&' escaped when it doesn't belong to an entity */
@@ -939,403 +939,403 @@ char_escape(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t off
static size_t
char_entity(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- size_t end = 1;
- hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL };
+ size_t end = 1;
+ hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL };
- if (end < size && data[end] == '#')
- end++;
+ if (end < size && data[end] == '#')
+ end++;
- while (end < size && isalnum(data[end]))
- end++;
+ while (end < size && isalnum(data[end]))
+ end++;
- if (end < size && data[end] == ';')
- end++; /* real entity */
- else
- return 0; /* lone '&' */
+ if (end < size && data[end] == ';')
+ end++; /* real entity */
+ else
+ return 0; /* lone '&' */
- if (doc->md.entity) {
- work.data = data;
- work.size = end;
- doc->md.entity(ob, &work, &doc->data);
- }
- else hoedown_buffer_put(ob, data, end);
+ if (doc->md.entity) {
+ work.data = data;
+ work.size = end;
+ doc->md.entity(ob, &work, &doc->data);
+ }
+ else hoedown_buffer_put(ob, data, end);
- return end;
+ return end;
}
/* char_langle_tag • '<' when tags or autolinks are allowed */
static size_t
char_langle_tag(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL };
- hoedown_autolink_type altype = HOEDOWN_AUTOLINK_NONE;
- size_t end = tag_length(data, size, &altype);
- int ret = 0;
+ hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL };
+ hoedown_autolink_type altype = HOEDOWN_AUTOLINK_NONE;
+ size_t end = tag_length(data, size, &altype);
+ int ret = 0;
- work.data = data;
- work.size = end;
+ work.data = data;
+ work.size = end;
- if (end > 2) {
- if (doc->md.autolink && altype != HOEDOWN_AUTOLINK_NONE) {
- hoedown_buffer *u_link = newbuf(doc, BUFFER_SPAN);
- work.data = data + 1;
- work.size = end - 2;
- unscape_text(u_link, &work);
- ret = doc->md.autolink(ob, u_link, altype, &doc->data);
- popbuf(doc, BUFFER_SPAN);
- }
- else if (doc->md.raw_html)
- ret = doc->md.raw_html(ob, &work, &doc->data);
- }
+ if (end > 2) {
+ if (doc->md.autolink && altype != HOEDOWN_AUTOLINK_NONE) {
+ hoedown_buffer *u_link = newbuf(doc, BUFFER_SPAN);
+ work.data = data + 1;
+ work.size = end - 2;
+ unscape_text(u_link, &work);
+ ret = doc->md.autolink(ob, u_link, altype, &doc->data);
+ popbuf(doc, BUFFER_SPAN);
+ }
+ else if (doc->md.raw_html)
+ ret = doc->md.raw_html(ob, &work, &doc->data);
+ }
- if (!ret) return 0;
- else return end;
+ if (!ret) return 0;
+ else return end;
}
static size_t
char_autolink_www(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- hoedown_buffer *link, *link_url, *link_text;
- size_t link_len, rewind;
+ hoedown_buffer *link, *link_url, *link_text;
+ size_t link_len, rewind;
- if (!doc->md.link || doc->in_link_body)
- return 0;
+ if (!doc->md.link || doc->in_link_body)
+ return 0;
- link = newbuf(doc, BUFFER_SPAN);
+ link = newbuf(doc, BUFFER_SPAN);
- if ((link_len = hoedown_autolink__www(&rewind, link, data, offset, size, HOEDOWN_AUTOLINK_SHORT_DOMAINS)) > 0) {
- link_url = newbuf(doc, BUFFER_SPAN);
- HOEDOWN_BUFPUTSL(link_url, "http://");
- hoedown_buffer_put(link_url, link->data, link->size);
+ if ((link_len = hoedown_autolink__www(&rewind, link, data, offset, size, HOEDOWN_AUTOLINK_SHORT_DOMAINS)) > 0) {
+ link_url = newbuf(doc, BUFFER_SPAN);
+ HOEDOWN_BUFPUTSL(link_url, "http://");
+ hoedown_buffer_put(link_url, link->data, link->size);
- ob->size -= rewind;
- if (doc->md.normal_text) {
- link_text = newbuf(doc, BUFFER_SPAN);
- doc->md.normal_text(link_text, link, &doc->data);
- doc->md.link(ob, link_text, link_url, NULL, &doc->data);
- popbuf(doc, BUFFER_SPAN);
- } else {
- doc->md.link(ob, link, link_url, NULL, &doc->data);
- }
- popbuf(doc, BUFFER_SPAN);
- }
+ ob->size -= rewind;
+ if (doc->md.normal_text) {
+ link_text = newbuf(doc, BUFFER_SPAN);
+ doc->md.normal_text(link_text, link, &doc->data);
+ doc->md.link(ob, link_text, link_url, NULL, &doc->data);
+ popbuf(doc, BUFFER_SPAN);
+ } else {
+ doc->md.link(ob, link, link_url, NULL, &doc->data);
+ }
+ popbuf(doc, BUFFER_SPAN);
+ }
- popbuf(doc, BUFFER_SPAN);
- return link_len;
+ popbuf(doc, BUFFER_SPAN);
+ return link_len;
}
static size_t
char_autolink_email(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- hoedown_buffer *link;
- size_t link_len, rewind;
+ hoedown_buffer *link;
+ size_t link_len, rewind;
- if (!doc->md.autolink || doc->in_link_body)
- return 0;
+ if (!doc->md.autolink || doc->in_link_body)
+ return 0;
- link = newbuf(doc, BUFFER_SPAN);
+ link = newbuf(doc, BUFFER_SPAN);
- if ((link_len = hoedown_autolink__email(&rewind, link, data, offset, size, 0)) > 0) {
- ob->size -= rewind;
- doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_EMAIL, &doc->data);
- }
+ if ((link_len = hoedown_autolink__email(&rewind, link, data, offset, size, 0)) > 0) {
+ ob->size -= rewind;
+ doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_EMAIL, &doc->data);
+ }
- popbuf(doc, BUFFER_SPAN);
- return link_len;
+ popbuf(doc, BUFFER_SPAN);
+ return link_len;
}
static size_t
char_autolink_url(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- hoedown_buffer *link;
- size_t link_len, rewind;
+ hoedown_buffer *link;
+ size_t link_len, rewind;
- if (!doc->md.autolink || doc->in_link_body)
- return 0;
+ if (!doc->md.autolink || doc->in_link_body)
+ return 0;
- link = newbuf(doc, BUFFER_SPAN);
+ link = newbuf(doc, BUFFER_SPAN);
- if ((link_len = hoedown_autolink__url(&rewind, link, data, offset, size, 0)) > 0) {
- ob->size -= rewind;
- doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_NORMAL, &doc->data);
- }
+ if ((link_len = hoedown_autolink__url(&rewind, link, data, offset, size, 0)) > 0) {
+ ob->size -= rewind;
+ doc->md.autolink(ob, link, HOEDOWN_AUTOLINK_NORMAL, &doc->data);
+ }
- popbuf(doc, BUFFER_SPAN);
- return link_len;
+ popbuf(doc, BUFFER_SPAN);
+ return link_len;
}
/* char_link • '[': parsing a link, a footnote or an image */
static size_t
char_link(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- int is_img = (offset && data[-1] == '!' && !is_escaped(data - offset, offset - 1));
- int is_footnote = (doc->ext_flags & HOEDOWN_EXT_FOOTNOTES && data[1] == '^');
- size_t i = 1, txt_e, link_b = 0, link_e = 0, title_b = 0, title_e = 0;
- hoedown_buffer *content = NULL;
- hoedown_buffer *link = NULL;
- hoedown_buffer *title = NULL;
- hoedown_buffer *u_link = NULL;
- size_t org_work_size = doc->work_bufs[BUFFER_SPAN].size;
- int ret = 0, in_title = 0, qtype = 0;
-
- /* checking whether the correct renderer exists */
- if ((is_footnote && !doc->md.footnote_ref) || (is_img && !doc->md.image)
- || (!is_img && !is_footnote && !doc->md.link))
- goto cleanup;
-
- /* looking for the matching closing bracket */
- i += find_emph_char(data + i, size - i, ']');
- txt_e = i;
-
- if (i < size && data[i] == ']') i++;
- else goto cleanup;
-
- /* footnote link */
- if (is_footnote) {
- hoedown_buffer id = { NULL, 0, 0, 0, NULL, NULL, NULL };
- struct footnote_ref *fr;
-
- if (txt_e < 3)
- goto cleanup;
-
- id.data = data + 2;
- id.size = txt_e - 2;
-
- fr = find_footnote_ref(&doc->footnotes_found, id.data, id.size);
-
- /* mark footnote used */
- if (fr && !fr->is_used) {
- if(!add_footnote_ref(&doc->footnotes_used, fr))
- goto cleanup;
- fr->is_used = 1;
- fr->num = doc->footnotes_used.count;
-
- /* render */
- if (doc->md.footnote_ref)
- ret = doc->md.footnote_ref(ob, fr->num, &doc->data);
- }
-
- goto cleanup;
- }
-
- /* skip any amount of spacing */
- /* (this is much more laxist than original markdown syntax) */
- while (i < size && _isspace(data[i]))
- i++;
-
- /* inline style link */
- if (i < size && data[i] == '(') {
- size_t nb_p;
-
- /* skipping initial spacing */
- i++;
-
- while (i < size && _isspace(data[i]))
- i++;
-
- link_b = i;
-
- /* looking for link end: ' " ) */
- /* Count the number of open parenthesis */
- nb_p = 0;
-
- while (i < size) {
- if (data[i] == '\\') i += 2;
- else if (data[i] == '(' && i != 0) {
- nb_p++; i++;
- }
- else if (data[i] == ')') {
- if (nb_p == 0) break;
- else nb_p--; i++;
- } else if (i >= 1 && _isspace(data[i-1]) && (data[i] == '\'' || data[i] == '"')) break;
- else i++;
- }
-
- if (i >= size) goto cleanup;
- link_e = i;
-
- /* looking for title end if present */
- if (data[i] == '\'' || data[i] == '"') {
- qtype = data[i];
- in_title = 1;
- i++;
- title_b = i;
-
- while (i < size) {
- if (data[i] == '\\') i += 2;
- else if (data[i] == qtype) {in_title = 0; i++;}
- else if ((data[i] == ')') && !in_title) break;
- else i++;
- }
-
- if (i >= size) goto cleanup;
-
- /* skipping spacing after title */
- title_e = i - 1;
- while (title_e > title_b && _isspace(data[title_e]))
- title_e--;
-
- /* checking for closing quote presence */
- if (data[title_e] != '\'' && data[title_e] != '"') {
- title_b = title_e = 0;
- link_e = i;
- }
- }
-
- /* remove spacing at the end of the link */
- while (link_e > link_b && _isspace(data[link_e - 1]))
- link_e--;
-
- /* remove optional angle brackets around the link */
- if (data[link_b] == '<') link_b++;
- if (data[link_e - 1] == '>') link_e--;
-
- /* building escaped link and title */
- if (link_e > link_b) {
- link = newbuf(doc, BUFFER_SPAN);
- hoedown_buffer_put(link, data + link_b, link_e - link_b);
- }
-
- if (title_e > title_b) {
- title = newbuf(doc, BUFFER_SPAN);
- hoedown_buffer_put(title, data + title_b, title_e - title_b);
- }
-
- i++;
- }
-
- /* reference style link */
- else if (i < size && data[i] == '[') {
- hoedown_buffer *id = newbuf(doc, BUFFER_SPAN);
- struct link_ref *lr;
-
- /* looking for the id */
- i++;
- link_b = i;
- while (i < size && data[i] != ']') i++;
- if (i >= size) goto cleanup;
- link_e = i;
-
- /* finding the link_ref */
- if (link_b == link_e)
- replace_spacing(id, data + 1, txt_e - 1);
- else
- hoedown_buffer_put(id, data + link_b, link_e - link_b);
-
- lr = find_link_ref(doc->refs, id->data, id->size);
- if (!lr)
- goto cleanup;
-
- /* keeping link and title from link_ref */
- link = lr->link;
- title = lr->title;
- i++;
- }
-
- /* shortcut reference style link */
- else {
- hoedown_buffer *id = newbuf(doc, BUFFER_SPAN);
- struct link_ref *lr;
-
- /* crafting the id */
- replace_spacing(id, data + 1, txt_e - 1);
-
- /* finding the link_ref */
- lr = find_link_ref(doc->refs, id->data, id->size);
- if (!lr)
- goto cleanup;
-
- /* keeping link and title from link_ref */
- link = lr->link;
- title = lr->title;
-
- /* rewinding the spacing */
- i = txt_e + 1;
- }
-
- /* building content: img alt is kept, only link content is parsed */
- if (txt_e > 1) {
- content = newbuf(doc, BUFFER_SPAN);
- if (is_img) {
- hoedown_buffer_put(content, data + 1, txt_e - 1);
- } else {
- /* disable autolinking when parsing inline the
- * content of a link */
- doc->in_link_body = 1;
- parse_inline(content, doc, data + 1, txt_e - 1);
- doc->in_link_body = 0;
- }
- }
-
- if (link) {
- u_link = newbuf(doc, BUFFER_SPAN);
- unscape_text(u_link, link);
- }
-
- /* calling the relevant rendering function */
- if (is_img) {
- if (ob->size && ob->data[ob->size - 1] == '!')
- ob->size -= 1;
-
- ret = doc->md.image(ob, u_link, title, content, &doc->data);
- } else {
- ret = doc->md.link(ob, content, u_link, title, &doc->data);
- }
-
- /* cleanup */
+ int is_img = (offset && data[-1] == '!' && !is_escaped(data - offset, offset - 1));
+ int is_footnote = (doc->ext_flags & HOEDOWN_EXT_FOOTNOTES && data[1] == '^');
+ size_t i = 1, txt_e, link_b = 0, link_e = 0, title_b = 0, title_e = 0;
+ hoedown_buffer *content = NULL;
+ hoedown_buffer *link = NULL;
+ hoedown_buffer *title = NULL;
+ hoedown_buffer *u_link = NULL;
+ size_t org_work_size = doc->work_bufs[BUFFER_SPAN].size;
+ int ret = 0, in_title = 0, qtype = 0;
+
+ /* checking whether the correct renderer exists */
+ if ((is_footnote && !doc->md.footnote_ref) || (is_img && !doc->md.image)
+ || (!is_img && !is_footnote && !doc->md.link))
+ goto cleanup;
+
+ /* looking for the matching closing bracket */
+ i += find_emph_char(data + i, size - i, ']');
+ txt_e = i;
+
+ if (i < size && data[i] == ']') i++;
+ else goto cleanup;
+
+ /* footnote link */
+ if (is_footnote) {
+ hoedown_buffer id = { NULL, 0, 0, 0, NULL, NULL, NULL };
+ struct footnote_ref *fr;
+
+ if (txt_e < 3)
+ goto cleanup;
+
+ id.data = data + 2;
+ id.size = txt_e - 2;
+
+ fr = find_footnote_ref(&doc->footnotes_found, id.data, id.size);
+
+ /* mark footnote used */
+ if (fr && !fr->is_used) {
+ if(!add_footnote_ref(&doc->footnotes_used, fr))
+ goto cleanup;
+ fr->is_used = 1;
+ fr->num = doc->footnotes_used.count;
+
+ /* render */
+ if (doc->md.footnote_ref)
+ ret = doc->md.footnote_ref(ob, fr->num, &doc->data);
+ }
+
+ goto cleanup;
+ }
+
+ /* skip any amount of spacing */
+ /* (this is much more laxist than original markdown syntax) */
+ while (i < size && _isspace(data[i]))
+ i++;
+
+ /* inline style link */
+ if (i < size && data[i] == '(') {
+ size_t nb_p;
+
+ /* skipping initial spacing */
+ i++;
+
+ while (i < size && _isspace(data[i]))
+ i++;
+
+ link_b = i;
+
+ /* looking for link end: ' " ) */
+ /* Count the number of open parenthesis */
+ nb_p = 0;
+
+ while (i < size) {
+ if (data[i] == '\\') i += 2;
+ else if (data[i] == '(' && i != 0) {
+ nb_p++; i++;
+ }
+ else if (data[i] == ')') {
+ if (nb_p == 0) break;
+ else nb_p--; i++;
+ } else if (i >= 1 && _isspace(data[i-1]) && (data[i] == '\'' || data[i] == '"')) break;
+ else i++;
+ }
+
+ if (i >= size) goto cleanup;
+ link_e = i;
+
+ /* looking for title end if present */
+ if (data[i] == '\'' || data[i] == '"') {
+ qtype = data[i];
+ in_title = 1;
+ i++;
+ title_b = i;
+
+ while (i < size) {
+ if (data[i] == '\\') i += 2;
+ else if (data[i] == qtype) {in_title = 0; i++;}
+ else if ((data[i] == ')') && !in_title) break;
+ else i++;
+ }
+
+ if (i >= size) goto cleanup;
+
+ /* skipping spacing after title */
+ title_e = i - 1;
+ while (title_e > title_b && _isspace(data[title_e]))
+ title_e--;
+
+ /* checking for closing quote presence */
+ if (data[title_e] != '\'' && data[title_e] != '"') {
+ title_b = title_e = 0;
+ link_e = i;
+ }
+ }
+
+ /* remove spacing at the end of the link */
+ while (link_e > link_b && _isspace(data[link_e - 1]))
+ link_e--;
+
+ /* remove optional angle brackets around the link */
+ if (data[link_b] == '<') link_b++;
+ if (data[link_e - 1] == '>') link_e--;
+
+ /* building escaped link and title */
+ if (link_e > link_b) {
+ link = newbuf(doc, BUFFER_SPAN);
+ hoedown_buffer_put(link, data + link_b, link_e - link_b);
+ }
+
+ if (title_e > title_b) {
+ title = newbuf(doc, BUFFER_SPAN);
+ hoedown_buffer_put(title, data + title_b, title_e - title_b);
+ }
+
+ i++;
+ }
+
+ /* reference style link */
+ else if (i < size && data[i] == '[') {
+ hoedown_buffer *id = newbuf(doc, BUFFER_SPAN);
+ struct link_ref *lr;
+
+ /* looking for the id */
+ i++;
+ link_b = i;
+ while (i < size && data[i] != ']') i++;
+ if (i >= size) goto cleanup;
+ link_e = i;
+
+ /* finding the link_ref */
+ if (link_b == link_e)
+ replace_spacing(id, data + 1, txt_e - 1);
+ else
+ hoedown_buffer_put(id, data + link_b, link_e - link_b);
+
+ lr = find_link_ref(doc->refs, id->data, id->size);
+ if (!lr)
+ goto cleanup;
+
+ /* keeping link and title from link_ref */
+ link = lr->link;
+ title = lr->title;
+ i++;
+ }
+
+ /* shortcut reference style link */
+ else {
+ hoedown_buffer *id = newbuf(doc, BUFFER_SPAN);
+ struct link_ref *lr;
+
+ /* crafting the id */
+ replace_spacing(id, data + 1, txt_e - 1);
+
+ /* finding the link_ref */
+ lr = find_link_ref(doc->refs, id->data, id->size);
+ if (!lr)
+ goto cleanup;
+
+ /* keeping link and title from link_ref */
+ link = lr->link;
+ title = lr->title;
+
+ /* rewinding the spacing */
+ i = txt_e + 1;
+ }
+
+ /* building content: img alt is kept, only link content is parsed */
+ if (txt_e > 1) {
+ content = newbuf(doc, BUFFER_SPAN);
+ if (is_img) {
+ hoedown_buffer_put(content, data + 1, txt_e - 1);
+ } else {
+ /* disable autolinking when parsing inline the
+ * content of a link */
+ doc->in_link_body = 1;
+ parse_inline(content, doc, data + 1, txt_e - 1);
+ doc->in_link_body = 0;
+ }
+ }
+
+ if (link) {
+ u_link = newbuf(doc, BUFFER_SPAN);
+ unscape_text(u_link, link);
+ }
+
+ /* calling the relevant rendering function */
+ if (is_img) {
+ if (ob->size && ob->data[ob->size - 1] == '!')
+ ob->size -= 1;
+
+ ret = doc->md.image(ob, u_link, title, content, &doc->data);
+ } else {
+ ret = doc->md.link(ob, content, u_link, title, &doc->data);
+ }
+
+ /* cleanup */
cleanup:
- doc->work_bufs[BUFFER_SPAN].size = (int)org_work_size;
- return ret ? i : 0;
+ doc->work_bufs[BUFFER_SPAN].size = (int)org_work_size;
+ return ret ? i : 0;
}
static size_t
char_superscript(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- size_t sup_start, sup_len;
- hoedown_buffer *sup;
+ size_t sup_start, sup_len;
+ hoedown_buffer *sup;
- if (!doc->md.superscript)
- return 0;
+ if (!doc->md.superscript)
+ return 0;
- if (size < 2)
- return 0;
+ if (size < 2)
+ return 0;
- if (data[1] == '(') {
- sup_start = 2;
- sup_len = find_emph_char(data + 2, size - 2, ')') + 2;
+ if (data[1] == '(') {
+ sup_start = 2;
+ sup_len = find_emph_char(data + 2, size - 2, ')') + 2;
- if (sup_len == size)
- return 0;
- } else {
- sup_start = sup_len = 1;
+ if (sup_len == size)
+ return 0;
+ } else {
+ sup_start = sup_len = 1;
- while (sup_len < size && !_isspace(data[sup_len]))
- sup_len++;
- }
+ while (sup_len < size && !_isspace(data[sup_len]))
+ sup_len++;
+ }
- if (sup_len - sup_start == 0)
- return (sup_start == 2) ? 3 : 0;
+ if (sup_len - sup_start == 0)
+ return (sup_start == 2) ? 3 : 0;
- sup = newbuf(doc, BUFFER_SPAN);
- parse_inline(sup, doc, data + sup_start, sup_len - sup_start);
- doc->md.superscript(ob, sup, &doc->data);
- popbuf(doc, BUFFER_SPAN);
+ sup = newbuf(doc, BUFFER_SPAN);
+ parse_inline(sup, doc, data + sup_start, sup_len - sup_start);
+ doc->md.superscript(ob, sup, &doc->data);
+ popbuf(doc, BUFFER_SPAN);
- return (sup_start == 2) ? sup_len + 1 : sup_len;
+ return (sup_start == 2) ? sup_len + 1 : sup_len;
}
static size_t
char_math(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offset, size_t size)
{
- /* double dollar */
- if (size > 1 && data[1] == '$')
- return parse_math(ob, doc, data, offset, size, "$$", 2, 1);
+ /* double dollar */
+ if (size > 1 && data[1] == '$')
+ return parse_math(ob, doc, data, offset, size, "$$", 2, 1);
- /* single dollar allowed only with MATH_EXPLICIT flag */
- if (doc->ext_flags & HOEDOWN_EXT_MATH_EXPLICIT)
- return parse_math(ob, doc, data, offset, size, "$", 1, 0);
+ /* single dollar allowed only with MATH_EXPLICIT flag */
+ if (doc->ext_flags & HOEDOWN_EXT_MATH_EXPLICIT)
+ return parse_math(ob, doc, data, offset, size, "$", 1, 0);
- return 0;
+ return 0;
}
/*********************************
@@ -1346,44 +1346,44 @@ char_math(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t offse
static size_t
is_empty(const uint8_t *data, size_t size)
{
- size_t i;
+ size_t i;
- for (i = 0; i < size && data[i] != '\n'; i++)
- if (data[i] != ' ')
- return 0;
+ for (i = 0; i < size && data[i] != '\n'; i++)
+ if (data[i] != ' ')
+ return 0;
- return i + 1;
+ return i + 1;
}
/* is_hrule • returns whether a line is a horizontal rule */
static int
is_hrule(uint8_t *data, size_t size)
{
- size_t i = 0, n = 0;
- uint8_t c;
+ size_t i = 0, n = 0;
+ uint8_t c;
- /* skipping initial spaces */
- if (size < 3) return 0;
- if (data[0] == ' ') { i++;
- if (data[1] == ' ') { i++;
- if (data[2] == ' ') { i++; } } }
+ /* skipping initial spaces */
+ if (size < 3) return 0;
+ if (data[0] == ' ') { i++;
+ if (data[1] == ' ') { i++;
+ if (data[2] == ' ') { i++; } } }
- /* looking at the hrule uint8_t */
- if (i + 2 >= size
- || (data[i] != '*' && data[i] != '-' && data[i] != '_'))
- return 0;
- c = data[i];
+ /* looking at the hrule uint8_t */
+ if (i + 2 >= size
+ || (data[i] != '*' && data[i] != '-' && data[i] != '_'))
+ return 0;
+ c = data[i];
- /* the whole line must be the char or space */
- while (i < size && data[i] != '\n') {
- if (data[i] == c) n++;
- else if (data[i] != ' ')
- return 0;
+ /* the whole line must be the char or space */
+ while (i < size && data[i] != '\n') {
+ if (data[i] == c) n++;
+ else if (data[i] != ' ')
+ return 0;
- i++;
- }
+ i++;
+ }
- return n >= 3;
+ return n >= 3;
}
/* check if a line is a code fence; return the
@@ -1392,239 +1392,239 @@ is_hrule(uint8_t *data, size_t size)
static size_t
is_codefence(uint8_t *data, size_t size, size_t *width, uint8_t *chr)
{
- size_t i = 0, n = 1;
- uint8_t c;
+ size_t i = 0, n = 1;
+ uint8_t c;
- /* skipping initial spaces */
- if (size < 3)
- return 0;
+ /* skipping initial spaces */
+ if (size < 3)
+ return 0;
- if (data[0] == ' ') { i++;
- if (data[1] == ' ') { i++;
- if (data[2] == ' ') { i++; } } }
+ if (data[0] == ' ') { i++;
+ if (data[1] == ' ') { i++;
+ if (data[2] == ' ') { i++; } } }
- /* looking at the hrule uint8_t */
- c = data[i];
- if (i + 2 >= size || !(c=='~' || c=='`'))
- return 0;
+ /* looking at the hrule uint8_t */
+ c = data[i];
+ if (i + 2 >= size || !(c=='~' || c=='`'))
+ return 0;
- /* the fence must be that same character */
- while (++i < size && data[i] == c)
- ++n;
+ /* the fence must be that same character */
+ while (++i < size && data[i] == c)
+ ++n;
- if (n < 3)
- return 0;
+ if (n < 3)
+ return 0;
- if (width) *width = n;
- if (chr) *chr = c;
- return i;
+ if (width) *width = n;
+ if (chr) *chr = c;
+ return i;
}
/* expects single line, checks if it's a codefence and extracts language */
static size_t
parse_codefence(uint8_t *data, size_t size, hoedown_buffer *lang, size_t *width, uint8_t *chr)
{
- size_t i, w, lang_start;
+ size_t i, w, lang_start;
- i = w = is_codefence(data, size, width, chr);
- if (i == 0)
- return 0;
+ i = w = is_codefence(data, size, width, chr);
+ if (i == 0)
+ return 0;
- while (i < size && _isspace(data[i]))
- i++;
+ while (i < size && _isspace(data[i]))
+ i++;
- lang_start = i;
+ lang_start = i;
- while (i < size && !_isspace(data[i]))
- i++;
+ while (i < size && !_isspace(data[i]))
+ i++;
- lang->data = data + lang_start;
- lang->size = i - lang_start;
+ lang->data = data + lang_start;
+ lang->size = i - lang_start;
- /* Avoid parsing a codespan as a fence */
- i = lang_start + 2;
- while (i < size && !(data[i] == *chr && data[i-1] == *chr && data[i-2] == *chr)) i++;
- if (i < size) return 0;
+ /* Avoid parsing a codespan as a fence */
+ i = lang_start + 2;
+ while (i < size && !(data[i] == *chr && data[i-1] == *chr && data[i-2] == *chr)) i++;
+ if (i < size) return 0;
- return w;
+ return w;
}
/* is_atxheader • returns whether the line is a hash-prefixed header */
static int
is_atxheader(hoedown_document *doc, uint8_t *data, size_t size)
{
- if (data[0] != '#')
- return 0;
+ if (data[0] != '#')
+ return 0;
- if (doc->ext_flags & HOEDOWN_EXT_SPACE_HEADERS) {
- size_t level = 0;
+ if (doc->ext_flags & HOEDOWN_EXT_SPACE_HEADERS) {
+ size_t level = 0;
- while (level < size && level < 6 && data[level] == '#')
- level++;
+ while (level < size && level < 6 && data[level] == '#')
+ level++;
- if (level < size && data[level] != ' ')
- return 0;
- }
+ if (level < size && data[level] != ' ')
+ return 0;
+ }
- return 1;
+ return 1;
}
/* is_headerline • returns whether the line is a setext-style hdr underline */
static int
is_headerline(uint8_t *data, size_t size)
{
- size_t i = 0;
+ size_t i = 0;
- /* test of level 1 header */
- if (data[i] == '=') {
- for (i = 1; i < size && data[i] == '='; i++);
- while (i < size && data[i] == ' ') i++;
- return (i >= size || data[i] == '\n') ? 1 : 0; }
+ /* test of level 1 header */
+ if (data[i] == '=') {
+ for (i = 1; i < size && data[i] == '='; i++);
+ while (i < size && data[i] == ' ') i++;
+ return (i >= size || data[i] == '\n') ? 1 : 0; }
- /* test of level 2 header */
- if (data[i] == '-') {
- for (i = 1; i < size && data[i] == '-'; i++);
- while (i < size && data[i] == ' ') i++;
- return (i >= size || data[i] == '\n') ? 2 : 0; }
+ /* test of level 2 header */
+ if (data[i] == '-') {
+ for (i = 1; i < size && data[i] == '-'; i++);
+ while (i < size && data[i] == ' ') i++;
+ return (i >= size || data[i] == '\n') ? 2 : 0; }
- return 0;
+ return 0;
}
static int
is_next_headerline(uint8_t *data, size_t size)
{
- size_t i = 0;
+ size_t i = 0;
- while (i < size && data[i] != '\n')
- i++;
+ while (i < size && data[i] != '\n')
+ i++;
- if (++i >= size)
- return 0;
+ if (++i >= size)
+ return 0;
- return is_headerline(data + i, size - i);
+ return is_headerline(data + i, size - i);
}
/* prefix_quote • returns blockquote prefix length */
static size_t
prefix_quote(uint8_t *data, size_t size)
{
- size_t i = 0;
- if (i < size && data[i] == ' ') i++;
- if (i < size && data[i] == ' ') i++;
- if (i < size && data[i] == ' ') i++;
+ size_t i = 0;
+ if (i < size && data[i] == ' ') i++;
+ if (i < size && data[i] == ' ') i++;
+ if (i < size && data[i] == ' ') i++;
- if (i < size && data[i] == '>') {
- if (i + 1 < size && data[i + 1] == ' ')
- return i + 2;
+ if (i < size && data[i] == '>') {
+ if (i + 1 < size && data[i + 1] == ' ')
+ return i + 2;
- return i + 1;
- }
+ return i + 1;
+ }
- return 0;
+ return 0;
}
/* prefix_code • returns prefix length for block code*/
static size_t
prefix_code(uint8_t *data, size_t size)
{
- if (size > 3 && data[0] == ' ' && data[1] == ' '
- && data[2] == ' ' && data[3] == ' ') return 4;
+ if (size > 3 && data[0] == ' ' && data[1] == ' '
+ && data[2] == ' ' && data[3] == ' ') return 4;
- return 0;
+ return 0;
}
/* prefix_oli • returns ordered list item prefix */
static size_t
prefix_oli(uint8_t *data, size_t size)
{
- size_t i = 0;
+ size_t i = 0;
- if (i < size && data[i] == ' ') i++;
- if (i < size && data[i] == ' ') i++;
- if (i < size && data[i] == ' ') i++;
+ if (i < size && data[i] == ' ') i++;
+ if (i < size && data[i] == ' ') i++;
+ if (i < size && data[i] == ' ') i++;
- if (i >= size || data[i] < '0' || data[i] > '9')
- return 0;
+ if (i >= size || data[i] < '0' || data[i] > '9')
+ return 0;
- while (i < size && data[i] >= '0' && data[i] <= '9')
- i++;
+ while (i < size && data[i] >= '0' && data[i] <= '9')
+ i++;
- if (i + 1 >= size || data[i] != '.' || data[i + 1] != ' ')
- return 0;
+ if (i + 1 >= size || data[i] != '.' || data[i + 1] != ' ')
+ return 0;
- if (is_next_headerline(data + i, size - i))
- return 0;
+ if (is_next_headerline(data + i, size - i))
+ return 0;
- return i + 2;
+ return i + 2;
}
/* prefix_uli • returns ordered list item prefix */
static size_t
prefix_uli(uint8_t *data, size_t size)
{
- size_t i = 0;
+ size_t i = 0;
- if (i < size && data[i] == ' ') i++;
- if (i < size && data[i] == ' ') i++;
- if (i < size && data[i] == ' ') i++;
+ if (i < size && data[i] == ' ') i++;
+ if (i < size && data[i] == ' ') i++;
+ if (i < size && data[i] == ' ') i++;
- if (i + 1 >= size ||
- (data[i] != '*' && data[i] != '+' && data[i] != '-') ||
- data[i + 1] != ' ')
- return 0;
+ if (i + 1 >= size ||
+ (data[i] != '*' && data[i] != '+' && data[i] != '-') ||
+ data[i + 1] != ' ')
+ return 0;
- if (is_next_headerline(data + i, size - i))
- return 0;
+ if (is_next_headerline(data + i, size - i))
+ return 0;
- return i + 2;
+ return i + 2;
}
/* parse_block • parsing of one block, returning next uint8_t to parse */
static void parse_block(hoedown_buffer *ob, hoedown_document *doc,
- uint8_t *data, size_t size);
+ uint8_t *data, size_t size);
/* parse_blockquote • handles parsing of a blockquote fragment */
static size_t
parse_blockquote(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size)
{
- size_t beg, end = 0, pre, work_size = 0;
- uint8_t *work_data = 0;
- hoedown_buffer *out = 0;
+ size_t beg, end = 0, pre, work_size = 0;
+ uint8_t *work_data = 0;
+ hoedown_buffer *out = 0;
- out = newbuf(doc, BUFFER_BLOCK);
- beg = 0;
- while (beg < size) {
- for (end = beg + 1; end < size && data[end - 1] != '\n'; end++);
+ out = newbuf(doc, BUFFER_BLOCK);
+ beg = 0;
+ while (beg < size) {
+ for (end = beg + 1; end < size && data[end - 1] != '\n'; end++);
- pre = prefix_quote(data + beg, end - beg);
+ pre = prefix_quote(data + beg, end - beg);
- if (pre)
- beg += pre; /* skipping prefix */
+ if (pre)
+ beg += pre; /* skipping prefix */
- /* empty line followed by non-quote line */
- else if (is_empty(data + beg, end - beg) &&
- (end >= size || (prefix_quote(data + end, size - end) == 0 &&
- !is_empty(data + end, size - end))))
- break;
+ /* empty line followed by non-quote line */
+ else if (is_empty(data + beg, end - beg) &&
+ (end >= size || (prefix_quote(data + end, size - end) == 0 &&
+ !is_empty(data + end, size - end))))
+ break;
- if (beg < end) { /* copy into the in-place working buffer */
- /* hoedown_buffer_put(work, data + beg, end - beg); */
- if (!work_data)
- work_data = data + beg;
- else if (data + beg != work_data + work_size)
- memmove(work_data + work_size, data + beg, end - beg);
- work_size += end - beg;
- }
- beg = end;
- }
+ if (beg < end) { /* copy into the in-place working buffer */
+ /* hoedown_buffer_put(work, data + beg, end - beg); */
+ if (!work_data)
+ work_data = data + beg;
+ else if (data + beg != work_data + work_size)
+ memmove(work_data + work_size, data + beg, end - beg);
+ work_size += end - beg;
+ }
+ beg = end;
+ }
- parse_block(out, doc, work_data, work_size);
- if (doc->md.blockquote)
- doc->md.blockquote(ob, out, &doc->data);
- popbuf(doc, BUFFER_BLOCK);
- return end;
+ parse_block(out, doc, work_data, work_size);
+ if (doc->md.blockquote)
+ doc->md.blockquote(ob, out, &doc->data);
+ popbuf(doc, BUFFER_BLOCK);
+ return end;
}
static size_t
@@ -1634,301 +1634,301 @@ parse_htmlblock(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
static size_t
parse_paragraph(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size)
{
- hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL };
- size_t i = 0, end = 0;
- int level = 0;
+ hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL };
+ size_t i = 0, end = 0;
+ int level = 0;
- work.data = data;
+ work.data = data;
- while (i < size) {
- for (end = i + 1; end < size && data[end - 1] != '\n'; end++) /* empty */;
+ while (i < size) {
+ for (end = i + 1; end < size && data[end - 1] != '\n'; end++) /* empty */;
- if (is_empty(data + i, size - i))
- break;
+ if (is_empty(data + i, size - i))
+ break;
- if ((level = is_headerline(data + i, size - i)) != 0)
- break;
+ if ((level = is_headerline(data + i, size - i)) != 0)
+ break;
- if (is_atxheader(doc, data + i, size - i) ||
- is_hrule(data + i, size - i) ||
- prefix_quote(data + i, size - i)) {
- end = i;
- break;
- }
+ if (is_atxheader(doc, data + i, size - i) ||
+ is_hrule(data + i, size - i) ||
+ prefix_quote(data + i, size - i)) {
+ end = i;
+ break;
+ }
- i = end;
- }
+ i = end;
+ }
- work.size = i;
- while (work.size && data[work.size - 1] == '\n')
- work.size--;
+ work.size = i;
+ while (work.size && data[work.size - 1] == '\n')
+ work.size--;
- if (!level) {
- hoedown_buffer *tmp = newbuf(doc, BUFFER_BLOCK);
- parse_inline(tmp, doc, work.data, work.size);
- if (doc->md.paragraph)
- doc->md.paragraph(ob, tmp, &doc->data);
- popbuf(doc, BUFFER_BLOCK);
- } else {
- hoedown_buffer *header_work;
+ if (!level) {
+ hoedown_buffer *tmp = newbuf(doc, BUFFER_BLOCK);
+ parse_inline(tmp, doc, work.data, work.size);
+ if (doc->md.paragraph)
+ doc->md.paragraph(ob, tmp, &doc->data);
+ popbuf(doc, BUFFER_BLOCK);
+ } else {
+ hoedown_buffer *header_work;
- if (work.size) {
- size_t beg;
- i = work.size;
- work.size -= 1;
+ if (work.size) {
+ size_t beg;
+ i = work.size;
+ work.size -= 1;
- while (work.size && data[work.size] != '\n')
- work.size -= 1;
+ while (work.size && data[work.size] != '\n')
+ work.size -= 1;
- beg = work.size + 1;
- while (work.size && data[work.size - 1] == '\n')
- work.size -= 1;
+ beg = work.size + 1;
+ while (work.size && data[work.size - 1] == '\n')
+ work.size -= 1;
- if (work.size > 0) {
- hoedown_buffer *tmp = newbuf(doc, BUFFER_BLOCK);
- parse_inline(tmp, doc, work.data, work.size);
+ if (work.size > 0) {
+ hoedown_buffer *tmp = newbuf(doc, BUFFER_BLOCK);
+ parse_inline(tmp, doc, work.data, work.size);
- if (doc->md.paragraph)
- doc->md.paragraph(ob, tmp, &doc->data);
+ if (doc->md.paragraph)
+ doc->md.paragraph(ob, tmp, &doc->data);
- popbuf(doc, BUFFER_BLOCK);
- work.data += beg;
- work.size = i - beg;
- }
- else work.size = i;
- }
+ popbuf(doc, BUFFER_BLOCK);
+ work.data += beg;
+ work.size = i - beg;
+ }
+ else work.size = i;
+ }
- header_work = newbuf(doc, BUFFER_SPAN);
- parse_inline(header_work, doc, work.data, work.size);
+ header_work = newbuf(doc, BUFFER_SPAN);
+ parse_inline(header_work, doc, work.data, work.size);
- if (doc->md.header)
- doc->md.header(ob, header_work, (int)level, &doc->data);
+ if (doc->md.header)
+ doc->md.header(ob, header_work, (int)level, &doc->data);
- popbuf(doc, BUFFER_SPAN);
- }
+ popbuf(doc, BUFFER_SPAN);
+ }
- return end;
+ return end;
}
/* parse_fencedcode • handles parsing of a block-level code fragment */
static size_t
parse_fencedcode(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size)
{
- hoedown_buffer text = { 0, 0, 0, 0, NULL, NULL, NULL };
- hoedown_buffer lang = { 0, 0, 0, 0, NULL, NULL, NULL };
- size_t i = 0, text_start, line_start;
- size_t w, w2;
- size_t width, width2;
- uint8_t chr, chr2;
+ hoedown_buffer text = { 0, 0, 0, 0, NULL, NULL, NULL };
+ hoedown_buffer lang = { 0, 0, 0, 0, NULL, NULL, NULL };
+ size_t i = 0, text_start, line_start;
+ size_t w, w2;
+ size_t width, width2;
+ uint8_t chr, chr2;
- /* parse codefence line */
- while (i < size && data[i] != '\n')
- i++;
+ /* parse codefence line */
+ while (i < size && data[i] != '\n')
+ i++;
- w = parse_codefence(data, i, &lang, &width, &chr);
- if (!w)
- return 0;
+ w = parse_codefence(data, i, &lang, &width, &chr);
+ if (!w)
+ return 0;
- /* search for end */
- i++;
- text_start = i;
- while ((line_start = i) < size) {
- while (i < size && data[i] != '\n')
- i++;
+ /* search for end */
+ i++;
+ text_start = i;
+ while ((line_start = i) < size) {
+ while (i < size && data[i] != '\n')
+ i++;
- w2 = is_codefence(data + line_start, i - line_start, &width2, &chr2);
- if (w == w2 && width == width2 && chr == chr2 &&
- is_empty(data + (line_start+w), i - (line_start+w)))
- break;
+ w2 = is_codefence(data + line_start, i - line_start, &width2, &chr2);
+ if (w == w2 && width == width2 && chr == chr2 &&
+ is_empty(data + (line_start+w), i - (line_start+w)))
+ break;
- i++;
- }
+ i++;
+ }
- text.data = data + text_start;
- text.size = line_start - text_start;
+ text.data = data + text_start;
+ text.size = line_start - text_start;
- if (doc->md.blockcode)
- doc->md.blockcode(ob, text.size ? &text : NULL, lang.size ? &lang : NULL, &doc->data);
+ if (doc->md.blockcode)
+ doc->md.blockcode(ob, text.size ? &text : NULL, lang.size ? &lang : NULL, &doc->data);
- return i;
+ return i;
}
static size_t
parse_blockcode(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size)
{
- size_t beg, end, pre;
- hoedown_buffer *work = 0;
+ size_t beg, end, pre;
+ hoedown_buffer *work = 0;
- work = newbuf(doc, BUFFER_BLOCK);
+ work = newbuf(doc, BUFFER_BLOCK);
- beg = 0;
- while (beg < size) {
- for (end = beg + 1; end < size && data[end - 1] != '\n'; end++) {};
- pre = prefix_code(data + beg, end - beg);
+ beg = 0;
+ while (beg < size) {
+ for (end = beg + 1; end < size && data[end - 1] != '\n'; end++) {};
+ pre = prefix_code(data + beg, end - beg);
- if (pre)
- beg += pre; /* skipping prefix */
- else if (!is_empty(data + beg, end - beg))
- /* non-empty non-prefixed line breaks the pre */
- break;
+ if (pre)
+ beg += pre; /* skipping prefix */
+ else if (!is_empty(data + beg, end - beg))
+ /* non-empty non-prefixed line breaks the pre */
+ break;
- if (beg < end) {
- /* verbatim copy to the working buffer,
- escaping entities */
- if (is_empty(data + beg, end - beg))
- hoedown_buffer_putc(work, '\n');
- else hoedown_buffer_put(work, data + beg, end - beg);
- }
- beg = end;
- }
+ if (beg < end) {
+ /* verbatim copy to the working buffer,
+ escaping entities */
+ if (is_empty(data + beg, end - beg))
+ hoedown_buffer_putc(work, '\n');
+ else hoedown_buffer_put(work, data + beg, end - beg);
+ }
+ beg = end;
+ }
- while (work->size && work->data[work->size - 1] == '\n')
- work->size -= 1;
+ while (work->size && work->data[work->size - 1] == '\n')
+ work->size -= 1;
- hoedown_buffer_putc(work, '\n');
+ hoedown_buffer_putc(work, '\n');
- if (doc->md.blockcode)
- doc->md.blockcode(ob, work, NULL, &doc->data);
+ if (doc->md.blockcode)
+ doc->md.blockcode(ob, work, NULL, &doc->data);
- popbuf(doc, BUFFER_BLOCK);
- return beg;
+ popbuf(doc, BUFFER_BLOCK);
+ return beg;
}
/* parse_listitem • parsing of a single list item */
-/* assuming initial prefix is already removed */
+/* assuming initial prefix is already removed */
static size_t
parse_listitem(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, hoedown_list_flags *flags)
{
- hoedown_buffer *work = 0, *inter = 0;
- size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
- int in_empty = 0, has_inside_empty = 0, in_fence = 0;
-
- /* keeping track of the first indentation prefix */
- while (orgpre < 3 && orgpre < size && data[orgpre] == ' ')
- orgpre++;
-
- beg = prefix_uli(data, size);
- if (!beg)
- beg = prefix_oli(data, size);
-
- if (!beg)
- return 0;
-
- /* skipping to the beginning of the following line */
- end = beg;
- while (end < size && data[end - 1] != '\n')
- end++;
-
- /* getting working buffers */
- work = newbuf(doc, BUFFER_SPAN);
- inter = newbuf(doc, BUFFER_SPAN);
-
- /* putting the first line into the working buffer */
- hoedown_buffer_put(work, data + beg, end - beg);
- beg = end;
-
- /* process the following lines */
- while (beg < size) {
- size_t has_next_uli = 0, has_next_oli = 0;
-
- end++;
-
- while (end < size && data[end - 1] != '\n')
- end++;
-
- /* process an empty line */
- if (is_empty(data + beg, end - beg)) {
- in_empty = 1;
- beg = end;
- continue;
- }
-
- /* calculating the indentation */
- i = 0;
- while (i < 4 && beg + i < end && data[beg + i] == ' ')
- i++;
-
- pre = i;
-
- if (doc->ext_flags & HOEDOWN_EXT_FENCED_CODE) {
- if (is_codefence(data + beg + i, end - beg - i, NULL, NULL))
- in_fence = !in_fence;
- }
-
- /* Only check for new list items if we are **not** inside
- * a fenced code block */
- if (!in_fence) {
- has_next_uli = prefix_uli(data + beg + i, end - beg - i);
- has_next_oli = prefix_oli(data + beg + i, end - beg - i);
- }
-
- /* checking for a new item */
- if ((has_next_uli && !is_hrule(data + beg + i, end - beg - i)) || has_next_oli) {
- if (in_empty)
- has_inside_empty = 1;
-
- /* the following item must have the same (or less) indentation */
- if (pre <= orgpre) {
- /* if the following item has different list type, we end this list */
- if (in_empty && (
- ((*flags & HOEDOWN_LIST_ORDERED) && has_next_uli) ||
- (!(*flags & HOEDOWN_LIST_ORDERED) && has_next_oli)))
- *flags |= HOEDOWN_LI_END;
-
- break;
- }
-
- if (!sublist)
- sublist = work->size;
- }
- /* joining only indented stuff after empty lines;
- * note that now we only require 1 space of indentation
- * to continue a list */
- else if (in_empty && pre == 0) {
- *flags |= HOEDOWN_LI_END;
- break;
- }
-
- if (in_empty) {
- hoedown_buffer_putc(work, '\n');
- has_inside_empty = 1;
- in_empty = 0;
- }
-
- /* adding the line without prefix into the working buffer */
- hoedown_buffer_put(work, data + beg + i, end - beg - i);
- beg = end;
- }
-
- /* render of li contents */
- if (has_inside_empty)
- *flags |= HOEDOWN_LI_BLOCK;
-
- if (*flags & HOEDOWN_LI_BLOCK) {
- /* intermediate render of block li */
- if (sublist && sublist < work->size) {
- parse_block(inter, doc, work->data, sublist);
- parse_block(inter, doc, work->data + sublist, work->size - sublist);
- }
- else
- parse_block(inter, doc, work->data, work->size);
- } else {
- /* intermediate render of inline li */
- if (sublist && sublist < work->size) {
- parse_inline(inter, doc, work->data, sublist);
- parse_block(inter, doc, work->data + sublist, work->size - sublist);
- }
- else
- parse_inline(inter, doc, work->data, work->size);
- }
-
- /* render of li itself */
- if (doc->md.listitem)
- doc->md.listitem(ob, inter, *flags, &doc->data);
-
- popbuf(doc, BUFFER_SPAN);
- popbuf(doc, BUFFER_SPAN);
- return beg;
+ hoedown_buffer *work = 0, *inter = 0;
+ size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
+ int in_empty = 0, has_inside_empty = 0, in_fence = 0;
+
+ /* keeping track of the first indentation prefix */
+ while (orgpre < 3 && orgpre < size && data[orgpre] == ' ')
+ orgpre++;
+
+ beg = prefix_uli(data, size);
+ if (!beg)
+ beg = prefix_oli(data, size);
+
+ if (!beg)
+ return 0;
+
+ /* skipping to the beginning of the following line */
+ end = beg;
+ while (end < size && data[end - 1] != '\n')
+ end++;
+
+ /* getting working buffers */
+ work = newbuf(doc, BUFFER_SPAN);
+ inter = newbuf(doc, BUFFER_SPAN);
+
+ /* putting the first line into the working buffer */
+ hoedown_buffer_put(work, data + beg, end - beg);
+ beg = end;
+
+ /* process the following lines */
+ while (beg < size) {
+ size_t has_next_uli = 0, has_next_oli = 0;
+
+ end++;
+
+ while (end < size && data[end - 1] != '\n')
+ end++;
+
+ /* process an empty line */
+ if (is_empty(data + beg, end - beg)) {
+ in_empty = 1;
+ beg = end;
+ continue;
+ }
+
+ /* calculating the indentation */
+ i = 0;
+ while (i < 4 && beg + i < end && data[beg + i] == ' ')
+ i++;
+
+ pre = i;
+
+ if (doc->ext_flags & HOEDOWN_EXT_FENCED_CODE) {
+ if (is_codefence(data + beg + i, end - beg - i, NULL, NULL))
+ in_fence = !in_fence;
+ }
+
+ /* Only check for new list items if we are **not** inside
+ * a fenced code block */
+ if (!in_fence) {
+ has_next_uli = prefix_uli(data + beg + i, end - beg - i);
+ has_next_oli = prefix_oli(data + beg + i, end - beg - i);
+ }
+
+ /* checking for a new item */
+ if ((has_next_uli && !is_hrule(data + beg + i, end - beg - i)) || has_next_oli) {
+ if (in_empty)
+ has_inside_empty = 1;
+
+ /* the following item must have the same (or less) indentation */
+ if (pre <= orgpre) {
+ /* if the following item has different list type, we end this list */
+ if (in_empty && (
+ ((*flags & HOEDOWN_LIST_ORDERED) && has_next_uli) ||
+ (!(*flags & HOEDOWN_LIST_ORDERED) && has_next_oli)))
+ *flags |= HOEDOWN_LI_END;
+
+ break;
+ }
+
+ if (!sublist)
+ sublist = work->size;
+ }
+ /* joining only indented stuff after empty lines;
+ * note that now we only require 1 space of indentation
+ * to continue a list */
+ else if (in_empty && pre == 0) {
+ *flags |= HOEDOWN_LI_END;
+ break;
+ }
+
+ if (in_empty) {
+ hoedown_buffer_putc(work, '\n');
+ has_inside_empty = 1;
+ in_empty = 0;
+ }
+
+ /* adding the line without prefix into the working buffer */
+ hoedown_buffer_put(work, data + beg + i, end - beg - i);
+ beg = end;
+ }
+
+ /* render of li contents */
+ if (has_inside_empty)
+ *flags |= HOEDOWN_LI_BLOCK;
+
+ if (*flags & HOEDOWN_LI_BLOCK) {
+ /* intermediate render of block li */
+ if (sublist && sublist < work->size) {
+ parse_block(inter, doc, work->data, sublist);
+ parse_block(inter, doc, work->data + sublist, work->size - sublist);
+ }
+ else
+ parse_block(inter, doc, work->data, work->size);
+ } else {
+ /* intermediate render of inline li */
+ if (sublist && sublist < work->size) {
+ parse_inline(inter, doc, work->data, sublist);
+ parse_block(inter, doc, work->data + sublist, work->size - sublist);
+ }
+ else
+ parse_inline(inter, doc, work->data, work->size);
+ }
+
+ /* render of li itself */
+ if (doc->md.listitem)
+ doc->md.listitem(ob, inter, *flags, &doc->data);
+
+ popbuf(doc, BUFFER_SPAN);
+ popbuf(doc, BUFFER_SPAN);
+ return beg;
}
@@ -1936,460 +1936,460 @@ parse_listitem(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t
static size_t
parse_list(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, hoedown_list_flags flags)
{
- hoedown_buffer *work = 0;
- size_t i = 0, j;
+ hoedown_buffer *work = 0;
+ size_t i = 0, j;
- work = newbuf(doc, BUFFER_BLOCK);
+ work = newbuf(doc, BUFFER_BLOCK);
- while (i < size) {
- j = parse_listitem(work, doc, data + i, size - i, &flags);
- i += j;
+ while (i < size) {
+ j = parse_listitem(work, doc, data + i, size - i, &flags);
+ i += j;
- if (!j || (flags & HOEDOWN_LI_END))
- break;
- }
+ if (!j || (flags & HOEDOWN_LI_END))
+ break;
+ }
- if (doc->md.list)
- doc->md.list(ob, work, flags, &doc->data);
- popbuf(doc, BUFFER_BLOCK);
- return i;
+ if (doc->md.list)
+ doc->md.list(ob, work, flags, &doc->data);
+ popbuf(doc, BUFFER_BLOCK);
+ return i;
}
/* parse_atxheader • parsing of atx-style headers */
static size_t
parse_atxheader(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size)
{
- size_t level = 0;
- size_t i, end, skip;
+ size_t level = 0;
+ size_t i, end, skip;
- while (level < size && level < 6 && data[level] == '#')
- level++;
+ while (level < size && level < 6 && data[level] == '#')
+ level++;
- for (i = level; i < size && data[i] == ' '; i++);
+ for (i = level; i < size && data[i] == ' '; i++);
- for (end = i; end < size && data[end] != '\n'; end++);
- skip = end;
+ for (end = i; end < size && data[end] != '\n'; end++);
+ skip = end;
- while (end && data[end - 1] == '#')
- end--;
+ while (end && data[end - 1] == '#')
+ end--;
- while (end && data[end - 1] == ' ')
- end--;
+ while (end && data[end - 1] == ' ')
+ end--;
- if (end > i) {
- hoedown_buffer *work = newbuf(doc, BUFFER_SPAN);
+ if (end > i) {
+ hoedown_buffer *work = newbuf(doc, BUFFER_SPAN);
- parse_inline(work, doc, data + i, end - i);
+ parse_inline(work, doc, data + i, end - i);
- if (doc->md.header)
- doc->md.header(ob, work, (int)level, &doc->data);
+ if (doc->md.header)
+ doc->md.header(ob, work, (int)level, &doc->data);
- popbuf(doc, BUFFER_SPAN);
- }
+ popbuf(doc, BUFFER_SPAN);
+ }
- return skip;
+ return skip;
}
/* parse_footnote_def • parse a single footnote definition */
static void
parse_footnote_def(hoedown_buffer *ob, hoedown_document *doc, unsigned int num, uint8_t *data, size_t size)
{
- hoedown_buffer *work = 0;
- work = newbuf(doc, BUFFER_SPAN);
+ hoedown_buffer *work = 0;
+ work = newbuf(doc, BUFFER_SPAN);
- parse_block(work, doc, data, size);
+ parse_block(work, doc, data, size);
- if (doc->md.footnote_def)
- doc->md.footnote_def(ob, work, num, &doc->data);
- popbuf(doc, BUFFER_SPAN);
+ if (doc->md.footnote_def)
+ doc->md.footnote_def(ob, work, num, &doc->data);
+ popbuf(doc, BUFFER_SPAN);
}
/* parse_footnote_list • render the contents of the footnotes */
static void
parse_footnote_list(hoedown_buffer *ob, hoedown_document *doc, struct footnote_list *footnotes)
{
- hoedown_buffer *work = 0;
- struct footnote_item *item;
- struct footnote_ref *ref;
+ hoedown_buffer *work = 0;
+ struct footnote_item *item;
+ struct footnote_ref *ref;
- if (footnotes->count == 0)
- return;
+ if (footnotes->count == 0)
+ return;
- work = newbuf(doc, BUFFER_BLOCK);
+ work = newbuf(doc, BUFFER_BLOCK);
- item = footnotes->head;
- while (item) {
- ref = item->ref;
- parse_footnote_def(work, doc, ref->num, ref->contents->data, ref->contents->size);
- item = item->next;
- }
+ item = footnotes->head;
+ while (item) {
+ ref = item->ref;
+ parse_footnote_def(work, doc, ref->num, ref->contents->data, ref->contents->size);
+ item = item->next;
+ }
- if (doc->md.footnotes)
- doc->md.footnotes(ob, work, &doc->data);
- popbuf(doc, BUFFER_BLOCK);
+ if (doc->md.footnotes)
+ doc->md.footnotes(ob, work, &doc->data);
+ popbuf(doc, BUFFER_BLOCK);
}
/* htmlblock_is_end • check for end of HTML block : </tag>( *)\n */
-/* returns tag length on match, 0 otherwise */
-/* assumes data starts with "<" */
+/* returns tag length on match, 0 otherwise */
+/* assumes data starts with "<" */
static size_t
htmlblock_is_end(
- const char *tag,
- size_t tag_len,
- hoedown_document *doc,
- uint8_t *data,
- size_t size)
+ const char *tag,
+ size_t tag_len,
+ hoedown_document *doc,
+ uint8_t *data,
+ size_t size)
{
- size_t i = tag_len + 3, w;
+ size_t i = tag_len + 3, w;
- /* try to match the end tag */
- /* note: we're not considering tags like "</tag >" which are still valid */
- if (i > size ||
- data[1] != '/' ||
- strncasecmp((char *)data + 2, tag, tag_len) != 0 ||
- data[tag_len + 2] != '>')
- return 0;
+ /* try to match the end tag */
+ /* note: we're not considering tags like "</tag >" which are still valid */
+ if (i > size ||
+ data[1] != '/' ||
+ strncasecmp((char *)data + 2, tag, tag_len) != 0 ||
+ data[tag_len + 2] != '>')
+ return 0;
- /* rest of the line must be empty */
- if ((w = is_empty(data + i, size - i)) == 0 && i < size)
- return 0;
+ /* rest of the line must be empty */
+ if ((w = is_empty(data + i, size - i)) == 0 && i < size)
+ return 0;
- return i + w;
+ return i + w;
}
/* htmlblock_find_end • try to find HTML block ending tag */
-/* returns the length on match, 0 otherwise */
+/* returns the length on match, 0 otherwise */
static size_t
htmlblock_find_end(
- const char *tag,
- size_t tag_len,
- hoedown_document *doc,
- uint8_t *data,
- size_t size)
+ const char *tag,
+ size_t tag_len,
+ hoedown_document *doc,
+ uint8_t *data,
+ size_t size)
{
- size_t i = 0, w;
+ size_t i = 0, w;
- while (1) {
- while (i < size && data[i] != '<') i++;
- if (i >= size) return 0;
+ while (1) {
+ while (i < size && data[i] != '<') i++;
+ if (i >= size) return 0;
- w = htmlblock_is_end(tag, tag_len, doc, data + i, size - i);
- if (w) return i + w;
- i++;
- }
+ w = htmlblock_is_end(tag, tag_len, doc, data + i, size - i);
+ if (w) return i + w;
+ i++;
+ }
}
/* htmlblock_find_end_strict • try to find end of HTML block in strict mode */
-/* (it must be an unindented line, and have a blank line afterwads) */
-/* returns the length on match, 0 otherwise */
+/* (it must be an unindented line, and have a blank line afterwads) */
+/* returns the length on match, 0 otherwise */
static size_t
htmlblock_find_end_strict(
- const char *tag,
- size_t tag_len,
- hoedown_document *doc,
- uint8_t *data,
- size_t size)
+ const char *tag,
+ size_t tag_len,
+ hoedown_document *doc,
+ uint8_t *data,
+ size_t size)
{
- size_t i = 0, mark;
+ size_t i = 0, mark;
- while (1) {
- mark = i;
- while (i < size && data[i] != '\n') i++;
- if (i < size) i++;
- if (i == mark) return 0;
+ while (1) {
+ mark = i;
+ while (i < size && data[i] != '\n') i++;
+ if (i < size) i++;
+ if (i == mark) return 0;
- if (data[mark] == ' ' && mark > 0) continue;
- mark += htmlblock_find_end(tag, tag_len, doc, data + mark, i - mark);
- if (mark == i && (is_empty(data + i, size - i) || i >= size)) break;
- }
+ if (data[mark] == ' ' && mark > 0) continue;
+ mark += htmlblock_find_end(tag, tag_len, doc, data + mark, i - mark);
+ if (mark == i && (is_empty(data + i, size - i) || i >= size)) break;
+ }
- return i;
+ return i;
}
/* parse_htmlblock • parsing of inline HTML block */
static size_t
parse_htmlblock(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size, int do_render)
{
- hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL };
- size_t i, j = 0, tag_len, tag_end;
- const char *curtag = NULL;
+ hoedown_buffer work = { NULL, 0, 0, 0, NULL, NULL, NULL };
+ size_t i, j = 0, tag_len, tag_end;
+ const char *curtag = NULL;
- work.data = data;
+ work.data = data;
- /* identification of the opening tag */
- if (size < 2 || data[0] != '<')
- return 0;
+ /* identification of the opening tag */
+ if (size < 2 || data[0] != '<')
+ return 0;
- i = 1;
- while (i < size && data[i] != '>' && data[i] != ' ')
- i++;
+ i = 1;
+ while (i < size && data[i] != '>' && data[i] != ' ')
+ i++;
- if (i < size)
- curtag = hoedown_find_block_tag((char *)data + 1, (int)i - 1);
+ if (i < size)
+ curtag = hoedown_find_block_tag((char *)data + 1, (int)i - 1);
- /* handling of special cases */
- if (!curtag) {
+ /* handling of special cases */
+ if (!curtag) {
- /* HTML comment, laxist form */
- if (size > 5 && data[1] == '!' && data[2] == '-' && data[3] == '-') {
- i = 5;
+ /* HTML comment, laxist form */
+ if (size > 5 && data[1] == '!' && data[2] == '-' && data[3] == '-') {
+ i = 5;
- while (i < size && !(data[i - 2] == '-' && data[i - 1] == '-' && data[i] == '>'))
- i++;
+ while (i < size && !(data[i - 2] == '-' && data[i - 1] == '-' && data[i] == '>'))
+ i++;
- i++;
+ i++;
- if (i < size)
- j = is_empty(data + i, size - i);
+ if (i < size)
+ j = is_empty(data + i, size - i);
- if (j) {
- work.size = i + j;
- if (do_render && doc->md.blockhtml)
- doc->md.blockhtml(ob, &work, &doc->data);
- return work.size;
- }
- }
+ if (j) {
+ work.size = i + j;
+ if (do_render && doc->md.blockhtml)
+ doc->md.blockhtml(ob, &work, &doc->data);
+ return work.size;
+ }
+ }
- /* HR, which is the only self-closing block tag considered */
- if (size > 4 && (data[1] == 'h' || data[1] == 'H') && (data[2] == 'r' || data[2] == 'R')) {
- i = 3;
- while (i < size && data[i] != '>')
- i++;
+ /* HR, which is the only self-closing block tag considered */
+ if (size > 4 && (data[1] == 'h' || data[1] == 'H') && (data[2] == 'r' || data[2] == 'R')) {
+ i = 3;
+ while (i < size && data[i] != '>')
+ i++;
- if (i + 1 < size) {
- i++;
- j = is_empty(data + i, size - i);
- if (j) {
- work.size = i + j;
- if (do_render && doc->md.blockhtml)
- doc->md.blockhtml(ob, &work, &doc->data);
- return work.size;
- }
- }
- }
+ if (i + 1 < size) {
+ i++;
+ j = is_empty(data + i, size - i);
+ if (j) {
+ work.size = i + j;
+ if (do_render && doc->md.blockhtml)
+ doc->md.blockhtml(ob, &work, &doc->data);
+ return work.size;
+ }
+ }
+ }
- /* no special case recognised */
- return 0;
- }
+ /* no special case recognised */
+ return 0;
+ }
- /* looking for a matching closing tag in strict mode */
- tag_len = strlen(curtag);
- tag_end = htmlblock_find_end_strict(curtag, tag_len, doc, data, size);
+ /* looking for a matching closing tag in strict mode */
+ tag_len = strlen(curtag);
+ tag_end = htmlblock_find_end_strict(curtag, tag_len, doc, data, size);
- /* if not found, trying a second pass looking for indented match */
- /* but not if tag is "ins" or "del" (following original Markdown.pl) */
- if (!tag_end && strcmp(curtag, "ins") != 0 && strcmp(curtag, "del") != 0)
- tag_end = htmlblock_find_end(curtag, tag_len, doc, data, size);
+ /* if not found, trying a second pass looking for indented match */
+ /* but not if tag is "ins" or "del" (following original Markdown.pl) */
+ if (!tag_end && strcmp(curtag, "ins") != 0 && strcmp(curtag, "del") != 0)
+ tag_end = htmlblock_find_end(curtag, tag_len, doc, data, size);
- if (!tag_end)
- return 0;
+ if (!tag_end)
+ return 0;
- /* the end of the block has been found */
- work.size = tag_end;
- if (do_render && doc->md.blockhtml)
- doc->md.blockhtml(ob, &work, &doc->data);
+ /* the end of the block has been found */
+ work.size = tag_end;
+ if (do_render && doc->md.blockhtml)
+ doc->md.blockhtml(ob, &work, &doc->data);
- return tag_end;
+ return tag_end;
}
static void
parse_table_row(
- hoedown_buffer *ob,
- hoedown_document *doc,
- uint8_t *data,
- size_t size,
- size_t columns,
- hoedown_table_flags *col_data,
- hoedown_table_flags header_flag)
+ hoedown_buffer *ob,
+ hoedown_document *doc,
+ uint8_t *data,
+ size_t size,
+ size_t columns,
+ hoedown_table_flags *col_data,
+ hoedown_table_flags header_flag)
{
- size_t i = 0, col, len;
- hoedown_buffer *row_work = 0;
+ size_t i = 0, col, len;
+ hoedown_buffer *row_work = 0;
- if (!doc->md.table_cell || !doc->md.table_row)
- return;
+ if (!doc->md.table_cell || !doc->md.table_row)
+ return;
- row_work = newbuf(doc, BUFFER_SPAN);
+ row_work = newbuf(doc, BUFFER_SPAN);
- if (i < size && data[i] == '|')
- i++;
+ if (i < size && data[i] == '|')
+ i++;
- for (col = 0; col < columns && i < size; ++col) {
- size_t cell_start, cell_end;
- hoedown_buffer *cell_work;
+ for (col = 0; col < columns && i < size; ++col) {
+ size_t cell_start, cell_end;
+ hoedown_buffer *cell_work;
- cell_work = newbuf(doc, BUFFER_SPAN);
+ cell_work = newbuf(doc, BUFFER_SPAN);
- while (i < size && _isspace(data[i]))
- i++;
+ while (i < size && _isspace(data[i]))
+ i++;
- cell_start = i;
+ cell_start = i;
- len = find_emph_char(data + i, size - i, '|');
- i += len ? len : size - i;
+ len = find_emph_char(data + i, size - i, '|');
+ i += len ? len : size - i;
- cell_end = i - 1;
+ cell_end = i - 1;
- while (cell_end > cell_start && _isspace(data[cell_end]))
- cell_end--;
+ while (cell_end > cell_start && _isspace(data[cell_end]))
+ cell_end--;
- parse_inline(cell_work, doc, data + cell_start, 1 + cell_end - cell_start);
- doc->md.table_cell(row_work, cell_work, col_data[col] | header_flag, &doc->data);
+ parse_inline(cell_work, doc, data + cell_start, 1 + cell_end - cell_start);
+ doc->md.table_cell(row_work, cell_work, col_data[col] | header_flag, &doc->data);
- popbuf(doc, BUFFER_SPAN);
- i++;
- }
+ popbuf(doc, BUFFER_SPAN);
+ i++;
+ }
- for (; col < columns; ++col) {
- hoedown_buffer empty_cell = { 0, 0, 0, 0, NULL, NULL, NULL };
- doc->md.table_cell(row_work, &empty_cell, col_data[col] | header_flag, &doc->data);
- }
+ for (; col < columns; ++col) {
+ hoedown_buffer empty_cell = { 0, 0, 0, 0, NULL, NULL, NULL };
+ doc->md.table_cell(row_work, &empty_cell, col_data[col] | header_flag, &doc->data);
+ }
- doc->md.table_row(ob, row_work, &doc->data);
+ doc->md.table_row(ob, row_work, &doc->data);
- popbuf(doc, BUFFER_SPAN);
+ popbuf(doc, BUFFER_SPAN);
}
static size_t
parse_table_header(
- hoedown_buffer *ob,
- hoedown_document *doc,
- uint8_t *data,
- size_t size,
- size_t *columns,
- hoedown_table_flags **column_data)
+ hoedown_buffer *ob,
+ hoedown_document *doc,
+ uint8_t *data,
+ size_t size,
+ size_t *columns,
+ hoedown_table_flags **column_data)
{
- int pipes;
- size_t i = 0, col, header_end, under_end;
+ int pipes;
+ size_t i = 0, col, header_end, under_end;
- pipes = 0;
- while (i < size && data[i] != '\n')
- if (data[i++] == '|')
- pipes++;
+ pipes = 0;
+ while (i < size && data[i] != '\n')
+ if (data[i++] == '|')
+ pipes++;
- if (i == size || pipes == 0)
- return 0;
+ if (i == size || pipes == 0)
+ return 0;
- header_end = i;
+ header_end = i;
- while (header_end > 0 && _isspace(data[header_end - 1]))
- header_end--;
+ while (header_end > 0 && _isspace(data[header_end - 1]))
+ header_end--;
- if (data[0] == '|')
- pipes--;
+ if (data[0] == '|')
+ pipes--;
- if (header_end && data[header_end - 1] == '|')
- pipes--;
+ if (header_end && data[header_end - 1] == '|')
+ pipes--;
- if (pipes < 0)
- return 0;
+ if (pipes < 0)
+ return 0;
- *columns = pipes + 1;
- *column_data = hoedown_calloc(*columns, sizeof(hoedown_table_flags));
+ *columns = pipes + 1;
+ *column_data = hoedown_calloc(*columns, sizeof(hoedown_table_flags));
- /* Parse the header underline */
- i++;
- if (i < size && data[i] == '|')
- i++;
+ /* Parse the header underline */
+ i++;
+ if (i < size && data[i] == '|')
+ i++;
- under_end = i;
- while (under_end < size && data[under_end] != '\n')
- under_end++;
+ under_end = i;
+ while (under_end < size && data[under_end] != '\n')
+ under_end++;
- for (col = 0; col < *columns && i < under_end; ++col) {
- size_t dashes = 0;
+ for (col = 0; col < *columns && i < under_end; ++col) {
+ size_t dashes = 0;
- while (i < under_end && data[i] == ' ')
- i++;
+ while (i < under_end && data[i] == ' ')
+ i++;
- if (data[i] == ':') {
- i++; (*column_data)[col] |= HOEDOWN_TABLE_ALIGN_LEFT;
- dashes++;
- }
+ if (data[i] == ':') {
+ i++; (*column_data)[col] |= HOEDOWN_TABLE_ALIGN_LEFT;
+ dashes++;
+ }
- while (i < under_end && data[i] == '-') {
- i++; dashes++;
- }
+ while (i < under_end && data[i] == '-') {
+ i++; dashes++;
+ }
- if (i < under_end && data[i] == ':') {
- i++; (*column_data)[col] |= HOEDOWN_TABLE_ALIGN_RIGHT;
- dashes++;
- }
+ if (i < under_end && data[i] == ':') {
+ i++; (*column_data)[col] |= HOEDOWN_TABLE_ALIGN_RIGHT;
+ dashes++;
+ }
- while (i < under_end && data[i] == ' ')
- i++;
+ while (i < under_end && data[i] == ' ')
+ i++;
- if (i < under_end && data[i] != '|' && data[i] != '+')
- break;
+ if (i < under_end && data[i] != '|' && data[i] != '+')
+ break;
- if (dashes < 3)
- break;
+ if (dashes < 3)
+ break;
- i++;
- }
+ i++;
+ }
- if (col < *columns)
- return 0;
+ if (col < *columns)
+ return 0;
- parse_table_row(
- ob, doc, data,
- header_end,
- *columns,
- *column_data,
- HOEDOWN_TABLE_HEADER
- );
+ parse_table_row(
+ ob, doc, data,
+ header_end,
+ *columns,
+ *column_data,
+ HOEDOWN_TABLE_HEADER
+ );
- return under_end + 1;
+ return under_end + 1;
}
static size_t
parse_table(
- hoedown_buffer *ob,
- hoedown_document *doc,
- uint8_t *data,
- size_t size)
+ hoedown_buffer *ob,
+ hoedown_document *doc,
+ uint8_t *data,
+ size_t size)
{
- size_t i;
+ size_t i;
- hoedown_buffer *work = 0;
- hoedown_buffer *header_work = 0;
- hoedown_buffer *body_work = 0;
+ hoedown_buffer *work = 0;
+ hoedown_buffer *header_work = 0;
+ hoedown_buffer *body_work = 0;
- size_t columns;
- hoedown_table_flags *col_data = NULL;
+ size_t columns;
+ hoedown_table_flags *col_data = NULL;
- work = newbuf(doc, BUFFER_BLOCK);
- header_work = newbuf(doc, BUFFER_SPAN);
- body_work = newbuf(doc, BUFFER_BLOCK);
+ work = newbuf(doc, BUFFER_BLOCK);
+ header_work = newbuf(doc, BUFFER_SPAN);
+ body_work = newbuf(doc, BUFFER_BLOCK);
- i = parse_table_header(header_work, doc, data, size, &columns, &col_data);
- if (i > 0) {
+ i = parse_table_header(header_work, doc, data, size, &columns, &col_data);
+ if (i > 0) {
- while (i < size) {
- size_t row_start;
- int pipes = 0;
+ while (i < size) {
+ size_t row_start;
+ int pipes = 0;
- row_start = i;
+ row_start = i;
- while (i < size && data[i] != '\n')
- if (data[i++] == '|')
- pipes++;
+ while (i < size && data[i] != '\n')
+ if (data[i++] == '|')
+ pipes++;
- if (pipes == 0 || i == size) {
- i = row_start;
- break;
- }
+ if (pipes == 0 || i == size) {
+ i = row_start;
+ break;
+ }
- parse_table_row(
- body_work,
- doc,
- data + row_start,
- i - row_start,
- columns,
- col_data, 0
- );
+ parse_table_row(
+ body_work,
+ doc,
+ data + row_start,
+ i - row_start,
+ columns,
+ col_data, 0
+ );
- i++;
- }
+ i++;
+ }
if (doc->md.table_header)
doc->md.table_header(work, header_work, &doc->data);
@@ -2397,76 +2397,76 @@ parse_table(
if (doc->md.table_body)
doc->md.table_body(work, body_work, &doc->data);
- if (doc->md.table)
- doc->md.table(ob, work, &doc->data);
- }
+ if (doc->md.table)
+ doc->md.table(ob, work, &doc->data);
+ }
- free(col_data);
- popbuf(doc, BUFFER_SPAN);
- popbuf(doc, BUFFER_BLOCK);
- popbuf(doc, BUFFER_BLOCK);
- return i;
+ free(col_data);
+ popbuf(doc, BUFFER_SPAN);
+ popbuf(doc, BUFFER_BLOCK);
+ popbuf(doc, BUFFER_BLOCK);
+ return i;
}
/* parse_block • parsing of one block, returning next uint8_t to parse */
static void
parse_block(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size)
{
- size_t beg, end, i;
- uint8_t *txt_data;
- beg = 0;
+ size_t beg, end, i;
+ uint8_t *txt_data;
+ beg = 0;
- if (doc->work_bufs[BUFFER_SPAN].size +
- doc->work_bufs[BUFFER_BLOCK].size > doc->max_nesting)
- return;
+ if (doc->work_bufs[BUFFER_SPAN].size +
+ doc->work_bufs[BUFFER_BLOCK].size > doc->max_nesting)
+ return;
- while (beg < size) {
- txt_data = data + beg;
- end = size - beg;
+ while (beg < size) {
+ txt_data = data + beg;
+ end = size - beg;
- if (is_atxheader(doc, txt_data, end))
- beg += parse_atxheader(ob, doc, txt_data, end);
+ if (is_atxheader(doc, txt_data, end))
+ beg += parse_atxheader(ob, doc, txt_data, end);
- else if (data[beg] == '<' && doc->md.blockhtml &&
- (i = parse_htmlblock(ob, doc, txt_data, end, 1)) != 0)
- beg += i;
+ else if (data[beg] == '<' && doc->md.blockhtml &&
+ (i = parse_htmlblock(ob, doc, txt_data, end, 1)) != 0)
+ beg += i;
- else if ((i = is_empty(txt_data, end)) != 0)
- beg += i;
+ else if ((i = is_empty(txt_data, end)) != 0)
+ beg += i;
- else if (is_hrule(txt_data, end)) {
- if (doc->md.hrule)
- doc->md.hrule(ob, &doc->data);
+ else if (is_hrule(txt_data, end)) {
+ if (doc->md.hrule)
+ doc->md.hrule(ob, &doc->data);
- while (beg < size && data[beg] != '\n')
- beg++;
+ while (beg < size && data[beg] != '\n')
+ beg++;
- beg++;
- }
+ beg++;
+ }
- else if ((doc->ext_flags & HOEDOWN_EXT_FENCED_CODE) != 0 &&
- (i = parse_fencedcode(ob, doc, txt_data, end)) != 0)
- beg += i;
+ else if ((doc->ext_flags & HOEDOWN_EXT_FENCED_CODE) != 0 &&
+ (i = parse_fencedcode(ob, doc, txt_data, end)) != 0)
+ beg += i;
- else if ((doc->ext_flags & HOEDOWN_EXT_TABLES) != 0 &&
- (i = parse_table(ob, doc, txt_data, end)) != 0)
- beg += i;
+ else if ((doc->ext_flags & HOEDOWN_EXT_TABLES) != 0 &&
+ (i = parse_table(ob, doc, txt_data, end)) != 0)
+ beg += i;
- else if (prefix_quote(txt_data, end))
- beg += parse_blockquote(ob, doc, txt_data, end);
+ else if (prefix_quote(txt_data, end))
+ beg += parse_blockquote(ob, doc, txt_data, end);
- else if (!(doc->ext_flags & HOEDOWN_EXT_DISABLE_INDENTED_CODE) && prefix_code(txt_data, end))
- beg += parse_blockcode(ob, doc, txt_data, end);
+ else if (!(doc->ext_flags & HOEDOWN_EXT_DISABLE_INDENTED_CODE) && prefix_code(txt_data, end))
+ beg += parse_blockcode(ob, doc, txt_data, end);
- else if (prefix_uli(txt_data, end))
- beg += parse_list(ob, doc, txt_data, end, 0);
+ else if (prefix_uli(txt_data, end))
+ beg += parse_list(ob, doc, txt_data, end, 0);
- else if (prefix_oli(txt_data, end))
- beg += parse_list(ob, doc, txt_data, end, HOEDOWN_LIST_ORDERED);
+ else if (prefix_oli(txt_data, end))
+ beg += parse_list(ob, doc, txt_data, end, HOEDOWN_LIST_ORDERED);
- else
- beg += parse_paragraph(ob, doc, txt_data, end);
- }
+ else
+ beg += parse_paragraph(ob, doc, txt_data, end);
+ }
}
@@ -2479,253 +2479,253 @@ parse_block(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t siz
static int
is_footnote(const uint8_t *data, size_t beg, size_t end, size_t *last, struct footnote_list *list)
{
- size_t i = 0;
- hoedown_buffer *contents = 0;
- size_t ind = 0;
- int in_empty = 0;
- size_t start = 0;
-
- size_t id_offset, id_end;
-
- /* up to 3 optional leading spaces */
- if (beg + 3 >= end) return 0;
- if (data[beg] == ' ') { i = 1;
- if (data[beg + 1] == ' ') { i = 2;
- if (data[beg + 2] == ' ') { i = 3;
- if (data[beg + 3] == ' ') return 0; } } }
- i += beg;
-
- /* id part: caret followed by anything between brackets */
- if (data[i] != '[') return 0;
- i++;
- if (i >= end || data[i] != '^') return 0;
- i++;
- id_offset = i;
- while (i < end && data[i] != '\n' && data[i] != '\r' && data[i] != ']')
- i++;
- if (i >= end || data[i] != ']') return 0;
- id_end = i;
-
- /* spacer: colon (space | tab)* newline? (space | tab)* */
- i++;
- if (i >= end || data[i] != ':') return 0;
- i++;
-
- /* getting content buffer */
- contents = hoedown_buffer_new(64);
-
- start = i;
-
- /* process lines similar to a list item */
- while (i < end) {
- while (i < end && data[i] != '\n' && data[i] != '\r') i++;
-
- /* process an empty line */
- if (is_empty(data + start, i - start)) {
- in_empty = 1;
- if (i < end && (data[i] == '\n' || data[i] == '\r')) {
- i++;
- if (i < end && data[i] == '\n' && data[i - 1] == '\r') i++;
- }
- start = i;
- continue;
- }
-
- /* calculating the indentation */
- ind = 0;
- while (ind < 4 && start + ind < end && data[start + ind] == ' ')
- ind++;
-
- /* joining only indented stuff after empty lines;
- * note that now we only require 1 space of indentation
- * to continue, just like lists */
- if (ind == 0) {
- if (start == id_end + 2 && data[start] == '\t') {}
- else break;
- }
- else if (in_empty) {
- hoedown_buffer_putc(contents, '\n');
- }
-
- in_empty = 0;
-
- /* adding the line into the content buffer */
- hoedown_buffer_put(contents, data + start + ind, i - start - ind);
- /* add carriage return */
- if (i < end) {
- hoedown_buffer_putc(contents, '\n');
- if (i < end && (data[i] == '\n' || data[i] == '\r')) {
- i++;
- if (i < end && data[i] == '\n' && data[i - 1] == '\r') i++;
- }
- }
- start = i;
- }
-
- if (last)
- *last = start;
-
- if (list) {
- struct footnote_ref *ref;
- ref = create_footnote_ref(list, data + id_offset, id_end - id_offset);
- if (!ref)
- return 0;
- if (!add_footnote_ref(list, ref)) {
- free_footnote_ref(ref);
- return 0;
- }
- ref->contents = contents;
- }
-
- return 1;
+ size_t i = 0;
+ hoedown_buffer *contents = 0;
+ size_t ind = 0;
+ int in_empty = 0;
+ size_t start = 0;
+
+ size_t id_offset, id_end;
+
+ /* up to 3 optional leading spaces */
+ if (beg + 3 >= end) return 0;
+ if (data[beg] == ' ') { i = 1;
+ if (data[beg + 1] == ' ') { i = 2;
+ if (data[beg + 2] == ' ') { i = 3;
+ if (data[beg + 3] == ' ') return 0; } } }
+ i += beg;
+
+ /* id part: caret followed by anything between brackets */
+ if (data[i] != '[') return 0;
+ i++;
+ if (i >= end || data[i] != '^') return 0;
+ i++;
+ id_offset = i;
+ while (i < end && data[i] != '\n' && data[i] != '\r' && data[i] != ']')
+ i++;
+ if (i >= end || data[i] != ']') return 0;
+ id_end = i;
+
+ /* spacer: colon (space | tab)* newline? (space | tab)* */
+ i++;
+ if (i >= end || data[i] != ':') return 0;
+ i++;
+
+ /* getting content buffer */
+ contents = hoedown_buffer_new(64);
+
+ start = i;
+
+ /* process lines similar to a list item */
+ while (i < end) {
+ while (i < end && data[i] != '\n' && data[i] != '\r') i++;
+
+ /* process an empty line */
+ if (is_empty(data + start, i - start)) {
+ in_empty = 1;
+ if (i < end && (data[i] == '\n' || data[i] == '\r')) {
+ i++;
+ if (i < end && data[i] == '\n' && data[i - 1] == '\r') i++;
+ }
+ start = i;
+ continue;
+ }
+
+ /* calculating the indentation */
+ ind = 0;
+ while (ind < 4 && start + ind < end && data[start + ind] == ' ')
+ ind++;
+
+ /* joining only indented stuff after empty lines;
+ * note that now we only require 1 space of indentation
+ * to continue, just like lists */
+ if (ind == 0) {
+ if (start == id_end + 2 && data[start] == '\t') {}
+ else break;
+ }
+ else if (in_empty) {
+ hoedown_buffer_putc(contents, '\n');
+ }
+
+ in_empty = 0;
+
+ /* adding the line into the content buffer */
+ hoedown_buffer_put(contents, data + start + ind, i - start - ind);
+ /* add carriage return */
+ if (i < end) {
+ hoedown_buffer_putc(contents, '\n');
+ if (i < end && (data[i] == '\n' || data[i] == '\r')) {
+ i++;
+ if (i < end && data[i] == '\n' && data[i - 1] == '\r') i++;
+ }
+ }
+ start = i;
+ }
+
+ if (last)
+ *last = start;
+
+ if (list) {
+ struct footnote_ref *ref;
+ ref = create_footnote_ref(list, data + id_offset, id_end - id_offset);
+ if (!ref)
+ return 0;
+ if (!add_footnote_ref(list, ref)) {
+ free_footnote_ref(ref);
+ return 0;
+ }
+ ref->contents = contents;
+ }
+
+ return 1;
}
/* is_ref • returns whether a line is a reference or not */
static int
is_ref(const uint8_t *data, size_t beg, size_t end, size_t *last, struct link_ref **refs)
{
-/* int n; */
- size_t i = 0;
- size_t id_offset, id_end;
- size_t link_offset, link_end;
- size_t title_offset, title_end;
- size_t line_end;
-
- /* up to 3 optional leading spaces */
- if (beg + 3 >= end) return 0;
- if (data[beg] == ' ') { i = 1;
- if (data[beg + 1] == ' ') { i = 2;
- if (data[beg + 2] == ' ') { i = 3;
- if (data[beg + 3] == ' ') return 0; } } }
- i += beg;
-
- /* id part: anything but a newline between brackets */
- if (data[i] != '[') return 0;
- i++;
- id_offset = i;
- while (i < end && data[i] != '\n' && data[i] != '\r' && data[i] != ']')
- i++;
- if (i >= end || data[i] != ']') return 0;
- id_end = i;
-
- /* spacer: colon (space | tab)* newline? (space | tab)* */
- i++;
- if (i >= end || data[i] != ':') return 0;
- i++;
- while (i < end && data[i] == ' ') i++;
- if (i < end && (data[i] == '\n' || data[i] == '\r')) {
- i++;
- if (i < end && data[i] == '\r' && data[i - 1] == '\n') i++; }
- while (i < end && data[i] == ' ') i++;
- if (i >= end) return 0;
-
- /* link: spacing-free sequence, optionally between angle brackets */
- if (data[i] == '<')
- i++;
-
- link_offset = i;
-
- while (i < end && data[i] != ' ' && data[i] != '\n' && data[i] != '\r')
- i++;
-
- if (data[i - 1] == '>') link_end = i - 1;
- else link_end = i;
-
- /* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */
- while (i < end && data[i] == ' ') i++;
- if (i < end && data[i] != '\n' && data[i] != '\r'
- && data[i] != '\'' && data[i] != '"' && data[i] != '(')
- return 0;
- line_end = 0;
- /* computing end-of-line */
- if (i >= end || data[i] == '\r' || data[i] == '\n') line_end = i;
- if (i + 1 < end && data[i] == '\n' && data[i + 1] == '\r')
- line_end = i + 1;
-
- /* optional (space|tab)* spacer after a newline */
- if (line_end) {
- i = line_end + 1;
- while (i < end && data[i] == ' ') i++; }
-
- /* optional title: any non-newline sequence enclosed in '"()
- alone on its line */
- title_offset = title_end = 0;
- if (i + 1 < end
- && (data[i] == '\'' || data[i] == '"' || data[i] == '(')) {
- i++;
- title_offset = i;
- /* looking for EOL */
- while (i < end && data[i] != '\n' && data[i] != '\r') i++;
- if (i + 1 < end && data[i] == '\n' && data[i + 1] == '\r')
- title_end = i + 1;
- else title_end = i;
- /* stepping back */
- i -= 1;
- while (i > title_offset && data[i] == ' ')
- i -= 1;
- if (i > title_offset
- && (data[i] == '\'' || data[i] == '"' || data[i] == ')')) {
- line_end = title_end;
- title_end = i; } }
-
- if (!line_end || link_end == link_offset)
- return 0; /* garbage after the link empty link */
-
- /* a valid ref has been found, filling-in return structures */
- if (last)
- *last = line_end;
-
- if (refs) {
- struct link_ref *ref;
-
- ref = add_link_ref(refs, data + id_offset, id_end - id_offset);
- if (!ref)
- return 0;
-
- ref->link = hoedown_buffer_new(link_end - link_offset);
- hoedown_buffer_put(ref->link, data + link_offset, link_end - link_offset);
-
- if (title_end > title_offset) {
- ref->title = hoedown_buffer_new(title_end - title_offset);
- hoedown_buffer_put(ref->title, data + title_offset, title_end - title_offset);
- }
- }
-
- return 1;
+/* int n; */
+ size_t i = 0;
+ size_t id_offset, id_end;
+ size_t link_offset, link_end;
+ size_t title_offset, title_end;
+ size_t line_end;
+
+ /* up to 3 optional leading spaces */
+ if (beg + 3 >= end) return 0;
+ if (data[beg] == ' ') { i = 1;
+ if (data[beg + 1] == ' ') { i = 2;
+ if (data[beg + 2] == ' ') { i = 3;
+ if (data[beg + 3] == ' ') return 0; } } }
+ i += beg;
+
+ /* id part: anything but a newline between brackets */
+ if (data[i] != '[') return 0;
+ i++;
+ id_offset = i;
+ while (i < end && data[i] != '\n' && data[i] != '\r' && data[i] != ']')
+ i++;
+ if (i >= end || data[i] != ']') return 0;
+ id_end = i;
+
+ /* spacer: colon (space | tab)* newline? (space | tab)* */
+ i++;
+ if (i >= end || data[i] != ':') return 0;
+ i++;
+ while (i < end && data[i] == ' ') i++;
+ if (i < end && (data[i] == '\n' || data[i] == '\r')) {
+ i++;
+ if (i < end && data[i] == '\r' && data[i - 1] == '\n') i++; }
+ while (i < end && data[i] == ' ') i++;
+ if (i >= end) return 0;
+
+ /* link: spacing-free sequence, optionally between angle brackets */
+ if (data[i] == '<')
+ i++;
+
+ link_offset = i;
+
+ while (i < end && data[i] != ' ' && data[i] != '\n' && data[i] != '\r')
+ i++;
+
+ if (data[i - 1] == '>') link_end = i - 1;
+ else link_end = i;
+
+ /* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */
+ while (i < end && data[i] == ' ') i++;
+ if (i < end && data[i] != '\n' && data[i] != '\r'
+ && data[i] != '\'' && data[i] != '"' && data[i] != '(')
+ return 0;
+ line_end = 0;
+ /* computing end-of-line */
+ if (i >= end || data[i] == '\r' || data[i] == '\n') line_end = i;
+ if (i + 1 < end && data[i] == '\n' && data[i + 1] == '\r')
+ line_end = i + 1;
+
+ /* optional (space|tab)* spacer after a newline */
+ if (line_end) {
+ i = line_end + 1;
+ while (i < end && data[i] == ' ') i++; }
+
+ /* optional title: any non-newline sequence enclosed in '"()
+ alone on its line */
+ title_offset = title_end = 0;
+ if (i + 1 < end
+ && (data[i] == '\'' || data[i] == '"' || data[i] == '(')) {
+ i++;
+ title_offset = i;
+ /* looking for EOL */
+ while (i < end && data[i] != '\n' && data[i] != '\r') i++;
+ if (i + 1 < end && data[i] == '\n' && data[i + 1] == '\r')
+ title_end = i + 1;
+ else title_end = i;
+ /* stepping back */
+ i -= 1;
+ while (i > title_offset && data[i] == ' ')
+ i -= 1;
+ if (i > title_offset
+ && (data[i] == '\'' || data[i] == '"' || data[i] == ')')) {
+ line_end = title_end;
+ title_end = i; } }
+
+ if (!line_end || link_end == link_offset)
+ return 0; /* garbage after the link empty link */
+
+ /* a valid ref has been found, filling-in return structures */
+ if (last)
+ *last = line_end;
+
+ if (refs) {
+ struct link_ref *ref;
+
+ ref = add_link_ref(refs, data + id_offset, id_end - id_offset);
+ if (!ref)
+ return 0;
+
+ ref->link = hoedown_buffer_new(link_end - link_offset);
+ hoedown_buffer_put(ref->link, data + link_offset, link_end - link_offset);
+
+ if (title_end > title_offset) {
+ ref->title = hoedown_buffer_new(title_end - title_offset);
+ hoedown_buffer_put(ref->title, data + title_offset, title_end - title_offset);
+ }
+ }
+
+ return 1;
}
static void expand_tabs(hoedown_buffer *ob, const uint8_t *line, size_t size)
{
- /* This code makes two assumptions:
- * - Input is valid UTF-8. (Any byte with top two bits 10 is skipped,
- * whether or not it is a valid UTF-8 continuation byte.)
- * - Input contains no combining characters. (Combining characters
- * should be skipped but are not.)
- */
- size_t i = 0, tab = 0;
+ /* This code makes two assumptions:
+ * - Input is valid UTF-8. (Any byte with top two bits 10 is skipped,
+ * whether or not it is a valid UTF-8 continuation byte.)
+ * - Input contains no combining characters. (Combining characters
+ * should be skipped but are not.)
+ */
+ size_t i = 0, tab = 0;
- while (i < size) {
- size_t org = i;
+ while (i < size) {
+ size_t org = i;
- while (i < size && line[i] != '\t') {
- /* ignore UTF-8 continuation bytes */
- if ((line[i] & 0xc0) != 0x80)
- tab++;
- i++;
- }
+ while (i < size && line[i] != '\t') {
+ /* ignore UTF-8 continuation bytes */
+ if ((line[i] & 0xc0) != 0x80)
+ tab++;
+ i++;
+ }
- if (i > org)
- hoedown_buffer_put(ob, line + org, i - org);
+ if (i > org)
+ hoedown_buffer_put(ob, line + org, i - org);
- if (i >= size)
- break;
+ if (i >= size)
+ break;
- do {
- hoedown_buffer_putc(ob, ' '); tab++;
- } while (tab % 4);
+ do {
+ hoedown_buffer_putc(ob, ' '); tab++;
+ } while (tab % 4);
- i++;
- }
+ i++;
+ }
}
/**********************
@@ -2734,225 +2734,225 @@ static void expand_tabs(hoedown_buffer *ob, const uint8_t *line, size_t size)
hoedown_document *
hoedown_document_new(
- const hoedown_renderer *renderer,
- hoedown_extensions extensions,
- size_t max_nesting)
+ const hoedown_renderer *renderer,
+ hoedown_extensions extensions,
+ size_t max_nesting)
{
- hoedown_document *doc = NULL;
+ hoedown_document *doc = NULL;
- assert(max_nesting > 0 && renderer);
+ assert(max_nesting > 0 && renderer);
- doc = hoedown_malloc(sizeof(hoedown_document));
- memcpy(&doc->md, renderer, sizeof(hoedown_renderer));
+ doc = hoedown_malloc(sizeof(hoedown_document));
+ memcpy(&doc->md, renderer, sizeof(hoedown_renderer));
- doc->data.opaque = renderer->opaque;
+ doc->data.opaque = renderer->opaque;
- hoedown_stack_init(&doc->work_bufs[BUFFER_BLOCK], 4);
- hoedown_stack_init(&doc->work_bufs[BUFFER_SPAN], 8);
+ hoedown_stack_init(&doc->work_bufs[BUFFER_BLOCK], 4);
+ hoedown_stack_init(&doc->work_bufs[BUFFER_SPAN], 8);
- memset(doc->active_char, 0x0, 256);
+ memset(doc->active_char, 0x0, 256);
- if (extensions & HOEDOWN_EXT_UNDERLINE && doc->md.underline) {
- doc->active_char['_'] = MD_CHAR_EMPHASIS;
- }
+ if (extensions & HOEDOWN_EXT_UNDERLINE && doc->md.underline) {
+ doc->active_char['_'] = MD_CHAR_EMPHASIS;
+ }
- if (doc->md.emphasis || doc->md.double_emphasis || doc->md.triple_emphasis) {
- doc->active_char['*'] = MD_CHAR_EMPHASIS;
- doc->active_char['_'] = MD_CHAR_EMPHASIS;
- if (extensions & HOEDOWN_EXT_STRIKETHROUGH)
- doc->active_char['~'] = MD_CHAR_EMPHASIS;
- if (extensions & HOEDOWN_EXT_HIGHLIGHT)
- doc->active_char['='] = MD_CHAR_EMPHASIS;
- }
+ if (doc->md.emphasis || doc->md.double_emphasis || doc->md.triple_emphasis) {
+ doc->active_char['*'] = MD_CHAR_EMPHASIS;
+ doc->active_char['_'] = MD_CHAR_EMPHASIS;
+ if (extensions & HOEDOWN_EXT_STRIKETHROUGH)
+ doc->active_char['~'] = MD_CHAR_EMPHASIS;
+ if (extensions & HOEDOWN_EXT_HIGHLIGHT)
+ doc->active_char['='] = MD_CHAR_EMPHASIS;
+ }
- if (doc->md.codespan)
- doc->active_char['`'] = MD_CHAR_CODESPAN;
+ if (doc->md.codespan)
+ doc->active_char['`'] = MD_CHAR_CODESPAN;
- if (doc->md.linebreak)
- doc->active_char['\n'] = MD_CHAR_LINEBREAK;
+ if (doc->md.linebreak)
+ doc->active_char['\n'] = MD_CHAR_LINEBREAK;
- if (doc->md.image || doc->md.link || doc->md.footnotes || doc->md.footnote_ref)
- doc->active_char['['] = MD_CHAR_LINK;
+ if (doc->md.image || doc->md.link || doc->md.footnotes || doc->md.footnote_ref)
+ doc->active_char['['] = MD_CHAR_LINK;
- doc->active_char['<'] = MD_CHAR_LANGLE;
- doc->active_char['\\'] = MD_CHAR_ESCAPE;
- doc->active_char['&'] = MD_CHAR_ENTITY;
+ doc->active_char['<'] = MD_CHAR_LANGLE;
+ doc->active_char['\\'] = MD_CHAR_ESCAPE;
+ doc->active_char['&'] = MD_CHAR_ENTITY;
- if (extensions & HOEDOWN_EXT_AUTOLINK) {
- doc->active_char[':'] = MD_CHAR_AUTOLINK_URL;
- doc->active_char['@'] = MD_CHAR_AUTOLINK_EMAIL;
- doc->active_char['w'] = MD_CHAR_AUTOLINK_WWW;
- }
+ if (extensions & HOEDOWN_EXT_AUTOLINK) {
+ doc->active_char[':'] = MD_CHAR_AUTOLINK_URL;
+ doc->active_char['@'] = MD_CHAR_AUTOLINK_EMAIL;
+ doc->active_char['w'] = MD_CHAR_AUTOLINK_WWW;
+ }
- if (extensions & HOEDOWN_EXT_SUPERSCRIPT)
- doc->active_char['^'] = MD_CHAR_SUPERSCRIPT;
+ if (extensions & HOEDOWN_EXT_SUPERSCRIPT)
+ doc->active_char['^'] = MD_CHAR_SUPERSCRIPT;
- if (extensions & HOEDOWN_EXT_QUOTE)
- doc->active_char['"'] = MD_CHAR_QUOTE;
+ if (extensions & HOEDOWN_EXT_QUOTE)
+ doc->active_char['"'] = MD_CHAR_QUOTE;
- if (extensions & HOEDOWN_EXT_MATH)
- doc->active_char['$'] = MD_CHAR_MATH;
+ if (extensions & HOEDOWN_EXT_MATH)
+ doc->active_char['$'] = MD_CHAR_MATH;
- /* Extension data */
- doc->ext_flags = extensions;
- doc->max_nesting = max_nesting;
- doc->in_link_body = 0;
+ /* Extension data */
+ doc->ext_flags = extensions;
+ doc->max_nesting = max_nesting;
+ doc->in_link_body = 0;
- return doc;
+ return doc;
}
void
hoedown_document_render(hoedown_document *doc, hoedown_buffer *ob, const uint8_t *data, size_t size)
{
- static const uint8_t UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
+ static const uint8_t UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
- hoedown_buffer *text;
- size_t beg, end;
+ hoedown_buffer *text;
+ size_t beg, end;
- int footnotes_enabled;
+ int footnotes_enabled;
- text = hoedown_buffer_new(64);
+ text = hoedown_buffer_new(64);
- /* Preallocate enough space for our buffer to avoid expanding while copying */
- hoedown_buffer_grow(text, size);
+ /* Preallocate enough space for our buffer to avoid expanding while copying */
+ hoedown_buffer_grow(text, size);
- /* reset the references table */
- memset(&doc->refs, 0x0, REF_TABLE_SIZE * sizeof(void *));
+ /* reset the references table */
+ memset(&doc->refs, 0x0, REF_TABLE_SIZE * sizeof(void *));
- footnotes_enabled = doc->ext_flags & HOEDOWN_EXT_FOOTNOTES;
+ footnotes_enabled = doc->ext_flags & HOEDOWN_EXT_FOOTNOTES;
- /* reset the footnotes lists */
- if (footnotes_enabled) {
- memset(&doc->footnotes_found, 0x0, sizeof(doc->footnotes_found));
- memset(&doc->footnotes_used, 0x0, sizeof(doc->footnotes_used));
- }
+ /* reset the footnotes lists */
+ if (footnotes_enabled) {
+ memset(&doc->footnotes_found, 0x0, sizeof(doc->footnotes_found));
+ memset(&doc->footnotes_used, 0x0, sizeof(doc->footnotes_used));
+ }
- /* first pass: looking for references, copying everything else */
- beg = 0;
+ /* first pass: looking for references, copying everything else */
+ beg = 0;
- /* Skip a possible UTF-8 BOM, even though the Unicode standard
- * discourages having these in UTF-8 documents */
- if (size >= 3 && memcmp(data, UTF8_BOM, 3) == 0)
- beg += 3;
+ /* Skip a possible UTF-8 BOM, even though the Unicode standard
+ * discourages having these in UTF-8 documents */
+ if (size >= 3 && memcmp(data, UTF8_BOM, 3) == 0)
+ beg += 3;
- while (beg < size) /* iterating over lines */
- if (footnotes_enabled && is_footnote(data, beg, size, &end, &doc->footnotes_found))
- beg = end;
- else if (is_ref(data, beg, size, &end, doc->refs))
- beg = end;
- else { /* skipping to the next line */
- end = beg;
- while (end < size && data[end] != '\n' && data[end] != '\r')
- end++;
+ while (beg < size) /* iterating over lines */
+ if (footnotes_enabled && is_footnote(data, beg, size, &end, &doc->footnotes_found))
+ beg = end;
+ else if (is_ref(data, beg, size, &end, doc->refs))
+ beg = end;
+ else { /* skipping to the next line */
+ end = beg;
+ while (end < size && data[end] != '\n' && data[end] != '\r')
+ end++;
- /* adding the line body if present */
- if (end > beg)
- expand_tabs(text, data + beg, end - beg);
+ /* adding the line body if present */
+ if (end > beg)
+ expand_tabs(text, data + beg, end - beg);
- while (end < size && (data[end] == '\n' || data[end] == '\r')) {
- /* add one \n per newline */
- if (data[end] == '\n' || (end + 1 < size && data[end + 1] != '\n'))
- hoedown_buffer_putc(text, '\n');
- end++;
- }
+ while (end < size && (data[end] == '\n' || data[end] == '\r')) {
+ /* add one \n per newline */
+ if (data[end] == '\n' || (end + 1 < size && data[end + 1] != '\n'))
+ hoedown_buffer_putc(text, '\n');
+ end++;
+ }
- beg = end;
- }
+ beg = end;
+ }
- /* pre-grow the output buffer to minimize allocations */
- hoedown_buffer_grow(ob, text->size + (text->size >> 1));
+ /* pre-grow the output buffer to minimize allocations */
+ hoedown_buffer_grow(ob, text->size + (text->size >> 1));
- /* second pass: actual rendering */
- if (doc->md.doc_header)
- doc->md.doc_header(ob, 0, &doc->data);
+ /* second pass: actual rendering */
+ if (doc->md.doc_header)
+ doc->md.doc_header(ob, 0, &doc->data);
- if (text->size) {
- /* adding a final newline if not already present */
- if (text->data[text->size - 1] != '\n' && text->data[text->size - 1] != '\r')
- hoedown_buffer_putc(text, '\n');
+ if (text->size) {
+ /* adding a final newline if not already present */
+ if (text->data[text->size - 1] != '\n' && text->data[text->size - 1] != '\r')
+ hoedown_buffer_putc(text, '\n');
- parse_block(ob, doc, text->data, text->size);
- }
+ parse_block(ob, doc, text->data, text->size);
+ }
- /* footnotes */
- if (footnotes_enabled)
- parse_footnote_list(ob, doc, &doc->footnotes_used);
+ /* footnotes */
+ if (footnotes_enabled)
+ parse_footnote_list(ob, doc, &doc->footnotes_used);
- if (doc->md.doc_footer)
- doc->md.doc_footer(ob, 0, &doc->data);
+ if (doc->md.doc_footer)
+ doc->md.doc_footer(ob, 0, &doc->data);
- /* clean-up */
- hoedown_buffer_free(text);
- free_link_refs(doc->refs);
- if (footnotes_enabled) {
- free_footnote_list(&doc->footnotes_found, 1);
- free_footnote_list(&doc->footnotes_used, 0);
- }
+ /* clean-up */
+ hoedown_buffer_free(text);
+ free_link_refs(doc->refs);
+ if (footnotes_enabled) {
+ free_footnote_list(&doc->footnotes_found, 1);
+ free_footnote_list(&doc->footnotes_used, 0);
+ }
- assert(doc->work_bufs[BUFFER_SPAN].size == 0);
- assert(doc->work_bufs[BUFFER_BLOCK].size == 0);
+ assert(doc->work_bufs[BUFFER_SPAN].size == 0);
+ assert(doc->work_bufs[BUFFER_BLOCK].size == 0);
}
void
hoedown_document_render_inline(hoedown_document *doc, hoedown_buffer *ob, const uint8_t *data, size_t size)
{
- size_t i = 0, mark;
- hoedown_buffer *text = hoedown_buffer_new(64);
+ size_t i = 0, mark;
+ hoedown_buffer *text = hoedown_buffer_new(64);
- /* reset the references table */
- memset(&doc->refs, 0x0, REF_TABLE_SIZE * sizeof(void *));
+ /* reset the references table */
+ memset(&doc->refs, 0x0, REF_TABLE_SIZE * sizeof(void *));
- /* first pass: expand tabs and process newlines */
- hoedown_buffer_grow(text, size);
- while (1) {
- mark = i;
- while (i < size && data[i] != '\n' && data[i] != '\r')
- i++;
+ /* first pass: expand tabs and process newlines */
+ hoedown_buffer_grow(text, size);
+ while (1) {
+ mark = i;
+ while (i < size && data[i] != '\n' && data[i] != '\r')
+ i++;
- expand_tabs(text, data + mark, i - mark);
+ expand_tabs(text, data + mark, i - mark);
- if (i >= size)
- break;
+ if (i >= size)
+ break;
- while (i < size && (data[i] == '\n' || data[i] == '\r')) {
- /* add one \n per newline */
- if (data[i] == '\n' || (i + 1 < size && data[i + 1] != '\n'))
- hoedown_buffer_putc(text, '\n');
- i++;
- }
- }
+ while (i < size && (data[i] == '\n' || data[i] == '\r')) {
+ /* add one \n per newline */
+ if (data[i] == '\n' || (i + 1 < size && data[i + 1] != '\n'))
+ hoedown_buffer_putc(text, '\n');
+ i++;
+ }
+ }
- /* second pass: actual rendering */
- hoedown_buffer_grow(ob, text->size + (text->size >> 1));
+ /* second pass: actual rendering */
+ hoedown_buffer_grow(ob, text->size + (text->size >> 1));
- if (doc->md.doc_header)
- doc->md.doc_header(ob, 1, &doc->data);
+ if (doc->md.doc_header)
+ doc->md.doc_header(ob, 1, &doc->data);
- parse_inline(ob, doc, text->data, text->size);
+ parse_inline(ob, doc, text->data, text->size);
- if (doc->md.doc_footer)
- doc->md.doc_footer(ob, 1, &doc->data);
+ if (doc->md.doc_footer)
+ doc->md.doc_footer(ob, 1, &doc->data);
- /* clean-up */
- hoedown_buffer_free(text);
+ /* clean-up */
+ hoedown_buffer_free(text);
- assert(doc->work_bufs[BUFFER_SPAN].size == 0);
- assert(doc->work_bufs[BUFFER_BLOCK].size == 0);
+ assert(doc->work_bufs[BUFFER_SPAN].size == 0);
+ assert(doc->work_bufs[BUFFER_BLOCK].size == 0);
}
void
hoedown_document_free(hoedown_document *doc)
{
- size_t i;
+ size_t i;
- for (i = 0; i < (size_t)doc->work_bufs[BUFFER_SPAN].asize; ++i)
- hoedown_buffer_free(doc->work_bufs[BUFFER_SPAN].item[i]);
+ for (i = 0; i < (size_t)doc->work_bufs[BUFFER_SPAN].asize; ++i)
+ hoedown_buffer_free(doc->work_bufs[BUFFER_SPAN].item[i]);
- for (i = 0; i < (size_t)doc->work_bufs[BUFFER_BLOCK].asize; ++i)
- hoedown_buffer_free(doc->work_bufs[BUFFER_BLOCK].item[i]);
+ for (i = 0; i < (size_t)doc->work_bufs[BUFFER_BLOCK].asize; ++i)
+ hoedown_buffer_free(doc->work_bufs[BUFFER_BLOCK].item[i]);
- hoedown_stack_uninit(&doc->work_bufs[BUFFER_SPAN]);
- hoedown_stack_uninit(&doc->work_bufs[BUFFER_BLOCK]);
+ hoedown_stack_uninit(&doc->work_bufs[BUFFER_SPAN]);
+ hoedown_stack_uninit(&doc->work_bufs[BUFFER_BLOCK]);
- free(doc);
+ free(doc);
}
diff --git a/libraries/hoedown/src/escape.c b/libraries/hoedown/src/escape.c
index b4a275ba..ce25dd54 100644
--- a/libraries/hoedown/src/escape.c
+++ b/libraries/hoedown/src/escape.c
@@ -12,13 +12,13 @@
/*
* The following characters will not be escaped:
*
- * -_.+!*'(),%#@?=;:/,+&$ alphanum
+ * -_.+!*'(),%#@?=;:/,+&$ alphanum
*
* Note that this character set is the addition of:
*
- * - The characters which are safe to be in an URL
- * - The characters which are *not* safe to be in
- * an URL because they are RESERVED characters.
+ * - The characters which are safe to be in an URL
+ * - The characters which are *not* safe to be in
+ * an URL because they are RESERVED characters.
*
* We assume (lazily) that any RESERVED char that
* appears inside an URL is actually meant to
@@ -35,84 +35,84 @@
*
*/
static const uint8_t HREF_SAFE[UINT8_MAX+1] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
void
hoedown_escape_href(hoedown_buffer *ob, const uint8_t *data, size_t size)
{
- static const char hex_chars[] = "0123456789ABCDEF";
- size_t i = 0, mark;
- char hex_str[3];
-
- hex_str[0] = '%';
-
- while (i < size) {
- mark = i;
- while (i < size && HREF_SAFE[data[i]]) i++;
-
- /* Optimization for cases where there's nothing to escape */
- if (mark == 0 && i >= size) {
- hoedown_buffer_put(ob, data, size);
- return;
- }
-
- if (likely(i > mark)) {
- hoedown_buffer_put(ob, data + mark, i - mark);
- }
-
- /* escaping */
- if (i >= size)
- break;
-
- switch (data[i]) {
- /* amp appears all the time in URLs, but needs
- * HTML-entity escaping to be inside an href */
- case '&':
- HOEDOWN_BUFPUTSL(ob, "&amp;");
- break;
-
- /* the single quote is a valid URL character
- * according to the standard; it needs HTML
- * entity escaping too */
- case '\'':
- HOEDOWN_BUFPUTSL(ob, "&#x27;");
- break;
-
- /* the space can be escaped to %20 or a plus
- * sign. we're going with the generic escape
- * for now. the plus thing is more commonly seen
- * when building GET strings */
+ static const char hex_chars[] = "0123456789ABCDEF";
+ size_t i = 0, mark;
+ char hex_str[3];
+
+ hex_str[0] = '%';
+
+ while (i < size) {
+ mark = i;
+ while (i < size && HREF_SAFE[data[i]]) i++;
+
+ /* Optimization for cases where there's nothing to escape */
+ if (mark == 0 && i >= size) {
+ hoedown_buffer_put(ob, data, size);
+ return;
+ }
+
+ if (likely(i > mark)) {
+ hoedown_buffer_put(ob, data + mark, i - mark);
+ }
+
+ /* escaping */
+ if (i >= size)
+ break;
+
+ switch (data[i]) {
+ /* amp appears all the time in URLs, but needs
+ * HTML-entity escaping to be inside an href */
+ case '&':
+ HOEDOWN_BUFPUTSL(ob, "&amp;");
+ break;
+
+ /* the single quote is a valid URL character
+ * according to the standard; it needs HTML
+ * entity escaping too */
+ case '\'':
+ HOEDOWN_BUFPUTSL(ob, "&#x27;");
+ break;
+
+ /* the space can be escaped to %20 or a plus
+ * sign. we're going with the generic escape
+ * for now. the plus thing is more commonly seen
+ * when building GET strings */
#if 0
- case ' ':
- hoedown_buffer_putc(ob, '+');
- break;
+ case ' ':
+ hoedown_buffer_putc(ob, '+');
+ break;
#endif
- /* every other character goes with a %XX escaping */
- default:
- hex_str[1] = hex_chars[(data[i] >> 4) & 0xF];
- hex_str[2] = hex_chars[data[i] & 0xF];
- hoedown_buffer_put(ob, (uint8_t *)hex_str, 3);
- }
+ /* every other character goes with a %XX escaping */
+ default:
+ hex_str[1] = hex_chars[(data[i] >> 4) & 0xF];
+ hex_str[2] = hex_chars[data[i] & 0xF];
+ hoedown_buffer_put(ob, (uint8_t *)hex_str, 3);
+ }
- i++;
- }
+ i++;
+ }
}
@@ -128,22 +128,22 @@ hoedown_escape_href(hoedown_buffer *ob, const uint8_t *data, size_t size)
*
*/
static const uint8_t HTML_ESCAPE_TABLE[UINT8_MAX+1] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static const char *HTML_ESCAPES[] = {
@@ -159,30 +159,30 @@ static const char *HTML_ESCAPES[] = {
void
hoedown_escape_html(hoedown_buffer *ob, const uint8_t *data, size_t size, int secure)
{
- size_t i = 0, mark;
+ size_t i = 0, mark;
- while (1) {
- mark = i;
- while (i < size && HTML_ESCAPE_TABLE[data[i]] == 0) i++;
+ while (1) {
+ mark = i;
+ while (i < size && HTML_ESCAPE_TABLE[data[i]] == 0) i++;
- /* Optimization for cases where there's nothing to escape */
- if (mark == 0 && i >= size) {
- hoedown_buffer_put(ob, data, size);
- return;
- }
+ /* Optimization for cases where there's nothing to escape */
+ if (mark == 0 && i >= size) {
+ hoedown_buffer_put(ob, data, size);
+ return;
+ }
- if (likely(i > mark))
- hoedown_buffer_put(ob, data + mark, i - mark);
+ if (likely(i > mark))
+ hoedown_buffer_put(ob, data + mark, i - mark);
- if (i >= size) break;
+ if (i >= size) break;
- /* The forward slash is only escaped in secure mode */
- if (!secure && data[i] == '/') {
- hoedown_buffer_putc(ob, '/');
- } else {
- hoedown_buffer_puts(ob, HTML_ESCAPES[HTML_ESCAPE_TABLE[data[i]]]);
- }
+ /* The forward slash is only escaped in secure mode */
+ if (!secure && data[i] == '/') {
+ hoedown_buffer_putc(ob, '/');
+ } else {
+ hoedown_buffer_puts(ob, HTML_ESCAPES[HTML_ESCAPE_TABLE[data[i]]]);
+ }
- i++;
- }
+ i++;
+ }
}
diff --git a/libraries/hoedown/src/html.c b/libraries/hoedown/src/html.c
index 4b18d804..8bf3358e 100644
--- a/libraries/hoedown/src/html.c
+++ b/libraries/hoedown/src/html.c
@@ -12,44 +12,44 @@
hoedown_html_tag
hoedown_html_is_tag(const uint8_t *data, size_t size, const char *tagname)
{
- size_t i;
- int closed = 0;
+ size_t i;
+ int closed = 0;
- if (size < 3 || data[0] != '<')
- return HOEDOWN_HTML_TAG_NONE;
+ if (size < 3 || data[0] != '<')
+ return HOEDOWN_HTML_TAG_NONE;
- i = 1;
+ i = 1;
- if (data[i] == '/') {
- closed = 1;
- i++;
- }
+ if (data[i] == '/') {
+ closed = 1;
+ i++;
+ }
- for (; i < size; ++i, ++tagname) {
- if (*tagname == 0)
- break;
+ for (; i < size; ++i, ++tagname) {
+ if (*tagname == 0)
+ break;
- if (data[i] != *tagname)
- return HOEDOWN_HTML_TAG_NONE;
- }
+ if (data[i] != *tagname)
+ return HOEDOWN_HTML_TAG_NONE;
+ }
- if (i == size)
- return HOEDOWN_HTML_TAG_NONE;
+ if (i == size)
+ return HOEDOWN_HTML_TAG_NONE;
- if (isspace(data[i]) || data[i] == '>')
- return closed ? HOEDOWN_HTML_TAG_CLOSE : HOEDOWN_HTML_TAG_OPEN;
+ if (isspace(data[i]) || data[i] == '>')
+ return closed ? HOEDOWN_HTML_TAG_CLOSE : HOEDOWN_HTML_TAG_OPEN;
- return HOEDOWN_HTML_TAG_NONE;
+ return HOEDOWN_HTML_TAG_NONE;
}
static void escape_html(hoedown_buffer *ob, const uint8_t *source, size_t length)
{
- hoedown_escape_html(ob, source, length, 0);
+ hoedown_escape_html(ob, source, length, 0);
}
static void escape_href(hoedown_buffer *ob, const uint8_t *source, size_t length)
{
- hoedown_escape_href(ob, source, length);
+ hoedown_escape_href(ob, source, length);
}
/********************
@@ -58,353 +58,353 @@ static void escape_href(hoedown_buffer *ob, const uint8_t *source, size_t length
static int
rndr_autolink(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
+ hoedown_html_renderer_state *state = data->opaque;
- if (!link || !link->size)
- return 0;
+ if (!link || !link->size)
+ return 0;
- HOEDOWN_BUFPUTSL(ob, "<a href=\"");
- if (type == HOEDOWN_AUTOLINK_EMAIL)
- HOEDOWN_BUFPUTSL(ob, "mailto:");
- escape_href(ob, link->data, link->size);
+ HOEDOWN_BUFPUTSL(ob, "<a href=\"");
+ if (type == HOEDOWN_AUTOLINK_EMAIL)
+ HOEDOWN_BUFPUTSL(ob, "mailto:");
+ escape_href(ob, link->data, link->size);
- if (state->link_attributes) {
- hoedown_buffer_putc(ob, '\"');
- state->link_attributes(ob, link, data);
- hoedown_buffer_putc(ob, '>');
- } else {
- HOEDOWN_BUFPUTSL(ob, "\">");
- }
+ if (state->link_attributes) {
+ hoedown_buffer_putc(ob, '\"');
+ state->link_attributes(ob, link, data);
+ hoedown_buffer_putc(ob, '>');
+ } else {
+ HOEDOWN_BUFPUTSL(ob, "\">");
+ }
- /*
- * Pretty printing: if we get an email address as
- * an actual URI, e.g. `mailto:foo@bar.com`, we don't
- * want to print the `mailto:` prefix
- */
- if (hoedown_buffer_prefix(link, "mailto:") == 0) {
- escape_html(ob, link->data + 7, link->size - 7);
- } else {
- escape_html(ob, link->data, link->size);
- }
+ /*
+ * Pretty printing: if we get an email address as
+ * an actual URI, e.g. `mailto:foo@bar.com`, we don't
+ * want to print the `mailto:` prefix
+ */
+ if (hoedown_buffer_prefix(link, "mailto:") == 0) {
+ escape_html(ob, link->data + 7, link->size - 7);
+ } else {
+ escape_html(ob, link->data, link->size);
+ }
- HOEDOWN_BUFPUTSL(ob, "</a>");
+ HOEDOWN_BUFPUTSL(ob, "</a>");
- return 1;
+ return 1;
}
static void
rndr_blockcode(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, const hoedown_renderer_data *data)
{
- if (ob->size) hoedown_buffer_putc(ob, '\n');
+ if (ob->size) hoedown_buffer_putc(ob, '\n');
- if (lang) {
- HOEDOWN_BUFPUTSL(ob, "<pre><code class=\"language-");
- escape_html(ob, lang->data, lang->size);
- HOEDOWN_BUFPUTSL(ob, "\">");
- } else {
- HOEDOWN_BUFPUTSL(ob, "<pre><code>");
- }
+ if (lang) {
+ HOEDOWN_BUFPUTSL(ob, "<pre><code class=\"language-");
+ escape_html(ob, lang->data, lang->size);
+ HOEDOWN_BUFPUTSL(ob, "\">");
+ } else {
+ HOEDOWN_BUFPUTSL(ob, "<pre><code>");
+ }
- if (text)
- escape_html(ob, text->data, text->size);
+ if (text)
+ escape_html(ob, text->data, text->size);
- HOEDOWN_BUFPUTSL(ob, "</code></pre>\n");
+ HOEDOWN_BUFPUTSL(ob, "</code></pre>\n");
}
static void
rndr_blockquote(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (ob->size) hoedown_buffer_putc(ob, '\n');
- HOEDOWN_BUFPUTSL(ob, "<blockquote>\n");
- if (content) hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</blockquote>\n");
+ if (ob->size) hoedown_buffer_putc(ob, '\n');
+ HOEDOWN_BUFPUTSL(ob, "<blockquote>\n");
+ if (content) hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</blockquote>\n");
}
static int
rndr_codespan(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)
{
- HOEDOWN_BUFPUTSL(ob, "<code>");
- if (text) escape_html(ob, text->data, text->size);
- HOEDOWN_BUFPUTSL(ob, "</code>");
- return 1;
+ HOEDOWN_BUFPUTSL(ob, "<code>");
+ if (text) escape_html(ob, text->data, text->size);
+ HOEDOWN_BUFPUTSL(ob, "</code>");
+ return 1;
}
static int
rndr_strikethrough(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (!content || !content->size)
- return 0;
+ if (!content || !content->size)
+ return 0;
- HOEDOWN_BUFPUTSL(ob, "<del>");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</del>");
- return 1;
+ HOEDOWN_BUFPUTSL(ob, "<del>");
+ hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</del>");
+ return 1;
}
static int
rndr_double_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (!content || !content->size)
- return 0;
+ if (!content || !content->size)
+ return 0;
- HOEDOWN_BUFPUTSL(ob, "<strong>");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</strong>");
+ HOEDOWN_BUFPUTSL(ob, "<strong>");
+ hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</strong>");
- return 1;
+ return 1;
}
static int
rndr_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (!content || !content->size) return 0;
- HOEDOWN_BUFPUTSL(ob, "<em>");
- if (content) hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</em>");
- return 1;
+ if (!content || !content->size) return 0;
+ HOEDOWN_BUFPUTSL(ob, "<em>");
+ if (content) hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</em>");
+ return 1;
}
static int
rndr_underline(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (!content || !content->size)
- return 0;
+ if (!content || !content->size)
+ return 0;
- HOEDOWN_BUFPUTSL(ob, "<u>");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</u>");
+ HOEDOWN_BUFPUTSL(ob, "<u>");
+ hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</u>");
- return 1;
+ return 1;
}
static int
rndr_highlight(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (!content || !content->size)
- return 0;
+ if (!content || !content->size)
+ return 0;
- HOEDOWN_BUFPUTSL(ob, "<mark>");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</mark>");
+ HOEDOWN_BUFPUTSL(ob, "<mark>");
+ hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</mark>");
- return 1;
+ return 1;
}
static int
rndr_quote(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (!content || !content->size)
- return 0;
+ if (!content || !content->size)
+ return 0;
- HOEDOWN_BUFPUTSL(ob, "<q>");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</q>");
+ HOEDOWN_BUFPUTSL(ob, "<q>");
+ hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</q>");
- return 1;
+ return 1;
}
static int
rndr_linebreak(hoedown_buffer *ob, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
- hoedown_buffer_puts(ob, USE_XHTML(state) ? "<br/>\n" : "<br>\n");
- return 1;
+ hoedown_html_renderer_state *state = data->opaque;
+ hoedown_buffer_puts(ob, USE_XHTML(state) ? "<br/>\n" : "<br>\n");
+ return 1;
}
static void
rndr_header(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
+ hoedown_html_renderer_state *state = data->opaque;
- if (ob->size)
- hoedown_buffer_putc(ob, '\n');
+ if (ob->size)
+ hoedown_buffer_putc(ob, '\n');
- if (level <= state->toc_data.nesting_level)
- hoedown_buffer_printf(ob, "<h%d id=\"toc_%d\">", level, state->toc_data.header_count++);
- else
- hoedown_buffer_printf(ob, "<h%d>", level);
+ if (level <= state->toc_data.nesting_level)
+ hoedown_buffer_printf(ob, "<h%d id=\"toc_%d\">", level, state->toc_data.header_count++);
+ else
+ hoedown_buffer_printf(ob, "<h%d>", level);
- if (content) hoedown_buffer_put(ob, content->data, content->size);
- hoedown_buffer_printf(ob, "</h%d>\n", level);
+ if (content) hoedown_buffer_put(ob, content->data, content->size);
+ hoedown_buffer_printf(ob, "</h%d>\n", level);
}
static int
rndr_link(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
+ hoedown_html_renderer_state *state = data->opaque;
- HOEDOWN_BUFPUTSL(ob, "<a href=\"");
+ HOEDOWN_BUFPUTSL(ob, "<a href=\"");
- if (link && link->size)
- escape_href(ob, link->data, link->size);
+ if (link && link->size)
+ escape_href(ob, link->data, link->size);
- if (title && title->size) {
- HOEDOWN_BUFPUTSL(ob, "\" title=\"");
- escape_html(ob, title->data, title->size);
- }
+ if (title && title->size) {
+ HOEDOWN_BUFPUTSL(ob, "\" title=\"");
+ escape_html(ob, title->data, title->size);
+ }
- if (state->link_attributes) {
- hoedown_buffer_putc(ob, '\"');
- state->link_attributes(ob, link, data);
- hoedown_buffer_putc(ob, '>');
- } else {
- HOEDOWN_BUFPUTSL(ob, "\">");
- }
+ if (state->link_attributes) {
+ hoedown_buffer_putc(ob, '\"');
+ state->link_attributes(ob, link, data);
+ hoedown_buffer_putc(ob, '>');
+ } else {
+ HOEDOWN_BUFPUTSL(ob, "\">");
+ }
- if (content && content->size) hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</a>");
- return 1;
+ if (content && content->size) hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</a>");
+ return 1;
}
static void
rndr_list(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data)
{
- if (ob->size) hoedown_buffer_putc(ob, '\n');
- hoedown_buffer_put(ob, (const uint8_t *)(flags & HOEDOWN_LIST_ORDERED ? "<ol>\n" : "<ul>\n"), 5);
- if (content) hoedown_buffer_put(ob, content->data, content->size);
- hoedown_buffer_put(ob, (const uint8_t *)(flags & HOEDOWN_LIST_ORDERED ? "</ol>\n" : "</ul>\n"), 6);
+ if (ob->size) hoedown_buffer_putc(ob, '\n');
+ hoedown_buffer_put(ob, (const uint8_t *)(flags & HOEDOWN_LIST_ORDERED ? "<ol>\n" : "<ul>\n"), 5);
+ if (content) hoedown_buffer_put(ob, content->data, content->size);
+ hoedown_buffer_put(ob, (const uint8_t *)(flags & HOEDOWN_LIST_ORDERED ? "</ol>\n" : "</ul>\n"), 6);
}
static void
rndr_listitem(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data)
{
- HOEDOWN_BUFPUTSL(ob, "<li>");
- if (content) {
- size_t size = content->size;
- while (size && content->data[size - 1] == '\n')
- size--;
+ HOEDOWN_BUFPUTSL(ob, "<li>");
+ if (content) {
+ size_t size = content->size;
+ while (size && content->data[size - 1] == '\n')
+ size--;
- hoedown_buffer_put(ob, content->data, size);
- }
- HOEDOWN_BUFPUTSL(ob, "</li>\n");
+ hoedown_buffer_put(ob, content->data, size);
+ }
+ HOEDOWN_BUFPUTSL(ob, "</li>\n");
}
static void
rndr_paragraph(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
- size_t i = 0;
+ hoedown_html_renderer_state *state = data->opaque;
+ size_t i = 0;
- if (ob->size) hoedown_buffer_putc(ob, '\n');
+ if (ob->size) hoedown_buffer_putc(ob, '\n');
- if (!content || !content->size)
- return;
+ if (!content || !content->size)
+ return;
- while (i < content->size && isspace(content->data[i])) i++;
+ while (i < content->size && isspace(content->data[i])) i++;
- if (i == content->size)
- return;
+ if (i == content->size)
+ return;
- HOEDOWN_BUFPUTSL(ob, "<p>");
- if (state->flags & HOEDOWN_HTML_HARD_WRAP) {
- size_t org;
- while (i < content->size) {
- org = i;
- while (i < content->size && content->data[i] != '\n')
- i++;
+ HOEDOWN_BUFPUTSL(ob, "<p>");
+ if (state->flags & HOEDOWN_HTML_HARD_WRAP) {
+ size_t org;
+ while (i < content->size) {
+ org = i;
+ while (i < content->size && content->data[i] != '\n')
+ i++;
- if (i > org)
- hoedown_buffer_put(ob, content->data + org, i - org);
+ if (i > org)
+ hoedown_buffer_put(ob, content->data + org, i - org);
- /*
- * do not insert a line break if this newline
- * is the last character on the paragraph
- */
- if (i >= content->size - 1)
- break;
+ /*
+ * do not insert a line break if this newline
+ * is the last character on the paragraph
+ */
+ if (i >= content->size - 1)
+ break;
- rndr_linebreak(ob, data);
- i++;
- }
- } else {
- hoedown_buffer_put(ob, content->data + i, content->size - i);
- }
- HOEDOWN_BUFPUTSL(ob, "</p>\n");
+ rndr_linebreak(ob, data);
+ i++;
+ }
+ } else {
+ hoedown_buffer_put(ob, content->data + i, content->size - i);
+ }
+ HOEDOWN_BUFPUTSL(ob, "</p>\n");
}
static void
rndr_raw_block(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)
{
- size_t org, sz;
+ size_t org, sz;
- if (!text)
- return;
+ if (!text)
+ return;
- /* FIXME: Do we *really* need to trim the HTML? How does that make a difference? */
- sz = text->size;
- while (sz > 0 && text->data[sz - 1] == '\n')
- sz--;
+ /* FIXME: Do we *really* need to trim the HTML? How does that make a difference? */
+ sz = text->size;
+ while (sz > 0 && text->data[sz - 1] == '\n')
+ sz--;
- org = 0;
- while (org < sz && text->data[org] == '\n')
- org++;
+ org = 0;
+ while (org < sz && text->data[org] == '\n')
+ org++;
- if (org >= sz)
- return;
+ if (org >= sz)
+ return;
- if (ob->size)
- hoedown_buffer_putc(ob, '\n');
+ if (ob->size)
+ hoedown_buffer_putc(ob, '\n');
- hoedown_buffer_put(ob, text->data + org, sz - org);
- hoedown_buffer_putc(ob, '\n');
+ hoedown_buffer_put(ob, text->data + org, sz - org);
+ hoedown_buffer_putc(ob, '\n');
}
static int
rndr_triple_emphasis(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (!content || !content->size) return 0;
- HOEDOWN_BUFPUTSL(ob, "<strong><em>");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</em></strong>");
- return 1;
+ if (!content || !content->size) return 0;
+ HOEDOWN_BUFPUTSL(ob, "<strong><em>");
+ hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</em></strong>");
+ return 1;
}
static void
rndr_hrule(hoedown_buffer *ob, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
- if (ob->size) hoedown_buffer_putc(ob, '\n');
- hoedown_buffer_puts(ob, USE_XHTML(state) ? "<hr/>\n" : "<hr>\n");
+ hoedown_html_renderer_state *state = data->opaque;
+ if (ob->size) hoedown_buffer_putc(ob, '\n');
+ hoedown_buffer_puts(ob, USE_XHTML(state) ? "<hr/>\n" : "<hr>\n");
}
static int
rndr_image(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
- if (!link || !link->size) return 0;
+ hoedown_html_renderer_state *state = data->opaque;
+ if (!link || !link->size) return 0;
- HOEDOWN_BUFPUTSL(ob, "<img src=\"");
- escape_href(ob, link->data, link->size);
- HOEDOWN_BUFPUTSL(ob, "\" alt=\"");
+ HOEDOWN_BUFPUTSL(ob, "<img src=\"");
+ escape_href(ob, link->data, link->size);
+ HOEDOWN_BUFPUTSL(ob, "\" alt=\"");
- if (alt && alt->size)
- escape_html(ob, alt->data, alt->size);
+ if (alt && alt->size)
+ escape_html(ob, alt->data, alt->size);
- if (title && title->size) {
- HOEDOWN_BUFPUTSL(ob, "\" title=\"");
- escape_html(ob, title->data, title->size); }
+ if (title && title->size) {
+ HOEDOWN_BUFPUTSL(ob, "\" title=\"");
+ escape_html(ob, title->data, title->size); }
- hoedown_buffer_puts(ob, USE_XHTML(state) ? "\"/>" : "\">");
- return 1;
+ hoedown_buffer_puts(ob, USE_XHTML(state) ? "\"/>" : "\">");
+ return 1;
}
static int
rndr_raw_html(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
+ hoedown_html_renderer_state *state = data->opaque;
- /* ESCAPE overrides SKIP_HTML. It doesn't look to see if
- * there are any valid tags, just escapes all of them. */
- if((state->flags & HOEDOWN_HTML_ESCAPE) != 0) {
- escape_html(ob, text->data, text->size);
- return 1;
- }
+ /* ESCAPE overrides SKIP_HTML. It doesn't look to see if
+ * there are any valid tags, just escapes all of them. */
+ if((state->flags & HOEDOWN_HTML_ESCAPE) != 0) {
+ escape_html(ob, text->data, text->size);
+ return 1;
+ }
- if ((state->flags & HOEDOWN_HTML_SKIP_HTML) != 0)
- return 1;
+ if ((state->flags & HOEDOWN_HTML_SKIP_HTML) != 0)
+ return 1;
- hoedown_buffer_put(ob, text->data, text->size);
- return 1;
+ hoedown_buffer_put(ob, text->data, text->size);
+ return 1;
}
static void
@@ -437,318 +437,318 @@ rndr_table_body(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown
static void
rndr_tablerow(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- HOEDOWN_BUFPUTSL(ob, "<tr>\n");
- if (content) hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</tr>\n");
+ HOEDOWN_BUFPUTSL(ob, "<tr>\n");
+ if (content) hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</tr>\n");
}
static void
rndr_tablecell(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_table_flags flags, const hoedown_renderer_data *data)
{
- if (flags & HOEDOWN_TABLE_HEADER) {
- HOEDOWN_BUFPUTSL(ob, "<th");
- } else {
- HOEDOWN_BUFPUTSL(ob, "<td");
- }
+ if (flags & HOEDOWN_TABLE_HEADER) {
+ HOEDOWN_BUFPUTSL(ob, "<th");
+ } else {
+ HOEDOWN_BUFPUTSL(ob, "<td");
+ }
- switch (flags & HOEDOWN_TABLE_ALIGNMASK) {
- case HOEDOWN_TABLE_ALIGN_CENTER:
- HOEDOWN_BUFPUTSL(ob, " style=\"text-align: center\">");
- break;
+ switch (flags & HOEDOWN_TABLE_ALIGNMASK) {
+ case HOEDOWN_TABLE_ALIGN_CENTER:
+ HOEDOWN_BUFPUTSL(ob, " style=\"text-align: center\">");
+ break;
- case HOEDOWN_TABLE_ALIGN_LEFT:
- HOEDOWN_BUFPUTSL(ob, " style=\"text-align: left\">");
- break;
+ case HOEDOWN_TABLE_ALIGN_LEFT:
+ HOEDOWN_BUFPUTSL(ob, " style=\"text-align: left\">");
+ break;
- case HOEDOWN_TABLE_ALIGN_RIGHT:
- HOEDOWN_BUFPUTSL(ob, " style=\"text-align: right\">");
- break;
+ case HOEDOWN_TABLE_ALIGN_RIGHT:
+ HOEDOWN_BUFPUTSL(ob, " style=\"text-align: right\">");
+ break;
- default:
- HOEDOWN_BUFPUTSL(ob, ">");
- }
+ default:
+ HOEDOWN_BUFPUTSL(ob, ">");
+ }
- if (content)
- hoedown_buffer_put(ob, content->data, content->size);
+ if (content)
+ hoedown_buffer_put(ob, content->data, content->size);
- if (flags & HOEDOWN_TABLE_HEADER) {
- HOEDOWN_BUFPUTSL(ob, "</th>\n");
- } else {
- HOEDOWN_BUFPUTSL(ob, "</td>\n");
- }
+ if (flags & HOEDOWN_TABLE_HEADER) {
+ HOEDOWN_BUFPUTSL(ob, "</th>\n");
+ } else {
+ HOEDOWN_BUFPUTSL(ob, "</td>\n");
+ }
}
static int
rndr_superscript(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (!content || !content->size) return 0;
- HOEDOWN_BUFPUTSL(ob, "<sup>");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</sup>");
- return 1;
+ if (!content || !content->size) return 0;
+ HOEDOWN_BUFPUTSL(ob, "<sup>");
+ hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</sup>");
+ return 1;
}
static void
rndr_normal_text(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- if (content)
- escape_html(ob, content->data, content->size);
+ if (content)
+ escape_html(ob, content->data, content->size);
}
static void
rndr_footnotes(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
+ hoedown_html_renderer_state *state = data->opaque;
- if (ob->size) hoedown_buffer_putc(ob, '\n');
- HOEDOWN_BUFPUTSL(ob, "<div class=\"footnotes\">\n");
- hoedown_buffer_puts(ob, USE_XHTML(state) ? "<hr/>\n" : "<hr>\n");
- HOEDOWN_BUFPUTSL(ob, "<ol>\n");
+ if (ob->size) hoedown_buffer_putc(ob, '\n');
+ HOEDOWN_BUFPUTSL(ob, "<div class=\"footnotes\">\n");
+ hoedown_buffer_puts(ob, USE_XHTML(state) ? "<hr/>\n" : "<hr>\n");
+ HOEDOWN_BUFPUTSL(ob, "<ol>\n");
- if (content) hoedown_buffer_put(ob, content->data, content->size);
+ if (content) hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "\n</ol>\n</div>\n");
+ HOEDOWN_BUFPUTSL(ob, "\n</ol>\n</div>\n");
}
static void
rndr_footnote_def(hoedown_buffer *ob, const hoedown_buffer *content, unsigned int num, const hoedown_renderer_data *data)
{
- size_t i = 0;
- int pfound = 0;
-
- /* insert anchor at the end of first paragraph block */
- if (content) {
- while ((i+3) < content->size) {
- if (content->data[i++] != '<') continue;
- if (content->data[i++] != '/') continue;
- if (content->data[i++] != 'p' && content->data[i] != 'P') continue;
- if (content->data[i] != '>') continue;
- i -= 3;
- pfound = 1;
- break;
- }
- }
-
- hoedown_buffer_printf(ob, "\n<li id=\"fn%d\">\n", num);
- if (pfound) {
- hoedown_buffer_put(ob, content->data, i);
- hoedown_buffer_printf(ob, "&nbsp;<a href=\"#fnref%d\" rev=\"footnote\">&#8617;</a>", num);
- hoedown_buffer_put(ob, content->data + i, content->size - i);
- } else if (content) {
- hoedown_buffer_put(ob, content->data, content->size);
- }
- HOEDOWN_BUFPUTSL(ob, "</li>\n");
+ size_t i = 0;
+ int pfound = 0;
+
+ /* insert anchor at the end of first paragraph block */
+ if (content) {
+ while ((i+3) < content->size) {
+ if (content->data[i++] != '<') continue;
+ if (content->data[i++] != '/') continue;
+ if (content->data[i++] != 'p' && content->data[i] != 'P') continue;
+ if (content->data[i] != '>') continue;
+ i -= 3;
+ pfound = 1;
+ break;
+ }
+ }
+
+ hoedown_buffer_printf(ob, "\n<li id=\"fn%d\">\n", num);
+ if (pfound) {
+ hoedown_buffer_put(ob, content->data, i);
+ hoedown_buffer_printf(ob, "&nbsp;<a href=\"#fnref%d\" rev=\"footnote\">&#8617;</a>", num);
+ hoedown_buffer_put(ob, content->data + i, content->size - i);
+ } else if (content) {
+ hoedown_buffer_put(ob, content->data, content->size);
+ }
+ HOEDOWN_BUFPUTSL(ob, "</li>\n");
}
static int
rndr_footnote_ref(hoedown_buffer *ob, unsigned int num, const hoedown_renderer_data *data)
{
- hoedown_buffer_printf(ob, "<sup id=\"fnref%d\"><a href=\"#fn%d\" rel=\"footnote\">%d</a></sup>", num, num, num);
- return 1;
+ hoedown_buffer_printf(ob, "<sup id=\"fnref%d\"><a href=\"#fn%d\" rel=\"footnote\">%d</a></sup>", num, num, num);
+ return 1;
}
static int
rndr_math(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, const hoedown_renderer_data *data)
{
- hoedown_buffer_put(ob, (const uint8_t *)(displaymode ? "\\[" : "\\("), 2);
- escape_html(ob, text->data, text->size);
- hoedown_buffer_put(ob, (const uint8_t *)(displaymode ? "\\]" : "\\)"), 2);
- return 1;
+ hoedown_buffer_put(ob, (const uint8_t *)(displaymode ? "\\[" : "\\("), 2);
+ escape_html(ob, text->data, text->size);
+ hoedown_buffer_put(ob, (const uint8_t *)(displaymode ? "\\]" : "\\)"), 2);
+ return 1;
}
static void
toc_header(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state = data->opaque;
-
- if (level <= state->toc_data.nesting_level) {
- /* set the level offset if this is the first header
- * we're parsing for the document */
- if (state->toc_data.current_level == 0)
- state->toc_data.level_offset = level - 1;
-
- level -= state->toc_data.level_offset;
-
- if (level > state->toc_data.current_level) {
- while (level > state->toc_data.current_level) {
- HOEDOWN_BUFPUTSL(ob, "<ul>\n<li>\n");
- state->toc_data.current_level++;
- }
- } else if (level < state->toc_data.current_level) {
- HOEDOWN_BUFPUTSL(ob, "</li>\n");
- while (level < state->toc_data.current_level) {
- HOEDOWN_BUFPUTSL(ob, "</ul>\n</li>\n");
- state->toc_data.current_level--;
- }
- HOEDOWN_BUFPUTSL(ob,"<li>\n");
- } else {
- HOEDOWN_BUFPUTSL(ob,"</li>\n<li>\n");
- }
-
- hoedown_buffer_printf(ob, "<a href=\"#toc_%d\">", state->toc_data.header_count++);
- if (content) hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "</a>\n");
- }
+ hoedown_html_renderer_state *state = data->opaque;
+
+ if (level <= state->toc_data.nesting_level) {
+ /* set the level offset if this is the first header
+ * we're parsing for the document */
+ if (state->toc_data.current_level == 0)
+ state->toc_data.level_offset = level - 1;
+
+ level -= state->toc_data.level_offset;
+
+ if (level > state->toc_data.current_level) {
+ while (level > state->toc_data.current_level) {
+ HOEDOWN_BUFPUTSL(ob, "<ul>\n<li>\n");
+ state->toc_data.current_level++;
+ }
+ } else if (level < state->toc_data.current_level) {
+ HOEDOWN_BUFPUTSL(ob, "</li>\n");
+ while (level < state->toc_data.current_level) {
+ HOEDOWN_BUFPUTSL(ob, "</ul>\n</li>\n");
+ state->toc_data.current_level--;
+ }
+ HOEDOWN_BUFPUTSL(ob,"<li>\n");
+ } else {
+ HOEDOWN_BUFPUTSL(ob,"</li>\n<li>\n");
+ }
+
+ hoedown_buffer_printf(ob, "<a href=\"#toc_%d\">", state->toc_data.header_count++);
+ if (content) hoedown_buffer_put(ob, content->data, content->size);
+ HOEDOWN_BUFPUTSL(ob, "</a>\n");
+ }
}
static int
toc_link(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data)
{
- if (content && content->size) hoedown_buffer_put(ob, content->data, content->size);
- return 1;
+ if (content && content->size) hoedown_buffer_put(ob, content->data, content->size);
+ return 1;
}
static void
toc_finalize(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data)
{
- hoedown_html_renderer_state *state;
+ hoedown_html_renderer_state *state;
- if (inline_render)
- return;
+ if (inline_render)
+ return;
- state = data->opaque;
+ state = data->opaque;
- while (state->toc_data.current_level > 0) {
- HOEDOWN_BUFPUTSL(ob, "</li>\n</ul>\n");
- state->toc_data.current_level--;
- }
+ while (state->toc_data.current_level > 0) {
+ HOEDOWN_BUFPUTSL(ob, "</li>\n</ul>\n");
+ state->toc_data.current_level--;
+ }
- state->toc_data.header_count = 0;
+ state->toc_data.header_count = 0;
}
hoedown_renderer *
hoedown_html_toc_renderer_new(int nesting_level)
{
- static const hoedown_renderer cb_default = {
- NULL,
-
- NULL,
- NULL,
- toc_header,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
-
- NULL,
- rndr_codespan,
- rndr_double_emphasis,
- rndr_emphasis,
- rndr_underline,
- rndr_highlight,
- rndr_quote,
- NULL,
- NULL,
- toc_link,
- rndr_triple_emphasis,
- rndr_strikethrough,
- rndr_superscript,
- NULL,
- NULL,
- NULL,
-
- NULL,
- rndr_normal_text,
-
- NULL,
- toc_finalize
- };
-
- hoedown_html_renderer_state *state;
- hoedown_renderer *renderer;
-
- /* Prepare the state pointer */
- state = hoedown_malloc(sizeof(hoedown_html_renderer_state));
- memset(state, 0x0, sizeof(hoedown_html_renderer_state));
-
- state->toc_data.nesting_level = nesting_level;
-
- /* Prepare the renderer */
- renderer = hoedown_malloc(sizeof(hoedown_renderer));
- memcpy(renderer, &cb_default, sizeof(hoedown_renderer));
-
- renderer->opaque = state;
- return renderer;
+ static const hoedown_renderer cb_default = {
+ NULL,
+
+ NULL,
+ NULL,
+ toc_header,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ NULL,
+ rndr_codespan,
+ rndr_double_emphasis,
+ rndr_emphasis,
+ rndr_underline,
+ rndr_highlight,
+ rndr_quote,
+ NULL,
+ NULL,
+ toc_link,
+ rndr_triple_emphasis,
+ rndr_strikethrough,
+ rndr_superscript,
+ NULL,
+ NULL,
+ NULL,
+
+ NULL,
+ rndr_normal_text,
+
+ NULL,
+ toc_finalize
+ };
+
+ hoedown_html_renderer_state *state;
+ hoedown_renderer *renderer;
+
+ /* Prepare the state pointer */
+ state = hoedown_malloc(sizeof(hoedown_html_renderer_state));
+ memset(state, 0x0, sizeof(hoedown_html_renderer_state));
+
+ state->toc_data.nesting_level = nesting_level;
+
+ /* Prepare the renderer */
+ renderer = hoedown_malloc(sizeof(hoedown_renderer));
+ memcpy(renderer, &cb_default, sizeof(hoedown_renderer));
+
+ renderer->opaque = state;
+ return renderer;
}
hoedown_renderer *
hoedown_html_renderer_new(hoedown_html_flags render_flags, int nesting_level)
{
- static const hoedown_renderer cb_default = {
- NULL,
-
- rndr_blockcode,
- rndr_blockquote,
- rndr_header,
- rndr_hrule,
- rndr_list,
- rndr_listitem,
- rndr_paragraph,
- rndr_table,
- rndr_table_header,
- rndr_table_body,
- rndr_tablerow,
- rndr_tablecell,
- rndr_footnotes,
- rndr_footnote_def,
- rndr_raw_block,
-
- rndr_autolink,
- rndr_codespan,
- rndr_double_emphasis,
- rndr_emphasis,
- rndr_underline,
- rndr_highlight,
- rndr_quote,
- rndr_image,
- rndr_linebreak,
- rndr_link,
- rndr_triple_emphasis,
- rndr_strikethrough,
- rndr_superscript,
- rndr_footnote_ref,
- rndr_math,
- rndr_raw_html,
-
- NULL,
- rndr_normal_text,
-
- NULL,
- NULL
- };
-
- hoedown_html_renderer_state *state;
- hoedown_renderer *renderer;
-
- /* Prepare the state pointer */
- state = hoedown_malloc(sizeof(hoedown_html_renderer_state));
- memset(state, 0x0, sizeof(hoedown_html_renderer_state));
-
- state->flags = render_flags;
- state->toc_data.nesting_level = nesting_level;
-
- /* Prepare the renderer */
- renderer = hoedown_malloc(sizeof(hoedown_renderer));
- memcpy(renderer, &cb_default, sizeof(hoedown_renderer));
-
- if (render_flags & HOEDOWN_HTML_SKIP_HTML || render_flags & HOEDOWN_HTML_ESCAPE)
- renderer->blockhtml = NULL;
-
- renderer->opaque = state;
- return renderer;
+ static const hoedown_renderer cb_default = {
+ NULL,
+
+ rndr_blockcode,
+ rndr_blockquote,
+ rndr_header,
+ rndr_hrule,
+ rndr_list,
+ rndr_listitem,
+ rndr_paragraph,
+ rndr_table,
+ rndr_table_header,
+ rndr_table_body,
+ rndr_tablerow,
+ rndr_tablecell,
+ rndr_footnotes,
+ rndr_footnote_def,
+ rndr_raw_block,
+
+ rndr_autolink,
+ rndr_codespan,
+ rndr_double_emphasis,
+ rndr_emphasis,
+ rndr_underline,
+ rndr_highlight,
+ rndr_quote,
+ rndr_image,
+ rndr_linebreak,
+ rndr_link,
+ rndr_triple_emphasis,
+ rndr_strikethrough,
+ rndr_superscript,
+ rndr_footnote_ref,
+ rndr_math,
+ rndr_raw_html,
+
+ NULL,
+ rndr_normal_text,
+
+ NULL,
+ NULL
+ };
+
+ hoedown_html_renderer_state *state;
+ hoedown_renderer *renderer;
+
+ /* Prepare the state pointer */
+ state = hoedown_malloc(sizeof(hoedown_html_renderer_state));
+ memset(state, 0x0, sizeof(hoedown_html_renderer_state));
+
+ state->flags = render_flags;
+ state->toc_data.nesting_level = nesting_level;
+
+ /* Prepare the renderer */
+ renderer = hoedown_malloc(sizeof(hoedown_renderer));
+ memcpy(renderer, &cb_default, sizeof(hoedown_renderer));
+
+ if (render_flags & HOEDOWN_HTML_SKIP_HTML || render_flags & HOEDOWN_HTML_ESCAPE)
+ renderer->blockhtml = NULL;
+
+ renderer->opaque = state;
+ return renderer;
}
void
hoedown_html_renderer_free(hoedown_renderer *renderer)
{
- free(renderer->opaque);
- free(renderer);
+ free(renderer->opaque);
+ free(renderer);
}
diff --git a/libraries/hoedown/src/html_smartypants.c b/libraries/hoedown/src/html_smartypants.c
index e24b6bf0..d89624f3 100644
--- a/libraries/hoedown/src/html_smartypants.c
+++ b/libraries/hoedown/src/html_smartypants.c
@@ -10,8 +10,8 @@
#endif
struct smartypants_data {
- int in_squote;
- int in_dquote;
+ int in_squote;
+ int in_dquote;
};
static size_t smartypants_cb__ltag(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);
@@ -26,353 +26,353 @@ static size_t smartypants_cb__backtick(hoedown_buffer *ob, struct smartypants_da
static size_t smartypants_cb__escape(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);
static size_t (*smartypants_cb_ptrs[])
- (hoedown_buffer *, struct smartypants_data *, uint8_t, const uint8_t *, size_t) =
+ (hoedown_buffer *, struct smartypants_data *, uint8_t, const uint8_t *, size_t) =
{
- NULL, /* 0 */
- smartypants_cb__dash, /* 1 */
- smartypants_cb__parens, /* 2 */
- smartypants_cb__squote, /* 3 */
- smartypants_cb__dquote, /* 4 */
- smartypants_cb__amp, /* 5 */
- smartypants_cb__period, /* 6 */
- smartypants_cb__number, /* 7 */
- smartypants_cb__ltag, /* 8 */
- smartypants_cb__backtick, /* 9 */
- smartypants_cb__escape, /* 10 */
+ NULL, /* 0 */
+ smartypants_cb__dash, /* 1 */
+ smartypants_cb__parens, /* 2 */
+ smartypants_cb__squote, /* 3 */
+ smartypants_cb__dquote, /* 4 */
+ smartypants_cb__amp, /* 5 */
+ smartypants_cb__period, /* 6 */
+ smartypants_cb__number, /* 7 */
+ smartypants_cb__ltag, /* 8 */
+ smartypants_cb__backtick, /* 9 */
+ smartypants_cb__escape, /* 10 */
};
static const uint8_t smartypants_cb_chars[UINT8_MAX+1] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 0, 0, 0, 5, 3, 2, 0, 0, 0, 0, 1, 6, 0,
- 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0,
- 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 5, 3, 2, 0, 0, 0, 0, 1, 6, 0,
+ 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static int
word_boundary(uint8_t c)
{
- return c == 0 || isspace(c) || ispunct(c);
+ return c == 0 || isspace(c) || ispunct(c);
}
/*
- If 'text' begins with any kind of single quote (e.g. "'" or "&apos;" etc.),
- returns the length of the sequence of characters that makes up the single-
- quote. Otherwise, returns zero.
+ If 'text' begins with any kind of single quote (e.g. "'" or "&apos;" etc.),
+ returns the length of the sequence of characters that makes up the single-
+ quote. Otherwise, returns zero.
*/
static size_t
squote_len(const uint8_t *text, size_t size)
{
- static char* single_quote_list[] = { "'", "&#39;", "&#x27;", "&apos;", NULL };
- char** p;
+ static char* single_quote_list[] = { "'", "&#39;", "&#x27;", "&apos;", NULL };
+ char** p;
- for (p = single_quote_list; *p; ++p) {
- size_t len = strlen(*p);
- if (size >= len && memcmp(text, *p, len) == 0) {
- return len;
- }
- }
+ for (p = single_quote_list; *p; ++p) {
+ size_t len = strlen(*p);
+ if (size >= len && memcmp(text, *p, len) == 0) {
+ return len;
+ }
+ }
- return 0;
+ return 0;
}
/* Converts " or ' at very beginning or end of a word to left or right quote */
static int
smartypants_quotes(hoedown_buffer *ob, uint8_t previous_char, uint8_t next_char, uint8_t quote, int *is_open)
{
- char ent[8];
+ char ent[8];
- if (*is_open && !word_boundary(next_char))
- return 0;
+ if (*is_open && !word_boundary(next_char))
+ return 0;
- if (!(*is_open) && !word_boundary(previous_char))
- return 0;
+ if (!(*is_open) && !word_boundary(previous_char))
+ return 0;
- snprintf(ent, sizeof(ent), "&%c%cquo;", (*is_open) ? 'r' : 'l', quote);
- *is_open = !(*is_open);
- hoedown_buffer_puts(ob, ent);
- return 1;
+ snprintf(ent, sizeof(ent), "&%c%cquo;", (*is_open) ? 'r' : 'l', quote);
+ *is_open = !(*is_open);
+ hoedown_buffer_puts(ob, ent);
+ return 1;
}
/*
- Converts ' to left or right single quote; but the initial ' might be in
- different forms, e.g. &apos; or &#39; or &#x27;.
- 'squote_text' points to the original single quote, and 'squote_size' is its length.
- 'text' points at the last character of the single-quote, e.g. ' or ;
+ Converts ' to left or right single quote; but the initial ' might be in
+ different forms, e.g. &apos; or &#39; or &#x27;.
+ 'squote_text' points to the original single quote, and 'squote_size' is its length.
+ 'text' points at the last character of the single-quote, e.g. ' or ;
*/
static size_t
smartypants_squote(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size,
- const uint8_t *squote_text, size_t squote_size)
+ const uint8_t *squote_text, size_t squote_size)
{
- if (size >= 2) {
- uint8_t t1 = tolower(text[1]);
- size_t next_squote_len = squote_len(text+1, size-1);
-
- /* convert '' to &ldquo; or &rdquo; */
- if (next_squote_len > 0) {
- uint8_t next_char = (size > 1+next_squote_len) ? text[1+next_squote_len] : 0;
- if (smartypants_quotes(ob, previous_char, next_char, 'd', &smrt->in_dquote))
- return next_squote_len;
- }
-
- /* Tom's, isn't, I'm, I'd */
- if ((t1 == 's' || t1 == 't' || t1 == 'm' || t1 == 'd') &&
- (size == 3 || word_boundary(text[2]))) {
- HOEDOWN_BUFPUTSL(ob, "&rsquo;");
- return 0;
- }
-
- /* you're, you'll, you've */
- if (size >= 3) {
- uint8_t t2 = tolower(text[2]);
-
- if (((t1 == 'r' && t2 == 'e') ||
- (t1 == 'l' && t2 == 'l') ||
- (t1 == 'v' && t2 == 'e')) &&
- (size == 4 || word_boundary(text[3]))) {
- HOEDOWN_BUFPUTSL(ob, "&rsquo;");
- return 0;
- }
- }
- }
-
- if (smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 's', &smrt->in_squote))
- return 0;
-
- hoedown_buffer_put(ob, squote_text, squote_size);
- return 0;
+ if (size >= 2) {
+ uint8_t t1 = tolower(text[1]);
+ size_t next_squote_len = squote_len(text+1, size-1);
+
+ /* convert '' to &ldquo; or &rdquo; */
+ if (next_squote_len > 0) {
+ uint8_t next_char = (size > 1+next_squote_len) ? text[1+next_squote_len] : 0;
+ if (smartypants_quotes(ob, previous_char, next_char, 'd', &smrt->in_dquote))
+ return next_squote_len;
+ }
+
+ /* Tom's, isn't, I'm, I'd */
+ if ((t1 == 's' || t1 == 't' || t1 == 'm' || t1 == 'd') &&
+ (size == 3 || word_boundary(text[2]))) {
+ HOEDOWN_BUFPUTSL(ob, "&rsquo;");
+ return 0;
+ }
+
+ /* you're, you'll, you've */
+ if (size >= 3) {
+ uint8_t t2 = tolower(text[2]);
+
+ if (((t1 == 'r' && t2 == 'e') ||
+ (t1 == 'l' && t2 == 'l') ||
+ (t1 == 'v' && t2 == 'e')) &&
+ (size == 4 || word_boundary(text[3]))) {
+ HOEDOWN_BUFPUTSL(ob, "&rsquo;");
+ return 0;
+ }
+ }
+ }
+
+ if (smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 's', &smrt->in_squote))
+ return 0;
+
+ hoedown_buffer_put(ob, squote_text, squote_size);
+ return 0;
}
/* Converts ' to left or right single quote. */
static size_t
smartypants_cb__squote(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- return smartypants_squote(ob, smrt, previous_char, text, size, text, 1);
+ return smartypants_squote(ob, smrt, previous_char, text, size, text, 1);
}
/* Converts (c), (r), (tm) */
static size_t
smartypants_cb__parens(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- if (size >= 3) {
- uint8_t t1 = tolower(text[1]);
- uint8_t t2 = tolower(text[2]);
-
- if (t1 == 'c' && t2 == ')') {
- HOEDOWN_BUFPUTSL(ob, "&copy;");
- return 2;
- }
-
- if (t1 == 'r' && t2 == ')') {
- HOEDOWN_BUFPUTSL(ob, "&reg;");
- return 2;
- }
-
- if (size >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')') {
- HOEDOWN_BUFPUTSL(ob, "&trade;");
- return 3;
- }
- }
-
- hoedown_buffer_putc(ob, text[0]);
- return 0;
+ if (size >= 3) {
+ uint8_t t1 = tolower(text[1]);
+ uint8_t t2 = tolower(text[2]);
+
+ if (t1 == 'c' && t2 == ')') {
+ HOEDOWN_BUFPUTSL(ob, "&copy;");
+ return 2;
+ }
+
+ if (t1 == 'r' && t2 == ')') {
+ HOEDOWN_BUFPUTSL(ob, "&reg;");
+ return 2;
+ }
+
+ if (size >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')') {
+ HOEDOWN_BUFPUTSL(ob, "&trade;");
+ return 3;
+ }
+ }
+
+ hoedown_buffer_putc(ob, text[0]);
+ return 0;
}
/* Converts "--" to em-dash, etc. */
static size_t
smartypants_cb__dash(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- if (size >= 3 && text[1] == '-' && text[2] == '-') {
- HOEDOWN_BUFPUTSL(ob, "&mdash;");
- return 2;
- }
-
- if (size >= 2 && text[1] == '-') {
- HOEDOWN_BUFPUTSL(ob, "&ndash;");
- return 1;
- }
-
- hoedown_buffer_putc(ob, text[0]);
- return 0;
+ if (size >= 3 && text[1] == '-' && text[2] == '-') {
+ HOEDOWN_BUFPUTSL(ob, "&mdash;");
+ return 2;
+ }
+
+ if (size >= 2 && text[1] == '-') {
+ HOEDOWN_BUFPUTSL(ob, "&ndash;");
+ return 1;
+ }
+
+ hoedown_buffer_putc(ob, text[0]);
+ return 0;
}
/* Converts &quot; etc. */
static size_t
smartypants_cb__amp(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- size_t len;
- if (size >= 6 && memcmp(text, "&quot;", 6) == 0) {
- if (smartypants_quotes(ob, previous_char, size >= 7 ? text[6] : 0, 'd', &smrt->in_dquote))
- return 5;
- }
-
- len = squote_len(text, size);
- if (len > 0) {
- return (len-1) + smartypants_squote(ob, smrt, previous_char, text+(len-1), size-(len-1), text, len);
- }
-
- if (size >= 4 && memcmp(text, "&#0;", 4) == 0)
- return 3;
-
- hoedown_buffer_putc(ob, '&');
- return 0;
+ size_t len;
+ if (size >= 6 && memcmp(text, "&quot;", 6) == 0) {
+ if (smartypants_quotes(ob, previous_char, size >= 7 ? text[6] : 0, 'd', &smrt->in_dquote))
+ return 5;
+ }
+
+ len = squote_len(text, size);
+ if (len > 0) {
+ return (len-1) + smartypants_squote(ob, smrt, previous_char, text+(len-1), size-(len-1), text, len);
+ }
+
+ if (size >= 4 && memcmp(text, "&#0;", 4) == 0)
+ return 3;
+
+ hoedown_buffer_putc(ob, '&');
+ return 0;
}
/* Converts "..." to ellipsis */
static size_t
smartypants_cb__period(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- if (size >= 3 && text[1] == '.' && text[2] == '.') {
- HOEDOWN_BUFPUTSL(ob, "&hellip;");
- return 2;
- }
-
- if (size >= 5 && text[1] == ' ' && text[2] == '.' && text[3] == ' ' && text[4] == '.') {
- HOEDOWN_BUFPUTSL(ob, "&hellip;");
- return 4;
- }
-
- hoedown_buffer_putc(ob, text[0]);
- return 0;
+ if (size >= 3 && text[1] == '.' && text[2] == '.') {
+ HOEDOWN_BUFPUTSL(ob, "&hellip;");
+ return 2;
+ }
+
+ if (size >= 5 && text[1] == ' ' && text[2] == '.' && text[3] == ' ' && text[4] == '.') {
+ HOEDOWN_BUFPUTSL(ob, "&hellip;");
+ return 4;
+ }
+
+ hoedown_buffer_putc(ob, text[0]);
+ return 0;
}
/* Converts `` to opening double quote */
static size_t
smartypants_cb__backtick(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- if (size >= 2 && text[1] == '`') {
- if (smartypants_quotes(ob, previous_char, size >= 3 ? text[2] : 0, 'd', &smrt->in_dquote))
- return 1;
- }
+ if (size >= 2 && text[1] == '`') {
+ if (smartypants_quotes(ob, previous_char, size >= 3 ? text[2] : 0, 'd', &smrt->in_dquote))
+ return 1;
+ }
- hoedown_buffer_putc(ob, text[0]);
- return 0;
+ hoedown_buffer_putc(ob, text[0]);
+ return 0;
}
/* Converts 1/2, 1/4, 3/4 */
static size_t
smartypants_cb__number(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- if (word_boundary(previous_char) && size >= 3) {
- if (text[0] == '1' && text[1] == '/' && text[2] == '2') {
- if (size == 3 || word_boundary(text[3])) {
- HOEDOWN_BUFPUTSL(ob, "&frac12;");
- return 2;
- }
- }
-
- if (text[0] == '1' && text[1] == '/' && text[2] == '4') {
- if (size == 3 || word_boundary(text[3]) ||
- (size >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h')) {
- HOEDOWN_BUFPUTSL(ob, "&frac14;");
- return 2;
- }
- }
-
- if (text[0] == '3' && text[1] == '/' && text[2] == '4') {
- if (size == 3 || word_boundary(text[3]) ||
- (size >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's')) {
- HOEDOWN_BUFPUTSL(ob, "&frac34;");
- return 2;
- }
- }
- }
-
- hoedown_buffer_putc(ob, text[0]);
- return 0;
+ if (word_boundary(previous_char) && size >= 3) {
+ if (text[0] == '1' && text[1] == '/' && text[2] == '2') {
+ if (size == 3 || word_boundary(text[3])) {
+ HOEDOWN_BUFPUTSL(ob, "&frac12;");
+ return 2;
+ }
+ }
+
+ if (text[0] == '1' && text[1] == '/' && text[2] == '4') {
+ if (size == 3 || word_boundary(text[3]) ||
+ (size >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h')) {
+ HOEDOWN_BUFPUTSL(ob, "&frac14;");
+ return 2;
+ }
+ }
+
+ if (text[0] == '3' && text[1] == '/' && text[2] == '4') {
+ if (size == 3 || word_boundary(text[3]) ||
+ (size >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's')) {
+ HOEDOWN_BUFPUTSL(ob, "&frac34;");
+ return 2;
+ }
+ }
+ }
+
+ hoedown_buffer_putc(ob, text[0]);
+ return 0;
}
/* Converts " to left or right double quote */
static size_t
smartypants_cb__dquote(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- if (!smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 'd', &smrt->in_dquote))
- HOEDOWN_BUFPUTSL(ob, "&quot;");
+ if (!smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 'd', &smrt->in_dquote))
+ HOEDOWN_BUFPUTSL(ob, "&quot;");
- return 0;
+ return 0;
}
static size_t
smartypants_cb__ltag(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- static const char *skip_tags[] = {
- "pre", "code", "var", "samp", "kbd", "math", "script", "style"
- };
- static const size_t skip_tags_count = 8;
-
- size_t tag, i = 0;
-
- /* This is a comment. Copy everything verbatim until --> or EOF is seen. */
- if (i + 4 < size && memcmp(text, "<!--", 4) == 0) {
- i += 4;
- while (i + 3 < size && memcmp(text + i, "-->", 3) != 0)
- i++;
- i += 3;
- hoedown_buffer_put(ob, text, i + 1);
- return i;
- }
-
- while (i < size && text[i] != '>')
- i++;
-
- for (tag = 0; tag < skip_tags_count; ++tag) {
- if (hoedown_html_is_tag(text, size, skip_tags[tag]) == HOEDOWN_HTML_TAG_OPEN)
- break;
- }
-
- if (tag < skip_tags_count) {
- for (;;) {
- while (i < size && text[i] != '<')
- i++;
-
- if (i == size)
- break;
-
- if (hoedown_html_is_tag(text + i, size - i, skip_tags[tag]) == HOEDOWN_HTML_TAG_CLOSE)
- break;
-
- i++;
- }
-
- while (i < size && text[i] != '>')
- i++;
- }
-
- hoedown_buffer_put(ob, text, i + 1);
- return i;
+ static const char *skip_tags[] = {
+ "pre", "code", "var", "samp", "kbd", "math", "script", "style"
+ };
+ static const size_t skip_tags_count = 8;
+
+ size_t tag, i = 0;
+
+ /* This is a comment. Copy everything verbatim until --> or EOF is seen. */
+ if (i + 4 < size && memcmp(text, "<!--", 4) == 0) {
+ i += 4;
+ while (i + 3 < size && memcmp(text + i, "-->", 3) != 0)
+ i++;
+ i += 3;
+ hoedown_buffer_put(ob, text, i + 1);
+ return i;
+ }
+
+ while (i < size && text[i] != '>')
+ i++;
+
+ for (tag = 0; tag < skip_tags_count; ++tag) {
+ if (hoedown_html_is_tag(text, size, skip_tags[tag]) == HOEDOWN_HTML_TAG_OPEN)
+ break;
+ }
+
+ if (tag < skip_tags_count) {
+ for (;;) {
+ while (i < size && text[i] != '<')
+ i++;
+
+ if (i == size)
+ break;
+
+ if (hoedown_html_is_tag(text + i, size - i, skip_tags[tag]) == HOEDOWN_HTML_TAG_CLOSE)
+ break;
+
+ i++;
+ }
+
+ while (i < size && text[i] != '>')
+ i++;
+ }
+
+ hoedown_buffer_put(ob, text, i + 1);
+ return i;
}
static size_t
smartypants_cb__escape(hoedown_buffer *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
{
- if (size < 2)
- return 0;
-
- switch (text[1]) {
- case '\\':
- case '"':
- case '\'':
- case '.':
- case '-':
- case '`':
- hoedown_buffer_putc(ob, text[1]);
- return 1;
-
- default:
- hoedown_buffer_putc(ob, '\\');
- return 0;
- }
+ if (size < 2)
+ return 0;
+
+ switch (text[1]) {
+ case '\\':
+ case '"':
+ case '\'':
+ case '.':
+ case '-':
+ case '`':
+ hoedown_buffer_putc(ob, text[1]);
+ return 1;
+
+ default:
+ hoedown_buffer_putc(ob, '\\');
+ return 0;
+ }
}
#if 0
@@ -408,28 +408,28 @@ static struct {
void
hoedown_html_smartypants(hoedown_buffer *ob, const uint8_t *text, size_t size)
{
- size_t i;
- struct smartypants_data smrt = {0, 0};
+ size_t i;
+ struct smartypants_data smrt = {0, 0};
- if (!text)
- return;
+ if (!text)
+ return;
- hoedown_buffer_grow(ob, size);
+ hoedown_buffer_grow(ob, size);
- for (i = 0; i < size; ++i) {
- size_t org;
- uint8_t action = 0;
+ for (i = 0; i < size; ++i) {
+ size_t org;
+ uint8_t action = 0;
- org = i;
- while (i < size && (action = smartypants_cb_chars[text[i]]) == 0)
- i++;
+ org = i;
+ while (i < size && (action = smartypants_cb_chars[text[i]]) == 0)
+ i++;
- if (i > org)
- hoedown_buffer_put(ob, text + org, i - org);
+ if (i > org)
+ hoedown_buffer_put(ob, text + org, i - org);
- if (i < size) {
- i += smartypants_cb_ptrs[(int)action]
- (ob, &smrt, i ? text[i - 1] : 0, text + i, size - i);
- }
- }
+ if (i < size) {
+ i += smartypants_cb_ptrs[(int)action]
+ (ob, &smrt, i ? text[i - 1] : 0, text + i, size - i);
+ }
+ }
}
diff --git a/libraries/hoedown/src/stack.c b/libraries/hoedown/src/stack.c
index 46ead232..0523c11b 100644
--- a/libraries/hoedown/src/stack.c
+++ b/libraries/hoedown/src/stack.c
@@ -9,71 +9,71 @@
void
hoedown_stack_init(hoedown_stack *st, size_t initial_size)
{
- assert(st);
+ assert(st);
- st->item = NULL;
- st->size = st->asize = 0;
+ st->item = NULL;
+ st->size = st->asize = 0;
- if (!initial_size)
- initial_size = 8;
+ if (!initial_size)
+ initial_size = 8;
- hoedown_stack_grow(st, initial_size);
+ hoedown_stack_grow(st, initial_size);
}
void
hoedown_stack_uninit(hoedown_stack *st)
{
- assert(st);
+ assert(st);
- free(st->item);
+ free(st->item);
}
void
hoedown_stack_grow(hoedown_stack *st, size_t neosz)
{
- assert(st);
+ assert(st);
- if (st->asize >= neosz)
- return;
+ if (st->asize >= neosz)
+ return;
- st->item = hoedown_realloc(st->item, neosz * sizeof(void *));
- memset(st->item + st->asize, 0x0, (neosz - st->asize) * sizeof(void *));
+ st->item = hoedown_realloc(st->item, neosz * sizeof(void *));
+ memset(st->item + st->asize, 0x0, (neosz - st->asize) * sizeof(void *));
- st->asize = neosz;
+ st->asize = neosz;
- if (st->size > neosz)
- st->size = neosz;
+ if (st->size > neosz)
+ st->size = neosz;
}
void
hoedown_stack_push(hoedown_stack *st, void *item)
{
- assert(st);
+ assert(st);
- if (st->size >= st->asize)
- hoedown_stack_grow(st, st->size * 2);
+ if (st->size >= st->asize)
+ hoedown_stack_grow(st, st->size * 2);
- st->item[st->size++] = item;
+ st->item[st->size++] = item;
}
void *
hoedown_stack_pop(hoedown_stack *st)
{
- assert(st);
+ assert(st);
- if (!st->size)
- return NULL;
+ if (!st->size)
+ return NULL;
- return st->item[--st->size];
+ return st->item[--st->size];
}
void *
hoedown_stack_top(const hoedown_stack *st)
{
- assert(st);
+ assert(st);
- if (!st->size)
- return NULL;
+ if (!st->size)
+ return NULL;
- return st->item[st->size - 1];
+ return st->item[st->size - 1];
}
diff --git a/libraries/hoedown/src/version.c b/libraries/hoedown/src/version.c
index 625ed196..10d36cb9 100644
--- a/libraries/hoedown/src/version.c
+++ b/libraries/hoedown/src/version.c
@@ -3,7 +3,7 @@
void
hoedown_version(int *major, int *minor, int *revision)
{
- *major = HOEDOWN_VERSION_MAJOR;
- *minor = HOEDOWN_VERSION_MINOR;
- *revision = HOEDOWN_VERSION_REVISION;
+ *major = HOEDOWN_VERSION_MAJOR;
+ *minor = HOEDOWN_VERSION_MINOR;
+ *revision = HOEDOWN_VERSION_REVISION;
}
diff --git a/libraries/iconfix/CMakeLists.txt b/libraries/iconfix/CMakeLists.txt
index d0b7aa34..ccf0edea 100644
--- a/libraries/iconfix/CMakeLists.txt
+++ b/libraries/iconfix/CMakeLists.txt
@@ -22,7 +22,7 @@ generate_export_header(MultiMC_iconfix)
# Install it
install(
- TARGETS MultiMC_iconfix
- RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
- LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
+ TARGETS MultiMC_iconfix
+ RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
+ LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
) \ No newline at end of file
diff --git a/libraries/iconfix/internal/qhexstring_p.h b/libraries/iconfix/internal/qhexstring_p.h
index f01b4cdd..c81904e5 100644
--- a/libraries/iconfix/internal/qhexstring_p.h
+++ b/libraries/iconfix/internal/qhexstring_p.h
@@ -61,40 +61,40 @@
// internal helper. Converts an integer value to an unique string token
template <typename T> struct HexString
{
- inline HexString(const T t) : val(t)
- {
- }
+ inline HexString(const T t) : val(t)
+ {
+ }
- inline void write(QChar *&dest) const
- {
- const ushort hexChars[] = {'0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
- const char *c = reinterpret_cast<const char *>(&val);
- for (uint i = 0; i < sizeof(T); ++i)
- {
- *dest++ = hexChars[*c & 0xf];
- *dest++ = hexChars[(*c & 0xf0) >> 4];
- ++c;
- }
- }
- const T val;
+ inline void write(QChar *&dest) const
+ {
+ const ushort hexChars[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ const char *c = reinterpret_cast<const char *>(&val);
+ for (uint i = 0; i < sizeof(T); ++i)
+ {
+ *dest++ = hexChars[*c & 0xf];
+ *dest++ = hexChars[(*c & 0xf0) >> 4];
+ ++c;
+ }
+ }
+ const T val;
};
// specialization to enable fast concatenating of our string tokens to a string
template <typename T> struct QConcatenable<HexString<T>>
{
- typedef HexString<T> type;
- enum
- {
- ExactSize = true
- };
- static int size(const HexString<T> &)
- {
- return sizeof(T) * 2;
- }
- static inline void appendTo(const HexString<T> &str, QChar *&out)
- {
- str.write(out);
- }
- typedef QString ConvertTo;
+ typedef HexString<T> type;
+ enum
+ {
+ ExactSize = true
+ };
+ static int size(const HexString<T> &)
+ {
+ return sizeof(T) * 2;
+ }
+ static inline void appendTo(const HexString<T> &str, QChar *&out)
+ {
+ str.write(out);
+ }
+ typedef QString ConvertTo;
};
diff --git a/libraries/iconfix/internal/qiconloader.cpp b/libraries/iconfix/internal/qiconloader.cpp
index b1195893..41cf3d50 100644
--- a/libraries/iconfix/internal/qiconloader.cpp
+++ b/libraries/iconfix/internal/qiconloader.cpp
@@ -55,7 +55,7 @@ Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance)
static QString fallbackTheme()
{
- return QString("hicolor");
+ return QString("hicolor");
}
QIconLoader::QIconLoader() : m_themeKey(1), m_supportsSvg(false), m_initialized(false)
@@ -67,403 +67,403 @@ QIconLoader::QIconLoader() : m_themeKey(1), m_supportsSvg(false), m_initialized(
static inline QString systemThemeName()
{
- return QIcon::themeName();
+ return QIcon::themeName();
}
static inline QStringList systemIconSearchPaths()
{
- auto paths = QIcon::themeSearchPaths();
- paths.push_front(":/icons");
- return paths;
+ auto paths = QIcon::themeSearchPaths();
+ paths.push_front(":/icons");
+ return paths;
}
void QIconLoader::ensureInitialized()
{
- if (!m_initialized)
- {
- m_initialized = true;
+ if (!m_initialized)
+ {
+ m_initialized = true;
- Q_ASSERT(qApp);
+ Q_ASSERT(qApp);
- m_systemTheme = QIcon::themeName();
+ m_systemTheme = QIcon::themeName();
- if (m_systemTheme.isEmpty())
- m_systemTheme = fallbackTheme();
- m_supportsSvg = true;
- }
+ if (m_systemTheme.isEmpty())
+ m_systemTheme = fallbackTheme();
+ m_supportsSvg = true;
+ }
}
QIconLoader *QIconLoader::instance()
{
- iconLoaderInstance()->ensureInitialized();
- return iconLoaderInstance();
+ iconLoaderInstance()->ensureInitialized();
+ return iconLoaderInstance();
}
// Queries the system theme and invalidates existing
// icons if the theme has changed.
void QIconLoader::updateSystemTheme()
{
- // Only change if this is not explicitly set by the user
- if (m_userTheme.isEmpty())
- {
- QString theme = systemThemeName();
- if (theme.isEmpty())
- theme = fallbackTheme();
- if (theme != m_systemTheme)
- {
- m_systemTheme = theme;
- invalidateKey();
- }
- }
+ // Only change if this is not explicitly set by the user
+ if (m_userTheme.isEmpty())
+ {
+ QString theme = systemThemeName();
+ if (theme.isEmpty())
+ theme = fallbackTheme();
+ if (theme != m_systemTheme)
+ {
+ m_systemTheme = theme;
+ invalidateKey();
+ }
+ }
}
void QIconLoader::setThemeName(const QString &themeName)
{
- m_userTheme = themeName;
- invalidateKey();
+ m_userTheme = themeName;
+ invalidateKey();
}
void QIconLoader::setThemeSearchPath(const QStringList &searchPaths)
{
- m_iconDirs = searchPaths;
- themeList.clear();
- invalidateKey();
+ m_iconDirs = searchPaths;
+ themeList.clear();
+ invalidateKey();
}
QStringList QIconLoader::themeSearchPaths() const
{
- if (m_iconDirs.isEmpty())
- {
- m_iconDirs = systemIconSearchPaths();
- }
- return m_iconDirs;
+ if (m_iconDirs.isEmpty())
+ {
+ m_iconDirs = systemIconSearchPaths();
+ }
+ return m_iconDirs;
}
QIconTheme::QIconTheme(const QString &themeName) : m_valid(false)
{
- QFile themeIndex;
-
- QStringList iconDirs = systemIconSearchPaths();
- for (int i = 0; i < iconDirs.size(); ++i)
- {
- QDir iconDir(iconDirs[i]);
- QString themeDir = iconDir.path() + QLatin1Char('/') + themeName;
- themeIndex.setFileName(themeDir + QLatin1String("/index.theme"));
- if (themeIndex.exists())
- {
- m_contentDir = themeDir;
- m_valid = true;
-
- foreach (QString path, iconDirs)
- {
- if (QFileInfo(path).isDir())
- m_contentDirs.append(path + QLatin1Char('/') + themeName);
- }
-
- break;
- }
- }
-
- // if there is no index file, abscond.
- if (!themeIndex.exists())
- return;
-
- // otherwise continue reading index file
- const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
- QStringListIterator keyIterator(indexReader.allKeys());
- while (keyIterator.hasNext())
- {
- const QString key = keyIterator.next();
- if (!key.endsWith(QLatin1String("/Size")))
- continue;
-
- // Note the QSettings ini-format does not accept
- // slashes in key names, hence we have to cheat
- int size = indexReader.value(key).toInt();
- if (!size)
- continue;
-
- QString directoryKey = key.left(key.size() - 5);
- QIconDirInfo dirInfo(directoryKey);
- dirInfo.size = size;
- QString type =
- indexReader.value(directoryKey + QLatin1String("/Type")).toString();
-
- if (type == QLatin1String("Fixed"))
- dirInfo.type = QIconDirInfo::Fixed;
- else if (type == QLatin1String("Scalable"))
- dirInfo.type = QIconDirInfo::Scalable;
- else
- dirInfo.type = QIconDirInfo::Threshold;
-
- dirInfo.threshold =
- indexReader.value(directoryKey + QLatin1String("/Threshold"), 2)
- .toInt();
-
- dirInfo.minSize =
- indexReader.value(directoryKey + QLatin1String("/MinSize"), size)
- .toInt();
-
- dirInfo.maxSize =
- indexReader.value(directoryKey + QLatin1String("/MaxSize"), size)
- .toInt();
- m_keyList.append(dirInfo);
- }
-
- // Parent themes provide fallbacks for missing icons
- m_parents = indexReader.value(QLatin1String("Icon Theme/Inherits")).toStringList();
- m_parents.removeAll(QString());
-
- // Ensure a default platform fallback for all themes
- if (m_parents.isEmpty())
- {
- const QString fallback = fallbackTheme();
- if (!fallback.isEmpty())
- m_parents.append(fallback);
- }
-
- // Ensure that all themes fall back to hicolor
- if (!m_parents.contains(QLatin1String("hicolor")))
- m_parents.append(QLatin1String("hicolor"));
+ QFile themeIndex;
+
+ QStringList iconDirs = systemIconSearchPaths();
+ for (int i = 0; i < iconDirs.size(); ++i)
+ {
+ QDir iconDir(iconDirs[i]);
+ QString themeDir = iconDir.path() + QLatin1Char('/') + themeName;
+ themeIndex.setFileName(themeDir + QLatin1String("/index.theme"));
+ if (themeIndex.exists())
+ {
+ m_contentDir = themeDir;
+ m_valid = true;
+
+ foreach (QString path, iconDirs)
+ {
+ if (QFileInfo(path).isDir())
+ m_contentDirs.append(path + QLatin1Char('/') + themeName);
+ }
+
+ break;
+ }
+ }
+
+ // if there is no index file, abscond.
+ if (!themeIndex.exists())
+ return;
+
+ // otherwise continue reading index file
+ const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
+ QStringListIterator keyIterator(indexReader.allKeys());
+ while (keyIterator.hasNext())
+ {
+ const QString key = keyIterator.next();
+ if (!key.endsWith(QLatin1String("/Size")))
+ continue;
+
+ // Note the QSettings ini-format does not accept
+ // slashes in key names, hence we have to cheat
+ int size = indexReader.value(key).toInt();
+ if (!size)
+ continue;
+
+ QString directoryKey = key.left(key.size() - 5);
+ QIconDirInfo dirInfo(directoryKey);
+ dirInfo.size = size;
+ QString type =
+ indexReader.value(directoryKey + QLatin1String("/Type")).toString();
+
+ if (type == QLatin1String("Fixed"))
+ dirInfo.type = QIconDirInfo::Fixed;
+ else if (type == QLatin1String("Scalable"))
+ dirInfo.type = QIconDirInfo::Scalable;
+ else
+ dirInfo.type = QIconDirInfo::Threshold;
+
+ dirInfo.threshold =
+ indexReader.value(directoryKey + QLatin1String("/Threshold"), 2)
+ .toInt();
+
+ dirInfo.minSize =
+ indexReader.value(directoryKey + QLatin1String("/MinSize"), size)
+ .toInt();
+
+ dirInfo.maxSize =
+ indexReader.value(directoryKey + QLatin1String("/MaxSize"), size)
+ .toInt();
+ m_keyList.append(dirInfo);
+ }
+
+ // Parent themes provide fallbacks for missing icons
+ m_parents = indexReader.value(QLatin1String("Icon Theme/Inherits")).toStringList();
+ m_parents.removeAll(QString());
+
+ // Ensure a default platform fallback for all themes
+ if (m_parents.isEmpty())
+ {
+ const QString fallback = fallbackTheme();
+ if (!fallback.isEmpty())
+ m_parents.append(fallback);
+ }
+
+ // Ensure that all themes fall back to hicolor
+ if (!m_parents.contains(QLatin1String("hicolor")))
+ m_parents.append(QLatin1String("hicolor"));
}
QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, const QString &iconName,
- QStringList &visited) const
-{
- QThemeIconEntries entries;
- Q_ASSERT(!themeName.isEmpty());
-
- QPixmap pixmap;
-
- // Used to protect against potential recursions
- visited << themeName;
-
- QIconTheme theme = themeList.value(themeName);
- if (!theme.isValid())
- {
- theme = QIconTheme(themeName);
- if (!theme.isValid())
- theme = QIconTheme(fallbackTheme());
-
- themeList.insert(themeName, theme);
- }
-
- QStringList contentDirs = theme.contentDirs();
- const QVector<QIconDirInfo> subDirs = theme.keyList();
-
- const QString svgext(QLatin1String(".svg"));
- const QString pngext(QLatin1String(".png"));
- const QString xpmext(QLatin1String(".xpm"));
-
- // Add all relevant files
- for (int i = 0; i < subDirs.size(); ++i)
- {
- const QIconDirInfo &dirInfo = subDirs.at(i);
- QString subdir = dirInfo.path;
-
- foreach (QString contentDir, contentDirs)
- {
- QDir currentDir(contentDir + '/' + subdir);
-
- if (currentDir.exists(iconName + pngext))
- {
- PixmapEntry *iconEntry = new PixmapEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + pngext);
- // Notice we ensure that pixmap entries always come before
- // scalable to preserve search order afterwards
- entries.prepend(iconEntry);
- }
- else if (m_supportsSvg && currentDir.exists(iconName + svgext))
- {
- ScalableEntry *iconEntry = new ScalableEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + svgext);
- entries.append(iconEntry);
- break;
- }
- else if (currentDir.exists(iconName + xpmext))
- {
- PixmapEntry *iconEntry = new PixmapEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + xpmext);
- // Notice we ensure that pixmap entries always come before
- // scalable to preserve search order afterwards
- entries.append(iconEntry);
- break;
- }
- }
- }
-
- if (entries.isEmpty())
- {
- const QStringList parents = theme.parents();
- // Search recursively through inherited themes
- for (int i = 0; i < parents.size(); ++i)
- {
-
- const QString parentTheme = parents.at(i).trimmed();
-
- if (!visited.contains(parentTheme)) // guard against recursion
- entries = findIconHelper(parentTheme, iconName, visited);
-
- if (!entries.isEmpty()) // success
- break;
- }
- }
+ QStringList &visited) const
+{
+ QThemeIconEntries entries;
+ Q_ASSERT(!themeName.isEmpty());
+
+ QPixmap pixmap;
+
+ // Used to protect against potential recursions
+ visited << themeName;
+
+ QIconTheme theme = themeList.value(themeName);
+ if (!theme.isValid())
+ {
+ theme = QIconTheme(themeName);
+ if (!theme.isValid())
+ theme = QIconTheme(fallbackTheme());
+
+ themeList.insert(themeName, theme);
+ }
+
+ QStringList contentDirs = theme.contentDirs();
+ const QVector<QIconDirInfo> subDirs = theme.keyList();
+
+ const QString svgext(QLatin1String(".svg"));
+ const QString pngext(QLatin1String(".png"));
+ const QString xpmext(QLatin1String(".xpm"));
+
+ // Add all relevant files
+ for (int i = 0; i < subDirs.size(); ++i)
+ {
+ const QIconDirInfo &dirInfo = subDirs.at(i);
+ QString subdir = dirInfo.path;
+
+ foreach (QString contentDir, contentDirs)
+ {
+ QDir currentDir(contentDir + '/' + subdir);
+
+ if (currentDir.exists(iconName + pngext))
+ {
+ PixmapEntry *iconEntry = new PixmapEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + pngext);
+ // Notice we ensure that pixmap entries always come before
+ // scalable to preserve search order afterwards
+ entries.prepend(iconEntry);
+ }
+ else if (m_supportsSvg && currentDir.exists(iconName + svgext))
+ {
+ ScalableEntry *iconEntry = new ScalableEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + svgext);
+ entries.append(iconEntry);
+ break;
+ }
+ else if (currentDir.exists(iconName + xpmext))
+ {
+ PixmapEntry *iconEntry = new PixmapEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + xpmext);
+ // Notice we ensure that pixmap entries always come before
+ // scalable to preserve search order afterwards
+ entries.append(iconEntry);
+ break;
+ }
+ }
+ }
+
+ if (entries.isEmpty())
+ {
+ const QStringList parents = theme.parents();
+ // Search recursively through inherited themes
+ for (int i = 0; i < parents.size(); ++i)
+ {
+
+ const QString parentTheme = parents.at(i).trimmed();
+
+ if (!visited.contains(parentTheme)) // guard against recursion
+ entries = findIconHelper(parentTheme, iconName, visited);
+
+ if (!entries.isEmpty()) // success
+ break;
+ }
+ }
/*********************************************************************
Author: Kaitlin Rupert <kaitlin.rupert@intel.com>
Date: Aug 12, 2010
Description: Make it so that the QIcon loader honors /usr/share/pixmaps
- directory. This is a valid directory per the Freedesktop.org
- icon theme specification.
+ directory. This is a valid directory per the Freedesktop.org
+ icon theme specification.
Bug: https://bugreports.qt.nokia.com/browse/QTBUG-12874
*********************************************************************/
#ifdef Q_OS_LINUX
- /* Freedesktop standard says to look in /usr/share/pixmaps last */
- if (entries.isEmpty())
- {
- const QString pixmaps(QLatin1String("/usr/share/pixmaps"));
-
- QDir currentDir(pixmaps);
- QIconDirInfo dirInfo(pixmaps);
- if (currentDir.exists(iconName + pngext))
- {
- PixmapEntry *iconEntry = new PixmapEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + pngext);
- // Notice we ensure that pixmap entries always come before
- // scalable to preserve search order afterwards
- entries.prepend(iconEntry);
- }
- else if (m_supportsSvg && currentDir.exists(iconName + svgext))
- {
- ScalableEntry *iconEntry = new ScalableEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + svgext);
- entries.append(iconEntry);
- }
- else if (currentDir.exists(iconName + xpmext))
- {
- PixmapEntry *iconEntry = new PixmapEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + xpmext);
- // Notice we ensure that pixmap entries always come before
- // scalable to preserve search order afterwards
- entries.append(iconEntry);
- }
- }
+ /* Freedesktop standard says to look in /usr/share/pixmaps last */
+ if (entries.isEmpty())
+ {
+ const QString pixmaps(QLatin1String("/usr/share/pixmaps"));
+
+ QDir currentDir(pixmaps);
+ QIconDirInfo dirInfo(pixmaps);
+ if (currentDir.exists(iconName + pngext))
+ {
+ PixmapEntry *iconEntry = new PixmapEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + pngext);
+ // Notice we ensure that pixmap entries always come before
+ // scalable to preserve search order afterwards
+ entries.prepend(iconEntry);
+ }
+ else if (m_supportsSvg && currentDir.exists(iconName + svgext))
+ {
+ ScalableEntry *iconEntry = new ScalableEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + svgext);
+ entries.append(iconEntry);
+ }
+ else if (currentDir.exists(iconName + xpmext))
+ {
+ PixmapEntry *iconEntry = new PixmapEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + xpmext);
+ // Notice we ensure that pixmap entries always come before
+ // scalable to preserve search order afterwards
+ entries.append(iconEntry);
+ }
+ }
#endif
- if (entries.isEmpty())
- {
- // Search for unthemed icons in main dir of search paths
- QStringList themeSearchPaths = QIcon::themeSearchPaths();
- foreach (QString contentDir, themeSearchPaths)
- {
- QDir currentDir(contentDir);
-
- if (currentDir.exists(iconName + pngext))
- {
- PixmapEntry *iconEntry = new PixmapEntry;
- iconEntry->filename = currentDir.filePath(iconName + pngext);
- // Notice we ensure that pixmap entries always come before
- // scalable to preserve search order afterwards
- entries.prepend(iconEntry);
- }
- else if (m_supportsSvg && currentDir.exists(iconName + svgext))
- {
- ScalableEntry *iconEntry = new ScalableEntry;
- iconEntry->filename = currentDir.filePath(iconName + svgext);
- entries.append(iconEntry);
- break;
- }
- else if (currentDir.exists(iconName + xpmext))
- {
- PixmapEntry *iconEntry = new PixmapEntry;
- iconEntry->filename = currentDir.filePath(iconName + xpmext);
- // Notice we ensure that pixmap entries always come before
- // scalable to preserve search order afterwards
- entries.append(iconEntry);
- break;
- }
- }
- }
- return entries;
+ if (entries.isEmpty())
+ {
+ // Search for unthemed icons in main dir of search paths
+ QStringList themeSearchPaths = QIcon::themeSearchPaths();
+ foreach (QString contentDir, themeSearchPaths)
+ {
+ QDir currentDir(contentDir);
+
+ if (currentDir.exists(iconName + pngext))
+ {
+ PixmapEntry *iconEntry = new PixmapEntry;
+ iconEntry->filename = currentDir.filePath(iconName + pngext);
+ // Notice we ensure that pixmap entries always come before
+ // scalable to preserve search order afterwards
+ entries.prepend(iconEntry);
+ }
+ else if (m_supportsSvg && currentDir.exists(iconName + svgext))
+ {
+ ScalableEntry *iconEntry = new ScalableEntry;
+ iconEntry->filename = currentDir.filePath(iconName + svgext);
+ entries.append(iconEntry);
+ break;
+ }
+ else if (currentDir.exists(iconName + xpmext))
+ {
+ PixmapEntry *iconEntry = new PixmapEntry;
+ iconEntry->filename = currentDir.filePath(iconName + xpmext);
+ // Notice we ensure that pixmap entries always come before
+ // scalable to preserve search order afterwards
+ entries.append(iconEntry);
+ break;
+ }
+ }
+ }
+ return entries;
}
QThemeIconEntries QIconLoader::loadIcon(const QString &name) const
{
- if (!themeName().isEmpty())
- {
- QStringList visited;
- return findIconHelper(themeName(), name, visited);
- }
+ if (!themeName().isEmpty())
+ {
+ QStringList visited;
+ return findIconHelper(themeName(), name, visited);
+ }
- return QThemeIconEntries();
+ return QThemeIconEntries();
}
// -------- Icon Loader Engine -------- //
QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QString &iconName)
- : m_iconName(iconName), m_key(0)
+ : m_iconName(iconName), m_key(0)
{
}
QIconLoaderEngineFixed::~QIconLoaderEngineFixed()
{
- qDeleteAll(m_entries);
+ qDeleteAll(m_entries);
}
QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other)
- : QIconEngine(other), m_iconName(other.m_iconName), m_key(0)
+ : QIconEngine(other), m_iconName(other.m_iconName), m_key(0)
{
}
QIconEngine *QIconLoaderEngineFixed::clone() const
{
- return new QIconLoaderEngineFixed(*this);
+ return new QIconLoaderEngineFixed(*this);
}
bool QIconLoaderEngineFixed::read(QDataStream &in)
{
- in >> m_iconName;
- return true;
+ in >> m_iconName;
+ return true;
}
bool QIconLoaderEngineFixed::write(QDataStream &out) const
{
- out << m_iconName;
- return true;
+ out << m_iconName;
+ return true;
}
bool QIconLoaderEngineFixed::hasIcon() const
{
- return !(m_entries.isEmpty());
+ return !(m_entries.isEmpty());
}
// Lazily load the icon
void QIconLoaderEngineFixed::ensureLoaded()
{
- if (!(QIconLoader::instance()->themeKey() == m_key))
- {
+ if (!(QIconLoader::instance()->themeKey() == m_key))
+ {
- qDeleteAll(m_entries);
+ qDeleteAll(m_entries);
- m_entries = QIconLoader::instance()->loadIcon(m_iconName);
- m_key = QIconLoader::instance()->themeKey();
- }
+ m_entries = QIconLoader::instance()->loadIcon(m_iconName);
+ m_key = QIconLoader::instance()->themeKey();
+ }
}
void QIconLoaderEngineFixed::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode,
- QIcon::State state)
+ QIcon::State state)
{
- QSize pixmapSize = rect.size();
+ QSize pixmapSize = rect.size();
#if defined(Q_WS_MAC)
- pixmapSize *= qt_mac_get_scalefactor();
+ pixmapSize *= qt_mac_get_scalefactor();
#endif
- painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
+ painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
}
/*
@@ -472,21 +472,21 @@ void QIconLoaderEngineFixed::paint(QPainter *painter, const QRect &rect, QIcon::
*/
static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize)
{
- if (dir.type == QIconDirInfo::Fixed)
- {
- return dir.size == iconsize;
- }
- else if (dir.type == QIconDirInfo::Scalable)
- {
- return dir.size <= dir.maxSize && iconsize >= dir.minSize;
- }
- else if (dir.type == QIconDirInfo::Threshold)
- {
- return iconsize >= dir.size - dir.threshold && iconsize <= dir.size + dir.threshold;
- }
-
- Q_ASSERT(1); // Not a valid value
- return false;
+ if (dir.type == QIconDirInfo::Fixed)
+ {
+ return dir.size == iconsize;
+ }
+ else if (dir.type == QIconDirInfo::Scalable)
+ {
+ return dir.size <= dir.maxSize && iconsize >= dir.minSize;
+ }
+ else if (dir.type == QIconDirInfo::Threshold)
+ {
+ return iconsize >= dir.size - dir.threshold && iconsize <= dir.size + dir.threshold;
+ }
+
+ Q_ASSERT(1); // Not a valid value
+ return false;
}
/*
@@ -495,66 +495,66 @@ static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize)
*/
static int directorySizeDistance(const QIconDirInfo &dir, int iconsize)
{
- if (dir.type == QIconDirInfo::Fixed)
- {
- return qAbs(dir.size - iconsize);
- }
- else if (dir.type == QIconDirInfo::Scalable)
- {
- if (iconsize < dir.minSize)
- return dir.minSize - iconsize;
- else if (iconsize > dir.maxSize)
- return iconsize - dir.maxSize;
- else
- return 0;
- }
- else if (dir.type == QIconDirInfo::Threshold)
- {
- if (iconsize < dir.size - dir.threshold)
- return dir.minSize - iconsize;
- else if (iconsize > dir.size + dir.threshold)
- return iconsize - dir.maxSize;
- else
- return 0;
- }
-
- Q_ASSERT(1); // Not a valid value
- return INT_MAX;
+ if (dir.type == QIconDirInfo::Fixed)
+ {
+ return qAbs(dir.size - iconsize);
+ }
+ else if (dir.type == QIconDirInfo::Scalable)
+ {
+ if (iconsize < dir.minSize)
+ return dir.minSize - iconsize;
+ else if (iconsize > dir.maxSize)
+ return iconsize - dir.maxSize;
+ else
+ return 0;
+ }
+ else if (dir.type == QIconDirInfo::Threshold)
+ {
+ if (iconsize < dir.size - dir.threshold)
+ return dir.minSize - iconsize;
+ else if (iconsize > dir.size + dir.threshold)
+ return iconsize - dir.maxSize;
+ else
+ return 0;
+ }
+
+ Q_ASSERT(1); // Not a valid value
+ return INT_MAX;
}
QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size)
{
- int iconsize = qMin(size.width(), size.height());
-
- // Note that m_entries are sorted so that png-files
- // come first
-
- const int numEntries = m_entries.size();
-
- // Search for exact matches first
- for (int i = 0; i < numEntries; ++i)
- {
- QIconLoaderEngineEntry *entry = m_entries.at(i);
- if (directoryMatchesSize(entry->dir, iconsize))
- {
- return entry;
- }
- }
-
- // Find the minimum distance icon
- int minimalSize = INT_MAX;
- QIconLoaderEngineEntry *closestMatch = 0;
- for (int i = 0; i < numEntries; ++i)
- {
- QIconLoaderEngineEntry *entry = m_entries.at(i);
- int distance = directorySizeDistance(entry->dir, iconsize);
- if (distance < minimalSize)
- {
- minimalSize = distance;
- closestMatch = entry;
- }
- }
- return closestMatch;
+ int iconsize = qMin(size.width(), size.height());
+
+ // Note that m_entries are sorted so that png-files
+ // come first
+
+ const int numEntries = m_entries.size();
+
+ // Search for exact matches first
+ for (int i = 0; i < numEntries; ++i)
+ {
+ QIconLoaderEngineEntry *entry = m_entries.at(i);
+ if (directoryMatchesSize(entry->dir, iconsize))
+ {
+ return entry;
+ }
+ }
+
+ // Find the minimum distance icon
+ int minimalSize = INT_MAX;
+ QIconLoaderEngineEntry *closestMatch = 0;
+ for (int i = 0; i < numEntries; ++i)
+ {
+ QIconLoaderEngineEntry *entry = m_entries.at(i);
+ int distance = directorySizeDistance(entry->dir, iconsize);
+ if (distance < minimalSize)
+ {
+ minimalSize = distance;
+ closestMatch = entry;
+ }
+ }
+ return closestMatch;
}
/*
@@ -564,125 +564,125 @@ QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size)
*
*/
QSize QIconLoaderEngineFixed::actualSize(const QSize &size, QIcon::Mode mode,
- QIcon::State state)
-{
- ensureLoaded();
-
- QIconLoaderEngineEntry *entry = entryForSize(size);
- if (entry)
- {
- const QIconDirInfo &dir = entry->dir;
- if (dir.type == QIconDirInfo::Scalable)
- return size;
- else
- {
- int result = qMin<int>(dir.size, qMin(size.width(), size.height()));
- return QSize(result, result);
- }
- }
- return QIconEngine::actualSize(size, mode, state);
+ QIcon::State state)
+{
+ ensureLoaded();
+
+ QIconLoaderEngineEntry *entry = entryForSize(size);
+ if (entry)
+ {
+ const QIconDirInfo &dir = entry->dir;
+ if (dir.type == QIconDirInfo::Scalable)
+ return size;
+ else
+ {
+ int result = qMin<int>(dir.size, qMin(size.width(), size.height()));
+ return QSize(result, result);
+ }
+ }
+ return QIconEngine::actualSize(size, mode, state);
}
QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
{
- Q_UNUSED(state);
-
- // Ensure that basePixmap is lazily initialized before generating the
- // key, otherwise the cache key is not unique
- if (basePixmap.isNull())
- basePixmap.load(filename);
-
- QSize actualSize = basePixmap.size();
- if (!actualSize.isNull() &&
- (actualSize.width() > size.width() || actualSize.height() > size.height()))
- actualSize.scale(size, Qt::KeepAspectRatio);
-
- QString key = QLatin1String("$qt_theme_") % HexString<qint64>(basePixmap.cacheKey()) %
- HexString<int>(mode) %
- HexString<qint64>(QGuiApplication::palette().cacheKey()) %
- HexString<int>(actualSize.width()) % HexString<int>(actualSize.height());
-
- QPixmap cachedPixmap;
- if (QPixmapCache::find(key, &cachedPixmap))
- {
- return cachedPixmap;
- }
- else
- {
- if (basePixmap.size() != actualSize)
- {
- cachedPixmap = basePixmap.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- }
- else
- {
- cachedPixmap = basePixmap;
- }
- QPixmapCache::insert(key, cachedPixmap);
- }
- return cachedPixmap;
+ Q_UNUSED(state);
+
+ // Ensure that basePixmap is lazily initialized before generating the
+ // key, otherwise the cache key is not unique
+ if (basePixmap.isNull())
+ basePixmap.load(filename);
+
+ QSize actualSize = basePixmap.size();
+ if (!actualSize.isNull() &&
+ (actualSize.width() > size.width() || actualSize.height() > size.height()))
+ actualSize.scale(size, Qt::KeepAspectRatio);
+
+ QString key = QLatin1String("$qt_theme_") % HexString<qint64>(basePixmap.cacheKey()) %
+ HexString<int>(mode) %
+ HexString<qint64>(QGuiApplication::palette().cacheKey()) %
+ HexString<int>(actualSize.width()) % HexString<int>(actualSize.height());
+
+ QPixmap cachedPixmap;
+ if (QPixmapCache::find(key, &cachedPixmap))
+ {
+ return cachedPixmap;
+ }
+ else
+ {
+ if (basePixmap.size() != actualSize)
+ {
+ cachedPixmap = basePixmap.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ }
+ else
+ {
+ cachedPixmap = basePixmap;
+ }
+ QPixmapCache::insert(key, cachedPixmap);
+ }
+ return cachedPixmap;
}
QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
{
- if (svgIcon.isNull())
- {
- svgIcon = QIcon(filename);
- }
+ if (svgIcon.isNull())
+ {
+ svgIcon = QIcon(filename);
+ }
- // Simply reuse svg icon engine
- return svgIcon.pixmap(size, mode, state);
+ // Simply reuse svg icon engine
+ return svgIcon.pixmap(size, mode, state);
}
QPixmap QIconLoaderEngineFixed::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
{
- ensureLoaded();
+ ensureLoaded();
- QIconLoaderEngineEntry *entry = entryForSize(size);
- if (entry)
- {
- return entry->pixmap(size, mode, state);
- }
+ QIconLoaderEngineEntry *entry = entryForSize(size);
+ if (entry)
+ {
+ return entry->pixmap(size, mode, state);
+ }
- return QPixmap();
+ return QPixmap();
}
QString QIconLoaderEngineFixed::key() const
{
- return QLatin1String("QIconLoaderEngineFixed");
+ return QLatin1String("QIconLoaderEngineFixed");
}
void QIconLoaderEngineFixed::virtual_hook(int id, void *data)
{
- ensureLoaded();
-
- switch (id)
- {
- case QIconEngine::AvailableSizesHook:
- {
- QIconEngine::AvailableSizesArgument &arg =
- *reinterpret_cast<QIconEngine::AvailableSizesArgument *>(data);
- const int N = m_entries.size();
- QList<QSize> sizes;
- sizes.reserve(N);
-
- // Gets all sizes from the DirectoryInfo entries
- for (int i = 0; i < N; ++i)
- {
- int size = m_entries.at(i)->dir.size;
- sizes.append(QSize(size, size));
- }
- arg.sizes.swap(sizes); // commit
- }
- break;
- case QIconEngine::IconNameHook:
- {
- QString &name = *reinterpret_cast<QString *>(data);
- name = m_iconName;
- }
- break;
- default:
- QIconEngine::virtual_hook(id, data);
- }
+ ensureLoaded();
+
+ switch (id)
+ {
+ case QIconEngine::AvailableSizesHook:
+ {
+ QIconEngine::AvailableSizesArgument &arg =
+ *reinterpret_cast<QIconEngine::AvailableSizesArgument *>(data);
+ const int N = m_entries.size();
+ QList<QSize> sizes;
+ sizes.reserve(N);
+
+ // Gets all sizes from the DirectoryInfo entries
+ for (int i = 0; i < N; ++i)
+ {
+ int size = m_entries.at(i)->dir.size;
+ sizes.append(QSize(size, size));
+ }
+ arg.sizes.swap(sizes); // commit
+ }
+ break;
+ case QIconEngine::IconNameHook:
+ {
+ QString &name = *reinterpret_cast<QString *>(data);
+ name = m_iconName;
+ }
+ break;
+ default:
+ QIconEngine::virtual_hook(id, data);
+ }
}
} // QtXdg
diff --git a/libraries/iconfix/internal/qiconloader_p.h b/libraries/iconfix/internal/qiconloader_p.h
index b71bdd83..e45a08d6 100644
--- a/libraries/iconfix/internal/qiconloader_p.h
+++ b/libraries/iconfix/internal/qiconloader_p.h
@@ -61,46 +61,46 @@ class QIconLoader;
struct QIconDirInfo
{
- enum Type
- {
- Fixed,
- Scalable,
- Threshold
- };
- QIconDirInfo(const QString &_path = QString())
- : path(_path), size(0), maxSize(0), minSize(0), threshold(0), type(Threshold)
- {
- }
- QString path;
- short size;
- short maxSize;
- short minSize;
- short threshold;
- Type type : 4;
+ enum Type
+ {
+ Fixed,
+ Scalable,
+ Threshold
+ };
+ QIconDirInfo(const QString &_path = QString())
+ : path(_path), size(0), maxSize(0), minSize(0), threshold(0), type(Threshold)
+ {
+ }
+ QString path;
+ short size;
+ short maxSize;
+ short minSize;
+ short threshold;
+ Type type : 4;
};
class QIconLoaderEngineEntry
{
public:
- virtual ~QIconLoaderEngineEntry()
- {
- }
- virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) = 0;
- QString filename;
- QIconDirInfo dir;
- static int count;
+ virtual ~QIconLoaderEngineEntry()
+ {
+ }
+ virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) = 0;
+ QString filename;
+ QIconDirInfo dir;
+ static int count;
};
struct ScalableEntry : public QIconLoaderEngineEntry
{
- QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE;
- QIcon svgIcon;
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE;
+ QIcon svgIcon;
};
struct PixmapEntry : public QIconLoaderEngineEntry
{
- QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE;
- QPixmap basePixmap;
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE;
+ QPixmap basePixmap;
};
typedef QList<QIconLoaderEngineEntry *> QThemeIconEntries;
@@ -109,107 +109,107 @@ typedef QList<QIconLoaderEngineEntry *> QThemeIconEntries;
class QIconLoaderEngineFixed : public QIconEngine
{
public:
- QIconLoaderEngineFixed(const QString &iconName = QString());
- ~QIconLoaderEngineFixed();
+ QIconLoaderEngineFixed(const QString &iconName = QString());
+ ~QIconLoaderEngineFixed();
- void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
- QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QIconEngine *clone() const;
- bool read(QDataStream &in);
- bool write(QDataStream &out) const;
+ void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QIconEngine *clone() const;
+ bool read(QDataStream &in);
+ bool write(QDataStream &out) const;
private:
- QString key() const;
- bool hasIcon() const;
- void ensureLoaded();
- void virtual_hook(int id, void *data);
- QIconLoaderEngineEntry *entryForSize(const QSize &size);
- QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other);
- QThemeIconEntries m_entries;
- QString m_iconName;
- uint m_key;
-
- friend class QIconLoader;
+ QString key() const;
+ bool hasIcon() const;
+ void ensureLoaded();
+ void virtual_hook(int id, void *data);
+ QIconLoaderEngineEntry *entryForSize(const QSize &size);
+ QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other);
+ QThemeIconEntries m_entries;
+ QString m_iconName;
+ uint m_key;
+
+ friend class QIconLoader;
};
class QIconTheme
{
public:
- QIconTheme(const QString &name);
- QIconTheme() : m_valid(false)
- {
- }
- QStringList parents()
- {
- return m_parents;
- }
- QVector<QIconDirInfo> keyList()
- {
- return m_keyList;
- }
- QString contentDir()
- {
- return m_contentDir;
- }
- QStringList contentDirs()
- {
- return m_contentDirs;
- }
- bool isValid()
- {
- return m_valid;
- }
+ QIconTheme(const QString &name);
+ QIconTheme() : m_valid(false)
+ {
+ }
+ QStringList parents()
+ {
+ return m_parents;
+ }
+ QVector<QIconDirInfo> keyList()
+ {
+ return m_keyList;
+ }
+ QString contentDir()
+ {
+ return m_contentDir;
+ }
+ QStringList contentDirs()
+ {
+ return m_contentDirs;
+ }
+ bool isValid()
+ {
+ return m_valid;
+ }
private:
- QString m_contentDir;
- QStringList m_contentDirs;
- QVector<QIconDirInfo> m_keyList;
- QStringList m_parents;
- bool m_valid;
+ QString m_contentDir;
+ QStringList m_contentDirs;
+ QVector<QIconDirInfo> m_keyList;
+ QStringList m_parents;
+ bool m_valid;
};
class QIconLoader
{
public:
- QIconLoader();
- QThemeIconEntries loadIcon(const QString &iconName) const;
- uint themeKey() const
- {
- return m_themeKey;
- }
-
- QString themeName() const
- {
- return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme;
- }
- void setThemeName(const QString &themeName);
- QIconTheme theme()
- {
- return themeList.value(themeName());
- }
- void setThemeSearchPath(const QStringList &searchPaths);
- QStringList themeSearchPaths() const;
- QIconDirInfo dirInfo(int dirindex);
- static QIconLoader *instance();
- void updateSystemTheme();
- void invalidateKey()
- {
- m_themeKey++;
- }
- void ensureInitialized();
+ QIconLoader();
+ QThemeIconEntries loadIcon(const QString &iconName) const;
+ uint themeKey() const
+ {
+ return m_themeKey;
+ }
+
+ QString themeName() const
+ {
+ return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme;
+ }
+ void setThemeName(const QString &themeName);
+ QIconTheme theme()
+ {
+ return themeList.value(themeName());
+ }
+ void setThemeSearchPath(const QStringList &searchPaths);
+ QStringList themeSearchPaths() const;
+ QIconDirInfo dirInfo(int dirindex);
+ static QIconLoader *instance();
+ void updateSystemTheme();
+ void invalidateKey()
+ {
+ m_themeKey++;
+ }
+ void ensureInitialized();
private:
- QThemeIconEntries findIconHelper(const QString &themeName, const QString &iconName,
- QStringList &visited) const;
- uint m_themeKey;
- bool m_supportsSvg;
- bool m_initialized;
-
- mutable QString m_userTheme;
- mutable QString m_systemTheme;
- mutable QStringList m_iconDirs;
- mutable QHash<QString, QIconTheme> themeList;
+ QThemeIconEntries findIconHelper(const QString &themeName, const QString &iconName,
+ QStringList &visited) const;
+ uint m_themeKey;
+ bool m_supportsSvg;
+ bool m_initialized;
+
+ mutable QString m_userTheme;
+ mutable QString m_systemTheme;
+ mutable QStringList m_iconDirs;
+ mutable QHash<QString, QIconTheme> themeList;
};
} // QtXdg
diff --git a/libraries/iconfix/xdgicon.cpp b/libraries/iconfix/xdgicon.cpp
index 84665a7d..36fb7d42 100644
--- a/libraries/iconfix/xdgicon.cpp
+++ b/libraries/iconfix/xdgicon.cpp
@@ -46,17 +46,17 @@ namespace
{
struct QtIconCache : public IconCache
{
- QtIconCache()
- {
- qAddPostRoutine(qt_cleanup_icon_cache);
- }
+ QtIconCache()
+ {
+ qAddPostRoutine(qt_cleanup_icon_cache);
+ }
};
}
Q_GLOBAL_STATIC(IconCache, qtIconCache)
static void qt_cleanup_icon_cache()
{
- qtIconCache()->clear();
+ qtIconCache()->clear();
}
/************************************************
@@ -78,7 +78,7 @@ XdgIcon::~XdgIcon()
************************************************/
QString XdgIcon::themeName()
{
- return QIcon::themeName();
+ return QIcon::themeName();
}
/************************************************
@@ -86,8 +86,8 @@ QString XdgIcon::themeName()
************************************************/
void XdgIcon::setThemeName(const QString &themeName)
{
- QIcon::setThemeName(themeName);
- QtXdg::QIconLoader::instance()->updateSystemTheme();
+ QIcon::setThemeName(themeName);
+ QtXdg::QIconLoader::instance()->updateSystemTheme();
}
/************************************************
@@ -96,43 +96,43 @@ void XdgIcon::setThemeName(const QString &themeName)
************************************************/
QIcon XdgIcon::fromTheme(const QString &iconName, const QIcon &fallback)
{
- if (iconName.isEmpty())
- return fallback;
-
- bool isAbsolute = (iconName[0] == '/');
-
- QString name = QFileInfo(iconName).fileName();
- if (name.endsWith(".png", Qt::CaseInsensitive) ||
- name.endsWith(".svg", Qt::CaseInsensitive) ||
- name.endsWith(".xpm", Qt::CaseInsensitive))
- {
- name.truncate(name.length() - 4);
- }
-
- QIcon icon;
-
- if (qtIconCache()->contains(name))
- {
- icon = *qtIconCache()->object(name);
- }
- else
- {
- QIcon *cachedIcon;
- if (!isAbsolute)
- cachedIcon = new QIcon(new QtXdg::QIconLoaderEngineFixed(name));
- else
- cachedIcon = new QIcon(iconName);
- qtIconCache()->insert(name, cachedIcon);
- icon = *cachedIcon;
- }
-
- // Note the qapp check is to allow lazy loading of static icons
- // Supporting fallbacks will not work for this case.
- if (qApp && !isAbsolute && icon.availableSizes().isEmpty())
- {
- return fallback;
- }
- return icon;
+ if (iconName.isEmpty())
+ return fallback;
+
+ bool isAbsolute = (iconName[0] == '/');
+
+ QString name = QFileInfo(iconName).fileName();
+ if (name.endsWith(".png", Qt::CaseInsensitive) ||
+ name.endsWith(".svg", Qt::CaseInsensitive) ||
+ name.endsWith(".xpm", Qt::CaseInsensitive))
+ {
+ name.truncate(name.length() - 4);
+ }
+
+ QIcon icon;
+
+ if (qtIconCache()->contains(name))
+ {
+ icon = *qtIconCache()->object(name);
+ }
+ else
+ {
+ QIcon *cachedIcon;
+ if (!isAbsolute)
+ cachedIcon = new QIcon(new QtXdg::QIconLoaderEngineFixed(name));
+ else
+ cachedIcon = new QIcon(iconName);
+ qtIconCache()->insert(name, cachedIcon);
+ icon = *cachedIcon;
+ }
+
+ // Note the qapp check is to allow lazy loading of static icons
+ // Supporting fallbacks will not work for this case.
+ if (qApp && !isAbsolute && icon.availableSizes().isEmpty())
+ {
+ return fallback;
+ }
+ return icon;
}
/************************************************
@@ -141,12 +141,12 @@ QIcon XdgIcon::fromTheme(const QString &iconName, const QIcon &fallback)
************************************************/
QIcon XdgIcon::fromTheme(const QStringList &iconNames, const QIcon &fallback)
{
- foreach (QString iconName, iconNames)
- {
- QIcon icon = fromTheme(iconName);
- if (!icon.isNull())
- return icon;
- }
-
- return fallback;
+ foreach (QString iconName, iconNames)
+ {
+ QIcon icon = fromTheme(iconName);
+ if (!icon.isNull())
+ return icon;
+ }
+
+ return fallback;
}
diff --git a/libraries/iconfix/xdgicon.h b/libraries/iconfix/xdgicon.h
index df8f026e..1380607c 100644
--- a/libraries/iconfix/xdgicon.h
+++ b/libraries/iconfix/xdgicon.h
@@ -36,13 +36,13 @@
class MULTIMC_ICONFIX_EXPORT XdgIcon
{
public:
- static QIcon fromTheme(const QString &iconName, const QIcon &fallback = QIcon());
- static QIcon fromTheme(const QStringList &iconNames, const QIcon &fallback = QIcon());
+ static QIcon fromTheme(const QString &iconName, const QIcon &fallback = QIcon());
+ static QIcon fromTheme(const QStringList &iconNames, const QIcon &fallback = QIcon());
- static QString themeName();
- static void setThemeName(const QString &themeName);
+ static QString themeName();
+ static void setThemeName(const QString &themeName);
protected:
- explicit XdgIcon();
- virtual ~XdgIcon();
+ explicit XdgIcon();
+ virtual ~XdgIcon();
};
diff --git a/libraries/javacheck/CMakeLists.txt b/libraries/javacheck/CMakeLists.txt
index 381efe08..dba5a1ae 100644
--- a/libraries/javacheck/CMakeLists.txt
+++ b/libraries/javacheck/CMakeLists.txt
@@ -7,7 +7,7 @@ set(CMAKE_JAVA_JAR_ENTRY_POINT JavaCheck)
set(CMAKE_JAVA_COMPILE_FLAGS -target 1.6 -source 1.6 -Xlint:deprecation -Xlint:unchecked)
set(SRC
- JavaCheck.java
+ JavaCheck.java
)
add_jar(JavaCheck ${SRC})
diff --git a/libraries/javacheck/JavaCheck.java b/libraries/javacheck/JavaCheck.java
index 11420b86..69933040 100644
--- a/libraries/javacheck/JavaCheck.java
+++ b/libraries/javacheck/JavaCheck.java
@@ -2,23 +2,23 @@ import java.lang.Integer;
public class JavaCheck
{
- private static final String[] keys = {"os.arch", "java.version"};
- public static void main (String [] args)
- {
- int ret = 0;
- for(String key : keys)
- {
- String property = System.getProperty(key);
- if(property != null)
- {
- System.out.println(key + "=" + property);
- }
- else
- {
- ret = 1;
- }
- }
-
- System.exit(ret);
- }
+ private static final String[] keys = {"os.arch", "java.version"};
+ public static void main (String [] args)
+ {
+ int ret = 0;
+ for(String key : keys)
+ {
+ String property = System.getProperty(key);
+ if(property != null)
+ {
+ System.out.println(key + "=" + property);
+ }
+ else
+ {
+ ret = 1;
+ }
+ }
+
+ System.exit(ret);
+ }
}
diff --git a/libraries/launcher/CMakeLists.txt b/libraries/launcher/CMakeLists.txt
index a4f52edb..a64c601d 100644
--- a/libraries/launcher/CMakeLists.txt
+++ b/libraries/launcher/CMakeLists.txt
@@ -7,15 +7,15 @@ set(CMAKE_JAVA_JAR_ENTRY_POINT org.multimc.EntryPoint)
set(CMAKE_JAVA_COMPILE_FLAGS -target 1.6 -source 1.6 -Xlint:deprecation -Xlint:unchecked)
set(SRC
- org/multimc/EntryPoint.java
- org/multimc/Launcher.java
- org/multimc/LegacyFrame.java
- org/multimc/NotFoundException.java
- org/multimc/ParamBucket.java
- org/multimc/ParseException.java
- org/multimc/Utils.java
- org/multimc/onesix/OneSixLauncher.java
- net/minecraft/Launcher.java
+ org/multimc/EntryPoint.java
+ org/multimc/Launcher.java
+ org/multimc/LegacyFrame.java
+ org/multimc/NotFoundException.java
+ org/multimc/ParamBucket.java
+ org/multimc/ParseException.java
+ org/multimc/Utils.java
+ org/multimc/onesix/OneSixLauncher.java
+ net/minecraft/Launcher.java
)
add_jar(NewLaunch ${SRC})
install_jar(NewLaunch "${JARS_DEST_DIR}")
diff --git a/libraries/launcher/net/minecraft/Launcher.java b/libraries/launcher/net/minecraft/Launcher.java
index 0c991cf5..0a4bebcd 100644
--- a/libraries/launcher/net/minecraft/Launcher.java
+++ b/libraries/launcher/net/minecraft/Launcher.java
@@ -28,138 +28,138 @@ import java.net.MalformedURLException;
public class Launcher extends Applet implements AppletStub
{
- private Applet wrappedApplet;
- private URL documentBase;
- private boolean active = false;
- private final Map<String, String> params;
-
- public Launcher(Applet applet, URL documentBase)
- {
- params = new TreeMap<String, String>();
-
- this.setLayout(new BorderLayout());
- this.add(applet, "Center");
- this.wrappedApplet = applet;
- this.documentBase = documentBase;
- }
-
- public void setParameter(String name, String value)
- {
- params.put(name, value);
- }
-
- public void replace(Applet applet)
- {
- this.wrappedApplet = applet;
-
- applet.setStub(this);
- applet.setSize(getWidth(), getHeight());
-
- this.setLayout(new BorderLayout());
- this.add(applet, "Center");
-
- applet.init();
- active = true;
- applet.start();
- validate();
- }
-
- @Override
- public String getParameter(String name)
- {
- String param = params.get(name);
- if (param != null)
- return param;
- try
- {
- return super.getParameter(name);
- } catch (Exception ignore){}
- return null;
- }
-
- @Override
- public boolean isActive()
- {
- return active;
- }
-
- @Override
- public void appletResize(int width, int height)
- {
- wrappedApplet.resize(width, height);
- }
-
- @Override
- public void resize(int width, int height)
- {
- wrappedApplet.resize(width, height);
- }
-
- @Override
- public void resize(Dimension d)
- {
- wrappedApplet.resize(d);
- }
-
- @Override
- public void init()
- {
- if (wrappedApplet != null)
- {
- wrappedApplet.init();
- }
- }
-
- @Override
- public void start()
- {
- wrappedApplet.start();
- active = true;
- }
-
- @Override
- public void stop()
- {
- wrappedApplet.stop();
- active = false;
- }
-
- public void destroy()
- {
- wrappedApplet.destroy();
- }
-
- @Override
- public URL getCodeBase() {
- try {
- return new URL("http://www.minecraft.net/game/");
- } catch (MalformedURLException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- @Override
- public URL getDocumentBase()
- {
- try {
- return new URL("http://www.minecraft.net/game/");
- } catch (MalformedURLException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- @Override
- public void setVisible(boolean b)
- {
- super.setVisible(b);
- wrappedApplet.setVisible(b);
- }
- public void update(Graphics paramGraphics)
- {
- }
- public void paint(Graphics paramGraphics)
- {
- }
+ private Applet wrappedApplet;
+ private URL documentBase;
+ private boolean active = false;
+ private final Map<String, String> params;
+
+ public Launcher(Applet applet, URL documentBase)
+ {
+ params = new TreeMap<String, String>();
+
+ this.setLayout(new BorderLayout());
+ this.add(applet, "Center");
+ this.wrappedApplet = applet;
+ this.documentBase = documentBase;
+ }
+
+ public void setParameter(String name, String value)
+ {
+ params.put(name, value);
+ }
+
+ public void replace(Applet applet)
+ {
+ this.wrappedApplet = applet;
+
+ applet.setStub(this);
+ applet.setSize(getWidth(), getHeight());
+
+ this.setLayout(new BorderLayout());
+ this.add(applet, "Center");
+
+ applet.init();
+ active = true;
+ applet.start();
+ validate();
+ }
+
+ @Override
+ public String getParameter(String name)
+ {
+ String param = params.get(name);
+ if (param != null)
+ return param;
+ try
+ {
+ return super.getParameter(name);
+ } catch (Exception ignore){}
+ return null;
+ }
+
+ @Override
+ public boolean isActive()
+ {
+ return active;
+ }
+
+ @Override
+ public void appletResize(int width, int height)
+ {
+ wrappedApplet.resize(width, height);
+ }
+
+ @Override
+ public void resize(int width, int height)
+ {
+ wrappedApplet.resize(width, height);
+ }
+
+ @Override
+ public void resize(Dimension d)
+ {
+ wrappedApplet.resize(d);
+ }
+
+ @Override
+ public void init()
+ {
+ if (wrappedApplet != null)
+ {
+ wrappedApplet.init();
+ }
+ }
+
+ @Override
+ public void start()
+ {
+ wrappedApplet.start();
+ active = true;
+ }
+
+ @Override
+ public void stop()
+ {
+ wrappedApplet.stop();
+ active = false;
+ }
+
+ public void destroy()
+ {
+ wrappedApplet.destroy();
+ }
+
+ @Override
+ public URL getCodeBase() {
+ try {
+ return new URL("http://www.minecraft.net/game/");
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public URL getDocumentBase()
+ {
+ try {
+ return new URL("http://www.minecraft.net/game/");
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public void setVisible(boolean b)
+ {
+ super.setVisible(b);
+ wrappedApplet.setVisible(b);
+ }
+ public void update(Graphics paramGraphics)
+ {
+ }
+ public void paint(Graphics paramGraphics)
+ {
+ }
} \ No newline at end of file
diff --git a/libraries/launcher/org/multimc/EntryPoint.java b/libraries/launcher/org/multimc/EntryPoint.java
index 8c9b8074..c4ae2a86 100644
--- a/libraries/launcher/org/multimc/EntryPoint.java
+++ b/libraries/launcher/org/multimc/EntryPoint.java
@@ -21,131 +21,131 @@ import java.nio.charset.Charset;
public class EntryPoint
{
- private enum Action
- {
- Proceed,
- Launch,
- Abort
- }
+ private enum Action
+ {
+ Proceed,
+ Launch,
+ Abort
+ }
- public static void main(String[] args)
- {
- EntryPoint listener = new EntryPoint();
- int retCode = listener.listen();
- if (retCode != 0)
- {
- System.out.println("Exiting with " + retCode);
- System.exit(retCode);
- }
- }
+ public static void main(String[] args)
+ {
+ EntryPoint listener = new EntryPoint();
+ int retCode = listener.listen();
+ if (retCode != 0)
+ {
+ System.out.println("Exiting with " + retCode);
+ System.exit(retCode);
+ }
+ }
- private Action parseLine(String inData) throws ParseException
- {
- String[] pair = inData.split(" ", 2);
+ private Action parseLine(String inData) throws ParseException
+ {
+ String[] pair = inData.split(" ", 2);
- if(pair.length == 1)
- {
- String command = pair[0];
- if (pair[0].equals("launch"))
- return Action.Launch;
+ if(pair.length == 1)
+ {
+ String command = pair[0];
+ if (pair[0].equals("launch"))
+ return Action.Launch;
- else if (pair[0].equals("abort"))
- return Action.Abort;
+ else if (pair[0].equals("abort"))
+ return Action.Abort;
- else throw new ParseException();
- }
+ else throw new ParseException();
+ }
- if(pair.length != 2)
- throw new ParseException();
+ if(pair.length != 2)
+ throw new ParseException();
- String command = pair[0];
- String param = pair[1];
+ String command = pair[0];
+ String param = pair[1];
- if(command.equals("launcher"))
- {
- if(param.equals("onesix"))
- {
- m_launcher = new OneSixLauncher();
- Utils.log("Using onesix launcher.");
- Utils.log();
- return Action.Proceed;
- }
- else
- throw new ParseException();
- }
+ if(command.equals("launcher"))
+ {
+ if(param.equals("onesix"))
+ {
+ m_launcher = new OneSixLauncher();
+ Utils.log("Using onesix launcher.");
+ Utils.log();
+ return Action.Proceed;
+ }
+ else
+ throw new ParseException();
+ }
- m_params.add(command, param);
- //System.out.println(command + " : " + param);
- return Action.Proceed;
- }
+ m_params.add(command, param);
+ //System.out.println(command + " : " + param);
+ return Action.Proceed;
+ }
- public int listen()
- {
- BufferedReader buffer;
- try
- {
- buffer = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
- } catch (UnsupportedEncodingException e)
- {
- System.err.println("For some reason, your java does not support UTF-8. Consider living in the current century.");
- e.printStackTrace();
- return 1;
- }
- boolean isListening = true;
- boolean isAborted = false;
- // Main loop
- while (isListening)
- {
- String inData;
- try
- {
- // Read from the pipe one line at a time
- inData = buffer.readLine();
- if (inData != null)
- {
- Action a = parseLine(inData);
- if(a == Action.Abort)
- {
- isListening = false;
- isAborted = true;
- }
- if(a == Action.Launch)
- {
- isListening = false;
- }
- }
- else
- {
- isListening = false;
- isAborted = true;
- }
- }
- catch (IOException e)
- {
- System.err.println("Launcher ABORT due to IO exception:");
- e.printStackTrace();
- return 1;
- }
- catch (ParseException e)
- {
- System.err.println("Launcher ABORT due to PARSE exception:");
- e.printStackTrace();
- return 1;
- }
- }
- if(isAborted)
- {
- System.err.println("Launch aborted by MultiMC.");
- return 1;
- }
- if(m_launcher != null)
- {
- return m_launcher.launch(m_params);
- }
- System.err.println("No valid launcher implementation specified.");
- return 1;
- }
+ public int listen()
+ {
+ BufferedReader buffer;
+ try
+ {
+ buffer = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
+ } catch (UnsupportedEncodingException e)
+ {
+ System.err.println("For some reason, your java does not support UTF-8. Consider living in the current century.");
+ e.printStackTrace();
+ return 1;
+ }
+ boolean isListening = true;
+ boolean isAborted = false;
+ // Main loop
+ while (isListening)
+ {
+ String inData;
+ try
+ {
+ // Read from the pipe one line at a time
+ inData = buffer.readLine();
+ if (inData != null)
+ {
+ Action a = parseLine(inData);
+ if(a == Action.Abort)
+ {
+ isListening = false;
+ isAborted = true;
+ }
+ if(a == Action.Launch)
+ {
+ isListening = false;
+ }
+ }
+ else
+ {
+ isListening = false;
+ isAborted = true;
+ }
+ }
+ catch (IOException e)
+ {
+ System.err.println("Launcher ABORT due to IO exception:");
+ e.printStackTrace();
+ return 1;
+ }
+ catch (ParseException e)
+ {
+ System.err.println("Launcher ABORT due to PARSE exception:");
+ e.printStackTrace();
+ return 1;
+ }
+ }
+ if(isAborted)
+ {
+ System.err.println("Launch aborted by MultiMC.");
+ return 1;
+ }
+ if(m_launcher != null)
+ {
+ return m_launcher.launch(m_params);
+ }
+ System.err.println("No valid launcher implementation specified.");
+ return 1;
+ }
- private ParamBucket m_params = new ParamBucket();
- private org.multimc.Launcher m_launcher;
+ private ParamBucket m_params = new ParamBucket();
+ private org.multimc.Launcher m_launcher;
}
diff --git a/libraries/launcher/org/multimc/Launcher.java b/libraries/launcher/org/multimc/Launcher.java
index 2e851d18..d19ef7b2 100644
--- a/libraries/launcher/org/multimc/Launcher.java
+++ b/libraries/launcher/org/multimc/Launcher.java
@@ -18,5 +18,5 @@ package org.multimc;
public interface Launcher
{
- abstract int launch(ParamBucket params);
+ abstract int launch(ParamBucket params);
}
diff --git a/libraries/launcher/org/multimc/ParamBucket.java b/libraries/launcher/org/multimc/ParamBucket.java
index 5e9c3ff6..e198706b 100644
--- a/libraries/launcher/org/multimc/ParamBucket.java
+++ b/libraries/launcher/org/multimc/ParamBucket.java
@@ -22,65 +22,65 @@ import java.util.List;
public class ParamBucket
{
- public void add(String key, String value)
- {
- List<String> coll = null;
- if(!m_params.containsKey(key))
- {
- coll = new ArrayList<String>();
- m_params.put(key, coll);
- }
- else
- {
- coll = m_params.get(key);
- }
- coll.add(value);
- }
+ public void add(String key, String value)
+ {
+ List<String> coll = null;
+ if(!m_params.containsKey(key))
+ {
+ coll = new ArrayList<String>();
+ m_params.put(key, coll);
+ }
+ else
+ {
+ coll = m_params.get(key);
+ }
+ coll.add(value);
+ }
- public List<String> all(String key) throws NotFoundException
- {
- if(!m_params.containsKey(key))
- throw new NotFoundException();
- return m_params.get(key);
- }
+ public List<String> all(String key) throws NotFoundException
+ {
+ if(!m_params.containsKey(key))
+ throw new NotFoundException();
+ return m_params.get(key);
+ }
- public List<String> allSafe(String key, List<String> def)
- {
- if(!m_params.containsKey(key) || m_params.get(key).size() < 1)
- {
- return def;
- }
- return m_params.get(key);
- }
+ public List<String> allSafe(String key, List<String> def)
+ {
+ if(!m_params.containsKey(key) || m_params.get(key).size() < 1)
+ {
+ return def;
+ }
+ return m_params.get(key);
+ }
- public List<String> allSafe(String key)
- {
- return allSafe(key, new ArrayList<String>());
- }
+ public List<String> allSafe(String key)
+ {
+ return allSafe(key, new ArrayList<String>());
+ }
- public String first(String key) throws NotFoundException
- {
- List<String> list = all(key);
- if(list.size() < 1)
- {
- throw new NotFoundException();
- }
- return list.get(0);
- }
+ public String first(String key) throws NotFoundException
+ {
+ List<String> list = all(key);
+ if(list.size() < 1)
+ {
+ throw new NotFoundException();
+ }
+ return list.get(0);
+ }
- public String firstSafe(String key, String def)
- {
- if(!m_params.containsKey(key) || m_params.get(key).size() < 1)
- {
- return def;
- }
- return m_params.get(key).get(0);
- }
+ public String firstSafe(String key, String def)
+ {
+ if(!m_params.containsKey(key) || m_params.get(key).size() < 1)
+ {
+ return def;
+ }
+ return m_params.get(key).get(0);
+ }
- public String firstSafe(String key)
- {
- return firstSafe(key, "");
- }
+ public String firstSafe(String key)
+ {
+ return firstSafe(key, "");
+ }
- private HashMap<String, List<String>> m_params = new HashMap<String, List<String>>();
+ private HashMap<String, List<String>> m_params = new HashMap<String, List<String>>();
}
diff --git a/libraries/launcher/org/multimc/Utils.java b/libraries/launcher/org/multimc/Utils.java
index c5292eaf..d6f254a1 100644
--- a/libraries/launcher/org/multimc/Utils.java
+++ b/libraries/launcher/org/multimc/Utils.java
@@ -34,86 +34,86 @@ import java.util.zip.ZipFile;
public class Utils
{
- /**
- * Combine two parts of a path.
- *
- * @param path1
- * @param path2
- * @return the paths, combined
- */
- public static String combine(String path1, String path2)
- {
- File file1 = new File(path1);
- File file2 = new File(file1, path2);
- return file2.getPath();
- }
+ /**
+ * Combine two parts of a path.
+ *
+ * @param path1
+ * @param path2
+ * @return the paths, combined
+ */
+ public static String combine(String path1, String path2)
+ {
+ File file1 = new File(path1);
+ File file2 = new File(file1, path2);
+ return file2.getPath();
+ }
- /**
- * Join a list of strings into a string using a separator!
- *
- * @param strings the string list to join
- * @param separator the glue
- * @return the result.
- */
- public static String join(List<String> strings, String separator)
- {
- StringBuilder sb = new StringBuilder();
- String sep = "";
- for (String s : strings)
- {
- sb.append(sep).append(s);
- sep = separator;
- }
- return sb.toString();
- }
+ /**
+ * Join a list of strings into a string using a separator!
+ *
+ * @param strings the string list to join
+ * @param separator the glue
+ * @return the result.
+ */
+ public static String join(List<String> strings, String separator)
+ {
+ StringBuilder sb = new StringBuilder();
+ String sep = "";
+ for (String s : strings)
+ {
+ sb.append(sep).append(s);
+ sep = separator;
+ }
+ return sb.toString();
+ }
- /**
- * Finds a field that looks like a Minecraft base folder in a supplied class
- *
- * @param mc the class to scan
- */
- public static Field getMCPathField(Class<?> mc)
- {
- Field[] fields = mc.getDeclaredFields();
+ /**
+ * Finds a field that looks like a Minecraft base folder in a supplied class
+ *
+ * @param mc the class to scan
+ */
+ public static Field getMCPathField(Class<?> mc)
+ {
+ Field[] fields = mc.getDeclaredFields();
- for (Field f : fields)
- {
- if (f.getType() != File.class)
- {
- // Has to be File
- continue;
- }
- if (f.getModifiers() != (Modifier.PRIVATE + Modifier.STATIC))
- {
- // And Private Static.
- continue;
- }
- return f;
- }
- return null;
- }
+ for (Field f : fields)
+ {
+ if (f.getType() != File.class)
+ {
+ // Has to be File
+ continue;
+ }
+ if (f.getModifiers() != (Modifier.PRIVATE + Modifier.STATIC))
+ {
+ // And Private Static.
+ continue;
+ }
+ return f;
+ }
+ return null;
+ }
- /**
- * Log to the MultiMC console
- *
- * @param message A String containing the message
- * @param level A String containing the level name. See MinecraftLauncher::getLevel()
- */
- public static void log(String message, String level)
- {
- // Kinda dirty
- String tag = "!![" + level + "]!";
- System.out.println(tag + message.replace("\n", "\n" + tag));
- }
+ /**
+ * Log to the MultiMC console
+ *
+ * @param message A String containing the message
+ * @param level A String containing the level name. See MinecraftLauncher::getLevel()
+ */
+ public static void log(String message, String level)
+ {
+ // Kinda dirty
+ String tag = "!![" + level + "]!";
+ System.out.println(tag + message.replace("\n", "\n" + tag));
+ }
- public static void log(String message)
- {
- log(message, "MultiMC");
- }
+ public static void log(String message)
+ {
+ log(message, "MultiMC");
+ }
- public static void log()
- {
- System.out.println();
- }
+ public static void log()
+ {
+ System.out.println();
+ }
}
diff --git a/libraries/launcher/org/multimc/onesix/OneSixLauncher.java b/libraries/launcher/org/multimc/onesix/OneSixLauncher.java
index 9667297d..48baba2e 100644
--- a/libraries/launcher/org/multimc/onesix/OneSixLauncher.java
+++ b/libraries/launcher/org/multimc/onesix/OneSixLauncher.java
@@ -27,208 +27,208 @@ import java.util.List;
public class OneSixLauncher implements Launcher
{
- // parameters, separated from ParamBucket
- private List<String> libraries;
- private List<String> mcparams;
- private List<String> mods;
- private List<String> jarmods;
- private List<String> coremods;
- private List<String> traits;
- private String appletClass;
- private String mainClass;
- private String nativePath;
- private String userName, sessionId;
- private String windowTitle;
- private String windowParams;
-
- // secondary parameters
- private int winSizeW;
- private int winSizeH;
- private boolean maximize;
- private String cwd;
-
- // the much abused system classloader, for convenience (for further abuse)
- private ClassLoader cl;
-
- private void processParams(ParamBucket params) throws NotFoundException
- {
- libraries = params.all("cp");
- mcparams = params.allSafe("param", new ArrayList<String>() );
- mainClass = params.firstSafe("mainClass", "net.minecraft.client.Minecraft");
- appletClass = params.firstSafe("appletClass", "net.minecraft.client.MinecraftApplet");
- traits = params.allSafe("traits", new ArrayList<String>());
- nativePath = params.first("natives");
-
- userName = params.first("userName");
- sessionId = params.first("sessionId");
- windowTitle = params.firstSafe("windowTitle", "Minecraft");
- windowParams = params.firstSafe("windowParams", "854x480");
-
- cwd = System.getProperty("user.dir");
-
- winSizeW = 854;
- winSizeH = 480;
- maximize = false;
-
- String[] dimStrings = windowParams.split("x");
-
- if (windowParams.equalsIgnoreCase("max"))
- {
- maximize = true;
- }
- else if (dimStrings.length == 2)
- {
- try
- {
- winSizeW = Integer.parseInt(dimStrings[0]);
- winSizeH = Integer.parseInt(dimStrings[1]);
- } catch (NumberFormatException ignored) {}
- }
- }
-
- int legacyLaunch()
- {
- // Get the Minecraft Class and set the base folder
- Class<?> mc;
- try
- {
- mc = cl.loadClass(mainClass);
-
- Field f = Utils.getMCPathField(mc);
-
- if (f == null)
- {
- System.err.println("Could not find Minecraft path field.");
- }
- else
- {
- f.setAccessible(true);
- f.set(null, new File(cwd));
- }
- } catch (Exception e)
- {
- System.err.println("Could not set base folder. Failed to find/access Minecraft main class:");
- e.printStackTrace(System.err);
- return -1;
- }
-
- System.setProperty("minecraft.applet.TargetDirectory", cwd);
-
- if(!traits.contains("noapplet"))
- {
- Utils.log("Launching with applet wrapper...");
- try
- {
- Class<?> MCAppletClass = cl.loadClass(appletClass);
- Applet mcappl = (Applet) MCAppletClass.newInstance();
- LegacyFrame mcWindow = new LegacyFrame(windowTitle);
- mcWindow.start(mcappl, userName, sessionId, winSizeW, winSizeH, maximize);
- return 0;
- } catch (Exception e)
- {
- Utils.log("Applet wrapper failed:", "Error");
- e.printStackTrace(System.err);
- Utils.log();
- Utils.log("Falling back to using main class.");
- }
- }
-
- // init params for the main method to chomp on.
- String[] paramsArray = mcparams.toArray(new String[mcparams.size()]);
- try
- {
- mc.getMethod("main", String[].class).invoke(null, (Object) paramsArray);
- return 0;
- } catch (Exception e)
- {
- Utils.log("Failed to invoke the Minecraft main class:", "Fatal");
- e.printStackTrace(System.err);
- return -1;
- }
- }
-
- int launchWithMainClass()
- {
- // window size, title and state, onesix
- if (maximize)
- {
- // FIXME: there is no good way to maximize the minecraft window in onesix.
- // the following often breaks linux screen setups
- // mcparams.add("--fullscreen");
- }
- else
- {
- mcparams.add("--width");
- mcparams.add(Integer.toString(winSizeW));
- mcparams.add("--height");
- mcparams.add(Integer.toString(winSizeH));
- }
-
- // Get the Minecraft Class.
- Class<?> mc;
- try
- {
- mc = cl.loadClass(mainClass);
- } catch (ClassNotFoundException e)
- {
- System.err.println("Failed to find Minecraft main class:");
- e.printStackTrace(System.err);
- return -1;
- }
-
- // get the main method.
- Method meth;
- try
- {
- meth = mc.getMethod("main", String[].class);
- } catch (NoSuchMethodException e)
- {
- System.err.println("Failed to acquire the main method:");
- e.printStackTrace(System.err);
- return -1;
- }
-
- // init params for the main method to chomp on.
- String[] paramsArray = mcparams.toArray(new String[mcparams.size()]);
- try
- {
- // static method doesn't have an instance
- meth.invoke(null, (Object) paramsArray);
- } catch (Exception e)
- {
- System.err.println("Failed to start Minecraft:");
- e.printStackTrace(System.err);
- return -1;
- }
- return 0;
- }
-
- @Override
- public int launch(ParamBucket params)
- {
- // get and process the launch script params
- try
- {
- processParams(params);
- } catch (NotFoundException e)
- {
- System.err.println("Not enough arguments.");
- e.printStackTrace(System.err);
- return -1;
- }
-
- // grab the system classloader and ...
- cl = ClassLoader.getSystemClassLoader();
-
- if (traits.contains("legacyLaunch") || traits.contains("alphaLaunch") )
- {
- // legacy launch uses the applet wrapper
- return legacyLaunch();
- }
- else
- {
- // normal launch just calls main()
- return launchWithMainClass();
- }
- }
+ // parameters, separated from ParamBucket
+ private List<String> libraries;
+ private List<String> mcparams;
+ private List<String> mods;
+ private List<String> jarmods;
+ private List<String> coremods;
+ private List<String> traits;
+ private String appletClass;
+ private String mainClass;
+ private String nativePath;
+ private String userName, sessionId;
+ private String windowTitle;
+ private String windowParams;
+
+ // secondary parameters
+ private int winSizeW;
+ private int winSizeH;
+ private boolean maximize;
+ private String cwd;
+
+ // the much abused system classloader, for convenience (for further abuse)
+ private ClassLoader cl;
+
+ private void processParams(ParamBucket params) throws NotFoundException
+ {
+ libraries = params.all("cp");
+ mcparams = params.allSafe("param", new ArrayList<String>() );
+ mainClass = params.firstSafe("mainClass", "net.minecraft.client.Minecraft");
+ appletClass = params.firstSafe("appletClass", "net.minecraft.client.MinecraftApplet");
+ traits = params.allSafe("traits", new ArrayList<String>());
+ nativePath = params.first("natives");
+
+ userName = params.first("userName");
+ sessionId = params.first("sessionId");
+ windowTitle = params.firstSafe("windowTitle", "Minecraft");
+ windowParams = params.firstSafe("windowParams", "854x480");
+
+ cwd = System.getProperty("user.dir");
+
+ winSizeW = 854;
+ winSizeH = 480;
+ maximize = false;
+
+ String[] dimStrings = windowParams.split("x");
+
+ if (windowParams.equalsIgnoreCase("max"))
+ {
+ maximize = true;
+ }
+ else if (dimStrings.length == 2)
+ {
+ try
+ {
+ winSizeW = Integer.parseInt(dimStrings[0]);
+ winSizeH = Integer.parseInt(dimStrings[1]);
+ } catch (NumberFormatException ignored) {}
+ }
+ }
+
+ int legacyLaunch()
+ {
+ // Get the Minecraft Class and set the base folder
+ Class<?> mc;
+ try
+ {
+ mc = cl.loadClass(mainClass);
+
+ Field f = Utils.getMCPathField(mc);
+
+ if (f == null)
+ {
+ System.err.println("Could not find Minecraft path field.");
+ }
+ else
+ {
+ f.setAccessible(true);
+ f.set(null, new File(cwd));
+ }
+ } catch (Exception e)
+ {
+ System.err.println("Could not set base folder. Failed to find/access Minecraft main class:");
+ e.printStackTrace(System.err);
+ return -1;
+ }
+
+ System.setProperty("minecraft.applet.TargetDirectory", cwd);
+
+ if(!traits.contains("noapplet"))
+ {
+ Utils.log("Launching with applet wrapper...");
+ try
+ {
+ Class<?> MCAppletClass = cl.loadClass(appletClass);
+ Applet mcappl = (Applet) MCAppletClass.newInstance();
+ LegacyFrame mcWindow = new LegacyFrame(windowTitle);
+ mcWindow.start(mcappl, userName, sessionId, winSizeW, winSizeH, maximize);
+ return 0;
+ } catch (Exception e)
+ {
+ Utils.log("Applet wrapper failed:", "Error");
+ e.printStackTrace(System.err);
+ Utils.log();
+ Utils.log("Falling back to using main class.");
+ }
+ }
+
+ // init params for the main method to chomp on.
+ String[] paramsArray = mcparams.toArray(new String[mcparams.size()]);
+ try
+ {
+ mc.getMethod("main", String[].class).invoke(null, (Object) paramsArray);
+ return 0;
+ } catch (Exception e)
+ {
+ Utils.log("Failed to invoke the Minecraft main class:", "Fatal");
+ e.printStackTrace(System.err);
+ return -1;
+ }
+ }
+
+ int launchWithMainClass()
+ {
+ // window size, title and state, onesix
+ if (maximize)
+ {
+ // FIXME: there is no good way to maximize the minecraft window in onesix.
+ // the following often breaks linux screen setups
+ // mcparams.add("--fullscreen");
+ }
+ else
+ {
+ mcparams.add("--width");
+ mcparams.add(Integer.toString(winSizeW));
+ mcparams.add("--height");
+ mcparams.add(Integer.toString(winSizeH));
+ }
+
+ // Get the Minecraft Class.
+ Class<?> mc;
+ try
+ {
+ mc = cl.loadClass(mainClass);
+ } catch (ClassNotFoundException e)
+ {
+ System.err.println("Failed to find Minecraft main class:");
+ e.printStackTrace(System.err);
+ return -1;
+ }
+
+ // get the main method.
+ Method meth;
+ try
+ {
+ meth = mc.getMethod("main", String[].class);
+ } catch (NoSuchMethodException e)
+ {
+ System.err.println("Failed to acquire the main method:");
+ e.printStackTrace(System.err);
+ return -1;
+ }
+
+ // init params for the main method to chomp on.
+ String[] paramsArray = mcparams.toArray(new String[mcparams.size()]);
+ try
+ {
+ // static method doesn't have an instance
+ meth.invoke(null, (Object) paramsArray);
+ } catch (Exception e)
+ {
+ System.err.println("Failed to start Minecraft:");
+ e.printStackTrace(System.err);
+ return -1;
+ }
+ return 0;
+ }
+
+ @Override
+ public int launch(ParamBucket params)
+ {
+ // get and process the launch script params
+ try
+ {
+ processParams(params);
+ } catch (NotFoundException e)
+ {
+ System.err.println("Not enough arguments.");
+ e.printStackTrace(System.err);
+ return -1;
+ }
+
+ // grab the system classloader and ...
+ cl = ClassLoader.getSystemClassLoader();
+
+ if (traits.contains("legacyLaunch") || traits.contains("alphaLaunch") )
+ {
+ // legacy launch uses the applet wrapper
+ return legacyLaunch();
+ }
+ else
+ {
+ // normal launch just calls main()
+ return launchWithMainClass();
+ }
+ }
}
diff --git a/libraries/pack200/CMakeLists.txt b/libraries/pack200/CMakeLists.txt
index b568e506..31eb0f73 100644
--- a/libraries/pack200/CMakeLists.txt
+++ b/libraries/pack200/CMakeLists.txt
@@ -8,22 +8,22 @@ option(PACK200_BUILD_BINARY "Build a tiny utility that decompresses pack200 stre
find_package(ZLIB REQUIRED)
set(PACK200_SRC
- include/unpack200.h
- src/bands.cpp
- src/bands.h
- src/bytes.cpp
- src/bytes.h
- src/coding.cpp
- src/coding.h
- src/constants.h
- src/defines.h
- src/unpack200.cpp
- src/unpack.cpp
- src/unpack.h
- src/utils.cpp
- src/utils.h
- src/zip.cpp
- src/zip.h
+ include/unpack200.h
+ src/bands.cpp
+ src/bands.h
+ src/bytes.cpp
+ src/bytes.h
+ src/coding.cpp
+ src/coding.h
+ src/constants.h
+ src/defines.h
+ src/unpack200.cpp
+ src/unpack.cpp
+ src/unpack.h
+ src/utils.cpp
+ src/utils.h
+ src/zip.cpp
+ src/zip.h
)
if (Qt5_POSITION_INDEPENDENT_CODE)
@@ -39,12 +39,12 @@ generate_export_header(MultiMC_unpack200)
# Install it
install(
- TARGETS MultiMC_unpack200
- RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
- LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
+ TARGETS MultiMC_unpack200
+ RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
+ LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
)
if(PACK200_BUILD_BINARY)
- add_executable(anti200 anti200.cpp)
- target_link_libraries(anti200 MultiMC_unpack200)
+ add_executable(anti200 anti200.cpp)
+ target_link_libraries(anti200 MultiMC_unpack200)
endif()
diff --git a/libraries/pack200/anti200.cpp b/libraries/pack200/anti200.cpp
index 0fa3d3e6..1e672847 100644
--- a/libraries/pack200/anti200.cpp
+++ b/libraries/pack200/anti200.cpp
@@ -8,36 +8,36 @@
int main(int argc, char **argv)
{
- if (argc != 3)
- {
- std::cerr << "Simple pack200 unpacker!" << std::endl << "Run like this:" << std::endl
- << " " << argv[0] << " input.jar.lzma output.jar" << std::endl;
- return EXIT_FAILURE;
- }
+ if (argc != 3)
+ {
+ std::cerr << "Simple pack200 unpacker!" << std::endl << "Run like this:" << std::endl
+ << " " << argv[0] << " input.jar.lzma output.jar" << std::endl;
+ return EXIT_FAILURE;
+ }
- FILE *input = fopen(argv[1], "rb");
- if (!input)
- {
- std::cerr << "Can't open input file";
- return EXIT_FAILURE;
- }
- FILE *output = fopen(argv[2], "wb");
- if (!output)
- {
- fclose(input);
- std::cerr << "Can't open output file";
- return EXIT_FAILURE;
- }
- try
- {
- unpack_200(input, output);
- }
- catch (const std::runtime_error &e)
- {
- std::cerr << "Bad things happened: " << e.what() << std::endl;
- fclose(input);
- fclose(output);
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
+ FILE *input = fopen(argv[1], "rb");
+ if (!input)
+ {
+ std::cerr << "Can't open input file";
+ return EXIT_FAILURE;
+ }
+ FILE *output = fopen(argv[2], "wb");
+ if (!output)
+ {
+ fclose(input);
+ std::cerr << "Can't open output file";
+ return EXIT_FAILURE;
+ }
+ try
+ {
+ unpack_200(input, output);
+ }
+ catch (const std::runtime_error &e)
+ {
+ std::cerr << "Bad things happened: " << e.what() << std::endl;
+ fclose(input);
+ fclose(output);
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
}
diff --git a/libraries/pack200/src/bands.cpp b/libraries/pack200/src/bands.cpp
index 1608d838..e82613b5 100644
--- a/libraries/pack200/src/bands.cpp
+++ b/libraries/pack200/src/bands.cpp
@@ -47,188 +47,188 @@
void band::readData(int expectedLength)
{
- assert(expectedLength >= 0);
- assert(vs[0].cmk == cmk_ERROR);
- if (expectedLength != 0)
- {
- assert(length == 0);
- length = expectedLength;
- }
- if (length == 0)
- {
- assert((rplimit = cm.vs0.rp = u->rp) != nullptr);
- return;
- }
- assert(length > 0);
+ assert(expectedLength >= 0);
+ assert(vs[0].cmk == cmk_ERROR);
+ if (expectedLength != 0)
+ {
+ assert(length == 0);
+ length = expectedLength;
+ }
+ if (length == 0)
+ {
+ assert((rplimit = cm.vs0.rp = u->rp) != nullptr);
+ return;
+ }
+ assert(length > 0);
- bool is_BYTE1 = (defc->spec == BYTE1_spec);
+ bool is_BYTE1 = (defc->spec == BYTE1_spec);
- if (is_BYTE1)
- {
- // No possibility of coding change. Sizing is exact.
- u->ensure_input(length);
- }
- else
- {
- // Make a conservatively generous estimate of band size in bytes.
- // Assume B == 5 everywhere.
- // Assume awkward pop with all {U} values (2*5 per value)
- int64_t generous = (int64_t)length * (B_MAX * 3 + 1) + C_SLOP;
- u->ensure_input(generous);
- }
+ if (is_BYTE1)
+ {
+ // No possibility of coding change. Sizing is exact.
+ u->ensure_input(length);
+ }
+ else
+ {
+ // Make a conservatively generous estimate of band size in bytes.
+ // Assume B == 5 everywhere.
+ // Assume awkward pop with all {U} values (2*5 per value)
+ int64_t generous = (int64_t)length * (B_MAX * 3 + 1) + C_SLOP;
+ u->ensure_input(generous);
+ }
- // Read one value to see what it might be.
- int XB = _meta_default;
- if (!is_BYTE1)
- {
- // must be a variable-length coding
- assert(defc->B() > 1 && defc->L() > 0);
+ // Read one value to see what it might be.
+ int XB = _meta_default;
+ if (!is_BYTE1)
+ {
+ // must be a variable-length coding
+ assert(defc->B() > 1 && defc->L() > 0);
- value_stream xvs;
- coding *valc = defc;
- if (valc->D() != 0)
- {
- valc = coding::findBySpec(defc->B(), defc->H(), defc->S());
- assert(!valc->isMalloc);
- }
- xvs.init(u->rp, u->rplimit, valc);
- int X = xvs.getInt();
- if (valc->S() != 0)
- {
- assert(valc->min <= -256);
- XB = -1 - X;
- }
- else
- {
- int L = valc->L();
- assert(valc->max >= L + 255);
- XB = X - L;
- }
- if (0 <= XB && XB < 256)
- {
- // Skip over the escape value.
- u->rp = xvs.rp;
- }
- else
- {
- // No, it's still default.
- XB = _meta_default;
- }
- }
+ value_stream xvs;
+ coding *valc = defc;
+ if (valc->D() != 0)
+ {
+ valc = coding::findBySpec(defc->B(), defc->H(), defc->S());
+ assert(!valc->isMalloc);
+ }
+ xvs.init(u->rp, u->rplimit, valc);
+ int X = xvs.getInt();
+ if (valc->S() != 0)
+ {
+ assert(valc->min <= -256);
+ XB = -1 - X;
+ }
+ else
+ {
+ int L = valc->L();
+ assert(valc->max >= L + 255);
+ XB = X - L;
+ }
+ if (0 <= XB && XB < 256)
+ {
+ // Skip over the escape value.
+ u->rp = xvs.rp;
+ }
+ else
+ {
+ // No, it's still default.
+ XB = _meta_default;
+ }
+ }
- if (XB <= _meta_canon_max)
- {
- byte XB_byte = (byte)XB;
- byte *XB_ptr = &XB_byte;
- cm.init(u->rp, u->rplimit, XB_ptr, 0, defc, length, nullptr);
- }
- else
- {
- assert(u->meta_rp != nullptr);
- // Scribble the initial byte onto the band.
- byte *save_meta_rp = --u->meta_rp;
- byte save_meta_xb = (*save_meta_rp);
- (*save_meta_rp) = (byte)XB;
- cm.init(u->rp, u->rplimit, u->meta_rp, 0, defc, length, nullptr);
- (*save_meta_rp) = save_meta_xb; // put it back, just to be tidy
- }
- rplimit = u->rp;
+ if (XB <= _meta_canon_max)
+ {
+ byte XB_byte = (byte)XB;
+ byte *XB_ptr = &XB_byte;
+ cm.init(u->rp, u->rplimit, XB_ptr, 0, defc, length, nullptr);
+ }
+ else
+ {
+ assert(u->meta_rp != nullptr);
+ // Scribble the initial byte onto the band.
+ byte *save_meta_rp = --u->meta_rp;
+ byte save_meta_xb = (*save_meta_rp);
+ (*save_meta_rp) = (byte)XB;
+ cm.init(u->rp, u->rplimit, u->meta_rp, 0, defc, length, nullptr);
+ (*save_meta_rp) = save_meta_xb; // put it back, just to be tidy
+ }
+ rplimit = u->rp;
- rewind();
+ rewind();
}
void band::setIndex(cpindex *ix_)
{
- assert(ix_ == nullptr || ixTag == ix_->ixTag);
- ix = ix_;
+ assert(ix_ == nullptr || ixTag == ix_->ixTag);
+ ix = ix_;
}
void band::setIndexByTag(byte tag)
{
- setIndex(u->cp.getIndex(tag));
+ setIndex(u->cp.getIndex(tag));
}
entry *band::getRefCommon(cpindex *ix_, bool nullOKwithCaller)
{
- assert(ix_->ixTag == ixTag ||
- (ixTag == CONSTANT_Literal && ix_->ixTag >= CONSTANT_Integer &&
- ix_->ixTag <= CONSTANT_String));
- int n = vs[0].getInt() - nullOK;
- // Note: band-local nullOK means nullptr encodes as 0.
- // But nullOKwithCaller means caller is willing to tolerate a nullptr.
- entry *ref = ix_->get(n);
- if (ref == nullptr && !(nullOKwithCaller && n == -1))
- unpack_abort(n == -1 ? "nullptr ref" : "bad ref");
- return ref;
+ assert(ix_->ixTag == ixTag ||
+ (ixTag == CONSTANT_Literal && ix_->ixTag >= CONSTANT_Integer &&
+ ix_->ixTag <= CONSTANT_String));
+ int n = vs[0].getInt() - nullOK;
+ // Note: band-local nullOK means nullptr encodes as 0.
+ // But nullOKwithCaller means caller is willing to tolerate a nullptr.
+ entry *ref = ix_->get(n);
+ if (ref == nullptr && !(nullOKwithCaller && n == -1))
+ unpack_abort(n == -1 ? "nullptr ref" : "bad ref");
+ return ref;
}
int64_t band::getLong(band &lo_band, bool have_hi)
{
- band &hi_band = (*this);
- assert(lo_band.bn == hi_band.bn + 1);
- uint32_t lo = lo_band.getInt();
- if (!have_hi)
- {
- assert(hi_band.length == 0);
- return makeLong(0, lo);
- }
- uint32_t hi = hi_band.getInt();
- return makeLong(hi, lo);
+ band &hi_band = (*this);
+ assert(lo_band.bn == hi_band.bn + 1);
+ uint32_t lo = lo_band.getInt();
+ if (!have_hi)
+ {
+ assert(hi_band.length == 0);
+ return makeLong(0, lo);
+ }
+ uint32_t hi = hi_band.getInt();
+ return makeLong(hi, lo);
}
int band::getIntTotal()
{
- if (length == 0)
- return 0;
- if (total_memo > 0)
- return total_memo - 1;
- int total = getInt();
- // overflow checks require that none of the addends are <0,
- // and that the partial sums never overflow (wrap negative)
- if (total < 0)
- {
- unpack_abort("overflow detected");
- }
- for (int k = length - 1; k > 0; k--)
- {
- int prev_total = total;
- total += vs[0].getInt();
- if (total < prev_total)
- {
- unpack_abort("overflow detected");
- }
- }
- rewind();
- total_memo = total + 1;
- return total;
+ if (length == 0)
+ return 0;
+ if (total_memo > 0)
+ return total_memo - 1;
+ int total = getInt();
+ // overflow checks require that none of the addends are <0,
+ // and that the partial sums never overflow (wrap negative)
+ if (total < 0)
+ {
+ unpack_abort("overflow detected");
+ }
+ for (int k = length - 1; k > 0; k--)
+ {
+ int prev_total = total;
+ total += vs[0].getInt();
+ if (total < prev_total)
+ {
+ unpack_abort("overflow detected");
+ }
+ }
+ rewind();
+ total_memo = total + 1;
+ return total;
}
int band::getIntCount(int tag)
{
- if (length == 0)
- return 0;
- if (tag >= HIST0_MIN && tag <= HIST0_MAX)
- {
- if (hist0 == nullptr)
- {
- // Lazily calculate an approximate histogram.
- hist0 = U_NEW(int, (HIST0_MAX - HIST0_MIN) + 1);
- for (int k = length; k > 0; k--)
- {
- int x = vs[0].getInt();
- if (x >= HIST0_MIN && x <= HIST0_MAX)
- hist0[x - HIST0_MIN] += 1;
- }
- rewind();
- }
- return hist0[tag - HIST0_MIN];
- }
- int total = 0;
- for (int k = length; k > 0; k--)
- {
- total += (vs[0].getInt() == tag) ? 1 : 0;
- }
- rewind();
- return total;
+ if (length == 0)
+ return 0;
+ if (tag >= HIST0_MIN && tag <= HIST0_MAX)
+ {
+ if (hist0 == nullptr)
+ {
+ // Lazily calculate an approximate histogram.
+ hist0 = U_NEW(int, (HIST0_MAX - HIST0_MIN) + 1);
+ for (int k = length; k > 0; k--)
+ {
+ int x = vs[0].getInt();
+ if (x >= HIST0_MIN && x <= HIST0_MAX)
+ hist0[x - HIST0_MIN] += 1;
+ }
+ rewind();
+ }
+ return hist0[tag - HIST0_MIN];
+ }
+ int total = 0;
+ for (int k = length; k > 0; k--)
+ {
+ total += (vs[0].getInt() == tag) ? 1 : 0;
+ }
+ rewind();
+ return total;
}
#define INDEX_INIT(tag, nullOK, subindex) ((tag) + (subindex) * SUBINDEX_BIT + (nullOK) * 256)
@@ -240,184 +240,184 @@ int band::getIntCount(int tag)
struct band_init
{
- int defc;
- int index;
+ int defc;
+ int index;
};
#define BAND_INIT(name, cspec, ix) \
- { \
- cspec, ix \
- }
+ { \
+ cspec, ix \
+ }
const band_init all_band_inits[] =
- {
- // BAND_INIT(archive_magic, BYTE1_spec, 0),
- // BAND_INIT(archive_header, UNSIGNED5_spec, 0),
- // BAND_INIT(band_headers, BYTE1_spec, 0),
- BAND_INIT(cp_Utf8_prefix, DELTA5_spec, 0), BAND_INIT(cp_Utf8_suffix, UNSIGNED5_spec, 0),
- BAND_INIT(cp_Utf8_chars, CHAR3_spec, 0), BAND_INIT(cp_Utf8_big_suffix, DELTA5_spec, 0),
- BAND_INIT(cp_Utf8_big_chars, DELTA5_spec, 0), BAND_INIT(cp_Int, UDELTA5_spec, 0),
- BAND_INIT(cp_Float, UDELTA5_spec, 0), BAND_INIT(cp_Long_hi, UDELTA5_spec, 0),
- BAND_INIT(cp_Long_lo, DELTA5_spec, 0), BAND_INIT(cp_Double_hi, UDELTA5_spec, 0),
- BAND_INIT(cp_Double_lo, DELTA5_spec, 0),
- BAND_INIT(cp_String, UDELTA5_spec, INDEX(CONSTANT_Utf8)),
- BAND_INIT(cp_Class, UDELTA5_spec, INDEX(CONSTANT_Utf8)),
- BAND_INIT(cp_Signature_form, DELTA5_spec, INDEX(CONSTANT_Utf8)),
- BAND_INIT(cp_Signature_classes, UDELTA5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(cp_Descr_name, DELTA5_spec, INDEX(CONSTANT_Utf8)),
- BAND_INIT(cp_Descr_type, UDELTA5_spec, INDEX(CONSTANT_Signature)),
- BAND_INIT(cp_Field_class, DELTA5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(cp_Field_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)),
- BAND_INIT(cp_Method_class, DELTA5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(cp_Method_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)),
- BAND_INIT(cp_Imethod_class, DELTA5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(cp_Imethod_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)),
- BAND_INIT(attr_definition_headers, BYTE1_spec, 0),
- BAND_INIT(attr_definition_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
- BAND_INIT(attr_definition_layout, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
- BAND_INIT(ic_this_class, UDELTA5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(ic_flags, UNSIGNED5_spec, 0),
- BAND_INIT(ic_outer_class, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Class)),
- BAND_INIT(ic_name, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Utf8)),
- BAND_INIT(class_this, DELTA5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(class_super, DELTA5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(class_interface_count, DELTA5_spec, 0),
- BAND_INIT(class_interface, DELTA5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(class_field_count, DELTA5_spec, 0),
- BAND_INIT(class_method_count, DELTA5_spec, 0),
- BAND_INIT(field_descr, DELTA5_spec, INDEX(CONSTANT_NameandType)),
- BAND_INIT(field_flags_hi, UNSIGNED5_spec, 0),
- BAND_INIT(field_flags_lo, UNSIGNED5_spec, 0),
- BAND_INIT(field_attr_count, UNSIGNED5_spec, 0),
- BAND_INIT(field_attr_indexes, UNSIGNED5_spec, 0),
- BAND_INIT(field_attr_calls, UNSIGNED5_spec, 0),
- BAND_INIT(field_ConstantValue_KQ, UNSIGNED5_spec, INDEX(CONSTANT_Literal)),
- BAND_INIT(field_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
- BAND_INIT(field_metadata_bands, -1, -1), BAND_INIT(field_attr_bands, -1, -1),
- BAND_INIT(method_descr, MDELTA5_spec, INDEX(CONSTANT_NameandType)),
- BAND_INIT(method_flags_hi, UNSIGNED5_spec, 0),
- BAND_INIT(method_flags_lo, UNSIGNED5_spec, 0),
- BAND_INIT(method_attr_count, UNSIGNED5_spec, 0),
- BAND_INIT(method_attr_indexes, UNSIGNED5_spec, 0),
- BAND_INIT(method_attr_calls, UNSIGNED5_spec, 0),
- BAND_INIT(method_Exceptions_N, UNSIGNED5_spec, 0),
- BAND_INIT(method_Exceptions_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(method_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
- BAND_INIT(method_metadata_bands, -1, -1), BAND_INIT(method_attr_bands, -1, -1),
- BAND_INIT(class_flags_hi, UNSIGNED5_spec, 0),
- BAND_INIT(class_flags_lo, UNSIGNED5_spec, 0),
- BAND_INIT(class_attr_count, UNSIGNED5_spec, 0),
- BAND_INIT(class_attr_indexes, UNSIGNED5_spec, 0),
- BAND_INIT(class_attr_calls, UNSIGNED5_spec, 0),
- BAND_INIT(class_SourceFile_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)),
- BAND_INIT(class_EnclosingMethod_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(class_EnclosingMethod_RDN, UNSIGNED5_spec,
- NULL_OR_INDEX(CONSTANT_NameandType)),
- BAND_INIT(class_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
- BAND_INIT(class_metadata_bands, -1, -1),
- BAND_INIT(class_InnerClasses_N, UNSIGNED5_spec, 0),
- BAND_INIT(class_InnerClasses_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(class_InnerClasses_F, UNSIGNED5_spec, 0),
- BAND_INIT(class_InnerClasses_outer_RCN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)),
- BAND_INIT(class_InnerClasses_name_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)),
- BAND_INIT(class_ClassFile_version_minor_H, UNSIGNED5_spec, 0),
- BAND_INIT(class_ClassFile_version_major_H, UNSIGNED5_spec, 0),
- BAND_INIT(class_attr_bands, -1, -1), BAND_INIT(code_headers, BYTE1_spec, 0),
- BAND_INIT(code_max_stack, UNSIGNED5_spec, 0),
- BAND_INIT(code_max_na_locals, UNSIGNED5_spec, 0),
- BAND_INIT(code_handler_count, UNSIGNED5_spec, 0),
- BAND_INIT(code_handler_start_P, BCI5_spec, 0),
- BAND_INIT(code_handler_end_PO, BRANCH5_spec, 0),
- BAND_INIT(code_handler_catch_PO, BRANCH5_spec, 0),
- BAND_INIT(code_handler_class_RCN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)),
- BAND_INIT(code_flags_hi, UNSIGNED5_spec, 0),
- BAND_INIT(code_flags_lo, UNSIGNED5_spec, 0),
- BAND_INIT(code_attr_count, UNSIGNED5_spec, 0),
- BAND_INIT(code_attr_indexes, UNSIGNED5_spec, 0),
- BAND_INIT(code_attr_calls, UNSIGNED5_spec, 0),
- BAND_INIT(code_StackMapTable_N, UNSIGNED5_spec, 0),
- BAND_INIT(code_StackMapTable_frame_T, BYTE1_spec, 0),
- BAND_INIT(code_StackMapTable_local_N, UNSIGNED5_spec, 0),
- BAND_INIT(code_StackMapTable_stack_N, UNSIGNED5_spec, 0),
- BAND_INIT(code_StackMapTable_offset, UNSIGNED5_spec, 0),
- BAND_INIT(code_StackMapTable_T, BYTE1_spec, 0),
- BAND_INIT(code_StackMapTable_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)),
- BAND_INIT(code_StackMapTable_P, BCI5_spec, 0),
- BAND_INIT(code_LineNumberTable_N, UNSIGNED5_spec, 0),
- BAND_INIT(code_LineNumberTable_bci_P, BCI5_spec, 0),
- BAND_INIT(code_LineNumberTable_line, UNSIGNED5_spec, 0),
- BAND_INIT(code_LocalVariableTable_N, UNSIGNED5_spec, 0),
- BAND_INIT(code_LocalVariableTable_bci_P, BCI5_spec, 0),
- BAND_INIT(code_LocalVariableTable_span_O, BRANCH5_spec, 0),
- BAND_INIT(code_LocalVariableTable_name_RU, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
- BAND_INIT(code_LocalVariableTable_type_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
- BAND_INIT(code_LocalVariableTable_slot, UNSIGNED5_spec, 0),
- BAND_INIT(code_LocalVariableTypeTable_N, UNSIGNED5_spec, 0),
- BAND_INIT(code_LocalVariableTypeTable_bci_P, BCI5_spec, 0),
- BAND_INIT(code_LocalVariableTypeTable_span_O, BRANCH5_spec, 0),
- BAND_INIT(code_LocalVariableTypeTable_name_RU, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
- BAND_INIT(code_LocalVariableTypeTable_type_RS, UNSIGNED5_spec,
- INDEX(CONSTANT_Signature)),
- BAND_INIT(code_LocalVariableTypeTable_slot, UNSIGNED5_spec, 0),
- BAND_INIT(code_attr_bands, -1, -1), BAND_INIT(bc_codes, BYTE1_spec, 0),
- BAND_INIT(bc_case_count, UNSIGNED5_spec, 0), BAND_INIT(bc_case_value, DELTA5_spec, 0),
- BAND_INIT(bc_byte, BYTE1_spec, 0), BAND_INIT(bc_short, DELTA5_spec, 0),
- BAND_INIT(bc_local, UNSIGNED5_spec, 0), BAND_INIT(bc_label, BRANCH5_spec, 0),
- BAND_INIT(bc_intref, DELTA5_spec, INDEX(CONSTANT_Integer)),
- BAND_INIT(bc_floatref, DELTA5_spec, INDEX(CONSTANT_Float)),
- BAND_INIT(bc_longref, DELTA5_spec, INDEX(CONSTANT_Long)),
- BAND_INIT(bc_doubleref, DELTA5_spec, INDEX(CONSTANT_Double)),
- BAND_INIT(bc_stringref, DELTA5_spec, INDEX(CONSTANT_String)),
- BAND_INIT(bc_classref, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)),
- BAND_INIT(bc_fieldref, DELTA5_spec, INDEX(CONSTANT_Fieldref)),
- BAND_INIT(bc_methodref, UNSIGNED5_spec, INDEX(CONSTANT_Methodref)),
- BAND_INIT(bc_imethodref, DELTA5_spec, INDEX(CONSTANT_InterfaceMethodref)),
- BAND_INIT(bc_thisfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)),
- BAND_INIT(bc_superfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)),
- BAND_INIT(bc_thismethod, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)),
- BAND_INIT(bc_supermethod, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)),
- BAND_INIT(bc_initref, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)),
- BAND_INIT(bc_escref, UNSIGNED5_spec, INDEX(CONSTANT_All)),
- BAND_INIT(bc_escrefsize, UNSIGNED5_spec, 0), BAND_INIT(bc_escsize, UNSIGNED5_spec, 0),
- BAND_INIT(bc_escbyte, BYTE1_spec, 0),
- BAND_INIT(file_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
- BAND_INIT(file_size_hi, UNSIGNED5_spec, 0), BAND_INIT(file_size_lo, UNSIGNED5_spec, 0),
- BAND_INIT(file_modtime, DELTA5_spec, 0), BAND_INIT(file_options, UNSIGNED5_spec, 0),
- // BAND_INIT(file_bits, BYTE1_spec, 0),
- {0, 0}};
+ {
+ // BAND_INIT(archive_magic, BYTE1_spec, 0),
+ // BAND_INIT(archive_header, UNSIGNED5_spec, 0),
+ // BAND_INIT(band_headers, BYTE1_spec, 0),
+ BAND_INIT(cp_Utf8_prefix, DELTA5_spec, 0), BAND_INIT(cp_Utf8_suffix, UNSIGNED5_spec, 0),
+ BAND_INIT(cp_Utf8_chars, CHAR3_spec, 0), BAND_INIT(cp_Utf8_big_suffix, DELTA5_spec, 0),
+ BAND_INIT(cp_Utf8_big_chars, DELTA5_spec, 0), BAND_INIT(cp_Int, UDELTA5_spec, 0),
+ BAND_INIT(cp_Float, UDELTA5_spec, 0), BAND_INIT(cp_Long_hi, UDELTA5_spec, 0),
+ BAND_INIT(cp_Long_lo, DELTA5_spec, 0), BAND_INIT(cp_Double_hi, UDELTA5_spec, 0),
+ BAND_INIT(cp_Double_lo, DELTA5_spec, 0),
+ BAND_INIT(cp_String, UDELTA5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(cp_Class, UDELTA5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(cp_Signature_form, DELTA5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(cp_Signature_classes, UDELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(cp_Descr_name, DELTA5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(cp_Descr_type, UDELTA5_spec, INDEX(CONSTANT_Signature)),
+ BAND_INIT(cp_Field_class, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(cp_Field_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(cp_Method_class, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(cp_Method_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(cp_Imethod_class, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(cp_Imethod_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(attr_definition_headers, BYTE1_spec, 0),
+ BAND_INIT(attr_definition_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(attr_definition_layout, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(ic_this_class, UDELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(ic_flags, UNSIGNED5_spec, 0),
+ BAND_INIT(ic_outer_class, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Class)),
+ BAND_INIT(ic_name, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Utf8)),
+ BAND_INIT(class_this, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(class_super, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(class_interface_count, DELTA5_spec, 0),
+ BAND_INIT(class_interface, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(class_field_count, DELTA5_spec, 0),
+ BAND_INIT(class_method_count, DELTA5_spec, 0),
+ BAND_INIT(field_descr, DELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(field_flags_hi, UNSIGNED5_spec, 0),
+ BAND_INIT(field_flags_lo, UNSIGNED5_spec, 0),
+ BAND_INIT(field_attr_count, UNSIGNED5_spec, 0),
+ BAND_INIT(field_attr_indexes, UNSIGNED5_spec, 0),
+ BAND_INIT(field_attr_calls, UNSIGNED5_spec, 0),
+ BAND_INIT(field_ConstantValue_KQ, UNSIGNED5_spec, INDEX(CONSTANT_Literal)),
+ BAND_INIT(field_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
+ BAND_INIT(field_metadata_bands, -1, -1), BAND_INIT(field_attr_bands, -1, -1),
+ BAND_INIT(method_descr, MDELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(method_flags_hi, UNSIGNED5_spec, 0),
+ BAND_INIT(method_flags_lo, UNSIGNED5_spec, 0),
+ BAND_INIT(method_attr_count, UNSIGNED5_spec, 0),
+ BAND_INIT(method_attr_indexes, UNSIGNED5_spec, 0),
+ BAND_INIT(method_attr_calls, UNSIGNED5_spec, 0),
+ BAND_INIT(method_Exceptions_N, UNSIGNED5_spec, 0),
+ BAND_INIT(method_Exceptions_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(method_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
+ BAND_INIT(method_metadata_bands, -1, -1), BAND_INIT(method_attr_bands, -1, -1),
+ BAND_INIT(class_flags_hi, UNSIGNED5_spec, 0),
+ BAND_INIT(class_flags_lo, UNSIGNED5_spec, 0),
+ BAND_INIT(class_attr_count, UNSIGNED5_spec, 0),
+ BAND_INIT(class_attr_indexes, UNSIGNED5_spec, 0),
+ BAND_INIT(class_attr_calls, UNSIGNED5_spec, 0),
+ BAND_INIT(class_SourceFile_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)),
+ BAND_INIT(class_EnclosingMethod_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(class_EnclosingMethod_RDN, UNSIGNED5_spec,
+ NULL_OR_INDEX(CONSTANT_NameandType)),
+ BAND_INIT(class_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
+ BAND_INIT(class_metadata_bands, -1, -1),
+ BAND_INIT(class_InnerClasses_N, UNSIGNED5_spec, 0),
+ BAND_INIT(class_InnerClasses_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(class_InnerClasses_F, UNSIGNED5_spec, 0),
+ BAND_INIT(class_InnerClasses_outer_RCN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)),
+ BAND_INIT(class_InnerClasses_name_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)),
+ BAND_INIT(class_ClassFile_version_minor_H, UNSIGNED5_spec, 0),
+ BAND_INIT(class_ClassFile_version_major_H, UNSIGNED5_spec, 0),
+ BAND_INIT(class_attr_bands, -1, -1), BAND_INIT(code_headers, BYTE1_spec, 0),
+ BAND_INIT(code_max_stack, UNSIGNED5_spec, 0),
+ BAND_INIT(code_max_na_locals, UNSIGNED5_spec, 0),
+ BAND_INIT(code_handler_count, UNSIGNED5_spec, 0),
+ BAND_INIT(code_handler_start_P, BCI5_spec, 0),
+ BAND_INIT(code_handler_end_PO, BRANCH5_spec, 0),
+ BAND_INIT(code_handler_catch_PO, BRANCH5_spec, 0),
+ BAND_INIT(code_handler_class_RCN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)),
+ BAND_INIT(code_flags_hi, UNSIGNED5_spec, 0),
+ BAND_INIT(code_flags_lo, UNSIGNED5_spec, 0),
+ BAND_INIT(code_attr_count, UNSIGNED5_spec, 0),
+ BAND_INIT(code_attr_indexes, UNSIGNED5_spec, 0),
+ BAND_INIT(code_attr_calls, UNSIGNED5_spec, 0),
+ BAND_INIT(code_StackMapTable_N, UNSIGNED5_spec, 0),
+ BAND_INIT(code_StackMapTable_frame_T, BYTE1_spec, 0),
+ BAND_INIT(code_StackMapTable_local_N, UNSIGNED5_spec, 0),
+ BAND_INIT(code_StackMapTable_stack_N, UNSIGNED5_spec, 0),
+ BAND_INIT(code_StackMapTable_offset, UNSIGNED5_spec, 0),
+ BAND_INIT(code_StackMapTable_T, BYTE1_spec, 0),
+ BAND_INIT(code_StackMapTable_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(code_StackMapTable_P, BCI5_spec, 0),
+ BAND_INIT(code_LineNumberTable_N, UNSIGNED5_spec, 0),
+ BAND_INIT(code_LineNumberTable_bci_P, BCI5_spec, 0),
+ BAND_INIT(code_LineNumberTable_line, UNSIGNED5_spec, 0),
+ BAND_INIT(code_LocalVariableTable_N, UNSIGNED5_spec, 0),
+ BAND_INIT(code_LocalVariableTable_bci_P, BCI5_spec, 0),
+ BAND_INIT(code_LocalVariableTable_span_O, BRANCH5_spec, 0),
+ BAND_INIT(code_LocalVariableTable_name_RU, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(code_LocalVariableTable_type_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
+ BAND_INIT(code_LocalVariableTable_slot, UNSIGNED5_spec, 0),
+ BAND_INIT(code_LocalVariableTypeTable_N, UNSIGNED5_spec, 0),
+ BAND_INIT(code_LocalVariableTypeTable_bci_P, BCI5_spec, 0),
+ BAND_INIT(code_LocalVariableTypeTable_span_O, BRANCH5_spec, 0),
+ BAND_INIT(code_LocalVariableTypeTable_name_RU, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(code_LocalVariableTypeTable_type_RS, UNSIGNED5_spec,
+ INDEX(CONSTANT_Signature)),
+ BAND_INIT(code_LocalVariableTypeTable_slot, UNSIGNED5_spec, 0),
+ BAND_INIT(code_attr_bands, -1, -1), BAND_INIT(bc_codes, BYTE1_spec, 0),
+ BAND_INIT(bc_case_count, UNSIGNED5_spec, 0), BAND_INIT(bc_case_value, DELTA5_spec, 0),
+ BAND_INIT(bc_byte, BYTE1_spec, 0), BAND_INIT(bc_short, DELTA5_spec, 0),
+ BAND_INIT(bc_local, UNSIGNED5_spec, 0), BAND_INIT(bc_label, BRANCH5_spec, 0),
+ BAND_INIT(bc_intref, DELTA5_spec, INDEX(CONSTANT_Integer)),
+ BAND_INIT(bc_floatref, DELTA5_spec, INDEX(CONSTANT_Float)),
+ BAND_INIT(bc_longref, DELTA5_spec, INDEX(CONSTANT_Long)),
+ BAND_INIT(bc_doubleref, DELTA5_spec, INDEX(CONSTANT_Double)),
+ BAND_INIT(bc_stringref, DELTA5_spec, INDEX(CONSTANT_String)),
+ BAND_INIT(bc_classref, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)),
+ BAND_INIT(bc_fieldref, DELTA5_spec, INDEX(CONSTANT_Fieldref)),
+ BAND_INIT(bc_methodref, UNSIGNED5_spec, INDEX(CONSTANT_Methodref)),
+ BAND_INIT(bc_imethodref, DELTA5_spec, INDEX(CONSTANT_InterfaceMethodref)),
+ BAND_INIT(bc_thisfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)),
+ BAND_INIT(bc_superfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)),
+ BAND_INIT(bc_thismethod, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)),
+ BAND_INIT(bc_supermethod, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)),
+ BAND_INIT(bc_initref, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)),
+ BAND_INIT(bc_escref, UNSIGNED5_spec, INDEX(CONSTANT_All)),
+ BAND_INIT(bc_escrefsize, UNSIGNED5_spec, 0), BAND_INIT(bc_escsize, UNSIGNED5_spec, 0),
+ BAND_INIT(bc_escbyte, BYTE1_spec, 0),
+ BAND_INIT(file_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(file_size_hi, UNSIGNED5_spec, 0), BAND_INIT(file_size_lo, UNSIGNED5_spec, 0),
+ BAND_INIT(file_modtime, DELTA5_spec, 0), BAND_INIT(file_options, UNSIGNED5_spec, 0),
+ // BAND_INIT(file_bits, BYTE1_spec, 0),
+ {0, 0}};
band *band::makeBands(unpacker *u)
{
- band *tmp_all_bands = U_NEW(band, BAND_LIMIT);
- for (int i = 0; i < BAND_LIMIT; i++)
- {
- assert((byte *)&all_band_inits[i + 1] <
- (byte *)all_band_inits + sizeof(all_band_inits));
- const band_init &bi = all_band_inits[i];
- band &b = tmp_all_bands[i];
- coding *defc = coding::findBySpec(bi.defc);
- assert((defc == nullptr) == (bi.defc == -1)); // no garbage, please
- assert(defc == nullptr || !defc->isMalloc);
- b.init(u, i, defc);
- if (bi.index > 0)
- {
- b.nullOK = ((bi.index >> 8) & 1);
- b.ixTag = (bi.index & 0xFF);
- }
- }
- return tmp_all_bands;
+ band *tmp_all_bands = U_NEW(band, BAND_LIMIT);
+ for (int i = 0; i < BAND_LIMIT; i++)
+ {
+ assert((byte *)&all_band_inits[i + 1] <
+ (byte *)all_band_inits + sizeof(all_band_inits));
+ const band_init &bi = all_band_inits[i];
+ band &b = tmp_all_bands[i];
+ coding *defc = coding::findBySpec(bi.defc);
+ assert((defc == nullptr) == (bi.defc == -1)); // no garbage, please
+ assert(defc == nullptr || !defc->isMalloc);
+ b.init(u, i, defc);
+ if (bi.index > 0)
+ {
+ b.nullOK = ((bi.index >> 8) & 1);
+ b.ixTag = (bi.index & 0xFF);
+ }
+ }
+ return tmp_all_bands;
}
void band::initIndexes(unpacker *u)
{
- band *tmp_all_bands = u->all_bands;
- for (int i = 0; i < BAND_LIMIT; i++)
- {
- band *scan = &tmp_all_bands[i];
- uint32_t tag = scan->ixTag; // Cf. #define INDEX(tag) above
- if (tag != 0 && tag != CONSTANT_Literal && (tag & SUBINDEX_BIT) == 0)
- {
- scan->setIndex(u->cp.getIndex(tag));
- }
- }
+ band *tmp_all_bands = u->all_bands;
+ for (int i = 0; i < BAND_LIMIT; i++)
+ {
+ band *scan = &tmp_all_bands[i];
+ uint32_t tag = scan->ixTag; // Cf. #define INDEX(tag) above
+ if (tag != 0 && tag != CONSTANT_Literal && (tag & SUBINDEX_BIT) == 0)
+ {
+ scan->setIndex(u->cp.getIndex(tag));
+ }
+ }
}
diff --git a/libraries/pack200/src/bands.h b/libraries/pack200/src/bands.h
index a56cd7d5..66c5aec4 100644
--- a/libraries/pack200/src/bands.h
+++ b/libraries/pack200/src/bands.h
@@ -30,138 +30,138 @@ struct unpacker;
struct band
{
- int bn; // band_number of this band
- coding *defc; // default coding method
- cpindex *ix; // CP entry mapping, if CPRefBand
- byte ixTag; // 0 or 1; nullptr is coded as (nullOK?0:-1)
- byte nullOK; // 0 or 1; nullptr is coded as (nullOK?0:-1)
- int length; // expected # values
- unpacker *u; // back pointer
-
- value_stream vs[2]; // source of values
- coding_method cm; // method used for initial state of vs[0]
- byte *rplimit; // end of band (encoded, transmitted)
-
- int total_memo; // cached value of getIntTotal, or -1
- int *hist0; // approximate. histogram
- enum
- {
- HIST0_MIN = 0,
- HIST0_MAX = 255
- }; // catches the usual cases
-
- // properties for attribute layout elements:
- byte le_kind; // EK_XXX
- byte le_bci; // 0,EK_BCI,EK_BCD,EK_BCO
- byte le_back; // ==EF_BACK
- byte le_len; // 0,1,2,4 (size in classfile), or call addr
- band **le_body; // body of repl, union, call (nullptr-terminated)
+ int bn; // band_number of this band
+ coding *defc; // default coding method
+ cpindex *ix; // CP entry mapping, if CPRefBand
+ byte ixTag; // 0 or 1; nullptr is coded as (nullOK?0:-1)
+ byte nullOK; // 0 or 1; nullptr is coded as (nullOK?0:-1)
+ int length; // expected # values
+ unpacker *u; // back pointer
+
+ value_stream vs[2]; // source of values
+ coding_method cm; // method used for initial state of vs[0]
+ byte *rplimit; // end of band (encoded, transmitted)
+
+ int total_memo; // cached value of getIntTotal, or -1
+ int *hist0; // approximate. histogram
+ enum
+ {
+ HIST0_MIN = 0,
+ HIST0_MAX = 255
+ }; // catches the usual cases
+
+ // properties for attribute layout elements:
+ byte le_kind; // EK_XXX
+ byte le_bci; // 0,EK_BCI,EK_BCD,EK_BCO
+ byte le_back; // ==EF_BACK
+ byte le_len; // 0,1,2,4 (size in classfile), or call addr
+ band **le_body; // body of repl, union, call (nullptr-terminated)
// Note: EK_CASE elements use hist0 to record union tags.
#define le_casetags hist0
- band &nextBand()
- {
- return this[1];
- }
- band &prevBand()
- {
- return this[-1];
- }
-
- void init(unpacker *u_, int bn_, coding *defc_)
- {
- u = u_;
- cm.u = u_;
- bn = bn_;
- defc = defc_;
- }
- void init(unpacker *u_, int bn_, int defcSpec)
- {
- init(u_, bn_, coding::findBySpec(defcSpec));
- }
- void initRef(int ixTag_ = 0, bool nullOK_ = false)
- {
- ixTag = ixTag_;
- nullOK = nullOK_;
- setIndexByTag(ixTag);
- }
-
- void expectMoreLength(int l)
- {
- assert(length >= 0); // able to accept a length
- assert((int)l >= 0); // no overflow
- assert(rplimit == nullptr); // readData not yet called
- length += l;
- assert(length >= l); // no overflow
- }
-
- void setIndex(cpindex *ix_);
- void setIndexByTag(byte tag);
-
- // Parse the band and its meta-coding header.
- void readData(int expectedLength = 0);
-
- // Reset the band for another pass (Cf. Java Band.resetForSecondPass.)
- void rewind()
- {
- cm.reset(&vs[0]);
- }
-
- byte *&curRP()
- {
- return vs[0].rp;
- }
- byte *minRP()
- {
- return cm.vs0.rp;
- }
- byte *maxRP()
- {
- return rplimit;
- }
- size_t size()
- {
- return maxRP() - minRP();
- }
-
- int getByte()
- {
- assert(ix == nullptr);
- return vs[0].getByte();
- }
- int getInt()
- {
- assert(ix == nullptr);
- return vs[0].getInt();
- }
- entry *getRefN()
- {
- assert(ix != nullptr);
- return getRefCommon(ix, true);
- }
- entry *getRef()
- {
- assert(ix != nullptr);
- return getRefCommon(ix, false);
- }
- entry *getRefUsing(cpindex *ix2)
- {
- assert(ix == nullptr);
- return getRefCommon(ix2, true);
- }
- entry *getRefCommon(cpindex *ix, bool nullOK);
- int64_t getLong(band &lo_band, bool have_hi);
-
- static int64_t makeLong(uint32_t hi, uint32_t lo)
- {
- return ((uint64_t)hi << 32) + (((uint64_t)lo << 32) >> 32);
- }
-
- int getIntTotal();
- int getIntCount(int tag);
-
- static band *makeBands(unpacker *u);
- static void initIndexes(unpacker *u);
+ band &nextBand()
+ {
+ return this[1];
+ }
+ band &prevBand()
+ {
+ return this[-1];
+ }
+
+ void init(unpacker *u_, int bn_, coding *defc_)
+ {
+ u = u_;
+ cm.u = u_;
+ bn = bn_;
+ defc = defc_;
+ }
+ void init(unpacker *u_, int bn_, int defcSpec)
+ {
+ init(u_, bn_, coding::findBySpec(defcSpec));
+ }
+ void initRef(int ixTag_ = 0, bool nullOK_ = false)
+ {
+ ixTag = ixTag_;
+ nullOK = nullOK_;
+ setIndexByTag(ixTag);
+ }
+
+ void expectMoreLength(int l)
+ {
+ assert(length >= 0); // able to accept a length
+ assert((int)l >= 0); // no overflow
+ assert(rplimit == nullptr); // readData not yet called
+ length += l;
+ assert(length >= l); // no overflow
+ }
+
+ void setIndex(cpindex *ix_);
+ void setIndexByTag(byte tag);
+
+ // Parse the band and its meta-coding header.
+ void readData(int expectedLength = 0);
+
+ // Reset the band for another pass (Cf. Java Band.resetForSecondPass.)
+ void rewind()
+ {
+ cm.reset(&vs[0]);
+ }
+
+ byte *&curRP()
+ {
+ return vs[0].rp;
+ }
+ byte *minRP()
+ {
+ return cm.vs0.rp;
+ }
+ byte *maxRP()
+ {
+ return rplimit;
+ }
+ size_t size()
+ {
+ return maxRP() - minRP();
+ }
+
+ int getByte()
+ {
+ assert(ix == nullptr);
+ return vs[0].getByte();
+ }
+ int getInt()
+ {
+ assert(ix == nullptr);
+ return vs[0].getInt();
+ }
+ entry *getRefN()
+ {
+ assert(ix != nullptr);
+ return getRefCommon(ix, true);
+ }
+ entry *getRef()
+ {
+ assert(ix != nullptr);
+ return getRefCommon(ix, false);
+ }
+ entry *getRefUsing(cpindex *ix2)
+ {
+ assert(ix == nullptr);
+ return getRefCommon(ix2, true);
+ }
+ entry *getRefCommon(cpindex *ix, bool nullOK);
+ int64_t getLong(band &lo_band, bool have_hi);
+
+ static int64_t makeLong(uint32_t hi, uint32_t lo)
+ {
+ return ((uint64_t)hi << 32) + (((uint64_t)lo << 32) >> 32);
+ }
+
+ int getIntTotal();
+ int getIntCount(int tag);
+
+ static band *makeBands(unpacker *u);
+ static void initIndexes(unpacker *u);
};
extern band all_bands[];
@@ -173,179 +173,179 @@ extern band all_bands[];
// Band schema:
enum band_number
{
- // e_archive_magic,
- // e_archive_header,
- // e_band_headers,
-
- // constant pool contents
- e_cp_Utf8_prefix,
- e_cp_Utf8_suffix,
- e_cp_Utf8_chars,
- e_cp_Utf8_big_suffix,
- e_cp_Utf8_big_chars,
- e_cp_Int,
- e_cp_Float,
- e_cp_Long_hi,
- e_cp_Long_lo,
- e_cp_Double_hi,
- e_cp_Double_lo,
- e_cp_String,
- e_cp_Class,
- e_cp_Signature_form,
- e_cp_Signature_classes,
- e_cp_Descr_name,
- e_cp_Descr_type,
- e_cp_Field_class,
- e_cp_Field_desc,
- e_cp_Method_class,
- e_cp_Method_desc,
- e_cp_Imethod_class,
- e_cp_Imethod_desc,
-
- // bands which define transmission of attributes
- e_attr_definition_headers,
- e_attr_definition_name,
- e_attr_definition_layout,
-
- // band for hardwired InnerClasses attribute (shared across the package)
- e_ic_this_class,
- e_ic_flags,
- // These bands contain data only where flags sets ACC_IC_LONG_FORM:
- e_ic_outer_class,
- e_ic_name,
-
- // bands for carrying class schema information:
- e_class_this,
- e_class_super,
- e_class_interface_count,
- e_class_interface,
-
- // bands for class members
- e_class_field_count,
- e_class_method_count,
- e_field_descr,
- e_field_flags_hi,
- e_field_flags_lo,
- e_field_attr_count,
- e_field_attr_indexes,
- e_field_attr_calls,
- e_field_ConstantValue_KQ,
- e_field_Signature_RS,
- e_field_metadata_bands,
- e_field_attr_bands,
- e_method_descr,
- e_method_flags_hi,
- e_method_flags_lo,
- e_method_attr_count,
- e_method_attr_indexes,
- e_method_attr_calls,
- e_method_Exceptions_N,
- e_method_Exceptions_RC,
- e_method_Signature_RS,
- e_method_metadata_bands,
- e_method_attr_bands,
- e_class_flags_hi,
- e_class_flags_lo,
- e_class_attr_count,
- e_class_attr_indexes,
- e_class_attr_calls,
- e_class_SourceFile_RUN,
- e_class_EnclosingMethod_RC,
- e_class_EnclosingMethod_RDN,
- e_class_Signature_RS,
- e_class_metadata_bands,
- e_class_InnerClasses_N,
- e_class_InnerClasses_RC,
- e_class_InnerClasses_F,
- e_class_InnerClasses_outer_RCN,
- e_class_InnerClasses_name_RUN,
- e_class_ClassFile_version_minor_H,
- e_class_ClassFile_version_major_H,
- e_class_attr_bands,
- e_code_headers,
- e_code_max_stack,
- e_code_max_na_locals,
- e_code_handler_count,
- e_code_handler_start_P,
- e_code_handler_end_PO,
- e_code_handler_catch_PO,
- e_code_handler_class_RCN,
-
- // code attributes
- e_code_flags_hi,
- e_code_flags_lo,
- e_code_attr_count,
- e_code_attr_indexes,
- e_code_attr_calls,
- e_code_StackMapTable_N,
- e_code_StackMapTable_frame_T,
- e_code_StackMapTable_local_N,
- e_code_StackMapTable_stack_N,
- e_code_StackMapTable_offset,
- e_code_StackMapTable_T,
- e_code_StackMapTable_RC,
- e_code_StackMapTable_P,
- e_code_LineNumberTable_N,
- e_code_LineNumberTable_bci_P,
- e_code_LineNumberTable_line,
- e_code_LocalVariableTable_N,
- e_code_LocalVariableTable_bci_P,
- e_code_LocalVariableTable_span_O,
- e_code_LocalVariableTable_name_RU,
- e_code_LocalVariableTable_type_RS,
- e_code_LocalVariableTable_slot,
- e_code_LocalVariableTypeTable_N,
- e_code_LocalVariableTypeTable_bci_P,
- e_code_LocalVariableTypeTable_span_O,
- e_code_LocalVariableTypeTable_name_RU,
- e_code_LocalVariableTypeTable_type_RS,
- e_code_LocalVariableTypeTable_slot,
- e_code_attr_bands,
-
- // bands for bytecodes
- e_bc_codes,
- // remaining bands provide typed opcode fields required by the bc_codes
- e_bc_case_count,
- e_bc_case_value,
- e_bc_byte,
- e_bc_short,
- e_bc_local,
- e_bc_label,
-
- // ldc* operands:
- e_bc_intref,
- e_bc_floatref,
- e_bc_longref,
- e_bc_doubleref,
- e_bc_stringref,
- e_bc_classref,
- e_bc_fieldref,
- e_bc_methodref,
- e_bc_imethodref,
-
- // _self_linker_op family
- e_bc_thisfield,
- e_bc_superfield,
- e_bc_thismethod,
- e_bc_supermethod,
-
- // bc_invokeinit family:
- e_bc_initref,
-
- // bytecode escape sequences
- e_bc_escref,
- e_bc_escrefsize,
- e_bc_escsize,
- e_bc_escbyte,
-
- // file attributes and contents
- e_file_name,
- e_file_size_hi,
- e_file_size_lo,
- e_file_modtime,
- e_file_options,
- // e_file_bits, // handled specially as an appendix
- BAND_LIMIT
+ // e_archive_magic,
+ // e_archive_header,
+ // e_band_headers,
+
+ // constant pool contents
+ e_cp_Utf8_prefix,
+ e_cp_Utf8_suffix,
+ e_cp_Utf8_chars,
+ e_cp_Utf8_big_suffix,
+ e_cp_Utf8_big_chars,
+ e_cp_Int,
+ e_cp_Float,
+ e_cp_Long_hi,
+ e_cp_Long_lo,
+ e_cp_Double_hi,
+ e_cp_Double_lo,
+ e_cp_String,
+ e_cp_Class,
+ e_cp_Signature_form,
+ e_cp_Signature_classes,
+ e_cp_Descr_name,
+ e_cp_Descr_type,
+ e_cp_Field_class,
+ e_cp_Field_desc,
+ e_cp_Method_class,
+ e_cp_Method_desc,
+ e_cp_Imethod_class,
+ e_cp_Imethod_desc,
+
+ // bands which define transmission of attributes
+ e_attr_definition_headers,
+ e_attr_definition_name,
+ e_attr_definition_layout,
+
+ // band for hardwired InnerClasses attribute (shared across the package)
+ e_ic_this_class,
+ e_ic_flags,
+ // These bands contain data only where flags sets ACC_IC_LONG_FORM:
+ e_ic_outer_class,
+ e_ic_name,
+
+ // bands for carrying class schema information:
+ e_class_this,
+ e_class_super,
+ e_class_interface_count,
+ e_class_interface,
+
+ // bands for class members
+ e_class_field_count,
+ e_class_method_count,
+ e_field_descr,
+ e_field_flags_hi,
+ e_field_flags_lo,
+ e_field_attr_count,
+ e_field_attr_indexes,
+ e_field_attr_calls,
+ e_field_ConstantValue_KQ,
+ e_field_Signature_RS,
+ e_field_metadata_bands,
+ e_field_attr_bands,
+ e_method_descr,
+ e_method_flags_hi,
+ e_method_flags_lo,
+ e_method_attr_count,
+ e_method_attr_indexes,
+ e_method_attr_calls,
+ e_method_Exceptions_N,
+ e_method_Exceptions_RC,
+ e_method_Signature_RS,
+ e_method_metadata_bands,
+ e_method_attr_bands,
+ e_class_flags_hi,
+ e_class_flags_lo,
+ e_class_attr_count,
+ e_class_attr_indexes,
+ e_class_attr_calls,
+ e_class_SourceFile_RUN,
+ e_class_EnclosingMethod_RC,
+ e_class_EnclosingMethod_RDN,
+ e_class_Signature_RS,
+ e_class_metadata_bands,
+ e_class_InnerClasses_N,
+ e_class_InnerClasses_RC,
+ e_class_InnerClasses_F,
+ e_class_InnerClasses_outer_RCN,
+ e_class_InnerClasses_name_RUN,
+ e_class_ClassFile_version_minor_H,
+ e_class_ClassFile_version_major_H,
+ e_class_attr_bands,
+ e_code_headers,
+ e_code_max_stack,
+ e_code_max_na_locals,
+ e_code_handler_count,
+ e_code_handler_start_P,
+ e_code_handler_end_PO,
+ e_code_handler_catch_PO,
+ e_code_handler_class_RCN,
+
+ // code attributes
+ e_code_flags_hi,
+ e_code_flags_lo,
+ e_code_attr_count,
+ e_code_attr_indexes,
+ e_code_attr_calls,
+ e_code_StackMapTable_N,
+ e_code_StackMapTable_frame_T,
+ e_code_StackMapTable_local_N,
+ e_code_StackMapTable_stack_N,
+ e_code_StackMapTable_offset,
+ e_code_StackMapTable_T,
+ e_code_StackMapTable_RC,
+ e_code_StackMapTable_P,
+ e_code_LineNumberTable_N,
+ e_code_LineNumberTable_bci_P,
+ e_code_LineNumberTable_line,
+ e_code_LocalVariableTable_N,
+ e_code_LocalVariableTable_bci_P,
+ e_code_LocalVariableTable_span_O,
+ e_code_LocalVariableTable_name_RU,
+ e_code_LocalVariableTable_type_RS,
+ e_code_LocalVariableTable_slot,
+ e_code_LocalVariableTypeTable_N,
+ e_code_LocalVariableTypeTable_bci_P,
+ e_code_LocalVariableTypeTable_span_O,
+ e_code_LocalVariableTypeTable_name_RU,
+ e_code_LocalVariableTypeTable_type_RS,
+ e_code_LocalVariableTypeTable_slot,
+ e_code_attr_bands,
+
+ // bands for bytecodes
+ e_bc_codes,
+ // remaining bands provide typed opcode fields required by the bc_codes
+ e_bc_case_count,
+ e_bc_case_value,
+ e_bc_byte,
+ e_bc_short,
+ e_bc_local,
+ e_bc_label,
+
+ // ldc* operands:
+ e_bc_intref,
+ e_bc_floatref,
+ e_bc_longref,
+ e_bc_doubleref,
+ e_bc_stringref,
+ e_bc_classref,
+ e_bc_fieldref,
+ e_bc_methodref,
+ e_bc_imethodref,
+
+ // _self_linker_op family
+ e_bc_thisfield,
+ e_bc_superfield,
+ e_bc_thismethod,
+ e_bc_supermethod,
+
+ // bc_invokeinit family:
+ e_bc_initref,
+
+ // bytecode escape sequences
+ e_bc_escref,
+ e_bc_escrefsize,
+ e_bc_escsize,
+ e_bc_escbyte,
+
+ // file attributes and contents
+ e_file_name,
+ e_file_size_hi,
+ e_file_size_lo,
+ e_file_modtime,
+ e_file_options,
+ // e_file_bits, // handled specially as an appendix
+ BAND_LIMIT
};
// Symbolic names for bands, as if in a giant global struct:
diff --git a/libraries/pack200/src/bytes.cpp b/libraries/pack200/src/bytes.cpp
index d3808afa..767fe0a5 100644
--- a/libraries/pack200/src/bytes.cpp
+++ b/libraries/pack200/src/bytes.cpp
@@ -36,182 +36,182 @@ static byte dummy[1 << 10];
bool bytes::inBounds(const void *p)
{
- return p >= ptr && p < limit();
+ return p >= ptr && p < limit();
}
void bytes::malloc(size_t len_)
{
- len = len_;
- ptr = NEW(byte, add_size(len_, 1)); // add trailing zero byte always
- if (ptr == nullptr)
- {
- // set ptr to some victim memory, to ease escape
- set(dummy, sizeof(dummy) - 1);
- unpack_abort(ERROR_ENOMEM);
- }
+ len = len_;
+ ptr = NEW(byte, add_size(len_, 1)); // add trailing zero byte always
+ if (ptr == nullptr)
+ {
+ // set ptr to some victim memory, to ease escape
+ set(dummy, sizeof(dummy) - 1);
+ unpack_abort(ERROR_ENOMEM);
+ }
}
void bytes::realloc(size_t len_)
{
- if (len == len_)
- return; // nothing to do
- if (ptr == dummy)
- return; // escaping from an error
- if (ptr == nullptr)
- {
- malloc(len_);
- return;
- }
- byte *oldptr = ptr;
- ptr = (len_ >= PSIZE_MAX) ? nullptr : (byte *)::realloc(ptr, add_size(len_, 1));
- if (ptr != nullptr)
- {
- if (len < len_)
- memset(ptr + len, 0, len_ - len);
- ptr[len_] = 0;
- len = len_;
- }
- else
- {
- ptr = oldptr; // ease our escape
- unpack_abort(ERROR_ENOMEM);
- }
+ if (len == len_)
+ return; // nothing to do
+ if (ptr == dummy)
+ return; // escaping from an error
+ if (ptr == nullptr)
+ {
+ malloc(len_);
+ return;
+ }
+ byte *oldptr = ptr;
+ ptr = (len_ >= PSIZE_MAX) ? nullptr : (byte *)::realloc(ptr, add_size(len_, 1));
+ if (ptr != nullptr)
+ {
+ if (len < len_)
+ memset(ptr + len, 0, len_ - len);
+ ptr[len_] = 0;
+ len = len_;
+ }
+ else
+ {
+ ptr = oldptr; // ease our escape
+ unpack_abort(ERROR_ENOMEM);
+ }
}
void bytes::free()
{
- if (ptr == dummy)
- return; // escaping from an error
- if (ptr != nullptr)
- {
- ::free(ptr);
- }
- len = 0;
- ptr = 0;
+ if (ptr == dummy)
+ return; // escaping from an error
+ if (ptr != nullptr)
+ {
+ ::free(ptr);
+ }
+ len = 0;
+ ptr = 0;
}
int bytes::indexOf(byte c)
{
- byte *p = (byte *)memchr(ptr, c, len);
- return (p == 0) ? -1 : (int)(p - ptr);
+ byte *p = (byte *)memchr(ptr, c, len);
+ return (p == 0) ? -1 : (int)(p - ptr);
}
byte *bytes::writeTo(byte *bp)
{
- memcpy(bp, ptr, len);
- return bp + len;
+ memcpy(bp, ptr, len);
+ return bp + len;
}
int bytes::compareTo(bytes &other)
{
- size_t l1 = len;
- size_t l2 = other.len;
- int cmp = memcmp(ptr, other.ptr, (l1 < l2) ? l1 : l2);
- if (cmp != 0)
- return cmp;
- return (l1 < l2) ? -1 : (l1 > l2) ? 1 : 0;
+ size_t l1 = len;
+ size_t l2 = other.len;
+ int cmp = memcmp(ptr, other.ptr, (l1 < l2) ? l1 : l2);
+ if (cmp != 0)
+ return cmp;
+ return (l1 < l2) ? -1 : (l1 > l2) ? 1 : 0;
}
void bytes::saveFrom(const void *ptr_, size_t len_)
{
- malloc(len_);
- // Save as much as possible.
- if (len_ > len)
- {
- assert(ptr == dummy); // error recovery
- len_ = len;
- }
- copyFrom(ptr_, len_);
+ malloc(len_);
+ // Save as much as possible.
+ if (len_ > len)
+ {
+ assert(ptr == dummy); // error recovery
+ len_ = len;
+ }
+ copyFrom(ptr_, len_);
}
//#TODO: Need to fix for exception handling
void bytes::copyFrom(const void *ptr_, size_t len_, size_t offset)
{
- assert(len_ == 0 || inBounds(ptr + offset));
- assert(len_ == 0 || inBounds(ptr + offset + len_ - 1));
- memcpy(ptr + offset, ptr_, len_);
+ assert(len_ == 0 || inBounds(ptr + offset));
+ assert(len_ == 0 || inBounds(ptr + offset + len_ - 1));
+ memcpy(ptr + offset, ptr_, len_);
}
// Make sure there are 'o' bytes beyond the fill pointer,
// advance the fill pointer, and return the old fill pointer.
byte *fillbytes::grow(size_t s)
{
- size_t nlen = add_size(b.len, s);
- if (nlen <= allocated)
- {
- b.len = nlen;
- return limit() - s;
- }
- size_t maxlen = nlen;
- if (maxlen < 128)
- maxlen = 128;
- if (maxlen < allocated * 2)
- maxlen = allocated * 2;
- if (allocated == 0)
- {
- // Initial buffer was not malloced. Do not reallocate it.
- bytes old = b;
- b.malloc(maxlen);
- if (b.len == maxlen)
- old.writeTo(b.ptr);
- }
- else
- {
- b.realloc(maxlen);
- }
- allocated = b.len;
- if (allocated != maxlen)
- {
- b.len = nlen - s; // back up
- return dummy; // scribble during error recov.
- }
- // after realloc, recompute pointers
- b.len = nlen;
- assert(b.len <= allocated);
- return limit() - s;
+ size_t nlen = add_size(b.len, s);
+ if (nlen <= allocated)
+ {
+ b.len = nlen;
+ return limit() - s;
+ }
+ size_t maxlen = nlen;
+ if (maxlen < 128)
+ maxlen = 128;
+ if (maxlen < allocated * 2)
+ maxlen = allocated * 2;
+ if (allocated == 0)
+ {
+ // Initial buffer was not malloced. Do not reallocate it.
+ bytes old = b;
+ b.malloc(maxlen);
+ if (b.len == maxlen)
+ old.writeTo(b.ptr);
+ }
+ else
+ {
+ b.realloc(maxlen);
+ }
+ allocated = b.len;
+ if (allocated != maxlen)
+ {
+ b.len = nlen - s; // back up
+ return dummy; // scribble during error recov.
+ }
+ // after realloc, recompute pointers
+ b.len = nlen;
+ assert(b.len <= allocated);
+ return limit() - s;
}
void fillbytes::ensureSize(size_t s)
{
- if (allocated >= s)
- return;
- size_t len0 = b.len;
- grow(s - size());
- b.len = len0; // put it back
+ if (allocated >= s)
+ return;
+ size_t len0 = b.len;
+ grow(s - size());
+ b.len = len0; // put it back
}
int ptrlist::indexOf(const void *x)
{
- int len = length();
- for (int i = 0; i < len; i++)
- {
- if (get(i) == x)
- return i;
- }
- return -1;
+ int len = length();
+ for (int i = 0; i < len; i++)
+ {
+ if (get(i) == x)
+ return i;
+ }
+ return -1;
}
void ptrlist::freeAll()
{
- int len = length();
- for (int i = 0; i < len; i++)
- {
- void *p = (void *)get(i);
- if (p != nullptr)
- {
- ::free(p);
- }
- }
- free();
+ int len = length();
+ for (int i = 0; i < len; i++)
+ {
+ void *p = (void *)get(i);
+ if (p != nullptr)
+ {
+ ::free(p);
+ }
+ }
+ free();
}
int intlist::indexOf(int x)
{
- int len = length();
- for (int i = 0; i < len; i++)
- {
- if (get(i) == x)
- return i;
- }
- return -1;
+ int len = length();
+ for (int i = 0; i < len; i++)
+ {
+ if (get(i) == x)
+ return i;
+ }
+ return -1;
}
diff --git a/libraries/pack200/src/bytes.h b/libraries/pack200/src/bytes.h
index b116efda..2ce1f7f4 100644
--- a/libraries/pack200/src/bytes.h
+++ b/libraries/pack200/src/bytes.h
@@ -27,225 +27,225 @@
struct bytes
{
- int8_t *ptr;
- size_t len;
- int8_t *limit()
- {
- return ptr + len;
- }
+ int8_t *ptr;
+ size_t len;
+ int8_t *limit()
+ {
+ return ptr + len;
+ }
- void set(int8_t *ptr_, size_t len_)
- {
- ptr = ptr_;
- len = len_;
- }
- void set(const char *str)
- {
- ptr = (int8_t *)str;
- len = strlen(str);
- }
- bool inBounds(const void *p); // p in [ptr, limit)
- void malloc(size_t len_);
- void realloc(size_t len_);
- void free();
- void copyFrom(const void *ptr_, size_t len_, size_t offset = 0);
- void saveFrom(const void *ptr_, size_t len_);
- void saveFrom(const char *str)
- {
- saveFrom(str, strlen(str));
- }
- void copyFrom(bytes &other, size_t offset = 0)
- {
- copyFrom(other.ptr, other.len, offset);
- }
- void saveFrom(bytes &other)
- {
- saveFrom(other.ptr, other.len);
- }
- void clear(int fill_byte = 0)
- {
- memset(ptr, fill_byte, len);
- }
- int8_t *writeTo(int8_t *bp);
- bool equals(bytes &other)
- {
- return 0 == compareTo(other);
- }
- int compareTo(bytes &other);
- bool contains(int8_t c)
- {
- return indexOf(c) >= 0;
- }
- int indexOf(int8_t c);
- // substrings:
- static bytes of(int8_t *ptr, size_t len)
- {
- bytes res;
- res.set(ptr, len);
- return res;
- }
- bytes slice(size_t beg, size_t end)
- {
- bytes res;
- res.ptr = ptr + beg;
- res.len = end - beg;
- assert(res.len == 0 ||(inBounds(res.ptr) && inBounds(res.limit() - 1)));
- return res;
- }
- // building C strings inside byte buffers:
- bytes &strcat(const char *str)
- {
- ::strcat((char *)ptr, str);
- return *this;
- }
- bytes &strcat(bytes &other)
- {
- ::strncat((char *)ptr, (char *)other.ptr, other.len);
- return *this;
- }
- char *strval()
- {
- assert(strlen((char *)ptr) == len);
- return (char *)ptr;
- }
+ void set(int8_t *ptr_, size_t len_)
+ {
+ ptr = ptr_;
+ len = len_;
+ }
+ void set(const char *str)
+ {
+ ptr = (int8_t *)str;
+ len = strlen(str);
+ }
+ bool inBounds(const void *p); // p in [ptr, limit)
+ void malloc(size_t len_);
+ void realloc(size_t len_);
+ void free();
+ void copyFrom(const void *ptr_, size_t len_, size_t offset = 0);
+ void saveFrom(const void *ptr_, size_t len_);
+ void saveFrom(const char *str)
+ {
+ saveFrom(str, strlen(str));
+ }
+ void copyFrom(bytes &other, size_t offset = 0)
+ {
+ copyFrom(other.ptr, other.len, offset);
+ }
+ void saveFrom(bytes &other)
+ {
+ saveFrom(other.ptr, other.len);
+ }
+ void clear(int fill_byte = 0)
+ {
+ memset(ptr, fill_byte, len);
+ }
+ int8_t *writeTo(int8_t *bp);
+ bool equals(bytes &other)
+ {
+ return 0 == compareTo(other);
+ }
+ int compareTo(bytes &other);
+ bool contains(int8_t c)
+ {
+ return indexOf(c) >= 0;
+ }
+ int indexOf(int8_t c);
+ // substrings:
+ static bytes of(int8_t *ptr, size_t len)
+ {
+ bytes res;
+ res.set(ptr, len);
+ return res;
+ }
+ bytes slice(size_t beg, size_t end)
+ {
+ bytes res;
+ res.ptr = ptr + beg;
+ res.len = end - beg;
+ assert(res.len == 0 ||(inBounds(res.ptr) && inBounds(res.limit() - 1)));
+ return res;
+ }
+ // building C strings inside byte buffers:
+ bytes &strcat(const char *str)
+ {
+ ::strcat((char *)ptr, str);
+ return *this;
+ }
+ bytes &strcat(bytes &other)
+ {
+ ::strncat((char *)ptr, (char *)other.ptr, other.len);
+ return *this;
+ }
+ char *strval()
+ {
+ assert(strlen((char *)ptr) == len);
+ return (char *)ptr;
+ }
};
#define BYTES_OF(var) (bytes::of((int8_t *)&(var), sizeof(var)))
struct fillbytes
{
- bytes b;
- size_t allocated;
+ bytes b;
+ size_t allocated;
- int8_t *base()
- {
- return b.ptr;
- }
- size_t size()
- {
- return b.len;
- }
- int8_t *limit()
- {
- return b.limit();
- } // logical limit
- void setLimit(int8_t *lp)
- {
- assert(isAllocated(lp));
- b.len = lp - b.ptr;
- }
- int8_t *end()
- {
- return b.ptr + allocated;
- } // physical limit
- int8_t *loc(size_t o)
- {
- assert(o < b.len);
- return b.ptr + o;
- }
- void init()
- {
- allocated = 0;
- b.set(nullptr, 0);
- }
- void init(size_t s)
- {
- init();
- ensureSize(s);
- }
- void free()
- {
- if (allocated != 0)
- b.free();
- allocated = 0;
- }
- void empty()
- {
- b.len = 0;
- }
- int8_t *grow(size_t s); // grow so that limit() += s
- int getByte(uint32_t i)
- {
- return *loc(i) & 0xFF;
- }
- void addByte(int8_t x)
- {
- *grow(1) = x;
- }
- void ensureSize(size_t s); // make sure allocated >= s
- void trimToSize()
- {
- if (allocated > size())
- b.realloc(allocated = size());
- }
- bool canAppend(size_t s)
- {
- return allocated > b.len + s;
- }
- bool isAllocated(int8_t *p)
- {
- return p >= base() && p <= end();
- } // asserts
- void set(bytes &src)
- {
- set(src.ptr, src.len);
- }
+ int8_t *base()
+ {
+ return b.ptr;
+ }
+ size_t size()
+ {
+ return b.len;
+ }
+ int8_t *limit()
+ {
+ return b.limit();
+ } // logical limit
+ void setLimit(int8_t *lp)
+ {
+ assert(isAllocated(lp));
+ b.len = lp - b.ptr;
+ }
+ int8_t *end()
+ {
+ return b.ptr + allocated;
+ } // physical limit
+ int8_t *loc(size_t o)
+ {
+ assert(o < b.len);
+ return b.ptr + o;
+ }
+ void init()
+ {
+ allocated = 0;
+ b.set(nullptr, 0);
+ }
+ void init(size_t s)
+ {
+ init();
+ ensureSize(s);
+ }
+ void free()
+ {
+ if (allocated != 0)
+ b.free();
+ allocated = 0;
+ }
+ void empty()
+ {
+ b.len = 0;
+ }
+ int8_t *grow(size_t s); // grow so that limit() += s
+ int getByte(uint32_t i)
+ {
+ return *loc(i) & 0xFF;
+ }
+ void addByte(int8_t x)
+ {
+ *grow(1) = x;
+ }
+ void ensureSize(size_t s); // make sure allocated >= s
+ void trimToSize()
+ {
+ if (allocated > size())
+ b.realloc(allocated = size());
+ }
+ bool canAppend(size_t s)
+ {
+ return allocated > b.len + s;
+ }
+ bool isAllocated(int8_t *p)
+ {
+ return p >= base() && p <= end();
+ } // asserts
+ void set(bytes &src)
+ {
+ set(src.ptr, src.len);
+ }
- void set(int8_t *ptr, size_t len)
- {
- b.set(ptr, len);
- allocated = 0; // mark as not reallocatable
- }
+ void set(int8_t *ptr, size_t len)
+ {
+ b.set(ptr, len);
+ allocated = 0; // mark as not reallocatable
+ }
- // block operations on resizing byte buffer:
- fillbytes &append(const void *ptr_, size_t len_)
- {
- memcpy(grow(len_), ptr_, len_);
- return (*this);
- }
- fillbytes &append(bytes &other)
- {
- return append(other.ptr, other.len);
- }
- fillbytes &append(const char *str)
- {
- return append(str, strlen(str));
- }
+ // block operations on resizing byte buffer:
+ fillbytes &append(const void *ptr_, size_t len_)
+ {
+ memcpy(grow(len_), ptr_, len_);
+ return (*this);
+ }
+ fillbytes &append(bytes &other)
+ {
+ return append(other.ptr, other.len);
+ }
+ fillbytes &append(const char *str)
+ {
+ return append(str, strlen(str));
+ }
};
struct ptrlist : fillbytes
{
- typedef const void *cvptr;
- int length()
- {
- return (int)(size() / sizeof(cvptr));
- }
- cvptr *base()
- {
- return (cvptr *)fillbytes::base();
- }
- cvptr &get(int i)
- {
- return *(cvptr *)loc(i * sizeof(cvptr));
- }
- cvptr *limit()
- {
- return (cvptr *)fillbytes::limit();
- }
- void add(cvptr x)
- {
- *(cvptr *)grow(sizeof(x)) = x;
- }
- void popTo(int l)
- {
- assert(l <= length());
- b.len = l * sizeof(cvptr);
- }
- int indexOf(cvptr x);
- bool contains(cvptr x)
- {
- return indexOf(x) >= 0;
- }
- void freeAll(); // frees every ptr on the list, plus the list itself
+ typedef const void *cvptr;
+ int length()
+ {
+ return (int)(size() / sizeof(cvptr));
+ }
+ cvptr *base()
+ {
+ return (cvptr *)fillbytes::base();
+ }
+ cvptr &get(int i)
+ {
+ return *(cvptr *)loc(i * sizeof(cvptr));
+ }
+ cvptr *limit()
+ {
+ return (cvptr *)fillbytes::limit();
+ }
+ void add(cvptr x)
+ {
+ *(cvptr *)grow(sizeof(x)) = x;
+ }
+ void popTo(int l)
+ {
+ assert(l <= length());
+ b.len = l * sizeof(cvptr);
+ }
+ int indexOf(cvptr x);
+ bool contains(cvptr x)
+ {
+ return indexOf(x) >= 0;
+ }
+ void freeAll(); // frees every ptr on the list, plus the list itself
};
// Use a macro rather than mess with subtle mismatches
// between member and non-member function pointers.
@@ -253,34 +253,34 @@ struct ptrlist : fillbytes
struct intlist : fillbytes
{
- int length()
- {
- return (int)(size() / sizeof(int));
- }
- int *base()
- {
- return (int *)fillbytes::base();
- }
- int &get(int i)
- {
- return *(int *)loc(i * sizeof(int));
- }
- int *limit()
- {
- return (int *)fillbytes::limit();
- }
- void add(int x)
- {
- *(int *)grow(sizeof(x)) = x;
- }
- void popTo(int l)
- {
- assert(l <= length());
- b.len = l * sizeof(int);
- }
- int indexOf(int x);
- bool contains(int x)
- {
- return indexOf(x) >= 0;
- }
+ int length()
+ {
+ return (int)(size() / sizeof(int));
+ }
+ int *base()
+ {
+ return (int *)fillbytes::base();
+ }
+ int &get(int i)
+ {
+ return *(int *)loc(i * sizeof(int));
+ }
+ int *limit()
+ {
+ return (int *)fillbytes::limit();
+ }
+ void add(int x)
+ {
+ *(int *)grow(sizeof(x)) = x;
+ }
+ void popTo(int l)
+ {
+ assert(l <= length());
+ b.len = l * sizeof(int);
+ }
+ int indexOf(int x);
+ bool contains(int x)
+ {
+ return indexOf(x) >= 0;
+ }
};
diff --git a/libraries/pack200/src/coding.cpp b/libraries/pack200/src/coding.cpp
index 6bd17a3c..8e872013 100644
--- a/libraries/pack200/src/coding.cpp
+++ b/libraries/pack200/src/coding.cpp
@@ -48,12 +48,12 @@ extern coding basic_codings[];
#pragma GCC diagnostic ignored "-Wunused-variable"
#define CODING_PRIVATE(spec) \
- int spec_ = spec; \
- int B = CODING_B(spec_); \
- int H = CODING_H(spec_); \
- int L = 256 - H; \
- int S = CODING_S(spec_); \
- int D = CODING_D(spec_)
+ int spec_ = spec; \
+ int B = CODING_B(spec_); \
+ int H = CODING_H(spec_); \
+ int L = 256 - H; \
+ int S = CODING_S(spec_); \
+ int D = CODING_D(spec_)
#define IS_NEG_CODE(S, codeVal) ((((int)(codeVal) + 1) & ((1 << S) - 1)) == 0)
@@ -61,568 +61,568 @@ extern coding basic_codings[];
static int decode_sign(int S, uint32_t ux)
{ // == Coding.decodeSign32
- assert(S > 0);
- uint32_t sigbits = (ux >> S);
- if (IS_NEG_CODE(S, ux))
- return (int)(~sigbits);
- else
- return (int)(ux - sigbits);
- // Note that (int)(ux-sigbits) can be negative, if ux is large enough.
+ assert(S > 0);
+ uint32_t sigbits = (ux >> S);
+ if (IS_NEG_CODE(S, ux))
+ return (int)(~sigbits);
+ else
+ return (int)(ux - sigbits);
+ // Note that (int)(ux-sigbits) can be negative, if ux is large enough.
}
coding *coding::init()
{
- if (umax > 0)
- return this; // already done
- assert(spec != 0); // sanity
-
- // fill in derived fields
- CODING_PRIVATE(spec);
-
- // Return nullptr if 'arb(BHSD)' parameter constraints are not met:
- if (B < 1 || B > B_MAX)
- return nullptr;
- if (H < 1 || H > 256)
- return nullptr;
- if (S < 0 || S > 2)
- return nullptr;
- if (D < 0 || D > 1)
- return nullptr;
- if (B == 1 && H != 256)
- return nullptr; // 1-byte coding must be fixed-size
- if (B >= 5 && H == 256)
- return nullptr; // no 5-byte fixed-size coding
-
- // first compute the range of the coding, in 64 bits
- int64_t range = 0;
- {
- int64_t H_i = 1;
- for (int i = 0; i < B; i++)
- {
- range += H_i;
- H_i *= H;
- }
- range *= L;
- range += H_i;
- }
- assert(range > 0); // no useless codings, please
-
- int this_umax;
-
- // now, compute min and max
- if (range >= ((int64_t)1 << 32))
- {
- this_umax = INT_MAX_VALUE;
- this->umin = INT_MIN_VALUE;
- this->max = INT_MAX_VALUE;
- this->min = INT_MIN_VALUE;
- }
- else
- {
- this_umax = (range > INT_MAX_VALUE) ? INT_MAX_VALUE : (int)range - 1;
- this->max = this_umax;
- this->min = this->umin = 0;
- if (S != 0 && range != 0)
- {
- int64_t maxPosCode = range - 1;
- int64_t maxNegCode = range - 1;
- while (IS_NEG_CODE(S, maxPosCode))
- --maxPosCode;
- while (!IS_NEG_CODE(S, maxNegCode))
- --maxNegCode;
- int maxPos = decode_sign(S, (uint32_t)maxPosCode);
- if (maxPos < 0)
- this->max = INT_MAX_VALUE; // 32-bit wraparound
- else
- this->max = maxPos;
- if (maxNegCode < 0)
- this->min = 0; // No negative codings at all.
- else
- this->min = decode_sign(S, (uint32_t)maxNegCode);
- }
- }
-
- assert(!(isFullRange | isSigned | isSubrange)); // init
- if (min < 0)
- this->isSigned = true;
- if (max < INT_MAX_VALUE && range <= INT_MAX_VALUE)
- this->isSubrange = true;
- if (max == INT_MAX_VALUE && min == INT_MIN_VALUE)
- this->isFullRange = true;
-
- // do this last, to reduce MT exposure (should have a membar too)
- this->umax = this_umax;
-
- return this;
+ if (umax > 0)
+ return this; // already done
+ assert(spec != 0); // sanity
+
+ // fill in derived fields
+ CODING_PRIVATE(spec);
+
+ // Return nullptr if 'arb(BHSD)' parameter constraints are not met:
+ if (B < 1 || B > B_MAX)
+ return nullptr;
+ if (H < 1 || H > 256)
+ return nullptr;
+ if (S < 0 || S > 2)
+ return nullptr;
+ if (D < 0 || D > 1)
+ return nullptr;
+ if (B == 1 && H != 256)
+ return nullptr; // 1-byte coding must be fixed-size
+ if (B >= 5 && H == 256)
+ return nullptr; // no 5-byte fixed-size coding
+
+ // first compute the range of the coding, in 64 bits
+ int64_t range = 0;
+ {
+ int64_t H_i = 1;
+ for (int i = 0; i < B; i++)
+ {
+ range += H_i;
+ H_i *= H;
+ }
+ range *= L;
+ range += H_i;
+ }
+ assert(range > 0); // no useless codings, please
+
+ int this_umax;
+
+ // now, compute min and max
+ if (range >= ((int64_t)1 << 32))
+ {
+ this_umax = INT_MAX_VALUE;
+ this->umin = INT_MIN_VALUE;
+ this->max = INT_MAX_VALUE;
+ this->min = INT_MIN_VALUE;
+ }
+ else
+ {
+ this_umax = (range > INT_MAX_VALUE) ? INT_MAX_VALUE : (int)range - 1;
+ this->max = this_umax;
+ this->min = this->umin = 0;
+ if (S != 0 && range != 0)
+ {
+ int64_t maxPosCode = range - 1;
+ int64_t maxNegCode = range - 1;
+ while (IS_NEG_CODE(S, maxPosCode))
+ --maxPosCode;
+ while (!IS_NEG_CODE(S, maxNegCode))
+ --maxNegCode;
+ int maxPos = decode_sign(S, (uint32_t)maxPosCode);
+ if (maxPos < 0)
+ this->max = INT_MAX_VALUE; // 32-bit wraparound
+ else
+ this->max = maxPos;
+ if (maxNegCode < 0)
+ this->min = 0; // No negative codings at all.
+ else
+ this->min = decode_sign(S, (uint32_t)maxNegCode);
+ }
+ }
+
+ assert(!(isFullRange | isSigned | isSubrange)); // init
+ if (min < 0)
+ this->isSigned = true;
+ if (max < INT_MAX_VALUE && range <= INT_MAX_VALUE)
+ this->isSubrange = true;
+ if (max == INT_MAX_VALUE && min == INT_MIN_VALUE)
+ this->isFullRange = true;
+
+ // do this last, to reduce MT exposure (should have a membar too)
+ this->umax = this_umax;
+
+ return this;
}
coding *coding::findBySpec(int spec)
{
- for (coding *scan = &basic_codings[0];; scan++)
- {
- if (scan->spec == spec)
- return scan->init();
- if (scan->spec == 0)
- break;
- }
- coding *ptr = NEW(coding, 1);
- if (!ptr)
- return nullptr;
- coding *c = ptr->initFrom(spec);
- if (c == nullptr)
- {
- ::free(ptr);
- }
- else
- // else caller should free it...
- c->isMalloc = true;
- return c;
+ for (coding *scan = &basic_codings[0];; scan++)
+ {
+ if (scan->spec == spec)
+ return scan->init();
+ if (scan->spec == 0)
+ break;
+ }
+ coding *ptr = NEW(coding, 1);
+ if (!ptr)
+ return nullptr;
+ coding *c = ptr->initFrom(spec);
+ if (c == nullptr)
+ {
+ ::free(ptr);
+ }
+ else
+ // else caller should free it...
+ c->isMalloc = true;
+ return c;
}
coding *coding::findBySpec(int B, int H, int S, int D)
{
- if (B < 1 || B > B_MAX)
- return nullptr;
- if (H < 1 || H > 256)
- return nullptr;
- if (S < 0 || S > 2)
- return nullptr;
- if (D < 0 || D > 1)
- return nullptr;
- return findBySpec(CODING_SPEC(B, H, S, D));
+ if (B < 1 || B > B_MAX)
+ return nullptr;
+ if (H < 1 || H > 256)
+ return nullptr;
+ if (S < 0 || S > 2)
+ return nullptr;
+ if (D < 0 || D > 1)
+ return nullptr;
+ return findBySpec(CODING_SPEC(B, H, S, D));
}
void coding::free()
{
- if (isMalloc)
- {
- ::free(this);
- }
+ if (isMalloc)
+ {
+ ::free(this);
+ }
}
void coding_method::reset(value_stream *state)
{
- assert(state->rp == state->rplimit); // not in mid-stream, please
- // assert(this == vs0.cm);
- state[0] = vs0;
- if (uValues != nullptr)
- {
- uValues->reset(state->helper());
- }
+ assert(state->rp == state->rplimit); // not in mid-stream, please
+ // assert(this == vs0.cm);
+ state[0] = vs0;
+ if (uValues != nullptr)
+ {
+ uValues->reset(state->helper());
+ }
}
uint32_t coding::parse(byte *&rp, int B, int H)
{
- int L = 256 - H;
- byte *ptr = rp;
- // hand peel the i==0 part of the loop:
- uint32_t b_i = *ptr++ & 0xFF;
- if (B == 1 || b_i < (uint32_t)L)
- {
- rp = ptr;
- return b_i;
- }
- uint32_t sum = b_i;
- uint32_t H_i = H;
- assert(B <= B_MAX);
- for (int i = 2; i <= B_MAX; i++)
- { // easy for compilers to unroll if desired
- b_i = *ptr++ & 0xFF;
- sum += b_i * H_i;
- if (i == B || b_i < (uint32_t)L)
- {
- rp = ptr;
- return sum;
- }
- H_i *= H;
- }
- assert(false);
- return 0;
+ int L = 256 - H;
+ byte *ptr = rp;
+ // hand peel the i==0 part of the loop:
+ uint32_t b_i = *ptr++ & 0xFF;
+ if (B == 1 || b_i < (uint32_t)L)
+ {
+ rp = ptr;
+ return b_i;
+ }
+ uint32_t sum = b_i;
+ uint32_t H_i = H;
+ assert(B <= B_MAX);
+ for (int i = 2; i <= B_MAX; i++)
+ { // easy for compilers to unroll if desired
+ b_i = *ptr++ & 0xFF;
+ sum += b_i * H_i;
+ if (i == B || b_i < (uint32_t)L)
+ {
+ rp = ptr;
+ return sum;
+ }
+ H_i *= H;
+ }
+ assert(false);
+ return 0;
}
uint32_t coding::parse_lgH(byte *&rp, int B, int H, int lgH)
{
- assert(H == (1 << lgH));
- int L = 256 - (1 << lgH);
- byte *ptr = rp;
- // hand peel the i==0 part of the loop:
- uint32_t b_i = *ptr++ & 0xFF;
- if (B == 1 || b_i < (uint32_t)L)
- {
- rp = ptr;
- return b_i;
- }
- uint32_t sum = b_i;
- uint32_t lg_H_i = lgH;
- assert(B <= B_MAX);
- for (int i = 2; i <= B_MAX; i++)
- { // easy for compilers to unroll if desired
- b_i = *ptr++ & 0xFF;
- sum += b_i << lg_H_i;
- if (i == B || b_i < (uint32_t)L)
- {
- rp = ptr;
- return sum;
- }
- lg_H_i += lgH;
- }
- assert(false);
- return 0;
+ assert(H == (1 << lgH));
+ int L = 256 - (1 << lgH);
+ byte *ptr = rp;
+ // hand peel the i==0 part of the loop:
+ uint32_t b_i = *ptr++ & 0xFF;
+ if (B == 1 || b_i < (uint32_t)L)
+ {
+ rp = ptr;
+ return b_i;
+ }
+ uint32_t sum = b_i;
+ uint32_t lg_H_i = lgH;
+ assert(B <= B_MAX);
+ for (int i = 2; i <= B_MAX; i++)
+ { // easy for compilers to unroll if desired
+ b_i = *ptr++ & 0xFF;
+ sum += b_i << lg_H_i;
+ if (i == B || b_i < (uint32_t)L)
+ {
+ rp = ptr;
+ return sum;
+ }
+ lg_H_i += lgH;
+ }
+ assert(false);
+ return 0;
}
static const char ERB[] = "EOF reading band";
void coding::parseMultiple(byte *&rp, int N, byte *limit, int B, int H)
{
- if (N < 0)
- {
- unpack_abort("bad value count");
- return;
- }
- byte *ptr = rp;
- if (B == 1 || H == 256)
- {
- size_t len = (size_t)N * B;
- if (len / B != (size_t)N || ptr + len > limit)
- {
- unpack_abort(ERB);
- return;
- }
- rp = ptr + len;
- return;
- }
- // Note: We assume rp has enough zero-padding.
- int L = 256 - H;
- int n = B;
- while (N > 0)
- {
- ptr += 1;
- if (--n == 0)
- {
- // end of encoding at B bytes, regardless of byte value
- }
- else
- {
- int b = (ptr[-1] & 0xFF);
- if (b >= L)
- {
- // keep going, unless we find a byte < L
- continue;
- }
- }
- // found the last byte
- N -= 1;
- n = B; // reset length counter
- // do an error check here
- if (ptr > limit)
- {
- unpack_abort(ERB);
- return;
- }
- }
- rp = ptr;
- return;
+ if (N < 0)
+ {
+ unpack_abort("bad value count");
+ return;
+ }
+ byte *ptr = rp;
+ if (B == 1 || H == 256)
+ {
+ size_t len = (size_t)N * B;
+ if (len / B != (size_t)N || ptr + len > limit)
+ {
+ unpack_abort(ERB);
+ return;
+ }
+ rp = ptr + len;
+ return;
+ }
+ // Note: We assume rp has enough zero-padding.
+ int L = 256 - H;
+ int n = B;
+ while (N > 0)
+ {
+ ptr += 1;
+ if (--n == 0)
+ {
+ // end of encoding at B bytes, regardless of byte value
+ }
+ else
+ {
+ int b = (ptr[-1] & 0xFF);
+ if (b >= L)
+ {
+ // keep going, unless we find a byte < L
+ continue;
+ }
+ }
+ // found the last byte
+ N -= 1;
+ n = B; // reset length counter
+ // do an error check here
+ if (ptr > limit)
+ {
+ unpack_abort(ERB);
+ return;
+ }
+ }
+ rp = ptr;
+ return;
}
bool value_stream::hasHelper()
{
- // If my coding method is a pop-style method,
- // then I need a second value stream to transmit
- // unfavored values.
- // This can be determined by examining fValues.
- return cm->fValues != nullptr;
+ // If my coding method is a pop-style method,
+ // then I need a second value stream to transmit
+ // unfavored values.
+ // This can be determined by examining fValues.
+ return cm->fValues != nullptr;
}
void value_stream::init(byte *rp_, byte *rplimit_, coding *defc)
{
- rp = rp_;
- rplimit = rplimit_;
- sum = 0;
- cm = nullptr; // no need in the simple case
- setCoding(defc);
+ rp = rp_;
+ rplimit = rplimit_;
+ sum = 0;
+ cm = nullptr; // no need in the simple case
+ setCoding(defc);
}
void value_stream::setCoding(coding *defc)
{
- if (defc == nullptr)
- {
- unpack_abort("bad coding");
- defc = coding::findByIndex(_meta_canon_min); // random pick for recovery
- }
-
- c = (*defc);
-
- // choose cmk
- cmk = cmk_ERROR;
- switch (c.spec)
- {
- case BYTE1_spec:
- cmk = cmk_BYTE1;
- break;
- case CHAR3_spec:
- cmk = cmk_CHAR3;
- break;
- case UNSIGNED5_spec:
- cmk = cmk_UNSIGNED5;
- break;
- case DELTA5_spec:
- cmk = cmk_DELTA5;
- break;
- case BCI5_spec:
- cmk = cmk_BCI5;
- break;
- case BRANCH5_spec:
- cmk = cmk_BRANCH5;
- break;
- default:
- if (c.D() == 0)
- {
- switch (c.S())
- {
- case 0:
- cmk = cmk_BHS0;
- break;
- case 1:
- cmk = cmk_BHS1;
- break;
- default:
- cmk = cmk_BHS;
- break;
- }
- }
- else
- {
- if (c.S() == 1)
- {
- if (c.isFullRange)
- cmk = cmk_BHS1D1full;
- if (c.isSubrange)
- cmk = cmk_BHS1D1sub;
- }
- if (cmk == cmk_ERROR)
- cmk = cmk_BHSD1;
- }
- }
+ if (defc == nullptr)
+ {
+ unpack_abort("bad coding");
+ defc = coding::findByIndex(_meta_canon_min); // random pick for recovery
+ }
+
+ c = (*defc);
+
+ // choose cmk
+ cmk = cmk_ERROR;
+ switch (c.spec)
+ {
+ case BYTE1_spec:
+ cmk = cmk_BYTE1;
+ break;
+ case CHAR3_spec:
+ cmk = cmk_CHAR3;
+ break;
+ case UNSIGNED5_spec:
+ cmk = cmk_UNSIGNED5;
+ break;
+ case DELTA5_spec:
+ cmk = cmk_DELTA5;
+ break;
+ case BCI5_spec:
+ cmk = cmk_BCI5;
+ break;
+ case BRANCH5_spec:
+ cmk = cmk_BRANCH5;
+ break;
+ default:
+ if (c.D() == 0)
+ {
+ switch (c.S())
+ {
+ case 0:
+ cmk = cmk_BHS0;
+ break;
+ case 1:
+ cmk = cmk_BHS1;
+ break;
+ default:
+ cmk = cmk_BHS;
+ break;
+ }
+ }
+ else
+ {
+ if (c.S() == 1)
+ {
+ if (c.isFullRange)
+ cmk = cmk_BHS1D1full;
+ if (c.isSubrange)
+ cmk = cmk_BHS1D1sub;
+ }
+ if (cmk == cmk_ERROR)
+ cmk = cmk_BHSD1;
+ }
+ }
}
static int getPopValue(value_stream *self, uint32_t uval)
{
- if (uval > 0)
- {
- // note that the initial parse performed a range check
- assert(uval <= (uint32_t)self->cm->fVlength);
- return self->cm->fValues[uval - 1];
- }
- else
- {
- // take an unfavored value
- return self->helper()->getInt();
- }
+ if (uval > 0)
+ {
+ // note that the initial parse performed a range check
+ assert(uval <= (uint32_t)self->cm->fVlength);
+ return self->cm->fValues[uval - 1];
+ }
+ else
+ {
+ // take an unfavored value
+ return self->helper()->getInt();
+ }
}
int coding::sumInUnsignedRange(int x, int y)
{
- assert(isSubrange);
- int range = (int)(umax + 1);
- assert(range > 0);
- x += y;
- if (x != (int)((int64_t)(x - y) + (int64_t)y))
- {
- // 32-bit overflow interferes with range reduction.
- // Back off from the overflow by adding a multiple of range:
- if (x < 0)
- {
- x -= range;
- assert(x >= 0);
- }
- else
- {
- x += range;
- assert(x < 0);
- }
- }
- if (x < 0)
- {
- x += range;
- if (x >= 0)
- return x;
- }
- else if (x >= range)
- {
- x -= range;
- if (x < range)
- return x;
- }
- else
- {
- // in range
- return x;
- }
- // do it the hard way
- x %= range;
- if (x < 0)
- x += range;
- return x;
+ assert(isSubrange);
+ int range = (int)(umax + 1);
+ assert(range > 0);
+ x += y;
+ if (x != (int)((int64_t)(x - y) + (int64_t)y))
+ {
+ // 32-bit overflow interferes with range reduction.
+ // Back off from the overflow by adding a multiple of range:
+ if (x < 0)
+ {
+ x -= range;
+ assert(x >= 0);
+ }
+ else
+ {
+ x += range;
+ assert(x < 0);
+ }
+ }
+ if (x < 0)
+ {
+ x += range;
+ if (x >= 0)
+ return x;
+ }
+ else if (x >= range)
+ {
+ x -= range;
+ if (x < range)
+ return x;
+ }
+ else
+ {
+ // in range
+ return x;
+ }
+ // do it the hard way
+ x %= range;
+ if (x < 0)
+ x += range;
+ return x;
}
static int getDeltaValue(value_stream *self, uint32_t uval, bool isSubrange)
{
- assert((uint32_t)(self->c.isSubrange) == (uint32_t)isSubrange);
- assert(self->c.isSubrange | self->c.isFullRange);
- if (isSubrange)
- return self->sum = self->c.sumInUnsignedRange(self->sum, (int)uval);
- else
- return self->sum += (int)uval;
+ assert((uint32_t)(self->c.isSubrange) == (uint32_t)isSubrange);
+ assert(self->c.isSubrange | self->c.isFullRange);
+ if (isSubrange)
+ return self->sum = self->c.sumInUnsignedRange(self->sum, (int)uval);
+ else
+ return self->sum += (int)uval;
}
bool value_stream::hasValue()
{
- if (rp < rplimit)
- return true;
- if (cm == nullptr)
- return false;
- if (cm->next == nullptr)
- return false;
- cm->next->reset(this);
- return hasValue();
+ if (rp < rplimit)
+ return true;
+ if (cm == nullptr)
+ return false;
+ if (cm->next == nullptr)
+ return false;
+ cm->next->reset(this);
+ return hasValue();
}
int value_stream::getInt()
{
- if (rp >= rplimit)
- {
- // Advance to next coding segment.
- if (rp > rplimit || cm == nullptr || cm->next == nullptr)
- {
- // Must perform this check and throw an exception on bad input.
- unpack_abort(ERB);
- return 0;
- }
- cm->next->reset(this);
- return getInt();
- }
-
- CODING_PRIVATE(c.spec);
- uint32_t uval;
- enum
- {
- B5 = 5,
- B3 = 3,
- H128 = 128,
- H64 = 64,
- H4 = 4
- };
- switch (cmk)
- {
- case cmk_BHS:
- assert(D == 0);
- uval = coding::parse(rp, B, H);
- if (S == 0)
- return (int)uval;
- return decode_sign(S, uval);
-
- case cmk_BHS0:
- assert(S == 0 && D == 0);
- uval = coding::parse(rp, B, H);
- return (int)uval;
-
- case cmk_BHS1:
- assert(S == 1 && D == 0);
- uval = coding::parse(rp, B, H);
- return DECODE_SIGN_S1(uval);
-
- case cmk_BYTE1:
- assert(c.spec == BYTE1_spec);
- assert(B == 1 && H == 256 && S == 0 && D == 0);
- return *rp++ & 0xFF;
-
- case cmk_CHAR3:
- assert(c.spec == CHAR3_spec);
- assert(B == B3 && H == H128 && S == 0 && D == 0);
- return coding::parse_lgH(rp, B3, H128, 7);
-
- case cmk_UNSIGNED5:
- assert(c.spec == UNSIGNED5_spec);
- assert(B == B5 && H == H64 && S == 0 && D == 0);
- return coding::parse_lgH(rp, B5, H64, 6);
-
- case cmk_BHSD1:
- assert(D == 1);
- uval = coding::parse(rp, B, H);
- if (S != 0)
- uval = (uint32_t)decode_sign(S, uval);
- return getDeltaValue(this, uval, (bool)c.isSubrange);
-
- case cmk_BHS1D1full:
- assert(S == 1 && D == 1 && c.isFullRange);
- uval = coding::parse(rp, B, H);
- uval = (uint32_t)DECODE_SIGN_S1(uval);
- return getDeltaValue(this, uval, false);
-
- case cmk_BHS1D1sub:
- assert(S == 1 && D == 1 && c.isSubrange);
- uval = coding::parse(rp, B, H);
- uval = (uint32_t)DECODE_SIGN_S1(uval);
- return getDeltaValue(this, uval, true);
-
- case cmk_DELTA5:
- assert(c.spec == DELTA5_spec);
- assert(B == B5 && H == H64 && S == 1 && D == 1 && c.isFullRange);
- uval = coding::parse_lgH(rp, B5, H64, 6);
- sum += DECODE_SIGN_S1(uval);
- return sum;
-
- case cmk_BCI5:
- assert(c.spec == BCI5_spec);
- assert(B == B5 && H == H4 && S == 0 && D == 0);
- return coding::parse_lgH(rp, B5, H4, 2);
-
- case cmk_BRANCH5:
- assert(c.spec == BRANCH5_spec);
- assert(B == B5 && H == H4 && S == 2 && D == 0);
- uval = coding::parse_lgH(rp, B5, H4, 2);
- return decode_sign(S, uval);
-
- case cmk_pop:
- uval = coding::parse(rp, B, H);
- if (S != 0)
- {
- uval = (uint32_t)decode_sign(S, uval);
- }
- if (D != 0)
- {
- assert(c.isSubrange | c.isFullRange);
- if (c.isSubrange)
- sum = c.sumInUnsignedRange(sum, (int)uval);
- else
- sum += (int)uval;
- uval = (uint32_t)sum;
- }
- return getPopValue(this, uval);
-
- case cmk_pop_BHS0:
- assert(S == 0 && D == 0);
- uval = coding::parse(rp, B, H);
- return getPopValue(this, uval);
-
- case cmk_pop_BYTE1:
- assert(c.spec == BYTE1_spec);
- assert(B == 1 && H == 256 && S == 0 && D == 0);
- return getPopValue(this, *rp++ & 0xFF);
-
- default:
- break;
- }
- assert(false);
- return 0;
+ if (rp >= rplimit)
+ {
+ // Advance to next coding segment.
+ if (rp > rplimit || cm == nullptr || cm->next == nullptr)
+ {
+ // Must perform this check and throw an exception on bad input.
+ unpack_abort(ERB);
+ return 0;
+ }
+ cm->next->reset(this);
+ return getInt();
+ }
+
+ CODING_PRIVATE(c.spec);
+ uint32_t uval;
+ enum
+ {
+ B5 = 5,
+ B3 = 3,
+ H128 = 128,
+ H64 = 64,
+ H4 = 4
+ };
+ switch (cmk)
+ {
+ case cmk_BHS:
+ assert(D == 0);
+ uval = coding::parse(rp, B, H);
+ if (S == 0)
+ return (int)uval;
+ return decode_sign(S, uval);
+
+ case cmk_BHS0:
+ assert(S == 0 && D == 0);
+ uval = coding::parse(rp, B, H);
+ return (int)uval;
+
+ case cmk_BHS1:
+ assert(S == 1 && D == 0);
+ uval = coding::parse(rp, B, H);
+ return DECODE_SIGN_S1(uval);
+
+ case cmk_BYTE1:
+ assert(c.spec == BYTE1_spec);
+ assert(B == 1 && H == 256 && S == 0 && D == 0);
+ return *rp++ & 0xFF;
+
+ case cmk_CHAR3:
+ assert(c.spec == CHAR3_spec);
+ assert(B == B3 && H == H128 && S == 0 && D == 0);
+ return coding::parse_lgH(rp, B3, H128, 7);
+
+ case cmk_UNSIGNED5:
+ assert(c.spec == UNSIGNED5_spec);
+ assert(B == B5 && H == H64 && S == 0 && D == 0);
+ return coding::parse_lgH(rp, B5, H64, 6);
+
+ case cmk_BHSD1:
+ assert(D == 1);
+ uval = coding::parse(rp, B, H);
+ if (S != 0)
+ uval = (uint32_t)decode_sign(S, uval);
+ return getDeltaValue(this, uval, (bool)c.isSubrange);
+
+ case cmk_BHS1D1full:
+ assert(S == 1 && D == 1 && c.isFullRange);
+ uval = coding::parse(rp, B, H);
+ uval = (uint32_t)DECODE_SIGN_S1(uval);
+ return getDeltaValue(this, uval, false);
+
+ case cmk_BHS1D1sub:
+ assert(S == 1 && D == 1 && c.isSubrange);
+ uval = coding::parse(rp, B, H);
+ uval = (uint32_t)DECODE_SIGN_S1(uval);
+ return getDeltaValue(this, uval, true);
+
+ case cmk_DELTA5:
+ assert(c.spec == DELTA5_spec);
+ assert(B == B5 && H == H64 && S == 1 && D == 1 && c.isFullRange);
+ uval = coding::parse_lgH(rp, B5, H64, 6);
+ sum += DECODE_SIGN_S1(uval);
+ return sum;
+
+ case cmk_BCI5:
+ assert(c.spec == BCI5_spec);
+ assert(B == B5 && H == H4 && S == 0 && D == 0);
+ return coding::parse_lgH(rp, B5, H4, 2);
+
+ case cmk_BRANCH5:
+ assert(c.spec == BRANCH5_spec);
+ assert(B == B5 && H == H4 && S == 2 && D == 0);
+ uval = coding::parse_lgH(rp, B5, H4, 2);
+ return decode_sign(S, uval);
+
+ case cmk_pop:
+ uval = coding::parse(rp, B, H);
+ if (S != 0)
+ {
+ uval = (uint32_t)decode_sign(S, uval);
+ }
+ if (D != 0)
+ {
+ assert(c.isSubrange | c.isFullRange);
+ if (c.isSubrange)
+ sum = c.sumInUnsignedRange(sum, (int)uval);
+ else
+ sum += (int)uval;
+ uval = (uint32_t)sum;
+ }
+ return getPopValue(this, uval);
+
+ case cmk_pop_BHS0:
+ assert(S == 0 && D == 0);
+ uval = coding::parse(rp, B, H);
+ return getPopValue(this, uval);
+
+ case cmk_pop_BYTE1:
+ assert(c.spec == BYTE1_spec);
+ assert(B == 1 && H == 256 && S == 0 && D == 0);
+ return getPopValue(this, *rp++ & 0xFF);
+
+ default:
+ break;
+ }
+ assert(false);
+ return 0;
}
static int moreCentral(int x, int y)
{ // used to find end of Pop.{F}
- // Suggested implementation from the Pack200 specification:
- uint32_t kx = (x >> 31) ^ (x << 1);
- uint32_t ky = (y >> 31) ^ (y << 1);
- return (kx < ky ? x : y);
+ // Suggested implementation from the Pack200 specification:
+ uint32_t kx = (x >> 31) ^ (x << 1);
+ uint32_t ky = (y >> 31) ^ (y << 1);
+ return (kx < ky ? x : y);
}
// static maybe_inline
// int moreCentral2(int x, int y, int min) {
@@ -641,7 +641,7 @@ static const byte *no_meta[] = {nullptr};
#define NO_META (*(byte **)no_meta)
enum
{
- POP_FAVORED_N = -2
+ POP_FAVORED_N = -2
};
// mode bits
@@ -650,395 +650,395 @@ enum
// This function knows all about meta-coding.
void coding_method::init(byte *&band_rp, byte *band_limit, byte *&meta_rp, int mode,
- coding *defc, int N, intlist *valueSink)
+ coding *defc, int N, intlist *valueSink)
{
- assert(N != 0);
-
- assert(u != nullptr); // must be pre-initialized
- // if (u == nullptr) u = unpacker::current(); // expensive
-
- int op = (meta_rp == nullptr) ? _meta_default : (*meta_rp++ & 0xFF);
- coding *foundc = nullptr;
- coding *to_free = nullptr;
-
- if (op == _meta_default)
- {
- foundc = defc;
- // and fall through
- }
- else if (op >= _meta_canon_min && op <= _meta_canon_max)
- {
- foundc = coding::findByIndex(op);
- // and fall through
- }
- else if (op == _meta_arb)
- {
- int args = (*meta_rp++ & 0xFF);
- // args = (D:[0..1] + 2*S[0..2] + 8*(B:[1..5]-1))
- int D = ((args >> 0) & 1);
- int S = ((args >> 1) & 3);
- int B = ((args >> 3) & -1) + 1;
- // & (H[1..256]-1)
- int H = (*meta_rp++ & 0xFF) + 1;
- foundc = coding::findBySpec(B, H, S, D);
- to_free = foundc; // findBySpec may dynamically allocate
- if (foundc == nullptr)
- {
- unpack_abort("illegal arbitrary coding");
- return;
- }
- // and fall through
- }
- else if (op >= _meta_run && op < _meta_pop)
- {
- int args = (op - _meta_run);
- // args: KX:[0..3] + 4*(KBFlag:[0..1]) + 8*(ABDef:[0..2])
- int KX = ((args >> 0) & 3);
- int KBFlag = ((args >> 2) & 1);
- int ABDef = ((args >> 3) & -1);
- assert(ABDef <= 2);
- // & KB: one of [0..255] if KBFlag=1
- int KB = (!KBFlag ? 3 : (*meta_rp++ & 0xFF));
- int K = (KB + 1) << (KX * 4);
- int N2 = (N >= 0) ? N - K : N;
- if (N == 0 || (N2 <= 0 && N2 != N))
- {
- unpack_abort("illegal run encoding");
- }
- if ((mode & DISABLE_RUN) != 0)
- {
- unpack_abort("illegal nested run encoding");
- }
-
- // & Enc{ ACode } if ADef=0 (ABDef != 1)
- // No direct nesting of 'run' in ACode, but in BCode it's OK.
- int disRun = mode | DISABLE_RUN;
- if (ABDef == 1)
- {
- this->init(band_rp, band_limit, NO_META, disRun, defc, K, valueSink);
- }
- else
- {
- this->init(band_rp, band_limit, meta_rp, disRun, defc, K, valueSink);
- }
-
- // & Enc{ BCode } if BDef=0 (ABDef != 2)
- coding_method *tail = U_NEW(coding_method, 1);
- if (!tail)
- return;
- tail->u = u;
-
- // The 'run' codings may be nested indirectly via 'pop' codings.
- // This means that this->next may already be filled in, if
- // ACode was of type 'pop' with a 'run' token coding.
- // No problem: Just chain the upcoming BCode onto the end.
- for (coding_method *self = this;; self = self->next)
- {
- if (self->next == nullptr)
- {
- self->next = tail;
- break;
- }
- }
-
- if (ABDef == 2)
- {
- tail->init(band_rp, band_limit, NO_META, mode, defc, N2, valueSink);
- }
- else
- {
- tail->init(band_rp, band_limit, meta_rp, mode, defc, N2, valueSink);
- }
- // Note: The preceding calls to init should be tail-recursive.
-
- return; // done; no falling through
- }
- else if (op >= _meta_pop && op < _meta_limit)
- {
- int args = (op - _meta_pop);
- // args: (FDef:[0..1]) + 2*UDef:[0..1] + 4*(TDefL:[0..11])
- int FDef = ((args >> 0) & 1);
- int UDef = ((args >> 1) & 1);
- int TDefL = ((args >> 2) & -1);
- assert(TDefL <= 11);
- int TDef = (TDefL > 0);
- int TL = (TDefL <= 6) ? (2 << TDefL) : (256 - (4 << (11 - TDefL)));
- int TH = (256 - TL);
- if (N <= 0)
- {
- unpack_abort("illegal pop encoding");
- }
- if ((mode & DISABLE_POP) != 0)
- {
- unpack_abort("illegal nested pop encoding");
- }
-
- // No indirect nesting of 'pop', but 'run' is OK.
- int disPop = DISABLE_POP;
-
- // & Enc{ FCode } if FDef=0
- int FN = POP_FAVORED_N;
- assert(valueSink == nullptr);
- intlist fValueSink;
- fValueSink.init();
- coding_method fval;
- BYTES_OF(fval).clear();
- fval.u = u;
- if (FDef != 0)
- {
- fval.init(band_rp, band_limit, NO_META, disPop, defc, FN, &fValueSink);
- }
- else
- {
- fval.init(band_rp, band_limit, meta_rp, disPop, defc, FN, &fValueSink);
- }
- bytes fvbuf;
- fValues = (u->saveTo(fvbuf, fValueSink.b), (int *)fvbuf.ptr);
- fVlength = fValueSink.length(); // i.e., the parameter K
- fValueSink.free();
-
- // Skip the first {F} run in all subsequent passes.
- // The next call to this->init(...) will set vs0.rp to point after the {F}.
-
- // & Enc{ TCode } if TDef=0 (TDefL==0)
- if (TDef != 0)
- {
- coding *tcode = coding::findBySpec(1, 256); // BYTE1
- // find the most narrowly sufficient code:
- for (int B = 2; B <= B_MAX; B++)
- {
- if (fVlength <= tcode->umax)
- break; // found it
- tcode->free();
- tcode = coding::findBySpec(B, TH);
- if (!tcode)
- return;
- }
- if (!(fVlength <= tcode->umax))
- {
- unpack_abort("pop.L value too small");
- }
- this->init(band_rp, band_limit, NO_META, disPop, tcode, N, nullptr);
- tcode->free();
- }
- else
- {
- this->init(band_rp, band_limit, meta_rp, disPop, defc, N, nullptr);
- }
-
- // Count the number of zero tokens right now.
- // Also verify that they are in bounds.
- int UN = 0; // one {U} for each zero in {T}
- value_stream vs = vs0;
- for (int i = 0; i < N; i++)
- {
- uint32_t val = vs.getInt();
- if (val == 0)
- UN += 1;
- if (!(val <= (uint32_t)fVlength))
- {
- unpack_abort("pop token out of range");
- }
- }
- vs.done();
-
- // & Enc{ UCode } if UDef=0
- if (UN != 0)
- {
- uValues = U_NEW(coding_method, 1);
- if (uValues == nullptr)
- return;
- uValues->u = u;
- if (UDef != 0)
- {
- uValues->init(band_rp, band_limit, NO_META, disPop, defc, UN, nullptr);
- }
- else
- {
- uValues->init(band_rp, band_limit, meta_rp, disPop, defc, UN, nullptr);
- }
- }
- else
- {
- if (UDef == 0)
- {
- int uop = (*meta_rp++ & 0xFF);
- if (uop > _meta_canon_max)
- // %%% Spec. requires the more strict (uop != _meta_default).
- unpack_abort("bad meta-coding for empty pop/U");
- }
- }
-
- // Bug fix for 6259542
- // Last of all, adjust vs0.cmk to the 'pop' flavor
- for (coding_method *self = this; self != nullptr; self = self->next)
- {
- coding_method_kind cmk2 = cmk_pop;
- switch (self->vs0.cmk)
- {
- case cmk_BHS0:
- cmk2 = cmk_pop_BHS0;
- break;
- case cmk_BYTE1:
- cmk2 = cmk_pop_BYTE1;
- break;
- default:
- break;
- }
- self->vs0.cmk = cmk2;
- if (self != this)
- {
- assert(self->fValues == nullptr); // no double init
- self->fValues = this->fValues;
- self->fVlength = this->fVlength;
- assert(self->uValues == nullptr); // must stay nullptr
- }
- }
-
- return; // done; no falling through
- }
- else
- {
- unpack_abort("bad meta-coding");
- }
-
- // Common code here skips a series of values with one coding.
- assert(foundc != nullptr);
-
- assert(vs0.cmk == cmk_ERROR); // no garbage, please
- assert(vs0.rp == nullptr); // no garbage, please
- assert(vs0.rplimit == nullptr); // no garbage, please
- assert(vs0.sum == 0); // no garbage, please
-
- vs0.init(band_rp, band_limit, foundc);
-
- // Done with foundc. Free if necessary.
- if (to_free != nullptr)
- {
- to_free->free();
- to_free = nullptr;
- }
- foundc = nullptr;
-
- coding &c = vs0.c;
- CODING_PRIVATE(c.spec);
- // assert sane N
- assert((uint32_t)N < INT_MAX_VALUE || N == POP_FAVORED_N);
-
- // Look at the values, or at least skip over them quickly.
- if (valueSink == nullptr)
- {
- // Skip and ignore values in the first pass.
- c.parseMultiple(band_rp, N, band_limit, B, H);
- }
- else if (N >= 0)
- {
- // Pop coding, {F} sequence, initial run of values...
- assert((mode & DISABLE_POP) != 0);
- value_stream vs = vs0;
- for (int n = 0; n < N; n++)
- {
- int val = vs.getInt();
- valueSink->add(val);
- }
- band_rp = vs.rp;
- }
- else
- {
- // Pop coding, {F} sequence, final run of values...
- assert((mode & DISABLE_POP) != 0);
- assert(N == POP_FAVORED_N);
- int min = INT_MIN_VALUE; // farthest from the center
- // min2 is based on the buggy specification of centrality in version 150.7
- // no known implementations transmit this value, but just in case...
- // int min2 = INT_MIN_VALUE;
- int last = 0;
- // if there were initial runs, find the potential sentinels in them:
- for (int i = 0; i < valueSink->length(); i++)
- {
- last = valueSink->get(i);
- min = moreCentral(min, last);
- // min2 = moreCentral2(min2, last, min);
- }
- value_stream vs = vs0;
- for (;;)
- {
- int val = vs.getInt();
- if (valueSink->length() > 0 && (val == last || val == min)) //|| val == min2
- break;
- valueSink->add(val);
- last = val;
- min = moreCentral(min, last);
- // min2 = moreCentral2(min2, last, min);
- }
- band_rp = vs.rp;
- }
-
- // Get an accurate upper limit now.
- vs0.rplimit = band_rp;
- vs0.cm = this;
-
- return; // success
+ assert(N != 0);
+
+ assert(u != nullptr); // must be pre-initialized
+ // if (u == nullptr) u = unpacker::current(); // expensive
+
+ int op = (meta_rp == nullptr) ? _meta_default : (*meta_rp++ & 0xFF);
+ coding *foundc = nullptr;
+ coding *to_free = nullptr;
+
+ if (op == _meta_default)
+ {
+ foundc = defc;
+ // and fall through
+ }
+ else if (op >= _meta_canon_min && op <= _meta_canon_max)
+ {
+ foundc = coding::findByIndex(op);
+ // and fall through
+ }
+ else if (op == _meta_arb)
+ {
+ int args = (*meta_rp++ & 0xFF);
+ // args = (D:[0..1] + 2*S[0..2] + 8*(B:[1..5]-1))
+ int D = ((args >> 0) & 1);
+ int S = ((args >> 1) & 3);
+ int B = ((args >> 3) & -1) + 1;
+ // & (H[1..256]-1)
+ int H = (*meta_rp++ & 0xFF) + 1;
+ foundc = coding::findBySpec(B, H, S, D);
+ to_free = foundc; // findBySpec may dynamically allocate
+ if (foundc == nullptr)
+ {
+ unpack_abort("illegal arbitrary coding");
+ return;
+ }
+ // and fall through
+ }
+ else if (op >= _meta_run && op < _meta_pop)
+ {
+ int args = (op - _meta_run);
+ // args: KX:[0..3] + 4*(KBFlag:[0..1]) + 8*(ABDef:[0..2])
+ int KX = ((args >> 0) & 3);
+ int KBFlag = ((args >> 2) & 1);
+ int ABDef = ((args >> 3) & -1);
+ assert(ABDef <= 2);
+ // & KB: one of [0..255] if KBFlag=1
+ int KB = (!KBFlag ? 3 : (*meta_rp++ & 0xFF));
+ int K = (KB + 1) << (KX * 4);
+ int N2 = (N >= 0) ? N - K : N;
+ if (N == 0 || (N2 <= 0 && N2 != N))
+ {
+ unpack_abort("illegal run encoding");
+ }
+ if ((mode & DISABLE_RUN) != 0)
+ {
+ unpack_abort("illegal nested run encoding");
+ }
+
+ // & Enc{ ACode } if ADef=0 (ABDef != 1)
+ // No direct nesting of 'run' in ACode, but in BCode it's OK.
+ int disRun = mode | DISABLE_RUN;
+ if (ABDef == 1)
+ {
+ this->init(band_rp, band_limit, NO_META, disRun, defc, K, valueSink);
+ }
+ else
+ {
+ this->init(band_rp, band_limit, meta_rp, disRun, defc, K, valueSink);
+ }
+
+ // & Enc{ BCode } if BDef=0 (ABDef != 2)
+ coding_method *tail = U_NEW(coding_method, 1);
+ if (!tail)
+ return;
+ tail->u = u;
+
+ // The 'run' codings may be nested indirectly via 'pop' codings.
+ // This means that this->next may already be filled in, if
+ // ACode was of type 'pop' with a 'run' token coding.
+ // No problem: Just chain the upcoming BCode onto the end.
+ for (coding_method *self = this;; self = self->next)
+ {
+ if (self->next == nullptr)
+ {
+ self->next = tail;
+ break;
+ }
+ }
+
+ if (ABDef == 2)
+ {
+ tail->init(band_rp, band_limit, NO_META, mode, defc, N2, valueSink);
+ }
+ else
+ {
+ tail->init(band_rp, band_limit, meta_rp, mode, defc, N2, valueSink);
+ }
+ // Note: The preceding calls to init should be tail-recursive.
+
+ return; // done; no falling through
+ }
+ else if (op >= _meta_pop && op < _meta_limit)
+ {
+ int args = (op - _meta_pop);
+ // args: (FDef:[0..1]) + 2*UDef:[0..1] + 4*(TDefL:[0..11])
+ int FDef = ((args >> 0) & 1);
+ int UDef = ((args >> 1) & 1);
+ int TDefL = ((args >> 2) & -1);
+ assert(TDefL <= 11);
+ int TDef = (TDefL > 0);
+ int TL = (TDefL <= 6) ? (2 << TDefL) : (256 - (4 << (11 - TDefL)));
+ int TH = (256 - TL);
+ if (N <= 0)
+ {
+ unpack_abort("illegal pop encoding");
+ }
+ if ((mode & DISABLE_POP) != 0)
+ {
+ unpack_abort("illegal nested pop encoding");
+ }
+
+ // No indirect nesting of 'pop', but 'run' is OK.
+ int disPop = DISABLE_POP;
+
+ // & Enc{ FCode } if FDef=0
+ int FN = POP_FAVORED_N;
+ assert(valueSink == nullptr);
+ intlist fValueSink;
+ fValueSink.init();
+ coding_method fval;
+ BYTES_OF(fval).clear();
+ fval.u = u;
+ if (FDef != 0)
+ {
+ fval.init(band_rp, band_limit, NO_META, disPop, defc, FN, &fValueSink);
+ }
+ else
+ {
+ fval.init(band_rp, band_limit, meta_rp, disPop, defc, FN, &fValueSink);
+ }
+ bytes fvbuf;
+ fValues = (u->saveTo(fvbuf, fValueSink.b), (int *)fvbuf.ptr);
+ fVlength = fValueSink.length(); // i.e., the parameter K
+ fValueSink.free();
+
+ // Skip the first {F} run in all subsequent passes.
+ // The next call to this->init(...) will set vs0.rp to point after the {F}.
+
+ // & Enc{ TCode } if TDef=0 (TDefL==0)
+ if (TDef != 0)
+ {
+ coding *tcode = coding::findBySpec(1, 256); // BYTE1
+ // find the most narrowly sufficient code:
+ for (int B = 2; B <= B_MAX; B++)
+ {
+ if (fVlength <= tcode->umax)
+ break; // found it
+ tcode->free();
+ tcode = coding::findBySpec(B, TH);
+ if (!tcode)
+ return;
+ }
+ if (!(fVlength <= tcode->umax))
+ {
+ unpack_abort("pop.L value too small");
+ }
+ this->init(band_rp, band_limit, NO_META, disPop, tcode, N, nullptr);
+ tcode->free();
+ }
+ else
+ {
+ this->init(band_rp, band_limit, meta_rp, disPop, defc, N, nullptr);
+ }
+
+ // Count the number of zero tokens right now.
+ // Also verify that they are in bounds.
+ int UN = 0; // one {U} for each zero in {T}
+ value_stream vs = vs0;
+ for (int i = 0; i < N; i++)
+ {
+ uint32_t val = vs.getInt();
+ if (val == 0)
+ UN += 1;
+ if (!(val <= (uint32_t)fVlength))
+ {
+ unpack_abort("pop token out of range");
+ }
+ }
+ vs.done();
+
+ // & Enc{ UCode } if UDef=0
+ if (UN != 0)
+ {
+ uValues = U_NEW(coding_method, 1);
+ if (uValues == nullptr)
+ return;
+ uValues->u = u;
+ if (UDef != 0)
+ {
+ uValues->init(band_rp, band_limit, NO_META, disPop, defc, UN, nullptr);
+ }
+ else
+ {
+ uValues->init(band_rp, band_limit, meta_rp, disPop, defc, UN, nullptr);
+ }
+ }
+ else
+ {
+ if (UDef == 0)
+ {
+ int uop = (*meta_rp++ & 0xFF);
+ if (uop > _meta_canon_max)
+ // %%% Spec. requires the more strict (uop != _meta_default).
+ unpack_abort("bad meta-coding for empty pop/U");
+ }
+ }
+
+ // Bug fix for 6259542
+ // Last of all, adjust vs0.cmk to the 'pop' flavor
+ for (coding_method *self = this; self != nullptr; self = self->next)
+ {
+ coding_method_kind cmk2 = cmk_pop;
+ switch (self->vs0.cmk)
+ {
+ case cmk_BHS0:
+ cmk2 = cmk_pop_BHS0;
+ break;
+ case cmk_BYTE1:
+ cmk2 = cmk_pop_BYTE1;
+ break;
+ default:
+ break;
+ }
+ self->vs0.cmk = cmk2;
+ if (self != this)
+ {
+ assert(self->fValues == nullptr); // no double init
+ self->fValues = this->fValues;
+ self->fVlength = this->fVlength;
+ assert(self->uValues == nullptr); // must stay nullptr
+ }
+ }
+
+ return; // done; no falling through
+ }
+ else
+ {
+ unpack_abort("bad meta-coding");
+ }
+
+ // Common code here skips a series of values with one coding.
+ assert(foundc != nullptr);
+
+ assert(vs0.cmk == cmk_ERROR); // no garbage, please
+ assert(vs0.rp == nullptr); // no garbage, please
+ assert(vs0.rplimit == nullptr); // no garbage, please
+ assert(vs0.sum == 0); // no garbage, please
+
+ vs0.init(band_rp, band_limit, foundc);
+
+ // Done with foundc. Free if necessary.
+ if (to_free != nullptr)
+ {
+ to_free->free();
+ to_free = nullptr;
+ }
+ foundc = nullptr;
+
+ coding &c = vs0.c;
+ CODING_PRIVATE(c.spec);
+ // assert sane N
+ assert((uint32_t)N < INT_MAX_VALUE || N == POP_FAVORED_N);
+
+ // Look at the values, or at least skip over them quickly.
+ if (valueSink == nullptr)
+ {
+ // Skip and ignore values in the first pass.
+ c.parseMultiple(band_rp, N, band_limit, B, H);
+ }
+ else if (N >= 0)
+ {
+ // Pop coding, {F} sequence, initial run of values...
+ assert((mode & DISABLE_POP) != 0);
+ value_stream vs = vs0;
+ for (int n = 0; n < N; n++)
+ {
+ int val = vs.getInt();
+ valueSink->add(val);
+ }
+ band_rp = vs.rp;
+ }
+ else
+ {
+ // Pop coding, {F} sequence, final run of values...
+ assert((mode & DISABLE_POP) != 0);
+ assert(N == POP_FAVORED_N);
+ int min = INT_MIN_VALUE; // farthest from the center
+ // min2 is based on the buggy specification of centrality in version 150.7
+ // no known implementations transmit this value, but just in case...
+ // int min2 = INT_MIN_VALUE;
+ int last = 0;
+ // if there were initial runs, find the potential sentinels in them:
+ for (int i = 0; i < valueSink->length(); i++)
+ {
+ last = valueSink->get(i);
+ min = moreCentral(min, last);
+ // min2 = moreCentral2(min2, last, min);
+ }
+ value_stream vs = vs0;
+ for (;;)
+ {
+ int val = vs.getInt();
+ if (valueSink->length() > 0 && (val == last || val == min)) //|| val == min2
+ break;
+ valueSink->add(val);
+ last = val;
+ min = moreCentral(min, last);
+ // min2 = moreCentral2(min2, last, min);
+ }
+ band_rp = vs.rp;
+ }
+
+ // Get an accurate upper limit now.
+ vs0.rplimit = band_rp;
+ vs0.cm = this;
+
+ return; // success
}
coding basic_codings[] = {
- // This one is not a usable irregular coding, but is used by cp_Utf8_chars.
- CODING_INIT(3, 128, 0, 0),
-
- // Fixed-length codings:
- CODING_INIT(1, 256, 0, 0), CODING_INIT(1, 256, 1, 0), CODING_INIT(1, 256, 0, 1),
- CODING_INIT(1, 256, 1, 1), CODING_INIT(2, 256, 0, 0), CODING_INIT(2, 256, 1, 0),
- CODING_INIT(2, 256, 0, 1), CODING_INIT(2, 256, 1, 1), CODING_INIT(3, 256, 0, 0),
- CODING_INIT(3, 256, 1, 0), CODING_INIT(3, 256, 0, 1), CODING_INIT(3, 256, 1, 1),
- CODING_INIT(4, 256, 0, 0), CODING_INIT(4, 256, 1, 0), CODING_INIT(4, 256, 0, 1),
- CODING_INIT(4, 256, 1, 1),
-
- // Full-range variable-length codings:
- CODING_INIT(5, 4, 0, 0), CODING_INIT(5, 4, 1, 0), CODING_INIT(5, 4, 2, 0),
- CODING_INIT(5, 16, 0, 0), CODING_INIT(5, 16, 1, 0), CODING_INIT(5, 16, 2, 0),
- CODING_INIT(5, 32, 0, 0), CODING_INIT(5, 32, 1, 0), CODING_INIT(5, 32, 2, 0),
- CODING_INIT(5, 64, 0, 0), CODING_INIT(5, 64, 1, 0), CODING_INIT(5, 64, 2, 0),
- CODING_INIT(5, 128, 0, 0), CODING_INIT(5, 128, 1, 0), CODING_INIT(5, 128, 2, 0),
- CODING_INIT(5, 4, 0, 1), CODING_INIT(5, 4, 1, 1), CODING_INIT(5, 4, 2, 1),
- CODING_INIT(5, 16, 0, 1), CODING_INIT(5, 16, 1, 1), CODING_INIT(5, 16, 2, 1),
- CODING_INIT(5, 32, 0, 1), CODING_INIT(5, 32, 1, 1), CODING_INIT(5, 32, 2, 1),
- CODING_INIT(5, 64, 0, 1), CODING_INIT(5, 64, 1, 1), CODING_INIT(5, 64, 2, 1),
- CODING_INIT(5, 128, 0, 1), CODING_INIT(5, 128, 1, 1), CODING_INIT(5, 128, 2, 1),
-
- // Variable length subrange codings:
- CODING_INIT(2, 192, 0, 0), CODING_INIT(2, 224, 0, 0), CODING_INIT(2, 240, 0, 0),
- CODING_INIT(2, 248, 0, 0), CODING_INIT(2, 252, 0, 0), CODING_INIT(2, 8, 0, 1),
- CODING_INIT(2, 8, 1, 1), CODING_INIT(2, 16, 0, 1), CODING_INIT(2, 16, 1, 1),
- CODING_INIT(2, 32, 0, 1), CODING_INIT(2, 32, 1, 1), CODING_INIT(2, 64, 0, 1),
- CODING_INIT(2, 64, 1, 1), CODING_INIT(2, 128, 0, 1), CODING_INIT(2, 128, 1, 1),
- CODING_INIT(2, 192, 0, 1), CODING_INIT(2, 192, 1, 1), CODING_INIT(2, 224, 0, 1),
- CODING_INIT(2, 224, 1, 1), CODING_INIT(2, 240, 0, 1), CODING_INIT(2, 240, 1, 1),
- CODING_INIT(2, 248, 0, 1), CODING_INIT(2, 248, 1, 1), CODING_INIT(3, 192, 0, 0),
- CODING_INIT(3, 224, 0, 0), CODING_INIT(3, 240, 0, 0), CODING_INIT(3, 248, 0, 0),
- CODING_INIT(3, 252, 0, 0), CODING_INIT(3, 8, 0, 1), CODING_INIT(3, 8, 1, 1),
- CODING_INIT(3, 16, 0, 1), CODING_INIT(3, 16, 1, 1), CODING_INIT(3, 32, 0, 1),
- CODING_INIT(3, 32, 1, 1), CODING_INIT(3, 64, 0, 1), CODING_INIT(3, 64, 1, 1),
- CODING_INIT(3, 128, 0, 1), CODING_INIT(3, 128, 1, 1), CODING_INIT(3, 192, 0, 1),
- CODING_INIT(3, 192, 1, 1), CODING_INIT(3, 224, 0, 1), CODING_INIT(3, 224, 1, 1),
- CODING_INIT(3, 240, 0, 1), CODING_INIT(3, 240, 1, 1), CODING_INIT(3, 248, 0, 1),
- CODING_INIT(3, 248, 1, 1), CODING_INIT(4, 192, 0, 0), CODING_INIT(4, 224, 0, 0),
- CODING_INIT(4, 240, 0, 0), CODING_INIT(4, 248, 0, 0), CODING_INIT(4, 252, 0, 0),
- CODING_INIT(4, 8, 0, 1), CODING_INIT(4, 8, 1, 1), CODING_INIT(4, 16, 0, 1),
- CODING_INIT(4, 16, 1, 1), CODING_INIT(4, 32, 0, 1), CODING_INIT(4, 32, 1, 1),
- CODING_INIT(4, 64, 0, 1), CODING_INIT(4, 64, 1, 1), CODING_INIT(4, 128, 0, 1),
- CODING_INIT(4, 128, 1, 1), CODING_INIT(4, 192, 0, 1), CODING_INIT(4, 192, 1, 1),
- CODING_INIT(4, 224, 0, 1), CODING_INIT(4, 224, 1, 1), CODING_INIT(4, 240, 0, 1),
- CODING_INIT(4, 240, 1, 1), CODING_INIT(4, 248, 0, 1), CODING_INIT(4, 248, 1, 1),
- CODING_INIT(0, 0, 0, 0)};
+ // This one is not a usable irregular coding, but is used by cp_Utf8_chars.
+ CODING_INIT(3, 128, 0, 0),
+
+ // Fixed-length codings:
+ CODING_INIT(1, 256, 0, 0), CODING_INIT(1, 256, 1, 0), CODING_INIT(1, 256, 0, 1),
+ CODING_INIT(1, 256, 1, 1), CODING_INIT(2, 256, 0, 0), CODING_INIT(2, 256, 1, 0),
+ CODING_INIT(2, 256, 0, 1), CODING_INIT(2, 256, 1, 1), CODING_INIT(3, 256, 0, 0),
+ CODING_INIT(3, 256, 1, 0), CODING_INIT(3, 256, 0, 1), CODING_INIT(3, 256, 1, 1),
+ CODING_INIT(4, 256, 0, 0), CODING_INIT(4, 256, 1, 0), CODING_INIT(4, 256, 0, 1),
+ CODING_INIT(4, 256, 1, 1),
+
+ // Full-range variable-length codings:
+ CODING_INIT(5, 4, 0, 0), CODING_INIT(5, 4, 1, 0), CODING_INIT(5, 4, 2, 0),
+ CODING_INIT(5, 16, 0, 0), CODING_INIT(5, 16, 1, 0), CODING_INIT(5, 16, 2, 0),
+ CODING_INIT(5, 32, 0, 0), CODING_INIT(5, 32, 1, 0), CODING_INIT(5, 32, 2, 0),
+ CODING_INIT(5, 64, 0, 0), CODING_INIT(5, 64, 1, 0), CODING_INIT(5, 64, 2, 0),
+ CODING_INIT(5, 128, 0, 0), CODING_INIT(5, 128, 1, 0), CODING_INIT(5, 128, 2, 0),
+ CODING_INIT(5, 4, 0, 1), CODING_INIT(5, 4, 1, 1), CODING_INIT(5, 4, 2, 1),
+ CODING_INIT(5, 16, 0, 1), CODING_INIT(5, 16, 1, 1), CODING_INIT(5, 16, 2, 1),
+ CODING_INIT(5, 32, 0, 1), CODING_INIT(5, 32, 1, 1), CODING_INIT(5, 32, 2, 1),
+ CODING_INIT(5, 64, 0, 1), CODING_INIT(5, 64, 1, 1), CODING_INIT(5, 64, 2, 1),
+ CODING_INIT(5, 128, 0, 1), CODING_INIT(5, 128, 1, 1), CODING_INIT(5, 128, 2, 1),
+
+ // Variable length subrange codings:
+ CODING_INIT(2, 192, 0, 0), CODING_INIT(2, 224, 0, 0), CODING_INIT(2, 240, 0, 0),
+ CODING_INIT(2, 248, 0, 0), CODING_INIT(2, 252, 0, 0), CODING_INIT(2, 8, 0, 1),
+ CODING_INIT(2, 8, 1, 1), CODING_INIT(2, 16, 0, 1), CODING_INIT(2, 16, 1, 1),
+ CODING_INIT(2, 32, 0, 1), CODING_INIT(2, 32, 1, 1), CODING_INIT(2, 64, 0, 1),
+ CODING_INIT(2, 64, 1, 1), CODING_INIT(2, 128, 0, 1), CODING_INIT(2, 128, 1, 1),
+ CODING_INIT(2, 192, 0, 1), CODING_INIT(2, 192, 1, 1), CODING_INIT(2, 224, 0, 1),
+ CODING_INIT(2, 224, 1, 1), CODING_INIT(2, 240, 0, 1), CODING_INIT(2, 240, 1, 1),
+ CODING_INIT(2, 248, 0, 1), CODING_INIT(2, 248, 1, 1), CODING_INIT(3, 192, 0, 0),
+ CODING_INIT(3, 224, 0, 0), CODING_INIT(3, 240, 0, 0), CODING_INIT(3, 248, 0, 0),
+ CODING_INIT(3, 252, 0, 0), CODING_INIT(3, 8, 0, 1), CODING_INIT(3, 8, 1, 1),
+ CODING_INIT(3, 16, 0, 1), CODING_INIT(3, 16, 1, 1), CODING_INIT(3, 32, 0, 1),
+ CODING_INIT(3, 32, 1, 1), CODING_INIT(3, 64, 0, 1), CODING_INIT(3, 64, 1, 1),
+ CODING_INIT(3, 128, 0, 1), CODING_INIT(3, 128, 1, 1), CODING_INIT(3, 192, 0, 1),
+ CODING_INIT(3, 192, 1, 1), CODING_INIT(3, 224, 0, 1), CODING_INIT(3, 224, 1, 1),
+ CODING_INIT(3, 240, 0, 1), CODING_INIT(3, 240, 1, 1), CODING_INIT(3, 248, 0, 1),
+ CODING_INIT(3, 248, 1, 1), CODING_INIT(4, 192, 0, 0), CODING_INIT(4, 224, 0, 0),
+ CODING_INIT(4, 240, 0, 0), CODING_INIT(4, 248, 0, 0), CODING_INIT(4, 252, 0, 0),
+ CODING_INIT(4, 8, 0, 1), CODING_INIT(4, 8, 1, 1), CODING_INIT(4, 16, 0, 1),
+ CODING_INIT(4, 16, 1, 1), CODING_INIT(4, 32, 0, 1), CODING_INIT(4, 32, 1, 1),
+ CODING_INIT(4, 64, 0, 1), CODING_INIT(4, 64, 1, 1), CODING_INIT(4, 128, 0, 1),
+ CODING_INIT(4, 128, 1, 1), CODING_INIT(4, 192, 0, 1), CODING_INIT(4, 192, 1, 1),
+ CODING_INIT(4, 224, 0, 1), CODING_INIT(4, 224, 1, 1), CODING_INIT(4, 240, 0, 1),
+ CODING_INIT(4, 240, 1, 1), CODING_INIT(4, 248, 0, 1), CODING_INIT(4, 248, 1, 1),
+ CODING_INIT(0, 0, 0, 0)};
#define BASIC_INDEX_LIMIT (int)(sizeof(basic_codings) / sizeof(basic_codings[0]) - 1)
coding *coding::findByIndex(int idx)
{
- int index_limit = BASIC_INDEX_LIMIT;
- assert(_meta_canon_min == 1 && _meta_canon_max + 1 == index_limit);
+ int index_limit = BASIC_INDEX_LIMIT;
+ assert(_meta_canon_min == 1 && _meta_canon_max + 1 == index_limit);
- if (idx >= _meta_canon_min && idx <= _meta_canon_max)
- return basic_codings[idx].init();
- else
- return nullptr;
+ if (idx >= _meta_canon_min && idx <= _meta_canon_max)
+ return basic_codings[idx].init();
+ else
+ return nullptr;
}
diff --git a/libraries/pack200/src/coding.h b/libraries/pack200/src/coding.h
index f9bd6ca2..bfdd252e 100644
--- a/libraries/pack200/src/coding.h
+++ b/libraries/pack200/src/coding.h
@@ -35,9 +35,9 @@ struct unpacker;
#define CODING_D(x) ((x) >> 0 & 0xF)
#define CODING_INIT(B, H, S, D) \
- { \
- CODING_SPEC(B, H, S, D), 0, 0, 0, 0, 0, 0, 0, 0 \
- }
+ { \
+ CODING_SPEC(B, H, S, D), 0, 0, 0, 0, 0, 0, 0, 0 \
+ }
// For debugging purposes, some compilers do not like this and will complain.
// #define long do_not_use_C_long_types_use_jlong_or_int
@@ -45,126 +45,126 @@ struct unpacker;
struct coding
{
- int spec; // B,H,S,D
-
- // Handy values derived from the spec:
- int B()
- {
- return CODING_B(spec);
- }
- int H()
- {
- return CODING_H(spec);
- }
- int S()
- {
- return CODING_S(spec);
- }
- int D()
- {
- return CODING_D(spec);
- }
- int L()
- {
- return 256 - CODING_H(spec);
- }
- int min, max;
- int umin, umax;
- char isSigned, isSubrange, isFullRange, isMalloc;
-
- coding *init(); // returns self or nullptr if error
- coding *initFrom(int spec_)
- {
- assert(this->spec == 0);
- this->spec = spec_;
- return init();
- }
-
- static coding *findBySpec(int spec);
- static coding *findBySpec(int B, int H, int S = 0, int D = 0);
- static coding *findByIndex(int irregularCodingIndex);
-
- static uint32_t parse(byte *&rp, int B, int H);
- static uint32_t parse_lgH(byte *&rp, int B, int H, int lgH);
- static void parseMultiple(byte *&rp, int N, byte *limit, int B, int H);
-
- uint32_t parse(byte *&rp)
- {
- return parse(rp, CODING_B(spec), CODING_H(spec));
- }
- void parseMultiple(byte *&rp, int N, byte *limit)
- {
- parseMultiple(rp, N, limit, CODING_B(spec), CODING_H(spec));
- }
-
- bool canRepresent(int x)
- {
- return (x >= min && x <= max);
- }
- bool canRepresentUnsigned(int x)
- {
- return (x >= umin && x <= umax);
- }
-
- int sumInUnsignedRange(int x, int y);
-
- int readFrom(byte *&rpVar, int *dbase);
- void readArrayFrom(byte *&rpVar, int *dbase, int length, int *values);
- void skipArrayFrom(byte *&rpVar, int length)
- {
- readArrayFrom(rpVar, (int *)NULL, length, (int *)NULL);
- }
-
- void free(); // free self if isMalloc
+ int spec; // B,H,S,D
+
+ // Handy values derived from the spec:
+ int B()
+ {
+ return CODING_B(spec);
+ }
+ int H()
+ {
+ return CODING_H(spec);
+ }
+ int S()
+ {
+ return CODING_S(spec);
+ }
+ int D()
+ {
+ return CODING_D(spec);
+ }
+ int L()
+ {
+ return 256 - CODING_H(spec);
+ }
+ int min, max;
+ int umin, umax;
+ char isSigned, isSubrange, isFullRange, isMalloc;
+
+ coding *init(); // returns self or nullptr if error
+ coding *initFrom(int spec_)
+ {
+ assert(this->spec == 0);
+ this->spec = spec_;
+ return init();
+ }
+
+ static coding *findBySpec(int spec);
+ static coding *findBySpec(int B, int H, int S = 0, int D = 0);
+ static coding *findByIndex(int irregularCodingIndex);
+
+ static uint32_t parse(byte *&rp, int B, int H);
+ static uint32_t parse_lgH(byte *&rp, int B, int H, int lgH);
+ static void parseMultiple(byte *&rp, int N, byte *limit, int B, int H);
+
+ uint32_t parse(byte *&rp)
+ {
+ return parse(rp, CODING_B(spec), CODING_H(spec));
+ }
+ void parseMultiple(byte *&rp, int N, byte *limit)
+ {
+ parseMultiple(rp, N, limit, CODING_B(spec), CODING_H(spec));
+ }
+
+ bool canRepresent(int x)
+ {
+ return (x >= min && x <= max);
+ }
+ bool canRepresentUnsigned(int x)
+ {
+ return (x >= umin && x <= umax);
+ }
+
+ int sumInUnsignedRange(int x, int y);
+
+ int readFrom(byte *&rpVar, int *dbase);
+ void readArrayFrom(byte *&rpVar, int *dbase, int length, int *values);
+ void skipArrayFrom(byte *&rpVar, int length)
+ {
+ readArrayFrom(rpVar, (int *)NULL, length, (int *)NULL);
+ }
+
+ void free(); // free self if isMalloc
};
enum coding_method_kind
{
- cmk_ERROR,
- cmk_BHS,
- cmk_BHS0,
- cmk_BHS1,
- cmk_BHSD1,
- cmk_BHS1D1full, // isFullRange
- cmk_BHS1D1sub, // isSubRange
-
- // special cases hand-optimized (~50% of all decoded values)
- cmk_BYTE1, //(1,256) 6%
- cmk_CHAR3, //(3,128) 7%
- cmk_UNSIGNED5, //(5,64) 13%
- cmk_DELTA5, //(5,64,1,1) 5%
- cmk_BCI5, //(5,4) 18%
- cmk_BRANCH5, //(5,4,2) 4%
- // cmk_UNSIGNED5H16, //(5,16) 5%
- // cmk_UNSIGNED2H4, //(2,4) 6%
- // cmk_DELTA4H8, //(4,8,1,1) 10%
- // cmk_DELTA3H16, //(3,16,1,1) 9%
- cmk_BHS_LIMIT,
- cmk_pop,
- cmk_pop_BHS0,
- cmk_pop_BYTE1,
- cmk_pop_LIMIT,
- cmk_LIMIT
+ cmk_ERROR,
+ cmk_BHS,
+ cmk_BHS0,
+ cmk_BHS1,
+ cmk_BHSD1,
+ cmk_BHS1D1full, // isFullRange
+ cmk_BHS1D1sub, // isSubRange
+
+ // special cases hand-optimized (~50% of all decoded values)
+ cmk_BYTE1, //(1,256) 6%
+ cmk_CHAR3, //(3,128) 7%
+ cmk_UNSIGNED5, //(5,64) 13%
+ cmk_DELTA5, //(5,64,1,1) 5%
+ cmk_BCI5, //(5,4) 18%
+ cmk_BRANCH5, //(5,4,2) 4%
+ // cmk_UNSIGNED5H16, //(5,16) 5%
+ // cmk_UNSIGNED2H4, //(2,4) 6%
+ // cmk_DELTA4H8, //(4,8,1,1) 10%
+ // cmk_DELTA3H16, //(3,16,1,1) 9%
+ cmk_BHS_LIMIT,
+ cmk_pop,
+ cmk_pop_BHS0,
+ cmk_pop_BYTE1,
+ cmk_pop_LIMIT,
+ cmk_LIMIT
};
enum
{
- BYTE1_spec = CODING_SPEC(1, 256, 0, 0),
- CHAR3_spec = CODING_SPEC(3, 128, 0, 0),
- UNSIGNED4_spec = CODING_SPEC(4, 256, 0, 0),
- UNSIGNED5_spec = CODING_SPEC(5, 64, 0, 0),
- SIGNED5_spec = CODING_SPEC(5, 64, 1, 0),
- DELTA5_spec = CODING_SPEC(5, 64, 1, 1),
- UDELTA5_spec = CODING_SPEC(5, 64, 0, 1),
- MDELTA5_spec = CODING_SPEC(5, 64, 2, 1),
- BCI5_spec = CODING_SPEC(5, 4, 0, 0),
- BRANCH5_spec = CODING_SPEC(5, 4, 2, 0)
+ BYTE1_spec = CODING_SPEC(1, 256, 0, 0),
+ CHAR3_spec = CODING_SPEC(3, 128, 0, 0),
+ UNSIGNED4_spec = CODING_SPEC(4, 256, 0, 0),
+ UNSIGNED5_spec = CODING_SPEC(5, 64, 0, 0),
+ SIGNED5_spec = CODING_SPEC(5, 64, 1, 0),
+ DELTA5_spec = CODING_SPEC(5, 64, 1, 1),
+ UDELTA5_spec = CODING_SPEC(5, 64, 0, 1),
+ MDELTA5_spec = CODING_SPEC(5, 64, 2, 1),
+ BCI5_spec = CODING_SPEC(5, 4, 0, 0),
+ BRANCH5_spec = CODING_SPEC(5, 4, 2, 0)
};
enum
{
- B_MAX = 5,
- C_SLOP = B_MAX * 10
+ B_MAX = 5,
+ C_SLOP = B_MAX * 10
};
struct coding_method;
@@ -172,76 +172,76 @@ struct coding_method;
// iterator under the control of a meta-coding
struct value_stream
{
- // current coding of values or values
- coding c; // B,H,S,D,etc.
- coding_method_kind cmk; // type of decoding needed
- byte *rp; // read pointer
- byte *rplimit; // final value of read pointer
- int sum; // partial sum of all values so far (D=1 only)
- coding_method *cm; // coding method that defines this stream
-
- void init(byte *band_rp, byte *band_limit, coding *defc);
- void init(byte *band_rp, byte *band_limit, int spec)
- {
- init(band_rp, band_limit, coding::findBySpec(spec));
- }
-
- void setCoding(coding *c);
- void setCoding(int spec)
- {
- setCoding(coding::findBySpec(spec));
- }
-
- // Parse and decode a single value.
- int getInt();
-
- // Parse and decode a single byte, with no error checks.
- int getByte()
- {
- assert(cmk == cmk_BYTE1);
- assert(rp < rplimit);
- return *rp++ & 0xFF;
- }
-
- // Used only for asserts.
- bool hasValue();
-
- void done()
- {
- assert(!hasValue());
- }
-
- // Sometimes a value stream has an auxiliary (but there are never two).
- value_stream *helper()
- {
- assert(hasHelper());
- return this + 1;
- }
- bool hasHelper();
+ // current coding of values or values
+ coding c; // B,H,S,D,etc.
+ coding_method_kind cmk; // type of decoding needed
+ byte *rp; // read pointer
+ byte *rplimit; // final value of read pointer
+ int sum; // partial sum of all values so far (D=1 only)
+ coding_method *cm; // coding method that defines this stream
+
+ void init(byte *band_rp, byte *band_limit, coding *defc);
+ void init(byte *band_rp, byte *band_limit, int spec)
+ {
+ init(band_rp, band_limit, coding::findBySpec(spec));
+ }
+
+ void setCoding(coding *c);
+ void setCoding(int spec)
+ {
+ setCoding(coding::findBySpec(spec));
+ }
+
+ // Parse and decode a single value.
+ int getInt();
+
+ // Parse and decode a single byte, with no error checks.
+ int getByte()
+ {
+ assert(cmk == cmk_BYTE1);
+ assert(rp < rplimit);
+ return *rp++ & 0xFF;
+ }
+
+ // Used only for asserts.
+ bool hasValue();
+
+ void done()
+ {
+ assert(!hasValue());
+ }
+
+ // Sometimes a value stream has an auxiliary (but there are never two).
+ value_stream *helper()
+ {
+ assert(hasHelper());
+ return this + 1;
+ }
+ bool hasHelper();
};
struct coding_method
{
- value_stream vs0; // initial state snapshot (vs.meta==this)
+ value_stream vs0; // initial state snapshot (vs.meta==this)
- coding_method *next; // what to do when we run out of bytes
+ coding_method *next; // what to do when we run out of bytes
- // these fields are used for pop codes only:
- int *fValues; // favored value array
- int fVlength; // maximum favored value token
- coding_method *uValues; // unfavored value stream
+ // these fields are used for pop codes only:
+ int *fValues; // favored value array
+ int fVlength; // maximum favored value token
+ coding_method *uValues; // unfavored value stream
- // pointer to outer unpacker, for error checks etc.
- unpacker *u;
+ // pointer to outer unpacker, for error checks etc.
+ unpacker *u;
- // Initialize a value stream.
- void reset(value_stream *state);
+ // Initialize a value stream.
+ void reset(value_stream *state);
- // Parse a band header, size a band, and initialize for further action.
- // band_rp advances (but not past band_limit), and meta_rp advances.
- // The mode gives context, such as "inside a pop".
- // The defc and N are the incoming parameters to a meta-coding.
- // The value sink is used to collect output values, when desired.
- void init(byte *&band_rp, byte *band_limit, byte *&meta_rp, int mode, coding *defc, int N,
- intlist *valueSink);
+ // Parse a band header, size a band, and initialize for further action.
+ // band_rp advances (but not past band_limit), and meta_rp advances.
+ // The mode gives context, such as "inside a pop".
+ // The defc and N are the incoming parameters to a meta-coding.
+ // The value sink is used to collect output values, when desired.
+ void init(byte *&band_rp, byte *band_limit, byte *&meta_rp, int mode, coding *defc, int N,
+ intlist *valueSink);
};
diff --git a/libraries/pack200/src/constants.h b/libraries/pack200/src/constants.h
index 2cc14b7d..f1baf42a 100644
--- a/libraries/pack200/src/constants.h
+++ b/libraries/pack200/src/constants.h
@@ -55,388 +55,388 @@
enum
{
- CONSTANT_None,
- CONSTANT_Utf8,
- CONSTANT_unused2, /* unused, was Unicode */
- CONSTANT_Integer,
- CONSTANT_Float,
- CONSTANT_Long,
- CONSTANT_Double,
- CONSTANT_Class,
- CONSTANT_String,
- CONSTANT_Fieldref,
- CONSTANT_Methodref,
- CONSTANT_InterfaceMethodref,
- CONSTANT_NameandType,
- CONSTANT_Signature = 13,
- CONSTANT_All = 14,
- CONSTANT_Limit = 15,
- CONSTANT_NONE = 0,
- CONSTANT_Literal = 20, // pseudo-tag for debugging
- CONSTANT_Member = 21, // pseudo-tag for debugging
- SUBINDEX_BIT = 64, // combined with CONSTANT_xxx for ixTag
- ACC_STATIC = 0x0008,
- ACC_IC_LONG_FORM = (1 << 16), // for ic_flags
- CLASS_ATTR_SourceFile = 17,
- CLASS_ATTR_EnclosingMethod = 18,
- CLASS_ATTR_InnerClasses = 23,
- CLASS_ATTR_ClassFile_version = 24,
- FIELD_ATTR_ConstantValue = 17,
- METHOD_ATTR_Code = 17,
- METHOD_ATTR_Exceptions = 18,
- METHOD_ATTR_RuntimeVisibleParameterAnnotations = 23,
- METHOD_ATTR_RuntimeInvisibleParameterAnnotations = 24,
- METHOD_ATTR_AnnotationDefault = 25,
- CODE_ATTR_StackMapTable = 0,
- CODE_ATTR_LineNumberTable = 1,
- CODE_ATTR_LocalVariableTable = 2,
- CODE_ATTR_LocalVariableTypeTable = 3,
- // X_ATTR_Synthetic = 12, // ACC_SYNTHETIC; not predefined
- X_ATTR_Signature = 19,
- X_ATTR_Deprecated = 20,
- X_ATTR_RuntimeVisibleAnnotations = 21,
- X_ATTR_RuntimeInvisibleAnnotations = 22,
- X_ATTR_OVERFLOW = 16,
- X_ATTR_LIMIT_NO_FLAGS_HI = 32,
- X_ATTR_LIMIT_FLAGS_HI = 63,
+ CONSTANT_None,
+ CONSTANT_Utf8,
+ CONSTANT_unused2, /* unused, was Unicode */
+ CONSTANT_Integer,
+ CONSTANT_Float,
+ CONSTANT_Long,
+ CONSTANT_Double,
+ CONSTANT_Class,
+ CONSTANT_String,
+ CONSTANT_Fieldref,
+ CONSTANT_Methodref,
+ CONSTANT_InterfaceMethodref,
+ CONSTANT_NameandType,
+ CONSTANT_Signature = 13,
+ CONSTANT_All = 14,
+ CONSTANT_Limit = 15,
+ CONSTANT_NONE = 0,
+ CONSTANT_Literal = 20, // pseudo-tag for debugging
+ CONSTANT_Member = 21, // pseudo-tag for debugging
+ SUBINDEX_BIT = 64, // combined with CONSTANT_xxx for ixTag
+ ACC_STATIC = 0x0008,
+ ACC_IC_LONG_FORM = (1 << 16), // for ic_flags
+ CLASS_ATTR_SourceFile = 17,
+ CLASS_ATTR_EnclosingMethod = 18,
+ CLASS_ATTR_InnerClasses = 23,
+ CLASS_ATTR_ClassFile_version = 24,
+ FIELD_ATTR_ConstantValue = 17,
+ METHOD_ATTR_Code = 17,
+ METHOD_ATTR_Exceptions = 18,
+ METHOD_ATTR_RuntimeVisibleParameterAnnotations = 23,
+ METHOD_ATTR_RuntimeInvisibleParameterAnnotations = 24,
+ METHOD_ATTR_AnnotationDefault = 25,
+ CODE_ATTR_StackMapTable = 0,
+ CODE_ATTR_LineNumberTable = 1,
+ CODE_ATTR_LocalVariableTable = 2,
+ CODE_ATTR_LocalVariableTypeTable = 3,
+ // X_ATTR_Synthetic = 12, // ACC_SYNTHETIC; not predefined
+ X_ATTR_Signature = 19,
+ X_ATTR_Deprecated = 20,
+ X_ATTR_RuntimeVisibleAnnotations = 21,
+ X_ATTR_RuntimeInvisibleAnnotations = 22,
+ X_ATTR_OVERFLOW = 16,
+ X_ATTR_LIMIT_NO_FLAGS_HI = 32,
+ X_ATTR_LIMIT_FLAGS_HI = 63,
#define O_ATTR_DO(F) \
- F(X_ATTR_OVERFLOW, 01) \
- /*(end)*/
+ F(X_ATTR_OVERFLOW, 01) \
+ /*(end)*/
#define X_ATTR_DO(F) \
- O_ATTR_DO(F) F(X_ATTR_Signature, Signature) F(X_ATTR_Deprecated, Deprecated) \
- F(X_ATTR_RuntimeVisibleAnnotations, RuntimeVisibleAnnotations) \
- F(X_ATTR_RuntimeInvisibleAnnotations, RuntimeInvisibleAnnotations) \
- /*F(X_ATTR_Synthetic,Synthetic)*/ \
- /*(end)*/
+ O_ATTR_DO(F) F(X_ATTR_Signature, Signature) F(X_ATTR_Deprecated, Deprecated) \
+ F(X_ATTR_RuntimeVisibleAnnotations, RuntimeVisibleAnnotations) \
+ F(X_ATTR_RuntimeInvisibleAnnotations, RuntimeInvisibleAnnotations) \
+ /*F(X_ATTR_Synthetic,Synthetic)*/ \
+ /*(end)*/
#define CLASS_ATTR_DO(F) \
- F(CLASS_ATTR_SourceFile, SourceFile) F(CLASS_ATTR_InnerClasses, InnerClasses) \
- F(CLASS_ATTR_EnclosingMethod, EnclosingMethod) F(CLASS_ATTR_ClassFile_version, 02) \
- /*(end)*/
+ F(CLASS_ATTR_SourceFile, SourceFile) F(CLASS_ATTR_InnerClasses, InnerClasses) \
+ F(CLASS_ATTR_EnclosingMethod, EnclosingMethod) F(CLASS_ATTR_ClassFile_version, 02) \
+ /*(end)*/
#define FIELD_ATTR_DO(F) \
- F(FIELD_ATTR_ConstantValue, ConstantValue) \
- /*(end)*/
+ F(FIELD_ATTR_ConstantValue, ConstantValue) \
+ /*(end)*/
#define METHOD_ATTR_DO(F) \
- F(METHOD_ATTR_Code, Code) F(METHOD_ATTR_Exceptions, Exceptions) \
- F(METHOD_ATTR_RuntimeVisibleParameterAnnotations, RuntimeVisibleParameterAnnotations) \
- F(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, \
- RuntimeInvisibleParameterAnnotations) \
- F(METHOD_ATTR_AnnotationDefault, AnnotationDefault) \
- /*(end)*/
+ F(METHOD_ATTR_Code, Code) F(METHOD_ATTR_Exceptions, Exceptions) \
+ F(METHOD_ATTR_RuntimeVisibleParameterAnnotations, RuntimeVisibleParameterAnnotations) \
+ F(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, \
+ RuntimeInvisibleParameterAnnotations) \
+ F(METHOD_ATTR_AnnotationDefault, AnnotationDefault) \
+ /*(end)*/
#define CODE_ATTR_DO(F) \
- F(CODE_ATTR_StackMapTable, StackMapTable) F(CODE_ATTR_LineNumberTable, LineNumberTable) \
- F(CODE_ATTR_LocalVariableTable, LocalVariableTable) \
- F(CODE_ATTR_LocalVariableTypeTable, LocalVariableTypeTable) \
- /*(end)*/
+ F(CODE_ATTR_StackMapTable, StackMapTable) F(CODE_ATTR_LineNumberTable, LineNumberTable) \
+ F(CODE_ATTR_LocalVariableTable, LocalVariableTable) \
+ F(CODE_ATTR_LocalVariableTypeTable, LocalVariableTypeTable) \
+ /*(end)*/
#define ALL_ATTR_DO(F) \
- X_ATTR_DO(F) CLASS_ATTR_DO(F) FIELD_ATTR_DO(F) METHOD_ATTR_DO(F) CODE_ATTR_DO(F) \
- /*(end)*/
+ X_ATTR_DO(F) CLASS_ATTR_DO(F) FIELD_ATTR_DO(F) METHOD_ATTR_DO(F) CODE_ATTR_DO(F) \
+ /*(end)*/
- // attribute "context types"
- ATTR_CONTEXT_CLASS = 0,
- ATTR_CONTEXT_FIELD = 1,
- ATTR_CONTEXT_METHOD = 2,
- ATTR_CONTEXT_CODE = 3,
- ATTR_CONTEXT_LIMIT = 4,
+ // attribute "context types"
+ ATTR_CONTEXT_CLASS = 0,
+ ATTR_CONTEXT_FIELD = 1,
+ ATTR_CONTEXT_METHOD = 2,
+ ATTR_CONTEXT_CODE = 3,
+ ATTR_CONTEXT_LIMIT = 4,
- // constants for parsed layouts (stored in band::le_kind)
- EK_NONE = 0, // not a layout element
- EK_INT = 'I', // B H I SH etc., also FH etc.
- EK_BCI = 'P', // PH etc.
- EK_BCID = 'Q', // POH etc.
- EK_BCO = 'O', // OH etc.
- EK_REPL = 'N', // NH[...] etc.
- EK_REF = 'R', // RUH, RUNH, KQH, etc.
- EK_UN = 'T', // TB(...)[...] etc.
- EK_CASE = 'K', // (...)[...] etc.
- EK_CALL = '(', // (0), (1), etc.
- EK_CBLE = '[', // [...][...] etc.
- NO_BAND_INDEX = -1,
+ // constants for parsed layouts (stored in band::le_kind)
+ EK_NONE = 0, // not a layout element
+ EK_INT = 'I', // B H I SH etc., also FH etc.
+ EK_BCI = 'P', // PH etc.
+ EK_BCID = 'Q', // POH etc.
+ EK_BCO = 'O', // OH etc.
+ EK_REPL = 'N', // NH[...] etc.
+ EK_REF = 'R', // RUH, RUNH, KQH, etc.
+ EK_UN = 'T', // TB(...)[...] etc.
+ EK_CASE = 'K', // (...)[...] etc.
+ EK_CALL = '(', // (0), (1), etc.
+ EK_CBLE = '[', // [...][...] etc.
+ NO_BAND_INDEX = -1,
- // File option bits, from LSB in ascending bit position.
- FO_DEFLATE_HINT = 1 << 0,
- FO_IS_CLASS_STUB = 1 << 1,
+ // File option bits, from LSB in ascending bit position.
+ FO_DEFLATE_HINT = 1 << 0,
+ FO_IS_CLASS_STUB = 1 << 1,
- // Archive option bits, from LSB in ascending bit position:
- AO_HAVE_SPECIAL_FORMATS = 1 << 0,
- AO_HAVE_CP_NUMBERS = 1 << 1,
- AO_HAVE_ALL_CODE_FLAGS = 1 << 2,
- AO_3_UNUSED_MBZ = 1 << 3,
- AO_HAVE_FILE_HEADERS = 1 << 4,
- AO_DEFLATE_HINT = 1 << 5,
- AO_HAVE_FILE_MODTIME = 1 << 6,
- AO_HAVE_FILE_OPTIONS = 1 << 7,
- AO_HAVE_FILE_SIZE_HI = 1 << 8,
- AO_HAVE_CLASS_FLAGS_HI = 1 << 9,
- AO_HAVE_FIELD_FLAGS_HI = 1 << 10,
- AO_HAVE_METHOD_FLAGS_HI = 1 << 11,
- AO_HAVE_CODE_FLAGS_HI = 1 << 12,
+ // Archive option bits, from LSB in ascending bit position:
+ AO_HAVE_SPECIAL_FORMATS = 1 << 0,
+ AO_HAVE_CP_NUMBERS = 1 << 1,
+ AO_HAVE_ALL_CODE_FLAGS = 1 << 2,
+ AO_3_UNUSED_MBZ = 1 << 3,
+ AO_HAVE_FILE_HEADERS = 1 << 4,
+ AO_DEFLATE_HINT = 1 << 5,
+ AO_HAVE_FILE_MODTIME = 1 << 6,
+ AO_HAVE_FILE_OPTIONS = 1 << 7,
+ AO_HAVE_FILE_SIZE_HI = 1 << 8,
+ AO_HAVE_CLASS_FLAGS_HI = 1 << 9,
+ AO_HAVE_FIELD_FLAGS_HI = 1 << 10,
+ AO_HAVE_METHOD_FLAGS_HI = 1 << 11,
+ AO_HAVE_CODE_FLAGS_HI = 1 << 12,
#define ARCHIVE_BIT_DO(F) \
- F(AO_HAVE_SPECIAL_FORMATS) F(AO_HAVE_CP_NUMBERS) F(AO_HAVE_ALL_CODE_FLAGS) \
- /*F(AO_3_UNUSED_MBZ)*/ \
- F(AO_HAVE_FILE_HEADERS) F(AO_DEFLATE_HINT) F(AO_HAVE_FILE_MODTIME) \
- F(AO_HAVE_FILE_OPTIONS) F(AO_HAVE_FILE_SIZE_HI) F(AO_HAVE_CLASS_FLAGS_HI) \
- F(AO_HAVE_FIELD_FLAGS_HI) F(AO_HAVE_METHOD_FLAGS_HI) F(AO_HAVE_CODE_FLAGS_HI) \
- /*(end)*/
+ F(AO_HAVE_SPECIAL_FORMATS) F(AO_HAVE_CP_NUMBERS) F(AO_HAVE_ALL_CODE_FLAGS) \
+ /*F(AO_3_UNUSED_MBZ)*/ \
+ F(AO_HAVE_FILE_HEADERS) F(AO_DEFLATE_HINT) F(AO_HAVE_FILE_MODTIME) \
+ F(AO_HAVE_FILE_OPTIONS) F(AO_HAVE_FILE_SIZE_HI) F(AO_HAVE_CLASS_FLAGS_HI) \
+ F(AO_HAVE_FIELD_FLAGS_HI) F(AO_HAVE_METHOD_FLAGS_HI) F(AO_HAVE_CODE_FLAGS_HI) \
+ /*(end)*/
- // Constants for decoding attribute definition header bytes.
- ADH_CONTEXT_MASK = 0x3, // (hdr & ADH_CONTEXT_MASK)
- ADH_BIT_SHIFT = 0x2, // (hdr >> ADH_BIT_SHIFT)
- ADH_BIT_IS_LSB = 1, // (hdr >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB
+ // Constants for decoding attribute definition header bytes.
+ ADH_CONTEXT_MASK = 0x3, // (hdr & ADH_CONTEXT_MASK)
+ ADH_BIT_SHIFT = 0x2, // (hdr >> ADH_BIT_SHIFT)
+ ADH_BIT_IS_LSB = 1, // (hdr >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB
#define ADH_BYTE(context, index) ((((index) + ADH_BIT_IS_LSB) << ADH_BIT_SHIFT) + (context))
#define ADH_BYTE_CONTEXT(adhb) ((adhb) & ADH_CONTEXT_MASK)
#define ADH_BYTE_INDEX(adhb) (((adhb) >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB)
- NO_MODTIME = 0, // nullptr modtime value
+ NO_MODTIME = 0, // nullptr modtime value
- // meta-coding
- _meta_default = 0,
- _meta_canon_min = 1,
- _meta_canon_max = 115,
- _meta_arb = 116,
- _meta_run = 117,
- _meta_pop = 141,
- _meta_limit = 189,
- _meta_error = 255,
- _xxx_1_end
+ // meta-coding
+ _meta_default = 0,
+ _meta_canon_min = 1,
+ _meta_canon_max = 115,
+ _meta_arb = 116,
+ _meta_run = 117,
+ _meta_pop = 141,
+ _meta_limit = 189,
+ _meta_error = 255,
+ _xxx_1_end
};
// Bytecodes.
enum
{
- bc_nop = 0, // 0x00
- bc_aconst_null = 1, // 0x01
- bc_iconst_m1 = 2, // 0x02
- bc_iconst_0 = 3, // 0x03
- bc_iconst_1 = 4, // 0x04
- bc_iconst_2 = 5, // 0x05
- bc_iconst_3 = 6, // 0x06
- bc_iconst_4 = 7, // 0x07
- bc_iconst_5 = 8, // 0x08
- bc_lconst_0 = 9, // 0x09
- bc_lconst_1 = 10, // 0x0a
- bc_fconst_0 = 11, // 0x0b
- bc_fconst_1 = 12, // 0x0c
- bc_fconst_2 = 13, // 0x0d
- bc_dconst_0 = 14, // 0x0e
- bc_dconst_1 = 15, // 0x0f
- bc_bipush = 16, // 0x10
- bc_sipush = 17, // 0x11
- bc_ldc = 18, // 0x12
- bc_ldc_w = 19, // 0x13
- bc_ldc2_w = 20, // 0x14
- bc_iload = 21, // 0x15
- bc_lload = 22, // 0x16
- bc_fload = 23, // 0x17
- bc_dload = 24, // 0x18
- bc_aload = 25, // 0x19
- bc_iload_0 = 26, // 0x1a
- bc_iload_1 = 27, // 0x1b
- bc_iload_2 = 28, // 0x1c
- bc_iload_3 = 29, // 0x1d
- bc_lload_0 = 30, // 0x1e
- bc_lload_1 = 31, // 0x1f
- bc_lload_2 = 32, // 0x20
- bc_lload_3 = 33, // 0x21
- bc_fload_0 = 34, // 0x22
- bc_fload_1 = 35, // 0x23
- bc_fload_2 = 36, // 0x24
- bc_fload_3 = 37, // 0x25
- bc_dload_0 = 38, // 0x26
- bc_dload_1 = 39, // 0x27
- bc_dload_2 = 40, // 0x28
- bc_dload_3 = 41, // 0x29
- bc_aload_0 = 42, // 0x2a
- bc_aload_1 = 43, // 0x2b
- bc_aload_2 = 44, // 0x2c
- bc_aload_3 = 45, // 0x2d
- bc_iaload = 46, // 0x2e
- bc_laload = 47, // 0x2f
- bc_faload = 48, // 0x30
- bc_daload = 49, // 0x31
- bc_aaload = 50, // 0x32
- bc_baload = 51, // 0x33
- bc_caload = 52, // 0x34
- bc_saload = 53, // 0x35
- bc_istore = 54, // 0x36
- bc_lstore = 55, // 0x37
- bc_fstore = 56, // 0x38
- bc_dstore = 57, // 0x39
- bc_astore = 58, // 0x3a
- bc_istore_0 = 59, // 0x3b
- bc_istore_1 = 60, // 0x3c
- bc_istore_2 = 61, // 0x3d
- bc_istore_3 = 62, // 0x3e
- bc_lstore_0 = 63, // 0x3f
- bc_lstore_1 = 64, // 0x40
- bc_lstore_2 = 65, // 0x41
- bc_lstore_3 = 66, // 0x42
- bc_fstore_0 = 67, // 0x43
- bc_fstore_1 = 68, // 0x44
- bc_fstore_2 = 69, // 0x45
- bc_fstore_3 = 70, // 0x46
- bc_dstore_0 = 71, // 0x47
- bc_dstore_1 = 72, // 0x48
- bc_dstore_2 = 73, // 0x49
- bc_dstore_3 = 74, // 0x4a
- bc_astore_0 = 75, // 0x4b
- bc_astore_1 = 76, // 0x4c
- bc_astore_2 = 77, // 0x4d
- bc_astore_3 = 78, // 0x4e
- bc_iastore = 79, // 0x4f
- bc_lastore = 80, // 0x50
- bc_fastore = 81, // 0x51
- bc_dastore = 82, // 0x52
- bc_aastore = 83, // 0x53
- bc_bastore = 84, // 0x54
- bc_castore = 85, // 0x55
- bc_sastore = 86, // 0x56
- bc_pop = 87, // 0x57
- bc_pop2 = 88, // 0x58
- bc_dup = 89, // 0x59
- bc_dup_x1 = 90, // 0x5a
- bc_dup_x2 = 91, // 0x5b
- bc_dup2 = 92, // 0x5c
- bc_dup2_x1 = 93, // 0x5d
- bc_dup2_x2 = 94, // 0x5e
- bc_swap = 95, // 0x5f
- bc_iadd = 96, // 0x60
- bc_ladd = 97, // 0x61
- bc_fadd = 98, // 0x62
- bc_dadd = 99, // 0x63
- bc_isub = 100, // 0x64
- bc_lsub = 101, // 0x65
- bc_fsub = 102, // 0x66
- bc_dsub = 103, // 0x67
- bc_imul = 104, // 0x68
- bc_lmul = 105, // 0x69
- bc_fmul = 106, // 0x6a
- bc_dmul = 107, // 0x6b
- bc_idiv = 108, // 0x6c
- bc_ldiv = 109, // 0x6d
- bc_fdiv = 110, // 0x6e
- bc_ddiv = 111, // 0x6f
- bc_irem = 112, // 0x70
- bc_lrem = 113, // 0x71
- bc_frem = 114, // 0x72
- bc_drem = 115, // 0x73
- bc_ineg = 116, // 0x74
- bc_lneg = 117, // 0x75
- bc_fneg = 118, // 0x76
- bc_dneg = 119, // 0x77
- bc_ishl = 120, // 0x78
- bc_lshl = 121, // 0x79
- bc_ishr = 122, // 0x7a
- bc_lshr = 123, // 0x7b
- bc_iushr = 124, // 0x7c
- bc_lushr = 125, // 0x7d
- bc_iand = 126, // 0x7e
- bc_land = 127, // 0x7f
- bc_ior = 128, // 0x80
- bc_lor = 129, // 0x81
- bc_ixor = 130, // 0x82
- bc_lxor = 131, // 0x83
- bc_iinc = 132, // 0x84
- bc_i2l = 133, // 0x85
- bc_i2f = 134, // 0x86
- bc_i2d = 135, // 0x87
- bc_l2i = 136, // 0x88
- bc_l2f = 137, // 0x89
- bc_l2d = 138, // 0x8a
- bc_f2i = 139, // 0x8b
- bc_f2l = 140, // 0x8c
- bc_f2d = 141, // 0x8d
- bc_d2i = 142, // 0x8e
- bc_d2l = 143, // 0x8f
- bc_d2f = 144, // 0x90
- bc_i2b = 145, // 0x91
- bc_i2c = 146, // 0x92
- bc_i2s = 147, // 0x93
- bc_lcmp = 148, // 0x94
- bc_fcmpl = 149, // 0x95
- bc_fcmpg = 150, // 0x96
- bc_dcmpl = 151, // 0x97
- bc_dcmpg = 152, // 0x98
- bc_ifeq = 153, // 0x99
- bc_ifne = 154, // 0x9a
- bc_iflt = 155, // 0x9b
- bc_ifge = 156, // 0x9c
- bc_ifgt = 157, // 0x9d
- bc_ifle = 158, // 0x9e
- bc_if_icmpeq = 159, // 0x9f
- bc_if_icmpne = 160, // 0xa0
- bc_if_icmplt = 161, // 0xa1
- bc_if_icmpge = 162, // 0xa2
- bc_if_icmpgt = 163, // 0xa3
- bc_if_icmple = 164, // 0xa4
- bc_if_acmpeq = 165, // 0xa5
- bc_if_acmpne = 166, // 0xa6
- bc_goto = 167, // 0xa7
- bc_jsr = 168, // 0xa8
- bc_ret = 169, // 0xa9
- bc_tableswitch = 170, // 0xaa
- bc_lookupswitch = 171, // 0xab
- bc_ireturn = 172, // 0xac
- bc_lreturn = 173, // 0xad
- bc_freturn = 174, // 0xae
- bc_dreturn = 175, // 0xaf
- bc_areturn = 176, // 0xb0
- bc_return = 177, // 0xb1
- bc_getstatic = 178, // 0xb2
- bc_putstatic = 179, // 0xb3
- bc_getfield = 180, // 0xb4
- bc_putfield = 181, // 0xb5
- bc_invokevirtual = 182, // 0xb6
- bc_invokespecial = 183, // 0xb7
- bc_invokestatic = 184, // 0xb8
- bc_invokeinterface = 185, // 0xb9
- bc_xxxunusedxxx = 186, // 0xba
- bc_new = 187, // 0xbb
- bc_newarray = 188, // 0xbc
- bc_anewarray = 189, // 0xbd
- bc_arraylength = 190, // 0xbe
- bc_athrow = 191, // 0xbf
- bc_checkcast = 192, // 0xc0
- bc_instanceof = 193, // 0xc1
- bc_monitorenter = 194, // 0xc2
- bc_monitorexit = 195, // 0xc3
- bc_wide = 196, // 0xc4
- bc_multianewarray = 197, // 0xc5
- bc_ifnull = 198, // 0xc6
- bc_ifnonnull = 199, // 0xc7
- bc_goto_w = 200, // 0xc8
- bc_jsr_w = 201, // 0xc9
- bc_bytecode_limit = 202 // 0xca
+ bc_nop = 0, // 0x00
+ bc_aconst_null = 1, // 0x01
+ bc_iconst_m1 = 2, // 0x02
+ bc_iconst_0 = 3, // 0x03
+ bc_iconst_1 = 4, // 0x04
+ bc_iconst_2 = 5, // 0x05
+ bc_iconst_3 = 6, // 0x06
+ bc_iconst_4 = 7, // 0x07
+ bc_iconst_5 = 8, // 0x08
+ bc_lconst_0 = 9, // 0x09
+ bc_lconst_1 = 10, // 0x0a
+ bc_fconst_0 = 11, // 0x0b
+ bc_fconst_1 = 12, // 0x0c
+ bc_fconst_2 = 13, // 0x0d
+ bc_dconst_0 = 14, // 0x0e
+ bc_dconst_1 = 15, // 0x0f
+ bc_bipush = 16, // 0x10
+ bc_sipush = 17, // 0x11
+ bc_ldc = 18, // 0x12
+ bc_ldc_w = 19, // 0x13
+ bc_ldc2_w = 20, // 0x14
+ bc_iload = 21, // 0x15
+ bc_lload = 22, // 0x16
+ bc_fload = 23, // 0x17
+ bc_dload = 24, // 0x18
+ bc_aload = 25, // 0x19
+ bc_iload_0 = 26, // 0x1a
+ bc_iload_1 = 27, // 0x1b
+ bc_iload_2 = 28, // 0x1c
+ bc_iload_3 = 29, // 0x1d
+ bc_lload_0 = 30, // 0x1e
+ bc_lload_1 = 31, // 0x1f
+ bc_lload_2 = 32, // 0x20
+ bc_lload_3 = 33, // 0x21
+ bc_fload_0 = 34, // 0x22
+ bc_fload_1 = 35, // 0x23
+ bc_fload_2 = 36, // 0x24
+ bc_fload_3 = 37, // 0x25
+ bc_dload_0 = 38, // 0x26
+ bc_dload_1 = 39, // 0x27
+ bc_dload_2 = 40, // 0x28
+ bc_dload_3 = 41, // 0x29
+ bc_aload_0 = 42, // 0x2a
+ bc_aload_1 = 43, // 0x2b
+ bc_aload_2 = 44, // 0x2c
+ bc_aload_3 = 45, // 0x2d
+ bc_iaload = 46, // 0x2e
+ bc_laload = 47, // 0x2f
+ bc_faload = 48, // 0x30
+ bc_daload = 49, // 0x31
+ bc_aaload = 50, // 0x32
+ bc_baload = 51, // 0x33
+ bc_caload = 52, // 0x34
+ bc_saload = 53, // 0x35
+ bc_istore = 54, // 0x36
+ bc_lstore = 55, // 0x37
+ bc_fstore = 56, // 0x38
+ bc_dstore = 57, // 0x39
+ bc_astore = 58, // 0x3a
+ bc_istore_0 = 59, // 0x3b
+ bc_istore_1 = 60, // 0x3c
+ bc_istore_2 = 61, // 0x3d
+ bc_istore_3 = 62, // 0x3e
+ bc_lstore_0 = 63, // 0x3f
+ bc_lstore_1 = 64, // 0x40
+ bc_lstore_2 = 65, // 0x41
+ bc_lstore_3 = 66, // 0x42
+ bc_fstore_0 = 67, // 0x43
+ bc_fstore_1 = 68, // 0x44
+ bc_fstore_2 = 69, // 0x45
+ bc_fstore_3 = 70, // 0x46
+ bc_dstore_0 = 71, // 0x47
+ bc_dstore_1 = 72, // 0x48
+ bc_dstore_2 = 73, // 0x49
+ bc_dstore_3 = 74, // 0x4a
+ bc_astore_0 = 75, // 0x4b
+ bc_astore_1 = 76, // 0x4c
+ bc_astore_2 = 77, // 0x4d
+ bc_astore_3 = 78, // 0x4e
+ bc_iastore = 79, // 0x4f
+ bc_lastore = 80, // 0x50
+ bc_fastore = 81, // 0x51
+ bc_dastore = 82, // 0x52
+ bc_aastore = 83, // 0x53
+ bc_bastore = 84, // 0x54
+ bc_castore = 85, // 0x55
+ bc_sastore = 86, // 0x56
+ bc_pop = 87, // 0x57
+ bc_pop2 = 88, // 0x58
+ bc_dup = 89, // 0x59
+ bc_dup_x1 = 90, // 0x5a
+ bc_dup_x2 = 91, // 0x5b
+ bc_dup2 = 92, // 0x5c
+ bc_dup2_x1 = 93, // 0x5d
+ bc_dup2_x2 = 94, // 0x5e
+ bc_swap = 95, // 0x5f
+ bc_iadd = 96, // 0x60
+ bc_ladd = 97, // 0x61
+ bc_fadd = 98, // 0x62
+ bc_dadd = 99, // 0x63
+ bc_isub = 100, // 0x64
+ bc_lsub = 101, // 0x65
+ bc_fsub = 102, // 0x66
+ bc_dsub = 103, // 0x67
+ bc_imul = 104, // 0x68
+ bc_lmul = 105, // 0x69
+ bc_fmul = 106, // 0x6a
+ bc_dmul = 107, // 0x6b
+ bc_idiv = 108, // 0x6c
+ bc_ldiv = 109, // 0x6d
+ bc_fdiv = 110, // 0x6e
+ bc_ddiv = 111, // 0x6f
+ bc_irem = 112, // 0x70
+ bc_lrem = 113, // 0x71
+ bc_frem = 114, // 0x72
+ bc_drem = 115, // 0x73
+ bc_ineg = 116, // 0x74
+ bc_lneg = 117, // 0x75
+ bc_fneg = 118, // 0x76
+ bc_dneg = 119, // 0x77
+ bc_ishl = 120, // 0x78
+ bc_lshl = 121, // 0x79
+ bc_ishr = 122, // 0x7a
+ bc_lshr = 123, // 0x7b
+ bc_iushr = 124, // 0x7c
+ bc_lushr = 125, // 0x7d
+ bc_iand = 126, // 0x7e
+ bc_land = 127, // 0x7f
+ bc_ior = 128, // 0x80
+ bc_lor = 129, // 0x81
+ bc_ixor = 130, // 0x82
+ bc_lxor = 131, // 0x83
+ bc_iinc = 132, // 0x84
+ bc_i2l = 133, // 0x85
+ bc_i2f = 134, // 0x86
+ bc_i2d = 135, // 0x87
+ bc_l2i = 136, // 0x88
+ bc_l2f = 137, // 0x89
+ bc_l2d = 138, // 0x8a
+ bc_f2i = 139, // 0x8b
+ bc_f2l = 140, // 0x8c
+ bc_f2d = 141, // 0x8d
+ bc_d2i = 142, // 0x8e
+ bc_d2l = 143, // 0x8f
+ bc_d2f = 144, // 0x90
+ bc_i2b = 145, // 0x91
+ bc_i2c = 146, // 0x92
+ bc_i2s = 147, // 0x93
+ bc_lcmp = 148, // 0x94
+ bc_fcmpl = 149, // 0x95
+ bc_fcmpg = 150, // 0x96
+ bc_dcmpl = 151, // 0x97
+ bc_dcmpg = 152, // 0x98
+ bc_ifeq = 153, // 0x99
+ bc_ifne = 154, // 0x9a
+ bc_iflt = 155, // 0x9b
+ bc_ifge = 156, // 0x9c
+ bc_ifgt = 157, // 0x9d
+ bc_ifle = 158, // 0x9e
+ bc_if_icmpeq = 159, // 0x9f
+ bc_if_icmpne = 160, // 0xa0
+ bc_if_icmplt = 161, // 0xa1
+ bc_if_icmpge = 162, // 0xa2
+ bc_if_icmpgt = 163, // 0xa3
+ bc_if_icmple = 164, // 0xa4
+ bc_if_acmpeq = 165, // 0xa5
+ bc_if_acmpne = 166, // 0xa6
+ bc_goto = 167, // 0xa7
+ bc_jsr = 168, // 0xa8
+ bc_ret = 169, // 0xa9
+ bc_tableswitch = 170, // 0xaa
+ bc_lookupswitch = 171, // 0xab
+ bc_ireturn = 172, // 0xac
+ bc_lreturn = 173, // 0xad
+ bc_freturn = 174, // 0xae
+ bc_dreturn = 175, // 0xaf
+ bc_areturn = 176, // 0xb0
+ bc_return = 177, // 0xb1
+ bc_getstatic = 178, // 0xb2
+ bc_putstatic = 179, // 0xb3
+ bc_getfield = 180, // 0xb4
+ bc_putfield = 181, // 0xb5
+ bc_invokevirtual = 182, // 0xb6
+ bc_invokespecial = 183, // 0xb7
+ bc_invokestatic = 184, // 0xb8
+ bc_invokeinterface = 185, // 0xb9
+ bc_xxxunusedxxx = 186, // 0xba
+ bc_new = 187, // 0xbb
+ bc_newarray = 188, // 0xbc
+ bc_anewarray = 189, // 0xbd
+ bc_arraylength = 190, // 0xbe
+ bc_athrow = 191, // 0xbf
+ bc_checkcast = 192, // 0xc0
+ bc_instanceof = 193, // 0xc1
+ bc_monitorenter = 194, // 0xc2
+ bc_monitorexit = 195, // 0xc3
+ bc_wide = 196, // 0xc4
+ bc_multianewarray = 197, // 0xc5
+ bc_ifnull = 198, // 0xc6
+ bc_ifnonnull = 199, // 0xc7
+ bc_goto_w = 200, // 0xc8
+ bc_jsr_w = 201, // 0xc9
+ bc_bytecode_limit = 202 // 0xca
};
enum
{
- bc_end_marker = 255,
- bc_byte_escape = 254,
- bc_ref_escape = 253,
- _first_linker_op = bc_getstatic,
- _last_linker_op = bc_invokestatic,
- _num_linker_ops = (_last_linker_op - _first_linker_op) + 1,
- _self_linker_op = bc_bytecode_limit,
- _self_linker_aload_flag = 1 * _num_linker_ops,
- _self_linker_super_flag = 2 * _num_linker_ops,
- _self_linker_limit = _self_linker_op + 4 * _num_linker_ops,
- _invokeinit_op = _self_linker_limit,
- _invokeinit_self_option = 0,
- _invokeinit_super_option = 1,
- _invokeinit_new_option = 2,
- _invokeinit_limit = _invokeinit_op + 3,
- _xldc_op = _invokeinit_limit,
- bc_aldc = bc_ldc,
- bc_cldc = _xldc_op + 0,
- bc_ildc = _xldc_op + 1,
- bc_fldc = _xldc_op + 2,
- bc_aldc_w = bc_ldc_w,
- bc_cldc_w = _xldc_op + 3,
- bc_ildc_w = _xldc_op + 4,
- bc_fldc_w = _xldc_op + 5,
- bc_lldc2_w = bc_ldc2_w,
- bc_dldc2_w = _xldc_op + 6,
- _xldc_limit = _xldc_op + 7,
- _xxx_3_end
+ bc_end_marker = 255,
+ bc_byte_escape = 254,
+ bc_ref_escape = 253,
+ _first_linker_op = bc_getstatic,
+ _last_linker_op = bc_invokestatic,
+ _num_linker_ops = (_last_linker_op - _first_linker_op) + 1,
+ _self_linker_op = bc_bytecode_limit,
+ _self_linker_aload_flag = 1 * _num_linker_ops,
+ _self_linker_super_flag = 2 * _num_linker_ops,
+ _self_linker_limit = _self_linker_op + 4 * _num_linker_ops,
+ _invokeinit_op = _self_linker_limit,
+ _invokeinit_self_option = 0,
+ _invokeinit_super_option = 1,
+ _invokeinit_new_option = 2,
+ _invokeinit_limit = _invokeinit_op + 3,
+ _xldc_op = _invokeinit_limit,
+ bc_aldc = bc_ldc,
+ bc_cldc = _xldc_op + 0,
+ bc_ildc = _xldc_op + 1,
+ bc_fldc = _xldc_op + 2,
+ bc_aldc_w = bc_ldc_w,
+ bc_cldc_w = _xldc_op + 3,
+ bc_ildc_w = _xldc_op + 4,
+ bc_fldc_w = _xldc_op + 5,
+ bc_lldc2_w = bc_ldc2_w,
+ bc_dldc2_w = _xldc_op + 6,
+ _xldc_limit = _xldc_op + 7,
+ _xxx_3_end
};
diff --git a/libraries/pack200/src/unpack.cpp b/libraries/pack200/src/unpack.cpp
index 92e2c523..9c4c633c 100644
--- a/libraries/pack200/src/unpack.cpp
+++ b/libraries/pack200/src/unpack.cpp
@@ -61,248 +61,248 @@
// tags, in canonical order:
static const byte TAGS_IN_ORDER[] = {
- CONSTANT_Utf8, CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long,
- CONSTANT_Double, CONSTANT_String, CONSTANT_Class, CONSTANT_Signature,
- CONSTANT_NameandType, CONSTANT_Fieldref, CONSTANT_Methodref, CONSTANT_InterfaceMethodref};
+ CONSTANT_Utf8, CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long,
+ CONSTANT_Double, CONSTANT_String, CONSTANT_Class, CONSTANT_Signature,
+ CONSTANT_NameandType, CONSTANT_Fieldref, CONSTANT_Methodref, CONSTANT_InterfaceMethodref};
#define N_TAGS_IN_ORDER (sizeof TAGS_IN_ORDER)
// REQUESTED must be -2 for u2 and REQUESTED_LDC must be -1 for u1
enum
{
- NOT_REQUESTED = 0,
- REQUESTED = -2,
- REQUESTED_LDC = -1
+ NOT_REQUESTED = 0,
+ REQUESTED = -2,
+ REQUESTED_LDC = -1
};
#define NO_INORD ((uint32_t) - 1)
struct entry
{
- byte tag;
- unsigned short nrefs; // pack w/ tag
-
- int outputIndex;
- uint32_t inord; // &cp.entries[cp.tag_base[this->tag]+this->inord] == this
-
- entry **refs;
-
- // put last to pack best
- union
- {
- bytes b;
- int i;
- int64_t l;
- } value;
-
- void requestOutputIndex(constant_pool &cp, int req = REQUESTED);
- int getOutputIndex()
- {
- assert(outputIndex > NOT_REQUESTED);
- return outputIndex;
- }
-
- entry *ref(int refnum)
- {
- assert((uint32_t)refnum < nrefs);
- return refs[refnum];
- }
-
- const char *utf8String()
- {
- assert(tagMatches(CONSTANT_Utf8));
- assert(value.b.len == strlen((const char *)value.b.ptr));
- return (const char *)value.b.ptr;
- }
-
- entry *className()
- {
- assert(tagMatches(CONSTANT_Class));
- return ref(0);
- }
-
- entry *memberClass()
- {
- assert(tagMatches(CONSTANT_Member));
- return ref(0);
- }
-
- entry *memberDescr()
- {
- assert(tagMatches(CONSTANT_Member));
- return ref(1);
- }
-
- entry *descrName()
- {
- assert(tagMatches(CONSTANT_NameandType));
- return ref(0);
- }
-
- entry *descrType()
- {
- assert(tagMatches(CONSTANT_NameandType));
- return ref(1);
- }
-
- int typeSize();
-
- bytes &asUtf8();
- int asInteger()
- {
- assert(tag == CONSTANT_Integer);
- return value.i;
- }
-
- bool isUtf8(bytes &b)
- {
- return tagMatches(CONSTANT_Utf8) && value.b.equals(b);
- }
-
- bool isDoubleWord()
- {
- return tag == CONSTANT_Double || tag == CONSTANT_Long;
- }
-
- bool tagMatches(byte tag2)
- {
- return (tag2 == tag) || (tag2 == CONSTANT_Utf8 && tag == CONSTANT_Signature) ||
- (tag2 == CONSTANT_Literal && tag >= CONSTANT_Integer && tag <= CONSTANT_String &&
- tag != CONSTANT_Class) ||
- (tag2 == CONSTANT_Member && tag >= CONSTANT_Fieldref &&
- tag <= CONSTANT_InterfaceMethodref);
- }
+ byte tag;
+ unsigned short nrefs; // pack w/ tag
+
+ int outputIndex;
+ uint32_t inord; // &cp.entries[cp.tag_base[this->tag]+this->inord] == this
+
+ entry **refs;
+
+ // put last to pack best
+ union
+ {
+ bytes b;
+ int i;
+ int64_t l;
+ } value;
+
+ void requestOutputIndex(constant_pool &cp, int req = REQUESTED);
+ int getOutputIndex()
+ {
+ assert(outputIndex > NOT_REQUESTED);
+ return outputIndex;
+ }
+
+ entry *ref(int refnum)
+ {
+ assert((uint32_t)refnum < nrefs);
+ return refs[refnum];
+ }
+
+ const char *utf8String()
+ {
+ assert(tagMatches(CONSTANT_Utf8));
+ assert(value.b.len == strlen((const char *)value.b.ptr));
+ return (const char *)value.b.ptr;
+ }
+
+ entry *className()
+ {
+ assert(tagMatches(CONSTANT_Class));
+ return ref(0);
+ }
+
+ entry *memberClass()
+ {
+ assert(tagMatches(CONSTANT_Member));
+ return ref(0);
+ }
+
+ entry *memberDescr()
+ {
+ assert(tagMatches(CONSTANT_Member));
+ return ref(1);
+ }
+
+ entry *descrName()
+ {
+ assert(tagMatches(CONSTANT_NameandType));
+ return ref(0);
+ }
+
+ entry *descrType()
+ {
+ assert(tagMatches(CONSTANT_NameandType));
+ return ref(1);
+ }
+
+ int typeSize();
+
+ bytes &asUtf8();
+ int asInteger()
+ {
+ assert(tag == CONSTANT_Integer);
+ return value.i;
+ }
+
+ bool isUtf8(bytes &b)
+ {
+ return tagMatches(CONSTANT_Utf8) && value.b.equals(b);
+ }
+
+ bool isDoubleWord()
+ {
+ return tag == CONSTANT_Double || tag == CONSTANT_Long;
+ }
+
+ bool tagMatches(byte tag2)
+ {
+ return (tag2 == tag) || (tag2 == CONSTANT_Utf8 && tag == CONSTANT_Signature) ||
+ (tag2 == CONSTANT_Literal && tag >= CONSTANT_Integer && tag <= CONSTANT_String &&
+ tag != CONSTANT_Class) ||
+ (tag2 == CONSTANT_Member && tag >= CONSTANT_Fieldref &&
+ tag <= CONSTANT_InterfaceMethodref);
+ }
};
entry *cpindex::get(uint32_t i)
{
- if (i >= len)
- return nullptr;
- else if (base1 != nullptr)
- // primary index
- return &base1[i];
- else
- // secondary index
- return base2[i];
+ if (i >= len)
+ return nullptr;
+ else if (base1 != nullptr)
+ // primary index
+ return &base1[i];
+ else
+ // secondary index
+ return base2[i];
}
inline bytes &entry::asUtf8()
{
- assert(tagMatches(CONSTANT_Utf8));
- return value.b;
+ assert(tagMatches(CONSTANT_Utf8));
+ return value.b;
}
int entry::typeSize()
{
- assert(tagMatches(CONSTANT_Utf8));
- const char *sigp = (char *)value.b.ptr;
- switch (*sigp)
- {
- case '(':
- sigp++;
- break; // skip opening '('
- case 'D':
- case 'J':
- return 2; // double field
- default:
- return 1; // field
- }
- int siglen = 0;
- for (;;)
- {
- int ch = *sigp++;
- switch (ch)
- {
- case 'D':
- case 'J':
- siglen += 1;
- break;
- case '[':
- // Skip rest of array info.
- while (ch == '[')
- {
- ch = *sigp++;
- }
- if (ch != 'L')
- break;
- // else fall through
- case 'L':
- sigp = strchr(sigp, ';');
- if (sigp == nullptr)
- {
- unpack_abort("bad data");
- return 0;
- }
- sigp += 1;
- break;
- case ')': // closing ')'
- return siglen;
- }
- siglen += 1;
- }
+ assert(tagMatches(CONSTANT_Utf8));
+ const char *sigp = (char *)value.b.ptr;
+ switch (*sigp)
+ {
+ case '(':
+ sigp++;
+ break; // skip opening '('
+ case 'D':
+ case 'J':
+ return 2; // double field
+ default:
+ return 1; // field
+ }
+ int siglen = 0;
+ for (;;)
+ {
+ int ch = *sigp++;
+ switch (ch)
+ {
+ case 'D':
+ case 'J':
+ siglen += 1;
+ break;
+ case '[':
+ // Skip rest of array info.
+ while (ch == '[')
+ {
+ ch = *sigp++;
+ }
+ if (ch != 'L')
+ break;
+ // else fall through
+ case 'L':
+ sigp = strchr(sigp, ';');
+ if (sigp == nullptr)
+ {
+ unpack_abort("bad data");
+ return 0;
+ }
+ sigp += 1;
+ break;
+ case ')': // closing ')'
+ return siglen;
+ }
+ siglen += 1;
+ }
}
inline cpindex *constant_pool::getFieldIndex(entry *classRef)
{
- assert(classRef->tagMatches(CONSTANT_Class));
- assert((uint32_t)classRef->inord < (uint32_t)tag_count[CONSTANT_Class]);
- return &member_indexes[classRef->inord * 2 + 0];
+ assert(classRef->tagMatches(CONSTANT_Class));
+ assert((uint32_t)classRef->inord < (uint32_t)tag_count[CONSTANT_Class]);
+ return &member_indexes[classRef->inord * 2 + 0];
}
inline cpindex *constant_pool::getMethodIndex(entry *classRef)
{
- assert(classRef->tagMatches(CONSTANT_Class));
- assert((uint32_t)classRef->inord < (uint32_t)tag_count[CONSTANT_Class]);
- return &member_indexes[classRef->inord * 2 + 1];
+ assert(classRef->tagMatches(CONSTANT_Class));
+ assert((uint32_t)classRef->inord < (uint32_t)tag_count[CONSTANT_Class]);
+ return &member_indexes[classRef->inord * 2 + 1];
}
struct inner_class
{
- entry *inner;
- entry *outer;
- entry *name;
- int flags;
- inner_class *next_sibling;
- bool requested;
+ entry *inner;
+ entry *outer;
+ entry *name;
+ int flags;
+ inner_class *next_sibling;
+ bool requested;
};
// Here is where everything gets deallocated:
void unpacker::free()
{
- int i;
- if (jarout != nullptr)
- jarout->reset();
- if (gzin != nullptr)
- {
- gzin->free();
- gzin = nullptr;
- }
- if (free_input)
- input.free();
- /*
- * free everybody ever allocated with U_NEW or (recently) with T_NEW
- */
- assert(smallbuf.base() == nullptr || mallocs.contains(smallbuf.base()));
- assert(tsmallbuf.base() == nullptr || tmallocs.contains(tsmallbuf.base()));
- mallocs.freeAll();
- tmallocs.freeAll();
- smallbuf.init();
- tsmallbuf.init();
- bcimap.free();
- class_fixup_type.free();
- class_fixup_offset.free();
- class_fixup_ref.free();
- code_fixup_type.free();
- code_fixup_offset.free();
- code_fixup_source.free();
- requested_ics.free();
- cur_classfile_head.free();
- cur_classfile_tail.free();
- for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
- attr_defs[i].free();
-
- // free CP state
- cp.outputEntries.free();
- for (i = 0; i < CONSTANT_Limit; i++)
- cp.tag_extras[i].free();
+ int i;
+ if (jarout != nullptr)
+ jarout->reset();
+ if (gzin != nullptr)
+ {
+ gzin->free();
+ gzin = nullptr;
+ }
+ if (free_input)
+ input.free();
+ /*
+ * free everybody ever allocated with U_NEW or (recently) with T_NEW
+ */
+ assert(smallbuf.base() == nullptr || mallocs.contains(smallbuf.base()));
+ assert(tsmallbuf.base() == nullptr || tmallocs.contains(tsmallbuf.base()));
+ mallocs.freeAll();
+ tmallocs.freeAll();
+ smallbuf.init();
+ tsmallbuf.init();
+ bcimap.free();
+ class_fixup_type.free();
+ class_fixup_offset.free();
+ class_fixup_ref.free();
+ code_fixup_type.free();
+ code_fixup_offset.free();
+ code_fixup_source.free();
+ requested_ics.free();
+ cur_classfile_head.free();
+ cur_classfile_tail.free();
+ for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
+ attr_defs[i].free();
+
+ // free CP state
+ cp.outputEntries.free();
+ for (i = 0; i < CONSTANT_Limit; i++)
+ cp.tag_extras[i].free();
}
// input handling
@@ -312,1933 +312,1933 @@ void unpacker::free()
// unless rplimit hits input.limit().
bool unpacker::ensure_input(int64_t more)
{
- uint64_t want = more - input_remaining();
- if ((int64_t)want <= 0)
- return true; // it's already in the buffer
- if (rplimit == input.limit())
- return true; // not expecting any more
-
- if (read_input_fn == nullptr)
- {
- // assume it is already all there
- bytes_read += input.limit() - rplimit;
- rplimit = input.limit();
- return true;
- }
-
- uint64_t remaining = (input.limit() - rplimit); // how much left to read?
- byte *rpgoal = (want >= remaining) ? input.limit() : rplimit + (size_t)want;
- enum
- {
- CHUNK_SIZE = (1 << 14)
- };
- uint64_t fetch = want;
- if (fetch < CHUNK_SIZE)
- fetch = CHUNK_SIZE;
- if (fetch > remaining * 3 / 4)
- fetch = remaining;
- // Try to fetch at least "more" bytes.
- while ((int64_t)fetch > 0)
- {
- int64_t nr = (*read_input_fn)(this, rplimit, fetch, remaining);
- if (nr <= 0)
- {
- return (rplimit >= rpgoal);
- }
- remaining -= nr;
- rplimit += nr;
- fetch -= nr;
- bytes_read += nr;
- assert(remaining == (uint64_t)(input.limit() - rplimit));
- }
- return true;
+ uint64_t want = more - input_remaining();
+ if ((int64_t)want <= 0)
+ return true; // it's already in the buffer
+ if (rplimit == input.limit())
+ return true; // not expecting any more
+
+ if (read_input_fn == nullptr)
+ {
+ // assume it is already all there
+ bytes_read += input.limit() - rplimit;
+ rplimit = input.limit();
+ return true;
+ }
+
+ uint64_t remaining = (input.limit() - rplimit); // how much left to read?
+ byte *rpgoal = (want >= remaining) ? input.limit() : rplimit + (size_t)want;
+ enum
+ {
+ CHUNK_SIZE = (1 << 14)
+ };
+ uint64_t fetch = want;
+ if (fetch < CHUNK_SIZE)
+ fetch = CHUNK_SIZE;
+ if (fetch > remaining * 3 / 4)
+ fetch = remaining;
+ // Try to fetch at least "more" bytes.
+ while ((int64_t)fetch > 0)
+ {
+ int64_t nr = (*read_input_fn)(this, rplimit, fetch, remaining);
+ if (nr <= 0)
+ {
+ return (rplimit >= rpgoal);
+ }
+ remaining -= nr;
+ rplimit += nr;
+ fetch -= nr;
+ bytes_read += nr;
+ assert(remaining == (uint64_t)(input.limit() - rplimit));
+ }
+ return true;
}
// output handling
fillbytes *unpacker::close_output(fillbytes *which)
{
- assert(wp != nullptr);
- if (which == nullptr)
- {
- if (wpbase == cur_classfile_head.base())
- {
- which = &cur_classfile_head;
- }
- else
- {
- which = &cur_classfile_tail;
- }
- }
- assert(wpbase == which->base());
- assert(wplimit == which->end());
- which->setLimit(wp);
- wp = nullptr;
- wplimit = nullptr;
- // wpbase = nullptr;
- return which;
+ assert(wp != nullptr);
+ if (which == nullptr)
+ {
+ if (wpbase == cur_classfile_head.base())
+ {
+ which = &cur_classfile_head;
+ }
+ else
+ {
+ which = &cur_classfile_tail;
+ }
+ }
+ assert(wpbase == which->base());
+ assert(wplimit == which->end());
+ which->setLimit(wp);
+ wp = nullptr;
+ wplimit = nullptr;
+ // wpbase = nullptr;
+ return which;
}
// maybe_inline
void unpacker::ensure_put_space(size_t size)
{
- if (wp + size <= wplimit)
- return;
- // Determine which segment needs expanding.
- fillbytes *which = close_output();
- byte *wp0 = which->grow(size);
- wpbase = which->base();
- wplimit = which->end();
- wp = wp0;
+ if (wp + size <= wplimit)
+ return;
+ // Determine which segment needs expanding.
+ fillbytes *which = close_output();
+ byte *wp0 = which->grow(size);
+ wpbase = which->base();
+ wplimit = which->end();
+ wp = wp0;
}
byte *unpacker::put_space(size_t size)
{
- byte *wp0 = wp;
- byte *wp1 = wp0 + size;
- if (wp1 > wplimit)
- {
- ensure_put_space(size);
- wp0 = wp;
- wp1 = wp0 + size;
- }
- wp = wp1;
- return wp0;
+ byte *wp0 = wp;
+ byte *wp1 = wp0 + size;
+ if (wp1 > wplimit)
+ {
+ ensure_put_space(size);
+ wp0 = wp;
+ wp1 = wp0 + size;
+ }
+ wp = wp1;
+ return wp0;
}
void unpacker::putu2_at(byte *wp, int n)
{
- if (n != (unsigned short)n)
- {
- unpack_abort(ERROR_OVERFLOW);
- return;
- }
- wp[0] = (n) >> 8;
- wp[1] = (n) >> 0;
+ if (n != (unsigned short)n)
+ {
+ unpack_abort(ERROR_OVERFLOW);
+ return;
+ }
+ wp[0] = (n) >> 8;
+ wp[1] = (n) >> 0;
}
void unpacker::putu4_at(byte *wp, int n)
{
- wp[0] = (n) >> 24;
- wp[1] = (n) >> 16;
- wp[2] = (n) >> 8;
- wp[3] = (n) >> 0;
+ wp[0] = (n) >> 24;
+ wp[1] = (n) >> 16;
+ wp[2] = (n) >> 8;
+ wp[3] = (n) >> 0;
}
void unpacker::putu8_at(byte *wp, int64_t n)
{
- putu4_at(wp + 0, (int)((uint64_t)n >> 32));
- putu4_at(wp + 4, (int)((uint64_t)n >> 0));
+ putu4_at(wp + 0, (int)((uint64_t)n >> 32));
+ putu4_at(wp + 4, (int)((uint64_t)n >> 0));
}
void unpacker::putu2(int n)
{
- putu2_at(put_space(2), n);
+ putu2_at(put_space(2), n);
}
void unpacker::putu4(int n)
{
- putu4_at(put_space(4), n);
+ putu4_at(put_space(4), n);
}
void unpacker::putu8(int64_t n)
{
- putu8_at(put_space(8), n);
+ putu8_at(put_space(8), n);
}
int unpacker::putref_index(entry *e, int size)
{
- if (e == nullptr)
- return 0;
- else if (e->outputIndex > NOT_REQUESTED)
- return e->outputIndex;
- else if (e->tag == CONSTANT_Signature)
- return putref_index(e->ref(0), size);
- else
- {
- e->requestOutputIndex(cp, -size);
- // Later on we'll fix the bits.
- class_fixup_type.addByte(size);
- class_fixup_offset.add((int)wpoffset());
- class_fixup_ref.add(e);
- return 0;
- }
+ if (e == nullptr)
+ return 0;
+ else if (e->outputIndex > NOT_REQUESTED)
+ return e->outputIndex;
+ else if (e->tag == CONSTANT_Signature)
+ return putref_index(e->ref(0), size);
+ else
+ {
+ e->requestOutputIndex(cp, -size);
+ // Later on we'll fix the bits.
+ class_fixup_type.addByte(size);
+ class_fixup_offset.add((int)wpoffset());
+ class_fixup_ref.add(e);
+ return 0;
+ }
}
void unpacker::putref(entry *e)
{
- int oidx = putref_index(e, 2);
- putu2_at(put_space(2), oidx);
+ int oidx = putref_index(e, 2);
+ putu2_at(put_space(2), oidx);
}
void unpacker::putu1ref(entry *e)
{
- int oidx = putref_index(e, 1);
- putu1_at(put_space(1), oidx);
+ int oidx = putref_index(e, 1);
+ putu1_at(put_space(1), oidx);
}
// Allocation of small and large blocks.
enum
{
- CHUNK = (1 << 14),
- SMALL = (1 << 9)
+ CHUNK = (1 << 14),
+ SMALL = (1 << 9)
};
// Call malloc. Try to combine small blocks and free much later.
void *unpacker::alloc_heap(size_t size, bool smallOK, bool temp)
{
- if (!smallOK || size > SMALL)
- {
- void *res = must_malloc((int)size);
- (temp ? &tmallocs : &mallocs)->add(res);
- return res;
- }
- fillbytes &xsmallbuf = *(temp ? &tsmallbuf : &smallbuf);
- if (!xsmallbuf.canAppend(size + 1))
- {
- xsmallbuf.init(CHUNK);
- (temp ? &tmallocs : &mallocs)->add(xsmallbuf.base());
- }
- int growBy = (int)size;
- growBy += -growBy & 7; // round up mod 8
- return xsmallbuf.grow(growBy);
+ if (!smallOK || size > SMALL)
+ {
+ void *res = must_malloc((int)size);
+ (temp ? &tmallocs : &mallocs)->add(res);
+ return res;
+ }
+ fillbytes &xsmallbuf = *(temp ? &tsmallbuf : &smallbuf);
+ if (!xsmallbuf.canAppend(size + 1))
+ {
+ xsmallbuf.init(CHUNK);
+ (temp ? &tmallocs : &mallocs)->add(xsmallbuf.base());
+ }
+ int growBy = (int)size;
+ growBy += -growBy & 7; // round up mod 8
+ return xsmallbuf.grow(growBy);
}
void unpacker::saveTo(bytes &b, byte *ptr, size_t len)
{
- b.ptr = U_NEW(byte, add_size(len, 1));
- b.len = len;
- b.copyFrom(ptr, len);
+ b.ptr = U_NEW(byte, add_size(len, 1));
+ b.len = len;
+ b.copyFrom(ptr, len);
}
// Read up through band_headers.
// Do the archive_size dance to set the size of the input mega-buffer.
void unpacker::read_file_header()
{
- // Read file header to determine file type and total size.
- enum
- {
- MAGIC_BYTES = 4,
- AH_LENGTH_0 = 3, // minver, majver, options are outside of archive_size
- AH_LENGTH_0_MAX = AH_LENGTH_0 + 1, // options might have 2 bytes
- AH_LENGTH = 26, // maximum archive header length (w/ all fields)
- // Length contributions from optional header fields:
- AH_FILE_HEADER_LEN = 5, // sizehi/lo/next/modtime/files
- AH_ARCHIVE_SIZE_LEN = 2, // sizehi/lo only; part of AH_FILE_HEADER_LEN
- AH_CP_NUMBER_LEN = 4, // int/float/long/double
- AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers
- AH_LENGTH_MIN =
- AH_LENGTH - (AH_FILE_HEADER_LEN + AH_SPECIAL_FORMAT_LEN + AH_CP_NUMBER_LEN),
- ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN),
- FIRST_READ = MAGIC_BYTES + AH_LENGTH_MIN
- };
-
- assert(AH_LENGTH_MIN == 15); // # of UNSIGNED5 fields required after archive_magic
- assert(ARCHIVE_SIZE_MIN == 10); // # of UNSIGNED5 fields required after archive_size
- // An absolute minimum nullptr archive is magic[4], {minver,majver,options}[3],
- // archive_size[0], cp_counts[8], class_counts[4], for a total of 19 bytes.
- // (Note that archive_size is optional; it may be 0..10 bytes in length.)
- // The first read must capture everything up through the options field.
- // This happens to work even if {minver,majver,options} is a pathological
- // 15 bytes long. Legal pack files limit those three fields to 1+1+2 bytes.
- assert(FIRST_READ >= MAGIC_BYTES + AH_LENGTH_0 * B_MAX);
-
- // Up through archive_size, the largest possible archive header is
- // magic[4], {minver,majver,options}[4], archive_size[10].
- // (Note only the low 12 bits of options are allowed to be non-zero.)
- // In order to parse archive_size, we need at least this many bytes
- // in the first read. Of course, if archive_size_hi is more than
- // a byte, we probably will fail to allocate the buffer, since it
- // will be many gigabytes long. This is a practical, not an
- // architectural limit to Pack200 archive sizes.
- assert(FIRST_READ >= MAGIC_BYTES + AH_LENGTH_0_MAX + 2 * B_MAX);
-
- bool foreign_buf = (read_input_fn == nullptr);
- byte initbuf[(int)FIRST_READ + (int)C_SLOP + 200]; // 200 is for JAR I/O
- if (foreign_buf)
- {
- // inbytes is all there is
- input.set(inbytes);
- rp = input.base();
- rplimit = input.limit();
- }
- else
- {
- // inbytes, if not empty, contains some read-ahead we must use first
- // ensure_input will take care of copying it into initbuf,
- // then querying read_input_fn for any additional data needed.
- // However, the caller must assume that we use up all of inbytes.
- // There is no way to tell the caller that we used only part of them.
- // Therefore, the caller must use only a bare minimum of read-ahead.
- if (inbytes.len > FIRST_READ)
- {
- unpack_abort("too much read-ahead");
- }
- input.set(initbuf, sizeof(initbuf));
- input.b.clear();
- input.b.copyFrom(inbytes);
- rplimit = rp = input.base();
- rplimit += inbytes.len;
- bytes_read += inbytes.len;
- }
- // Read only 19 bytes, which is certain to contain #archive_options fields,
- // but is certain not to overflow past the archive_header.
- input.b.len = FIRST_READ;
- if (!ensure_input(FIRST_READ))
- unpack_abort("EOF reading archive magic number");
-
- if (rp[0] == 'P' && rp[1] == 'K')
- {
- // In the Unix-style program, we simply simulate a copy command.
- // Copy until EOF; assume the JAR file is the last segment.
- fprintf(stderr, "Copy-mode.\n");
- for (;;)
- {
- jarout->write_data(rp, (int)input_remaining());
- if (foreign_buf)
- break; // one-time use of a passed in buffer
- if (input.size() < CHUNK)
- {
- // Get some breathing room.
- input.set(U_NEW(byte, (size_t)CHUNK + C_SLOP), (size_t)CHUNK);
- }
- rp = rplimit = input.base();
- if (!ensure_input(1))
- break;
- }
- jarout->closeJarFile(false);
- return;
- }
-
- // Read the magic number.
- magic = 0;
- for (int i1 = 0; i1 < (int)sizeof(magic); i1++)
- {
- magic <<= 8;
- magic += (*rp++ & 0xFF);
- }
-
- // Read the first 3 values from the header.
- value_stream hdr;
- int hdrVals = 0;
- int hdrValsSkipped = 0; // debug only
- hdr.init(rp, rplimit, UNSIGNED5_spec);
- minver = hdr.getInt();
- majver = hdr.getInt();
- hdrVals += 2;
-
- if (magic != (int)JAVA_PACKAGE_MAGIC ||
- (majver != JAVA5_PACKAGE_MAJOR_VERSION && majver != JAVA6_PACKAGE_MAJOR_VERSION) ||
- (minver != JAVA5_PACKAGE_MINOR_VERSION && minver != JAVA6_PACKAGE_MINOR_VERSION))
- {
- char message[200];
- sprintf(message, "@" ERROR_FORMAT ": magic/ver = "
- "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n",
- magic, majver, minver, JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION,
- JAVA5_PACKAGE_MINOR_VERSION, JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION,
- JAVA6_PACKAGE_MINOR_VERSION);
- unpack_abort(message);
- }
-
- archive_options = hdr.getInt();
- hdrVals += 1;
- assert(hdrVals == AH_LENGTH_0); // first three fields only
+ // Read file header to determine file type and total size.
+ enum
+ {
+ MAGIC_BYTES = 4,
+ AH_LENGTH_0 = 3, // minver, majver, options are outside of archive_size
+ AH_LENGTH_0_MAX = AH_LENGTH_0 + 1, // options might have 2 bytes
+ AH_LENGTH = 26, // maximum archive header length (w/ all fields)
+ // Length contributions from optional header fields:
+ AH_FILE_HEADER_LEN = 5, // sizehi/lo/next/modtime/files
+ AH_ARCHIVE_SIZE_LEN = 2, // sizehi/lo only; part of AH_FILE_HEADER_LEN
+ AH_CP_NUMBER_LEN = 4, // int/float/long/double
+ AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers
+ AH_LENGTH_MIN =
+ AH_LENGTH - (AH_FILE_HEADER_LEN + AH_SPECIAL_FORMAT_LEN + AH_CP_NUMBER_LEN),
+ ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN),
+ FIRST_READ = MAGIC_BYTES + AH_LENGTH_MIN
+ };
+
+ assert(AH_LENGTH_MIN == 15); // # of UNSIGNED5 fields required after archive_magic
+ assert(ARCHIVE_SIZE_MIN == 10); // # of UNSIGNED5 fields required after archive_size
+ // An absolute minimum nullptr archive is magic[4], {minver,majver,options}[3],
+ // archive_size[0], cp_counts[8], class_counts[4], for a total of 19 bytes.
+ // (Note that archive_size is optional; it may be 0..10 bytes in length.)
+ // The first read must capture everything up through the options field.
+ // This happens to work even if {minver,majver,options} is a pathological
+ // 15 bytes long. Legal pack files limit those three fields to 1+1+2 bytes.
+ assert(FIRST_READ >= MAGIC_BYTES + AH_LENGTH_0 * B_MAX);
+
+ // Up through archive_size, the largest possible archive header is
+ // magic[4], {minver,majver,options}[4], archive_size[10].
+ // (Note only the low 12 bits of options are allowed to be non-zero.)
+ // In order to parse archive_size, we need at least this many bytes
+ // in the first read. Of course, if archive_size_hi is more than
+ // a byte, we probably will fail to allocate the buffer, since it
+ // will be many gigabytes long. This is a practical, not an
+ // architectural limit to Pack200 archive sizes.
+ assert(FIRST_READ >= MAGIC_BYTES + AH_LENGTH_0_MAX + 2 * B_MAX);
+
+ bool foreign_buf = (read_input_fn == nullptr);
+ byte initbuf[(int)FIRST_READ + (int)C_SLOP + 200]; // 200 is for JAR I/O
+ if (foreign_buf)
+ {
+ // inbytes is all there is
+ input.set(inbytes);
+ rp = input.base();
+ rplimit = input.limit();
+ }
+ else
+ {
+ // inbytes, if not empty, contains some read-ahead we must use first
+ // ensure_input will take care of copying it into initbuf,
+ // then querying read_input_fn for any additional data needed.
+ // However, the caller must assume that we use up all of inbytes.
+ // There is no way to tell the caller that we used only part of them.
+ // Therefore, the caller must use only a bare minimum of read-ahead.
+ if (inbytes.len > FIRST_READ)
+ {
+ unpack_abort("too much read-ahead");
+ }
+ input.set(initbuf, sizeof(initbuf));
+ input.b.clear();
+ input.b.copyFrom(inbytes);
+ rplimit = rp = input.base();
+ rplimit += inbytes.len;
+ bytes_read += inbytes.len;
+ }
+ // Read only 19 bytes, which is certain to contain #archive_options fields,
+ // but is certain not to overflow past the archive_header.
+ input.b.len = FIRST_READ;
+ if (!ensure_input(FIRST_READ))
+ unpack_abort("EOF reading archive magic number");
+
+ if (rp[0] == 'P' && rp[1] == 'K')
+ {
+ // In the Unix-style program, we simply simulate a copy command.
+ // Copy until EOF; assume the JAR file is the last segment.
+ fprintf(stderr, "Copy-mode.\n");
+ for (;;)
+ {
+ jarout->write_data(rp, (int)input_remaining());
+ if (foreign_buf)
+ break; // one-time use of a passed in buffer
+ if (input.size() < CHUNK)
+ {
+ // Get some breathing room.
+ input.set(U_NEW(byte, (size_t)CHUNK + C_SLOP), (size_t)CHUNK);
+ }
+ rp = rplimit = input.base();
+ if (!ensure_input(1))
+ break;
+ }
+ jarout->closeJarFile(false);
+ return;
+ }
+
+ // Read the magic number.
+ magic = 0;
+ for (int i1 = 0; i1 < (int)sizeof(magic); i1++)
+ {
+ magic <<= 8;
+ magic += (*rp++ & 0xFF);
+ }
+
+ // Read the first 3 values from the header.
+ value_stream hdr;
+ int hdrVals = 0;
+ int hdrValsSkipped = 0; // debug only
+ hdr.init(rp, rplimit, UNSIGNED5_spec);
+ minver = hdr.getInt();
+ majver = hdr.getInt();
+ hdrVals += 2;
+
+ if (magic != (int)JAVA_PACKAGE_MAGIC ||
+ (majver != JAVA5_PACKAGE_MAJOR_VERSION && majver != JAVA6_PACKAGE_MAJOR_VERSION) ||
+ (minver != JAVA5_PACKAGE_MINOR_VERSION && minver != JAVA6_PACKAGE_MINOR_VERSION))
+ {
+ char message[200];
+ sprintf(message, "@" ERROR_FORMAT ": magic/ver = "
+ "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n",
+ magic, majver, minver, JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION,
+ JAVA5_PACKAGE_MINOR_VERSION, JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION,
+ JAVA6_PACKAGE_MINOR_VERSION);
+ unpack_abort(message);
+ }
+
+ archive_options = hdr.getInt();
+ hdrVals += 1;
+ assert(hdrVals == AH_LENGTH_0); // first three fields only
#define ORBIT(bit) | (bit)
- int OPTION_LIMIT = (0 ARCHIVE_BIT_DO(ORBIT));
+ int OPTION_LIMIT = (0 ARCHIVE_BIT_DO(ORBIT));
#undef ORBIT
- if ((archive_options & ~OPTION_LIMIT) != 0)
- {
- fprintf(stderr, "Warning: Illegal archive options 0x%x\n", archive_options);
- unpack_abort("illegal archive options");
- return;
- }
-
- if ((archive_options & AO_HAVE_FILE_HEADERS) != 0)
- {
- uint32_t hi = hdr.getInt();
- uint32_t lo = hdr.getInt();
- uint64_t x = band::makeLong(hi, lo);
- archive_size = (size_t)x;
- if (archive_size != x)
- {
- // Silly size specified; force overflow.
- archive_size = PSIZE_MAX + 1;
- }
- hdrVals += 2;
- }
- else
- {
- hdrValsSkipped += 2;
- }
-
- // Now we can size the whole archive.
- // Read everything else into a mega-buffer.
- rp = hdr.rp;
- int header_size_0 = (int)(rp - input.base()); // used-up header (4byte + 3int)
- int header_size_1 = (int)(rplimit - rp); // buffered unused initial fragment
- int header_size = header_size_0 + header_size_1;
- unsized_bytes_read = header_size_0;
- if (foreign_buf)
- {
- if (archive_size > (size_t)header_size_1)
- {
- unpack_abort("EOF reading fixed input buffer");
- return;
- }
- }
- else if (archive_size != 0)
- {
- if (archive_size < ARCHIVE_SIZE_MIN)
- {
- unpack_abort("impossible archive size"); // bad input data
- return;
- }
- if (archive_size < (size_t)header_size_1)
- {
- unpack_abort("too much read-ahead"); // somehow we pre-fetched too much?
- return;
- }
- input.set(U_NEW(byte, add_size(header_size_0, archive_size, C_SLOP)),
- (size_t)header_size_0 + archive_size);
- assert(input.limit()[0] == 0);
- // Move all the bytes we read initially into the real buffer.
- input.b.copyFrom(initbuf, header_size);
- rp = input.b.ptr + header_size_0;
- rplimit = input.b.ptr + header_size;
- }
- else
- {
- // It's more complicated and painful.
- // A zero archive_size means that we must read until EOF.
- input.init(CHUNK * 2);
- input.b.len = input.allocated;
- rp = rplimit = input.base();
- // Set up input buffer as if we already read the header:
- input.b.copyFrom(initbuf, header_size);
- rplimit += header_size;
- while (ensure_input(input.limit() - rp))
- {
- size_t dataSoFar = input_remaining();
- size_t nextSize = add_size(dataSoFar, CHUNK);
- input.ensureSize(nextSize);
- input.b.len = input.allocated;
- rp = rplimit = input.base();
- rplimit += dataSoFar;
- }
- size_t dataSize = (rplimit - input.base());
- input.b.len = dataSize;
- input.grow(C_SLOP);
- free_input = true; // free it later
- input.b.len = dataSize;
- assert(input.limit()[0] == 0);
- rp = rplimit = input.base();
- rplimit += dataSize;
- rp += header_size_0; // already scanned these bytes...
- }
- live_input = true; // mark as "do not reuse"
-
- // read the rest of the header fields
- ensure_input((AH_LENGTH - AH_LENGTH_0) * B_MAX);
- hdr.rp = rp;
- hdr.rplimit = rplimit;
-
- if ((archive_options & AO_HAVE_FILE_HEADERS) != 0)
- {
- archive_next_count = hdr.getInt();
- if (archive_next_count < 0)
- unpack_abort("bad archive_next_count");
- archive_modtime = hdr.getInt();
- file_count = hdr.getInt();
- if (file_count < 0)
- unpack_abort("bad file_count");
- hdrVals += 3;
- }
- else
- {
- hdrValsSkipped += 3;
- }
-
- if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0)
- {
- band_headers_size = hdr.getInt();
- if (band_headers_size < 0)
- unpack_abort("bad band_headers_size");
- attr_definition_count = hdr.getInt();
- if (attr_definition_count < 0)
- unpack_abort("bad attr_definition_count");
- hdrVals += 2;
- }
- else
- {
- hdrValsSkipped += 2;
- }
-
- int cp_counts[N_TAGS_IN_ORDER];
- for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++)
- {
- if (!(archive_options & AO_HAVE_CP_NUMBERS))
- {
- switch (TAGS_IN_ORDER[k])
- {
- case CONSTANT_Integer:
- case CONSTANT_Float:
- case CONSTANT_Long:
- case CONSTANT_Double:
- cp_counts[k] = 0;
- hdrValsSkipped += 1;
- continue;
- }
- }
- cp_counts[k] = hdr.getInt();
- if (cp_counts[k] < 0)
- unpack_abort("bad cp_counts");
- hdrVals += 1;
- }
-
- ic_count = hdr.getInt();
- if (ic_count < 0)
- unpack_abort("bad ic_count");
-
- default_class_minver = hdr.getInt();
- default_class_majver = hdr.getInt();
-
- class_count = hdr.getInt();
- if (class_count < 0)
- unpack_abort("bad class_count");
-
- hdrVals += 4;
-
- // done with archive_header
- hdrVals += hdrValsSkipped;
- assert(hdrVals == AH_LENGTH);
-
- rp = hdr.rp;
- if (rp > rplimit)
- unpack_abort("EOF reading archive header");
-
- // Now size the CP.
- cp.init(this, cp_counts);
-
- default_file_modtime = archive_modtime;
- if (default_file_modtime == 0 && !(archive_options & AO_HAVE_FILE_MODTIME))
- default_file_modtime = DEFAULT_ARCHIVE_MODTIME; // taken from driver
- if ((archive_options & AO_DEFLATE_HINT) != 0)
- default_file_options |= FO_DEFLATE_HINT;
-
- // meta-bytes, if any, immediately follow archive header
- // band_headers.readData(band_headers_size);
- ensure_input(band_headers_size);
- if (input_remaining() < (size_t)band_headers_size)
- {
- unpack_abort("EOF reading band headers");
- return;
- }
- bytes band_headers;
- // The "1+" allows an initial byte to be pushed on the front.
- band_headers.set(1 + U_NEW(byte, 1 + band_headers_size + C_SLOP), band_headers_size);
-
- // Start scanning band headers here:
- band_headers.copyFrom(rp, band_headers.len);
- rp += band_headers.len;
- assert(rp <= rplimit);
- meta_rp = band_headers.ptr;
- // Put evil meta-codes at the end of the band headers,
- // so we are sure to throw an error if we run off the end.
- bytes::of(band_headers.limit(), C_SLOP).clear(_meta_error);
+ if ((archive_options & ~OPTION_LIMIT) != 0)
+ {
+ fprintf(stderr, "Warning: Illegal archive options 0x%x\n", archive_options);
+ unpack_abort("illegal archive options");
+ return;
+ }
+
+ if ((archive_options & AO_HAVE_FILE_HEADERS) != 0)
+ {
+ uint32_t hi = hdr.getInt();
+ uint32_t lo = hdr.getInt();
+ uint64_t x = band::makeLong(hi, lo);
+ archive_size = (size_t)x;
+ if (archive_size != x)
+ {
+ // Silly size specified; force overflow.
+ archive_size = PSIZE_MAX + 1;
+ }
+ hdrVals += 2;
+ }
+ else
+ {
+ hdrValsSkipped += 2;
+ }
+
+ // Now we can size the whole archive.
+ // Read everything else into a mega-buffer.
+ rp = hdr.rp;
+ int header_size_0 = (int)(rp - input.base()); // used-up header (4byte + 3int)
+ int header_size_1 = (int)(rplimit - rp); // buffered unused initial fragment
+ int header_size = header_size_0 + header_size_1;
+ unsized_bytes_read = header_size_0;
+ if (foreign_buf)
+ {
+ if (archive_size > (size_t)header_size_1)
+ {
+ unpack_abort("EOF reading fixed input buffer");
+ return;
+ }
+ }
+ else if (archive_size != 0)
+ {
+ if (archive_size < ARCHIVE_SIZE_MIN)
+ {
+ unpack_abort("impossible archive size"); // bad input data
+ return;
+ }
+ if (archive_size < (size_t)header_size_1)
+ {
+ unpack_abort("too much read-ahead"); // somehow we pre-fetched too much?
+ return;
+ }
+ input.set(U_NEW(byte, add_size(header_size_0, archive_size, C_SLOP)),
+ (size_t)header_size_0 + archive_size);
+ assert(input.limit()[0] == 0);
+ // Move all the bytes we read initially into the real buffer.
+ input.b.copyFrom(initbuf, header_size);
+ rp = input.b.ptr + header_size_0;
+ rplimit = input.b.ptr + header_size;
+ }
+ else
+ {
+ // It's more complicated and painful.
+ // A zero archive_size means that we must read until EOF.
+ input.init(CHUNK * 2);
+ input.b.len = input.allocated;
+ rp = rplimit = input.base();
+ // Set up input buffer as if we already read the header:
+ input.b.copyFrom(initbuf, header_size);
+ rplimit += header_size;
+ while (ensure_input(input.limit() - rp))
+ {
+ size_t dataSoFar = input_remaining();
+ size_t nextSize = add_size(dataSoFar, CHUNK);
+ input.ensureSize(nextSize);
+ input.b.len = input.allocated;
+ rp = rplimit = input.base();
+ rplimit += dataSoFar;
+ }
+ size_t dataSize = (rplimit - input.base());
+ input.b.len = dataSize;
+ input.grow(C_SLOP);
+ free_input = true; // free it later
+ input.b.len = dataSize;
+ assert(input.limit()[0] == 0);
+ rp = rplimit = input.base();
+ rplimit += dataSize;
+ rp += header_size_0; // already scanned these bytes...
+ }
+ live_input = true; // mark as "do not reuse"
+
+ // read the rest of the header fields
+ ensure_input((AH_LENGTH - AH_LENGTH_0) * B_MAX);
+ hdr.rp = rp;
+ hdr.rplimit = rplimit;
+
+ if ((archive_options & AO_HAVE_FILE_HEADERS) != 0)
+ {
+ archive_next_count = hdr.getInt();
+ if (archive_next_count < 0)
+ unpack_abort("bad archive_next_count");
+ archive_modtime = hdr.getInt();
+ file_count = hdr.getInt();
+ if (file_count < 0)
+ unpack_abort("bad file_count");
+ hdrVals += 3;
+ }
+ else
+ {
+ hdrValsSkipped += 3;
+ }
+
+ if ((archive_options & AO_HAVE_SPECIAL_FORMATS) != 0)
+ {
+ band_headers_size = hdr.getInt();
+ if (band_headers_size < 0)
+ unpack_abort("bad band_headers_size");
+ attr_definition_count = hdr.getInt();
+ if (attr_definition_count < 0)
+ unpack_abort("bad attr_definition_count");
+ hdrVals += 2;
+ }
+ else
+ {
+ hdrValsSkipped += 2;
+ }
+
+ int cp_counts[N_TAGS_IN_ORDER];
+ for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++)
+ {
+ if (!(archive_options & AO_HAVE_CP_NUMBERS))
+ {
+ switch (TAGS_IN_ORDER[k])
+ {
+ case CONSTANT_Integer:
+ case CONSTANT_Float:
+ case CONSTANT_Long:
+ case CONSTANT_Double:
+ cp_counts[k] = 0;
+ hdrValsSkipped += 1;
+ continue;
+ }
+ }
+ cp_counts[k] = hdr.getInt();
+ if (cp_counts[k] < 0)
+ unpack_abort("bad cp_counts");
+ hdrVals += 1;
+ }
+
+ ic_count = hdr.getInt();
+ if (ic_count < 0)
+ unpack_abort("bad ic_count");
+
+ default_class_minver = hdr.getInt();
+ default_class_majver = hdr.getInt();
+
+ class_count = hdr.getInt();
+ if (class_count < 0)
+ unpack_abort("bad class_count");
+
+ hdrVals += 4;
+
+ // done with archive_header
+ hdrVals += hdrValsSkipped;
+ assert(hdrVals == AH_LENGTH);
+
+ rp = hdr.rp;
+ if (rp > rplimit)
+ unpack_abort("EOF reading archive header");
+
+ // Now size the CP.
+ cp.init(this, cp_counts);
+
+ default_file_modtime = archive_modtime;
+ if (default_file_modtime == 0 && !(archive_options & AO_HAVE_FILE_MODTIME))
+ default_file_modtime = DEFAULT_ARCHIVE_MODTIME; // taken from driver
+ if ((archive_options & AO_DEFLATE_HINT) != 0)
+ default_file_options |= FO_DEFLATE_HINT;
+
+ // meta-bytes, if any, immediately follow archive header
+ // band_headers.readData(band_headers_size);
+ ensure_input(band_headers_size);
+ if (input_remaining() < (size_t)band_headers_size)
+ {
+ unpack_abort("EOF reading band headers");
+ return;
+ }
+ bytes band_headers;
+ // The "1+" allows an initial byte to be pushed on the front.
+ band_headers.set(1 + U_NEW(byte, 1 + band_headers_size + C_SLOP), band_headers_size);
+
+ // Start scanning band headers here:
+ band_headers.copyFrom(rp, band_headers.len);
+ rp += band_headers.len;
+ assert(rp <= rplimit);
+ meta_rp = band_headers.ptr;
+ // Put evil meta-codes at the end of the band headers,
+ // so we are sure to throw an error if we run off the end.
+ bytes::of(band_headers.limit(), C_SLOP).clear(_meta_error);
}
void unpacker::finish()
{
- if (verbose >= 1)
- {
- fprintf(stderr, "A total of %" PRIu64 " bytes were read in %d segment(s).\n",
- (bytes_read_before_reset + bytes_read), segments_read_before_reset + 1);
- fprintf(stderr, "A total of %" PRIu64 " file content bytes were written.\n",
- (bytes_written_before_reset + bytes_written));
- fprintf(stderr,
- "A total of %d files (of which %d are classes) were written to output.\n",
- files_written_before_reset + files_written,
- classes_written_before_reset + classes_written);
- }
- if (jarout != nullptr)
- jarout->closeJarFile(true);
+ if (verbose >= 1)
+ {
+ fprintf(stderr, "A total of %" PRIu64 " bytes were read in %d segment(s).\n",
+ (bytes_read_before_reset + bytes_read), segments_read_before_reset + 1);
+ fprintf(stderr, "A total of %" PRIu64 " file content bytes were written.\n",
+ (bytes_written_before_reset + bytes_written));
+ fprintf(stderr,
+ "A total of %d files (of which %d are classes) were written to output.\n",
+ files_written_before_reset + files_written,
+ classes_written_before_reset + classes_written);
+ }
+ if (jarout != nullptr)
+ jarout->closeJarFile(true);
}
// Cf. PackageReader.readConstantPoolCounts
void constant_pool::init(unpacker *u_, int counts[NUM_COUNTS])
{
- this->u = u_;
-
- // Fill-pointer for CP.
- int next_entry = 0;
-
- // Size the constant pool:
- for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++)
- {
- byte tag = TAGS_IN_ORDER[k];
- int len = counts[k];
- tag_count[tag] = len;
- tag_base[tag] = next_entry;
- next_entry += len;
- // Detect and defend against constant pool size overflow.
- // (Pack200 forbids the sum of CP counts to exceed 2^29-1.)
- enum
- {
- CP_SIZE_LIMIT = (1 << 29),
- IMPLICIT_ENTRY_COUNT = 1 // empty Utf8 string
- };
- if (len >= (1 << 29) || len < 0 || next_entry >= CP_SIZE_LIMIT + IMPLICIT_ENTRY_COUNT)
- {
- unpack_abort("archive too large: constant pool limit exceeded");
- }
- }
-
- // Close off the end of the CP:
- nentries = next_entry;
-
- // place a limit on future CP growth:
- int generous = 0;
- generous = add_size(generous, u->ic_count); // implicit name
- generous = add_size(generous, u->ic_count); // outer
- generous = add_size(generous, u->ic_count); // outer.utf8
- generous = add_size(generous, 40); // WKUs, misc
- generous = add_size(generous, u->class_count); // implicit SourceFile strings
- maxentries = add_size(nentries, generous);
-
- // Note that this CP does not include "empty" entries
- // for longs and doubles. Those are introduced when
- // the entries are renumbered for classfile output.
-
- entries = U_NEW(entry, maxentries);
-
- first_extra_entry = &entries[nentries];
-
- // Initialize the standard indexes.
- tag_count[CONSTANT_All] = nentries;
- tag_base[CONSTANT_All] = 0;
- for (int tag = 0; tag < CONSTANT_Limit; tag++)
- {
- entry *cpMap = &entries[tag_base[tag]];
- tag_index[tag].init(tag_count[tag], cpMap, tag);
- }
-
- // Initialize hashTab to a generous power-of-two size.
- uint32_t pow2 = 1;
- uint32_t target = maxentries + maxentries / 2; // 60% full
- while (pow2 < target)
- pow2 <<= 1;
- hashTab = U_NEW(entry *, hashTabLength = pow2);
+ this->u = u_;
+
+ // Fill-pointer for CP.
+ int next_entry = 0;
+
+ // Size the constant pool:
+ for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++)
+ {
+ byte tag = TAGS_IN_ORDER[k];
+ int len = counts[k];
+ tag_count[tag] = len;
+ tag_base[tag] = next_entry;
+ next_entry += len;
+ // Detect and defend against constant pool size overflow.
+ // (Pack200 forbids the sum of CP counts to exceed 2^29-1.)
+ enum
+ {
+ CP_SIZE_LIMIT = (1 << 29),
+ IMPLICIT_ENTRY_COUNT = 1 // empty Utf8 string
+ };
+ if (len >= (1 << 29) || len < 0 || next_entry >= CP_SIZE_LIMIT + IMPLICIT_ENTRY_COUNT)
+ {
+ unpack_abort("archive too large: constant pool limit exceeded");
+ }
+ }
+
+ // Close off the end of the CP:
+ nentries = next_entry;
+
+ // place a limit on future CP growth:
+ int generous = 0;
+ generous = add_size(generous, u->ic_count); // implicit name
+ generous = add_size(generous, u->ic_count); // outer
+ generous = add_size(generous, u->ic_count); // outer.utf8
+ generous = add_size(generous, 40); // WKUs, misc
+ generous = add_size(generous, u->class_count); // implicit SourceFile strings
+ maxentries = add_size(nentries, generous);
+
+ // Note that this CP does not include "empty" entries
+ // for longs and doubles. Those are introduced when
+ // the entries are renumbered for classfile output.
+
+ entries = U_NEW(entry, maxentries);
+
+ first_extra_entry = &entries[nentries];
+
+ // Initialize the standard indexes.
+ tag_count[CONSTANT_All] = nentries;
+ tag_base[CONSTANT_All] = 0;
+ for (int tag = 0; tag < CONSTANT_Limit; tag++)
+ {
+ entry *cpMap = &entries[tag_base[tag]];
+ tag_index[tag].init(tag_count[tag], cpMap, tag);
+ }
+
+ // Initialize hashTab to a generous power-of-two size.
+ uint32_t pow2 = 1;
+ uint32_t target = maxentries + maxentries / 2; // 60% full
+ while (pow2 < target)
+ pow2 <<= 1;
+ hashTab = U_NEW(entry *, hashTabLength = pow2);
}
static byte *store_Utf8_char(byte *cp, unsigned short ch)
{
- if (ch >= 0x001 && ch <= 0x007F)
- {
- *cp++ = (byte)ch;
- }
- else if (ch <= 0x07FF)
- {
- *cp++ = (byte)(0xC0 | ((ch >> 6) & 0x1F));
- *cp++ = (byte)(0x80 | ((ch >> 0) & 0x3F));
- }
- else
- {
- *cp++ = (byte)(0xE0 | ((ch >> 12) & 0x0F));
- *cp++ = (byte)(0x80 | ((ch >> 6) & 0x3F));
- *cp++ = (byte)(0x80 | ((ch >> 0) & 0x3F));
- }
- return cp;
+ if (ch >= 0x001 && ch <= 0x007F)
+ {
+ *cp++ = (byte)ch;
+ }
+ else if (ch <= 0x07FF)
+ {
+ *cp++ = (byte)(0xC0 | ((ch >> 6) & 0x1F));
+ *cp++ = (byte)(0x80 | ((ch >> 0) & 0x3F));
+ }
+ else
+ {
+ *cp++ = (byte)(0xE0 | ((ch >> 12) & 0x0F));
+ *cp++ = (byte)(0x80 | ((ch >> 6) & 0x3F));
+ *cp++ = (byte)(0x80 | ((ch >> 0) & 0x3F));
+ }
+ return cp;
}
static byte *skip_Utf8_chars(byte *cp, int len)
{
- for (;; cp++)
- {
- int ch = *cp & 0xFF;
- if ((ch & 0xC0) != 0x80)
- {
- if (len-- == 0)
- return cp;
- if (ch < 0x80 && len == 0)
- return cp + 1;
- }
- }
+ for (;; cp++)
+ {
+ int ch = *cp & 0xFF;
+ if ((ch & 0xC0) != 0x80)
+ {
+ if (len-- == 0)
+ return cp;
+ if (ch < 0x80 && len == 0)
+ return cp + 1;
+ }
+ }
}
static int compare_Utf8_chars(bytes &b1, bytes &b2)
{
- int l1 = (int)b1.len;
- int l2 = (int)b2.len;
- int l0 = (l1 < l2) ? l1 : l2;
- byte *p1 = b1.ptr;
- byte *p2 = b2.ptr;
- int c0 = 0;
- for (int i = 0; i < l0; i++)
- {
- int c1 = p1[i] & 0xFF;
- int c2 = p2[i] & 0xFF;
- if (c1 != c2)
- {
- // Before returning the obvious answer,
- // check to see if c1 or c2 is part of a 0x0000,
- // which encodes as {0xC0,0x80}. The 0x0000 is the
- // lowest-sorting Java char value, and yet it encodes
- // as if it were the first char after 0x7F, which causes
- // strings containing nulls to sort too high. All other
- // comparisons are consistent between Utf8 and Java chars.
- if (c1 == 0xC0 && (p1[i + 1] & 0xFF) == 0x80)
- c1 = 0;
- if (c2 == 0xC0 && (p2[i + 1] & 0xFF) == 0x80)
- c2 = 0;
- if (c0 == 0xC0)
- {
- assert(((c1 | c2) & 0xC0) == 0x80); // c1 & c2 are extension chars
- if (c1 == 0x80)
- c1 = 0; // will sort below c2
- if (c2 == 0x80)
- c2 = 0; // will sort below c1
- }
- return c1 - c2;
- }
- c0 = c1; // save away previous char
- }
- // common prefix is identical; return length difference if any
- return l1 - l2;
+ int l1 = (int)b1.len;
+ int l2 = (int)b2.len;
+ int l0 = (l1 < l2) ? l1 : l2;
+ byte *p1 = b1.ptr;
+ byte *p2 = b2.ptr;
+ int c0 = 0;
+ for (int i = 0; i < l0; i++)
+ {
+ int c1 = p1[i] & 0xFF;
+ int c2 = p2[i] & 0xFF;
+ if (c1 != c2)
+ {
+ // Before returning the obvious answer,
+ // check to see if c1 or c2 is part of a 0x0000,
+ // which encodes as {0xC0,0x80}. The 0x0000 is the
+ // lowest-sorting Java char value, and yet it encodes
+ // as if it were the first char after 0x7F, which causes
+ // strings containing nulls to sort too high. All other
+ // comparisons are consistent between Utf8 and Java chars.
+ if (c1 == 0xC0 && (p1[i + 1] & 0xFF) == 0x80)
+ c1 = 0;
+ if (c2 == 0xC0 && (p2[i + 1] & 0xFF) == 0x80)
+ c2 = 0;
+ if (c0 == 0xC0)
+ {
+ assert(((c1 | c2) & 0xC0) == 0x80); // c1 & c2 are extension chars
+ if (c1 == 0x80)
+ c1 = 0; // will sort below c2
+ if (c2 == 0x80)
+ c2 = 0; // will sort below c1
+ }
+ return c1 - c2;
+ }
+ c0 = c1; // save away previous char
+ }
+ // common prefix is identical; return length difference if any
+ return l1 - l2;
}
// Cf. PackageReader.readUtf8Bands
void unpacker::read_Utf8_values(entry *cpMap, int len)
{
- // Implicit first Utf8 string is the empty string.
- enum
- {
- // certain bands begin with implicit zeroes
- PREFIX_SKIP_2 = 2,
- SUFFIX_SKIP_1 = 1
- };
-
- int i;
-
- // First band: Read lengths of shared prefixes.
- if (len > PREFIX_SKIP_2)
- cp_Utf8_prefix.readData(len - PREFIX_SKIP_2);
-
- // Second band: Read lengths of unshared suffixes:
- if (len > SUFFIX_SKIP_1)
- cp_Utf8_suffix.readData(len - SUFFIX_SKIP_1);
-
- bytes *allsuffixes = T_NEW(bytes, len);
-
- int nbigsuf = 0;
- fillbytes charbuf; // buffer to allocate small strings
- charbuf.init();
-
- // Third band: Read the char values in the unshared suffixes:
- cp_Utf8_chars.readData(cp_Utf8_suffix.getIntTotal());
- for (i = 0; i < len; i++)
- {
- int suffix = (i < SUFFIX_SKIP_1) ? 0 : cp_Utf8_suffix.getInt();
- if (suffix < 0)
- {
- unpack_abort("bad utf8 suffix");
- }
- if (suffix == 0 && i >= SUFFIX_SKIP_1)
- {
- // chars are packed in cp_Utf8_big_chars
- nbigsuf += 1;
- continue;
- }
- bytes &chars = allsuffixes[i];
- uint32_t size3 = suffix * 3; // max Utf8 length
- bool isMalloc = (suffix > SMALL);
- if (isMalloc)
- {
- chars.malloc(size3);
- }
- else
- {
- if (!charbuf.canAppend(size3 + 1))
- {
- assert(charbuf.allocated == 0 || tmallocs.contains(charbuf.base()));
- charbuf.init(CHUNK); // Reset to new buffer.
- tmallocs.add(charbuf.base());
- }
- chars.set(charbuf.grow(size3 + 1), size3);
- }
-
- byte *chp = chars.ptr;
- for (int j = 0; j < suffix; j++)
- {
- unsigned short ch = cp_Utf8_chars.getInt();
- chp = store_Utf8_char(chp, ch);
- }
- // shrink to fit:
- if (isMalloc)
- {
- chars.realloc(chp - chars.ptr);
- tmallocs.add(chars.ptr); // free it later
- }
- else
- {
- int shrink = (int)(chars.limit() - chp);
- chars.len -= shrink;
- charbuf.b.len -= shrink; // ungrow to reclaim buffer space
- // Note that we did not reclaim the final '\0'.
- assert(chars.limit() == charbuf.limit() - 1);
- assert(strlen((char *)chars.ptr) == chars.len);
- }
- }
- // cp_Utf8_chars.done();
-
- // Fourth band: Go back and size the specially packed strings.
- int maxlen = 0;
- cp_Utf8_big_suffix.readData(nbigsuf);
- cp_Utf8_suffix.rewind();
- for (i = 0; i < len; i++)
- {
- int suffix = (i < SUFFIX_SKIP_1) ? 0 : cp_Utf8_suffix.getInt();
- int prefix = (i < PREFIX_SKIP_2) ? 0 : cp_Utf8_prefix.getInt();
- if (prefix < 0 || prefix + suffix < 0)
- {
- unpack_abort("bad utf8 prefix");
- }
- bytes &chars = allsuffixes[i];
- if (suffix == 0 && i >= SUFFIX_SKIP_1)
- {
- suffix = cp_Utf8_big_suffix.getInt();
- assert(chars.ptr == nullptr);
- chars.len = suffix; // just a momentary hack
- }
- else
- {
- assert(chars.ptr != nullptr);
- }
- if (maxlen < prefix + suffix)
- {
- maxlen = prefix + suffix;
- }
- }
- // cp_Utf8_suffix.done(); // will use allsuffixes[i].len (ptr!=nullptr)
- // cp_Utf8_big_suffix.done(); // will use allsuffixes[i].len
-
- // Fifth band(s): Get the specially packed characters.
- cp_Utf8_big_suffix.rewind();
- for (i = 0; i < len; i++)
- {
- bytes &chars = allsuffixes[i];
- if (chars.ptr != nullptr)
- continue; // already input
- int suffix = (int)chars.len; // pick up the hack
- uint32_t size3 = suffix * 3;
- if (suffix == 0)
- continue; // done with empty string
- chars.malloc(size3);
- byte *chp = chars.ptr;
- band saved_band = cp_Utf8_big_chars;
- cp_Utf8_big_chars.readData(suffix);
- for (int j = 0; j < suffix; j++)
- {
- unsigned short ch = cp_Utf8_big_chars.getInt();
- chp = store_Utf8_char(chp, ch);
- }
- chars.realloc(chp - chars.ptr);
- tmallocs.add(chars.ptr); // free it later
- // cp_Utf8_big_chars.done();
- cp_Utf8_big_chars = saved_band; // reset the band for the next string
- }
- cp_Utf8_big_chars.readData(0); // zero chars
- // cp_Utf8_big_chars.done();
-
- // Finally, sew together all the prefixes and suffixes.
- bytes bigbuf;
- bigbuf.malloc(maxlen * 3 + 1); // max Utf8 length, plus slop for nullptr
- int prevlen = 0; // previous string length (in chars)
- tmallocs.add(bigbuf.ptr); // free after this block
- cp_Utf8_prefix.rewind();
- for (i = 0; i < len; i++)
- {
- bytes &chars = allsuffixes[i];
- int prefix = (i < PREFIX_SKIP_2) ? 0 : cp_Utf8_prefix.getInt();
- int suffix = (int)chars.len;
- byte *fillp;
- // by induction, the buffer is already filled with the prefix
- // make sure the prefix value is not corrupted, though:
- if (prefix > prevlen)
- {
- unpack_abort("utf8 prefix overflow");
- return;
- }
- fillp = skip_Utf8_chars(bigbuf.ptr, prefix);
- // copy the suffix into the same buffer:
- fillp = chars.writeTo(fillp);
- assert(bigbuf.inBounds(fillp));
- *fillp = 0; // bigbuf must contain a well-formed Utf8 string
- int length = (int)(fillp - bigbuf.ptr);
- bytes &value = cpMap[i].value.b;
- value.set(U_NEW(byte, add_size(length, 1)), length);
- value.copyFrom(bigbuf.ptr, length);
- // Index all Utf8 strings
- entry *&htref = cp.hashTabRef(CONSTANT_Utf8, value);
- if (htref == nullptr)
- {
- // Note that if two identical strings are transmitted,
- // the first is taken to be the canonical one.
- htref = &cpMap[i];
- }
- prevlen = prefix + suffix;
- }
- // cp_Utf8_prefix.done();
-
- // Free intermediate buffers.
- free_temps();
+ // Implicit first Utf8 string is the empty string.
+ enum
+ {
+ // certain bands begin with implicit zeroes
+ PREFIX_SKIP_2 = 2,
+ SUFFIX_SKIP_1 = 1
+ };
+
+ int i;
+
+ // First band: Read lengths of shared prefixes.
+ if (len > PREFIX_SKIP_2)
+ cp_Utf8_prefix.readData(len - PREFIX_SKIP_2);
+
+ // Second band: Read lengths of unshared suffixes:
+ if (len > SUFFIX_SKIP_1)
+ cp_Utf8_suffix.readData(len - SUFFIX_SKIP_1);
+
+ bytes *allsuffixes = T_NEW(bytes, len);
+
+ int nbigsuf = 0;
+ fillbytes charbuf; // buffer to allocate small strings
+ charbuf.init();
+
+ // Third band: Read the char values in the unshared suffixes:
+ cp_Utf8_chars.readData(cp_Utf8_suffix.getIntTotal());
+ for (i = 0; i < len; i++)
+ {
+ int suffix = (i < SUFFIX_SKIP_1) ? 0 : cp_Utf8_suffix.getInt();
+ if (suffix < 0)
+ {
+ unpack_abort("bad utf8 suffix");
+ }
+ if (suffix == 0 && i >= SUFFIX_SKIP_1)
+ {
+ // chars are packed in cp_Utf8_big_chars
+ nbigsuf += 1;
+ continue;
+ }
+ bytes &chars = allsuffixes[i];
+ uint32_t size3 = suffix * 3; // max Utf8 length
+ bool isMalloc = (suffix > SMALL);
+ if (isMalloc)
+ {
+ chars.malloc(size3);
+ }
+ else
+ {
+ if (!charbuf.canAppend(size3 + 1))
+ {
+ assert(charbuf.allocated == 0 || tmallocs.contains(charbuf.base()));
+ charbuf.init(CHUNK); // Reset to new buffer.
+ tmallocs.add(charbuf.base());
+ }
+ chars.set(charbuf.grow(size3 + 1), size3);
+ }
+
+ byte *chp = chars.ptr;
+ for (int j = 0; j < suffix; j++)
+ {
+ unsigned short ch = cp_Utf8_chars.getInt();
+ chp = store_Utf8_char(chp, ch);
+ }
+ // shrink to fit:
+ if (isMalloc)
+ {
+ chars.realloc(chp - chars.ptr);
+ tmallocs.add(chars.ptr); // free it later
+ }
+ else
+ {
+ int shrink = (int)(chars.limit() - chp);
+ chars.len -= shrink;
+ charbuf.b.len -= shrink; // ungrow to reclaim buffer space
+ // Note that we did not reclaim the final '\0'.
+ assert(chars.limit() == charbuf.limit() - 1);
+ assert(strlen((char *)chars.ptr) == chars.len);
+ }
+ }
+ // cp_Utf8_chars.done();
+
+ // Fourth band: Go back and size the specially packed strings.
+ int maxlen = 0;
+ cp_Utf8_big_suffix.readData(nbigsuf);
+ cp_Utf8_suffix.rewind();
+ for (i = 0; i < len; i++)
+ {
+ int suffix = (i < SUFFIX_SKIP_1) ? 0 : cp_Utf8_suffix.getInt();
+ int prefix = (i < PREFIX_SKIP_2) ? 0 : cp_Utf8_prefix.getInt();
+ if (prefix < 0 || prefix + suffix < 0)
+ {
+ unpack_abort("bad utf8 prefix");
+ }
+ bytes &chars = allsuffixes[i];
+ if (suffix == 0 && i >= SUFFIX_SKIP_1)
+ {
+ suffix = cp_Utf8_big_suffix.getInt();
+ assert(chars.ptr == nullptr);
+ chars.len = suffix; // just a momentary hack
+ }
+ else
+ {
+ assert(chars.ptr != nullptr);
+ }
+ if (maxlen < prefix + suffix)
+ {
+ maxlen = prefix + suffix;
+ }
+ }
+ // cp_Utf8_suffix.done(); // will use allsuffixes[i].len (ptr!=nullptr)
+ // cp_Utf8_big_suffix.done(); // will use allsuffixes[i].len
+
+ // Fifth band(s): Get the specially packed characters.
+ cp_Utf8_big_suffix.rewind();
+ for (i = 0; i < len; i++)
+ {
+ bytes &chars = allsuffixes[i];
+ if (chars.ptr != nullptr)
+ continue; // already input
+ int suffix = (int)chars.len; // pick up the hack
+ uint32_t size3 = suffix * 3;
+ if (suffix == 0)
+ continue; // done with empty string
+ chars.malloc(size3);
+ byte *chp = chars.ptr;
+ band saved_band = cp_Utf8_big_chars;
+ cp_Utf8_big_chars.readData(suffix);
+ for (int j = 0; j < suffix; j++)
+ {
+ unsigned short ch = cp_Utf8_big_chars.getInt();
+ chp = store_Utf8_char(chp, ch);
+ }
+ chars.realloc(chp - chars.ptr);
+ tmallocs.add(chars.ptr); // free it later
+ // cp_Utf8_big_chars.done();
+ cp_Utf8_big_chars = saved_band; // reset the band for the next string
+ }
+ cp_Utf8_big_chars.readData(0); // zero chars
+ // cp_Utf8_big_chars.done();
+
+ // Finally, sew together all the prefixes and suffixes.
+ bytes bigbuf;
+ bigbuf.malloc(maxlen * 3 + 1); // max Utf8 length, plus slop for nullptr
+ int prevlen = 0; // previous string length (in chars)
+ tmallocs.add(bigbuf.ptr); // free after this block
+ cp_Utf8_prefix.rewind();
+ for (i = 0; i < len; i++)
+ {
+ bytes &chars = allsuffixes[i];
+ int prefix = (i < PREFIX_SKIP_2) ? 0 : cp_Utf8_prefix.getInt();
+ int suffix = (int)chars.len;
+ byte *fillp;
+ // by induction, the buffer is already filled with the prefix
+ // make sure the prefix value is not corrupted, though:
+ if (prefix > prevlen)
+ {
+ unpack_abort("utf8 prefix overflow");
+ return;
+ }
+ fillp = skip_Utf8_chars(bigbuf.ptr, prefix);
+ // copy the suffix into the same buffer:
+ fillp = chars.writeTo(fillp);
+ assert(bigbuf.inBounds(fillp));
+ *fillp = 0; // bigbuf must contain a well-formed Utf8 string
+ int length = (int)(fillp - bigbuf.ptr);
+ bytes &value = cpMap[i].value.b;
+ value.set(U_NEW(byte, add_size(length, 1)), length);
+ value.copyFrom(bigbuf.ptr, length);
+ // Index all Utf8 strings
+ entry *&htref = cp.hashTabRef(CONSTANT_Utf8, value);
+ if (htref == nullptr)
+ {
+ // Note that if two identical strings are transmitted,
+ // the first is taken to be the canonical one.
+ htref = &cpMap[i];
+ }
+ prevlen = prefix + suffix;
+ }
+ // cp_Utf8_prefix.done();
+
+ // Free intermediate buffers.
+ free_temps();
}
void unpacker::read_single_words(band &cp_band, entry *cpMap, int len)
{
- cp_band.readData(len);
- for (int i = 0; i < len; i++)
- {
- cpMap[i].value.i = cp_band.getInt(); // coding handles signs OK
- }
+ cp_band.readData(len);
+ for (int i = 0; i < len; i++)
+ {
+ cpMap[i].value.i = cp_band.getInt(); // coding handles signs OK
+ }
}
void unpacker::read_double_words(band &cp_bands, entry *cpMap, int len)
{
- band &cp_band_hi = cp_bands;
- band &cp_band_lo = cp_bands.nextBand();
- cp_band_hi.readData(len);
- cp_band_lo.readData(len);
- for (int i = 0; i < len; i++)
- {
- cpMap[i].value.l = cp_band_hi.getLong(cp_band_lo, true);
- }
- // cp_band_hi.done();
- // cp_band_lo.done();
+ band &cp_band_hi = cp_bands;
+ band &cp_band_lo = cp_bands.nextBand();
+ cp_band_hi.readData(len);
+ cp_band_lo.readData(len);
+ for (int i = 0; i < len; i++)
+ {
+ cpMap[i].value.l = cp_band_hi.getLong(cp_band_lo, true);
+ }
+ // cp_band_hi.done();
+ // cp_band_lo.done();
}
void unpacker::read_single_refs(band &cp_band, byte refTag, entry *cpMap, int len)
{
- assert(refTag == CONSTANT_Utf8);
- cp_band.setIndexByTag(refTag);
- cp_band.readData(len);
- int indexTag = (cp_band.bn == e_cp_Class) ? CONSTANT_Class : 0;
- for (int i = 0; i < len; i++)
- {
- entry &e = cpMap[i];
- e.refs = U_NEW(entry *, e.nrefs = 1);
- entry *utf = cp_band.getRef();
- e.refs[0] = utf;
- e.value.b = utf->value.b; // copy value of Utf8 string to self
- if (indexTag != 0)
- {
- // Maintain cross-reference:
- entry *&htref = cp.hashTabRef(indexTag, e.value.b);
- if (htref == nullptr)
- {
- // Note that if two identical classes are transmitted,
- // the first is taken to be the canonical one.
- htref = &e;
- }
- }
- }
- // cp_band.done();
+ assert(refTag == CONSTANT_Utf8);
+ cp_band.setIndexByTag(refTag);
+ cp_band.readData(len);
+ int indexTag = (cp_band.bn == e_cp_Class) ? CONSTANT_Class : 0;
+ for (int i = 0; i < len; i++)
+ {
+ entry &e = cpMap[i];
+ e.refs = U_NEW(entry *, e.nrefs = 1);
+ entry *utf = cp_band.getRef();
+ e.refs[0] = utf;
+ e.value.b = utf->value.b; // copy value of Utf8 string to self
+ if (indexTag != 0)
+ {
+ // Maintain cross-reference:
+ entry *&htref = cp.hashTabRef(indexTag, e.value.b);
+ if (htref == nullptr)
+ {
+ // Note that if two identical classes are transmitted,
+ // the first is taken to be the canonical one.
+ htref = &e;
+ }
+ }
+ }
+ // cp_band.done();
}
void unpacker::read_double_refs(band &cp_band, byte ref1Tag, byte ref2Tag, entry *cpMap,
- int len)
+ int len)
{
- band &cp_band1 = cp_band;
- band &cp_band2 = cp_band.nextBand();
- cp_band1.setIndexByTag(ref1Tag);
- cp_band2.setIndexByTag(ref2Tag);
- cp_band1.readData(len);
- cp_band2.readData(len);
- for (int i = 0; i < len; i++)
- {
- entry &e = cpMap[i];
- e.refs = U_NEW(entry *, e.nrefs = 2);
- e.refs[0] = cp_band1.getRef();
- e.refs[1] = cp_band2.getRef();
- }
- // cp_band1.done();
- // cp_band2.done();
+ band &cp_band1 = cp_band;
+ band &cp_band2 = cp_band.nextBand();
+ cp_band1.setIndexByTag(ref1Tag);
+ cp_band2.setIndexByTag(ref2Tag);
+ cp_band1.readData(len);
+ cp_band2.readData(len);
+ for (int i = 0; i < len; i++)
+ {
+ entry &e = cpMap[i];
+ e.refs = U_NEW(entry *, e.nrefs = 2);
+ e.refs[0] = cp_band1.getRef();
+ e.refs[1] = cp_band2.getRef();
+ }
+ // cp_band1.done();
+ // cp_band2.done();
}
// Cf. PackageReader.readSignatureBands
void unpacker::read_signature_values(entry *cpMap, int len)
{
- cp_Signature_form.setIndexByTag(CONSTANT_Utf8);
- cp_Signature_form.readData(len);
- int ncTotal = 0;
- int i;
- for (i = 0; i < len; i++)
- {
- entry &e = cpMap[i];
- entry &form = *cp_Signature_form.getRef();
- int nc = 0;
-
- for (const char *ncp = form.utf8String(); *ncp; ncp++)
- {
- if (*ncp == 'L')
- nc++;
- }
-
- ncTotal += nc;
- e.refs = U_NEW(entry *, cpMap[i].nrefs = 1 + nc);
- e.refs[0] = &form;
- }
- // cp_Signature_form.done();
- cp_Signature_classes.setIndexByTag(CONSTANT_Class);
- cp_Signature_classes.readData(ncTotal);
- for (i = 0; i < len; i++)
- {
- entry &e = cpMap[i];
- for (int j = 1; j < e.nrefs; j++)
- {
- e.refs[j] = cp_Signature_classes.getRef();
- }
- }
- // cp_Signature_classes.done();
+ cp_Signature_form.setIndexByTag(CONSTANT_Utf8);
+ cp_Signature_form.readData(len);
+ int ncTotal = 0;
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ entry &e = cpMap[i];
+ entry &form = *cp_Signature_form.getRef();
+ int nc = 0;
+
+ for (const char *ncp = form.utf8String(); *ncp; ncp++)
+ {
+ if (*ncp == 'L')
+ nc++;
+ }
+
+ ncTotal += nc;
+ e.refs = U_NEW(entry *, cpMap[i].nrefs = 1 + nc);
+ e.refs[0] = &form;
+ }
+ // cp_Signature_form.done();
+ cp_Signature_classes.setIndexByTag(CONSTANT_Class);
+ cp_Signature_classes.readData(ncTotal);
+ for (i = 0; i < len; i++)
+ {
+ entry &e = cpMap[i];
+ for (int j = 1; j < e.nrefs; j++)
+ {
+ e.refs[j] = cp_Signature_classes.getRef();
+ }
+ }
+ // cp_Signature_classes.done();
}
// Cf. PackageReader.readConstantPool
void unpacker::read_cp()
{
- int i;
-
- for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++)
- {
- byte tag = TAGS_IN_ORDER[k];
- int len = cp.tag_count[tag];
- int base = cp.tag_base[tag];
-
- entry *cpMap = &cp.entries[base];
- for (i = 0; i < len; i++)
- {
- cpMap[i].tag = tag;
- cpMap[i].inord = i;
- }
-
- switch (tag)
- {
- case CONSTANT_Utf8:
- read_Utf8_values(cpMap, len);
- break;
- case CONSTANT_Integer:
- read_single_words(cp_Int, cpMap, len);
- break;
- case CONSTANT_Float:
- read_single_words(cp_Float, cpMap, len);
- break;
- case CONSTANT_Long:
- read_double_words(cp_Long_hi /*& cp_Long_lo*/, cpMap, len);
- break;
- case CONSTANT_Double:
- read_double_words(cp_Double_hi /*& cp_Double_lo*/, cpMap, len);
- break;
- case CONSTANT_String:
- read_single_refs(cp_String, CONSTANT_Utf8, cpMap, len);
- break;
- case CONSTANT_Class:
- read_single_refs(cp_Class, CONSTANT_Utf8, cpMap, len);
- break;
- case CONSTANT_Signature:
- read_signature_values(cpMap, len);
- break;
- case CONSTANT_NameandType:
- read_double_refs(cp_Descr_name /*& cp_Descr_type*/, CONSTANT_Utf8,
- CONSTANT_Signature, cpMap, len);
- break;
- case CONSTANT_Fieldref:
- read_double_refs(cp_Field_class /*& cp_Field_desc*/, CONSTANT_Class,
- CONSTANT_NameandType, cpMap, len);
- break;
- case CONSTANT_Methodref:
- read_double_refs(cp_Method_class /*& cp_Method_desc*/, CONSTANT_Class,
- CONSTANT_NameandType, cpMap, len);
- break;
- case CONSTANT_InterfaceMethodref:
- read_double_refs(cp_Imethod_class /*& cp_Imethod_desc*/, CONSTANT_Class,
- CONSTANT_NameandType, cpMap, len);
- break;
- default:
- assert(false);
- break;
- }
- }
-
- cp.expandSignatures();
- cp.initMemberIndexes();
+ int i;
+
+ for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++)
+ {
+ byte tag = TAGS_IN_ORDER[k];
+ int len = cp.tag_count[tag];
+ int base = cp.tag_base[tag];
+
+ entry *cpMap = &cp.entries[base];
+ for (i = 0; i < len; i++)
+ {
+ cpMap[i].tag = tag;
+ cpMap[i].inord = i;
+ }
+
+ switch (tag)
+ {
+ case CONSTANT_Utf8:
+ read_Utf8_values(cpMap, len);
+ break;
+ case CONSTANT_Integer:
+ read_single_words(cp_Int, cpMap, len);
+ break;
+ case CONSTANT_Float:
+ read_single_words(cp_Float, cpMap, len);
+ break;
+ case CONSTANT_Long:
+ read_double_words(cp_Long_hi /*& cp_Long_lo*/, cpMap, len);
+ break;
+ case CONSTANT_Double:
+ read_double_words(cp_Double_hi /*& cp_Double_lo*/, cpMap, len);
+ break;
+ case CONSTANT_String:
+ read_single_refs(cp_String, CONSTANT_Utf8, cpMap, len);
+ break;
+ case CONSTANT_Class:
+ read_single_refs(cp_Class, CONSTANT_Utf8, cpMap, len);
+ break;
+ case CONSTANT_Signature:
+ read_signature_values(cpMap, len);
+ break;
+ case CONSTANT_NameandType:
+ read_double_refs(cp_Descr_name /*& cp_Descr_type*/, CONSTANT_Utf8,
+ CONSTANT_Signature, cpMap, len);
+ break;
+ case CONSTANT_Fieldref:
+ read_double_refs(cp_Field_class /*& cp_Field_desc*/, CONSTANT_Class,
+ CONSTANT_NameandType, cpMap, len);
+ break;
+ case CONSTANT_Methodref:
+ read_double_refs(cp_Method_class /*& cp_Method_desc*/, CONSTANT_Class,
+ CONSTANT_NameandType, cpMap, len);
+ break;
+ case CONSTANT_InterfaceMethodref:
+ read_double_refs(cp_Imethod_class /*& cp_Imethod_desc*/, CONSTANT_Class,
+ CONSTANT_NameandType, cpMap, len);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ }
+
+ cp.expandSignatures();
+ cp.initMemberIndexes();
#define SNAME(n, s) #s "\0"
- const char *symNames = (ALL_ATTR_DO(SNAME) "<init>");
+ const char *symNames = (ALL_ATTR_DO(SNAME) "<init>");
#undef SNAME
- for (int sn = 0; sn < constant_pool::s_LIMIT; sn++)
- {
- assert(symNames[0] >= '0' && symNames[0] <= 'Z'); // sanity
- bytes name;
- name.set(symNames);
- if (name.len > 0 && name.ptr[0] != '0')
- {
- cp.sym[sn] = cp.ensureUtf8(name);
- }
- symNames += name.len + 1; // skip trailing nullptr to next name
- }
-
- band::initIndexes(this);
+ for (int sn = 0; sn < constant_pool::s_LIMIT; sn++)
+ {
+ assert(symNames[0] >= '0' && symNames[0] <= 'Z'); // sanity
+ bytes name;
+ name.set(symNames);
+ if (name.len > 0 && name.ptr[0] != '0')
+ {
+ cp.sym[sn] = cp.ensureUtf8(name);
+ }
+ symNames += name.len + 1; // skip trailing nullptr to next name
+ }
+
+ band::initIndexes(this);
}
static band *no_bands[] = {nullptr}; // shared empty body
inline band &unpacker::attr_definitions::fixed_band(int e_class_xxx)
{
- return u->all_bands[xxx_flags_hi_bn + (e_class_xxx - e_class_flags_hi)];
+ return u->all_bands[xxx_flags_hi_bn + (e_class_xxx - e_class_flags_hi)];
}
inline band &unpacker::attr_definitions::xxx_flags_hi()
{
- return fixed_band(e_class_flags_hi);
+ return fixed_band(e_class_flags_hi);
}
inline band &unpacker::attr_definitions::xxx_flags_lo()
{
- return fixed_band(e_class_flags_lo);
+ return fixed_band(e_class_flags_lo);
}
inline band &unpacker::attr_definitions::xxx_attr_count()
{
- return fixed_band(e_class_attr_count);
+ return fixed_band(e_class_attr_count);
}
inline band &unpacker::attr_definitions::xxx_attr_indexes()
{
- return fixed_band(e_class_attr_indexes);
+ return fixed_band(e_class_attr_indexes);
}
inline band &unpacker::attr_definitions::xxx_attr_calls()
{
- return fixed_band(e_class_attr_calls);
+ return fixed_band(e_class_attr_calls);
}
inline unpacker::layout_definition *
unpacker::attr_definitions::defineLayout(int idx, entry *nameEntry, const char *layout)
{
- const char *name = nameEntry->value.b.strval();
- layout_definition *lo = defineLayout(idx, name, layout);
- lo->nameEntry = nameEntry;
- return lo;
+ const char *name = nameEntry->value.b.strval();
+ layout_definition *lo = defineLayout(idx, name, layout);
+ lo->nameEntry = nameEntry;
+ return lo;
}
unpacker::layout_definition *unpacker::attr_definitions::defineLayout(int idx, const char *name,
- const char *layout)
+ const char *layout)
{
- assert(flag_limit != 0); // must be set up already
- if (idx >= 0)
- {
- // Fixed attr.
- if (idx >= (int)flag_limit)
- unpack_abort("attribute index too large");
- if (isRedefined(idx))
- unpack_abort("redefined attribute index");
- redef |= ((uint64_t)1 << idx);
- }
- else
- {
- idx = flag_limit + overflow_count.length();
- overflow_count.add(0); // make a new counter
- }
- layout_definition *lo = U_NEW(layout_definition, 1);
- lo->idx = idx;
- lo->name = name;
- lo->layout = layout;
- for (int adds = (idx + 1) - layouts.length(); adds > 0; adds--)
- {
- layouts.add(nullptr);
- }
- layouts.get(idx) = lo;
- return lo;
+ assert(flag_limit != 0); // must be set up already
+ if (idx >= 0)
+ {
+ // Fixed attr.
+ if (idx >= (int)flag_limit)
+ unpack_abort("attribute index too large");
+ if (isRedefined(idx))
+ unpack_abort("redefined attribute index");
+ redef |= ((uint64_t)1 << idx);
+ }
+ else
+ {
+ idx = flag_limit + overflow_count.length();
+ overflow_count.add(0); // make a new counter
+ }
+ layout_definition *lo = U_NEW(layout_definition, 1);
+ lo->idx = idx;
+ lo->name = name;
+ lo->layout = layout;
+ for (int adds = (idx + 1) - layouts.length(); adds > 0; adds--)
+ {
+ layouts.add(nullptr);
+ }
+ layouts.get(idx) = lo;
+ return lo;
}
band **unpacker::attr_definitions::buildBands(unpacker::layout_definition *lo)
{
- int i;
- if (lo->elems != nullptr)
- return lo->bands();
- if (lo->layout[0] == '\0')
- {
- lo->elems = no_bands;
- }
- else
- {
- // Create bands for this attribute by parsing the layout.
- bool hasCallables = lo->hasCallables();
- bands_made = 0x10000; // base number for bands made
- const char *lp = lo->layout;
- lp = parseLayout(lp, lo->elems, -1);
- if (lp[0] != '\0' || band_stack.length() > 0)
- {
- unpack_abort("garbage at end of layout");
- }
- band_stack.popTo(0);
-
- // Fix up callables to point at their callees.
- band **bands = lo->elems;
- assert(bands == lo->bands());
- int num_callables = 0;
- if (hasCallables)
- {
- while (bands[num_callables] != nullptr)
- {
- if (bands[num_callables]->le_kind != EK_CBLE)
- {
- unpack_abort("garbage mixed with callables");
- break;
- }
- num_callables += 1;
- }
- }
- for (i = 0; i < calls_to_link.length(); i++)
- {
- band &call = *(band *)calls_to_link.get(i);
- assert(call.le_kind == EK_CALL);
- // Determine the callee.
- int call_num = call.le_len;
- if (call_num < 0 || call_num >= num_callables)
- {
- unpack_abort("bad call in layout");
- break;
- }
- band &cble = *bands[call_num];
- // Link the call to it.
- call.le_body[0] = &cble;
- // Distinguish backward calls and callables:
- assert(cble.le_kind == EK_CBLE);
- // FIXME: hit this one
- // assert(cble.le_len == call_num);
- cble.le_back |= call.le_back;
- }
- calls_to_link.popTo(0);
- }
- return lo->elems;
+ int i;
+ if (lo->elems != nullptr)
+ return lo->bands();
+ if (lo->layout[0] == '\0')
+ {
+ lo->elems = no_bands;
+ }
+ else
+ {
+ // Create bands for this attribute by parsing the layout.
+ bool hasCallables = lo->hasCallables();
+ bands_made = 0x10000; // base number for bands made
+ const char *lp = lo->layout;
+ lp = parseLayout(lp, lo->elems, -1);
+ if (lp[0] != '\0' || band_stack.length() > 0)
+ {
+ unpack_abort("garbage at end of layout");
+ }
+ band_stack.popTo(0);
+
+ // Fix up callables to point at their callees.
+ band **bands = lo->elems;
+ assert(bands == lo->bands());
+ int num_callables = 0;
+ if (hasCallables)
+ {
+ while (bands[num_callables] != nullptr)
+ {
+ if (bands[num_callables]->le_kind != EK_CBLE)
+ {
+ unpack_abort("garbage mixed with callables");
+ break;
+ }
+ num_callables += 1;
+ }
+ }
+ for (i = 0; i < calls_to_link.length(); i++)
+ {
+ band &call = *(band *)calls_to_link.get(i);
+ assert(call.le_kind == EK_CALL);
+ // Determine the callee.
+ int call_num = call.le_len;
+ if (call_num < 0 || call_num >= num_callables)
+ {
+ unpack_abort("bad call in layout");
+ break;
+ }
+ band &cble = *bands[call_num];
+ // Link the call to it.
+ call.le_body[0] = &cble;
+ // Distinguish backward calls and callables:
+ assert(cble.le_kind == EK_CBLE);
+ // FIXME: hit this one
+ // assert(cble.le_len == call_num);
+ cble.le_back |= call.le_back;
+ }
+ calls_to_link.popTo(0);
+ }
+ return lo->elems;
}
/* attribute layout language parser
attribute_layout:
- ( layout_element )* | ( callable )+
+ ( layout_element )* | ( callable )+
layout_element:
- ( integral | replication | union | call | reference )
+ ( integral | replication | union | call | reference )
callable:
- '[' body ']'
+ '[' body ']'
body:
- ( layout_element )+
+ ( layout_element )+
integral:
- ( unsigned_int | signed_int | bc_index | bc_offset | flag )
+ ( unsigned_int | signed_int | bc_index | bc_offset | flag )
unsigned_int:
- uint_type
+ uint_type
signed_int:
- 'S' uint_type
+ 'S' uint_type
any_int:
- ( unsigned_int | signed_int )
+ ( unsigned_int | signed_int )
bc_index:
- ( 'P' uint_type | 'PO' uint_type )
+ ( 'P' uint_type | 'PO' uint_type )
bc_offset:
- 'O' any_int
+ 'O' any_int
flag:
- 'F' uint_type
+ 'F' uint_type
uint_type:
- ( 'B' | 'H' | 'I' | 'V' )
+ ( 'B' | 'H' | 'I' | 'V' )
replication:
- 'N' uint_type '[' body ']'
+ 'N' uint_type '[' body ']'
union:
- 'T' any_int (union_case)* '(' ')' '[' (body)? ']'
+ 'T' any_int (union_case)* '(' ')' '[' (body)? ']'
union_case:
- '(' union_case_tag (',' union_case_tag)* ')' '[' (body)? ']'
+ '(' union_case_tag (',' union_case_tag)* ')' '[' (body)? ']'
union_case_tag:
- ( numeral | numeral '-' numeral )
+ ( numeral | numeral '-' numeral )
call:
- '(' numeral ')'
+ '(' numeral ')'
reference:
- reference_type ( 'N' )? uint_type
+ reference_type ( 'N' )? uint_type
reference_type:
- ( constant_ref | schema_ref | utf8_ref | untyped_ref )
+ ( constant_ref | schema_ref | utf8_ref | untyped_ref )
constant_ref:
- ( 'KI' | 'KJ' | 'KF' | 'KD' | 'KS' | 'KQ' )
+ ( 'KI' | 'KJ' | 'KF' | 'KD' | 'KS' | 'KQ' )
schema_ref:
- ( 'RC' | 'RS' | 'RD' | 'RF' | 'RM' | 'RI' )
+ ( 'RC' | 'RS' | 'RD' | 'RF' | 'RM' | 'RI' )
utf8_ref:
- 'RU'
+ 'RU'
untyped_ref:
- 'RQ'
+ 'RQ'
numeral:
- '(' ('-')? (digit)+ ')'
+ '(' ('-')? (digit)+ ')'
digit:
- ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
+ ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
*/
const char *unpacker::attr_definitions::parseIntLayout(const char *lp, band *&res, byte le_kind,
- bool can_be_signed)
+ bool can_be_signed)
{
- band *b = U_NEW(band, 1);
- char le = *lp++;
- int spec = UNSIGNED5_spec;
- if (le == 'S' && can_be_signed)
- {
- // Note: This is the last use of sign. There is no 'EF_SIGN'.
- spec = SIGNED5_spec;
- le = *lp++;
- }
- else if (le == 'B')
- {
- spec = BYTE1_spec; // unsigned byte
- }
- b->init(u, bands_made++, spec);
- b->le_kind = le_kind;
- int le_len = 0;
- switch (le)
- {
- case 'B':
- le_len = 1;
- break;
- case 'H':
- le_len = 2;
- break;
- case 'I':
- le_len = 4;
- break;
- case 'V':
- le_len = 0;
- break;
- default:
- unpack_abort("bad layout element");
- }
- b->le_len = le_len;
- band_stack.add(b);
- res = b;
- return lp;
+ band *b = U_NEW(band, 1);
+ char le = *lp++;
+ int spec = UNSIGNED5_spec;
+ if (le == 'S' && can_be_signed)
+ {
+ // Note: This is the last use of sign. There is no 'EF_SIGN'.
+ spec = SIGNED5_spec;
+ le = *lp++;
+ }
+ else if (le == 'B')
+ {
+ spec = BYTE1_spec; // unsigned byte
+ }
+ b->init(u, bands_made++, spec);
+ b->le_kind = le_kind;
+ int le_len = 0;
+ switch (le)
+ {
+ case 'B':
+ le_len = 1;
+ break;
+ case 'H':
+ le_len = 2;
+ break;
+ case 'I':
+ le_len = 4;
+ break;
+ case 'V':
+ le_len = 0;
+ break;
+ default:
+ unpack_abort("bad layout element");
+ }
+ b->le_len = le_len;
+ band_stack.add(b);
+ res = b;
+ return lp;
}
const char *unpacker::attr_definitions::parseNumeral(const char *lp, int &res)
{
- bool sgn = false;
- if (*lp == '0')
- {
- res = 0;
- return lp + 1;
- } // special case '0'
- if (*lp == '-')
- {
- sgn = true;
- lp++;
- }
- const char *dp = lp;
- int con = 0;
- while (*dp >= '0' && *dp <= '9')
- {
- int con0 = con;
- con *= 10;
- con += (*dp++) - '0';
- if (con <= con0)
- {
- con = -1;
- break;
- } // numeral overflow
- }
- if (lp == dp)
- {
- unpack_abort("missing numeral in layout");
- }
- lp = dp;
- if (con < 0 && !(sgn && con == -con))
- {
- // (Portability note: Misses the error if int is not 32 bits.)
- unpack_abort("numeral overflow");
- }
- if (sgn)
- con = -con;
- res = con;
- return lp;
+ bool sgn = false;
+ if (*lp == '0')
+ {
+ res = 0;
+ return lp + 1;
+ } // special case '0'
+ if (*lp == '-')
+ {
+ sgn = true;
+ lp++;
+ }
+ const char *dp = lp;
+ int con = 0;
+ while (*dp >= '0' && *dp <= '9')
+ {
+ int con0 = con;
+ con *= 10;
+ con += (*dp++) - '0';
+ if (con <= con0)
+ {
+ con = -1;
+ break;
+ } // numeral overflow
+ }
+ if (lp == dp)
+ {
+ unpack_abort("missing numeral in layout");
+ }
+ lp = dp;
+ if (con < 0 && !(sgn && con == -con))
+ {
+ // (Portability note: Misses the error if int is not 32 bits.)
+ unpack_abort("numeral overflow");
+ }
+ if (sgn)
+ con = -con;
+ res = con;
+ return lp;
}
band **unpacker::attr_definitions::popBody(int bs_base)
{
- // Return everything that was pushed, as a nullptr-terminated pointer array.
- int bs_limit = band_stack.length();
- if (bs_base == bs_limit)
- {
- return no_bands;
- }
- else
- {
- int nb = bs_limit - bs_base;
- band **res = U_NEW(band *, add_size(nb, 1));
- for (int i = 0; i < nb; i++)
- {
- band *b = (band *)band_stack.get(bs_base + i);
- res[i] = b;
- }
- band_stack.popTo(bs_base);
- return res;
- }
+ // Return everything that was pushed, as a nullptr-terminated pointer array.
+ int bs_limit = band_stack.length();
+ if (bs_base == bs_limit)
+ {
+ return no_bands;
+ }
+ else
+ {
+ int nb = bs_limit - bs_base;
+ band **res = U_NEW(band *, add_size(nb, 1));
+ for (int i = 0; i < nb; i++)
+ {
+ band *b = (band *)band_stack.get(bs_base + i);
+ res[i] = b;
+ }
+ band_stack.popTo(bs_base);
+ return res;
+ }
}
const char *unpacker::attr_definitions::parseLayout(const char *lp, band **&res, int curCble)
{
- int bs_base = band_stack.length();
- bool top_level = (bs_base == 0);
- band *b;
- enum
- {
- can_be_signed = true
- }; // optional arg to parseIntLayout
-
- for (bool done = false; !done;)
- {
- switch (*lp++)
- {
- case 'B':
- case 'H':
- case 'I':
- case 'V': // unsigned_int
- case 'S': // signed_int
- --lp; // reparse
- case 'F':
- lp = parseIntLayout(lp, b, EK_INT);
- break;
- case 'P':
- {
- int le_bci = EK_BCI;
- if (*lp == 'O')
- {
- ++lp;
- le_bci = EK_BCID;
- }
- assert(*lp != 'S'); // no PSH, etc.
- lp = parseIntLayout(lp, b, EK_INT);
- b->le_bci = le_bci;
- if (le_bci == EK_BCI)
- b->defc = coding::findBySpec(BCI5_spec);
- else
- b->defc = coding::findBySpec(BRANCH5_spec);
- }
- break;
- case 'O':
- lp = parseIntLayout(lp, b, EK_INT, can_be_signed);
- b->le_bci = EK_BCO;
- b->defc = coding::findBySpec(BRANCH5_spec);
- break;
- case 'N': // replication: 'N' uint32_t '[' elem ... ']'
- lp = parseIntLayout(lp, b, EK_REPL);
- assert(*lp == '[');
- ++lp;
- lp = parseLayout(lp, b->le_body, curCble);
- break;
- case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']'
- lp = parseIntLayout(lp, b, EK_UN, can_be_signed);
- {
- int union_base = band_stack.length();
- for (;;)
- { // for each case
- band &k_case = *U_NEW(band, 1);
- band_stack.add(&k_case);
- k_case.le_kind = EK_CASE;
- k_case.bn = bands_made++;
- if (*lp++ != '(')
- {
- unpack_abort("bad union case");
- return "";
- }
- if (*lp++ != ')')
- {
- --lp; // reparse
- // Read some case values. (Use band_stack for temp. storage.)
- int case_base = band_stack.length();
- for (;;)
- {
- int caseval = 0;
- lp = parseNumeral(lp, caseval);
- band_stack.add((void *)(size_t)caseval);
- if (*lp == '-')
- {
- // new in version 160, allow (1-5) for (1,2,3,4,5)
- if (u->majver < JAVA6_PACKAGE_MAJOR_VERSION)
- {
- unpack_abort(
- "bad range in union case label (old archive format)");
- return "";
- }
- int caselimit = caseval;
- lp++;
- lp = parseNumeral(lp, caselimit);
- if (caseval >= caselimit ||
- (uint32_t)(caselimit - caseval) > 0x10000)
- {
- // Note: 0x10000 is arbitrary implementation restriction.
- // We can remove it later if it's important to.
- unpack_abort("bad range in union case label");
- }
- for (;;)
- {
- ++caseval;
- band_stack.add((void *)(size_t)caseval);
- if (caseval == caselimit)
- break;
- }
- }
- if (*lp != ',')
- break;
- lp++;
- }
- if (*lp++ != ')')
- {
- unpack_abort("bad case label");
- }
- // save away the case labels
- int ntags = band_stack.length() - case_base;
- int *tags = U_NEW(int, add_size(ntags, 1));
- k_case.le_casetags = tags;
- *tags++ = ntags;
- for (int i = 0; i < ntags; i++)
- {
- *tags++ = ptrlowbits(band_stack.get(case_base + i));
- }
- band_stack.popTo(case_base);
- }
- // Got le_casetags. Now grab the body.
- assert(*lp == '[');
- ++lp;
- lp = parseLayout(lp, k_case.le_body, curCble);
- if (k_case.le_casetags == nullptr)
- break; // done
- }
- b->le_body = popBody(union_base);
- }
- break;
- case '(': // call: '(' -?NN* ')'
- {
- band &call = *U_NEW(band, 1);
- band_stack.add(&call);
- call.le_kind = EK_CALL;
- call.bn = bands_made++;
- call.le_body = U_NEW(band *, 2); // fill in later
- int call_num = 0;
- lp = parseNumeral(lp, call_num);
- call.le_back = (call_num <= 0);
- call_num += curCble; // numeral is self-relative offset
- call.le_len = call_num; // use le_len as scratch
- calls_to_link.add(&call);
- if (*lp++ != ')')
- {
- unpack_abort("bad call label");
- }
- }
- break;
- case 'K': // reference_type: constant_ref
- case 'R': // reference_type: schema_ref
- {
- int ixTag = CONSTANT_None;
- if (lp[-1] == 'K')
- {
- switch (*lp++)
- {
- case 'I':
- ixTag = CONSTANT_Integer;
- break;
- case 'J':
- ixTag = CONSTANT_Long;
- break;
- case 'F':
- ixTag = CONSTANT_Float;
- break;
- case 'D':
- ixTag = CONSTANT_Double;
- break;
- case 'S':
- ixTag = CONSTANT_String;
- break;
- case 'Q':
- ixTag = CONSTANT_Literal;
- break;
- }
- }
- else
- {
- switch (*lp++)
- {
- case 'C':
- ixTag = CONSTANT_Class;
- break;
- case 'S':
- ixTag = CONSTANT_Signature;
- break;
- case 'D':
- ixTag = CONSTANT_NameandType;
- break;
- case 'F':
- ixTag = CONSTANT_Fieldref;
- break;
- case 'M':
- ixTag = CONSTANT_Methodref;
- break;
- case 'I':
- ixTag = CONSTANT_InterfaceMethodref;
- break;
- case 'U':
- ixTag = CONSTANT_Utf8;
- break; // utf8_ref
- case 'Q':
- ixTag = CONSTANT_All;
- break; // untyped_ref
- }
- }
- if (ixTag == CONSTANT_None)
- {
- unpack_abort("bad reference layout");
- break;
- }
- bool nullOK = false;
- if (*lp == 'N')
- {
- nullOK = true;
- lp++;
- }
- lp = parseIntLayout(lp, b, EK_REF);
- b->defc = coding::findBySpec(UNSIGNED5_spec);
- b->initRef(ixTag, nullOK);
- }
- break;
- case '[':
- {
- // [callable1][callable2]...
- if (!top_level)
- {
- unpack_abort("bad nested callable");
- break;
- }
- curCble += 1;
- band &cble = *U_NEW(band, 1);
- band_stack.add(&cble);
- cble.le_kind = EK_CBLE;
- cble.bn = bands_made++;
- lp = parseLayout(lp, cble.le_body, curCble);
- }
- break;
- case ']':
- // Hit a closing brace. This ends whatever body we were in.
- done = true;
- break;
- case '\0':
- // Hit a nullptr. Also ends the (top-level) body.
- --lp; // back up, so caller can see the nullptr also
- done = true;
- break;
- default:
- unpack_abort("bad layout");
- }
- }
-
- // Return the accumulated bands:
- res = popBody(bs_base);
- return lp;
+ int bs_base = band_stack.length();
+ bool top_level = (bs_base == 0);
+ band *b;
+ enum
+ {
+ can_be_signed = true
+ }; // optional arg to parseIntLayout
+
+ for (bool done = false; !done;)
+ {
+ switch (*lp++)
+ {
+ case 'B':
+ case 'H':
+ case 'I':
+ case 'V': // unsigned_int
+ case 'S': // signed_int
+ --lp; // reparse
+ case 'F':
+ lp = parseIntLayout(lp, b, EK_INT);
+ break;
+ case 'P':
+ {
+ int le_bci = EK_BCI;
+ if (*lp == 'O')
+ {
+ ++lp;
+ le_bci = EK_BCID;
+ }
+ assert(*lp != 'S'); // no PSH, etc.
+ lp = parseIntLayout(lp, b, EK_INT);
+ b->le_bci = le_bci;
+ if (le_bci == EK_BCI)
+ b->defc = coding::findBySpec(BCI5_spec);
+ else
+ b->defc = coding::findBySpec(BRANCH5_spec);
+ }
+ break;
+ case 'O':
+ lp = parseIntLayout(lp, b, EK_INT, can_be_signed);
+ b->le_bci = EK_BCO;
+ b->defc = coding::findBySpec(BRANCH5_spec);
+ break;
+ case 'N': // replication: 'N' uint32_t '[' elem ... ']'
+ lp = parseIntLayout(lp, b, EK_REPL);
+ assert(*lp == '[');
+ ++lp;
+ lp = parseLayout(lp, b->le_body, curCble);
+ break;
+ case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']'
+ lp = parseIntLayout(lp, b, EK_UN, can_be_signed);
+ {
+ int union_base = band_stack.length();
+ for (;;)
+ { // for each case
+ band &k_case = *U_NEW(band, 1);
+ band_stack.add(&k_case);
+ k_case.le_kind = EK_CASE;
+ k_case.bn = bands_made++;
+ if (*lp++ != '(')
+ {
+ unpack_abort("bad union case");
+ return "";
+ }
+ if (*lp++ != ')')
+ {
+ --lp; // reparse
+ // Read some case values. (Use band_stack for temp. storage.)
+ int case_base = band_stack.length();
+ for (;;)
+ {
+ int caseval = 0;
+ lp = parseNumeral(lp, caseval);
+ band_stack.add((void *)(size_t)caseval);
+ if (*lp == '-')
+ {
+ // new in version 160, allow (1-5) for (1,2,3,4,5)
+ if (u->majver < JAVA6_PACKAGE_MAJOR_VERSION)
+ {
+ unpack_abort(
+ "bad range in union case label (old archive format)");
+ return "";
+ }
+ int caselimit = caseval;
+ lp++;
+ lp = parseNumeral(lp, caselimit);
+ if (caseval >= caselimit ||
+ (uint32_t)(caselimit - caseval) > 0x10000)
+ {
+ // Note: 0x10000 is arbitrary implementation restriction.
+ // We can remove it later if it's important to.
+ unpack_abort("bad range in union case label");
+ }
+ for (;;)
+ {
+ ++caseval;
+ band_stack.add((void *)(size_t)caseval);
+ if (caseval == caselimit)
+ break;
+ }
+ }
+ if (*lp != ',')
+ break;
+ lp++;
+ }
+ if (*lp++ != ')')
+ {
+ unpack_abort("bad case label");
+ }
+ // save away the case labels
+ int ntags = band_stack.length() - case_base;
+ int *tags = U_NEW(int, add_size(ntags, 1));
+ k_case.le_casetags = tags;
+ *tags++ = ntags;
+ for (int i = 0; i < ntags; i++)
+ {
+ *tags++ = ptrlowbits(band_stack.get(case_base + i));
+ }
+ band_stack.popTo(case_base);
+ }
+ // Got le_casetags. Now grab the body.
+ assert(*lp == '[');
+ ++lp;
+ lp = parseLayout(lp, k_case.le_body, curCble);
+ if (k_case.le_casetags == nullptr)
+ break; // done
+ }
+ b->le_body = popBody(union_base);
+ }
+ break;
+ case '(': // call: '(' -?NN* ')'
+ {
+ band &call = *U_NEW(band, 1);
+ band_stack.add(&call);
+ call.le_kind = EK_CALL;
+ call.bn = bands_made++;
+ call.le_body = U_NEW(band *, 2); // fill in later
+ int call_num = 0;
+ lp = parseNumeral(lp, call_num);
+ call.le_back = (call_num <= 0);
+ call_num += curCble; // numeral is self-relative offset
+ call.le_len = call_num; // use le_len as scratch
+ calls_to_link.add(&call);
+ if (*lp++ != ')')
+ {
+ unpack_abort("bad call label");
+ }
+ }
+ break;
+ case 'K': // reference_type: constant_ref
+ case 'R': // reference_type: schema_ref
+ {
+ int ixTag = CONSTANT_None;
+ if (lp[-1] == 'K')
+ {
+ switch (*lp++)
+ {
+ case 'I':
+ ixTag = CONSTANT_Integer;
+ break;
+ case 'J':
+ ixTag = CONSTANT_Long;
+ break;
+ case 'F':
+ ixTag = CONSTANT_Float;
+ break;
+ case 'D':
+ ixTag = CONSTANT_Double;
+ break;
+ case 'S':
+ ixTag = CONSTANT_String;
+ break;
+ case 'Q':
+ ixTag = CONSTANT_Literal;
+ break;
+ }
+ }
+ else
+ {
+ switch (*lp++)
+ {
+ case 'C':
+ ixTag = CONSTANT_Class;
+ break;
+ case 'S':
+ ixTag = CONSTANT_Signature;
+ break;
+ case 'D':
+ ixTag = CONSTANT_NameandType;
+ break;
+ case 'F':
+ ixTag = CONSTANT_Fieldref;
+ break;
+ case 'M':
+ ixTag = CONSTANT_Methodref;
+ break;
+ case 'I':
+ ixTag = CONSTANT_InterfaceMethodref;
+ break;
+ case 'U':
+ ixTag = CONSTANT_Utf8;
+ break; // utf8_ref
+ case 'Q':
+ ixTag = CONSTANT_All;
+ break; // untyped_ref
+ }
+ }
+ if (ixTag == CONSTANT_None)
+ {
+ unpack_abort("bad reference layout");
+ break;
+ }
+ bool nullOK = false;
+ if (*lp == 'N')
+ {
+ nullOK = true;
+ lp++;
+ }
+ lp = parseIntLayout(lp, b, EK_REF);
+ b->defc = coding::findBySpec(UNSIGNED5_spec);
+ b->initRef(ixTag, nullOK);
+ }
+ break;
+ case '[':
+ {
+ // [callable1][callable2]...
+ if (!top_level)
+ {
+ unpack_abort("bad nested callable");
+ break;
+ }
+ curCble += 1;
+ band &cble = *U_NEW(band, 1);
+ band_stack.add(&cble);
+ cble.le_kind = EK_CBLE;
+ cble.bn = bands_made++;
+ lp = parseLayout(lp, cble.le_body, curCble);
+ }
+ break;
+ case ']':
+ // Hit a closing brace. This ends whatever body we were in.
+ done = true;
+ break;
+ case '\0':
+ // Hit a nullptr. Also ends the (top-level) body.
+ --lp; // back up, so caller can see the nullptr also
+ done = true;
+ break;
+ default:
+ unpack_abort("bad layout");
+ }
+ }
+
+ // Return the accumulated bands:
+ res = popBody(bs_base);
+ return lp;
}
void unpacker::read_attr_defs()
{
- int i;
-
- // Tell each AD which attrc it is and where its fixed flags are:
- attr_defs[ATTR_CONTEXT_CLASS].attrc = ATTR_CONTEXT_CLASS;
- attr_defs[ATTR_CONTEXT_CLASS].xxx_flags_hi_bn = e_class_flags_hi;
- attr_defs[ATTR_CONTEXT_FIELD].attrc = ATTR_CONTEXT_FIELD;
- attr_defs[ATTR_CONTEXT_FIELD].xxx_flags_hi_bn = e_field_flags_hi;
- attr_defs[ATTR_CONTEXT_METHOD].attrc = ATTR_CONTEXT_METHOD;
- attr_defs[ATTR_CONTEXT_METHOD].xxx_flags_hi_bn = e_method_flags_hi;
- attr_defs[ATTR_CONTEXT_CODE].attrc = ATTR_CONTEXT_CODE;
- attr_defs[ATTR_CONTEXT_CODE].xxx_flags_hi_bn = e_code_flags_hi;
-
- // Decide whether bands for the optional high flag words are present.
- attr_defs[ATTR_CONTEXT_CLASS]
- .setHaveLongFlags((archive_options & AO_HAVE_CLASS_FLAGS_HI) != 0);
- attr_defs[ATTR_CONTEXT_FIELD]
- .setHaveLongFlags((archive_options & AO_HAVE_FIELD_FLAGS_HI) != 0);
- attr_defs[ATTR_CONTEXT_METHOD]
- .setHaveLongFlags((archive_options & AO_HAVE_METHOD_FLAGS_HI) != 0);
- attr_defs[ATTR_CONTEXT_CODE]
- .setHaveLongFlags((archive_options & AO_HAVE_CODE_FLAGS_HI) != 0);
-
- // Set up built-in attrs.
- // (The simple ones are hard-coded. The metadata layouts are not.)
- const char *md_layout = (
+ int i;
+
+ // Tell each AD which attrc it is and where its fixed flags are:
+ attr_defs[ATTR_CONTEXT_CLASS].attrc = ATTR_CONTEXT_CLASS;
+ attr_defs[ATTR_CONTEXT_CLASS].xxx_flags_hi_bn = e_class_flags_hi;
+ attr_defs[ATTR_CONTEXT_FIELD].attrc = ATTR_CONTEXT_FIELD;
+ attr_defs[ATTR_CONTEXT_FIELD].xxx_flags_hi_bn = e_field_flags_hi;
+ attr_defs[ATTR_CONTEXT_METHOD].attrc = ATTR_CONTEXT_METHOD;
+ attr_defs[ATTR_CONTEXT_METHOD].xxx_flags_hi_bn = e_method_flags_hi;
+ attr_defs[ATTR_CONTEXT_CODE].attrc = ATTR_CONTEXT_CODE;
+ attr_defs[ATTR_CONTEXT_CODE].xxx_flags_hi_bn = e_code_flags_hi;
+
+ // Decide whether bands for the optional high flag words are present.
+ attr_defs[ATTR_CONTEXT_CLASS]
+ .setHaveLongFlags((archive_options & AO_HAVE_CLASS_FLAGS_HI) != 0);
+ attr_defs[ATTR_CONTEXT_FIELD]
+ .setHaveLongFlags((archive_options & AO_HAVE_FIELD_FLAGS_HI) != 0);
+ attr_defs[ATTR_CONTEXT_METHOD]
+ .setHaveLongFlags((archive_options & AO_HAVE_METHOD_FLAGS_HI) != 0);
+ attr_defs[ATTR_CONTEXT_CODE]
+ .setHaveLongFlags((archive_options & AO_HAVE_CODE_FLAGS_HI) != 0);
+
+ // Set up built-in attrs.
+ // (The simple ones are hard-coded. The metadata layouts are not.)
+ const char *md_layout = (
// parameter annotations:
#define MDL0 "[NB[(1)]]"
- MDL0
+ MDL0
// annotations:
#define MDL1 \
- "[NH[(1)]]" \
- "[RSHNH[RUH(1)]]"
- MDL1
- // member_value:
- "[TB"
- "(66,67,73,83,90)[KIH]"
- "(68)[KDH]"
- "(70)[KFH]"
- "(74)[KJH]"
- "(99)[RSH]"
- "(101)[RSHRUH]"
- "(115)[RUH]"
- "(91)[NH[(0)]]"
- "(64)["
- // nested annotation:
- "RSH"
- "NH[RUH(0)]"
- "]"
- "()[]"
- "]");
-
- const char *md_layout_P = md_layout;
- const char *md_layout_A = md_layout + strlen(MDL0);
- const char *md_layout_V = md_layout + strlen(MDL0 MDL1);
- assert(0 == strncmp(&md_layout_A[-3], ")]][", 4));
- assert(0 == strncmp(&md_layout_V[-3], ")]][", 4));
-
- for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
- {
- attr_definitions &ad = attr_defs[i];
- ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations, "RuntimeVisibleAnnotations",
- md_layout_A);
- ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations, "RuntimeInvisibleAnnotations",
- md_layout_A);
- if (i != ATTR_CONTEXT_METHOD)
- continue;
- ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
- "RuntimeVisibleParameterAnnotations", md_layout_P);
- ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
- "RuntimeInvisibleParameterAnnotations", md_layout_P);
- ad.defineLayout(METHOD_ATTR_AnnotationDefault, "AnnotationDefault", md_layout_V);
- }
-
- attr_definition_headers.readData(attr_definition_count);
- attr_definition_name.readData(attr_definition_count);
- attr_definition_layout.readData(attr_definition_count);
+ "[NH[(1)]]" \
+ "[RSHNH[RUH(1)]]"
+ MDL1
+ // member_value:
+ "[TB"
+ "(66,67,73,83,90)[KIH]"
+ "(68)[KDH]"
+ "(70)[KFH]"
+ "(74)[KJH]"
+ "(99)[RSH]"
+ "(101)[RSHRUH]"
+ "(115)[RUH]"
+ "(91)[NH[(0)]]"
+ "(64)["
+ // nested annotation:
+ "RSH"
+ "NH[RUH(0)]"
+ "]"
+ "()[]"
+ "]");
+
+ const char *md_layout_P = md_layout;
+ const char *md_layout_A = md_layout + strlen(MDL0);
+ const char *md_layout_V = md_layout + strlen(MDL0 MDL1);
+ assert(0 == strncmp(&md_layout_A[-3], ")]][", 4));
+ assert(0 == strncmp(&md_layout_V[-3], ")]][", 4));
+
+ for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
+ {
+ attr_definitions &ad = attr_defs[i];
+ ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations, "RuntimeVisibleAnnotations",
+ md_layout_A);
+ ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations, "RuntimeInvisibleAnnotations",
+ md_layout_A);
+ if (i != ATTR_CONTEXT_METHOD)
+ continue;
+ ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
+ "RuntimeVisibleParameterAnnotations", md_layout_P);
+ ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
+ "RuntimeInvisibleParameterAnnotations", md_layout_P);
+ ad.defineLayout(METHOD_ATTR_AnnotationDefault, "AnnotationDefault", md_layout_V);
+ }
+
+ attr_definition_headers.readData(attr_definition_count);
+ attr_definition_name.readData(attr_definition_count);
+ attr_definition_layout.readData(attr_definition_count);
// Initialize correct predef bits, to distinguish predefs from new defs.
#define ORBIT(n, s) | ((uint64_t)1 << n)
- attr_defs[ATTR_CONTEXT_CLASS].predef = (0 X_ATTR_DO(ORBIT) CLASS_ATTR_DO(ORBIT));
- attr_defs[ATTR_CONTEXT_FIELD].predef = (0 X_ATTR_DO(ORBIT) FIELD_ATTR_DO(ORBIT));
- attr_defs[ATTR_CONTEXT_METHOD].predef = (0 X_ATTR_DO(ORBIT) METHOD_ATTR_DO(ORBIT));
- attr_defs[ATTR_CONTEXT_CODE].predef = (0 O_ATTR_DO(ORBIT) CODE_ATTR_DO(ORBIT));
+ attr_defs[ATTR_CONTEXT_CLASS].predef = (0 X_ATTR_DO(ORBIT) CLASS_ATTR_DO(ORBIT));
+ attr_defs[ATTR_CONTEXT_FIELD].predef = (0 X_ATTR_DO(ORBIT) FIELD_ATTR_DO(ORBIT));
+ attr_defs[ATTR_CONTEXT_METHOD].predef = (0 X_ATTR_DO(ORBIT) METHOD_ATTR_DO(ORBIT));
+ attr_defs[ATTR_CONTEXT_CODE].predef = (0 O_ATTR_DO(ORBIT) CODE_ATTR_DO(ORBIT));
#undef ORBIT
- // Clear out the redef bits, folding them back into predef.
- for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
- {
- attr_defs[i].predef |= attr_defs[i].redef;
- attr_defs[i].redef = 0;
- }
-
- // Now read the transmitted locally defined attrs.
- // This will set redef bits again.
- for (i = 0; i < attr_definition_count; i++)
- {
- int header = attr_definition_headers.getByte();
- int attrc = ADH_BYTE_CONTEXT(header);
- int idx = ADH_BYTE_INDEX(header);
- entry *name = attr_definition_name.getRef();
- entry *layout = attr_definition_layout.getRef();
- attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval());
- }
+ // Clear out the redef bits, folding them back into predef.
+ for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
+ {
+ attr_defs[i].predef |= attr_defs[i].redef;
+ attr_defs[i].redef = 0;
+ }
+
+ // Now read the transmitted locally defined attrs.
+ // This will set redef bits again.
+ for (i = 0; i < attr_definition_count; i++)
+ {
+ int header = attr_definition_headers.getByte();
+ int attrc = ADH_BYTE_CONTEXT(header);
+ int idx = ADH_BYTE_INDEX(header);
+ entry *name = attr_definition_name.getRef();
+ entry *layout = attr_definition_layout.getRef();
+ attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval());
+ }
}
#define NO_ENTRY_YET ((entry *)-1)
static bool isDigitString(bytes &x, int beg, int end)
{
- if (beg == end)
- return false; // nullptr string
- byte *xptr = x.ptr;
- for (int i = beg; i < end; i++)
- {
- char ch = xptr[i];
- if (!(ch >= '0' && ch <= '9'))
- return false;
- }
- return true;
+ if (beg == end)
+ return false; // nullptr string
+ byte *xptr = x.ptr;
+ for (int i = beg; i < end; i++)
+ {
+ char ch = xptr[i];
+ if (!(ch >= '0' && ch <= '9'))
+ return false;
+ }
+ return true;
}
enum
{ // constants for parsing class names
- SLASH_MIN = '.',
- SLASH_MAX = '/',
- DOLLAR_MIN = 0,
- DOLLAR_MAX = '-'};
+ SLASH_MIN = '.',
+ SLASH_MAX = '/',
+ DOLLAR_MIN = 0,
+ DOLLAR_MAX = '-'};
static int lastIndexOf(int chmin, int chmax, bytes &x, int pos)
{
- byte *ptr = x.ptr;
- for (byte *cp = ptr + pos; --cp >= ptr;)
- {
- assert(x.inBounds(cp));
- if (*cp >= chmin && *cp <= chmax)
- return (int)(cp - ptr);
- }
- return -1;
+ byte *ptr = x.ptr;
+ for (byte *cp = ptr + pos; --cp >= ptr;)
+ {
+ assert(x.inBounds(cp));
+ if (*cp >= chmin && *cp <= chmax)
+ return (int)(cp - ptr);
+ }
+ return -1;
}
inner_class *constant_pool::getIC(entry *inner)
{
- if (inner == nullptr)
- return nullptr;
- assert(inner->tag == CONSTANT_Class);
- if (inner->inord == NO_INORD)
- return nullptr;
- inner_class *ic = ic_index[inner->inord];
- assert(ic == nullptr || ic->inner == inner);
- return ic;
+ if (inner == nullptr)
+ return nullptr;
+ assert(inner->tag == CONSTANT_Class);
+ if (inner->inord == NO_INORD)
+ return nullptr;
+ inner_class *ic = ic_index[inner->inord];
+ assert(ic == nullptr || ic->inner == inner);
+ return ic;
}
inner_class *constant_pool::getFirstChildIC(entry *outer)
{
- if (outer == nullptr)
- return nullptr;
- assert(outer->tag == CONSTANT_Class);
- if (outer->inord == NO_INORD)
- return nullptr;
- inner_class *ic = ic_child_index[outer->inord];
- assert(ic == nullptr || ic->outer == outer);
- return ic;
+ if (outer == nullptr)
+ return nullptr;
+ assert(outer->tag == CONSTANT_Class);
+ if (outer->inord == NO_INORD)
+ return nullptr;
+ inner_class *ic = ic_child_index[outer->inord];
+ assert(ic == nullptr || ic->outer == outer);
+ return ic;
}
inner_class *constant_pool::getNextChildIC(inner_class *child)
{
- inner_class *ic = child->next_sibling;
- assert(ic == nullptr || ic->outer == child->outer);
- return ic;
+ inner_class *ic = child->next_sibling;
+ assert(ic == nullptr || ic->outer == child->outer);
+ return ic;
}
void unpacker::read_ics()
{
- int i;
- int index_size = cp.tag_count[CONSTANT_Class];
- inner_class **ic_index = U_NEW(inner_class *, index_size);
- inner_class **ic_child_index = U_NEW(inner_class *, index_size);
- cp.ic_index = ic_index;
- cp.ic_child_index = ic_child_index;
- ics = U_NEW(inner_class, ic_count);
- ic_this_class.readData(ic_count);
- ic_flags.readData(ic_count);
- // Scan flags to get count of long-form bands.
- int long_forms = 0;
- for (i = 0; i < ic_count; i++)
- {
- int flags = ic_flags.getInt(); // may be long form!
- if ((flags & ACC_IC_LONG_FORM) != 0)
- {
- long_forms += 1;
- ics[i].name = NO_ENTRY_YET;
- }
- flags &= ~ACC_IC_LONG_FORM;
- entry *inner = ic_this_class.getRef();
- uint32_t inord = inner->inord;
- assert(inord < (uint32_t)cp.tag_count[CONSTANT_Class]);
- if (ic_index[inord] != nullptr)
- {
- unpack_abort("identical inner class");
- break;
- }
- ic_index[inord] = &ics[i];
- ics[i].inner = inner;
- ics[i].flags = flags;
- assert(cp.getIC(inner) == &ics[i]);
- }
- // ic_this_class.done();
- // ic_flags.done();
- ic_outer_class.readData(long_forms);
- ic_name.readData(long_forms);
- for (i = 0; i < ic_count; i++)
- {
- if (ics[i].name == NO_ENTRY_YET)
- {
- // Long form.
- ics[i].outer = ic_outer_class.getRefN();
- ics[i].name = ic_name.getRefN();
- }
- else
- {
- // Fill in outer and name based on inner.
- bytes &n = ics[i].inner->value.b;
- bytes pkgOuter;
- bytes number;
- bytes name;
- // Parse n into pkgOuter and name (and number).
- int dollar1, dollar2; // pointers to $ in the pattern
- // parse n = (<pkg>/)*<outer>($<number>)?($<name>)?
- int nlen = (int)n.len;
- int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, nlen) + 1;
- dollar2 = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, nlen);
- if (dollar2 < 0)
- {
- unpack_abort();
- }
- assert(dollar2 >= pkglen);
- if (isDigitString(n, dollar2 + 1, nlen))
- {
- // n = (<pkg>/)*<outer>$<number>
- number = n.slice(dollar2 + 1, nlen);
- name.set(nullptr, 0);
- dollar1 = dollar2;
- }
- else if (pkglen < (dollar1 = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, dollar2 - 1)) &&
- isDigitString(n, dollar1 + 1, dollar2))
- {
- // n = (<pkg>/)*<outer>$<number>$<name>
- number = n.slice(dollar1 + 1, dollar2);
- name = n.slice(dollar2 + 1, nlen);
- }
- else
- {
- // n = (<pkg>/)*<outer>$<name>
- dollar1 = dollar2;
- number.set(nullptr, 0);
- name = n.slice(dollar2 + 1, nlen);
- }
- if (number.ptr == nullptr)
- pkgOuter = n.slice(0, dollar1);
- else
- pkgOuter.set(nullptr, 0);
-
- if (pkgOuter.ptr != nullptr)
- ics[i].outer = cp.ensureClass(pkgOuter);
-
- if (name.ptr != nullptr)
- ics[i].name = cp.ensureUtf8(name);
- }
-
- // update child/sibling list
- if (ics[i].outer != nullptr)
- {
- uint32_t outord = ics[i].outer->inord;
- if (outord != NO_INORD)
- {
- assert(outord < (uint32_t)cp.tag_count[CONSTANT_Class]);
- ics[i].next_sibling = ic_child_index[outord];
- ic_child_index[outord] = &ics[i];
- }
- }
- }
- // ic_outer_class.done();
- // ic_name.done();
+ int i;
+ int index_size = cp.tag_count[CONSTANT_Class];
+ inner_class **ic_index = U_NEW(inner_class *, index_size);
+ inner_class **ic_child_index = U_NEW(inner_class *, index_size);
+ cp.ic_index = ic_index;
+ cp.ic_child_index = ic_child_index;
+ ics = U_NEW(inner_class, ic_count);
+ ic_this_class.readData(ic_count);
+ ic_flags.readData(ic_count);
+ // Scan flags to get count of long-form bands.
+ int long_forms = 0;
+ for (i = 0; i < ic_count; i++)
+ {
+ int flags = ic_flags.getInt(); // may be long form!
+ if ((flags & ACC_IC_LONG_FORM) != 0)
+ {
+ long_forms += 1;
+ ics[i].name = NO_ENTRY_YET;
+ }
+ flags &= ~ACC_IC_LONG_FORM;
+ entry *inner = ic_this_class.getRef();
+ uint32_t inord = inner->inord;
+ assert(inord < (uint32_t)cp.tag_count[CONSTANT_Class]);
+ if (ic_index[inord] != nullptr)
+ {
+ unpack_abort("identical inner class");
+ break;
+ }
+ ic_index[inord] = &ics[i];
+ ics[i].inner = inner;
+ ics[i].flags = flags;
+ assert(cp.getIC(inner) == &ics[i]);
+ }
+ // ic_this_class.done();
+ // ic_flags.done();
+ ic_outer_class.readData(long_forms);
+ ic_name.readData(long_forms);
+ for (i = 0; i < ic_count; i++)
+ {
+ if (ics[i].name == NO_ENTRY_YET)
+ {
+ // Long form.
+ ics[i].outer = ic_outer_class.getRefN();
+ ics[i].name = ic_name.getRefN();
+ }
+ else
+ {
+ // Fill in outer and name based on inner.
+ bytes &n = ics[i].inner->value.b;
+ bytes pkgOuter;
+ bytes number;
+ bytes name;
+ // Parse n into pkgOuter and name (and number).
+ int dollar1, dollar2; // pointers to $ in the pattern
+ // parse n = (<pkg>/)*<outer>($<number>)?($<name>)?
+ int nlen = (int)n.len;
+ int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, nlen) + 1;
+ dollar2 = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, nlen);
+ if (dollar2 < 0)
+ {
+ unpack_abort();
+ }
+ assert(dollar2 >= pkglen);
+ if (isDigitString(n, dollar2 + 1, nlen))
+ {
+ // n = (<pkg>/)*<outer>$<number>
+ number = n.slice(dollar2 + 1, nlen);
+ name.set(nullptr, 0);
+ dollar1 = dollar2;
+ }
+ else if (pkglen < (dollar1 = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, dollar2 - 1)) &&
+ isDigitString(n, dollar1 + 1, dollar2))
+ {
+ // n = (<pkg>/)*<outer>$<number>$<name>
+ number = n.slice(dollar1 + 1, dollar2);
+ name = n.slice(dollar2 + 1, nlen);
+ }
+ else
+ {
+ // n = (<pkg>/)*<outer>$<name>
+ dollar1 = dollar2;
+ number.set(nullptr, 0);
+ name = n.slice(dollar2 + 1, nlen);
+ }
+ if (number.ptr == nullptr)
+ pkgOuter = n.slice(0, dollar1);
+ else
+ pkgOuter.set(nullptr, 0);
+
+ if (pkgOuter.ptr != nullptr)
+ ics[i].outer = cp.ensureClass(pkgOuter);
+
+ if (name.ptr != nullptr)
+ ics[i].name = cp.ensureUtf8(name);
+ }
+
+ // update child/sibling list
+ if (ics[i].outer != nullptr)
+ {
+ uint32_t outord = ics[i].outer->inord;
+ if (outord != NO_INORD)
+ {
+ assert(outord < (uint32_t)cp.tag_count[CONSTANT_Class]);
+ ics[i].next_sibling = ic_child_index[outord];
+ ic_child_index[outord] = &ics[i];
+ }
+ }
+ }
+ // ic_outer_class.done();
+ // ic_name.done();
}
void unpacker::read_classes()
{
- class_this.readData(class_count);
- class_super.readData(class_count);
- class_interface_count.readData(class_count);
- class_interface.readData(class_interface_count.getIntTotal());
+ class_this.readData(class_count);
+ class_super.readData(class_count);
+ class_interface_count.readData(class_count);
+ class_interface.readData(class_interface_count.getIntTotal());
#if 0
int i;
@@ -2250,1220 +2250,1220 @@ void unpacker::read_classes()
class_super.rewind();
#endif
- // Members.
- class_field_count.readData(class_count);
- class_method_count.readData(class_count);
+ // Members.
+ class_field_count.readData(class_count);
+ class_method_count.readData(class_count);
- int field_count = class_field_count.getIntTotal();
- int method_count = class_method_count.getIntTotal();
+ int field_count = class_field_count.getIntTotal();
+ int method_count = class_method_count.getIntTotal();
- field_descr.readData(field_count);
- read_attrs(ATTR_CONTEXT_FIELD, field_count);
- method_descr.readData(method_count);
- read_attrs(ATTR_CONTEXT_METHOD, method_count);
- read_attrs(ATTR_CONTEXT_CLASS, class_count);
- read_code_headers();
+ field_descr.readData(field_count);
+ read_attrs(ATTR_CONTEXT_FIELD, field_count);
+ method_descr.readData(method_count);
+ read_attrs(ATTR_CONTEXT_METHOD, method_count);
+ read_attrs(ATTR_CONTEXT_CLASS, class_count);
+ read_code_headers();
}
int unpacker::attr_definitions::predefCount(uint32_t idx)
{
- return isPredefined(idx) ? flag_count[idx] : 0;
+ return isPredefined(idx) ? flag_count[idx] : 0;
}
void unpacker::read_attrs(int attrc, int obj_count)
{
- attr_definitions &ad = attr_defs[attrc];
- assert(ad.attrc == attrc);
-
- int i, idx, count;
-
- bool haveLongFlags = ad.haveLongFlags();
-
- band &xxx_flags_hi = ad.xxx_flags_hi();
- if (haveLongFlags)
- xxx_flags_hi.readData(obj_count);
-
- band &xxx_flags_lo = ad.xxx_flags_lo();
- xxx_flags_lo.readData(obj_count);
-
- // pre-scan flags, counting occurrences of each index bit
- uint64_t indexMask = ad.flagIndexMask(); // which flag bits are index bits?
- for (i = 0; i < obj_count; i++)
- {
- uint64_t indexBits = xxx_flags_hi.getLong(xxx_flags_lo, haveLongFlags);
- if ((indexBits & ~indexMask) > (ushort) - 1)
- {
- unpack_abort("undefined attribute flag bit");
- return;
- }
- indexBits &= indexMask; // ignore classfile flag bits
- for (idx = 0; indexBits != 0; idx++, indexBits >>= 1)
- {
- ad.flag_count[idx] += (int)(indexBits & 1);
- }
- }
- // we'll scan these again later for output:
- xxx_flags_lo.rewind();
- xxx_flags_hi.rewind();
-
- band &xxx_attr_count = ad.xxx_attr_count();
- // There is one count element for each 1<<16 bit set in flags:
- xxx_attr_count.readData(ad.predefCount(X_ATTR_OVERFLOW));
-
- band &xxx_attr_indexes = ad.xxx_attr_indexes();
- int overflowIndexCount = xxx_attr_count.getIntTotal();
- xxx_attr_indexes.readData(overflowIndexCount);
- // pre-scan attr indexes, counting occurrences of each value
- for (i = 0; i < overflowIndexCount; i++)
- {
- idx = xxx_attr_indexes.getInt();
- if (!ad.isIndex(idx))
- {
- unpack_abort("attribute index out of bounds");
- return;
- }
- ad.getCount(idx) += 1;
- }
- xxx_attr_indexes.rewind(); // we'll scan it again later for output
-
- // We will need a backward call count for each used backward callable.
- int backwardCounts = 0;
- for (idx = 0; idx < ad.layouts.length(); idx++)
- {
- layout_definition *lo = ad.getLayout(idx);
- if (lo != nullptr && ad.getCount(idx) != 0)
- {
- // Build the bands lazily, only when they are used.
- band **bands = ad.buildBands(lo);
- if (lo->hasCallables())
- {
- for (i = 0; bands[i] != nullptr; i++)
- {
- if (bands[i]->le_back)
- {
- assert(bands[i]->le_kind == EK_CBLE);
- backwardCounts += 1;
- }
- }
- }
- }
- }
- ad.xxx_attr_calls().readData(backwardCounts);
-
- // Read built-in bands.
- // Mostly, these are hand-coded equivalents to readBandData().
- switch (attrc)
- {
- case ATTR_CONTEXT_CLASS:
-
- count = ad.predefCount(CLASS_ATTR_SourceFile);
- class_SourceFile_RUN.readData(count);
-
- count = ad.predefCount(CLASS_ATTR_EnclosingMethod);
- class_EnclosingMethod_RC.readData(count);
- class_EnclosingMethod_RDN.readData(count);
-
- count = ad.predefCount(X_ATTR_Signature);
- class_Signature_RS.readData(count);
-
- ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
- ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
-
- count = ad.predefCount(CLASS_ATTR_InnerClasses);
- class_InnerClasses_N.readData(count);
-
- count = class_InnerClasses_N.getIntTotal();
- class_InnerClasses_RC.readData(count);
- class_InnerClasses_F.readData(count);
-
- // Drop remaining columns wherever flags are zero:
- count -= class_InnerClasses_F.getIntCount(0);
- class_InnerClasses_outer_RCN.readData(count);
- class_InnerClasses_name_RUN.readData(count);
-
- count = ad.predefCount(CLASS_ATTR_ClassFile_version);
- class_ClassFile_version_minor_H.readData(count);
- class_ClassFile_version_major_H.readData(count);
- break;
-
- case ATTR_CONTEXT_FIELD:
-
- count = ad.predefCount(FIELD_ATTR_ConstantValue);
- field_ConstantValue_KQ.readData(count);
-
- count = ad.predefCount(X_ATTR_Signature);
- field_Signature_RS.readData(count);
-
- ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
- ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
- break;
-
- case ATTR_CONTEXT_METHOD:
-
- code_count = ad.predefCount(METHOD_ATTR_Code);
- // Code attrs are handled very specially below...
-
- count = ad.predefCount(METHOD_ATTR_Exceptions);
- method_Exceptions_N.readData(count);
- count = method_Exceptions_N.getIntTotal();
- method_Exceptions_RC.readData(count);
-
- count = ad.predefCount(X_ATTR_Signature);
- method_Signature_RS.readData(count);
-
- ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
- ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
- ad.readBandData(METHOD_ATTR_RuntimeVisibleParameterAnnotations);
- ad.readBandData(METHOD_ATTR_RuntimeInvisibleParameterAnnotations);
- ad.readBandData(METHOD_ATTR_AnnotationDefault);
- break;
-
- case ATTR_CONTEXT_CODE:
- // (keep this code aligned with its brother in unpacker::write_attrs)
- count = ad.predefCount(CODE_ATTR_StackMapTable);
- // disable this feature in old archives!
- if (count != 0 && majver < JAVA6_PACKAGE_MAJOR_VERSION)
- {
- unpack_abort("undefined StackMapTable attribute (old archive format)");
- return;
- }
- code_StackMapTable_N.readData(count);
- count = code_StackMapTable_N.getIntTotal();
- code_StackMapTable_frame_T.readData(count);
- // the rest of it depends in a complicated way on frame tags
- {
- int fat_frame_count = 0;
- int offset_count = 0;
- int type_count = 0;
- for (int k = 0; k < count; k++)
- {
- int tag = code_StackMapTable_frame_T.getByte();
- if (tag <= 127)
- {
- // (64-127) [(2)]
- if (tag >= 64)
- type_count++;
- }
- else if (tag <= 251)
- {
- // (247) [(1)(2)]
- // (248-251) [(1)]
- if (tag >= 247)
- offset_count++;
- if (tag == 247)
- type_count++;
- }
- else if (tag <= 254)
- {
- // (252) [(1)(2)]
- // (253) [(1)(2)(2)]
- // (254) [(1)(2)(2)(2)]
- offset_count++;
- type_count += (tag - 251);
- }
- else
- {
- // (255) [(1)NH[(2)]NH[(2)]]
- fat_frame_count++;
- }
- }
-
- // done pre-scanning frame tags:
- code_StackMapTable_frame_T.rewind();
-
- // deal completely with fat frames:
- offset_count += fat_frame_count;
- code_StackMapTable_local_N.readData(fat_frame_count);
- type_count += code_StackMapTable_local_N.getIntTotal();
- code_StackMapTable_stack_N.readData(fat_frame_count);
- type_count += code_StackMapTable_stack_N.getIntTotal();
- // read the rest:
- code_StackMapTable_offset.readData(offset_count);
- code_StackMapTable_T.readData(type_count);
- // (7) [RCH]
- count = code_StackMapTable_T.getIntCount(7);
- code_StackMapTable_RC.readData(count);
- // (8) [PH]
- count = code_StackMapTable_T.getIntCount(8);
- code_StackMapTable_P.readData(count);
- }
-
- count = ad.predefCount(CODE_ATTR_LineNumberTable);
- code_LineNumberTable_N.readData(count);
- count = code_LineNumberTable_N.getIntTotal();
- code_LineNumberTable_bci_P.readData(count);
- code_LineNumberTable_line.readData(count);
-
- count = ad.predefCount(CODE_ATTR_LocalVariableTable);
- code_LocalVariableTable_N.readData(count);
- count = code_LocalVariableTable_N.getIntTotal();
- code_LocalVariableTable_bci_P.readData(count);
- code_LocalVariableTable_span_O.readData(count);
- code_LocalVariableTable_name_RU.readData(count);
- code_LocalVariableTable_type_RS.readData(count);
- code_LocalVariableTable_slot.readData(count);
-
- count = ad.predefCount(CODE_ATTR_LocalVariableTypeTable);
- code_LocalVariableTypeTable_N.readData(count);
- count = code_LocalVariableTypeTable_N.getIntTotal();
- code_LocalVariableTypeTable_bci_P.readData(count);
- code_LocalVariableTypeTable_span_O.readData(count);
- code_LocalVariableTypeTable_name_RU.readData(count);
- code_LocalVariableTypeTable_type_RS.readData(count);
- code_LocalVariableTypeTable_slot.readData(count);
- break;
- }
-
- // Read compressor-defined bands.
- for (idx = 0; idx < ad.layouts.length(); idx++)
- {
- if (ad.getLayout(idx) == nullptr)
- continue; // none at this fixed index <32
- if (idx < (int)ad.flag_limit && ad.isPredefined(idx))
- continue; // already handled
- if (ad.getCount(idx) == 0)
- continue; // no attributes of this type (then why transmit layouts?)
- ad.readBandData(idx);
- }
+ attr_definitions &ad = attr_defs[attrc];
+ assert(ad.attrc == attrc);
+
+ int i, idx, count;
+
+ bool haveLongFlags = ad.haveLongFlags();
+
+ band &xxx_flags_hi = ad.xxx_flags_hi();
+ if (haveLongFlags)
+ xxx_flags_hi.readData(obj_count);
+
+ band &xxx_flags_lo = ad.xxx_flags_lo();
+ xxx_flags_lo.readData(obj_count);
+
+ // pre-scan flags, counting occurrences of each index bit
+ uint64_t indexMask = ad.flagIndexMask(); // which flag bits are index bits?
+ for (i = 0; i < obj_count; i++)
+ {
+ uint64_t indexBits = xxx_flags_hi.getLong(xxx_flags_lo, haveLongFlags);
+ if ((indexBits & ~indexMask) > (ushort) - 1)
+ {
+ unpack_abort("undefined attribute flag bit");
+ return;
+ }
+ indexBits &= indexMask; // ignore classfile flag bits
+ for (idx = 0; indexBits != 0; idx++, indexBits >>= 1)
+ {
+ ad.flag_count[idx] += (int)(indexBits & 1);
+ }
+ }
+ // we'll scan these again later for output:
+ xxx_flags_lo.rewind();
+ xxx_flags_hi.rewind();
+
+ band &xxx_attr_count = ad.xxx_attr_count();
+ // There is one count element for each 1<<16 bit set in flags:
+ xxx_attr_count.readData(ad.predefCount(X_ATTR_OVERFLOW));
+
+ band &xxx_attr_indexes = ad.xxx_attr_indexes();
+ int overflowIndexCount = xxx_attr_count.getIntTotal();
+ xxx_attr_indexes.readData(overflowIndexCount);
+ // pre-scan attr indexes, counting occurrences of each value
+ for (i = 0; i < overflowIndexCount; i++)
+ {
+ idx = xxx_attr_indexes.getInt();
+ if (!ad.isIndex(idx))
+ {
+ unpack_abort("attribute index out of bounds");
+ return;
+ }
+ ad.getCount(idx) += 1;
+ }
+ xxx_attr_indexes.rewind(); // we'll scan it again later for output
+
+ // We will need a backward call count for each used backward callable.
+ int backwardCounts = 0;
+ for (idx = 0; idx < ad.layouts.length(); idx++)
+ {
+ layout_definition *lo = ad.getLayout(idx);
+ if (lo != nullptr && ad.getCount(idx) != 0)
+ {
+ // Build the bands lazily, only when they are used.
+ band **bands = ad.buildBands(lo);
+ if (lo->hasCallables())
+ {
+ for (i = 0; bands[i] != nullptr; i++)
+ {
+ if (bands[i]->le_back)
+ {
+ assert(bands[i]->le_kind == EK_CBLE);
+ backwardCounts += 1;
+ }
+ }
+ }
+ }
+ }
+ ad.xxx_attr_calls().readData(backwardCounts);
+
+ // Read built-in bands.
+ // Mostly, these are hand-coded equivalents to readBandData().
+ switch (attrc)
+ {
+ case ATTR_CONTEXT_CLASS:
+
+ count = ad.predefCount(CLASS_ATTR_SourceFile);
+ class_SourceFile_RUN.readData(count);
+
+ count = ad.predefCount(CLASS_ATTR_EnclosingMethod);
+ class_EnclosingMethod_RC.readData(count);
+ class_EnclosingMethod_RDN.readData(count);
+
+ count = ad.predefCount(X_ATTR_Signature);
+ class_Signature_RS.readData(count);
+
+ ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
+ ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
+
+ count = ad.predefCount(CLASS_ATTR_InnerClasses);
+ class_InnerClasses_N.readData(count);
+
+ count = class_InnerClasses_N.getIntTotal();
+ class_InnerClasses_RC.readData(count);
+ class_InnerClasses_F.readData(count);
+
+ // Drop remaining columns wherever flags are zero:
+ count -= class_InnerClasses_F.getIntCount(0);
+ class_InnerClasses_outer_RCN.readData(count);
+ class_InnerClasses_name_RUN.readData(count);
+
+ count = ad.predefCount(CLASS_ATTR_ClassFile_version);
+ class_ClassFile_version_minor_H.readData(count);
+ class_ClassFile_version_major_H.readData(count);
+ break;
+
+ case ATTR_CONTEXT_FIELD:
+
+ count = ad.predefCount(FIELD_ATTR_ConstantValue);
+ field_ConstantValue_KQ.readData(count);
+
+ count = ad.predefCount(X_ATTR_Signature);
+ field_Signature_RS.readData(count);
+
+ ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
+ ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
+ break;
+
+ case ATTR_CONTEXT_METHOD:
+
+ code_count = ad.predefCount(METHOD_ATTR_Code);
+ // Code attrs are handled very specially below...
+
+ count = ad.predefCount(METHOD_ATTR_Exceptions);
+ method_Exceptions_N.readData(count);
+ count = method_Exceptions_N.getIntTotal();
+ method_Exceptions_RC.readData(count);
+
+ count = ad.predefCount(X_ATTR_Signature);
+ method_Signature_RS.readData(count);
+
+ ad.readBandData(X_ATTR_RuntimeVisibleAnnotations);
+ ad.readBandData(X_ATTR_RuntimeInvisibleAnnotations);
+ ad.readBandData(METHOD_ATTR_RuntimeVisibleParameterAnnotations);
+ ad.readBandData(METHOD_ATTR_RuntimeInvisibleParameterAnnotations);
+ ad.readBandData(METHOD_ATTR_AnnotationDefault);
+ break;
+
+ case ATTR_CONTEXT_CODE:
+ // (keep this code aligned with its brother in unpacker::write_attrs)
+ count = ad.predefCount(CODE_ATTR_StackMapTable);
+ // disable this feature in old archives!
+ if (count != 0 && majver < JAVA6_PACKAGE_MAJOR_VERSION)
+ {
+ unpack_abort("undefined StackMapTable attribute (old archive format)");
+ return;
+ }
+ code_StackMapTable_N.readData(count);
+ count = code_StackMapTable_N.getIntTotal();
+ code_StackMapTable_frame_T.readData(count);
+ // the rest of it depends in a complicated way on frame tags
+ {
+ int fat_frame_count = 0;
+ int offset_count = 0;
+ int type_count = 0;
+ for (int k = 0; k < count; k++)
+ {
+ int tag = code_StackMapTable_frame_T.getByte();
+ if (tag <= 127)
+ {
+ // (64-127) [(2)]
+ if (tag >= 64)
+ type_count++;
+ }
+ else if (tag <= 251)
+ {
+ // (247) [(1)(2)]
+ // (248-251) [(1)]
+ if (tag >= 247)
+ offset_count++;
+ if (tag == 247)
+ type_count++;
+ }
+ else if (tag <= 254)
+ {
+ // (252) [(1)(2)]
+ // (253) [(1)(2)(2)]
+ // (254) [(1)(2)(2)(2)]
+ offset_count++;
+ type_count += (tag - 251);
+ }
+ else
+ {
+ // (255) [(1)NH[(2)]NH[(2)]]
+ fat_frame_count++;
+ }
+ }
+
+ // done pre-scanning frame tags:
+ code_StackMapTable_frame_T.rewind();
+
+ // deal completely with fat frames:
+ offset_count += fat_frame_count;
+ code_StackMapTable_local_N.readData(fat_frame_count);
+ type_count += code_StackMapTable_local_N.getIntTotal();
+ code_StackMapTable_stack_N.readData(fat_frame_count);
+ type_count += code_StackMapTable_stack_N.getIntTotal();
+ // read the rest:
+ code_StackMapTable_offset.readData(offset_count);
+ code_StackMapTable_T.readData(type_count);
+ // (7) [RCH]
+ count = code_StackMapTable_T.getIntCount(7);
+ code_StackMapTable_RC.readData(count);
+ // (8) [PH]
+ count = code_StackMapTable_T.getIntCount(8);
+ code_StackMapTable_P.readData(count);
+ }
+
+ count = ad.predefCount(CODE_ATTR_LineNumberTable);
+ code_LineNumberTable_N.readData(count);
+ count = code_LineNumberTable_N.getIntTotal();
+ code_LineNumberTable_bci_P.readData(count);
+ code_LineNumberTable_line.readData(count);
+
+ count = ad.predefCount(CODE_ATTR_LocalVariableTable);
+ code_LocalVariableTable_N.readData(count);
+ count = code_LocalVariableTable_N.getIntTotal();
+ code_LocalVariableTable_bci_P.readData(count);
+ code_LocalVariableTable_span_O.readData(count);
+ code_LocalVariableTable_name_RU.readData(count);
+ code_LocalVariableTable_type_RS.readData(count);
+ code_LocalVariableTable_slot.readData(count);
+
+ count = ad.predefCount(CODE_ATTR_LocalVariableTypeTable);
+ code_LocalVariableTypeTable_N.readData(count);
+ count = code_LocalVariableTypeTable_N.getIntTotal();
+ code_LocalVariableTypeTable_bci_P.readData(count);
+ code_LocalVariableTypeTable_span_O.readData(count);
+ code_LocalVariableTypeTable_name_RU.readData(count);
+ code_LocalVariableTypeTable_type_RS.readData(count);
+ code_LocalVariableTypeTable_slot.readData(count);
+ break;
+ }
+
+ // Read compressor-defined bands.
+ for (idx = 0; idx < ad.layouts.length(); idx++)
+ {
+ if (ad.getLayout(idx) == nullptr)
+ continue; // none at this fixed index <32
+ if (idx < (int)ad.flag_limit && ad.isPredefined(idx))
+ continue; // already handled
+ if (ad.getCount(idx) == 0)
+ continue; // no attributes of this type (then why transmit layouts?)
+ ad.readBandData(idx);
+ }
}
void unpacker::attr_definitions::readBandData(int idx)
{
- int j;
- uint32_t count = getCount(idx);
- if (count == 0)
- return;
- layout_definition *lo = getLayout(idx);
- bool hasCallables = lo->hasCallables();
- band **bands = lo->bands();
- if (!hasCallables)
- {
- // Read through the rest of the bands in a regular way.
- readBandData(bands, count);
- }
- else
- {
- // Deal with the callables.
- // First set up the forward entry count for each callable.
- // This is stored on band::length of the callable.
- bands[0]->expectMoreLength(count);
- for (j = 0; bands[j] != nullptr; j++)
- {
- band &j_cble = *bands[j];
- assert(j_cble.le_kind == EK_CBLE);
- if (j_cble.le_back)
- {
- // Add in the predicted effects of backward calls, too.
- int back_calls = xxx_attr_calls().getInt();
- j_cble.expectMoreLength(back_calls);
- // In a moment, more forward calls may increment j_cble.length.
- }
- }
- // Now consult whichever callables have non-zero entry counts.
- readBandData(bands, (uint32_t) - 1);
- }
+ int j;
+ uint32_t count = getCount(idx);
+ if (count == 0)
+ return;
+ layout_definition *lo = getLayout(idx);
+ bool hasCallables = lo->hasCallables();
+ band **bands = lo->bands();
+ if (!hasCallables)
+ {
+ // Read through the rest of the bands in a regular way.
+ readBandData(bands, count);
+ }
+ else
+ {
+ // Deal with the callables.
+ // First set up the forward entry count for each callable.
+ // This is stored on band::length of the callable.
+ bands[0]->expectMoreLength(count);
+ for (j = 0; bands[j] != nullptr; j++)
+ {
+ band &j_cble = *bands[j];
+ assert(j_cble.le_kind == EK_CBLE);
+ if (j_cble.le_back)
+ {
+ // Add in the predicted effects of backward calls, too.
+ int back_calls = xxx_attr_calls().getInt();
+ j_cble.expectMoreLength(back_calls);
+ // In a moment, more forward calls may increment j_cble.length.
+ }
+ }
+ // Now consult whichever callables have non-zero entry counts.
+ readBandData(bands, (uint32_t) - 1);
+ }
}
// Recursive helper to the previous function:
void unpacker::attr_definitions::readBandData(band **body, uint32_t count)
{
- int j, k;
- for (j = 0; body[j] != nullptr; j++)
- {
- band &b = *body[j];
- if (b.defc != nullptr)
- {
- // It has data, so read it.
- b.readData(count);
- }
- switch (b.le_kind)
- {
- case EK_REPL:
- {
- int reps = b.getIntTotal();
- readBandData(b.le_body, reps);
- }
- break;
- case EK_UN:
- {
- int remaining = count;
- for (k = 0; b.le_body[k] != nullptr; k++)
- {
- band &k_case = *b.le_body[k];
- int k_count = 0;
- if (k_case.le_casetags == nullptr)
- {
- k_count = remaining; // last (empty) case
- }
- else
- {
- int *tags = k_case.le_casetags;
- int ntags = *tags++; // 1st element is length (why not?)
- while (ntags-- > 0)
- {
- int tag = *tags++;
- k_count += b.getIntCount(tag);
- }
- }
- readBandData(k_case.le_body, k_count);
- remaining -= k_count;
- }
- assert(remaining == 0);
- }
- break;
- case EK_CALL:
- // Push the count forward, if it is not a backward call.
- if (!b.le_back)
- {
- band &cble = *b.le_body[0];
- assert(cble.le_kind == EK_CBLE);
- cble.expectMoreLength(count);
- }
- break;
- case EK_CBLE:
- assert((int)count == -1); // incoming count is meaningless
- k = b.length;
- assert(k >= 0);
- // This is intended and required for non production mode.
- assert((b.length = -1)); // make it unable to accept more calls now.
- readBandData(b.le_body, k);
- break;
- }
- }
+ int j, k;
+ for (j = 0; body[j] != nullptr; j++)
+ {
+ band &b = *body[j];
+ if (b.defc != nullptr)
+ {
+ // It has data, so read it.
+ b.readData(count);
+ }
+ switch (b.le_kind)
+ {
+ case EK_REPL:
+ {
+ int reps = b.getIntTotal();
+ readBandData(b.le_body, reps);
+ }
+ break;
+ case EK_UN:
+ {
+ int remaining = count;
+ for (k = 0; b.le_body[k] != nullptr; k++)
+ {
+ band &k_case = *b.le_body[k];
+ int k_count = 0;
+ if (k_case.le_casetags == nullptr)
+ {
+ k_count = remaining; // last (empty) case
+ }
+ else
+ {
+ int *tags = k_case.le_casetags;
+ int ntags = *tags++; // 1st element is length (why not?)
+ while (ntags-- > 0)
+ {
+ int tag = *tags++;
+ k_count += b.getIntCount(tag);
+ }
+ }
+ readBandData(k_case.le_body, k_count);
+ remaining -= k_count;
+ }
+ assert(remaining == 0);
+ }
+ break;
+ case EK_CALL:
+ // Push the count forward, if it is not a backward call.
+ if (!b.le_back)
+ {
+ band &cble = *b.le_body[0];
+ assert(cble.le_kind == EK_CBLE);
+ cble.expectMoreLength(count);
+ }
+ break;
+ case EK_CBLE:
+ assert((int)count == -1); // incoming count is meaningless
+ k = b.length;
+ assert(k >= 0);
+ // This is intended and required for non production mode.
+ assert((b.length = -1)); // make it unable to accept more calls now.
+ readBandData(b.le_body, k);
+ break;
+ }
+ }
}
static inline band **findMatchingCase(int matchTag, band **cases)
{
- for (int k = 0; cases[k] != nullptr; k++)
- {
- band &k_case = *cases[k];
- if (k_case.le_casetags != nullptr)
- {
- // If it has tags, it must match a tag.
- int *tags = k_case.le_casetags;
- int ntags = *tags++; // 1st element is length
- for (; ntags > 0; ntags--)
- {
- int tag = *tags++;
- if (tag == matchTag)
- break;
- }
- if (ntags == 0)
- continue; // does not match
- }
- return k_case.le_body;
- }
- return nullptr;
+ for (int k = 0; cases[k] != nullptr; k++)
+ {
+ band &k_case = *cases[k];
+ if (k_case.le_casetags != nullptr)
+ {
+ // If it has tags, it must match a tag.
+ int *tags = k_case.le_casetags;
+ int ntags = *tags++; // 1st element is length
+ for (; ntags > 0; ntags--)
+ {
+ int tag = *tags++;
+ if (tag == matchTag)
+ break;
+ }
+ if (ntags == 0)
+ continue; // does not match
+ }
+ return k_case.le_body;
+ }
+ return nullptr;
}
// write attribute band data:
void unpacker::putlayout(band **body)
{
- int i;
- int prevBII = -1;
- int prevBCI = -1;
- if (body == NULL)
- {
- unpack_abort("putlayout: unexpected NULL for body");
- return;
- }
- for (i = 0; body[i] != nullptr; i++)
- {
- band &b = *body[i];
- byte le_kind = b.le_kind;
-
- // Handle scalar part, if any.
- int x = 0;
- entry *e = nullptr;
- if (b.defc != nullptr)
- {
- // It has data, so unparse an element.
- if (b.ixTag != CONSTANT_None)
- {
- assert(le_kind == EK_REF);
- if (b.ixTag == CONSTANT_Literal)
- e = b.getRefUsing(cp.getKQIndex());
- else
- e = b.getRefN();
- switch (b.le_len)
- {
- case 0:
- break;
- case 1:
- putu1ref(e);
- break;
- case 2:
- putref(e);
- break;
- case 4:
- putu2(0);
- putref(e);
- break;
- default:
- assert(false);
- }
- }
- else
- {
- assert(le_kind == EK_INT || le_kind == EK_REPL || le_kind == EK_UN);
- x = b.getInt();
-
- assert(!b.le_bci || prevBCI == (int)to_bci(prevBII));
- switch (b.le_bci)
- {
- case EK_BCI: // PH: transmit R(bci), store bci
- x = to_bci(prevBII = x);
- prevBCI = x;
- break;
- case EK_BCID: // POH: transmit D(R(bci)), store bci
- x = to_bci(prevBII += x);
- prevBCI = x;
- break;
- case EK_BCO: // OH: transmit D(R(bci)), store D(bci)
- x = to_bci(prevBII += x) - prevBCI;
- prevBCI += x;
- break;
- }
- assert(!b.le_bci || prevBCI == (int)to_bci(prevBII));
-
- switch (b.le_len)
- {
- case 0:
- break;
- case 1:
- putu1(x);
- break;
- case 2:
- putu2(x);
- break;
- case 4:
- putu4(x);
- break;
- default:
- assert(false);
- }
- }
- }
-
- // Handle subparts, if any.
- switch (le_kind)
- {
- case EK_REPL:
- // x is the repeat count
- while (x-- > 0)
- {
- putlayout(b.le_body);
- }
- break;
- case EK_UN:
- // x is the tag
- putlayout(findMatchingCase(x, b.le_body));
- break;
- case EK_CALL:
- {
- band &cble = *b.le_body[0];
- assert(cble.le_kind == EK_CBLE);
- // FIXME: hit this one
- // assert(cble.le_len == b.le_len);
- putlayout(cble.le_body);
- }
- break;
-
- case EK_CBLE:
- case EK_CASE:
- assert(false); // should not reach here
- }
- }
+ int i;
+ int prevBII = -1;
+ int prevBCI = -1;
+ if (body == NULL)
+ {
+ unpack_abort("putlayout: unexpected NULL for body");
+ return;
+ }
+ for (i = 0; body[i] != nullptr; i++)
+ {
+ band &b = *body[i];
+ byte le_kind = b.le_kind;
+
+ // Handle scalar part, if any.
+ int x = 0;
+ entry *e = nullptr;
+ if (b.defc != nullptr)
+ {
+ // It has data, so unparse an element.
+ if (b.ixTag != CONSTANT_None)
+ {
+ assert(le_kind == EK_REF);
+ if (b.ixTag == CONSTANT_Literal)
+ e = b.getRefUsing(cp.getKQIndex());
+ else
+ e = b.getRefN();
+ switch (b.le_len)
+ {
+ case 0:
+ break;
+ case 1:
+ putu1ref(e);
+ break;
+ case 2:
+ putref(e);
+ break;
+ case 4:
+ putu2(0);
+ putref(e);
+ break;
+ default:
+ assert(false);
+ }
+ }
+ else
+ {
+ assert(le_kind == EK_INT || le_kind == EK_REPL || le_kind == EK_UN);
+ x = b.getInt();
+
+ assert(!b.le_bci || prevBCI == (int)to_bci(prevBII));
+ switch (b.le_bci)
+ {
+ case EK_BCI: // PH: transmit R(bci), store bci
+ x = to_bci(prevBII = x);
+ prevBCI = x;
+ break;
+ case EK_BCID: // POH: transmit D(R(bci)), store bci
+ x = to_bci(prevBII += x);
+ prevBCI = x;
+ break;
+ case EK_BCO: // OH: transmit D(R(bci)), store D(bci)
+ x = to_bci(prevBII += x) - prevBCI;
+ prevBCI += x;
+ break;
+ }
+ assert(!b.le_bci || prevBCI == (int)to_bci(prevBII));
+
+ switch (b.le_len)
+ {
+ case 0:
+ break;
+ case 1:
+ putu1(x);
+ break;
+ case 2:
+ putu2(x);
+ break;
+ case 4:
+ putu4(x);
+ break;
+ default:
+ assert(false);
+ }
+ }
+ }
+
+ // Handle subparts, if any.
+ switch (le_kind)
+ {
+ case EK_REPL:
+ // x is the repeat count
+ while (x-- > 0)
+ {
+ putlayout(b.le_body);
+ }
+ break;
+ case EK_UN:
+ // x is the tag
+ putlayout(findMatchingCase(x, b.le_body));
+ break;
+ case EK_CALL:
+ {
+ band &cble = *b.le_body[0];
+ assert(cble.le_kind == EK_CBLE);
+ // FIXME: hit this one
+ // assert(cble.le_len == b.le_len);
+ putlayout(cble.le_body);
+ }
+ break;
+
+ case EK_CBLE:
+ case EK_CASE:
+ assert(false); // should not reach here
+ }
+ }
}
void unpacker::read_files()
{
- file_name.readData(file_count);
- if ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0)
- file_size_hi.readData(file_count);
- file_size_lo.readData(file_count);
- if ((archive_options & AO_HAVE_FILE_MODTIME) != 0)
- file_modtime.readData(file_count);
- int allFiles = file_count + class_count;
- if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0)
- {
- file_options.readData(file_count);
- // FO_IS_CLASS_STUB might be set, causing overlap between classes and files
- for (int i = 0; i < file_count; i++)
- {
- if ((file_options.getInt() & FO_IS_CLASS_STUB) != 0)
- {
- allFiles -= 1; // this one counts as both class and file
- }
- }
- file_options.rewind();
- }
- assert((default_file_options & FO_IS_CLASS_STUB) == 0);
- files_remaining = allFiles;
+ file_name.readData(file_count);
+ if ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0)
+ file_size_hi.readData(file_count);
+ file_size_lo.readData(file_count);
+ if ((archive_options & AO_HAVE_FILE_MODTIME) != 0)
+ file_modtime.readData(file_count);
+ int allFiles = file_count + class_count;
+ if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0)
+ {
+ file_options.readData(file_count);
+ // FO_IS_CLASS_STUB might be set, causing overlap between classes and files
+ for (int i = 0; i < file_count; i++)
+ {
+ if ((file_options.getInt() & FO_IS_CLASS_STUB) != 0)
+ {
+ allFiles -= 1; // this one counts as both class and file
+ }
+ }
+ file_options.rewind();
+ }
+ assert((default_file_options & FO_IS_CLASS_STUB) == 0);
+ files_remaining = allFiles;
}
void unpacker::get_code_header(int &max_stack, int &max_na_locals, int &handler_count,
- int &cflags)
+ int &cflags)
{
- int sc = code_headers.getByte();
- if (sc == 0)
- {
- max_stack = max_na_locals = handler_count = cflags = -1;
- return;
- }
- // Short code header is the usual case:
- int nh;
- int mod;
- if (sc < 1 + 12 * 12)
- {
- sc -= 1;
- nh = 0;
- mod = 12;
- }
- else if (sc < 1 + 12 * 12 + 8 * 8)
- {
- sc -= 1 + 12 * 12;
- nh = 1;
- mod = 8;
- }
- else
- {
- assert(sc < 1 + 12 * 12 + 8 * 8 + 7 * 7);
- sc -= 1 + 12 * 12 + 8 * 8;
- nh = 2;
- mod = 7;
- }
- max_stack = sc % mod;
- max_na_locals = sc / mod; // caller must add static, siglen
- handler_count = nh;
- if ((archive_options & AO_HAVE_ALL_CODE_FLAGS) != 0)
- cflags = -1;
- else
- cflags = 0; // this one has no attributes
+ int sc = code_headers.getByte();
+ if (sc == 0)
+ {
+ max_stack = max_na_locals = handler_count = cflags = -1;
+ return;
+ }
+ // Short code header is the usual case:
+ int nh;
+ int mod;
+ if (sc < 1 + 12 * 12)
+ {
+ sc -= 1;
+ nh = 0;
+ mod = 12;
+ }
+ else if (sc < 1 + 12 * 12 + 8 * 8)
+ {
+ sc -= 1 + 12 * 12;
+ nh = 1;
+ mod = 8;
+ }
+ else
+ {
+ assert(sc < 1 + 12 * 12 + 8 * 8 + 7 * 7);
+ sc -= 1 + 12 * 12 + 8 * 8;
+ nh = 2;
+ mod = 7;
+ }
+ max_stack = sc % mod;
+ max_na_locals = sc / mod; // caller must add static, siglen
+ handler_count = nh;
+ if ((archive_options & AO_HAVE_ALL_CODE_FLAGS) != 0)
+ cflags = -1;
+ else
+ cflags = 0; // this one has no attributes
}
// Cf. PackageReader.readCodeHeaders
void unpacker::read_code_headers()
{
- code_headers.readData(code_count);
- int totalHandlerCount = 0;
- int totalFlagsCount = 0;
- for (int i = 0; i < code_count; i++)
- {
- int max_stack, max_locals, handler_count, cflags;
- get_code_header(max_stack, max_locals, handler_count, cflags);
- if (max_stack < 0)
- code_max_stack.expectMoreLength(1);
- if (max_locals < 0)
- code_max_na_locals.expectMoreLength(1);
- if (handler_count < 0)
- code_handler_count.expectMoreLength(1);
- else
- totalHandlerCount += handler_count;
- if (cflags < 0)
- totalFlagsCount += 1;
- }
- code_headers.rewind(); // replay later during writing
-
- code_max_stack.readData();
- code_max_na_locals.readData();
- code_handler_count.readData();
- totalHandlerCount += code_handler_count.getIntTotal();
-
- // Read handler specifications.
- // Cf. PackageReader.readCodeHandlers.
- code_handler_start_P.readData(totalHandlerCount);
- code_handler_end_PO.readData(totalHandlerCount);
- code_handler_catch_PO.readData(totalHandlerCount);
- code_handler_class_RCN.readData(totalHandlerCount);
-
- read_attrs(ATTR_CONTEXT_CODE, totalFlagsCount);
+ code_headers.readData(code_count);
+ int totalHandlerCount = 0;
+ int totalFlagsCount = 0;
+ for (int i = 0; i < code_count; i++)
+ {
+ int max_stack, max_locals, handler_count, cflags;
+ get_code_header(max_stack, max_locals, handler_count, cflags);
+ if (max_stack < 0)
+ code_max_stack.expectMoreLength(1);
+ if (max_locals < 0)
+ code_max_na_locals.expectMoreLength(1);
+ if (handler_count < 0)
+ code_handler_count.expectMoreLength(1);
+ else
+ totalHandlerCount += handler_count;
+ if (cflags < 0)
+ totalFlagsCount += 1;
+ }
+ code_headers.rewind(); // replay later during writing
+
+ code_max_stack.readData();
+ code_max_na_locals.readData();
+ code_handler_count.readData();
+ totalHandlerCount += code_handler_count.getIntTotal();
+
+ // Read handler specifications.
+ // Cf. PackageReader.readCodeHandlers.
+ code_handler_start_P.readData(totalHandlerCount);
+ code_handler_end_PO.readData(totalHandlerCount);
+ code_handler_catch_PO.readData(totalHandlerCount);
+ code_handler_class_RCN.readData(totalHandlerCount);
+
+ read_attrs(ATTR_CONTEXT_CODE, totalFlagsCount);
}
static inline bool is_in_range(uint32_t n, uint32_t min, uint32_t max)
{
- return n - min <= max - min; // unsigned arithmetic!
+ return n - min <= max - min; // unsigned arithmetic!
}
static inline bool is_field_op(int bc)
{
- return is_in_range(bc, bc_getstatic, bc_putfield);
+ return is_in_range(bc, bc_getstatic, bc_putfield);
}
static inline bool is_invoke_init_op(int bc)
{
- return is_in_range(bc, _invokeinit_op, _invokeinit_limit - 1);
+ return is_in_range(bc, _invokeinit_op, _invokeinit_limit - 1);
}
static inline bool is_self_linker_op(int bc)
{
- return is_in_range(bc, _self_linker_op, _self_linker_limit - 1);
+ return is_in_range(bc, _self_linker_op, _self_linker_limit - 1);
}
static bool is_branch_op(int bc)
{
- return is_in_range(bc, bc_ifeq, bc_jsr) || is_in_range(bc, bc_ifnull, bc_jsr_w);
+ return is_in_range(bc, bc_ifeq, bc_jsr) || is_in_range(bc, bc_ifnull, bc_jsr_w);
}
static bool is_local_slot_op(int bc)
{
- return is_in_range(bc, bc_iload, bc_aload) || is_in_range(bc, bc_istore, bc_astore) ||
- bc == bc_iinc || bc == bc_ret;
+ return is_in_range(bc, bc_iload, bc_aload) || is_in_range(bc, bc_istore, bc_astore) ||
+ bc == bc_iinc || bc == bc_ret;
}
band *unpacker::ref_band_for_op(int bc)
{
- switch (bc)
- {
- case bc_ildc:
- case bc_ildc_w:
- return &bc_intref;
- case bc_fldc:
- case bc_fldc_w:
- return &bc_floatref;
- case bc_lldc2_w:
- return &bc_longref;
- case bc_dldc2_w:
- return &bc_doubleref;
- case bc_aldc:
- case bc_aldc_w:
- return &bc_stringref;
- case bc_cldc:
- case bc_cldc_w:
- return &bc_classref;
-
- case bc_getstatic:
- case bc_putstatic:
- case bc_getfield:
- case bc_putfield:
- return &bc_fieldref;
-
- case bc_invokevirtual:
- case bc_invokespecial:
- case bc_invokestatic:
- return &bc_methodref;
- case bc_invokeinterface:
- return &bc_imethodref;
-
- case bc_new:
- case bc_anewarray:
- case bc_checkcast:
- case bc_instanceof:
- case bc_multianewarray:
- return &bc_classref;
- }
- return nullptr;
+ switch (bc)
+ {
+ case bc_ildc:
+ case bc_ildc_w:
+ return &bc_intref;
+ case bc_fldc:
+ case bc_fldc_w:
+ return &bc_floatref;
+ case bc_lldc2_w:
+ return &bc_longref;
+ case bc_dldc2_w:
+ return &bc_doubleref;
+ case bc_aldc:
+ case bc_aldc_w:
+ return &bc_stringref;
+ case bc_cldc:
+ case bc_cldc_w:
+ return &bc_classref;
+
+ case bc_getstatic:
+ case bc_putstatic:
+ case bc_getfield:
+ case bc_putfield:
+ return &bc_fieldref;
+
+ case bc_invokevirtual:
+ case bc_invokespecial:
+ case bc_invokestatic:
+ return &bc_methodref;
+ case bc_invokeinterface:
+ return &bc_imethodref;
+
+ case bc_new:
+ case bc_anewarray:
+ case bc_checkcast:
+ case bc_instanceof:
+ case bc_multianewarray:
+ return &bc_classref;
+ }
+ return nullptr;
}
band *unpacker::ref_band_for_self_op(int bc, bool &isAloadVar, int &origBCVar)
{
- if (!is_self_linker_op(bc))
- return nullptr;
- int idx = (bc - _self_linker_op);
- bool isSuper = (idx >= _self_linker_super_flag);
- if (isSuper)
- idx -= _self_linker_super_flag;
- bool isAload = (idx >= _self_linker_aload_flag);
- if (isAload)
- idx -= _self_linker_aload_flag;
- int origBC = _first_linker_op + idx;
- bool isField = is_field_op(origBC);
- isAloadVar = isAload;
- origBCVar = _first_linker_op + idx;
- if (!isSuper)
- return isField ? &bc_thisfield : &bc_thismethod;
- else
- return isField ? &bc_superfield : &bc_supermethod;
+ if (!is_self_linker_op(bc))
+ return nullptr;
+ int idx = (bc - _self_linker_op);
+ bool isSuper = (idx >= _self_linker_super_flag);
+ if (isSuper)
+ idx -= _self_linker_super_flag;
+ bool isAload = (idx >= _self_linker_aload_flag);
+ if (isAload)
+ idx -= _self_linker_aload_flag;
+ int origBC = _first_linker_op + idx;
+ bool isField = is_field_op(origBC);
+ isAloadVar = isAload;
+ origBCVar = _first_linker_op + idx;
+ if (!isSuper)
+ return isField ? &bc_thisfield : &bc_thismethod;
+ else
+ return isField ? &bc_superfield : &bc_supermethod;
}
// Cf. PackageReader.readByteCodes
inline // called exactly once => inline
- void
+ void
unpacker::read_bcs()
{
- // read from bc_codes and bc_case_count
- fillbytes all_switch_ops;
- all_switch_ops.init();
-
- // Read directly from rp/rplimit.
- // Do this later: bc_codes.readData(...)
- byte *rp0 = rp;
-
- band *bc_which;
- byte *opptr = rp;
- byte *oplimit = rplimit;
-
- bool isAload; // passed by ref and then ignored
- int junkBC; // passed by ref and then ignored
- for (int k = 0; k < code_count; k++)
- {
- // Scan one method:
- for (;;)
- {
- if (opptr + 2 > oplimit)
- {
- rp = opptr;
- ensure_input(2);
- oplimit = rplimit;
- rp = rp0; // back up
- }
- if (opptr == oplimit)
- {
- unpack_abort();
- }
- int bc = *opptr++ & 0xFF;
- bool isWide = false;
- if (bc == bc_wide)
- {
- if (opptr == oplimit)
- {
- unpack_abort();
- }
- bc = *opptr++ & 0xFF;
- isWide = true;
- }
- // Adjust expectations of various band sizes.
- switch (bc)
- {
- case bc_tableswitch:
- case bc_lookupswitch:
- all_switch_ops.addByte(bc);
- break;
- case bc_iinc:
- bc_local.expectMoreLength(1);
- bc_which = isWide ? &bc_short : &bc_byte;
- bc_which->expectMoreLength(1);
- break;
- case bc_sipush:
- bc_short.expectMoreLength(1);
- break;
- case bc_bipush:
- bc_byte.expectMoreLength(1);
- break;
- case bc_newarray:
- bc_byte.expectMoreLength(1);
- break;
- case bc_multianewarray:
- assert(ref_band_for_op(bc) == &bc_classref);
- bc_classref.expectMoreLength(1);
- bc_byte.expectMoreLength(1);
- break;
- case bc_ref_escape:
- bc_escrefsize.expectMoreLength(1);
- bc_escref.expectMoreLength(1);
- break;
- case bc_byte_escape:
- bc_escsize.expectMoreLength(1);
- // bc_escbyte will have to be counted too
- break;
- default:
- if (is_invoke_init_op(bc))
- {
- bc_initref.expectMoreLength(1);
- break;
- }
- bc_which = ref_band_for_self_op(bc, isAload, junkBC);
- if (bc_which != nullptr)
- {
- bc_which->expectMoreLength(1);
- break;
- }
- if (is_branch_op(bc))
- {
- bc_label.expectMoreLength(1);
- break;
- }
- bc_which = ref_band_for_op(bc);
- if (bc_which != nullptr)
- {
- bc_which->expectMoreLength(1);
- assert(bc != bc_multianewarray); // handled elsewhere
- break;
- }
- if (is_local_slot_op(bc))
- {
- bc_local.expectMoreLength(1);
- break;
- }
- break;
- case bc_end_marker:
- // Increment k and test against code_count.
- goto doneScanningMethod;
- }
- }
- doneScanningMethod:
- {
- }
- }
-
- // Go through the formality, so we can use it in a regular fashion later:
- assert(rp == rp0);
- bc_codes.readData((int)(opptr - rp));
-
- int i = 0;
-
- // To size instruction bands correctly, we need info on switches:
- bc_case_count.readData((int)all_switch_ops.size());
- for (i = 0; i < (int)all_switch_ops.size(); i++)
- {
- int caseCount = bc_case_count.getInt();
- int bc = all_switch_ops.getByte(i);
- bc_label.expectMoreLength(1 + caseCount); // default label + cases
- bc_case_value.expectMoreLength(bc == bc_tableswitch ? 1 : caseCount);
- }
- bc_case_count.rewind(); // uses again for output
-
- all_switch_ops.free();
-
- for (i = e_bc_case_value; i <= e_bc_escsize; i++)
- {
- all_bands[i].readData();
- }
-
- // The bc_escbyte band is counted by the immediately previous band.
- bc_escbyte.readData(bc_escsize.getIntTotal());
+ // read from bc_codes and bc_case_count
+ fillbytes all_switch_ops;
+ all_switch_ops.init();
+
+ // Read directly from rp/rplimit.
+ // Do this later: bc_codes.readData(...)
+ byte *rp0 = rp;
+
+ band *bc_which;
+ byte *opptr = rp;
+ byte *oplimit = rplimit;
+
+ bool isAload; // passed by ref and then ignored
+ int junkBC; // passed by ref and then ignored
+ for (int k = 0; k < code_count; k++)
+ {
+ // Scan one method:
+ for (;;)
+ {
+ if (opptr + 2 > oplimit)
+ {
+ rp = opptr;
+ ensure_input(2);
+ oplimit = rplimit;
+ rp = rp0; // back up
+ }
+ if (opptr == oplimit)
+ {
+ unpack_abort();
+ }
+ int bc = *opptr++ & 0xFF;
+ bool isWide = false;
+ if (bc == bc_wide)
+ {
+ if (opptr == oplimit)
+ {
+ unpack_abort();
+ }
+ bc = *opptr++ & 0xFF;
+ isWide = true;
+ }
+ // Adjust expectations of various band sizes.
+ switch (bc)
+ {
+ case bc_tableswitch:
+ case bc_lookupswitch:
+ all_switch_ops.addByte(bc);
+ break;
+ case bc_iinc:
+ bc_local.expectMoreLength(1);
+ bc_which = isWide ? &bc_short : &bc_byte;
+ bc_which->expectMoreLength(1);
+ break;
+ case bc_sipush:
+ bc_short.expectMoreLength(1);
+ break;
+ case bc_bipush:
+ bc_byte.expectMoreLength(1);
+ break;
+ case bc_newarray:
+ bc_byte.expectMoreLength(1);
+ break;
+ case bc_multianewarray:
+ assert(ref_band_for_op(bc) == &bc_classref);
+ bc_classref.expectMoreLength(1);
+ bc_byte.expectMoreLength(1);
+ break;
+ case bc_ref_escape:
+ bc_escrefsize.expectMoreLength(1);
+ bc_escref.expectMoreLength(1);
+ break;
+ case bc_byte_escape:
+ bc_escsize.expectMoreLength(1);
+ // bc_escbyte will have to be counted too
+ break;
+ default:
+ if (is_invoke_init_op(bc))
+ {
+ bc_initref.expectMoreLength(1);
+ break;
+ }
+ bc_which = ref_band_for_self_op(bc, isAload, junkBC);
+ if (bc_which != nullptr)
+ {
+ bc_which->expectMoreLength(1);
+ break;
+ }
+ if (is_branch_op(bc))
+ {
+ bc_label.expectMoreLength(1);
+ break;
+ }
+ bc_which = ref_band_for_op(bc);
+ if (bc_which != nullptr)
+ {
+ bc_which->expectMoreLength(1);
+ assert(bc != bc_multianewarray); // handled elsewhere
+ break;
+ }
+ if (is_local_slot_op(bc))
+ {
+ bc_local.expectMoreLength(1);
+ break;
+ }
+ break;
+ case bc_end_marker:
+ // Increment k and test against code_count.
+ goto doneScanningMethod;
+ }
+ }
+ doneScanningMethod:
+ {
+ }
+ }
+
+ // Go through the formality, so we can use it in a regular fashion later:
+ assert(rp == rp0);
+ bc_codes.readData((int)(opptr - rp));
+
+ int i = 0;
+
+ // To size instruction bands correctly, we need info on switches:
+ bc_case_count.readData((int)all_switch_ops.size());
+ for (i = 0; i < (int)all_switch_ops.size(); i++)
+ {
+ int caseCount = bc_case_count.getInt();
+ int bc = all_switch_ops.getByte(i);
+ bc_label.expectMoreLength(1 + caseCount); // default label + cases
+ bc_case_value.expectMoreLength(bc == bc_tableswitch ? 1 : caseCount);
+ }
+ bc_case_count.rewind(); // uses again for output
+
+ all_switch_ops.free();
+
+ for (i = e_bc_case_value; i <= e_bc_escsize; i++)
+ {
+ all_bands[i].readData();
+ }
+
+ // The bc_escbyte band is counted by the immediately previous band.
+ bc_escbyte.readData(bc_escsize.getIntTotal());
}
void unpacker::read_bands()
{
- read_file_header();
-
- if (cp.nentries == 0)
- {
- // read_file_header failed to read a CP, because it copied a JAR.
- return;
- }
-
- // Do this after the file header has been read:
- check_options();
-
- read_cp();
- read_attr_defs();
- read_ics();
- read_classes();
- read_bcs();
- read_files();
+ read_file_header();
+
+ if (cp.nentries == 0)
+ {
+ // read_file_header failed to read a CP, because it copied a JAR.
+ return;
+ }
+
+ // Do this after the file header has been read:
+ check_options();
+
+ read_cp();
+ read_attr_defs();
+ read_ics();
+ read_classes();
+ read_bcs();
+ read_files();
}
/// CP routines
entry *&constant_pool::hashTabRef(byte tag, bytes &b)
{
- uint32_t hash = tag + (int)b.len;
- for (int i = 0; i < (int)b.len; i++)
- {
- hash = hash * 31 + (0xFF & b.ptr[i]);
- }
- entry **ht = hashTab;
- int hlen = hashTabLength;
- assert((hlen & (hlen - 1)) == 0); // must be power of 2
- uint32_t hash1 = hash & (hlen - 1); // == hash % hlen
- uint32_t hash2 = 0; // lazily computed (requires mod op.)
+ uint32_t hash = tag + (int)b.len;
+ for (int i = 0; i < (int)b.len; i++)
+ {
+ hash = hash * 31 + (0xFF & b.ptr[i]);
+ }
+ entry **ht = hashTab;
+ int hlen = hashTabLength;
+ assert((hlen & (hlen - 1)) == 0); // must be power of 2
+ uint32_t hash1 = hash & (hlen - 1); // == hash % hlen
+ uint32_t hash2 = 0; // lazily computed (requires mod op.)
#ifndef NDEBUG
- int probes = 0;
+ int probes = 0;
#endif
- while (ht[hash1] != nullptr)
- {
- entry &e = *ht[hash1];
- if (e.value.b.equals(b) && e.tag == tag)
- break;
- if (hash2 == 0)
- // Note: hash2 must be relatively prime to hlen, hence the "|1".
- hash2 = (((hash % 499) & (hlen - 1)) | 1);
- hash1 += hash2;
- if (hash1 >= (uint32_t)hlen)
- hash1 -= hlen;
- assert(hash1 < (uint32_t)hlen);
- assert(++probes < hlen);
- }
- return ht[hash1];
+ while (ht[hash1] != nullptr)
+ {
+ entry &e = *ht[hash1];
+ if (e.value.b.equals(b) && e.tag == tag)
+ break;
+ if (hash2 == 0)
+ // Note: hash2 must be relatively prime to hlen, hence the "|1".
+ hash2 = (((hash % 499) & (hlen - 1)) | 1);
+ hash1 += hash2;
+ if (hash1 >= (uint32_t)hlen)
+ hash1 -= hlen;
+ assert(hash1 < (uint32_t)hlen);
+ assert(++probes < hlen);
+ }
+ return ht[hash1];
}
static void insert_extra(entry *e, ptrlist &extras)
{
- // This ordering helps implement the Pack200 requirement
- // of a predictable CP order in the class files produced.
- e->inord = NO_INORD; // mark as an "extra"
- extras.add(e);
- // Note: We will sort the list (by string-name) later.
+ // This ordering helps implement the Pack200 requirement
+ // of a predictable CP order in the class files produced.
+ e->inord = NO_INORD; // mark as an "extra"
+ extras.add(e);
+ // Note: We will sort the list (by string-name) later.
}
entry *constant_pool::ensureUtf8(bytes &b)
{
- entry *&ix = hashTabRef(CONSTANT_Utf8, b);
- if (ix != nullptr)
- return ix;
- // Make one.
- if (nentries == maxentries)
- {
- unpack_abort("cp utf8 overflow");
- return &entries[tag_base[CONSTANT_Utf8]]; // return something
- }
- entry &e = entries[nentries++];
- e.tag = CONSTANT_Utf8;
- u->saveTo(e.value.b, b);
- assert(&e >= first_extra_entry);
- insert_extra(&e, tag_extras[CONSTANT_Utf8]);
- return ix = &e;
+ entry *&ix = hashTabRef(CONSTANT_Utf8, b);
+ if (ix != nullptr)
+ return ix;
+ // Make one.
+ if (nentries == maxentries)
+ {
+ unpack_abort("cp utf8 overflow");
+ return &entries[tag_base[CONSTANT_Utf8]]; // return something
+ }
+ entry &e = entries[nentries++];
+ e.tag = CONSTANT_Utf8;
+ u->saveTo(e.value.b, b);
+ assert(&e >= first_extra_entry);
+ insert_extra(&e, tag_extras[CONSTANT_Utf8]);
+ return ix = &e;
}
entry *constant_pool::ensureClass(bytes &b)
{
- entry *&ix = hashTabRef(CONSTANT_Class, b);
- if (ix != nullptr)
- return ix;
- // Make one.
- if (nentries == maxentries)
- {
- unpack_abort("cp class overflow");
- return &entries[tag_base[CONSTANT_Class]]; // return something
- }
- entry &e = entries[nentries++];
- e.tag = CONSTANT_Class;
- e.nrefs = 1;
- e.refs = U_NEW(entry *, 1);
- ix = &e; // hold my spot in the index
- entry *utf = ensureUtf8(b);
- e.refs[0] = utf;
- e.value.b = utf->value.b;
- assert(&e >= first_extra_entry);
- insert_extra(&e, tag_extras[CONSTANT_Class]);
- return &e;
+ entry *&ix = hashTabRef(CONSTANT_Class, b);
+ if (ix != nullptr)
+ return ix;
+ // Make one.
+ if (nentries == maxentries)
+ {
+ unpack_abort("cp class overflow");
+ return &entries[tag_base[CONSTANT_Class]]; // return something
+ }
+ entry &e = entries[nentries++];
+ e.tag = CONSTANT_Class;
+ e.nrefs = 1;
+ e.refs = U_NEW(entry *, 1);
+ ix = &e; // hold my spot in the index
+ entry *utf = ensureUtf8(b);
+ e.refs[0] = utf;
+ e.value.b = utf->value.b;
+ assert(&e >= first_extra_entry);
+ insert_extra(&e, tag_extras[CONSTANT_Class]);
+ return &e;
}
void constant_pool::expandSignatures()
{
- int i;
- int nsigs = 0;
- int nreused = 0;
- int first_sig = tag_base[CONSTANT_Signature];
- int sig_limit = tag_count[CONSTANT_Signature] + first_sig;
- fillbytes buf;
- buf.init(1 << 10);
- for (i = first_sig; i < sig_limit; i++)
- {
- entry &e = entries[i];
- assert(e.tag == CONSTANT_Signature);
- int refnum = 0;
- bytes form = e.refs[refnum++]->asUtf8();
- buf.empty();
- for (int j = 0; j < (int)form.len; j++)
- {
- int c = form.ptr[j];
- buf.addByte(c);
- if (c == 'L')
- {
- entry *cls = e.refs[refnum++];
- buf.append(cls->className()->asUtf8());
- }
- }
- assert(refnum == e.nrefs);
- bytes &sig = buf.b;
-
- // try to find a pre-existing Utf8:
- entry *&e2 = hashTabRef(CONSTANT_Utf8, sig);
- if (e2 != nullptr)
- {
- assert(e2->isUtf8(sig));
- e.value.b = e2->value.b;
- e.refs[0] = e2;
- e.nrefs = 1;
- nreused++;
- }
- else
- {
- // there is no other replacement; reuse this CP entry as a Utf8
- u->saveTo(e.value.b, sig);
- e.tag = CONSTANT_Utf8;
- e.nrefs = 0;
- e2 = &e;
- }
- nsigs++;
- }
- buf.free();
-
- // go expunge all references to remaining signatures:
- for (i = 0; i < (int)nentries; i++)
- {
- entry &e = entries[i];
- for (int j = 0; j < e.nrefs; j++)
- {
- entry *&e2 = e.refs[j];
- if (e2 != nullptr && e2->tag == CONSTANT_Signature)
- e2 = e2->refs[0];
- }
- }
+ int i;
+ int nsigs = 0;
+ int nreused = 0;
+ int first_sig = tag_base[CONSTANT_Signature];
+ int sig_limit = tag_count[CONSTANT_Signature] + first_sig;
+ fillbytes buf;
+ buf.init(1 << 10);
+ for (i = first_sig; i < sig_limit; i++)
+ {
+ entry &e = entries[i];
+ assert(e.tag == CONSTANT_Signature);
+ int refnum = 0;
+ bytes form = e.refs[refnum++]->asUtf8();
+ buf.empty();
+ for (int j = 0; j < (int)form.len; j++)
+ {
+ int c = form.ptr[j];
+ buf.addByte(c);
+ if (c == 'L')
+ {
+ entry *cls = e.refs[refnum++];
+ buf.append(cls->className()->asUtf8());
+ }
+ }
+ assert(refnum == e.nrefs);
+ bytes &sig = buf.b;
+
+ // try to find a pre-existing Utf8:
+ entry *&e2 = hashTabRef(CONSTANT_Utf8, sig);
+ if (e2 != nullptr)
+ {
+ assert(e2->isUtf8(sig));
+ e.value.b = e2->value.b;
+ e.refs[0] = e2;
+ e.nrefs = 1;
+ nreused++;
+ }
+ else
+ {
+ // there is no other replacement; reuse this CP entry as a Utf8
+ u->saveTo(e.value.b, sig);
+ e.tag = CONSTANT_Utf8;
+ e.nrefs = 0;
+ e2 = &e;
+ }
+ nsigs++;
+ }
+ buf.free();
+
+ // go expunge all references to remaining signatures:
+ for (i = 0; i < (int)nentries; i++)
+ {
+ entry &e = entries[i];
+ for (int j = 0; j < e.nrefs; j++)
+ {
+ entry *&e2 = e.refs[j];
+ if (e2 != nullptr && e2->tag == CONSTANT_Signature)
+ e2 = e2->refs[0];
+ }
+ }
}
void constant_pool::initMemberIndexes()
{
- // This function does NOT refer to any class schema.
- // It is totally internal to the cpool.
- int i, j;
-
- // Get the pre-existing indexes:
- int nclasses = tag_count[CONSTANT_Class];
- // entry *classes = tag_base[CONSTANT_Class] + entries; // UNUSED
- int nfields = tag_count[CONSTANT_Fieldref];
- entry *fields = tag_base[CONSTANT_Fieldref] + entries;
- int nmethods = tag_count[CONSTANT_Methodref];
- entry *methods = tag_base[CONSTANT_Methodref] + entries;
-
- int *field_counts = T_NEW(int, nclasses);
- int *method_counts = T_NEW(int, nclasses);
- cpindex *all_indexes = U_NEW(cpindex, nclasses * 2);
- entry **field_ix = U_NEW(entry *, add_size(nfields, nclasses));
- entry **method_ix = U_NEW(entry *, add_size(nmethods, nclasses));
-
- for (j = 0; j < nfields; j++)
- {
- entry &f = fields[j];
- i = f.memberClass()->inord;
- assert(i < nclasses);
- field_counts[i]++;
- }
- for (j = 0; j < nmethods; j++)
- {
- entry &m = methods[j];
- i = m.memberClass()->inord;
- assert(i < nclasses);
- method_counts[i]++;
- }
-
- int fbase = 0, mbase = 0;
- for (i = 0; i < nclasses; i++)
- {
- int fc = field_counts[i];
- int mc = method_counts[i];
- all_indexes[i * 2 + 0].init(fc, field_ix + fbase, CONSTANT_Fieldref + SUBINDEX_BIT);
- all_indexes[i * 2 + 1].init(mc, method_ix + mbase, CONSTANT_Methodref + SUBINDEX_BIT);
- // reuse field_counts and member_counts as fill pointers:
- field_counts[i] = fbase;
- method_counts[i] = mbase;
- fbase += fc + 1;
- mbase += mc + 1;
- // (the +1 leaves a space between every subarray)
- }
- assert(fbase == nfields + nclasses);
- assert(mbase == nmethods + nclasses);
-
- for (j = 0; j < nfields; j++)
- {
- entry &f = fields[j];
- i = f.memberClass()->inord;
- field_ix[field_counts[i]++] = &f;
- }
- for (j = 0; j < nmethods; j++)
- {
- entry &m = methods[j];
- i = m.memberClass()->inord;
- method_ix[method_counts[i]++] = &m;
- }
-
- member_indexes = all_indexes;
-
- // Free intermediate buffers.
- u->free_temps();
+ // This function does NOT refer to any class schema.
+ // It is totally internal to the cpool.
+ int i, j;
+
+ // Get the pre-existing indexes:
+ int nclasses = tag_count[CONSTANT_Class];
+ // entry *classes = tag_base[CONSTANT_Class] + entries; // UNUSED
+ int nfields = tag_count[CONSTANT_Fieldref];
+ entry *fields = tag_base[CONSTANT_Fieldref] + entries;
+ int nmethods = tag_count[CONSTANT_Methodref];
+ entry *methods = tag_base[CONSTANT_Methodref] + entries;
+
+ int *field_counts = T_NEW(int, nclasses);
+ int *method_counts = T_NEW(int, nclasses);
+ cpindex *all_indexes = U_NEW(cpindex, nclasses * 2);
+ entry **field_ix = U_NEW(entry *, add_size(nfields, nclasses));
+ entry **method_ix = U_NEW(entry *, add_size(nmethods, nclasses));
+
+ for (j = 0; j < nfields; j++)
+ {
+ entry &f = fields[j];
+ i = f.memberClass()->inord;
+ assert(i < nclasses);
+ field_counts[i]++;
+ }
+ for (j = 0; j < nmethods; j++)
+ {
+ entry &m = methods[j];
+ i = m.memberClass()->inord;
+ assert(i < nclasses);
+ method_counts[i]++;
+ }
+
+ int fbase = 0, mbase = 0;
+ for (i = 0; i < nclasses; i++)
+ {
+ int fc = field_counts[i];
+ int mc = method_counts[i];
+ all_indexes[i * 2 + 0].init(fc, field_ix + fbase, CONSTANT_Fieldref + SUBINDEX_BIT);
+ all_indexes[i * 2 + 1].init(mc, method_ix + mbase, CONSTANT_Methodref + SUBINDEX_BIT);
+ // reuse field_counts and member_counts as fill pointers:
+ field_counts[i] = fbase;
+ method_counts[i] = mbase;
+ fbase += fc + 1;
+ mbase += mc + 1;
+ // (the +1 leaves a space between every subarray)
+ }
+ assert(fbase == nfields + nclasses);
+ assert(mbase == nmethods + nclasses);
+
+ for (j = 0; j < nfields; j++)
+ {
+ entry &f = fields[j];
+ i = f.memberClass()->inord;
+ field_ix[field_counts[i]++] = &f;
+ }
+ for (j = 0; j < nmethods; j++)
+ {
+ entry &m = methods[j];
+ i = m.memberClass()->inord;
+ method_ix[method_counts[i]++] = &m;
+ }
+
+ member_indexes = all_indexes;
+
+ // Free intermediate buffers.
+ u->free_temps();
}
void entry::requestOutputIndex(constant_pool &cp, int req)
{
- assert(outputIndex <= NOT_REQUESTED); // must not have assigned indexes yet
- if (tag == CONSTANT_Signature)
- {
- ref(0)->requestOutputIndex(cp, req);
- return;
- }
- assert(req == REQUESTED || req == REQUESTED_LDC);
- if (outputIndex != NOT_REQUESTED)
- {
- if (req == REQUESTED_LDC)
- outputIndex = req; // this kind has precedence
- return;
- }
- outputIndex = req;
- // assert(!cp.outputEntries.contains(this));
- assert(tag != CONSTANT_Signature);
- cp.outputEntries.add(this);
- for (int j = 0; j < nrefs; j++)
- {
- ref(j)->requestOutputIndex(cp);
- }
+ assert(outputIndex <= NOT_REQUESTED); // must not have assigned indexes yet
+ if (tag == CONSTANT_Signature)
+ {
+ ref(0)->requestOutputIndex(cp, req);
+ return;
+ }
+ assert(req == REQUESTED || req == REQUESTED_LDC);
+ if (outputIndex != NOT_REQUESTED)
+ {
+ if (req == REQUESTED_LDC)
+ outputIndex = req; // this kind has precedence
+ return;
+ }
+ outputIndex = req;
+ // assert(!cp.outputEntries.contains(this));
+ assert(tag != CONSTANT_Signature);
+ cp.outputEntries.add(this);
+ for (int j = 0; j < nrefs; j++)
+ {
+ ref(j)->requestOutputIndex(cp);
+ }
}
void constant_pool::resetOutputIndexes()
{
- int i;
- int noes = outputEntries.length();
- entry **oes = (entry **)outputEntries.base();
- for (i = 0; i < noes; i++)
- {
- entry &e = *oes[i];
- e.outputIndex = NOT_REQUESTED;
- }
- outputIndexLimit = 0;
- outputEntries.empty();
+ int i;
+ int noes = outputEntries.length();
+ entry **oes = (entry **)outputEntries.base();
+ for (i = 0; i < noes; i++)
+ {
+ entry &e = *oes[i];
+ e.outputIndex = NOT_REQUESTED;
+ }
+ outputIndexLimit = 0;
+ outputEntries.empty();
}
static const byte TAG_ORDER[CONSTANT_Limit] = {0, 1, 0, 2, 3, 4, 5, 7, 6, 10, 11, 12, 9, 8};
extern "C" int outputEntry_cmp(const void *e1p, const void *e2p)
{
- // Sort entries according to the Pack200 rules for deterministic
- // constant pool ordering.
- //
- // The four sort keys as follows, in order of decreasing importance:
- // 1. ldc first, then non-ldc guys
- // 2. normal cp_All entries by input order (i.e., address order)
- // 3. after that, extra entries by lexical order (as in tag_extras[*])
- entry &e1 = *(entry *)*(void **)e1p;
- entry &e2 = *(entry *)*(void **)e2p;
- int oi1 = e1.outputIndex;
- int oi2 = e2.outputIndex;
- assert(oi1 == REQUESTED || oi1 == REQUESTED_LDC);
- assert(oi2 == REQUESTED || oi2 == REQUESTED_LDC);
- if (oi1 != oi2)
- {
- if (oi1 == REQUESTED_LDC)
- return 0 - 1;
- if (oi2 == REQUESTED_LDC)
- return 1 - 0;
- // Else fall through; neither is an ldc request.
- }
- if (e1.inord != NO_INORD || e2.inord != NO_INORD)
- {
- // One or both is normal. Use input order.
- if (&e1 > &e2)
- return 1 - 0;
- if (&e1 < &e2)
- return 0 - 1;
- return 0; // equal pointers
- }
- // Both are extras. Sort by tag and then by value.
- if (e1.tag != e2.tag)
- {
- return TAG_ORDER[e1.tag] - TAG_ORDER[e2.tag];
- }
- // If the tags are the same, use string comparison.
- return compare_Utf8_chars(e1.value.b, e2.value.b);
+ // Sort entries according to the Pack200 rules for deterministic
+ // constant pool ordering.
+ //
+ // The four sort keys as follows, in order of decreasing importance:
+ // 1. ldc first, then non-ldc guys
+ // 2. normal cp_All entries by input order (i.e., address order)
+ // 3. after that, extra entries by lexical order (as in tag_extras[*])
+ entry &e1 = *(entry *)*(void **)e1p;
+ entry &e2 = *(entry *)*(void **)e2p;
+ int oi1 = e1.outputIndex;
+ int oi2 = e2.outputIndex;
+ assert(oi1 == REQUESTED || oi1 == REQUESTED_LDC);
+ assert(oi2 == REQUESTED || oi2 == REQUESTED_LDC);
+ if (oi1 != oi2)
+ {
+ if (oi1 == REQUESTED_LDC)
+ return 0 - 1;
+ if (oi2 == REQUESTED_LDC)
+ return 1 - 0;
+ // Else fall through; neither is an ldc request.
+ }
+ if (e1.inord != NO_INORD || e2.inord != NO_INORD)
+ {
+ // One or both is normal. Use input order.
+ if (&e1 > &e2)
+ return 1 - 0;
+ if (&e1 < &e2)
+ return 0 - 1;
+ return 0; // equal pointers
+ }
+ // Both are extras. Sort by tag and then by value.
+ if (e1.tag != e2.tag)
+ {
+ return TAG_ORDER[e1.tag] - TAG_ORDER[e2.tag];
+ }
+ // If the tags are the same, use string comparison.
+ return compare_Utf8_chars(e1.value.b, e2.value.b);
}
void constant_pool::computeOutputIndexes()
{
- int i;
-
- int noes = outputEntries.length();
- entry **oes = (entry **)outputEntries.base();
-
- // Sort the output constant pool into the order required by Pack200.
- PTRLIST_QSORT(outputEntries, outputEntry_cmp);
-
- // Allocate a new index for each entry that needs one.
- // We do this in two passes, one for LDC entries and one for the rest.
- int nextIndex = 1; // always skip index #0 in output cpool
- for (i = 0; i < noes; i++)
- {
- entry &e = *oes[i];
- assert(e.outputIndex == REQUESTED || e.outputIndex == REQUESTED_LDC);
- e.outputIndex = nextIndex++;
- if (e.isDoubleWord())
- nextIndex++; // do not use the next index
- }
- outputIndexLimit = nextIndex;
+ int i;
+
+ int noes = outputEntries.length();
+ entry **oes = (entry **)outputEntries.base();
+
+ // Sort the output constant pool into the order required by Pack200.
+ PTRLIST_QSORT(outputEntries, outputEntry_cmp);
+
+ // Allocate a new index for each entry that needs one.
+ // We do this in two passes, one for LDC entries and one for the rest.
+ int nextIndex = 1; // always skip index #0 in output cpool
+ for (i = 0; i < noes; i++)
+ {
+ entry &e = *oes[i];
+ assert(e.outputIndex == REQUESTED || e.outputIndex == REQUESTED_LDC);
+ e.outputIndex = nextIndex++;
+ if (e.isDoubleWord())
+ nextIndex++; // do not use the next index
+ }
+ outputIndexLimit = nextIndex;
}
// Unpacker Start
@@ -3473,63 +3473,63 @@ void constant_pool::computeOutputIndexes()
// Do not reset any unpack options.
void unpacker::reset()
{
- bytes_read_before_reset += bytes_read;
- bytes_written_before_reset += bytes_written;
- files_written_before_reset += files_written;
- classes_written_before_reset += classes_written;
- segments_read_before_reset += 1;
- if (verbose >= 2)
- {
- fprintf(stderr, "After segment %d, %" PRIu64 " bytes read and %" PRIu64 " bytes written.\n",
- segments_read_before_reset - 1, bytes_read_before_reset,
- bytes_written_before_reset);
- fprintf(stderr,
- "After segment %d, %d files (of which %d are classes) written to output.\n",
- segments_read_before_reset - 1, files_written_before_reset,
- classes_written_before_reset);
- if (archive_next_count != 0)
- {
- fprintf(stderr, "After segment %d, %d segment%s remaining (estimated).\n",
- segments_read_before_reset - 1, archive_next_count,
- archive_next_count == 1 ? "" : "s");
- }
- }
-
- unpacker save_u = (*this); // save bytewise image
- infileptr = nullptr; // make asserts happy
- jarout = nullptr; // do not close the output jar
- gzin = nullptr; // do not close the input gzip stream
- this->free();
- this->init(read_input_fn);
-
- // restore selected interface state:
- infileptr = save_u.infileptr;
- inbytes = save_u.inbytes;
- jarout = save_u.jarout;
- gzin = save_u.gzin;
- verbose = save_u.verbose;
- deflate_hint_or_zero = save_u.deflate_hint_or_zero;
- modification_time_or_zero = save_u.modification_time_or_zero;
- bytes_read_before_reset = save_u.bytes_read_before_reset;
- bytes_written_before_reset = save_u.bytes_written_before_reset;
- files_written_before_reset = save_u.files_written_before_reset;
- classes_written_before_reset = save_u.classes_written_before_reset;
- segments_read_before_reset = save_u.segments_read_before_reset;
- // Note: If we use strip_names, watch out: They get nuked here.
+ bytes_read_before_reset += bytes_read;
+ bytes_written_before_reset += bytes_written;
+ files_written_before_reset += files_written;
+ classes_written_before_reset += classes_written;
+ segments_read_before_reset += 1;
+ if (verbose >= 2)
+ {
+ fprintf(stderr, "After segment %d, %" PRIu64 " bytes read and %" PRIu64 " bytes written.\n",
+ segments_read_before_reset - 1, bytes_read_before_reset,
+ bytes_written_before_reset);
+ fprintf(stderr,
+ "After segment %d, %d files (of which %d are classes) written to output.\n",
+ segments_read_before_reset - 1, files_written_before_reset,
+ classes_written_before_reset);
+ if (archive_next_count != 0)
+ {
+ fprintf(stderr, "After segment %d, %d segment%s remaining (estimated).\n",
+ segments_read_before_reset - 1, archive_next_count,
+ archive_next_count == 1 ? "" : "s");
+ }
+ }
+
+ unpacker save_u = (*this); // save bytewise image
+ infileptr = nullptr; // make asserts happy
+ jarout = nullptr; // do not close the output jar
+ gzin = nullptr; // do not close the input gzip stream
+ this->free();
+ this->init(read_input_fn);
+
+ // restore selected interface state:
+ infileptr = save_u.infileptr;
+ inbytes = save_u.inbytes;
+ jarout = save_u.jarout;
+ gzin = save_u.gzin;
+ verbose = save_u.verbose;
+ deflate_hint_or_zero = save_u.deflate_hint_or_zero;
+ modification_time_or_zero = save_u.modification_time_or_zero;
+ bytes_read_before_reset = save_u.bytes_read_before_reset;
+ bytes_written_before_reset = save_u.bytes_written_before_reset;
+ files_written_before_reset = save_u.files_written_before_reset;
+ classes_written_before_reset = save_u.classes_written_before_reset;
+ segments_read_before_reset = save_u.segments_read_before_reset;
+ // Note: If we use strip_names, watch out: They get nuked here.
}
void unpacker::init(read_input_fn_t input_fn)
{
- int i;
- BYTES_OF(*this).clear();
- this->u = this; // self-reference for U_NEW macro
- read_input_fn = input_fn;
- all_bands = band::makeBands(this);
- // Make a default jar buffer; caller may safely overwrite it.
- jarout = U_NEW(jar, 1);
- jarout->init(this);
- for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
- attr_defs[i].u = u; // set up outer ptr
+ int i;
+ BYTES_OF(*this).clear();
+ this->u = this; // self-reference for U_NEW macro
+ read_input_fn = input_fn;
+ all_bands = band::makeBands(this);
+ // Make a default jar buffer; caller may safely overwrite it.
+ jarout = U_NEW(jar, 1);
+ jarout->init(this);
+ for (i = 0; i < ATTR_CONTEXT_LIMIT; i++)
+ attr_defs[i].u = u; // set up outer ptr
}
// Usage: unpack a byte buffer
@@ -3538,1253 +3538,1253 @@ void unpacker::init(read_input_fn_t input_fn)
// If nullptr, the callback is used to fill an internal buffer.
void unpacker::start(void *packptr, size_t len)
{
- if (packptr != nullptr && len != 0)
- {
- inbytes.set((byte *)packptr, len);
- }
- read_bands();
+ if (packptr != nullptr && len != 0)
+ {
+ inbytes.set((byte *)packptr, len);
+ }
+ read_bands();
}
void unpacker::check_options()
{
- if (deflate_hint_or_zero != 0)
- {
- bool force_deflate_hint = (deflate_hint_or_zero > 0);
- if (force_deflate_hint)
- default_file_options |= FO_DEFLATE_HINT;
- else
- default_file_options &= ~FO_DEFLATE_HINT;
- // Turn off per-file deflate hint by force.
- suppress_file_options |= FO_DEFLATE_HINT;
- }
- if (modification_time_or_zero != 0)
- {
- default_file_modtime = modification_time_or_zero;
- // Turn off per-file modtime by force.
- archive_options &= ~AO_HAVE_FILE_MODTIME;
- }
+ if (deflate_hint_or_zero != 0)
+ {
+ bool force_deflate_hint = (deflate_hint_or_zero > 0);
+ if (force_deflate_hint)
+ default_file_options |= FO_DEFLATE_HINT;
+ else
+ default_file_options &= ~FO_DEFLATE_HINT;
+ // Turn off per-file deflate hint by force.
+ suppress_file_options |= FO_DEFLATE_HINT;
+ }
+ if (modification_time_or_zero != 0)
+ {
+ default_file_modtime = modification_time_or_zero;
+ // Turn off per-file modtime by force.
+ archive_options &= ~AO_HAVE_FILE_MODTIME;
+ }
}
// classfile writing
void unpacker::reset_cur_classfile()
{
- // set defaults
- cur_class_minver = default_class_minver;
- cur_class_majver = default_class_majver;
-
- // reset constant pool state
- cp.resetOutputIndexes();
-
- // reset fixups
- class_fixup_type.empty();
- class_fixup_offset.empty();
- class_fixup_ref.empty();
- requested_ics.empty();
+ // set defaults
+ cur_class_minver = default_class_minver;
+ cur_class_majver = default_class_majver;
+
+ // reset constant pool state
+ cp.resetOutputIndexes();
+
+ // reset fixups
+ class_fixup_type.empty();
+ class_fixup_offset.empty();
+ class_fixup_ref.empty();
+ requested_ics.empty();
}
cpindex *constant_pool::getKQIndex()
{
- char ch = '?';
- if (u->cur_descr != nullptr)
- {
- entry *type = u->cur_descr->descrType();
- ch = type->value.b.ptr[0];
- }
- byte tag = CONSTANT_Integer;
- switch (ch)
- {
- case 'L':
- tag = CONSTANT_String;
- break;
- case 'I':
- tag = CONSTANT_Integer;
- break;
- case 'J':
- tag = CONSTANT_Long;
- break;
- case 'F':
- tag = CONSTANT_Float;
- break;
- case 'D':
- tag = CONSTANT_Double;
- break;
- case 'B':
- case 'S':
- case 'C':
- case 'Z':
- tag = CONSTANT_Integer;
- break;
- default:
- unpack_abort("bad KQ reference");
- break;
- }
- return getIndex(tag);
+ char ch = '?';
+ if (u->cur_descr != nullptr)
+ {
+ entry *type = u->cur_descr->descrType();
+ ch = type->value.b.ptr[0];
+ }
+ byte tag = CONSTANT_Integer;
+ switch (ch)
+ {
+ case 'L':
+ tag = CONSTANT_String;
+ break;
+ case 'I':
+ tag = CONSTANT_Integer;
+ break;
+ case 'J':
+ tag = CONSTANT_Long;
+ break;
+ case 'F':
+ tag = CONSTANT_Float;
+ break;
+ case 'D':
+ tag = CONSTANT_Double;
+ break;
+ case 'B':
+ case 'S':
+ case 'C':
+ case 'Z':
+ tag = CONSTANT_Integer;
+ break;
+ default:
+ unpack_abort("bad KQ reference");
+ break;
+ }
+ return getIndex(tag);
}
uint32_t unpacker::to_bci(uint32_t bii)
{
- uint32_t len = bcimap.length();
- uint32_t *map = (uint32_t *)bcimap.base();
- assert(len > 0); // must be initialized before using to_bci
- if (bii < len)
- return map[bii];
- // Else it's a fractional or out-of-range BCI.
- uint32_t key = bii - len;
- for (int i = len;; i--)
- {
- if (map[i - 1] - (i - 1) <= key)
- break;
- else
- --bii;
- }
- return bii;
+ uint32_t len = bcimap.length();
+ uint32_t *map = (uint32_t *)bcimap.base();
+ assert(len > 0); // must be initialized before using to_bci
+ if (bii < len)
+ return map[bii];
+ // Else it's a fractional or out-of-range BCI.
+ uint32_t key = bii - len;
+ for (int i = len;; i--)
+ {
+ if (map[i - 1] - (i - 1) <= key)
+ break;
+ else
+ --bii;
+ }
+ return bii;
}
void unpacker::put_stackmap_type()
{
- int tag = code_StackMapTable_T.getByte();
- putu1(tag);
- switch (tag)
- {
- case 7: // (7) [RCH]
- putref(code_StackMapTable_RC.getRef());
- break;
- case 8: // (8) [PH]
- putu2(to_bci(code_StackMapTable_P.getInt()));
- break;
- }
+ int tag = code_StackMapTable_T.getByte();
+ putu1(tag);
+ switch (tag)
+ {
+ case 7: // (7) [RCH]
+ putref(code_StackMapTable_RC.getRef());
+ break;
+ case 8: // (8) [PH]
+ putu2(to_bci(code_StackMapTable_P.getInt()));
+ break;
+ }
}
// Functions for writing code.
void unpacker::put_label(int curIP, int size)
{
- code_fixup_type.addByte(size);
- code_fixup_offset.add((int)put_empty(size));
- code_fixup_source.add(curIP);
+ code_fixup_type.addByte(size);
+ code_fixup_offset.add((int)put_empty(size));
+ code_fixup_source.add(curIP);
}
inline // called exactly once => inline
- void
+ void
unpacker::write_bc_ops()
{
- bcimap.empty();
- code_fixup_type.empty();
- code_fixup_offset.empty();
- code_fixup_source.empty();
-
- band *bc_which;
-
- byte *opptr = bc_codes.curRP();
- // No need for oplimit, since the codes are pre-counted.
-
- size_t codeBase = wpoffset();
-
- bool isAload; // copy-out result
- int origBC;
-
- entry *thisClass = cur_class;
- entry *superClass = cur_super;
- entry *newClass = nullptr; // class of last _new opcode
-
- // overwrite any prior index on these bands; it changes w/ current class:
- bc_thisfield.setIndex(cp.getFieldIndex(thisClass));
- bc_thismethod.setIndex(cp.getMethodIndex(thisClass));
- if (superClass != nullptr)
- {
- bc_superfield.setIndex(cp.getFieldIndex(superClass));
- bc_supermethod.setIndex(cp.getMethodIndex(superClass));
- }
-
- for (int curIP = 0;; curIP++)
- {
- int curPC = (int)(wpoffset() - codeBase);
- bcimap.add(curPC);
- ensure_put_space(10); // covers most instrs w/o further bounds check
- int bc = *opptr++ & 0xFF;
-
- putu1_fast(bc);
- // Note: See '--wp' below for pseudo-bytecodes like bc_end_marker.
-
- bool isWide = false;
- if (bc == bc_wide)
- {
- bc = *opptr++ & 0xFF;
- putu1_fast(bc);
- isWide = true;
- }
- switch (bc)
- {
- case bc_end_marker:
- --wp; // not really part of the code
- assert(opptr <= bc_codes.maxRP());
- bc_codes.curRP() = opptr; // advance over this in bc_codes
- goto doneScanningMethod;
- case bc_tableswitch: // apc: (df, lo, hi, (hi-lo+1)*(label))
- case bc_lookupswitch: // apc: (df, nc, nc*(case, label))
- {
- int caseCount = bc_case_count.getInt();
- while (((wpoffset() - codeBase) % 4) != 0)
- putu1_fast(0);
- ensure_put_space(30 + caseCount * 8);
- put_label(curIP, 4); // int df = bc_label.getInt();
- if (bc == bc_tableswitch)
- {
- int lo = bc_case_value.getInt();
- int hi = lo + caseCount - 1;
- putu4(lo);
- putu4(hi);
- for (int j = 0; j < caseCount; j++)
- {
- put_label(curIP, 4); // int lVal = bc_label.getInt();
- // int cVal = lo + j;
- }
- }
- else
- {
- putu4(caseCount);
- for (int j = 0; j < caseCount; j++)
- {
- int cVal = bc_case_value.getInt();
- putu4(cVal);
- put_label(curIP, 4); // int lVal = bc_label.getInt();
- }
- }
- assert((int)to_bci(curIP) == curPC);
- continue;
- }
- case bc_iinc:
- {
- int local = bc_local.getInt();
- int delta = (isWide ? bc_short : bc_byte).getInt();
- if (isWide)
- {
- putu2(local);
- putu2(delta);
- }
- else
- {
- putu1_fast(local);
- putu1_fast(delta);
- }
- continue;
- }
- case bc_sipush:
- {
- int val = bc_short.getInt();
- putu2(val);
- continue;
- }
- case bc_bipush:
- case bc_newarray:
- {
- int val = bc_byte.getByte();
- putu1_fast(val);
- continue;
- }
- case bc_ref_escape:
- {
- // Note that insnMap has one entry for this.
- --wp; // not really part of the code
- int size = bc_escrefsize.getInt();
- entry *ref = bc_escref.getRefN();
- switch (size)
- {
- case 1:
- putu1ref(ref);
- break;
- case 2:
- putref(ref);
- break;
- default:
- assert(false);
- }
- continue;
- }
- case bc_byte_escape:
- {
- // Note that insnMap has one entry for all these bytes.
- --wp; // not really part of the code
- int size = bc_escsize.getInt();
- ensure_put_space(size);
- for (int j = 0; j < size; j++)
- putu1_fast(bc_escbyte.getByte());
- continue;
- }
- default:
- if (is_invoke_init_op(bc))
- {
- origBC = bc_invokespecial;
- entry *classRef;
- switch (bc - _invokeinit_op)
- {
- case _invokeinit_self_option:
- classRef = thisClass;
- break;
- case _invokeinit_super_option:
- classRef = superClass;
- break;
- default:
- assert(bc == _invokeinit_op + _invokeinit_new_option);
- case _invokeinit_new_option:
- classRef = newClass;
- break;
- }
- wp[-1] = origBC; // overwrite with origBC
- int coding = bc_initref.getInt();
- // Find the nth overloading of <init> in classRef.
- entry *ref = nullptr;
- cpindex *ix = (classRef == nullptr) ? nullptr : cp.getMethodIndex(classRef);
- for (int j = 0, which_init = 0;; j++)
- {
- ref = (ix == nullptr) ? nullptr : ix->get(j);
- if (ref == nullptr)
- break; // oops, bad input
- assert(ref->tag == CONSTANT_Methodref);
- if (ref->memberDescr()->descrName() == cp.sym[constant_pool::s_lt_init_gt])
- {
- if (which_init++ == coding)
- break;
- }
- }
- putref(ref);
- continue;
- }
- bc_which = ref_band_for_self_op(bc, isAload, origBC);
- if (bc_which != nullptr)
- {
- if (!isAload)
- {
- wp[-1] = origBC; // overwrite with origBC
- }
- else
- {
- wp[-1] = bc_aload_0; // overwrite with _aload_0
- // Note: insnMap keeps the _aload_0 separate.
- bcimap.add(++curPC);
- ++curIP;
- putu1_fast(origBC);
- }
- entry *ref = bc_which->getRef();
- putref(ref);
- continue;
- }
- if (is_branch_op(bc))
- {
- // int lVal = bc_label.getInt();
- if (bc < bc_goto_w)
- {
- put_label(curIP, 2); // putu2(lVal & 0xFFFF);
- }
- else
- {
- assert(bc <= bc_jsr_w);
- put_label(curIP, 4); // putu4(lVal);
- }
- assert((int)to_bci(curIP) == curPC);
- continue;
- }
- bc_which = ref_band_for_op(bc);
- if (bc_which != nullptr)
- {
- entry *ref = bc_which->getRefCommon(bc_which->ix, bc_which->nullOK);
- if (ref == nullptr && bc_which == &bc_classref)
- {
- // Shorthand for class self-references.
- ref = thisClass;
- }
- origBC = bc;
- switch (bc)
- {
- case bc_ildc:
- case bc_cldc:
- case bc_fldc:
- case bc_aldc:
- origBC = bc_ldc;
- break;
- case bc_ildc_w:
- case bc_cldc_w:
- case bc_fldc_w:
- case bc_aldc_w:
- origBC = bc_ldc_w;
- break;
- case bc_lldc2_w:
- case bc_dldc2_w:
- origBC = bc_ldc2_w;
- break;
- case bc_new:
- newClass = ref;
- break;
- }
- wp[-1] = origBC; // overwrite with origBC
- if (origBC == bc_ldc)
- {
- putu1ref(ref);
- }
- else
- {
- putref(ref);
- }
- if (origBC == bc_multianewarray)
- {
- // Copy the trailing byte also.
- int val = bc_byte.getByte();
- putu1_fast(val);
- }
- else if (origBC == bc_invokeinterface)
- {
- int argSize = ref->memberDescr()->descrType()->typeSize();
- putu1_fast(1 + argSize);
- putu1_fast(0);
- }
- continue;
- }
- if (is_local_slot_op(bc))
- {
- int local = bc_local.getInt();
- if (isWide)
- {
- putu2(local);
- if (bc == bc_iinc)
- {
- int iVal = bc_short.getInt();
- putu2(iVal);
- }
- }
- else
- {
- putu1_fast(local);
- if (bc == bc_iinc)
- {
- int iVal = bc_byte.getByte();
- putu1_fast(iVal);
- }
- }
- continue;
- }
- // Random bytecode. Just copy it.
- assert(bc < bc_bytecode_limit);
- }
- }
+ bcimap.empty();
+ code_fixup_type.empty();
+ code_fixup_offset.empty();
+ code_fixup_source.empty();
+
+ band *bc_which;
+
+ byte *opptr = bc_codes.curRP();
+ // No need for oplimit, since the codes are pre-counted.
+
+ size_t codeBase = wpoffset();
+
+ bool isAload; // copy-out result
+ int origBC;
+
+ entry *thisClass = cur_class;
+ entry *superClass = cur_super;
+ entry *newClass = nullptr; // class of last _new opcode
+
+ // overwrite any prior index on these bands; it changes w/ current class:
+ bc_thisfield.setIndex(cp.getFieldIndex(thisClass));
+ bc_thismethod.setIndex(cp.getMethodIndex(thisClass));
+ if (superClass != nullptr)
+ {
+ bc_superfield.setIndex(cp.getFieldIndex(superClass));
+ bc_supermethod.setIndex(cp.getMethodIndex(superClass));
+ }
+
+ for (int curIP = 0;; curIP++)
+ {
+ int curPC = (int)(wpoffset() - codeBase);
+ bcimap.add(curPC);
+ ensure_put_space(10); // covers most instrs w/o further bounds check
+ int bc = *opptr++ & 0xFF;
+
+ putu1_fast(bc);
+ // Note: See '--wp' below for pseudo-bytecodes like bc_end_marker.
+
+ bool isWide = false;
+ if (bc == bc_wide)
+ {
+ bc = *opptr++ & 0xFF;
+ putu1_fast(bc);
+ isWide = true;
+ }
+ switch (bc)
+ {
+ case bc_end_marker:
+ --wp; // not really part of the code
+ assert(opptr <= bc_codes.maxRP());
+ bc_codes.curRP() = opptr; // advance over this in bc_codes
+ goto doneScanningMethod;
+ case bc_tableswitch: // apc: (df, lo, hi, (hi-lo+1)*(label))
+ case bc_lookupswitch: // apc: (df, nc, nc*(case, label))
+ {
+ int caseCount = bc_case_count.getInt();
+ while (((wpoffset() - codeBase) % 4) != 0)
+ putu1_fast(0);
+ ensure_put_space(30 + caseCount * 8);
+ put_label(curIP, 4); // int df = bc_label.getInt();
+ if (bc == bc_tableswitch)
+ {
+ int lo = bc_case_value.getInt();
+ int hi = lo + caseCount - 1;
+ putu4(lo);
+ putu4(hi);
+ for (int j = 0; j < caseCount; j++)
+ {
+ put_label(curIP, 4); // int lVal = bc_label.getInt();
+ // int cVal = lo + j;
+ }
+ }
+ else
+ {
+ putu4(caseCount);
+ for (int j = 0; j < caseCount; j++)
+ {
+ int cVal = bc_case_value.getInt();
+ putu4(cVal);
+ put_label(curIP, 4); // int lVal = bc_label.getInt();
+ }
+ }
+ assert((int)to_bci(curIP) == curPC);
+ continue;
+ }
+ case bc_iinc:
+ {
+ int local = bc_local.getInt();
+ int delta = (isWide ? bc_short : bc_byte).getInt();
+ if (isWide)
+ {
+ putu2(local);
+ putu2(delta);
+ }
+ else
+ {
+ putu1_fast(local);
+ putu1_fast(delta);
+ }
+ continue;
+ }
+ case bc_sipush:
+ {
+ int val = bc_short.getInt();
+ putu2(val);
+ continue;
+ }
+ case bc_bipush:
+ case bc_newarray:
+ {
+ int val = bc_byte.getByte();
+ putu1_fast(val);
+ continue;
+ }
+ case bc_ref_escape:
+ {
+ // Note that insnMap has one entry for this.
+ --wp; // not really part of the code
+ int size = bc_escrefsize.getInt();
+ entry *ref = bc_escref.getRefN();
+ switch (size)
+ {
+ case 1:
+ putu1ref(ref);
+ break;
+ case 2:
+ putref(ref);
+ break;
+ default:
+ assert(false);
+ }
+ continue;
+ }
+ case bc_byte_escape:
+ {
+ // Note that insnMap has one entry for all these bytes.
+ --wp; // not really part of the code
+ int size = bc_escsize.getInt();
+ ensure_put_space(size);
+ for (int j = 0; j < size; j++)
+ putu1_fast(bc_escbyte.getByte());
+ continue;
+ }
+ default:
+ if (is_invoke_init_op(bc))
+ {
+ origBC = bc_invokespecial;
+ entry *classRef;
+ switch (bc - _invokeinit_op)
+ {
+ case _invokeinit_self_option:
+ classRef = thisClass;
+ break;
+ case _invokeinit_super_option:
+ classRef = superClass;
+ break;
+ default:
+ assert(bc == _invokeinit_op + _invokeinit_new_option);
+ case _invokeinit_new_option:
+ classRef = newClass;
+ break;
+ }
+ wp[-1] = origBC; // overwrite with origBC
+ int coding = bc_initref.getInt();
+ // Find the nth overloading of <init> in classRef.
+ entry *ref = nullptr;
+ cpindex *ix = (classRef == nullptr) ? nullptr : cp.getMethodIndex(classRef);
+ for (int j = 0, which_init = 0;; j++)
+ {
+ ref = (ix == nullptr) ? nullptr : ix->get(j);
+ if (ref == nullptr)
+ break; // oops, bad input
+ assert(ref->tag == CONSTANT_Methodref);
+ if (ref->memberDescr()->descrName() == cp.sym[constant_pool::s_lt_init_gt])
+ {
+ if (which_init++ == coding)
+ break;
+ }
+ }
+ putref(ref);
+ continue;
+ }
+ bc_which = ref_band_for_self_op(bc, isAload, origBC);
+ if (bc_which != nullptr)
+ {
+ if (!isAload)
+ {
+ wp[-1] = origBC; // overwrite with origBC
+ }
+ else
+ {
+ wp[-1] = bc_aload_0; // overwrite with _aload_0
+ // Note: insnMap keeps the _aload_0 separate.
+ bcimap.add(++curPC);
+ ++curIP;
+ putu1_fast(origBC);
+ }
+ entry *ref = bc_which->getRef();
+ putref(ref);
+ continue;
+ }
+ if (is_branch_op(bc))
+ {
+ // int lVal = bc_label.getInt();
+ if (bc < bc_goto_w)
+ {
+ put_label(curIP, 2); // putu2(lVal & 0xFFFF);
+ }
+ else
+ {
+ assert(bc <= bc_jsr_w);
+ put_label(curIP, 4); // putu4(lVal);
+ }
+ assert((int)to_bci(curIP) == curPC);
+ continue;
+ }
+ bc_which = ref_band_for_op(bc);
+ if (bc_which != nullptr)
+ {
+ entry *ref = bc_which->getRefCommon(bc_which->ix, bc_which->nullOK);
+ if (ref == nullptr && bc_which == &bc_classref)
+ {
+ // Shorthand for class self-references.
+ ref = thisClass;
+ }
+ origBC = bc;
+ switch (bc)
+ {
+ case bc_ildc:
+ case bc_cldc:
+ case bc_fldc:
+ case bc_aldc:
+ origBC = bc_ldc;
+ break;
+ case bc_ildc_w:
+ case bc_cldc_w:
+ case bc_fldc_w:
+ case bc_aldc_w:
+ origBC = bc_ldc_w;
+ break;
+ case bc_lldc2_w:
+ case bc_dldc2_w:
+ origBC = bc_ldc2_w;
+ break;
+ case bc_new:
+ newClass = ref;
+ break;
+ }
+ wp[-1] = origBC; // overwrite with origBC
+ if (origBC == bc_ldc)
+ {
+ putu1ref(ref);
+ }
+ else
+ {
+ putref(ref);
+ }
+ if (origBC == bc_multianewarray)
+ {
+ // Copy the trailing byte also.
+ int val = bc_byte.getByte();
+ putu1_fast(val);
+ }
+ else if (origBC == bc_invokeinterface)
+ {
+ int argSize = ref->memberDescr()->descrType()->typeSize();
+ putu1_fast(1 + argSize);
+ putu1_fast(0);
+ }
+ continue;
+ }
+ if (is_local_slot_op(bc))
+ {
+ int local = bc_local.getInt();
+ if (isWide)
+ {
+ putu2(local);
+ if (bc == bc_iinc)
+ {
+ int iVal = bc_short.getInt();
+ putu2(iVal);
+ }
+ }
+ else
+ {
+ putu1_fast(local);
+ if (bc == bc_iinc)
+ {
+ int iVal = bc_byte.getByte();
+ putu1_fast(iVal);
+ }
+ }
+ continue;
+ }
+ // Random bytecode. Just copy it.
+ assert(bc < bc_bytecode_limit);
+ }
+ }
doneScanningMethod:
{
}
- // bcimap.add(curPC); // PC limit is already also in map, from bc_end_marker
-
- // Armed with a bcimap, we can now fix up all the labels.
- for (int i = 0; i < (int)code_fixup_type.size(); i++)
- {
- int type = code_fixup_type.getByte(i);
- byte *bp = wp_at(code_fixup_offset.get(i));
- int curIP = code_fixup_source.get(i);
- int destIP = curIP + bc_label.getInt();
- int span = to_bci(destIP) - to_bci(curIP);
- switch (type)
- {
- case 2:
- putu2_at(bp, (ushort)span);
- break;
- case 4:
- putu4_at(bp, span);
- break;
- default:
- assert(false);
- }
- }
+ // bcimap.add(curPC); // PC limit is already also in map, from bc_end_marker
+
+ // Armed with a bcimap, we can now fix up all the labels.
+ for (int i = 0; i < (int)code_fixup_type.size(); i++)
+ {
+ int type = code_fixup_type.getByte(i);
+ byte *bp = wp_at(code_fixup_offset.get(i));
+ int curIP = code_fixup_source.get(i);
+ int destIP = curIP + bc_label.getInt();
+ int span = to_bci(destIP) - to_bci(curIP);
+ switch (type)
+ {
+ case 2:
+ putu2_at(bp, (ushort)span);
+ break;
+ case 4:
+ putu4_at(bp, span);
+ break;
+ default:
+ assert(false);
+ }
+ }
}
inline // called exactly once => inline
- void
+ void
unpacker::write_code()
{
- int j;
-
- int max_stack, max_locals, handler_count, cflags;
- get_code_header(max_stack, max_locals, handler_count, cflags);
-
- if (max_stack < 0)
- max_stack = code_max_stack.getInt();
- if (max_locals < 0)
- max_locals = code_max_na_locals.getInt();
- if (handler_count < 0)
- handler_count = code_handler_count.getInt();
-
- int siglen = cur_descr->descrType()->typeSize();
- if ((cur_descr_flags & ACC_STATIC) == 0)
- siglen++;
- max_locals += siglen;
-
- putu2(max_stack);
- putu2(max_locals);
- size_t bcbase = put_empty(4);
-
- // Write the bytecodes themselves.
- write_bc_ops();
-
- byte *bcbasewp = wp_at(bcbase);
- putu4_at(bcbasewp, (int)(wp - (bcbasewp + 4))); // size of code attr
-
- putu2(handler_count);
- for (j = 0; j < handler_count; j++)
- {
- int bii = code_handler_start_P.getInt();
- putu2(to_bci(bii));
- bii += code_handler_end_PO.getInt();
- putu2(to_bci(bii));
- bii += code_handler_catch_PO.getInt();
- putu2(to_bci(bii));
- putref(code_handler_class_RCN.getRefN());
- }
-
- uint64_t indexBits = cflags;
- if (cflags < 0)
- {
- bool haveLongFlags = attr_defs[ATTR_CONTEXT_CODE].haveLongFlags();
- indexBits = code_flags_hi.getLong(code_flags_lo, haveLongFlags);
- }
- write_attrs(ATTR_CONTEXT_CODE, indexBits);
+ int j;
+
+ int max_stack, max_locals, handler_count, cflags;
+ get_code_header(max_stack, max_locals, handler_count, cflags);
+
+ if (max_stack < 0)
+ max_stack = code_max_stack.getInt();
+ if (max_locals < 0)
+ max_locals = code_max_na_locals.getInt();
+ if (handler_count < 0)
+ handler_count = code_handler_count.getInt();
+
+ int siglen = cur_descr->descrType()->typeSize();
+ if ((cur_descr_flags & ACC_STATIC) == 0)
+ siglen++;
+ max_locals += siglen;
+
+ putu2(max_stack);
+ putu2(max_locals);
+ size_t bcbase = put_empty(4);
+
+ // Write the bytecodes themselves.
+ write_bc_ops();
+
+ byte *bcbasewp = wp_at(bcbase);
+ putu4_at(bcbasewp, (int)(wp - (bcbasewp + 4))); // size of code attr
+
+ putu2(handler_count);
+ for (j = 0; j < handler_count; j++)
+ {
+ int bii = code_handler_start_P.getInt();
+ putu2(to_bci(bii));
+ bii += code_handler_end_PO.getInt();
+ putu2(to_bci(bii));
+ bii += code_handler_catch_PO.getInt();
+ putu2(to_bci(bii));
+ putref(code_handler_class_RCN.getRefN());
+ }
+
+ uint64_t indexBits = cflags;
+ if (cflags < 0)
+ {
+ bool haveLongFlags = attr_defs[ATTR_CONTEXT_CODE].haveLongFlags();
+ indexBits = code_flags_hi.getLong(code_flags_lo, haveLongFlags);
+ }
+ write_attrs(ATTR_CONTEXT_CODE, indexBits);
}
int unpacker::write_attrs(int attrc, uint64_t indexBits)
{
- if (indexBits == 0)
- {
- // Quick short-circuit.
- putu2(0);
- return 0;
- }
-
- attr_definitions &ad = attr_defs[attrc];
-
- int i, j, j2, idx, count;
-
- int oiCount = 0;
- if (ad.isPredefined(X_ATTR_OVERFLOW) && (indexBits & ((uint64_t)1 << X_ATTR_OVERFLOW)) != 0)
- {
- indexBits -= ((uint64_t)1 << X_ATTR_OVERFLOW);
- oiCount = ad.xxx_attr_count().getInt();
- }
-
- int bitIndexes[X_ATTR_LIMIT_FLAGS_HI];
- int biCount = 0;
-
- // Fill bitIndexes with index bits, in order.
- for (idx = 0; indexBits != 0; idx++, indexBits >>= 1)
- {
- if ((indexBits & 1) != 0)
- bitIndexes[biCount++] = idx;
- }
- assert(biCount <= (int)lengthof(bitIndexes));
-
- // Write a provisional attribute count, perhaps to be corrected later.
- int naOffset = (int)wpoffset();
- int na0 = biCount + oiCount;
- putu2(na0);
-
- int na = 0;
- for (i = 0; i < na0; i++)
- {
- if (i < biCount)
- idx = bitIndexes[i];
- else
- idx = ad.xxx_attr_indexes().getInt();
- assert(ad.isIndex(idx));
- entry *aname = nullptr;
- entry *ref; // scratch
- size_t abase = put_empty(2 + 4);
- if (idx < (int)ad.flag_limit && ad.isPredefined(idx))
- {
- // Switch on the attrc and idx simultaneously.
- switch (ADH_BYTE(attrc, idx))
- {
-
- case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_OVERFLOW) :
- case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_OVERFLOW) :
- case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_OVERFLOW) :
- case ADH_BYTE(ATTR_CONTEXT_CODE, X_ATTR_OVERFLOW) :
- // no attribute at all, so back up on this one
- wp = wp_at(abase);
- continue;
-
- case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_ClassFile_version) :
- cur_class_minver = class_ClassFile_version_minor_H.getInt();
- cur_class_majver = class_ClassFile_version_major_H.getInt();
- // back up; not a real attribute
- wp = wp_at(abase);
- continue;
-
- case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_InnerClasses) :
- // note the existence of this attr, but save for later
- if (cur_class_has_local_ics)
- unpack_abort("too many InnerClasses attrs");
- cur_class_has_local_ics = true;
- wp = wp_at(abase);
- continue;
-
- case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_SourceFile) :
- aname = cp.sym[constant_pool::s_SourceFile];
- ref = class_SourceFile_RUN.getRefN();
- if (ref == nullptr)
- {
- bytes &n = cur_class->ref(0)->value.b;
- // parse n = (<pkg>/)*<outer>?($<id>)*
- int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, (int)n.len) + 1;
- bytes prefix = n.slice(pkglen, n.len);
- for (;;)
- {
- // Work backwards, finding all '$', '#', etc.
- int dollar =
- lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, prefix, (int)prefix.len);
- if (dollar < 0)
- break;
- prefix = prefix.slice(0, dollar);
- }
- const char *suffix = ".java";
- int len = (int)(prefix.len + strlen(suffix));
- bytes name;
- name.set(T_NEW(byte, add_size(len, 1)), len);
- name.strcat(prefix).strcat(suffix);
- ref = cp.ensureUtf8(name);
- }
- putref(ref);
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod) :
- aname = cp.sym[constant_pool::s_EnclosingMethod];
- putref(class_EnclosingMethod_RC.getRefN());
- putref(class_EnclosingMethod_RDN.getRefN());
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_FIELD, FIELD_ATTR_ConstantValue) :
- aname = cp.sym[constant_pool::s_ConstantValue];
- putref(field_ConstantValue_KQ.getRefUsing(cp.getKQIndex()));
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Code) :
- aname = cp.sym[constant_pool::s_Code];
- write_code();
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Exceptions) :
- aname = cp.sym[constant_pool::s_Exceptions];
- putu2(count = method_Exceptions_N.getInt());
- for (j = 0; j < count; j++)
- {
- putref(method_Exceptions_RC.getRefN());
- }
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_StackMapTable) :
- aname = cp.sym[constant_pool::s_StackMapTable];
- // (keep this code aligned with its brother in unpacker::read_attrs)
- putu2(count = code_StackMapTable_N.getInt());
- for (j = 0; j < count; j++)
- {
- int tag = code_StackMapTable_frame_T.getByte();
- putu1(tag);
- if (tag <= 127)
- {
- // (64-127) [(2)]
- if (tag >= 64)
- put_stackmap_type();
- }
- else if (tag <= 251)
- {
- // (247) [(1)(2)]
- // (248-251) [(1)]
- if (tag >= 247)
- putu2(code_StackMapTable_offset.getInt());
- if (tag == 247)
- put_stackmap_type();
- }
- else if (tag <= 254)
- {
- // (252) [(1)(2)]
- // (253) [(1)(2)(2)]
- // (254) [(1)(2)(2)(2)]
- putu2(code_StackMapTable_offset.getInt());
- for (int k = (tag - 251); k > 0; k--)
- {
- put_stackmap_type();
- }
- }
- else
- {
- // (255) [(1)NH[(2)]NH[(2)]]
- putu2(code_StackMapTable_offset.getInt());
- putu2(j2 = code_StackMapTable_local_N.getInt());
- while (j2-- > 0)
- put_stackmap_type();
- putu2(j2 = code_StackMapTable_stack_N.getInt());
- while (j2-- > 0)
- put_stackmap_type();
- }
- }
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LineNumberTable) :
- aname = cp.sym[constant_pool::s_LineNumberTable];
- putu2(count = code_LineNumberTable_N.getInt());
- for (j = 0; j < count; j++)
- {
- putu2(to_bci(code_LineNumberTable_bci_P.getInt()));
- putu2(code_LineNumberTable_line.getInt());
- }
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTable) :
- aname = cp.sym[constant_pool::s_LocalVariableTable];
- putu2(count = code_LocalVariableTable_N.getInt());
- for (j = 0; j < count; j++)
- {
- int bii = code_LocalVariableTable_bci_P.getInt();
- int bci = to_bci(bii);
- putu2(bci);
- bii += code_LocalVariableTable_span_O.getInt();
- putu2(to_bci(bii) - bci);
- putref(code_LocalVariableTable_name_RU.getRefN());
- putref(code_LocalVariableTable_type_RS.getRefN());
- putu2(code_LocalVariableTable_slot.getInt());
- }
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTypeTable) :
- aname = cp.sym[constant_pool::s_LocalVariableTypeTable];
- putu2(count = code_LocalVariableTypeTable_N.getInt());
- for (j = 0; j < count; j++)
- {
- int bii = code_LocalVariableTypeTable_bci_P.getInt();
- int bci = to_bci(bii);
- putu2(bci);
- bii += code_LocalVariableTypeTable_span_O.getInt();
- putu2(to_bci(bii) - bci);
- putref(code_LocalVariableTypeTable_name_RU.getRefN());
- putref(code_LocalVariableTypeTable_type_RS.getRefN());
- putu2(code_LocalVariableTypeTable_slot.getInt());
- }
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Signature) :
- aname = cp.sym[constant_pool::s_Signature];
- putref(class_Signature_RS.getRefN());
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Signature) :
- aname = cp.sym[constant_pool::s_Signature];
- putref(field_Signature_RS.getRefN());
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Signature) :
- aname = cp.sym[constant_pool::s_Signature];
- putref(method_Signature_RS.getRefN());
- break;
-
- case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Deprecated) :
- case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Deprecated) :
- case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Deprecated) :
- aname = cp.sym[constant_pool::s_Deprecated];
- // no data
- break;
- }
- }
-
- if (aname == nullptr)
- {
- // Unparse a compressor-defined attribute.
- layout_definition *lo = ad.getLayout(idx);
- if (lo == nullptr)
- {
- unpack_abort("bad layout index");
- break;
- }
- assert((int)lo->idx == idx);
- aname = lo->nameEntry;
- if (aname == nullptr)
- {
- bytes nameb;
- nameb.set(lo->name);
- aname = cp.ensureUtf8(nameb);
- // Cache the name entry for next time.
- lo->nameEntry = aname;
- }
- // Execute all the layout elements.
- band **bands = lo->bands();
- if (lo->hasCallables())
- {
- band &cble = *bands[0];
- assert(cble.le_kind == EK_CBLE);
- bands = cble.le_body;
- }
- putlayout(bands);
- }
-
- if (aname == nullptr)
- unpack_abort("bad attribute index");
-
- byte *wp1 = wp;
- wp = wp_at(abase);
-
- // DTRT if this attr is on the strip-list.
- // (Note that we emptied the data out of the band first.)
- if (ad.strip_names.contains(aname))
- {
- continue;
- }
-
- // patch the name and length
- putref(aname);
- putu4((int)(wp1 - (wp + 4))); // put the attr size
- wp = wp1;
- na++; // count the attrs actually written
- }
-
- if (na != na0)
- // Refresh changed count.
- putu2_at(wp_at(naOffset), na);
- return na;
+ if (indexBits == 0)
+ {
+ // Quick short-circuit.
+ putu2(0);
+ return 0;
+ }
+
+ attr_definitions &ad = attr_defs[attrc];
+
+ int i, j, j2, idx, count;
+
+ int oiCount = 0;
+ if (ad.isPredefined(X_ATTR_OVERFLOW) && (indexBits & ((uint64_t)1 << X_ATTR_OVERFLOW)) != 0)
+ {
+ indexBits -= ((uint64_t)1 << X_ATTR_OVERFLOW);
+ oiCount = ad.xxx_attr_count().getInt();
+ }
+
+ int bitIndexes[X_ATTR_LIMIT_FLAGS_HI];
+ int biCount = 0;
+
+ // Fill bitIndexes with index bits, in order.
+ for (idx = 0; indexBits != 0; idx++, indexBits >>= 1)
+ {
+ if ((indexBits & 1) != 0)
+ bitIndexes[biCount++] = idx;
+ }
+ assert(biCount <= (int)lengthof(bitIndexes));
+
+ // Write a provisional attribute count, perhaps to be corrected later.
+ int naOffset = (int)wpoffset();
+ int na0 = biCount + oiCount;
+ putu2(na0);
+
+ int na = 0;
+ for (i = 0; i < na0; i++)
+ {
+ if (i < biCount)
+ idx = bitIndexes[i];
+ else
+ idx = ad.xxx_attr_indexes().getInt();
+ assert(ad.isIndex(idx));
+ entry *aname = nullptr;
+ entry *ref; // scratch
+ size_t abase = put_empty(2 + 4);
+ if (idx < (int)ad.flag_limit && ad.isPredefined(idx))
+ {
+ // Switch on the attrc and idx simultaneously.
+ switch (ADH_BYTE(attrc, idx))
+ {
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_OVERFLOW) :
+ case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_OVERFLOW) :
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_OVERFLOW) :
+ case ADH_BYTE(ATTR_CONTEXT_CODE, X_ATTR_OVERFLOW) :
+ // no attribute at all, so back up on this one
+ wp = wp_at(abase);
+ continue;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_ClassFile_version) :
+ cur_class_minver = class_ClassFile_version_minor_H.getInt();
+ cur_class_majver = class_ClassFile_version_major_H.getInt();
+ // back up; not a real attribute
+ wp = wp_at(abase);
+ continue;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_InnerClasses) :
+ // note the existence of this attr, but save for later
+ if (cur_class_has_local_ics)
+ unpack_abort("too many InnerClasses attrs");
+ cur_class_has_local_ics = true;
+ wp = wp_at(abase);
+ continue;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_SourceFile) :
+ aname = cp.sym[constant_pool::s_SourceFile];
+ ref = class_SourceFile_RUN.getRefN();
+ if (ref == nullptr)
+ {
+ bytes &n = cur_class->ref(0)->value.b;
+ // parse n = (<pkg>/)*<outer>?($<id>)*
+ int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, (int)n.len) + 1;
+ bytes prefix = n.slice(pkglen, n.len);
+ for (;;)
+ {
+ // Work backwards, finding all '$', '#', etc.
+ int dollar =
+ lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, prefix, (int)prefix.len);
+ if (dollar < 0)
+ break;
+ prefix = prefix.slice(0, dollar);
+ }
+ const char *suffix = ".java";
+ int len = (int)(prefix.len + strlen(suffix));
+ bytes name;
+ name.set(T_NEW(byte, add_size(len, 1)), len);
+ name.strcat(prefix).strcat(suffix);
+ ref = cp.ensureUtf8(name);
+ }
+ putref(ref);
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod) :
+ aname = cp.sym[constant_pool::s_EnclosingMethod];
+ putref(class_EnclosingMethod_RC.getRefN());
+ putref(class_EnclosingMethod_RDN.getRefN());
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_FIELD, FIELD_ATTR_ConstantValue) :
+ aname = cp.sym[constant_pool::s_ConstantValue];
+ putref(field_ConstantValue_KQ.getRefUsing(cp.getKQIndex()));
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Code) :
+ aname = cp.sym[constant_pool::s_Code];
+ write_code();
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Exceptions) :
+ aname = cp.sym[constant_pool::s_Exceptions];
+ putu2(count = method_Exceptions_N.getInt());
+ for (j = 0; j < count; j++)
+ {
+ putref(method_Exceptions_RC.getRefN());
+ }
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_StackMapTable) :
+ aname = cp.sym[constant_pool::s_StackMapTable];
+ // (keep this code aligned with its brother in unpacker::read_attrs)
+ putu2(count = code_StackMapTable_N.getInt());
+ for (j = 0; j < count; j++)
+ {
+ int tag = code_StackMapTable_frame_T.getByte();
+ putu1(tag);
+ if (tag <= 127)
+ {
+ // (64-127) [(2)]
+ if (tag >= 64)
+ put_stackmap_type();
+ }
+ else if (tag <= 251)
+ {
+ // (247) [(1)(2)]
+ // (248-251) [(1)]
+ if (tag >= 247)
+ putu2(code_StackMapTable_offset.getInt());
+ if (tag == 247)
+ put_stackmap_type();
+ }
+ else if (tag <= 254)
+ {
+ // (252) [(1)(2)]
+ // (253) [(1)(2)(2)]
+ // (254) [(1)(2)(2)(2)]
+ putu2(code_StackMapTable_offset.getInt());
+ for (int k = (tag - 251); k > 0; k--)
+ {
+ put_stackmap_type();
+ }
+ }
+ else
+ {
+ // (255) [(1)NH[(2)]NH[(2)]]
+ putu2(code_StackMapTable_offset.getInt());
+ putu2(j2 = code_StackMapTable_local_N.getInt());
+ while (j2-- > 0)
+ put_stackmap_type();
+ putu2(j2 = code_StackMapTable_stack_N.getInt());
+ while (j2-- > 0)
+ put_stackmap_type();
+ }
+ }
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LineNumberTable) :
+ aname = cp.sym[constant_pool::s_LineNumberTable];
+ putu2(count = code_LineNumberTable_N.getInt());
+ for (j = 0; j < count; j++)
+ {
+ putu2(to_bci(code_LineNumberTable_bci_P.getInt()));
+ putu2(code_LineNumberTable_line.getInt());
+ }
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTable) :
+ aname = cp.sym[constant_pool::s_LocalVariableTable];
+ putu2(count = code_LocalVariableTable_N.getInt());
+ for (j = 0; j < count; j++)
+ {
+ int bii = code_LocalVariableTable_bci_P.getInt();
+ int bci = to_bci(bii);
+ putu2(bci);
+ bii += code_LocalVariableTable_span_O.getInt();
+ putu2(to_bci(bii) - bci);
+ putref(code_LocalVariableTable_name_RU.getRefN());
+ putref(code_LocalVariableTable_type_RS.getRefN());
+ putu2(code_LocalVariableTable_slot.getInt());
+ }
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTypeTable) :
+ aname = cp.sym[constant_pool::s_LocalVariableTypeTable];
+ putu2(count = code_LocalVariableTypeTable_N.getInt());
+ for (j = 0; j < count; j++)
+ {
+ int bii = code_LocalVariableTypeTable_bci_P.getInt();
+ int bci = to_bci(bii);
+ putu2(bci);
+ bii += code_LocalVariableTypeTable_span_O.getInt();
+ putu2(to_bci(bii) - bci);
+ putref(code_LocalVariableTypeTable_name_RU.getRefN());
+ putref(code_LocalVariableTypeTable_type_RS.getRefN());
+ putu2(code_LocalVariableTypeTable_slot.getInt());
+ }
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Signature) :
+ aname = cp.sym[constant_pool::s_Signature];
+ putref(class_Signature_RS.getRefN());
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Signature) :
+ aname = cp.sym[constant_pool::s_Signature];
+ putref(field_Signature_RS.getRefN());
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Signature) :
+ aname = cp.sym[constant_pool::s_Signature];
+ putref(method_Signature_RS.getRefN());
+ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Deprecated) :
+ case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Deprecated) :
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Deprecated) :
+ aname = cp.sym[constant_pool::s_Deprecated];
+ // no data
+ break;
+ }
+ }
+
+ if (aname == nullptr)
+ {
+ // Unparse a compressor-defined attribute.
+ layout_definition *lo = ad.getLayout(idx);
+ if (lo == nullptr)
+ {
+ unpack_abort("bad layout index");
+ break;
+ }
+ assert((int)lo->idx == idx);
+ aname = lo->nameEntry;
+ if (aname == nullptr)
+ {
+ bytes nameb;
+ nameb.set(lo->name);
+ aname = cp.ensureUtf8(nameb);
+ // Cache the name entry for next time.
+ lo->nameEntry = aname;
+ }
+ // Execute all the layout elements.
+ band **bands = lo->bands();
+ if (lo->hasCallables())
+ {
+ band &cble = *bands[0];
+ assert(cble.le_kind == EK_CBLE);
+ bands = cble.le_body;
+ }
+ putlayout(bands);
+ }
+
+ if (aname == nullptr)
+ unpack_abort("bad attribute index");
+
+ byte *wp1 = wp;
+ wp = wp_at(abase);
+
+ // DTRT if this attr is on the strip-list.
+ // (Note that we emptied the data out of the band first.)
+ if (ad.strip_names.contains(aname))
+ {
+ continue;
+ }
+
+ // patch the name and length
+ putref(aname);
+ putu4((int)(wp1 - (wp + 4))); // put the attr size
+ wp = wp1;
+ na++; // count the attrs actually written
+ }
+
+ if (na != na0)
+ // Refresh changed count.
+ putu2_at(wp_at(naOffset), na);
+ return na;
}
void unpacker::write_members(int num, int attrc)
{
- attr_definitions &ad = attr_defs[attrc];
- band &member_flags_hi = ad.xxx_flags_hi();
- band &member_flags_lo = ad.xxx_flags_lo();
- band &member_descr = (&member_flags_hi)[e_field_descr - e_field_flags_hi];
- bool haveLongFlags = ad.haveLongFlags();
-
- putu2(num);
- uint64_t indexMask = attr_defs[attrc].flagIndexMask();
- for (int i = 0; i < num; i++)
- {
- uint64_t mflags = member_flags_hi.getLong(member_flags_lo, haveLongFlags);
- entry *mdescr = member_descr.getRef();
- cur_descr = mdescr;
- putu2(cur_descr_flags = (ushort)(mflags & ~indexMask));
- putref(mdescr->descrName());
- putref(mdescr->descrType());
- write_attrs(attrc, (mflags & indexMask));
- }
- cur_descr = nullptr;
+ attr_definitions &ad = attr_defs[attrc];
+ band &member_flags_hi = ad.xxx_flags_hi();
+ band &member_flags_lo = ad.xxx_flags_lo();
+ band &member_descr = (&member_flags_hi)[e_field_descr - e_field_flags_hi];
+ bool haveLongFlags = ad.haveLongFlags();
+
+ putu2(num);
+ uint64_t indexMask = attr_defs[attrc].flagIndexMask();
+ for (int i = 0; i < num; i++)
+ {
+ uint64_t mflags = member_flags_hi.getLong(member_flags_lo, haveLongFlags);
+ entry *mdescr = member_descr.getRef();
+ cur_descr = mdescr;
+ putu2(cur_descr_flags = (ushort)(mflags & ~indexMask));
+ putref(mdescr->descrName());
+ putref(mdescr->descrType());
+ write_attrs(attrc, (mflags & indexMask));
+ }
+ cur_descr = nullptr;
}
extern "C" int raw_address_cmp(const void *p1p, const void *p2p)
{
- void *p1 = *(void **)p1p;
- void *p2 = *(void **)p2p;
- return (p1 > p2) ? 1 : (p1 < p2) ? -1 : 0;
+ void *p1 = *(void **)p1p;
+ void *p2 = *(void **)p2p;
+ return (p1 > p2) ? 1 : (p1 < p2) ? -1 : 0;
}
void unpacker::write_classfile_tail()
{
- cur_classfile_tail.empty();
- set_output(&cur_classfile_tail);
+ cur_classfile_tail.empty();
+ set_output(&cur_classfile_tail);
- int i, num;
+ int i, num;
- attr_definitions &ad = attr_defs[ATTR_CONTEXT_CLASS];
+ attr_definitions &ad = attr_defs[ATTR_CONTEXT_CLASS];
- bool haveLongFlags = ad.haveLongFlags();
- uint64_t kflags = class_flags_hi.getLong(class_flags_lo, haveLongFlags);
- uint64_t indexMask = ad.flagIndexMask();
+ bool haveLongFlags = ad.haveLongFlags();
+ uint64_t kflags = class_flags_hi.getLong(class_flags_lo, haveLongFlags);
+ uint64_t indexMask = ad.flagIndexMask();
- cur_class = class_this.getRef();
- cur_super = class_super.getRef();
+ cur_class = class_this.getRef();
+ cur_super = class_super.getRef();
- if (cur_super == cur_class)
- cur_super = nullptr;
- // special representation for java/lang/Object
+ if (cur_super == cur_class)
+ cur_super = nullptr;
+ // special representation for java/lang/Object
- putu2((ushort)(kflags & ~indexMask));
- putref(cur_class);
- putref(cur_super);
+ putu2((ushort)(kflags & ~indexMask));
+ putref(cur_class);
+ putref(cur_super);
- putu2(num = class_interface_count.getInt());
- for (i = 0; i < num; i++)
- {
- putref(class_interface.getRef());
- }
+ putu2(num = class_interface_count.getInt());
+ for (i = 0; i < num; i++)
+ {
+ putref(class_interface.getRef());
+ }
- write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD);
- write_members(class_method_count.getInt(), ATTR_CONTEXT_METHOD);
+ write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD);
+ write_members(class_method_count.getInt(), ATTR_CONTEXT_METHOD);
- cur_class_has_local_ics = false; // may be set true by write_attrs
+ cur_class_has_local_ics = false; // may be set true by write_attrs
- int naOffset = (int)wpoffset();
- int na = write_attrs(ATTR_CONTEXT_CLASS, (kflags & indexMask));
+ int naOffset = (int)wpoffset();
+ int na = write_attrs(ATTR_CONTEXT_CLASS, (kflags & indexMask));
// at the very last, choose which inner classes (if any) pertain to k:
#ifdef ASSERT
- for (i = 0; i < ic_count; i++)
- {
- assert(!ics[i].requested);
- }
+ for (i = 0; i < ic_count; i++)
+ {
+ assert(!ics[i].requested);
+ }
#endif
- // First, consult the global table and the local constant pool,
- // and decide on the globally implied inner classes.
- // (Note that we read the cpool's outputIndex fields, but we
- // do not yet write them, since the local IC attribute might
- // reverse a global decision to declare an IC.)
- assert(requested_ics.length() == 0); // must start out empty
- // Always include all members of the current class.
- for (inner_class *child = cp.getFirstChildIC(cur_class); child != nullptr;
- child = cp.getNextChildIC(child))
- {
- child->requested = true;
- requested_ics.add(child);
- }
- // And, for each inner class mentioned in the constant pool,
- // include it and all its outers.
- int noes = cp.outputEntries.length();
- entry **oes = (entry **)cp.outputEntries.base();
- for (i = 0; i < noes; i++)
- {
- entry &e = *oes[i];
- if (e.tag != CONSTANT_Class)
- continue; // wrong sort
- for (inner_class *ic = cp.getIC(&e); ic != nullptr; ic = cp.getIC(ic->outer))
- {
- if (ic->requested)
- break; // already processed
- ic->requested = true;
- requested_ics.add(ic);
- }
- }
- int local_ics = requested_ics.length();
- // Second, consult a local attribute (if any) and adjust the global set.
- inner_class *extra_ics = nullptr;
- int num_extra_ics = 0;
- if (cur_class_has_local_ics)
- {
- // adjust the set of ICs by symmetric set difference w/ the locals
- num_extra_ics = class_InnerClasses_N.getInt();
- if (num_extra_ics == 0)
- {
- // Explicit zero count has an irregular meaning: It deletes the attr.
- local_ics = 0; // (short-circuit all tests of requested bits)
- }
- else
- {
- extra_ics = T_NEW(inner_class, num_extra_ics);
- // Note: extra_ics will be freed up by next call to get_next_file().
- }
- }
- for (i = 0; i < num_extra_ics; i++)
- {
- inner_class &extra_ic = extra_ics[i];
- extra_ic.inner = class_InnerClasses_RC.getRef();
- // Find the corresponding equivalent global IC:
- inner_class *global_ic = cp.getIC(extra_ic.inner);
- int flags = class_InnerClasses_F.getInt();
- if (flags == 0)
- {
- // The extra IC is simply a copy of a global IC.
- if (global_ic == nullptr)
- {
- unpack_abort("bad reference to inner class");
- break;
- }
- extra_ic = (*global_ic); // fill in rest of fields
- }
- else
- {
- flags &= ~ACC_IC_LONG_FORM; // clear high bit if set to get clean zero
- extra_ic.flags = flags;
- extra_ic.outer = class_InnerClasses_outer_RCN.getRefN();
- extra_ic.name = class_InnerClasses_name_RUN.getRefN();
- // Detect if this is an exact copy of the global tuple.
- if (global_ic != nullptr)
- {
- if (global_ic->flags != extra_ic.flags || global_ic->outer != extra_ic.outer ||
- global_ic->name != extra_ic.name)
- {
- global_ic = nullptr; // not really the same, so break the link
- }
- }
- }
- if (global_ic != nullptr && global_ic->requested)
- {
- // This local repetition reverses the globally implied request.
- global_ic->requested = false;
- extra_ic.requested = false;
- local_ics -= 1;
- }
- else
- {
- // The global either does not exist, or is not yet requested.
- extra_ic.requested = true;
- local_ics += 1;
- }
- }
- // Finally, if there are any that survived, put them into an attribute.
- // (Note that a zero-count attribute is always deleted.)
- // The putref calls below will tell the constant pool to add any
- // necessary local CP references to support the InnerClasses attribute.
- // This step must be the last round of additions to the local CP.
- if (local_ics > 0)
- {
- // append the new attribute:
- putref(cp.sym[constant_pool::s_InnerClasses]);
- putu4(2 + 2 * 4 * local_ics);
- putu2(local_ics);
- PTRLIST_QSORT(requested_ics, raw_address_cmp);
- int num_global_ics = requested_ics.length();
- for (i = -num_global_ics; i < num_extra_ics; i++)
- {
- inner_class *ic;
- if (i < 0)
- ic = (inner_class *)requested_ics.get(num_global_ics + i);
- else
- ic = &extra_ics[i];
- if (ic->requested)
- {
- putref(ic->inner);
- putref(ic->outer);
- putref(ic->name);
- putu2(ic->flags);
- }
- }
- putu2_at(wp_at(naOffset), ++na); // increment class attr count
- }
-
- // Tidy up global 'requested' bits:
- for (i = requested_ics.length(); --i >= 0;)
- {
- inner_class *ic = (inner_class *)requested_ics.get(i);
- ic->requested = false;
- }
- requested_ics.empty();
-
- close_output();
-
- // rewrite CP references in the tail
- cp.computeOutputIndexes();
- int nextref = 0;
- for (i = 0; i < (int)class_fixup_type.size(); i++)
- {
- int type = class_fixup_type.getByte(i);
- byte *fixp = wp_at(class_fixup_offset.get(i));
- entry *e = (entry *)class_fixup_ref.get(nextref++);
- int idx = e->getOutputIndex();
- switch (type)
- {
- case 1:
- putu1_at(fixp, idx);
- break;
- case 2:
- putu2_at(fixp, idx);
- break;
- default:
- assert(false); // should not reach here
- }
- }
+ // First, consult the global table and the local constant pool,
+ // and decide on the globally implied inner classes.
+ // (Note that we read the cpool's outputIndex fields, but we
+ // do not yet write them, since the local IC attribute might
+ // reverse a global decision to declare an IC.)
+ assert(requested_ics.length() == 0); // must start out empty
+ // Always include all members of the current class.
+ for (inner_class *child = cp.getFirstChildIC(cur_class); child != nullptr;
+ child = cp.getNextChildIC(child))
+ {
+ child->requested = true;
+ requested_ics.add(child);
+ }
+ // And, for each inner class mentioned in the constant pool,
+ // include it and all its outers.
+ int noes = cp.outputEntries.length();
+ entry **oes = (entry **)cp.outputEntries.base();
+ for (i = 0; i < noes; i++)
+ {
+ entry &e = *oes[i];
+ if (e.tag != CONSTANT_Class)
+ continue; // wrong sort
+ for (inner_class *ic = cp.getIC(&e); ic != nullptr; ic = cp.getIC(ic->outer))
+ {
+ if (ic->requested)
+ break; // already processed
+ ic->requested = true;
+ requested_ics.add(ic);
+ }
+ }
+ int local_ics = requested_ics.length();
+ // Second, consult a local attribute (if any) and adjust the global set.
+ inner_class *extra_ics = nullptr;
+ int num_extra_ics = 0;
+ if (cur_class_has_local_ics)
+ {
+ // adjust the set of ICs by symmetric set difference w/ the locals
+ num_extra_ics = class_InnerClasses_N.getInt();
+ if (num_extra_ics == 0)
+ {
+ // Explicit zero count has an irregular meaning: It deletes the attr.
+ local_ics = 0; // (short-circuit all tests of requested bits)
+ }
+ else
+ {
+ extra_ics = T_NEW(inner_class, num_extra_ics);
+ // Note: extra_ics will be freed up by next call to get_next_file().
+ }
+ }
+ for (i = 0; i < num_extra_ics; i++)
+ {
+ inner_class &extra_ic = extra_ics[i];
+ extra_ic.inner = class_InnerClasses_RC.getRef();
+ // Find the corresponding equivalent global IC:
+ inner_class *global_ic = cp.getIC(extra_ic.inner);
+ int flags = class_InnerClasses_F.getInt();
+ if (flags == 0)
+ {
+ // The extra IC is simply a copy of a global IC.
+ if (global_ic == nullptr)
+ {
+ unpack_abort("bad reference to inner class");
+ break;
+ }
+ extra_ic = (*global_ic); // fill in rest of fields
+ }
+ else
+ {
+ flags &= ~ACC_IC_LONG_FORM; // clear high bit if set to get clean zero
+ extra_ic.flags = flags;
+ extra_ic.outer = class_InnerClasses_outer_RCN.getRefN();
+ extra_ic.name = class_InnerClasses_name_RUN.getRefN();
+ // Detect if this is an exact copy of the global tuple.
+ if (global_ic != nullptr)
+ {
+ if (global_ic->flags != extra_ic.flags || global_ic->outer != extra_ic.outer ||
+ global_ic->name != extra_ic.name)
+ {
+ global_ic = nullptr; // not really the same, so break the link
+ }
+ }
+ }
+ if (global_ic != nullptr && global_ic->requested)
+ {
+ // This local repetition reverses the globally implied request.
+ global_ic->requested = false;
+ extra_ic.requested = false;
+ local_ics -= 1;
+ }
+ else
+ {
+ // The global either does not exist, or is not yet requested.
+ extra_ic.requested = true;
+ local_ics += 1;
+ }
+ }
+ // Finally, if there are any that survived, put them into an attribute.
+ // (Note that a zero-count attribute is always deleted.)
+ // The putref calls below will tell the constant pool to add any
+ // necessary local CP references to support the InnerClasses attribute.
+ // This step must be the last round of additions to the local CP.
+ if (local_ics > 0)
+ {
+ // append the new attribute:
+ putref(cp.sym[constant_pool::s_InnerClasses]);
+ putu4(2 + 2 * 4 * local_ics);
+ putu2(local_ics);
+ PTRLIST_QSORT(requested_ics, raw_address_cmp);
+ int num_global_ics = requested_ics.length();
+ for (i = -num_global_ics; i < num_extra_ics; i++)
+ {
+ inner_class *ic;
+ if (i < 0)
+ ic = (inner_class *)requested_ics.get(num_global_ics + i);
+ else
+ ic = &extra_ics[i];
+ if (ic->requested)
+ {
+ putref(ic->inner);
+ putref(ic->outer);
+ putref(ic->name);
+ putu2(ic->flags);
+ }
+ }
+ putu2_at(wp_at(naOffset), ++na); // increment class attr count
+ }
+
+ // Tidy up global 'requested' bits:
+ for (i = requested_ics.length(); --i >= 0;)
+ {
+ inner_class *ic = (inner_class *)requested_ics.get(i);
+ ic->requested = false;
+ }
+ requested_ics.empty();
+
+ close_output();
+
+ // rewrite CP references in the tail
+ cp.computeOutputIndexes();
+ int nextref = 0;
+ for (i = 0; i < (int)class_fixup_type.size(); i++)
+ {
+ int type = class_fixup_type.getByte(i);
+ byte *fixp = wp_at(class_fixup_offset.get(i));
+ entry *e = (entry *)class_fixup_ref.get(nextref++);
+ int idx = e->getOutputIndex();
+ switch (type)
+ {
+ case 1:
+ putu1_at(fixp, idx);
+ break;
+ case 2:
+ putu2_at(fixp, idx);
+ break;
+ default:
+ assert(false); // should not reach here
+ }
+ }
}
void unpacker::write_classfile_head()
{
- cur_classfile_head.empty();
- set_output(&cur_classfile_head);
+ cur_classfile_head.empty();
+ set_output(&cur_classfile_head);
- putu4(JAVA_MAGIC);
- putu2(cur_class_minver);
- putu2(cur_class_majver);
- putu2(cp.outputIndexLimit);
+ putu4(JAVA_MAGIC);
+ putu2(cur_class_minver);
+ putu2(cur_class_majver);
+ putu2(cp.outputIndexLimit);
#ifndef NDEBUG
- int checkIndex = 1;
+ int checkIndex = 1;
#endif
- int noes = cp.outputEntries.length();
- entry **oes = (entry **)cp.outputEntries.base();
- for (int i = 0; i < noes; i++)
- {
- entry &e = *oes[i];
- assert(e.getOutputIndex() == checkIndex++);
- byte tag = e.tag;
- assert(tag != CONSTANT_Signature);
- putu1(tag);
- switch (tag)
- {
- case CONSTANT_Utf8:
- putu2((int)e.value.b.len);
- put_bytes(e.value.b);
- break;
- case CONSTANT_Integer:
- case CONSTANT_Float:
- putu4(e.value.i);
- break;
- case CONSTANT_Long:
- case CONSTANT_Double:
- putu8(e.value.l);
- assert(checkIndex++);
- break;
- case CONSTANT_Class:
- case CONSTANT_String:
- // just write the ref
- putu2(e.refs[0]->getOutputIndex());
- break;
- case CONSTANT_Fieldref:
- case CONSTANT_Methodref:
- case CONSTANT_InterfaceMethodref:
- case CONSTANT_NameandType:
- putu2(e.refs[0]->getOutputIndex());
- putu2(e.refs[1]->getOutputIndex());
- break;
- default:
- unpack_abort(ERROR_INTERNAL);
- }
- }
- close_output();
+ int noes = cp.outputEntries.length();
+ entry **oes = (entry **)cp.outputEntries.base();
+ for (int i = 0; i < noes; i++)
+ {
+ entry &e = *oes[i];
+ assert(e.getOutputIndex() == checkIndex++);
+ byte tag = e.tag;
+ assert(tag != CONSTANT_Signature);
+ putu1(tag);
+ switch (tag)
+ {
+ case CONSTANT_Utf8:
+ putu2((int)e.value.b.len);
+ put_bytes(e.value.b);
+ break;
+ case CONSTANT_Integer:
+ case CONSTANT_Float:
+ putu4(e.value.i);
+ break;
+ case CONSTANT_Long:
+ case CONSTANT_Double:
+ putu8(e.value.l);
+ assert(checkIndex++);
+ break;
+ case CONSTANT_Class:
+ case CONSTANT_String:
+ // just write the ref
+ putu2(e.refs[0]->getOutputIndex());
+ break;
+ case CONSTANT_Fieldref:
+ case CONSTANT_Methodref:
+ case CONSTANT_InterfaceMethodref:
+ case CONSTANT_NameandType:
+ putu2(e.refs[0]->getOutputIndex());
+ putu2(e.refs[1]->getOutputIndex());
+ break;
+ default:
+ unpack_abort(ERROR_INTERNAL);
+ }
+ }
+ close_output();
}
unpacker::file *unpacker::get_next_file()
{
- free_temps();
- if (files_remaining == 0)
- {
- // Leave a clue that we're exhausted.
- cur_file.name = nullptr;
- cur_file.size = 0;
- if (archive_size != 0)
- {
- uint64_t predicted_size = unsized_bytes_read + archive_size;
- if (predicted_size != bytes_read)
- unpack_abort("archive header had incorrect size");
- }
- return nullptr;
- }
- files_remaining -= 1;
- assert(files_written < file_count || classes_written < class_count);
- cur_file.name = "";
- cur_file.size = 0;
- cur_file.modtime = default_file_modtime;
- cur_file.options = default_file_options;
- cur_file.data[0].set(nullptr, 0);
- cur_file.data[1].set(nullptr, 0);
- if (files_written < file_count)
- {
- entry *e = file_name.getRef();
- cur_file.name = e->utf8String();
- bool haveLongSize = ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0);
- cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize);
- if ((archive_options & AO_HAVE_FILE_MODTIME) != 0)
- cur_file.modtime += file_modtime.getInt(); // relative to archive modtime
- if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0)
- cur_file.options |= file_options.getInt() & ~suppress_file_options;
- }
- else if (classes_written < class_count)
- {
- // there is a class for a missing file record
- cur_file.options |= FO_IS_CLASS_STUB;
- }
- if ((cur_file.options & FO_IS_CLASS_STUB) != 0)
- {
- assert(classes_written < class_count);
- classes_written += 1;
- if (cur_file.size != 0)
- {
- unpack_abort("class file size transmitted");
- }
- reset_cur_classfile();
-
- // write the meat of the classfile:
- write_classfile_tail();
- cur_file.data[1] = cur_classfile_tail.b;
-
- // write the CP of the classfile, second:
- write_classfile_head();
- cur_file.data[0] = cur_classfile_head.b;
-
- cur_file.size += cur_file.data[0].len;
- cur_file.size += cur_file.data[1].len;
- if (cur_file.name[0] == '\0')
- {
- bytes &prefix = cur_class->ref(0)->value.b;
- const char *suffix = ".class";
- int len = (int)(prefix.len + strlen(suffix));
- bytes name;
- name.set(T_NEW(byte, add_size(len, 1)), len);
- cur_file.name = name.strcat(prefix).strcat(suffix).strval();
- }
- }
- else
- {
- // If there is buffered file data, produce a pointer to it.
- if (cur_file.size != (size_t)cur_file.size)
- {
- // Silly size specified.
- unpack_abort("resource file too large");
- }
- size_t rpleft = input_remaining();
- if (rpleft > 0)
- {
- if (rpleft > cur_file.size)
- rpleft = (size_t)cur_file.size;
- cur_file.data[0].set(rp, rpleft);
- rp += rpleft;
- }
- if (rpleft < cur_file.size)
- {
- // Caller must read the rest.
- size_t fleft = (size_t)cur_file.size - rpleft;
- bytes_read += fleft; // Credit it to the overall archive size.
- }
- }
- bytes_written += cur_file.size;
- files_written += 1;
- return &cur_file;
+ free_temps();
+ if (files_remaining == 0)
+ {
+ // Leave a clue that we're exhausted.
+ cur_file.name = nullptr;
+ cur_file.size = 0;
+ if (archive_size != 0)
+ {
+ uint64_t predicted_size = unsized_bytes_read + archive_size;
+ if (predicted_size != bytes_read)
+ unpack_abort("archive header had incorrect size");
+ }
+ return nullptr;
+ }
+ files_remaining -= 1;
+ assert(files_written < file_count || classes_written < class_count);
+ cur_file.name = "";
+ cur_file.size = 0;
+ cur_file.modtime = default_file_modtime;
+ cur_file.options = default_file_options;
+ cur_file.data[0].set(nullptr, 0);
+ cur_file.data[1].set(nullptr, 0);
+ if (files_written < file_count)
+ {
+ entry *e = file_name.getRef();
+ cur_file.name = e->utf8String();
+ bool haveLongSize = ((archive_options & AO_HAVE_FILE_SIZE_HI) != 0);
+ cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize);
+ if ((archive_options & AO_HAVE_FILE_MODTIME) != 0)
+ cur_file.modtime += file_modtime.getInt(); // relative to archive modtime
+ if ((archive_options & AO_HAVE_FILE_OPTIONS) != 0)
+ cur_file.options |= file_options.getInt() & ~suppress_file_options;
+ }
+ else if (classes_written < class_count)
+ {
+ // there is a class for a missing file record
+ cur_file.options |= FO_IS_CLASS_STUB;
+ }
+ if ((cur_file.options & FO_IS_CLASS_STUB) != 0)
+ {
+ assert(classes_written < class_count);
+ classes_written += 1;
+ if (cur_file.size != 0)
+ {
+ unpack_abort("class file size transmitted");
+ }
+ reset_cur_classfile();
+
+ // write the meat of the classfile:
+ write_classfile_tail();
+ cur_file.data[1] = cur_classfile_tail.b;
+
+ // write the CP of the classfile, second:
+ write_classfile_head();
+ cur_file.data[0] = cur_classfile_head.b;
+
+ cur_file.size += cur_file.data[0].len;
+ cur_file.size += cur_file.data[1].len;
+ if (cur_file.name[0] == '\0')
+ {
+ bytes &prefix = cur_class->ref(0)->value.b;
+ const char *suffix = ".class";
+ int len = (int)(prefix.len + strlen(suffix));
+ bytes name;
+ name.set(T_NEW(byte, add_size(len, 1)), len);
+ cur_file.name = name.strcat(prefix).strcat(suffix).strval();
+ }
+ }
+ else
+ {
+ // If there is buffered file data, produce a pointer to it.
+ if (cur_file.size != (size_t)cur_file.size)
+ {
+ // Silly size specified.
+ unpack_abort("resource file too large");
+ }
+ size_t rpleft = input_remaining();
+ if (rpleft > 0)
+ {
+ if (rpleft > cur_file.size)
+ rpleft = (size_t)cur_file.size;
+ cur_file.data[0].set(rp, rpleft);
+ rp += rpleft;
+ }
+ if (rpleft < cur_file.size)
+ {
+ // Caller must read the rest.
+ size_t fleft = (size_t)cur_file.size - rpleft;
+ bytes_read += fleft; // Credit it to the overall archive size.
+ }
+ }
+ bytes_written += cur_file.size;
+ files_written += 1;
+ return &cur_file;
}
// Write a file to jarout.
void unpacker::write_file_to_jar(unpacker::file *f)
{
- size_t htsize = f->data[0].len + f->data[1].len;
- uint64_t fsize = f->size;
- if (htsize == fsize)
- {
- jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime, f->data[0], f->data[1]);
- }
- else
- {
- assert(input_remaining() == 0);
- bytes part1, part2;
- part1.len = f->data[0].len;
- part1.set(T_NEW(byte, part1.len), part1.len);
- part1.copyFrom(f->data[0]);
- assert(f->data[1].len == 0);
- part2.set(nullptr, 0);
- size_t fleft = (size_t)fsize - part1.len;
- assert(bytes_read > fleft); // part2 already credited by get_next_file
- bytes_read -= fleft;
- if (fleft > 0)
- {
- // Must read some more.
- if (live_input)
- {
- // Stop using the input buffer. Make a new one:
- if (free_input)
- input.free();
- input.init(fleft > (1 << 12) ? fleft : (1 << 12));
- free_input = true;
- live_input = false;
- }
- else
- {
- // Make it large enough.
- assert(free_input); // must be reallocable
- input.ensureSize(fleft);
- }
- rplimit = rp = input.base();
- input.setLimit(rp + fleft);
- if (!ensure_input(fleft))
- unpack_abort("EOF reading resource file");
- part2.ptr = input_scan();
- part2.len = input_remaining();
- rplimit = rp = input.base();
- }
- jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime, part1, part2);
- }
- if (verbose >= 3)
- {
- fprintf(stderr, "Wrote %" PRIu64 " bytes to: %s\n", fsize, f->name);
- }
+ size_t htsize = f->data[0].len + f->data[1].len;
+ uint64_t fsize = f->size;
+ if (htsize == fsize)
+ {
+ jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime, f->data[0], f->data[1]);
+ }
+ else
+ {
+ assert(input_remaining() == 0);
+ bytes part1, part2;
+ part1.len = f->data[0].len;
+ part1.set(T_NEW(byte, part1.len), part1.len);
+ part1.copyFrom(f->data[0]);
+ assert(f->data[1].len == 0);
+ part2.set(nullptr, 0);
+ size_t fleft = (size_t)fsize - part1.len;
+ assert(bytes_read > fleft); // part2 already credited by get_next_file
+ bytes_read -= fleft;
+ if (fleft > 0)
+ {
+ // Must read some more.
+ if (live_input)
+ {
+ // Stop using the input buffer. Make a new one:
+ if (free_input)
+ input.free();
+ input.init(fleft > (1 << 12) ? fleft : (1 << 12));
+ free_input = true;
+ live_input = false;
+ }
+ else
+ {
+ // Make it large enough.
+ assert(free_input); // must be reallocable
+ input.ensureSize(fleft);
+ }
+ rplimit = rp = input.base();
+ input.setLimit(rp + fleft);
+ if (!ensure_input(fleft))
+ unpack_abort("EOF reading resource file");
+ part2.ptr = input_scan();
+ part2.len = input_remaining();
+ rplimit = rp = input.base();
+ }
+ jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime, part1, part2);
+ }
+ if (verbose >= 3)
+ {
+ fprintf(stderr, "Wrote %" PRIu64 " bytes to: %s\n", fsize, f->name);
+ }
}
diff --git a/libraries/pack200/src/unpack.h b/libraries/pack200/src/unpack.h
index 0100700d..8363740d 100644
--- a/libraries/pack200/src/unpack.h
+++ b/libraries/pack200/src/unpack.h
@@ -35,104 +35,104 @@ struct value_stream;
struct cpindex
{
- uint32_t len;
- entry *base1; // base of primary index
- entry **base2; // base of secondary index
- byte ixTag; // type of entries (!= CONSTANT_None), plus 64 if sub-index
- enum
- {
- SUB_TAG = 64
- };
-
- entry *get(uint32_t i);
-
- void init(int len_, entry *base1_, int ixTag_)
- {
- len = len_;
- base1 = base1_;
- base2 = nullptr;
- ixTag = ixTag_;
- }
- void init(int len_, entry **base2_, int ixTag_)
- {
- len = len_;
- base1 = nullptr;
- base2 = base2_;
- ixTag = ixTag_;
- }
+ uint32_t len;
+ entry *base1; // base of primary index
+ entry **base2; // base of secondary index
+ byte ixTag; // type of entries (!= CONSTANT_None), plus 64 if sub-index
+ enum
+ {
+ SUB_TAG = 64
+ };
+
+ entry *get(uint32_t i);
+
+ void init(int len_, entry *base1_, int ixTag_)
+ {
+ len = len_;
+ base1 = base1_;
+ base2 = nullptr;
+ ixTag = ixTag_;
+ }
+ void init(int len_, entry **base2_, int ixTag_)
+ {
+ len = len_;
+ base1 = nullptr;
+ base2 = base2_;
+ ixTag = ixTag_;
+ }
};
struct constant_pool
{
- uint32_t nentries;
- entry *entries;
- entry *first_extra_entry;
- uint32_t maxentries; // total allocated size of entries
-
- // Position and size of each homogeneous subrange:
- int tag_count[CONSTANT_Limit];
- int tag_base[CONSTANT_Limit];
- cpindex tag_index[CONSTANT_Limit];
- ptrlist tag_extras[CONSTANT_Limit];
-
- cpindex *member_indexes; // indexed by 2*CONSTANT_Class.inord
- cpindex *getFieldIndex(entry *classRef);
- cpindex *getMethodIndex(entry *classRef);
-
- inner_class **ic_index;
- inner_class **ic_child_index;
- inner_class *getIC(entry *inner);
- inner_class *getFirstChildIC(entry *outer);
- inner_class *getNextChildIC(inner_class *child);
-
- int outputIndexLimit; // index limit after renumbering
- ptrlist outputEntries; // list of entry* needing output idx assigned
-
- entry **hashTab;
- uint32_t hashTabLength;
- entry *&hashTabRef(byte tag, bytes &b);
- entry *ensureUtf8(bytes &b);
- entry *ensureClass(bytes &b);
-
- // Well-known Utf8 symbols.
- enum
- {
+ uint32_t nentries;
+ entry *entries;
+ entry *first_extra_entry;
+ uint32_t maxentries; // total allocated size of entries
+
+ // Position and size of each homogeneous subrange:
+ int tag_count[CONSTANT_Limit];
+ int tag_base[CONSTANT_Limit];
+ cpindex tag_index[CONSTANT_Limit];
+ ptrlist tag_extras[CONSTANT_Limit];
+
+ cpindex *member_indexes; // indexed by 2*CONSTANT_Class.inord
+ cpindex *getFieldIndex(entry *classRef);
+ cpindex *getMethodIndex(entry *classRef);
+
+ inner_class **ic_index;
+ inner_class **ic_child_index;
+ inner_class *getIC(entry *inner);
+ inner_class *getFirstChildIC(entry *outer);
+ inner_class *getNextChildIC(inner_class *child);
+
+ int outputIndexLimit; // index limit after renumbering
+ ptrlist outputEntries; // list of entry* needing output idx assigned
+
+ entry **hashTab;
+ uint32_t hashTabLength;
+ entry *&hashTabRef(byte tag, bytes &b);
+ entry *ensureUtf8(bytes &b);
+ entry *ensureClass(bytes &b);
+
+ // Well-known Utf8 symbols.
+ enum
+ {
#define SNAME(n, s) s_##s,
- ALL_ATTR_DO(SNAME)
+ ALL_ATTR_DO(SNAME)
#undef SNAME
- s_lt_init_gt, // <init>
- s_LIMIT
- };
- entry *sym[s_LIMIT];
-
- // read counts from hdr, allocate main arrays
- enum
- {
- NUM_COUNTS = 12
- };
- void init(unpacker *u, int counts[NUM_COUNTS]);
-
- // pointer to outer unpacker, for error checks etc.
- unpacker *u;
-
- int getCount(byte tag)
- {
- assert((uint32_t)tag < CONSTANT_Limit);
- return tag_count[tag];
- }
- cpindex *getIndex(byte tag)
- {
- assert((uint32_t)tag < CONSTANT_Limit);
- return &tag_index[tag];
- }
- cpindex *getKQIndex(); // uses cur_descr
-
- void expandSignatures();
- void initMemberIndexes();
-
- void computeOutputOrder();
- void computeOutputIndexes();
- void resetOutputIndexes();
+ s_lt_init_gt, // <init>
+ s_LIMIT
+ };
+ entry *sym[s_LIMIT];
+
+ // read counts from hdr, allocate main arrays
+ enum
+ {
+ NUM_COUNTS = 12
+ };
+ void init(unpacker *u, int counts[NUM_COUNTS]);
+
+ // pointer to outer unpacker, for error checks etc.
+ unpacker *u;
+
+ int getCount(byte tag)
+ {
+ assert((uint32_t)tag < CONSTANT_Limit);
+ return tag_count[tag];
+ }
+ cpindex *getIndex(byte tag)
+ {
+ assert((uint32_t)tag < CONSTANT_Limit);
+ return &tag_index[tag];
+ }
+ cpindex *getKQIndex(); // uses cur_descr
+
+ void expandSignatures();
+ void initMemberIndexes();
+
+ void computeOutputOrder();
+ void computeOutputIndexes();
+ void resetOutputIndexes();
};
/*
@@ -141,407 +141,407 @@ struct constant_pool
*/
struct unpacker
{
- // One element of the resulting JAR.
- struct file
- {
- const char *name;
- uint64_t size;
- int modtime;
- int options;
- bytes data[2];
- // Note: If Sum(data[*].len) < size,
- // remaining bytes must be read directly from the input stream.
- bool deflate_hint()
- {
- return ((options & FO_DEFLATE_HINT) != 0);
- }
- };
-
- // if running Unix-style, here are the inputs and outputs
- FILE *infileptr; // buffered
- bytes inbytes; // direct
- gunzip *gzin; // gunzip filter, if any
- jar *jarout; // output JAR file
-
- // pointer to self, for U_NEW macro
- unpacker *u;
-
- ptrlist mallocs; // list of guys to free when we are all done
- ptrlist tmallocs; // list of guys to free on next client request
- fillbytes smallbuf; // supplies small alloc requests
- fillbytes tsmallbuf; // supplies temporary small alloc requests
-
- // option management members
- int verbose; // verbose level, 0 means no output
- int deflate_hint_or_zero; // ==0 means not set, otherwise -1 or 1
- int modification_time_or_zero;
-
- // input stream
- fillbytes input; // the whole block (size is predicted, has slop too)
- bool live_input; // is the data in this block live?
- bool free_input; // must the input buffer be freed?
- byte *rp; // read pointer (< rplimit <= input.limit())
- byte *rplimit; // how much of the input block has been read?
- uint64_t bytes_read;
- int unsized_bytes_read;
-
- // callback to read at least one byte, up to available input
- typedef int64_t (*read_input_fn_t)(unpacker *self, void *buf, int64_t minlen,
- int64_t maxlen);
- read_input_fn_t read_input_fn;
-
- // archive header fields
- int magic, minver, majver;
- size_t archive_size;
- int archive_next_count, archive_options, archive_modtime;
- int band_headers_size;
- int file_count, attr_definition_count, ic_count, class_count;
- int default_class_minver, default_class_majver;
- int default_file_options, suppress_file_options; // not header fields
- int default_archive_modtime, default_file_modtime; // not header fields
- int code_count; // not a header field
- int files_remaining; // not a header field
-
- // engine state
- band *all_bands; // indexed by band_number
- byte *meta_rp; // read-pointer into (copy of) band_headers
- constant_pool cp; // all constant pool information
- inner_class *ics; // InnerClasses
-
- // output stream
- bytes output; // output block (either classfile head or tail)
- byte *wp; // write pointer (< wplimit == output.limit())
- byte *wpbase; // write pointer starting address (<= wp)
- byte *wplimit; // how much of the output block has been written?
-
- // output state
- file cur_file;
- entry *cur_class; // CONSTANT_Class entry
- entry *cur_super; // CONSTANT_Class entry or nullptr
- entry *cur_descr; // CONSTANT_NameandType entry
- int cur_descr_flags; // flags corresponding to cur_descr
- int cur_class_minver, cur_class_majver;
- bool cur_class_has_local_ics;
- fillbytes cur_classfile_head;
- fillbytes cur_classfile_tail;
- int files_written; // also tells which file we're working on
- int classes_written; // also tells which class we're working on
- uint64_t bytes_written;
- intlist bcimap;
- fillbytes class_fixup_type;
- intlist class_fixup_offset;
- ptrlist class_fixup_ref;
- fillbytes code_fixup_type; // which format of branch operand?
- intlist code_fixup_offset; // location of operand needing fixup
- intlist code_fixup_source; // encoded ID of branch insn
- ptrlist requested_ics; // which ics need output?
-
- // stats pertaining to multiple segments (updated on reset)
- uint64_t bytes_read_before_reset;
- uint64_t bytes_written_before_reset;
- int files_written_before_reset;
- int classes_written_before_reset;
- int segments_read_before_reset;
-
- // attribute state
- struct layout_definition
- {
- uint32_t idx; // index (0..31...) which identifies this layout
- const char *name; // name of layout
- entry *nameEntry;
- const char *layout; // string of layout (not yet parsed)
- band **elems; // array of top-level layout elems (or callables)
-
- bool hasCallables()
- {
- return layout[0] == '[';
- }
- band **bands()
- {
- assert(elems != nullptr);
- return elems;
- }
- };
- struct attr_definitions
- {
- unpacker *u; // pointer to self, for U_NEW macro
- int xxx_flags_hi_bn; // locator for flags, count, indexes, calls bands
- int attrc; // ATTR_CONTEXT_CLASS, etc.
- uint32_t flag_limit; // 32 or 63, depending on archive_options bit
- uint64_t predef; // mask of built-in definitions
- uint64_t redef; // mask of local flag definitions or redefinitions
- ptrlist layouts; // local (compressor-defined) defs, in index order
- int flag_count[X_ATTR_LIMIT_FLAGS_HI];
- intlist overflow_count;
- ptrlist strip_names; // what attribute names are being stripped?
- ptrlist band_stack; // Temp., used during layout parsing.
- ptrlist calls_to_link; // (ditto)
- int bands_made; // (ditto)
-
- void free()
- {
- layouts.free();
- overflow_count.free();
- strip_names.free();
- band_stack.free();
- calls_to_link.free();
- }
-
- // Locate the five fixed bands.
- band &xxx_flags_hi();
- band &xxx_flags_lo();
- band &xxx_attr_count();
- band &xxx_attr_indexes();
- band &xxx_attr_calls();
- band &fixed_band(int e_class_xxx);
-
- // Register a new layout, and make bands for it.
- layout_definition *defineLayout(int idx, const char *name, const char *layout);
- layout_definition *defineLayout(int idx, entry *nameEntry, const char *layout);
- band **buildBands(layout_definition *lo);
-
- // Parse a layout string or part of one, recursively if necessary.
- const char *parseLayout(const char *lp, band **&res, int curCble);
- const char *parseNumeral(const char *lp, int &res);
- const char *parseIntLayout(const char *lp, band *&res, byte le_kind,
- bool can_be_signed = false);
- band **popBody(int band_stack_base); // pops a body off band_stack
-
- // Read data into the bands of the idx-th layout.
- void readBandData(int idx); // parse layout, make bands, read data
- void readBandData(band **body, uint32_t count); // recursive helper
-
- layout_definition *getLayout(uint32_t idx)
- {
- if (idx >= (uint32_t)layouts.length())
- return nullptr;
- return (layout_definition *)layouts.get(idx);
- }
-
- void setHaveLongFlags(bool z)
- {
- assert(flag_limit == 0); // not set up yet
- flag_limit = (z ? X_ATTR_LIMIT_FLAGS_HI : X_ATTR_LIMIT_NO_FLAGS_HI);
- }
- bool haveLongFlags()
- {
- assert(flag_limit == X_ATTR_LIMIT_NO_FLAGS_HI ||
- flag_limit == X_ATTR_LIMIT_FLAGS_HI);
- return flag_limit == X_ATTR_LIMIT_FLAGS_HI;
- }
-
- // Return flag_count if idx is predef and not redef, else zero.
- int predefCount(uint32_t idx);
-
- bool isRedefined(uint32_t idx)
- {
- if (idx >= flag_limit)
- return false;
- return (bool)((redef >> idx) & 1);
- }
- bool isPredefined(uint32_t idx)
- {
- if (idx >= flag_limit)
- return false;
- return (bool)(((predef & ~redef) >> idx) & 1);
- }
- uint64_t flagIndexMask()
- {
- return (predef | redef);
- }
- bool isIndex(uint32_t idx)
- {
- assert(flag_limit != 0); // must be set up already
- if (idx < flag_limit)
- return (bool)(((predef | redef) >> idx) & 1);
- else
- return (idx - flag_limit < (uint32_t)overflow_count.length());
- }
- int &getCount(uint32_t idx)
- {
- assert(isIndex(idx));
- if (idx < flag_limit)
- return flag_count[idx];
- else
- return overflow_count.get(idx - flag_limit);
- }
- };
-
- attr_definitions attr_defs[ATTR_CONTEXT_LIMIT];
-
- // Initialization
- void init(read_input_fn_t input_fn = nullptr);
- // Resets to a known sane state
- void reset();
- // Deallocates all storage.
- void free();
- // Deallocates temporary storage (volatile after next client call).
- void free_temps()
- {
- tsmallbuf.init();
- tmallocs.freeAll();
- }
-
- // Option management methods
- bool set_option(const char *option, const char *value);
- const char *get_option(const char *option);
-
- // Fetching input.
- bool ensure_input(int64_t more);
- byte *input_scan()
- {
- return rp;
- }
- size_t input_remaining()
- {
- return rplimit - rp;
- }
- size_t input_consumed()
- {
- return rp - input.base();
- }
-
- // Entry points to the unpack engine
- static int run(int argc, char **argv); // Unix-style entry point.
- void check_options();
- void start(void *packptr = nullptr, size_t len = 0);
- void write_file_to_jar(file *f);
- void finish();
-
- // Public post unpack methods
- int get_files_remaining()
- {
- return files_remaining;
- }
- int get_segments_remaining()
- {
- return archive_next_count;
- }
- file *get_next_file(); // returns nullptr on last file
-
- // General purpose methods
- void *alloc(size_t size)
- {
- return alloc_heap(size, true);
- }
- void *temp_alloc(size_t size)
- {
- return alloc_heap(size, true, true);
- }
- void *alloc_heap(size_t size, bool smallOK = false, bool temp = false);
- void saveTo(bytes &b, const char *str)
- {
- saveTo(b, (byte *)str, strlen(str));
- }
- void saveTo(bytes &b, bytes &data)
- {
- saveTo(b, data.ptr, data.len);
- }
- void saveTo(bytes &b, byte *ptr, size_t len); //{ b.ptr = U_NEW...}
- const char *saveStr(const char *str)
- {
- bytes buf;
- saveTo(buf, str);
- return buf.strval();
- }
- const char *saveIntStr(int num)
- {
- char buf[30];
- sprintf(buf, "%d", num);
- return saveStr(buf);
- }
- static unpacker *current(); // find current instance
-
- // Output management
- void set_output(fillbytes *which)
- {
- assert(wp == nullptr);
- which->ensureSize(1 << 12); // covers the average classfile
- wpbase = which->base();
- wp = which->limit();
- wplimit = which->end();
- }
- fillbytes *close_output(fillbytes *which = nullptr); // inverse of set_output
-
- // These take an implicit parameter of wp/wplimit, and resize as necessary:
- byte *put_space(size_t len); // allocates space at wp, returns pointer
- size_t put_empty(size_t s)
- {
- byte *p = put_space(s);
- return p - wpbase;
- }
- void ensure_put_space(size_t len);
- void put_bytes(bytes &b)
- {
- b.writeTo(put_space(b.len));
- }
- void putu1(int n)
- {
- putu1_at(put_space(1), n);
- }
- void putu1_fast(int n)
- {
- putu1_at(wp++, n);
- }
- void putu2(int n); // { putu2_at(put_space(2), n); }
- void putu4(int n); // { putu4_at(put_space(4), n); }
- void putu8(int64_t n); // { putu8_at(put_space(8), n); }
- void putref(entry *e); // { putu2_at(put_space(2), putref_index(e, 2)); }
- void putu1ref(entry *e); // { putu1_at(put_space(1), putref_index(e, 1)); }
- int putref_index(entry *e, int size); // size in [1..2]
- void put_label(int curIP, int size); // size in {2,4}
- void putlayout(band **body);
- void put_stackmap_type();
-
- size_t wpoffset()
- {
- return (size_t)(wp - wpbase);
- } // (unvariant across overflow)
- byte *wp_at(size_t offset)
- {
- return wpbase + offset;
- }
- uint32_t to_bci(uint32_t bii);
- void get_code_header(int &max_stack, int &max_na_locals, int &handler_count, int &cflags);
- band *ref_band_for_self_op(int bc, bool &isAloadVar, int &origBCVar);
- band *ref_band_for_op(int bc);
-
- // Definitions of standard classfile int formats:
- static void putu1_at(byte *wp, int n)
- {
- assert(n == (n & 0xFF));
- wp[0] = n;
- }
- static void putu2_at(byte *wp, int n);
- static void putu4_at(byte *wp, int n);
- static void putu8_at(byte *wp, int64_t n);
-
- // Private stuff
- void reset_cur_classfile();
- void write_classfile_tail();
- void write_classfile_head();
- void write_code();
- void write_bc_ops();
- void write_members(int num, int attrc); // attrc=ATTR_CONTEXT_FIELD/METHOD
- int write_attrs(int attrc, uint64_t indexBits);
-
- // The readers
- void read_bands();
- void read_file_header();
- void read_cp();
- void read_cp_counts(value_stream &hdr);
- void read_attr_defs();
- void read_ics();
- void read_attrs(int attrc, int obj_count);
- void read_classes();
- void read_code_headers();
- void read_bcs();
- void read_bc_ops();
- void read_files();
- void read_Utf8_values(entry *cpMap, int len);
- void read_single_words(band &cp_band, entry *cpMap, int len);
- void read_double_words(band &cp_bands, entry *cpMap, int len);
- void read_single_refs(band &cp_band, byte refTag, entry *cpMap, int len);
- void read_double_refs(band &cp_band, byte ref1Tag, byte ref2Tag, entry *cpMap, int len);
- void read_signature_values(entry *cpMap, int len);
+ // One element of the resulting JAR.
+ struct file
+ {
+ const char *name;
+ uint64_t size;
+ int modtime;
+ int options;
+ bytes data[2];
+ // Note: If Sum(data[*].len) < size,
+ // remaining bytes must be read directly from the input stream.
+ bool deflate_hint()
+ {
+ return ((options & FO_DEFLATE_HINT) != 0);
+ }
+ };
+
+ // if running Unix-style, here are the inputs and outputs
+ FILE *infileptr; // buffered
+ bytes inbytes; // direct
+ gunzip *gzin; // gunzip filter, if any
+ jar *jarout; // output JAR file
+
+ // pointer to self, for U_NEW macro
+ unpacker *u;
+
+ ptrlist mallocs; // list of guys to free when we are all done
+ ptrlist tmallocs; // list of guys to free on next client request
+ fillbytes smallbuf; // supplies small alloc requests
+ fillbytes tsmallbuf; // supplies temporary small alloc requests
+
+ // option management members
+ int verbose; // verbose level, 0 means no output
+ int deflate_hint_or_zero; // ==0 means not set, otherwise -1 or 1
+ int modification_time_or_zero;
+
+ // input stream
+ fillbytes input; // the whole block (size is predicted, has slop too)
+ bool live_input; // is the data in this block live?
+ bool free_input; // must the input buffer be freed?
+ byte *rp; // read pointer (< rplimit <= input.limit())
+ byte *rplimit; // how much of the input block has been read?
+ uint64_t bytes_read;
+ int unsized_bytes_read;
+
+ // callback to read at least one byte, up to available input
+ typedef int64_t (*read_input_fn_t)(unpacker *self, void *buf, int64_t minlen,
+ int64_t maxlen);
+ read_input_fn_t read_input_fn;
+
+ // archive header fields
+ int magic, minver, majver;
+ size_t archive_size;
+ int archive_next_count, archive_options, archive_modtime;
+ int band_headers_size;
+ int file_count, attr_definition_count, ic_count, class_count;
+ int default_class_minver, default_class_majver;
+ int default_file_options, suppress_file_options; // not header fields
+ int default_archive_modtime, default_file_modtime; // not header fields
+ int code_count; // not a header field
+ int files_remaining; // not a header field
+
+ // engine state
+ band *all_bands; // indexed by band_number
+ byte *meta_rp; // read-pointer into (copy of) band_headers
+ constant_pool cp; // all constant pool information
+ inner_class *ics; // InnerClasses
+
+ // output stream
+ bytes output; // output block (either classfile head or tail)
+ byte *wp; // write pointer (< wplimit == output.limit())
+ byte *wpbase; // write pointer starting address (<= wp)
+ byte *wplimit; // how much of the output block has been written?
+
+ // output state
+ file cur_file;
+ entry *cur_class; // CONSTANT_Class entry
+ entry *cur_super; // CONSTANT_Class entry or nullptr
+ entry *cur_descr; // CONSTANT_NameandType entry
+ int cur_descr_flags; // flags corresponding to cur_descr
+ int cur_class_minver, cur_class_majver;
+ bool cur_class_has_local_ics;
+ fillbytes cur_classfile_head;
+ fillbytes cur_classfile_tail;
+ int files_written; // also tells which file we're working on
+ int classes_written; // also tells which class we're working on
+ uint64_t bytes_written;
+ intlist bcimap;
+ fillbytes class_fixup_type;
+ intlist class_fixup_offset;
+ ptrlist class_fixup_ref;
+ fillbytes code_fixup_type; // which format of branch operand?
+ intlist code_fixup_offset; // location of operand needing fixup
+ intlist code_fixup_source; // encoded ID of branch insn
+ ptrlist requested_ics; // which ics need output?
+
+ // stats pertaining to multiple segments (updated on reset)
+ uint64_t bytes_read_before_reset;
+ uint64_t bytes_written_before_reset;
+ int files_written_before_reset;
+ int classes_written_before_reset;
+ int segments_read_before_reset;
+
+ // attribute state
+ struct layout_definition
+ {
+ uint32_t idx; // index (0..31...) which identifies this layout
+ const char *name; // name of layout
+ entry *nameEntry;
+ const char *layout; // string of layout (not yet parsed)
+ band **elems; // array of top-level layout elems (or callables)
+
+ bool hasCallables()
+ {
+ return layout[0] == '[';
+ }
+ band **bands()
+ {
+ assert(elems != nullptr);
+ return elems;
+ }
+ };
+ struct attr_definitions
+ {
+ unpacker *u; // pointer to self, for U_NEW macro
+ int xxx_flags_hi_bn; // locator for flags, count, indexes, calls bands
+ int attrc; // ATTR_CONTEXT_CLASS, etc.
+ uint32_t flag_limit; // 32 or 63, depending on archive_options bit
+ uint64_t predef; // mask of built-in definitions
+ uint64_t redef; // mask of local flag definitions or redefinitions
+ ptrlist layouts; // local (compressor-defined) defs, in index order
+ int flag_count[X_ATTR_LIMIT_FLAGS_HI];
+ intlist overflow_count;
+ ptrlist strip_names; // what attribute names are being stripped?
+ ptrlist band_stack; // Temp., used during layout parsing.
+ ptrlist calls_to_link; // (ditto)
+ int bands_made; // (ditto)
+
+ void free()
+ {
+ layouts.free();
+ overflow_count.free();
+ strip_names.free();
+ band_stack.free();
+ calls_to_link.free();
+ }
+
+ // Locate the five fixed bands.
+ band &xxx_flags_hi();
+ band &xxx_flags_lo();
+ band &xxx_attr_count();
+ band &xxx_attr_indexes();
+ band &xxx_attr_calls();
+ band &fixed_band(int e_class_xxx);
+
+ // Register a new layout, and make bands for it.
+ layout_definition *defineLayout(int idx, const char *name, const char *layout);
+ layout_definition *defineLayout(int idx, entry *nameEntry, const char *layout);
+ band **buildBands(layout_definition *lo);
+
+ // Parse a layout string or part of one, recursively if necessary.
+ const char *parseLayout(const char *lp, band **&res, int curCble);
+ const char *parseNumeral(const char *lp, int &res);
+ const char *parseIntLayout(const char *lp, band *&res, byte le_kind,
+ bool can_be_signed = false);
+ band **popBody(int band_stack_base); // pops a body off band_stack
+
+ // Read data into the bands of the idx-th layout.
+ void readBandData(int idx); // parse layout, make bands, read data
+ void readBandData(band **body, uint32_t count); // recursive helper
+
+ layout_definition *getLayout(uint32_t idx)
+ {
+ if (idx >= (uint32_t)layouts.length())
+ return nullptr;
+ return (layout_definition *)layouts.get(idx);
+ }
+
+ void setHaveLongFlags(bool z)
+ {
+ assert(flag_limit == 0); // not set up yet
+ flag_limit = (z ? X_ATTR_LIMIT_FLAGS_HI : X_ATTR_LIMIT_NO_FLAGS_HI);
+ }
+ bool haveLongFlags()
+ {
+ assert(flag_limit == X_ATTR_LIMIT_NO_FLAGS_HI ||
+ flag_limit == X_ATTR_LIMIT_FLAGS_HI);
+ return flag_limit == X_ATTR_LIMIT_FLAGS_HI;
+ }
+
+ // Return flag_count if idx is predef and not redef, else zero.
+ int predefCount(uint32_t idx);
+
+ bool isRedefined(uint32_t idx)
+ {
+ if (idx >= flag_limit)
+ return false;
+ return (bool)((redef >> idx) & 1);
+ }
+ bool isPredefined(uint32_t idx)
+ {
+ if (idx >= flag_limit)
+ return false;
+ return (bool)(((predef & ~redef) >> idx) & 1);
+ }
+ uint64_t flagIndexMask()
+ {
+ return (predef | redef);
+ }
+ bool isIndex(uint32_t idx)
+ {
+ assert(flag_limit != 0); // must be set up already
+ if (idx < flag_limit)
+ return (bool)(((predef | redef) >> idx) & 1);
+ else
+ return (idx - flag_limit < (uint32_t)overflow_count.length());
+ }
+ int &getCount(uint32_t idx)
+ {
+ assert(isIndex(idx));
+ if (idx < flag_limit)
+ return flag_count[idx];
+ else
+ return overflow_count.get(idx - flag_limit);
+ }
+ };
+
+ attr_definitions attr_defs[ATTR_CONTEXT_LIMIT];
+
+ // Initialization
+ void init(read_input_fn_t input_fn = nullptr);
+ // Resets to a known sane state
+ void reset();
+ // Deallocates all storage.
+ void free();
+ // Deallocates temporary storage (volatile after next client call).
+ void free_temps()
+ {
+ tsmallbuf.init();
+ tmallocs.freeAll();
+ }
+
+ // Option management methods
+ bool set_option(const char *option, const char *value);
+ const char *get_option(const char *option);
+
+ // Fetching input.
+ bool ensure_input(int64_t more);
+ byte *input_scan()
+ {
+ return rp;
+ }
+ size_t input_remaining()
+ {
+ return rplimit - rp;
+ }
+ size_t input_consumed()
+ {
+ return rp - input.base();
+ }
+
+ // Entry points to the unpack engine
+ static int run(int argc, char **argv); // Unix-style entry point.
+ void check_options();
+ void start(void *packptr = nullptr, size_t len = 0);
+ void write_file_to_jar(file *f);
+ void finish();
+
+ // Public post unpack methods
+ int get_files_remaining()
+ {
+ return files_remaining;
+ }
+ int get_segments_remaining()
+ {
+ return archive_next_count;
+ }
+ file *get_next_file(); // returns nullptr on last file
+
+ // General purpose methods
+ void *alloc(size_t size)
+ {
+ return alloc_heap(size, true);
+ }
+ void *temp_alloc(size_t size)
+ {
+ return alloc_heap(size, true, true);
+ }
+ void *alloc_heap(size_t size, bool smallOK = false, bool temp = false);
+ void saveTo(bytes &b, const char *str)
+ {
+ saveTo(b, (byte *)str, strlen(str));
+ }
+ void saveTo(bytes &b, bytes &data)
+ {
+ saveTo(b, data.ptr, data.len);
+ }
+ void saveTo(bytes &b, byte *ptr, size_t len); //{ b.ptr = U_NEW...}
+ const char *saveStr(const char *str)
+ {
+ bytes buf;
+ saveTo(buf, str);
+ return buf.strval();
+ }
+ const char *saveIntStr(int num)
+ {
+ char buf[30];
+ sprintf(buf, "%d", num);
+ return saveStr(buf);
+ }
+ static unpacker *current(); // find current instance
+
+ // Output management
+ void set_output(fillbytes *which)
+ {
+ assert(wp == nullptr);
+ which->ensureSize(1 << 12); // covers the average classfile
+ wpbase = which->base();
+ wp = which->limit();
+ wplimit = which->end();
+ }
+ fillbytes *close_output(fillbytes *which = nullptr); // inverse of set_output
+
+ // These take an implicit parameter of wp/wplimit, and resize as necessary:
+ byte *put_space(size_t len); // allocates space at wp, returns pointer
+ size_t put_empty(size_t s)
+ {
+ byte *p = put_space(s);
+ return p - wpbase;
+ }
+ void ensure_put_space(size_t len);
+ void put_bytes(bytes &b)
+ {
+ b.writeTo(put_space(b.len));
+ }
+ void putu1(int n)
+ {
+ putu1_at(put_space(1), n);
+ }
+ void putu1_fast(int n)
+ {
+ putu1_at(wp++, n);
+ }
+ void putu2(int n); // { putu2_at(put_space(2), n); }
+ void putu4(int n); // { putu4_at(put_space(4), n); }
+ void putu8(int64_t n); // { putu8_at(put_space(8), n); }
+ void putref(entry *e); // { putu2_at(put_space(2), putref_index(e, 2)); }
+ void putu1ref(entry *e); // { putu1_at(put_space(1), putref_index(e, 1)); }
+ int putref_index(entry *e, int size); // size in [1..2]
+ void put_label(int curIP, int size); // size in {2,4}
+ void putlayout(band **body);
+ void put_stackmap_type();
+
+ size_t wpoffset()
+ {
+ return (size_t)(wp - wpbase);
+ } // (unvariant across overflow)
+ byte *wp_at(size_t offset)
+ {
+ return wpbase + offset;
+ }
+ uint32_t to_bci(uint32_t bii);
+ void get_code_header(int &max_stack, int &max_na_locals, int &handler_count, int &cflags);
+ band *ref_band_for_self_op(int bc, bool &isAloadVar, int &origBCVar);
+ band *ref_band_for_op(int bc);
+
+ // Definitions of standard classfile int formats:
+ static void putu1_at(byte *wp, int n)
+ {
+ assert(n == (n & 0xFF));
+ wp[0] = n;
+ }
+ static void putu2_at(byte *wp, int n);
+ static void putu4_at(byte *wp, int n);
+ static void putu8_at(byte *wp, int64_t n);
+
+ // Private stuff
+ void reset_cur_classfile();
+ void write_classfile_tail();
+ void write_classfile_head();
+ void write_code();
+ void write_bc_ops();
+ void write_members(int num, int attrc); // attrc=ATTR_CONTEXT_FIELD/METHOD
+ int write_attrs(int attrc, uint64_t indexBits);
+
+ // The readers
+ void read_bands();
+ void read_file_header();
+ void read_cp();
+ void read_cp_counts(value_stream &hdr);
+ void read_attr_defs();
+ void read_ics();
+ void read_attrs(int attrc, int obj_count);
+ void read_classes();
+ void read_code_headers();
+ void read_bcs();
+ void read_bc_ops();
+ void read_files();
+ void read_Utf8_values(entry *cpMap, int len);
+ void read_single_words(band &cp_band, entry *cpMap, int len);
+ void read_double_words(band &cp_bands, entry *cpMap, int len);
+ void read_single_refs(band &cp_band, byte refTag, entry *cpMap, int len);
+ void read_double_refs(band &cp_band, byte ref1Tag, byte ref2Tag, entry *cpMap, int len);
+ void read_signature_values(entry *cpMap, int len);
};
diff --git a/libraries/pack200/src/unpack200.cpp b/libraries/pack200/src/unpack200.cpp
index 22b7f3b0..e8826f28 100644
--- a/libraries/pack200/src/unpack200.cpp
+++ b/libraries/pack200/src/unpack200.cpp
@@ -45,118 +45,118 @@
// Callback for fetching data, Unix style.
static int64_t read_input_via_stdio(unpacker *u, void *buf, int64_t minlen, int64_t maxlen)
{
- assert(u->infileptr != nullptr);
- assert(minlen <= maxlen); // don't talk nonsense
- int64_t numread = 0;
- char *bufptr = (char *)buf;
- while (numread < minlen)
- {
- // read available input, up to buf.length or maxlen
- int readlen = (1 << 16);
- if (readlen > (maxlen - numread))
- readlen = (int)(maxlen - numread);
- int nr = 0;
+ assert(u->infileptr != nullptr);
+ assert(minlen <= maxlen); // don't talk nonsense
+ int64_t numread = 0;
+ char *bufptr = (char *)buf;
+ while (numread < minlen)
+ {
+ // read available input, up to buf.length or maxlen
+ int readlen = (1 << 16);
+ if (readlen > (maxlen - numread))
+ readlen = (int)(maxlen - numread);
+ int nr = 0;
- nr = (int)fread(bufptr, 1, readlen, u->infileptr);
- if (nr <= 0)
- {
- if (errno != EINTR)
- break;
- nr = 0;
- }
- numread += nr;
- bufptr += nr;
- assert(numread <= maxlen);
- }
- return numread;
+ nr = (int)fread(bufptr, 1, readlen, u->infileptr);
+ if (nr <= 0)
+ {
+ if (errno != EINTR)
+ break;
+ nr = 0;
+ }
+ numread += nr;
+ bufptr += nr;
+ assert(numread <= maxlen);
+ }
+ return numread;
}
enum
{
- EOF_MAGIC = 0,
- BAD_MAGIC = -1
+ EOF_MAGIC = 0,
+ BAD_MAGIC = -1
};
static int read_magic(unpacker *u, char peek[], int peeklen)
{
- assert(peeklen == 4); // magic numbers are always 4 bytes
- int64_t nr = (u->read_input_fn)(u, peek, peeklen, peeklen);
- if (nr != peeklen)
- {
- return (nr == 0) ? EOF_MAGIC : BAD_MAGIC;
- }
- int magic = 0;
- for (int i = 0; i < peeklen; i++)
- {
- magic <<= 8;
- magic += peek[i] & 0xFF;
- }
- return magic;
+ assert(peeklen == 4); // magic numbers are always 4 bytes
+ int64_t nr = (u->read_input_fn)(u, peek, peeklen, peeklen);
+ if (nr != peeklen)
+ {
+ return (nr == 0) ? EOF_MAGIC : BAD_MAGIC;
+ }
+ int magic = 0;
+ for (int i = 0; i < peeklen; i++)
+ {
+ magic <<= 8;
+ magic += peek[i] & 0xFF;
+ }
+ return magic;
}
void unpack_200(FILE *input, FILE *output)
{
- unpacker u;
- u.init(read_input_via_stdio);
+ unpacker u;
+ u.init(read_input_via_stdio);
- // initialize jar output
- // the output takes ownership of the file handle
- jar jarout;
- jarout.init(&u);
- jarout.jarfp = output;
+ // initialize jar output
+ // the output takes ownership of the file handle
+ jar jarout;
+ jarout.init(&u);
+ jarout.jarfp = output;
- // the input doesn't
- u.infileptr = input;
+ // the input doesn't
+ u.infileptr = input;
- // read the magic!
- char peek[4];
- int magic;
- magic = read_magic(&u, peek, (int)sizeof(peek));
+ // read the magic!
+ char peek[4];
+ int magic;
+ magic = read_magic(&u, peek, (int)sizeof(peek));
- // if it is a gzip encoded file, we need an extra gzip input filter
- if ((magic & GZIP_MAGIC_MASK) == GZIP_MAGIC)
- {
- gunzip *gzin = NEW(gunzip, 1);
- gzin->init(&u);
- // FIXME: why the side effects? WHY?
- u.gzin->start(magic);
- u.start();
- }
- else
- {
- // otherwise, feed the bytes to the unpacker directly
- u.start(peek, sizeof(peek));
- }
+ // if it is a gzip encoded file, we need an extra gzip input filter
+ if ((magic & GZIP_MAGIC_MASK) == GZIP_MAGIC)
+ {
+ gunzip *gzin = NEW(gunzip, 1);
+ gzin->init(&u);
+ // FIXME: why the side effects? WHY?
+ u.gzin->start(magic);
+ u.start();
+ }
+ else
+ {
+ // otherwise, feed the bytes to the unpacker directly
+ u.start(peek, sizeof(peek));
+ }
- // Note: The checks to u.aborting() are necessary to gracefully
- // terminate processing when the first segment throws an error.
- for (;;)
- {
- // Each trip through this loop unpacks one segment
- // and then resets the unpacker.
- for (unpacker::file *filep; (filep = u.get_next_file()) != nullptr;)
- {
- u.write_file_to_jar(filep);
- }
+ // Note: The checks to u.aborting() are necessary to gracefully
+ // terminate processing when the first segment throws an error.
+ for (;;)
+ {
+ // Each trip through this loop unpacks one segment
+ // and then resets the unpacker.
+ for (unpacker::file *filep; (filep = u.get_next_file()) != nullptr;)
+ {
+ u.write_file_to_jar(filep);
+ }
- // Peek ahead for more data.
- magic = read_magic(&u, peek, (int)sizeof(peek));
- if (magic != (int)JAVA_PACKAGE_MAGIC)
- {
- // we do not feel strongly about this kind of thing...
- /*
- if (magic != EOF_MAGIC)
- unpack_abort("garbage after end of pack archive");
- */
- break; // all done
- }
+ // Peek ahead for more data.
+ magic = read_magic(&u, peek, (int)sizeof(peek));
+ if (magic != (int)JAVA_PACKAGE_MAGIC)
+ {
+ // we do not feel strongly about this kind of thing...
+ /*
+ if (magic != EOF_MAGIC)
+ unpack_abort("garbage after end of pack archive");
+ */
+ break; // all done
+ }
- // Release all storage from parsing the old segment.
- u.reset();
- // Restart, beginning with the peek-ahead.
- u.start(peek, sizeof(peek));
- }
- u.finish();
- u.free(); // tidy up malloc blocks
- fclose(input);
+ // Release all storage from parsing the old segment.
+ u.reset();
+ // Restart, beginning with the peek-ahead.
+ u.start(peek, sizeof(peek));
+ }
+ u.finish();
+ u.free(); // tidy up malloc blocks
+ fclose(input);
}
diff --git a/libraries/pack200/src/utils.cpp b/libraries/pack200/src/utils.cpp
index 0b7d91ca..fd6dad60 100644
--- a/libraries/pack200/src/utils.cpp
+++ b/libraries/pack200/src/utils.cpp
@@ -50,22 +50,22 @@
void *must_malloc(size_t size)
{
- size_t msize = size;
- void *ptr = (msize > PSIZE_MAX) ? nullptr : malloc(msize);
- if (ptr != nullptr)
- {
- memset(ptr, 0, size);
- }
- else
- {
- throw std::runtime_error(ERROR_ENOMEM);
- }
- return ptr;
+ size_t msize = size;
+ void *ptr = (msize > PSIZE_MAX) ? nullptr : malloc(msize);
+ if (ptr != nullptr)
+ {
+ memset(ptr, 0, size);
+ }
+ else
+ {
+ throw std::runtime_error(ERROR_ENOMEM);
+ }
+ return ptr;
}
void unpack_abort(const char *msg)
{
- if (msg == nullptr)
- msg = "corrupt pack file or internal error";
- throw std::runtime_error(msg);
+ if (msg == nullptr)
+ msg = "corrupt pack file or internal error";
+ throw std::runtime_error(msg);
}
diff --git a/libraries/pack200/src/utils.h b/libraries/pack200/src/utils.h
index 5a3dc8f6..3bd2dae7 100644
--- a/libraries/pack200/src/utils.h
+++ b/libraries/pack200/src/utils.h
@@ -35,17 +35,17 @@ void *must_malloc(size_t size);
inline size_t scale_size(size_t size, size_t scale)
{
- return (size > PSIZE_MAX / scale) ? OVERFLOW : size * scale;
+ return (size > PSIZE_MAX / scale) ? OVERFLOW : size * scale;
}
inline size_t add_size(size_t size1, size_t size2)
{
- return ((size1 | size2 | (size1 + size2)) > PSIZE_MAX) ? OVERFLOW : size1 + size2;
+ return ((size1 | size2 | (size1 + size2)) > PSIZE_MAX) ? OVERFLOW : size1 + size2;
}
inline size_t add_size(size_t size1, size_t size2, int size3)
{
- return add_size(add_size(size1, size2), size3);
+ return add_size(add_size(size1, size2), size3);
}
struct unpacker;
diff --git a/libraries/pack200/src/zip.cpp b/libraries/pack200/src/zip.cpp
index 32e8bd50..13b955cc 100644
--- a/libraries/pack200/src/zip.cpp
+++ b/libraries/pack200/src/zip.cpp
@@ -52,7 +52,7 @@
inline uint32_t jar::get_crc32(uint32_t c, uchar *ptr, uint32_t len)
{
- return crc32(c, ptr, len);
+ return crc32(c, ptr, len);
}
// FIXME: this is bullshit. Do real endianness detection.
@@ -68,175 +68,175 @@ inline uint32_t jar::get_crc32(uint32_t c, uchar *ptr, uint32_t len)
void jar::init(unpacker *u_)
{
- BYTES_OF(*this).clear();
- u = u_;
- u->jarout = this;
+ BYTES_OF(*this).clear();
+ u = u_;
+ u->jarout = this;
}
// Write data to the ZIP output stream.
void jar::write_data(void *buff, int len)
{
- while (len > 0)
- {
- int rc = (int)fwrite(buff, 1, len, jarfp);
- if (rc <= 0)
- {
- fprintf(stderr, "Error: write on output file failed err=%d\n", errno);
- exit(1); // Called only from the native standalone unpacker
- }
- output_file_offset += rc;
- buff = ((char *)buff) + rc;
- len -= rc;
- }
+ while (len > 0)
+ {
+ int rc = (int)fwrite(buff, 1, len, jarfp);
+ if (rc <= 0)
+ {
+ fprintf(stderr, "Error: write on output file failed err=%d\n", errno);
+ exit(1); // Called only from the native standalone unpacker
+ }
+ output_file_offset += rc;
+ buff = ((char *)buff) + rc;
+ len -= rc;
+ }
}
void jar::add_to_jar_directory(const char *fname, bool store, int modtime, int len, int clen,
- uint32_t crc)
+ uint32_t crc)
{
- uint32_t fname_length = (uint32_t)strlen(fname);
- ushort header[23];
- if (modtime == 0)
- modtime = default_modtime;
- uint32_t dostime = get_dostime(modtime);
-
- header[0] = (ushort)SWAP_BYTES(0x4B50);
- header[1] = (ushort)SWAP_BYTES(0x0201);
- header[2] = (ushort)SWAP_BYTES(0xA);
-
- // required version
- header[3] = (ushort)SWAP_BYTES(0xA);
-
- // flags 02 = maximum sub-compression flag
- header[4] = (store) ? 0x0 : SWAP_BYTES(0x2);
-
- // Compression method 8=deflate.
- header[5] = (store) ? 0x0 : SWAP_BYTES(0x08);
-
- // Last modified date and time.
- header[6] = (ushort)GET_INT_LO(dostime);
- header[7] = (ushort)GET_INT_HI(dostime);
-
- // CRC
- header[8] = (ushort)GET_INT_LO(crc);
- header[9] = (ushort)GET_INT_HI(crc);
-
- // Compressed length:
- header[10] = (ushort)GET_INT_LO(clen);
- header[11] = (ushort)GET_INT_HI(clen);
-
- // Uncompressed length.
- header[12] = (ushort)GET_INT_LO(len);
- header[13] = (ushort)GET_INT_HI(len);
-
- // Filename length
- header[14] = (ushort)SWAP_BYTES(fname_length);
- // So called "extra field" length.
- header[15] = 0;
- // So called "comment" length.
- header[16] = 0;
- // Disk number start
- header[17] = 0;
- // File flags => binary
- header[18] = 0;
- // More file flags
- header[19] = 0;
- header[20] = 0;
- // Offset within ZIP file.
- header[21] = (ushort)GET_INT_LO(output_file_offset);
- header[22] = (ushort)GET_INT_HI(output_file_offset);
-
- // Copy the whole thing into the central directory.
- central_directory.append(header, sizeof(header));
-
- // Copy the fname to the header.
- central_directory.append(fname, fname_length);
-
- central_directory_count++;
+ uint32_t fname_length = (uint32_t)strlen(fname);
+ ushort header[23];
+ if (modtime == 0)
+ modtime = default_modtime;
+ uint32_t dostime = get_dostime(modtime);
+
+ header[0] = (ushort)SWAP_BYTES(0x4B50);
+ header[1] = (ushort)SWAP_BYTES(0x0201);
+ header[2] = (ushort)SWAP_BYTES(0xA);
+
+ // required version
+ header[3] = (ushort)SWAP_BYTES(0xA);
+
+ // flags 02 = maximum sub-compression flag
+ header[4] = (store) ? 0x0 : SWAP_BYTES(0x2);
+
+ // Compression method 8=deflate.
+ header[5] = (store) ? 0x0 : SWAP_BYTES(0x08);
+
+ // Last modified date and time.
+ header[6] = (ushort)GET_INT_LO(dostime);
+ header[7] = (ushort)GET_INT_HI(dostime);
+
+ // CRC
+ header[8] = (ushort)GET_INT_LO(crc);
+ header[9] = (ushort)GET_INT_HI(crc);
+
+ // Compressed length:
+ header[10] = (ushort)GET_INT_LO(clen);
+ header[11] = (ushort)GET_INT_HI(clen);
+
+ // Uncompressed length.
+ header[12] = (ushort)GET_INT_LO(len);
+ header[13] = (ushort)GET_INT_HI(len);
+
+ // Filename length
+ header[14] = (ushort)SWAP_BYTES(fname_length);
+ // So called "extra field" length.
+ header[15] = 0;
+ // So called "comment" length.
+ header[16] = 0;
+ // Disk number start
+ header[17] = 0;
+ // File flags => binary
+ header[18] = 0;
+ // More file flags
+ header[19] = 0;
+ header[20] = 0;
+ // Offset within ZIP file.
+ header[21] = (ushort)GET_INT_LO(output_file_offset);
+ header[22] = (ushort)GET_INT_HI(output_file_offset);
+
+ // Copy the whole thing into the central directory.
+ central_directory.append(header, sizeof(header));
+
+ // Copy the fname to the header.
+ central_directory.append(fname, fname_length);
+
+ central_directory_count++;
}
void jar::write_jar_header(const char *fname, bool store, int modtime, int len, int clen,
- uint32_t crc)
+ uint32_t crc)
{
- uint32_t fname_length = (uint32_t)strlen(fname);
- ushort header[15];
- if (modtime == 0)
- modtime = default_modtime;
- uint32_t dostime = get_dostime(modtime);
+ uint32_t fname_length = (uint32_t)strlen(fname);
+ ushort header[15];
+ if (modtime == 0)
+ modtime = default_modtime;
+ uint32_t dostime = get_dostime(modtime);
- // ZIP LOC magic.
- header[0] = (ushort)SWAP_BYTES(0x4B50);
- header[1] = (ushort)SWAP_BYTES(0x0403);
+ // ZIP LOC magic.
+ header[0] = (ushort)SWAP_BYTES(0x4B50);
+ header[1] = (ushort)SWAP_BYTES(0x0403);
- // Version
- header[2] = (ushort)SWAP_BYTES(0xA);
+ // Version
+ header[2] = (ushort)SWAP_BYTES(0xA);
- // flags 02 = maximum sub-compression flag
- header[3] = (store) ? 0x0 : SWAP_BYTES(0x2);
+ // flags 02 = maximum sub-compression flag
+ header[3] = (store) ? 0x0 : SWAP_BYTES(0x2);
- // Compression method = deflate
- header[4] = (store) ? 0x0 : SWAP_BYTES(0x08);
+ // Compression method = deflate
+ header[4] = (store) ? 0x0 : SWAP_BYTES(0x08);
- // Last modified date and time.
- header[5] = (ushort)GET_INT_LO(dostime);
- header[6] = (ushort)GET_INT_HI(dostime);
+ // Last modified date and time.
+ header[5] = (ushort)GET_INT_LO(dostime);
+ header[6] = (ushort)GET_INT_HI(dostime);
- // CRC
- header[7] = (ushort)GET_INT_LO(crc);
- header[8] = (ushort)GET_INT_HI(crc);
+ // CRC
+ header[7] = (ushort)GET_INT_LO(crc);
+ header[8] = (ushort)GET_INT_HI(crc);
- // Compressed length:
- header[9] = (ushort)GET_INT_LO(clen);
- header[10] = (ushort)GET_INT_HI(clen);
+ // Compressed length:
+ header[9] = (ushort)GET_INT_LO(clen);
+ header[10] = (ushort)GET_INT_HI(clen);
- // Uncompressed length.
- header[11] = (ushort)GET_INT_LO(len);
- header[12] = (ushort)GET_INT_HI(len);
+ // Uncompressed length.
+ header[11] = (ushort)GET_INT_LO(len);
+ header[12] = (ushort)GET_INT_HI(len);
- // Filename length
- header[13] = (ushort)SWAP_BYTES(fname_length);
- // So called "extra field" length.
- header[14] = 0;
+ // Filename length
+ header[13] = (ushort)SWAP_BYTES(fname_length);
+ // So called "extra field" length.
+ header[14] = 0;
- // Write the LOC header to the output file.
- write_data(header, (int)sizeof(header));
+ // Write the LOC header to the output file.
+ write_data(header, (int)sizeof(header));
- // Copy the fname to the header.
- write_data((char *)fname, (int)fname_length);
+ // Copy the fname to the header.
+ write_data((char *)fname, (int)fname_length);
}
void jar::write_central_directory()
{
- bytes mc;
- mc.set("PACK200");
-
- ushort header[11];
-
- // Create the End of Central Directory structure.
- header[0] = (ushort)SWAP_BYTES(0x4B50);
- header[1] = (ushort)SWAP_BYTES(0x0605);
- // disk numbers
- header[2] = 0;
- header[3] = 0;
- // Number of entries in central directory.
- header[4] = (ushort)SWAP_BYTES(central_directory_count);
- header[5] = (ushort)SWAP_BYTES(central_directory_count);
- // Size of the central directory}
- header[6] = (ushort)GET_INT_LO((int)central_directory.size());
- header[7] = (ushort)GET_INT_HI((int)central_directory.size());
- // Offset of central directory within disk.
- header[8] = (ushort)GET_INT_LO(output_file_offset);
- header[9] = (ushort)GET_INT_HI(output_file_offset);
- // zipfile comment length;
- header[10] = (ushort)SWAP_BYTES((int)mc.len);
-
- // Write the central directory.
- write_data(central_directory.b);
-
- // Write the End of Central Directory structure.
- write_data(header, (int)sizeof(header));
-
- // Write the comment.
- write_data(mc);
+ bytes mc;
+ mc.set("PACK200");
+
+ ushort header[11];
+
+ // Create the End of Central Directory structure.
+ header[0] = (ushort)SWAP_BYTES(0x4B50);
+ header[1] = (ushort)SWAP_BYTES(0x0605);
+ // disk numbers
+ header[2] = 0;
+ header[3] = 0;
+ // Number of entries in central directory.
+ header[4] = (ushort)SWAP_BYTES(central_directory_count);
+ header[5] = (ushort)SWAP_BYTES(central_directory_count);
+ // Size of the central directory}
+ header[6] = (ushort)GET_INT_LO((int)central_directory.size());
+ header[7] = (ushort)GET_INT_HI((int)central_directory.size());
+ // Offset of central directory within disk.
+ header[8] = (ushort)GET_INT_LO(output_file_offset);
+ header[9] = (ushort)GET_INT_HI(output_file_offset);
+ // zipfile comment length;
+ header[10] = (ushort)SWAP_BYTES((int)mc.len);
+
+ // Write the central directory.
+ write_data(central_directory.b);
+
+ // Write the End of Central Directory structure.
+ write_data(header, (int)sizeof(header));
+
+ // Write the comment.
+ write_data(mc);
}
// Public API
@@ -244,74 +244,74 @@ void jar::write_central_directory()
// Open a Jar file and initialize.
void jar::openJarFile(const char *fname)
{
- if (!jarfp)
- {
- jarfp = fopen(fname, "wb");
- if (!jarfp)
- {
- fprintf(stderr, "Error: Could not open jar file: %s\n", fname);
- exit(3); // Called only from the native standalone unpacker
- }
- }
+ if (!jarfp)
+ {
+ jarfp = fopen(fname, "wb");
+ if (!jarfp)
+ {
+ fprintf(stderr, "Error: Could not open jar file: %s\n", fname);
+ exit(3); // Called only from the native standalone unpacker
+ }
+ }
}
// Add a ZIP entry and copy the file data
void jar::addJarEntry(const char *fname, bool deflate_hint, int modtime, bytes &head,
- bytes &tail)
+ bytes &tail)
{
- int len = (int)(head.len + tail.len);
- int clen = 0;
-
- uint32_t crc = get_crc32(0, Z_NULL, 0);
- if (head.len != 0)
- crc = get_crc32(crc, (uchar *)head.ptr, (uint32_t)head.len);
- if (tail.len != 0)
- crc = get_crc32(crc, (uchar *)tail.ptr, (uint32_t)tail.len);
-
- bool deflate = (deflate_hint && len > 0);
-
- if (deflate)
- {
- if (deflate_bytes(head, tail) == false)
- {
- deflate = false;
- }
- }
- clen = (int)((deflate) ? deflated.size() : len);
- add_to_jar_directory(fname, !deflate, modtime, len, clen, crc);
- write_jar_header(fname, !deflate, modtime, len, clen, crc);
-
- if (deflate)
- {
- write_data(deflated.b);
- }
- else
- {
- write_data(head);
- write_data(tail);
- }
+ int len = (int)(head.len + tail.len);
+ int clen = 0;
+
+ uint32_t crc = get_crc32(0, Z_NULL, 0);
+ if (head.len != 0)
+ crc = get_crc32(crc, (uchar *)head.ptr, (uint32_t)head.len);
+ if (tail.len != 0)
+ crc = get_crc32(crc, (uchar *)tail.ptr, (uint32_t)tail.len);
+
+ bool deflate = (deflate_hint && len > 0);
+
+ if (deflate)
+ {
+ if (deflate_bytes(head, tail) == false)
+ {
+ deflate = false;
+ }
+ }
+ clen = (int)((deflate) ? deflated.size() : len);
+ add_to_jar_directory(fname, !deflate, modtime, len, clen, crc);
+ write_jar_header(fname, !deflate, modtime, len, clen, crc);
+
+ if (deflate)
+ {
+ write_data(deflated.b);
+ }
+ else
+ {
+ write_data(head);
+ write_data(tail);
+ }
}
// Add a ZIP entry for a directory name no data
void jar::addDirectoryToJarFile(const char *dir_name)
{
- bool store = true;
- add_to_jar_directory((const char *)dir_name, store, default_modtime, 0, 0, 0);
- write_jar_header((const char *)dir_name, store, default_modtime, 0, 0, 0);
+ bool store = true;
+ add_to_jar_directory((const char *)dir_name, store, default_modtime, 0, 0, 0);
+ write_jar_header((const char *)dir_name, store, default_modtime, 0, 0, 0);
}
// Write out the central directory and close the jar file.
void jar::closeJarFile(bool central)
{
- if (jarfp)
- {
- fflush(jarfp);
- if (central)
- write_central_directory();
- fflush(jarfp);
- fclose(jarfp);
- }
- reset();
+ if (jarfp)
+ {
+ fflush(jarfp);
+ if (central)
+ write_central_directory();
+ fflush(jarfp);
+ fclose(jarfp);
+ }
+ reset();
}
/* Convert the date y/n/d and time h:m:s to a four byte DOS date and
@@ -320,9 +320,9 @@ void jar::closeJarFile(bool central)
*/
inline uint32_t jar::dostime(int y, int n, int d, int h, int m, int s)
{
- return y < 1980 ? dostime(1980, 1, 1, 0, 0, 0)
- : (((uint32_t)y - 1980) << 25) | ((uint32_t)n << 21) | ((uint32_t)d << 16) |
- ((uint32_t)h << 11) | ((uint32_t)m << 5) | ((uint32_t)s >> 1);
+ return y < 1980 ? dostime(1980, 1, 1, 0, 0, 0)
+ : (((uint32_t)y - 1980) << 25) | ((uint32_t)n << 21) | ((uint32_t)d << 16) |
+ ((uint32_t)h << 11) | ((uint32_t)m << 5) | ((uint32_t)s >> 1);
}
/*
#ifdef _REENTRANT // solaris
@@ -336,20 +336,20 @@ extern "C" struct tm *gmtime_r(const time_t *, struct tm *);
*/
uint32_t jar::get_dostime(int modtime)
{
- // see defines.h
- if (modtime != 0 && modtime == modtime_cache)
- return dostime_cache;
- if (modtime != 0 && default_modtime == 0)
- default_modtime = modtime; // catch a reasonable default
- time_t t = modtime;
- struct tm sbuf;
- (void)memset((void *)&sbuf, 0, sizeof(sbuf));
- struct tm *s = gmtime_r(&t, &sbuf);
- modtime_cache = modtime;
- dostime_cache =
- dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday, s->tm_hour, s->tm_min, s->tm_sec);
- // printf("modtime %d => %d\n", modtime_cache, dostime_cache);
- return dostime_cache;
+ // see defines.h
+ if (modtime != 0 && modtime == modtime_cache)
+ return dostime_cache;
+ if (modtime != 0 && default_modtime == 0)
+ default_modtime = modtime; // catch a reasonable default
+ time_t t = modtime;
+ struct tm sbuf;
+ (void)memset((void *)&sbuf, 0, sizeof(sbuf));
+ struct tm *s = gmtime_r(&t, &sbuf);
+ modtime_cache = modtime;
+ dostime_cache =
+ dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday, s->tm_hour, s->tm_min, s->tm_sec);
+ // printf("modtime %d => %d\n", modtime_cache, dostime_cache);
+ return dostime_cache;
}
/* Returns true on success, and will set the clen to the compressed
@@ -358,232 +358,232 @@ uint32_t jar::get_dostime(int modtime)
*/
bool jar::deflate_bytes(bytes &head, bytes &tail)
{
- int len = (int)(head.len + tail.len);
-
- z_stream zs;
- BYTES_OF(zs).clear();
-
- // NOTE: the window size should always be -MAX_WBITS normally -15.
- // unzip/zipup.c and java/Deflater.c
-
- int error =
- deflateInit2(&zs, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
- if (error != Z_OK)
- {
- /*
- switch (error)
- {
- case Z_MEM_ERROR:
- PRINTCR((2, "Error: deflate error : Out of memory \n"));
- break;
- case Z_STREAM_ERROR:
- PRINTCR((2, "Error: deflate error : Invalid compression level \n"));
- break;
- case Z_VERSION_ERROR:
- PRINTCR((2, "Error: deflate error : Invalid version\n"));
- break;
- default:
- PRINTCR((2, "Error: Internal deflate error error = %d\n", error));
- }
- */
- return false;
- }
-
- deflated.empty();
- zs.next_out = (uchar *)deflated.grow(len + (len / 2));
- zs.avail_out = (int)deflated.size();
-
- zs.next_in = (uchar *)head.ptr;
- zs.avail_in = (int)head.len;
-
- bytes *first = &head;
- bytes *last = &tail;
- if (last->len == 0)
- {
- first = nullptr;
- last = &head;
- }
- else if (first->len == 0)
- {
- first = nullptr;
- }
-
- if (first != nullptr && error == Z_OK)
- {
- zs.next_in = (uchar *)first->ptr;
- zs.avail_in = (int)first->len;
- error = deflate(&zs, Z_NO_FLUSH);
- }
- if (error == Z_OK)
- {
- zs.next_in = (uchar *)last->ptr;
- zs.avail_in = (int)last->len;
- error = deflate(&zs, Z_FINISH);
- }
- if (error == Z_STREAM_END)
- {
- if (len > (int)zs.total_out)
- {
- deflated.b.len = zs.total_out;
- deflateEnd(&zs);
- return true;
- }
- deflateEnd(&zs);
- return false;
- }
-
- deflateEnd(&zs);
- return false;
+ int len = (int)(head.len + tail.len);
+
+ z_stream zs;
+ BYTES_OF(zs).clear();
+
+ // NOTE: the window size should always be -MAX_WBITS normally -15.
+ // unzip/zipup.c and java/Deflater.c
+
+ int error =
+ deflateInit2(&zs, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
+ if (error != Z_OK)
+ {
+ /*
+ switch (error)
+ {
+ case Z_MEM_ERROR:
+ PRINTCR((2, "Error: deflate error : Out of memory \n"));
+ break;
+ case Z_STREAM_ERROR:
+ PRINTCR((2, "Error: deflate error : Invalid compression level \n"));
+ break;
+ case Z_VERSION_ERROR:
+ PRINTCR((2, "Error: deflate error : Invalid version\n"));
+ break;
+ default:
+ PRINTCR((2, "Error: Internal deflate error error = %d\n", error));
+ }
+ */
+ return false;
+ }
+
+ deflated.empty();
+ zs.next_out = (uchar *)deflated.grow(len + (len / 2));
+ zs.avail_out = (int)deflated.size();
+
+ zs.next_in = (uchar *)head.ptr;
+ zs.avail_in = (int)head.len;
+
+ bytes *first = &head;
+ bytes *last = &tail;
+ if (last->len == 0)
+ {
+ first = nullptr;
+ last = &head;
+ }
+ else if (first->len == 0)
+ {
+ first = nullptr;
+ }
+
+ if (first != nullptr && error == Z_OK)
+ {
+ zs.next_in = (uchar *)first->ptr;
+ zs.avail_in = (int)first->len;
+ error = deflate(&zs, Z_NO_FLUSH);
+ }
+ if (error == Z_OK)
+ {
+ zs.next_in = (uchar *)last->ptr;
+ zs.avail_in = (int)last->len;
+ error = deflate(&zs, Z_FINISH);
+ }
+ if (error == Z_STREAM_END)
+ {
+ if (len > (int)zs.total_out)
+ {
+ deflated.b.len = zs.total_out;
+ deflateEnd(&zs);
+ return true;
+ }
+ deflateEnd(&zs);
+ return false;
+ }
+
+ deflateEnd(&zs);
+ return false;
}
// Callback for fetching data from a GZIP input stream
static int64_t read_input_via_gzip(unpacker *u, void *buf, int64_t minlen, int64_t maxlen)
{
- assert(minlen <= maxlen); // don't talk nonsense
- int64_t numread = 0;
- char *bufptr = (char *)buf;
- char *inbuf = u->gzin->inbuf;
- size_t inbuflen = sizeof(u->gzin->inbuf);
- unpacker::read_input_fn_t read_gzin_fn = (unpacker::read_input_fn_t)u->gzin->read_input_fn;
- z_stream &zs = *(z_stream *)u->gzin->zstream;
- while (numread < minlen)
- {
- int readlen = (1 << 16); // pretty arbitrary
- if (readlen > (maxlen - numread))
- readlen = (int)(maxlen - numread);
- zs.next_out = (uchar *)bufptr;
- zs.avail_out = readlen;
- if (zs.avail_in == 0)
- {
- zs.avail_in = (int)read_gzin_fn(u, inbuf, 1, inbuflen);
- zs.next_in = (uchar *)inbuf;
- }
- int error = inflate(&zs, Z_NO_FLUSH);
- if (error != Z_OK && error != Z_STREAM_END)
- {
- unpack_abort("error inflating input");
- break;
- }
- int nr = readlen - zs.avail_out;
- numread += nr;
- bufptr += nr;
- assert(numread <= maxlen);
- if (error == Z_STREAM_END)
- {
- enum
- {
- TRAILER_LEN = 8
- };
- // skip 8-byte trailer
- if (zs.avail_in >= TRAILER_LEN)
- {
- zs.avail_in -= TRAILER_LEN;
- }
- else
- {
- // Bug: 5023768,we read past the TRAILER_LEN to see if there is
- // any extraneous data, as we dont support concatenated .gz
- // files just yet.
- int extra = (int)read_gzin_fn(u, inbuf, 1, inbuflen);
- zs.avail_in += extra - TRAILER_LEN;
- }
- // %%% should check final CRC and length here
- // %%% should check for concatenated *.gz files here
- if (zs.avail_in > 0)
- unpack_abort("garbage after end of deflated input stream");
- // pop this filter off:
- u->gzin->free();
- break;
- }
- }
-
- // fprintf(u->errstrm, "readInputFn(%d,%d) => %d (gunzip)\n",
- // (int)minlen, (int)maxlen, (int)numread);
- return numread;
+ assert(minlen <= maxlen); // don't talk nonsense
+ int64_t numread = 0;
+ char *bufptr = (char *)buf;
+ char *inbuf = u->gzin->inbuf;
+ size_t inbuflen = sizeof(u->gzin->inbuf);
+ unpacker::read_input_fn_t read_gzin_fn = (unpacker::read_input_fn_t)u->gzin->read_input_fn;
+ z_stream &zs = *(z_stream *)u->gzin->zstream;
+ while (numread < minlen)
+ {
+ int readlen = (1 << 16); // pretty arbitrary
+ if (readlen > (maxlen - numread))
+ readlen = (int)(maxlen - numread);
+ zs.next_out = (uchar *)bufptr;
+ zs.avail_out = readlen;
+ if (zs.avail_in == 0)
+ {
+ zs.avail_in = (int)read_gzin_fn(u, inbuf, 1, inbuflen);
+ zs.next_in = (uchar *)inbuf;
+ }
+ int error = inflate(&zs, Z_NO_FLUSH);
+ if (error != Z_OK && error != Z_STREAM_END)
+ {
+ unpack_abort("error inflating input");
+ break;
+ }
+ int nr = readlen - zs.avail_out;
+ numread += nr;
+ bufptr += nr;
+ assert(numread <= maxlen);
+ if (error == Z_STREAM_END)
+ {
+ enum
+ {
+ TRAILER_LEN = 8
+ };
+ // skip 8-byte trailer
+ if (zs.avail_in >= TRAILER_LEN)
+ {
+ zs.avail_in -= TRAILER_LEN;
+ }
+ else
+ {
+ // Bug: 5023768,we read past the TRAILER_LEN to see if there is
+ // any extraneous data, as we dont support concatenated .gz
+ // files just yet.
+ int extra = (int)read_gzin_fn(u, inbuf, 1, inbuflen);
+ zs.avail_in += extra - TRAILER_LEN;
+ }
+ // %%% should check final CRC and length here
+ // %%% should check for concatenated *.gz files here
+ if (zs.avail_in > 0)
+ unpack_abort("garbage after end of deflated input stream");
+ // pop this filter off:
+ u->gzin->free();
+ break;
+ }
+ }
+
+ // fprintf(u->errstrm, "readInputFn(%d,%d) => %d (gunzip)\n",
+ // (int)minlen, (int)maxlen, (int)numread);
+ return numread;
}
void gunzip::init(unpacker *u_)
{
- BYTES_OF(*this).clear();
- u = u_;
- assert(u->gzin == nullptr); // once only, please
- read_input_fn = (void *)u->read_input_fn;
- zstream = NEW(z_stream, 1);
- u->gzin = this;
- u->read_input_fn = read_input_via_gzip;
+ BYTES_OF(*this).clear();
+ u = u_;
+ assert(u->gzin == nullptr); // once only, please
+ read_input_fn = (void *)u->read_input_fn;
+ zstream = NEW(z_stream, 1);
+ u->gzin = this;
+ u->read_input_fn = read_input_via_gzip;
}
void gunzip::start(int magic)
{
- assert((magic & GZIP_MAGIC_MASK) == GZIP_MAGIC);
- int gz_flg = (magic & 0xFF); // keep "flg", discard other 3 bytes
- enum
- {
- FHCRC = (1 << 1),
- FEXTRA = (1 << 2),
- FNAME = (1 << 3),
- FCOMMENT = (1 << 4)
- };
- char gz_mtime[4];
- char gz_xfl[1];
- char gz_os[1];
- char gz_extra_len[2];
- char gz_hcrc[2];
- char gz_ignore;
- // do not save extra, name, comment
- read_fixed_field(gz_mtime, sizeof(gz_mtime));
- read_fixed_field(gz_xfl, sizeof(gz_xfl));
- read_fixed_field(gz_os, sizeof(gz_os));
- if (gz_flg & FEXTRA)
- {
- read_fixed_field(gz_extra_len, sizeof(gz_extra_len));
- int extra_len = gz_extra_len[0] & 0xFF;
- extra_len += (gz_extra_len[1] & 0xFF) << 8;
- for (; extra_len > 0; extra_len--)
- {
- read_fixed_field(&gz_ignore, 1);
- }
- }
- int null_terms = 0;
- if (gz_flg & FNAME)
- null_terms++;
- if (gz_flg & FCOMMENT)
- null_terms++;
- for (; null_terms; null_terms--)
- {
- for (;;)
- {
- gz_ignore = 0;
- read_fixed_field(&gz_ignore, 1);
- if (gz_ignore == 0)
- break;
- }
- }
- if (gz_flg & FHCRC)
- read_fixed_field(gz_hcrc, sizeof(gz_hcrc));
-
- // now the input stream is ready to read into the inflater
- int error = inflateInit2((z_stream *)zstream, -MAX_WBITS);
- if (error != Z_OK)
- {
- unpack_abort("cannot create input");
- }
+ assert((magic & GZIP_MAGIC_MASK) == GZIP_MAGIC);
+ int gz_flg = (magic & 0xFF); // keep "flg", discard other 3 bytes
+ enum
+ {
+ FHCRC = (1 << 1),
+ FEXTRA = (1 << 2),
+ FNAME = (1 << 3),
+ FCOMMENT = (1 << 4)
+ };
+ char gz_mtime[4];
+ char gz_xfl[1];
+ char gz_os[1];
+ char gz_extra_len[2];
+ char gz_hcrc[2];
+ char gz_ignore;
+ // do not save extra, name, comment
+ read_fixed_field(gz_mtime, sizeof(gz_mtime));
+ read_fixed_field(gz_xfl, sizeof(gz_xfl));
+ read_fixed_field(gz_os, sizeof(gz_os));
+ if (gz_flg & FEXTRA)
+ {
+ read_fixed_field(gz_extra_len, sizeof(gz_extra_len));
+ int extra_len = gz_extra_len[0] & 0xFF;
+ extra_len += (gz_extra_len[1] & 0xFF) << 8;
+ for (; extra_len > 0; extra_len--)
+ {
+ read_fixed_field(&gz_ignore, 1);
+ }
+ }
+ int null_terms = 0;
+ if (gz_flg & FNAME)
+ null_terms++;
+ if (gz_flg & FCOMMENT)
+ null_terms++;
+ for (; null_terms; null_terms--)
+ {
+ for (;;)
+ {
+ gz_ignore = 0;
+ read_fixed_field(&gz_ignore, 1);
+ if (gz_ignore == 0)
+ break;
+ }
+ }
+ if (gz_flg & FHCRC)
+ read_fixed_field(gz_hcrc, sizeof(gz_hcrc));
+
+ // now the input stream is ready to read into the inflater
+ int error = inflateInit2((z_stream *)zstream, -MAX_WBITS);
+ if (error != Z_OK)
+ {
+ unpack_abort("cannot create input");
+ }
}
void gunzip::free()
{
- assert(u->gzin == this);
- u->gzin = nullptr;
- u->read_input_fn = (unpacker::read_input_fn_t) this->read_input_fn;
- inflateEnd((z_stream *)zstream);
- ::free(zstream);
- zstream = nullptr;
- ::free(this);
+ assert(u->gzin == this);
+ u->gzin = nullptr;
+ u->read_input_fn = (unpacker::read_input_fn_t) this->read_input_fn;
+ inflateEnd((z_stream *)zstream);
+ ::free(zstream);
+ zstream = nullptr;
+ ::free(this);
}
void gunzip::read_fixed_field(char *buf, size_t buflen)
{
- int64_t nr = ((unpacker::read_input_fn_t)read_input_fn)(u, buf, buflen, buflen);
- if ((size_t)nr != buflen)
- unpack_abort("short stream header");
+ int64_t nr = ((unpacker::read_input_fn_t)read_input_fn)(u, buf, buflen, buflen);
+ if ((size_t)nr != buflen)
+ unpack_abort("short stream header");
}
diff --git a/libraries/pack200/src/zip.h b/libraries/pack200/src/zip.h
index 67ec24da..5fcbae94 100644
--- a/libraries/pack200/src/zip.h
+++ b/libraries/pack200/src/zip.h
@@ -31,80 +31,80 @@ struct unpacker;
struct jar
{
- // JAR file writer
- FILE *jarfp;
- int default_modtime;
-
- // Used by unix2dostime:
- int modtime_cache;
- uint32_t dostime_cache;
-
- // Private members
- fillbytes central_directory;
- ushort central_directory_count;
- uint32_t output_file_offset;
- fillbytes deflated; // temporary buffer
-
- // pointer to outer unpacker, for error checks etc.
- unpacker *u;
-
- // Public Methods
- void openJarFile(const char *fname);
- void addJarEntry(const char *fname, bool deflate_hint, int modtime, bytes &head,
- bytes &tail);
- void addDirectoryToJarFile(const char *dir_name);
- void closeJarFile(bool central);
-
- void init(unpacker *u_);
-
- void free()
- {
- central_directory.free();
- deflated.free();
- }
-
- void reset()
- {
- free();
- init(u);
- }
-
- // Private Methods
- void write_data(void *ptr, int len);
- void write_data(bytes &b)
- {
- write_data(b.ptr, (int)b.len);
- }
- void add_to_jar_directory(const char *fname, bool store, int modtime, int len, int clen,
- uint32_t crc);
- void write_jar_header(const char *fname, bool store, int modtime, int len, int clen,
- unsigned int crc);
- void write_central_directory();
- uint32_t dostime(int y, int n, int d, int h, int m, int s);
- uint32_t get_dostime(int modtime);
-
- // The definitions of these depend on the NO_ZLIB option:
- bool deflate_bytes(bytes &head, bytes &tail);
- static uint32_t get_crc32(uint32_t c, unsigned char *ptr, uint32_t len);
+ // JAR file writer
+ FILE *jarfp;
+ int default_modtime;
+
+ // Used by unix2dostime:
+ int modtime_cache;
+ uint32_t dostime_cache;
+
+ // Private members
+ fillbytes central_directory;
+ ushort central_directory_count;
+ uint32_t output_file_offset;
+ fillbytes deflated; // temporary buffer
+
+ // pointer to outer unpacker, for error checks etc.
+ unpacker *u;
+
+ // Public Methods
+ void openJarFile(const char *fname);
+ void addJarEntry(const char *fname, bool deflate_hint, int modtime, bytes &head,
+ bytes &tail);
+ void addDirectoryToJarFile(const char *dir_name);
+ void closeJarFile(bool central);
+
+ void init(unpacker *u_);
+
+ void free()
+ {
+ central_directory.free();
+ deflated.free();
+ }
+
+ void reset()
+ {
+ free();
+ init(u);
+ }
+
+ // Private Methods
+ void write_data(void *ptr, int len);
+ void write_data(bytes &b)
+ {
+ write_data(b.ptr, (int)b.len);
+ }
+ void add_to_jar_directory(const char *fname, bool store, int modtime, int len, int clen,
+ uint32_t crc);
+ void write_jar_header(const char *fname, bool store, int modtime, int len, int clen,
+ unsigned int crc);
+ void write_central_directory();
+ uint32_t dostime(int y, int n, int d, int h, int m, int s);
+ uint32_t get_dostime(int modtime);
+
+ // The definitions of these depend on the NO_ZLIB option:
+ bool deflate_bytes(bytes &head, bytes &tail);
+ static uint32_t get_crc32(uint32_t c, unsigned char *ptr, uint32_t len);
};
struct gunzip
{
- // optional gzip input stream control block
+ // optional gzip input stream control block
- // pointer to outer unpacker, for error checks etc.
- unpacker *u;
+ // pointer to outer unpacker, for error checks etc.
+ unpacker *u;
- void *read_input_fn; // underlying \bchar\b stream
- void *zstream; // inflater state
- char inbuf[1 << 14]; // input buffer
+ void *read_input_fn; // underlying \bchar\b stream
+ void *zstream; // inflater state
+ char inbuf[1 << 14]; // input buffer
- void init(unpacker *u_); // pushes new value on u->read_input_fn
+ void init(unpacker *u_); // pushes new value on u->read_input_fn
- void free();
+ void free();
- void start(int magic);
+ void start(int magic);
- // private stuff
- void read_fixed_field(char *buf, size_t buflen);
+ // private stuff
+ void read_fixed_field(char *buf, size_t buflen);
};
diff --git a/libraries/rainbow/CMakeLists.txt b/libraries/rainbow/CMakeLists.txt
index b7e11045..ad806faa 100644
--- a/libraries/rainbow/CMakeLists.txt
+++ b/libraries/rainbow/CMakeLists.txt
@@ -16,7 +16,7 @@ target_link_libraries(MultiMC_rainbow Qt5::Core Qt5::Gui)
# Install it
install(
- TARGETS MultiMC_rainbow
- RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
- LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
+ TARGETS MultiMC_rainbow
+ RUNTIME DESTINATION ${LIBRARY_DEST_DIR}
+ LIBRARY DESTINATION ${LIBRARY_DEST_DIR}
)
diff --git a/libraries/rainbow/include/rainbow.h b/libraries/rainbow/include/rainbow.h
index b12052b1..67c46300 100644
--- a/libraries/rainbow/include/rainbow.h
+++ b/libraries/rainbow/include/rainbow.h
@@ -50,7 +50,7 @@ RAINBOW_EXPORT qreal luma(const QColor &);
* @since 5.0
*/
RAINBOW_EXPORT void getHcy(const QColor &, qreal *hue, qreal *chroma, qreal *luma,
- qreal *alpha = 0);
+ qreal *alpha = 0);
/**
* Calculate the contrast ratio between two colors, according to the
@@ -132,7 +132,7 @@ RAINBOW_EXPORT QColor tint(const QColor &base, const QColor &color, qreal amount
/**
* Blend two colors into a new color by linear combination.
* @code
- QColor lighter = Rainbow::mix(myColor, Qt::white)
+ QColor lighter = Rainbow::mix(myColor, Qt::white)
* @endcode
* @param c1 first color.
* @param c2 second color.
@@ -146,9 +146,9 @@ RAINBOW_EXPORT QColor mix(const QColor &c1, const QColor &c2, qreal bias = 0.5);
* Blend two colors into a new color by painting the second color over the
* first using the specified composition mode.
* @code
- QColor white(Qt::white);
- white.setAlphaF(0.5);
- QColor lighter = Rainbow::overlayColors(myColor, white);
+ QColor white(Qt::white);
+ white.setAlphaF(0.5);
+ QColor lighter = Rainbow::overlayColors(myColor, white);
@endcode
* @param base the base color (alpha channel is ignored).
* @param paint the color to be overlayed onto the base color.
@@ -156,5 +156,5 @@ RAINBOW_EXPORT QColor mix(const QColor &c1, const QColor &c2, qreal bias = 0.5);
*/
RAINBOW_EXPORT QColor
overlayColors(const QColor &base, const QColor &paint,
- QPainter::CompositionMode comp = QPainter::CompositionMode_SourceOver);
+ QPainter::CompositionMode comp = QPainter::CompositionMode_SourceOver);
}
diff --git a/libraries/rainbow/include/rainbow_config.h b/libraries/rainbow/include/rainbow_config.h
index 9290dc8a..ce7fc537 100644
--- a/libraries/rainbow/include/rainbow_config.h
+++ b/libraries/rainbow/include/rainbow_config.h
@@ -16,11 +16,11 @@
#include <QtCore/QtGlobal>
#ifdef RAINBOW_STATIC
- #define RAINBOW_EXPORT
+ #define RAINBOW_EXPORT
#else
- #ifdef RAINBOW_LIBRARY
- #define RAINBOW_EXPORT Q_DECL_EXPORT
- #else
- #define RAINBOW_EXPORT Q_DECL_IMPORT
- #endif
+ #ifdef RAINBOW_LIBRARY
+ #define RAINBOW_EXPORT Q_DECL_EXPORT
+ #else
+ #define RAINBOW_EXPORT Q_DECL_IMPORT
+ #endif
#endif \ No newline at end of file
diff --git a/libraries/rainbow/src/rainbow.cpp b/libraries/rainbow/src/rainbow.cpp
index 8502fcd0..9054d71d 100644
--- a/libraries/rainbow/src/rainbow.cpp
+++ b/libraries/rainbow/src/rainbow.cpp
@@ -33,8 +33,8 @@
static inline qreal wrap(qreal a, qreal d = 1.0)
{
- qreal r = fmod(a, d);
- return (r < 0.0 ? d + r : (r > 0.0 ? r : 0.0));
+ qreal r = fmod(a, d);
+ return (r < 0.0 ? d + r : (r > 0.0 ? r : 0.0));
}
// normalize: like qBound(a, 0.0, 1.0) but without needing the args and with
@@ -60,306 +60,306 @@ static const qreal yc[3] = {0.34375, 0.5, 0.15625};
class KHCY
{
public:
- explicit KHCY(const QColor &color)
- {
- qreal r = gamma(color.redF());
- qreal g = gamma(color.greenF());
- qreal b = gamma(color.blueF());
- a = color.alphaF();
-
- // luma component
- y = lumag(r, g, b);
-
- // hue component
- qreal p = qMax(qMax(r, g), b);
- qreal n = qMin(qMin(r, g), b);
- qreal d = 6.0 * (p - n);
- if (n == p)
- {
- h = 0.0;
- }
- else if (r == p)
- {
- h = ((g - b) / d);
- }
- else if (g == p)
- {
- h = ((b - r) / d) + (1.0 / 3.0);
- }
- else
- {
- h = ((r - g) / d) + (2.0 / 3.0);
- }
-
- // chroma component
- if (r == g && g == b)
- {
- c = 0.0;
- }
- else
- {
- c = qMax((y - n) / y, (p - y) / (1 - y));
- }
- }
- explicit KHCY(qreal h_, qreal c_, qreal y_, qreal a_ = 1.0)
- {
- h = h_;
- c = c_;
- y = y_;
- a = a_;
- }
-
- QColor qColor() const
- {
- // start with sane component values
- qreal _h = wrap(h);
- qreal _c = normalize(c);
- qreal _y = normalize(y);
-
- // calculate some needed variables
- qreal _hs = _h * 6.0, th, tm;
- if (_hs < 1.0)
- {
- th = _hs;
- tm = yc[0] + yc[1] * th;
- }
- else if (_hs < 2.0)
- {
- th = 2.0 - _hs;
- tm = yc[1] + yc[0] * th;
- }
- else if (_hs < 3.0)
- {
- th = _hs - 2.0;
- tm = yc[1] + yc[2] * th;
- }
- else if (_hs < 4.0)
- {
- th = 4.0 - _hs;
- tm = yc[2] + yc[1] * th;
- }
- else if (_hs < 5.0)
- {
- th = _hs - 4.0;
- tm = yc[2] + yc[0] * th;
- }
- else
- {
- th = 6.0 - _hs;
- tm = yc[0] + yc[2] * th;
- }
-
- // calculate RGB channels in sorted order
- qreal tn, to, tp;
- if (tm >= _y)
- {
- tp = _y + _y * _c * (1.0 - tm) / tm;
- to = _y + _y * _c * (th - tm) / tm;
- tn = _y - (_y * _c);
- }
- else
- {
- tp = _y + (1.0 - _y) * _c;
- to = _y + (1.0 - _y) * _c * (th - tm) / (1.0 - tm);
- tn = _y - (1.0 - _y) * _c * tm / (1.0 - tm);
- }
-
- // return RGB channels in appropriate order
- if (_hs < 1.0)
- {
- return QColor::fromRgbF(igamma(tp), igamma(to), igamma(tn), a);
- }
- else if (_hs < 2.0)
- {
- return QColor::fromRgbF(igamma(to), igamma(tp), igamma(tn), a);
- }
- else if (_hs < 3.0)
- {
- return QColor::fromRgbF(igamma(tn), igamma(tp), igamma(to), a);
- }
- else if (_hs < 4.0)
- {
- return QColor::fromRgbF(igamma(tn), igamma(to), igamma(tp), a);
- }
- else if (_hs < 5.0)
- {
- return QColor::fromRgbF(igamma(to), igamma(tn), igamma(tp), a);
- }
- else
- {
- return QColor::fromRgbF(igamma(tp), igamma(tn), igamma(to), a);
- }
- }
-
- qreal h, c, y, a;
- static qreal luma(const QColor &color)
- {
- return lumag(gamma(color.redF()), gamma(color.greenF()), gamma(color.blueF()));
- }
+ explicit KHCY(const QColor &color)
+ {
+ qreal r = gamma(color.redF());
+ qreal g = gamma(color.greenF());
+ qreal b = gamma(color.blueF());
+ a = color.alphaF();
+
+ // luma component
+ y = lumag(r, g, b);
+
+ // hue component
+ qreal p = qMax(qMax(r, g), b);
+ qreal n = qMin(qMin(r, g), b);
+ qreal d = 6.0 * (p - n);
+ if (n == p)
+ {
+ h = 0.0;
+ }
+ else if (r == p)
+ {
+ h = ((g - b) / d);
+ }
+ else if (g == p)
+ {
+ h = ((b - r) / d) + (1.0 / 3.0);
+ }
+ else
+ {
+ h = ((r - g) / d) + (2.0 / 3.0);
+ }
+
+ // chroma component
+ if (r == g && g == b)
+ {
+ c = 0.0;
+ }
+ else
+ {
+ c = qMax((y - n) / y, (p - y) / (1 - y));
+ }
+ }
+ explicit KHCY(qreal h_, qreal c_, qreal y_, qreal a_ = 1.0)
+ {
+ h = h_;
+ c = c_;
+ y = y_;
+ a = a_;
+ }
+
+ QColor qColor() const
+ {
+ // start with sane component values
+ qreal _h = wrap(h);
+ qreal _c = normalize(c);
+ qreal _y = normalize(y);
+
+ // calculate some needed variables
+ qreal _hs = _h * 6.0, th, tm;
+ if (_hs < 1.0)
+ {
+ th = _hs;
+ tm = yc[0] + yc[1] * th;
+ }
+ else if (_hs < 2.0)
+ {
+ th = 2.0 - _hs;
+ tm = yc[1] + yc[0] * th;
+ }
+ else if (_hs < 3.0)
+ {
+ th = _hs - 2.0;
+ tm = yc[1] + yc[2] * th;
+ }
+ else if (_hs < 4.0)
+ {
+ th = 4.0 - _hs;
+ tm = yc[2] + yc[1] * th;
+ }
+ else if (_hs < 5.0)
+ {
+ th = _hs - 4.0;
+ tm = yc[2] + yc[0] * th;
+ }
+ else
+ {
+ th = 6.0 - _hs;
+ tm = yc[0] + yc[2] * th;
+ }
+
+ // calculate RGB channels in sorted order
+ qreal tn, to, tp;
+ if (tm >= _y)
+ {
+ tp = _y + _y * _c * (1.0 - tm) / tm;
+ to = _y + _y * _c * (th - tm) / tm;
+ tn = _y - (_y * _c);
+ }
+ else
+ {
+ tp = _y + (1.0 - _y) * _c;
+ to = _y + (1.0 - _y) * _c * (th - tm) / (1.0 - tm);
+ tn = _y - (1.0 - _y) * _c * tm / (1.0 - tm);
+ }
+
+ // return RGB channels in appropriate order
+ if (_hs < 1.0)
+ {
+ return QColor::fromRgbF(igamma(tp), igamma(to), igamma(tn), a);
+ }
+ else if (_hs < 2.0)
+ {
+ return QColor::fromRgbF(igamma(to), igamma(tp), igamma(tn), a);
+ }
+ else if (_hs < 3.0)
+ {
+ return QColor::fromRgbF(igamma(tn), igamma(tp), igamma(to), a);
+ }
+ else if (_hs < 4.0)
+ {
+ return QColor::fromRgbF(igamma(tn), igamma(to), igamma(tp), a);
+ }
+ else if (_hs < 5.0)
+ {
+ return QColor::fromRgbF(igamma(to), igamma(tn), igamma(tp), a);
+ }
+ else
+ {
+ return QColor::fromRgbF(igamma(tp), igamma(tn), igamma(to), a);
+ }
+ }
+
+ qreal h, c, y, a;
+ static qreal luma(const QColor &color)
+ {
+ return lumag(gamma(color.redF()), gamma(color.greenF()), gamma(color.blueF()));
+ }
private:
- static qreal gamma(qreal n)
- {
- return pow(normalize(n), 2.2);
- }
- static qreal igamma(qreal n)
- {
- return pow(normalize(n), 1.0 / 2.2);
- }
- static qreal lumag(qreal r, qreal g, qreal b)
- {
- return r * yc[0] + g * yc[1] + b * yc[2];
- }
+ static qreal gamma(qreal n)
+ {
+ return pow(normalize(n), 2.2);
+ }
+ static qreal igamma(qreal n)
+ {
+ return pow(normalize(n), 1.0 / 2.2);
+ }
+ static qreal lumag(qreal r, qreal g, qreal b)
+ {
+ return r * yc[0] + g * yc[1] + b * yc[2];
+ }
};
static inline qreal mixQreal(qreal a, qreal b, qreal bias)
{
- return a + (b - a) * bias;
+ return a + (b - a) * bias;
}
//END internal helper functions
qreal Rainbow::luma(const QColor &color)
{
- return KHCY::luma(color);
+ return KHCY::luma(color);
}
void Rainbow::getHcy(const QColor &color, qreal *h, qreal *c, qreal *y, qreal *a)
{
- if (!c || !h || !y)
- {
- return;
- }
- KHCY khcy(color);
- *c = khcy.c;
- *h = khcy.h;
- *y = khcy.y;
- if (a)
- {
- *a = khcy.a;
- }
+ if (!c || !h || !y)
+ {
+ return;
+ }
+ KHCY khcy(color);
+ *c = khcy.c;
+ *h = khcy.h;
+ *y = khcy.y;
+ if (a)
+ {
+ *a = khcy.a;
+ }
}
static qreal contrastRatioForLuma(qreal y1, qreal y2)
{
- if (y1 > y2)
- {
- return (y1 + 0.05) / (y2 + 0.05);
- }
- else
- {
- return (y2 + 0.05) / (y1 + 0.05);
- }
+ if (y1 > y2)
+ {
+ return (y1 + 0.05) / (y2 + 0.05);
+ }
+ else
+ {
+ return (y2 + 0.05) / (y1 + 0.05);
+ }
}
qreal Rainbow::contrastRatio(const QColor &c1, const QColor &c2)
{
- return contrastRatioForLuma(luma(c1), luma(c2));
+ return contrastRatioForLuma(luma(c1), luma(c2));
}
QColor Rainbow::lighten(const QColor &color, qreal ky, qreal kc)
{
- KHCY c(color);
- c.y = 1.0 - normalize((1.0 - c.y) * (1.0 - ky));
- c.c = 1.0 - normalize((1.0 - c.c) * kc);
- return c.qColor();
+ KHCY c(color);
+ c.y = 1.0 - normalize((1.0 - c.y) * (1.0 - ky));
+ c.c = 1.0 - normalize((1.0 - c.c) * kc);
+ return c.qColor();
}
QColor Rainbow::darken(const QColor &color, qreal ky, qreal kc)
{
- KHCY c(color);
- c.y = normalize(c.y * (1.0 - ky));
- c.c = normalize(c.c * kc);
- return c.qColor();
+ KHCY c(color);
+ c.y = normalize(c.y * (1.0 - ky));
+ c.c = normalize(c.c * kc);
+ return c.qColor();
}
QColor Rainbow::shade(const QColor &color, qreal ky, qreal kc)
{
- KHCY c(color);
- c.y = normalize(c.y + ky);
- c.c = normalize(c.c + kc);
- return c.qColor();
+ KHCY c(color);
+ c.y = normalize(c.y + ky);
+ c.c = normalize(c.c + kc);
+ return c.qColor();
}
static QColor tintHelper(const QColor &base, qreal baseLuma, const QColor &color, qreal amount)
{
- KHCY result(Rainbow::mix(base, color, pow(amount, 0.3)));
- result.y = mixQreal(baseLuma, result.y, amount);
+ KHCY result(Rainbow::mix(base, color, pow(amount, 0.3)));
+ result.y = mixQreal(baseLuma, result.y, amount);
- return result.qColor();
+ return result.qColor();
}
QColor Rainbow::tint(const QColor &base, const QColor &color, qreal amount)
{
- if (amount <= 0.0)
- {
- return base;
- }
- if (amount >= 1.0)
- {
- return color;
- }
- if (qIsNaN(amount))
- {
- return base;
- }
-
- qreal baseLuma = luma(base); // cache value because luma call is expensive
- double ri = contrastRatioForLuma(baseLuma, luma(color));
- double rg = 1.0 + ((ri + 1.0) * amount * amount * amount);
- double u = 1.0, l = 0.0;
- QColor result;
- for (int i = 12; i; --i)
- {
- double a = 0.5 * (l + u);
- result = tintHelper(base, baseLuma, color, a);
- double ra = contrastRatioForLuma(baseLuma, luma(result));
- if (ra > rg)
- {
- u = a;
- }
- else
- {
- l = a;
- }
- }
- return result;
+ if (amount <= 0.0)
+ {
+ return base;
+ }
+ if (amount >= 1.0)
+ {
+ return color;
+ }
+ if (qIsNaN(amount))
+ {
+ return base;
+ }
+
+ qreal baseLuma = luma(base); // cache value because luma call is expensive
+ double ri = contrastRatioForLuma(baseLuma, luma(color));
+ double rg = 1.0 + ((ri + 1.0) * amount * amount * amount);
+ double u = 1.0, l = 0.0;
+ QColor result;
+ for (int i = 12; i; --i)
+ {
+ double a = 0.5 * (l + u);
+ result = tintHelper(base, baseLuma, color, a);
+ double ra = contrastRatioForLuma(baseLuma, luma(result));
+ if (ra > rg)
+ {
+ u = a;
+ }
+ else
+ {
+ l = a;
+ }
+ }
+ return result;
}
QColor Rainbow::mix(const QColor &c1, const QColor &c2, qreal bias)
{
- if (bias <= 0.0)
- {
- return c1;
- }
- if (bias >= 1.0)
- {
- return c2;
- }
- if (qIsNaN(bias))
- {
- return c1;
- }
-
- qreal r = mixQreal(c1.redF(), c2.redF(), bias);
- qreal g = mixQreal(c1.greenF(), c2.greenF(), bias);
- qreal b = mixQreal(c1.blueF(), c2.blueF(), bias);
- qreal a = mixQreal(c1.alphaF(), c2.alphaF(), bias);
-
- return QColor::fromRgbF(r, g, b, a);
+ if (bias <= 0.0)
+ {
+ return c1;
+ }
+ if (bias >= 1.0)
+ {
+ return c2;
+ }
+ if (qIsNaN(bias))
+ {
+ return c1;
+ }
+
+ qreal r = mixQreal(c1.redF(), c2.redF(), bias);
+ qreal g = mixQreal(c1.greenF(), c2.greenF(), bias);
+ qreal b = mixQreal(c1.blueF(), c2.blueF(), bias);
+ qreal a = mixQreal(c1.alphaF(), c2.alphaF(), bias);
+
+ return QColor::fromRgbF(r, g, b, a);
}
QColor Rainbow::overlayColors(const QColor &base, const QColor &paint,
- QPainter::CompositionMode comp)
+ QPainter::CompositionMode comp)
{
- // This isn't the fastest way, but should be "fast enough".
- // It's also the only safe way to use QPainter::CompositionMode
- QImage img(1, 1, QImage::Format_ARGB32_Premultiplied);
- QPainter p(&img);
- QColor start = base;
- start.setAlpha(255); // opaque
- p.fillRect(0, 0, 1, 1, start);
- p.setCompositionMode(comp);
- p.fillRect(0, 0, 1, 1, paint);
- p.end();
- return img.pixel(0, 0);
+ // This isn't the fastest way, but should be "fast enough".
+ // It's also the only safe way to use QPainter::CompositionMode
+ QImage img(1, 1, QImage::Format_ARGB32_Premultiplied);
+ QPainter p(&img);
+ QColor start = base;
+ start.setAlpha(255); // opaque
+ p.fillRect(0, 0, 1, 1, start);
+ p.setCompositionMode(comp);
+ p.fillRect(0, 0, 1, 1, paint);
+ p.end();
+ return img.pixel(0, 0);
}
diff --git a/libraries/systeminfo/CMakeLists.txt b/libraries/systeminfo/CMakeLists.txt
index 173d7b59..548a589c 100644
--- a/libraries/systeminfo/CMakeLists.txt
+++ b/libraries/systeminfo/CMakeLists.txt
@@ -9,13 +9,13 @@ src/distroutils.cpp
)
if (WIN32)
- list(APPEND systeminfo_SOURCES src/sys_win32.cpp)
+ list(APPEND systeminfo_SOURCES src/sys_win32.cpp)
elseif (UNIX)
- if(APPLE)
- list(APPEND systeminfo_SOURCES src/sys_apple.cpp)
- else()
- list(APPEND systeminfo_SOURCES src/sys_unix.cpp)
- endif()
+ if(APPLE)
+ list(APPEND systeminfo_SOURCES src/sys_apple.cpp)
+ else()
+ list(APPEND systeminfo_SOURCES src/sys_unix.cpp)
+ endif()
endif()
add_library(systeminfo STATIC ${systeminfo_SOURCES})
@@ -24,6 +24,6 @@ target_include_directories(systeminfo PUBLIC include)
include (UnitTest)
add_unit_test(sys
- SOURCES src/sys_test.cpp
- LIBS systeminfo
+ SOURCES src/sys_test.cpp
+ LIBS systeminfo
)
diff --git a/libraries/systeminfo/include/distroutils.h b/libraries/systeminfo/include/distroutils.h
index 5ff8d591..2e85f433 100644
--- a/libraries/systeminfo/include/distroutils.h
+++ b/libraries/systeminfo/include/distroutils.h
@@ -4,10 +4,10 @@
namespace Sys {
struct LsbInfo
{
- QString distributor;
- QString version;
- QString description;
- QString codename;
+ QString distributor;
+ QString version;
+ QString description;
+ QString codename;
};
bool main_lsb_info(LsbInfo & out);
diff --git a/libraries/systeminfo/include/sys.h b/libraries/systeminfo/include/sys.h
index c573eb53..7980dfdf 100644
--- a/libraries/systeminfo/include/sys.h
+++ b/libraries/systeminfo/include/sys.h
@@ -6,37 +6,37 @@ namespace Sys
const uint64_t megabyte = 1024ull * 1024ull;
struct KernelInfo
{
- QString kernelName;
- QString kernelVersion;
+ QString kernelName;
+ QString kernelVersion;
};
KernelInfo getKernelInfo();
struct DistributionInfo
{
- DistributionInfo operator+(const DistributionInfo& rhs) const
- {
- DistributionInfo out;
- if(!distributionName.isEmpty())
- {
- out.distributionName = distributionName;
- }
- else
- {
- out.distributionName = rhs.distributionName;
- }
- if(!distributionVersion.isEmpty())
- {
- out.distributionVersion = distributionVersion;
- }
- else
- {
- out.distributionVersion = rhs.distributionVersion;
- }
- return out;
- }
- QString distributionName;
- QString distributionVersion;
+ DistributionInfo operator+(const DistributionInfo& rhs) const
+ {
+ DistributionInfo out;
+ if(!distributionName.isEmpty())
+ {
+ out.distributionName = distributionName;
+ }
+ else
+ {
+ out.distributionName = rhs.distributionName;
+ }
+ if(!distributionVersion.isEmpty())
+ {
+ out.distributionVersion = distributionVersion;
+ }
+ else
+ {
+ out.distributionVersion = rhs.distributionVersion;
+ }
+ return out;
+ }
+ QString distributionName;
+ QString distributionVersion;
};
DistributionInfo getDistributionInfo();
diff --git a/libraries/systeminfo/src/distroutils.cpp b/libraries/systeminfo/src/distroutils.cpp
index cdba05d0..fb9ae25d 100644
--- a/libraries/systeminfo/src/distroutils.cpp
+++ b/libraries/systeminfo/src/distroutils.cpp
@@ -41,243 +41,243 @@ SOFTWARE.
Sys::DistributionInfo Sys::read_os_release()
{
- Sys::DistributionInfo out;
- QStringList files = { "/etc/os-release", "/usr/lib/os-release" };
- QString name;
- QString version;
- for (auto &file: files)
- {
- if(!QFile::exists(file))
- {
- continue;
- }
- QSettings settings(file, QSettings::IniFormat);
- if(settings.contains("ID"))
- {
- name = settings.value("ID").toString().toLower();
- }
- else if (settings.contains("NAME"))
- {
- name = settings.value("NAME").toString().toLower();
- }
- else
- {
- continue;
- }
+ Sys::DistributionInfo out;
+ QStringList files = { "/etc/os-release", "/usr/lib/os-release" };
+ QString name;
+ QString version;
+ for (auto &file: files)
+ {
+ if(!QFile::exists(file))
+ {
+ continue;
+ }
+ QSettings settings(file, QSettings::IniFormat);
+ if(settings.contains("ID"))
+ {
+ name = settings.value("ID").toString().toLower();
+ }
+ else if (settings.contains("NAME"))
+ {
+ name = settings.value("NAME").toString().toLower();
+ }
+ else
+ {
+ continue;
+ }
- if(settings.contains("VERSION_ID"))
- {
- version = settings.value("VERSION_ID").toString().toLower();
- }
- else if(settings.contains("VERSION"))
- {
- version = settings.value("VERSION").toString().toLower();
- }
- break;
- }
- if(name.isEmpty())
- {
- return out;
- }
- out.distributionName = name;
- out.distributionVersion = version;
- return out;
+ if(settings.contains("VERSION_ID"))
+ {
+ version = settings.value("VERSION_ID").toString().toLower();
+ }
+ else if(settings.contains("VERSION"))
+ {
+ version = settings.value("VERSION").toString().toLower();
+ }
+ break;
+ }
+ if(name.isEmpty())
+ {
+ return out;
+ }
+ out.distributionName = name;
+ out.distributionVersion = version;
+ return out;
}
bool Sys::main_lsb_info(Sys::LsbInfo & out)
{
- int status=0;
- QProcess lsbProcess;
- lsbProcess.start("lsb_release -a");
- lsbProcess.waitForFinished();
- status = lsbProcess.exitStatus();
- QString output = lsbProcess.readAllStandardOutput();
- qDebug() << output;
- lsbProcess.close();
- if(status == 0)
- {
- auto lines = output.split('\n');
- for(auto line:lines)
- {
- int index = line.indexOf(':');
- auto key = line.left(index).trimmed();
- auto value = line.mid(index + 1).toLower().trimmed();
- if(key == "Distributor ID")
- out.distributor = value;
- else if(key == "Release")
- out.version = value;
- else if(key == "Description")
- out.description = value;
- else if(key == "Codename")
- out.codename = value;
- }
- return !out.distributor.isEmpty();
- }
- return false;
+ int status=0;
+ QProcess lsbProcess;
+ lsbProcess.start("lsb_release -a");
+ lsbProcess.waitForFinished();
+ status = lsbProcess.exitStatus();
+ QString output = lsbProcess.readAllStandardOutput();
+ qDebug() << output;
+ lsbProcess.close();
+ if(status == 0)
+ {
+ auto lines = output.split('\n');
+ for(auto line:lines)
+ {
+ int index = line.indexOf(':');
+ auto key = line.left(index).trimmed();
+ auto value = line.mid(index + 1).toLower().trimmed();
+ if(key == "Distributor ID")
+ out.distributor = value;
+ else if(key == "Release")
+ out.version = value;
+ else if(key == "Description")
+ out.description = value;
+ else if(key == "Codename")
+ out.codename = value;
+ }
+ return !out.distributor.isEmpty();
+ }
+ return false;
}
bool Sys::fallback_lsb_info(Sys::LsbInfo & out)
{
- // running lsb_release failed, try to read the file instead
- // /etc/lsb-release format, if the file even exists, is non-standard.
- // Only the `lsb_release` command is specified by LSB. Nonetheless, some
- // distributions install an /etc/lsb-release as part of the base
- // distribution, but `lsb_release` remains optional.
- QString file = "/etc/lsb-release";
- if (QFile::exists(file))
- {
- QSettings settings(file, QSettings::IniFormat);
- if(settings.contains("DISTRIB_ID"))
- {
- out.distributor = settings.value("DISTRIB_ID").toString().toLower();
- }
- if(settings.contains("DISTRIB_RELEASE"))
- {
- out.version = settings.value("DISTRIB_RELEASE").toString().toLower();
- }
- return !out.distributor.isEmpty();
- }
- return false;
+ // running lsb_release failed, try to read the file instead
+ // /etc/lsb-release format, if the file even exists, is non-standard.
+ // Only the `lsb_release` command is specified by LSB. Nonetheless, some
+ // distributions install an /etc/lsb-release as part of the base
+ // distribution, but `lsb_release` remains optional.
+ QString file = "/etc/lsb-release";
+ if (QFile::exists(file))
+ {
+ QSettings settings(file, QSettings::IniFormat);
+ if(settings.contains("DISTRIB_ID"))
+ {
+ out.distributor = settings.value("DISTRIB_ID").toString().toLower();
+ }
+ if(settings.contains("DISTRIB_RELEASE"))
+ {
+ out.version = settings.value("DISTRIB_RELEASE").toString().toLower();
+ }
+ return !out.distributor.isEmpty();
+ }
+ return false;
}
void Sys::lsb_postprocess(Sys::LsbInfo & lsb, Sys::DistributionInfo & out)
{
- QString dist = lsb.distributor;
- QString vers = lsb.version;
- if(dist.startsWith("redhatenterprise"))
- {
- dist = "rhel";
- }
- else if(dist == "archlinux")
- {
- dist = "arch";
- }
- else if (dist.startsWith("suse"))
- {
- if(lsb.description.startsWith("opensuse"))
- {
- dist = "opensuse";
- }
- else if (lsb.description.startsWith("suse linux enterprise"))
- {
- dist = "sles";
- }
- }
- else if (dist == "debian" and vers == "testing")
- {
- vers = lsb.codename;
- }
- else
- {
- // ubuntu, debian, gentoo, scientific, slackware, ... ?
- auto parts = dist.split(QRegExp("\\s+"), QString::SkipEmptyParts);
- if(parts.size())
- {
- dist = parts[0];
- }
- }
- if(!dist.isEmpty())
- {
- out.distributionName = dist;
- out.distributionVersion = vers;
- }
+ QString dist = lsb.distributor;
+ QString vers = lsb.version;
+ if(dist.startsWith("redhatenterprise"))
+ {
+ dist = "rhel";
+ }
+ else if(dist == "archlinux")
+ {
+ dist = "arch";
+ }
+ else if (dist.startsWith("suse"))
+ {
+ if(lsb.description.startsWith("opensuse"))
+ {
+ dist = "opensuse";
+ }
+ else if (lsb.description.startsWith("suse linux enterprise"))
+ {
+ dist = "sles";
+ }
+ }
+ else if (dist == "debian" and vers == "testing")
+ {
+ vers = lsb.codename;
+ }
+ else
+ {
+ // ubuntu, debian, gentoo, scientific, slackware, ... ?
+ auto parts = dist.split(QRegExp("\\s+"), QString::SkipEmptyParts);
+ if(parts.size())
+ {
+ dist = parts[0];
+ }
+ }
+ if(!dist.isEmpty())
+ {
+ out.distributionName = dist;
+ out.distributionVersion = vers;
+ }
}
Sys::DistributionInfo Sys::read_lsb_release()
{
- LsbInfo lsb;
- if(!main_lsb_info(lsb))
- {
- if(!fallback_lsb_info(lsb))
- {
- return Sys::DistributionInfo();
- }
- }
- Sys::DistributionInfo out;
- lsb_postprocess(lsb, out);
- return out;
+ LsbInfo lsb;
+ if(!main_lsb_info(lsb))
+ {
+ if(!fallback_lsb_info(lsb))
+ {
+ return Sys::DistributionInfo();
+ }
+ }
+ Sys::DistributionInfo out;
+ lsb_postprocess(lsb, out);
+ return out;
}
QString Sys::_extract_distribution(const QString & x)
{
- QString release = x.toLower();
- if (release.startsWith("red hat enterprise"))
- {
- return "rhel";
- }
- if (release.startsWith("suse linux enterprise"))
- {
- return "sles";
- }
- QStringList list = release.split(QRegExp("\\s+"), QString::SkipEmptyParts);
- if(list.size())
- {
- return list[0];
- }
- return QString();
+ QString release = x.toLower();
+ if (release.startsWith("red hat enterprise"))
+ {
+ return "rhel";
+ }
+ if (release.startsWith("suse linux enterprise"))
+ {
+ return "sles";
+ }
+ QStringList list = release.split(QRegExp("\\s+"), QString::SkipEmptyParts);
+ if(list.size())
+ {
+ return list[0];
+ }
+ return QString();
}
QString Sys::_extract_version(const QString & x)
{
- QRegExp versionish_string("\\d+(?:\\.\\d+)*$");
- QStringList list = x.split(QRegExp("\\s+"), QString::SkipEmptyParts);
- for(int i = list.size() - 1; i >= 0; --i)
- {
- QString chunk = list[i];
- if(versionish_string.exactMatch(chunk))
- {
- return chunk;
- }
- }
- return QString();
+ QRegExp versionish_string("\\d+(?:\\.\\d+)*$");
+ QStringList list = x.split(QRegExp("\\s+"), QString::SkipEmptyParts);
+ for(int i = list.size() - 1; i >= 0; --i)
+ {
+ QString chunk = list[i];
+ if(versionish_string.exactMatch(chunk))
+ {
+ return chunk;
+ }
+ }
+ return QString();
}
Sys::DistributionInfo Sys::read_legacy_release()
{
- struct checkEntry
- {
- QString file;
- std::function<QString(const QString &)> extract_distro;
- std::function<QString(const QString &)> extract_version;
- };
- QList<checkEntry> checks =
- {
- {"/etc/arch-release", [](const QString &){ return "arch";}, [](const QString &){ return "rolling";}},
- {"/etc/slackware-version", &Sys::_extract_distribution, &Sys::_extract_version},
- {QString(), &Sys::_extract_distribution, &Sys::_extract_version},
- {"/etc/debian_version", [](const QString &){ return "debian";}, [](const QString & x){ return x;}},
- };
- for(auto & check: checks)
- {
- QStringList files;
- if(check.file.isNull())
- {
- QDir etcDir("/etc");
- etcDir.setNameFilters({"*-release"});
- etcDir.setFilter(QDir::Files | QDir::NoDot | QDir::NoDotDot | QDir::Readable | QDir::Hidden);
- files = etcDir.entryList();
- }
- else
- {
- files.append(check.file);
- }
- for (auto file : files)
- {
- QFile relfile(file);
- if(!relfile.open(QIODevice::ReadOnly | QIODevice::Text))
- continue;
- QString contents = QString::fromUtf8(relfile.readLine()).trimmed();
- QString dist = check.extract_distro(contents);
- QString vers = check.extract_version(contents);
- if(!dist.isEmpty())
- {
- Sys::DistributionInfo out;
- out.distributionName = dist;
- out.distributionVersion = vers;
- return out;
- }
- }
- }
- return Sys::DistributionInfo();
+ struct checkEntry
+ {
+ QString file;
+ std::function<QString(const QString &)> extract_distro;
+ std::function<QString(const QString &)> extract_version;
+ };
+ QList<checkEntry> checks =
+ {
+ {"/etc/arch-release", [](const QString &){ return "arch";}, [](const QString &){ return "rolling";}},
+ {"/etc/slackware-version", &Sys::_extract_distribution, &Sys::_extract_version},
+ {QString(), &Sys::_extract_distribution, &Sys::_extract_version},
+ {"/etc/debian_version", [](const QString &){ return "debian";}, [](const QString & x){ return x;}},
+ };
+ for(auto & check: checks)
+ {
+ QStringList files;
+ if(check.file.isNull())
+ {
+ QDir etcDir("/etc");
+ etcDir.setNameFilters({"*-release"});
+ etcDir.setFilter(QDir::Files | QDir::NoDot | QDir::NoDotDot | QDir::Readable | QDir::Hidden);
+ files = etcDir.entryList();
+ }
+ else
+ {
+ files.append(check.file);
+ }
+ for (auto file : files)
+ {
+ QFile relfile(file);
+ if(!relfile.open(QIODevice::ReadOnly | QIODevice::Text))
+ continue;
+ QString contents = QString::fromUtf8(relfile.readLine()).trimmed();
+ QString dist = check.extract_distro(contents);
+ QString vers = check.extract_version(contents);
+ if(!dist.isEmpty())
+ {
+ Sys::DistributionInfo out;
+ out.distributionName = dist;
+ out.distributionVersion = vers;
+ return out;
+ }
+ }
+ }
+ return Sys::DistributionInfo();
}
diff --git a/libraries/systeminfo/src/sys_apple.cpp b/libraries/systeminfo/src/sys_apple.cpp
index 62e6037d..4bcffae4 100644
--- a/libraries/systeminfo/src/sys_apple.cpp
+++ b/libraries/systeminfo/src/sys_apple.cpp
@@ -4,44 +4,44 @@
Sys::KernelInfo Sys::getKernelInfo()
{
- Sys::KernelInfo out;
- struct utsname buf;
- uname(&buf);
- out.kernelName = buf.sysname;
- out.kernelVersion = buf.release;
- return out;
+ Sys::KernelInfo out;
+ struct utsname buf;
+ uname(&buf);
+ out.kernelName = buf.sysname;
+ out.kernelVersion = buf.release;
+ return out;
}
#include <sys/sysctl.h>
uint64_t Sys::getSystemRam()
{
- uint64_t memsize;
- size_t memsizesize = sizeof(memsize);
- if(!sysctlbyname("hw.memsize", &memsize, &memsizesize, NULL, 0))
- {
- return memsize;
- }
- else
- {
- return 0;
- }
+ uint64_t memsize;
+ size_t memsizesize = sizeof(memsize);
+ if(!sysctlbyname("hw.memsize", &memsize, &memsizesize, NULL, 0))
+ {
+ return memsize;
+ }
+ else
+ {
+ return 0;
+ }
}
bool Sys::isCPU64bit()
{
- // not even going to pretend I'm going to support anything else
- return true;
+ // not even going to pretend I'm going to support anything else
+ return true;
}
bool Sys::isSystem64bit()
{
- // yep. maybe when we have 128bit CPUs on consumer devices.
- return true;
+ // yep. maybe when we have 128bit CPUs on consumer devices.
+ return true;
}
Sys::DistributionInfo Sys::getDistributionInfo()
{
- DistributionInfo result;
- return result;
+ DistributionInfo result;
+ return result;
}
diff --git a/libraries/systeminfo/src/sys_test.cpp b/libraries/systeminfo/src/sys_test.cpp
index 5888e02b..315050d2 100644
--- a/libraries/systeminfo/src/sys_test.cpp
+++ b/libraries/systeminfo/src/sys_test.cpp
@@ -5,24 +5,24 @@
class SysTest : public QObject
{
- Q_OBJECT
+ Q_OBJECT
private
slots:
- void test_kernelNotNull()
- {
- auto kinfo = Sys::getKernelInfo();
- QVERIFY(!kinfo.kernelName.isEmpty());
- QVERIFY(kinfo.kernelVersion != "0.0");
- }
+ void test_kernelNotNull()
+ {
+ auto kinfo = Sys::getKernelInfo();
+ QVERIFY(!kinfo.kernelName.isEmpty());
+ QVERIFY(kinfo.kernelVersion != "0.0");
+ }
/*
- void test_systemDistroNotNull()
- {
- auto kinfo = Sys::getDistributionInfo();
- QVERIFY(!kinfo.distributionName.isEmpty());
- QVERIFY(!kinfo.distributionVersion.isEmpty());
- qDebug() << "Distro: " << kinfo.distributionName << "version" << kinfo.distributionVersion;
- }
+ void test_systemDistroNotNull()
+ {
+ auto kinfo = Sys::getDistributionInfo();
+ QVERIFY(!kinfo.distributionName.isEmpty());
+ QVERIFY(!kinfo.distributionVersion.isEmpty());
+ qDebug() << "Distro: " << kinfo.distributionName << "version" << kinfo.distributionVersion;
+ }
*/
};
diff --git a/libraries/systeminfo/src/sys_unix.cpp b/libraries/systeminfo/src/sys_unix.cpp
index 313908f3..ab3f302e 100644
--- a/libraries/systeminfo/src/sys_unix.cpp
+++ b/libraries/systeminfo/src/sys_unix.cpp
@@ -7,69 +7,69 @@
Sys::KernelInfo Sys::getKernelInfo()
{
- Sys::KernelInfo out;
- struct utsname buf;
- uname(&buf);
- out.kernelName = buf.sysname;
- out.kernelVersion = buf.release;
- return out;
+ Sys::KernelInfo out;
+ struct utsname buf;
+ uname(&buf);
+ out.kernelName = buf.sysname;
+ out.kernelVersion = buf.release;
+ return out;
}
uint64_t Sys::getSystemRam()
{
- std::string token;
- std::ifstream file("/proc/meminfo");
- while(file >> token)
- {
- if(token == "MemTotal:")
- {
- uint64_t mem;
- if(file >> mem)
- {
- return mem * 1024ull;
- }
- else
- {
- return 0;
- }
- }
- // ignore rest of the line
- file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
- }
- return 0; // nothing found
+ std::string token;
+ std::ifstream file("/proc/meminfo");
+ while(file >> token)
+ {
+ if(token == "MemTotal:")
+ {
+ uint64_t mem;
+ if(file >> mem)
+ {
+ return mem * 1024ull;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ // ignore rest of the line
+ file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+ }
+ return 0; // nothing found
}
bool Sys::isCPU64bit()
{
- return isSystem64bit();
+ return isSystem64bit();
}
bool Sys::isSystem64bit()
{
- // kernel build arch on linux
- return QSysInfo::currentCpuArchitecture() == "x86_64";
+ // kernel build arch on linux
+ return QSysInfo::currentCpuArchitecture() == "x86_64";
}
Sys::DistributionInfo Sys::getDistributionInfo()
{
- DistributionInfo systemd_info = read_os_release();
- DistributionInfo lsb_info = read_lsb_release();
- DistributionInfo legacy_info = read_legacy_release();
- DistributionInfo result = systemd_info + lsb_info + legacy_info;
- if(result.distributionName.isNull())
- {
- result.distributionName = "unknown";
- }
- if(result.distributionVersion.isNull())
- {
- if(result.distributionName == "arch")
- {
- result.distributionVersion = "rolling";
- }
- else
- {
- result.distributionVersion = "unknown";
- }
- }
- return result;
+ DistributionInfo systemd_info = read_os_release();
+ DistributionInfo lsb_info = read_lsb_release();
+ DistributionInfo legacy_info = read_legacy_release();
+ DistributionInfo result = systemd_info + lsb_info + legacy_info;
+ if(result.distributionName.isNull())
+ {
+ result.distributionName = "unknown";
+ }
+ if(result.distributionVersion.isNull())
+ {
+ if(result.distributionName == "arch")
+ {
+ result.distributionVersion = "rolling";
+ }
+ else
+ {
+ result.distributionVersion = "unknown";
+ }
+ }
+ return result;
}
diff --git a/libraries/systeminfo/src/sys_win32.cpp b/libraries/systeminfo/src/sys_win32.cpp
index cc1d61c1..a750b3a7 100644
--- a/libraries/systeminfo/src/sys_win32.cpp
+++ b/libraries/systeminfo/src/sys_win32.cpp
@@ -4,49 +4,49 @@
Sys::KernelInfo Sys::getKernelInfo()
{
- Sys::KernelInfo out;
- out.kernelName = "Windows";
- OSVERSIONINFOW osvi;
- ZeroMemory(&osvi, sizeof(OSVERSIONINFOW));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
- GetVersionExW(&osvi);
- out.kernelVersion = QString("%1.%2").arg(osvi.dwMajorVersion).arg(osvi.dwMinorVersion);
- return out;
+ Sys::KernelInfo out;
+ out.kernelName = "Windows";
+ OSVERSIONINFOW osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOW));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
+ GetVersionExW(&osvi);
+ out.kernelVersion = QString("%1.%2").arg(osvi.dwMajorVersion).arg(osvi.dwMinorVersion);
+ return out;
}
uint64_t Sys::getSystemRam()
{
- MEMORYSTATUSEX status;
- status.dwLength = sizeof(status);
- GlobalMemoryStatusEx( &status );
- // bytes
- return (uint64_t)status.ullTotalPhys;
+ MEMORYSTATUSEX status;
+ status.dwLength = sizeof(status);
+ GlobalMemoryStatusEx( &status );
+ // bytes
+ return (uint64_t)status.ullTotalPhys;
}
bool Sys::isSystem64bit()
{
#if defined(_WIN64)
- return true;
+ return true;
#elif defined(_WIN32)
- BOOL f64 = false;
- return IsWow64Process(GetCurrentProcess(), &f64) && f64;
+ BOOL f64 = false;
+ return IsWow64Process(GetCurrentProcess(), &f64) && f64;
#else
- // it's some other kind of system...
- return false;
+ // it's some other kind of system...
+ return false;
#endif
}
bool Sys::isCPU64bit()
{
- SYSTEM_INFO info;
- ZeroMemory(&info, sizeof(SYSTEM_INFO));
- GetNativeSystemInfo(&info);
- auto arch = info.wProcessorArchitecture;
- return arch == PROCESSOR_ARCHITECTURE_AMD64 || arch == PROCESSOR_ARCHITECTURE_IA64;
+ SYSTEM_INFO info;
+ ZeroMemory(&info, sizeof(SYSTEM_INFO));
+ GetNativeSystemInfo(&info);
+ auto arch = info.wProcessorArchitecture;
+ return arch == PROCESSOR_ARCHITECTURE_AMD64 || arch == PROCESSOR_ARCHITECTURE_IA64;
}
Sys::DistributionInfo Sys::getDistributionInfo()
{
- DistributionInfo result;
- return result;
+ DistributionInfo result;
+ return result;
}
diff --git a/libraries/xz-embedded/CMakeLists.txt b/libraries/xz-embedded/CMakeLists.txt
index 5f744671..86ac60c8 100644
--- a/libraries/xz-embedded/CMakeLists.txt
+++ b/libraries/xz-embedded/CMakeLists.txt
@@ -9,18 +9,18 @@ option(XZ_BUILD_MINIDEC "Build a tiny utility that decompresses xz streams" OFF)
# tweak this list and xz.h to fit your needs
set(XZ_SOURCES
- src/xz_crc32.c
- src/xz_crc64.c
- src/xz_dec_lzma2.c
- src/xz_dec_stream.c
-# src/xz_dec_bcj.c
+ src/xz_crc32.c
+ src/xz_crc64.c
+ src/xz_dec_lzma2.c
+ src/xz_dec_stream.c
+# src/xz_dec_bcj.c
)
add_library(xz-embedded STATIC ${XZ_SOURCES})
target_include_directories(xz-embedded PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
set_property(TARGET xz-embedded PROPERTY C_STANDARD 99)
if(${XZ_BUILD_MINIDEC})
- add_executable(xzminidec xzminidec.c)
- target_link_libraries(xzminidec xz-embedded)
- set_property(TARGET xzminidec PROPERTY C_STANDARD 99)
+ add_executable(xzminidec xzminidec.c)
+ target_link_libraries(xzminidec xz-embedded)
+ set_property(TARGET xzminidec PROPERTY C_STANDARD 99)
endif()
diff --git a/libraries/xz-embedded/include/xz.h b/libraries/xz-embedded/include/xz.h
index eef8ef69..3779124c 100644
--- a/libraries/xz-embedded/include/xz.h
+++ b/libraries/xz-embedded/include/xz.h
@@ -69,9 +69,9 @@ extern "C" {
*/
enum xz_mode
{
- XZ_SINGLE,
- XZ_PREALLOC,
- XZ_DYNALLOC
+ XZ_SINGLE,
+ XZ_PREALLOC,
+ XZ_DYNALLOC
};
/**
@@ -126,15 +126,15 @@ enum xz_mode
*/
enum xz_ret
{
- XZ_OK,
- XZ_STREAM_END,
- XZ_UNSUPPORTED_CHECK,
- XZ_MEM_ERROR,
- XZ_MEMLIMIT_ERROR,
- XZ_FORMAT_ERROR,
- XZ_OPTIONS_ERROR,
- XZ_DATA_ERROR,
- XZ_BUF_ERROR
+ XZ_OK,
+ XZ_STREAM_END,
+ XZ_UNSUPPORTED_CHECK,
+ XZ_MEM_ERROR,
+ XZ_MEMLIMIT_ERROR,
+ XZ_FORMAT_ERROR,
+ XZ_OPTIONS_ERROR,
+ XZ_DATA_ERROR,
+ XZ_BUF_ERROR
};
/**
@@ -155,13 +155,13 @@ enum xz_ret
*/
struct xz_buf
{
- const uint8_t *in;
- size_t in_pos;
- size_t in_size;
+ const uint8_t *in;
+ size_t in_pos;
+ size_t in_size;
- uint8_t *out;
- size_t out_pos;
- size_t out_size;
+ uint8_t *out;
+ size_t out_pos;
+ size_t out_size;
};
/**
diff --git a/libraries/xz-embedded/src/xz_config.h b/libraries/xz-embedded/src/xz_config.h
index 40805b75..effdb1bd 100644
--- a/libraries/xz-embedded/src/xz_config.h
+++ b/libraries/xz-embedded/src/xz_config.h
@@ -74,36 +74,36 @@ typedef unsigned char bool;
#ifndef get_unaligned_le32
static inline uint32_t get_unaligned_le32(const uint8_t *buf)
{
- return (uint32_t)buf[0] | ((uint32_t)buf[1] << 8) | ((uint32_t)buf[2] << 16) |
- ((uint32_t)buf[3] << 24);
+ return (uint32_t)buf[0] | ((uint32_t)buf[1] << 8) | ((uint32_t)buf[2] << 16) |
+ ((uint32_t)buf[3] << 24);
}
#endif
#ifndef get_unaligned_be32
static inline uint32_t get_unaligned_be32(const uint8_t *buf)
{
- return (uint32_t)(buf[0] << 24) | ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) |
- (uint32_t)buf[3];
+ return (uint32_t)(buf[0] << 24) | ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) |
+ (uint32_t)buf[3];
}
#endif
#ifndef put_unaligned_le32
static inline void put_unaligned_le32(uint32_t val, uint8_t *buf)
{
- buf[0] = (uint8_t)val;
- buf[1] = (uint8_t)(val >> 8);
- buf[2] = (uint8_t)(val >> 16);
- buf[3] = (uint8_t)(val >> 24);
+ buf[0] = (uint8_t)val;
+ buf[1] = (uint8_t)(val >> 8);
+ buf[2] = (uint8_t)(val >> 16);
+ buf[3] = (uint8_t)(val >> 24);
}
#endif
#ifndef put_unaligned_be32
static inline void put_unaligned_be32(uint32_t val, uint8_t *buf)
{
- buf[0] = (uint8_t)(val >> 24);
- buf[1] = (uint8_t)(val >> 16);
- buf[2] = (uint8_t)(val >> 8);
- buf[3] = (uint8_t)val;
+ buf[0] = (uint8_t)(val >> 24);
+ buf[1] = (uint8_t)(val >> 16);
+ buf[2] = (uint8_t)(val >> 8);
+ buf[3] = (uint8_t)val;
}
#endif
diff --git a/libraries/xz-embedded/src/xz_crc32.c b/libraries/xz-embedded/src/xz_crc32.c
index c412662b..65d9d5b8 100644
--- a/libraries/xz-embedded/src/xz_crc32.c
+++ b/libraries/xz-embedded/src/xz_crc32.c
@@ -29,33 +29,33 @@ STATIC_RW_DATA uint32_t xz_crc32_table[256];
XZ_EXTERN void xz_crc32_init(void)
{
- const uint32_t poly = 0xEDB88320;
+ const uint32_t poly = 0xEDB88320;
- uint32_t i;
- uint32_t j;
- uint32_t r;
+ uint32_t i;
+ uint32_t j;
+ uint32_t r;
- for (i = 0; i < 256; ++i)
- {
- r = i;
- for (j = 0; j < 8; ++j)
- r = (r >> 1) ^ (poly & ~((r & 1) - 1));
+ for (i = 0; i < 256; ++i)
+ {
+ r = i;
+ for (j = 0; j < 8; ++j)
+ r = (r >> 1) ^ (poly & ~((r & 1) - 1));
- xz_crc32_table[i] = r;
- }
+ xz_crc32_table[i] = r;
+ }
- return;
+ return;
}
XZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
{
- crc = ~crc;
+ crc = ~crc;
- while (size != 0)
- {
- crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
- --size;
- }
+ while (size != 0)
+ {
+ crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
+ --size;
+ }
- return ~crc;
+ return ~crc;
}
diff --git a/libraries/xz-embedded/src/xz_crc64.c b/libraries/xz-embedded/src/xz_crc64.c
index 4794b9d3..0f711d8d 100644
--- a/libraries/xz-embedded/src/xz_crc64.c
+++ b/libraries/xz-embedded/src/xz_crc64.c
@@ -20,33 +20,33 @@ STATIC_RW_DATA uint64_t xz_crc64_table[256];
XZ_EXTERN void xz_crc64_init(void)
{
- const uint64_t poly = 0xC96C5795D7870F42;
+ const uint64_t poly = 0xC96C5795D7870F42;
- uint32_t i;
- uint32_t j;
- uint64_t r;
+ uint32_t i;
+ uint32_t j;
+ uint64_t r;
- for (i = 0; i < 256; ++i)
- {
- r = i;
- for (j = 0; j < 8; ++j)
- r = (r >> 1) ^ (poly & ~((r & 1) - 1));
+ for (i = 0; i < 256; ++i)
+ {
+ r = i;
+ for (j = 0; j < 8; ++j)
+ r = (r >> 1) ^ (poly & ~((r & 1) - 1));
- xz_crc64_table[i] = r;
- }
+ xz_crc64_table[i] = r;
+ }
- return;
+ return;
}
XZ_EXTERN uint64_t xz_crc64(const uint8_t *buf, size_t size, uint64_t crc)
{
- crc = ~crc;
+ crc = ~crc;
- while (size != 0)
- {
- crc = xz_crc64_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
- --size;
- }
+ while (size != 0)
+ {
+ crc = xz_crc64_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
+ --size;
+ }
- return ~crc;
+ return ~crc;
}
diff --git a/libraries/xz-embedded/src/xz_dec_bcj.c b/libraries/xz-embedded/src/xz_dec_bcj.c
index 9ffda3bd..a79fa76d 100644
--- a/libraries/xz-embedded/src/xz_dec_bcj.c
+++ b/libraries/xz-embedded/src/xz_dec_bcj.c
@@ -18,64 +18,64 @@
struct xz_dec_bcj
{
- /* Type of the BCJ filter being used */
- enum
- {
- BCJ_X86 = 4, /* x86 or x86-64 */
- BCJ_POWERPC = 5, /* Big endian only */
- BCJ_IA64 = 6, /* Big or little endian */
- BCJ_ARM = 7, /* Little endian only */
- BCJ_ARMTHUMB = 8, /* Little endian only */
- BCJ_SPARC = 9 /* Big or little endian */
- } type;
-
- /*
- * Return value of the next filter in the chain. We need to preserve
- * this information across calls, because we must not call the next
- * filter anymore once it has returned XZ_STREAM_END.
- */
- enum xz_ret ret;
-
- /* True if we are operating in single-call mode. */
- bool single_call;
-
- /*
- * Absolute position relative to the beginning of the uncompressed
- * data (in a single .xz Block). We care only about the lowest 32
- * bits so this doesn't need to be uint64_t even with big files.
- */
- uint32_t pos;
-
- /* x86 filter state */
- uint32_t x86_prev_mask;
-
- /* Temporary space to hold the variables from struct xz_buf */
- uint8_t *out;
- size_t out_pos;
- size_t out_size;
-
- struct
- {
- /* Amount of already filtered data in the beginning of buf */
- size_t filtered;
-
- /* Total amount of data currently stored in buf */
- size_t size;
-
- /*
- * Buffer to hold a mix of filtered and unfiltered data. This
- * needs to be big enough to hold Alignment + 2 * Look-ahead:
- *
- * Type Alignment Look-ahead
- * x86 1 4
- * PowerPC 4 0
- * IA-64 16 0
- * ARM 4 0
- * ARM-Thumb 2 2
- * SPARC 4 0
- */
- uint8_t buf[16];
- } temp;
+ /* Type of the BCJ filter being used */
+ enum
+ {
+ BCJ_X86 = 4, /* x86 or x86-64 */
+ BCJ_POWERPC = 5, /* Big endian only */
+ BCJ_IA64 = 6, /* Big or little endian */
+ BCJ_ARM = 7, /* Little endian only */
+ BCJ_ARMTHUMB = 8, /* Little endian only */
+ BCJ_SPARC = 9 /* Big or little endian */
+ } type;
+
+ /*
+ * Return value of the next filter in the chain. We need to preserve
+ * this information across calls, because we must not call the next
+ * filter anymore once it has returned XZ_STREAM_END.
+ */
+ enum xz_ret ret;
+
+ /* True if we are operating in single-call mode. */
+ bool single_call;
+
+ /*
+ * Absolute position relative to the beginning of the uncompressed
+ * data (in a single .xz Block). We care only about the lowest 32
+ * bits so this doesn't need to be uint64_t even with big files.
+ */
+ uint32_t pos;
+
+ /* x86 filter state */
+ uint32_t x86_prev_mask;
+
+ /* Temporary space to hold the variables from struct xz_buf */
+ uint8_t *out;
+ size_t out_pos;
+ size_t out_size;
+
+ struct
+ {
+ /* Amount of already filtered data in the beginning of buf */
+ size_t filtered;
+
+ /* Total amount of data currently stored in buf */
+ size_t size;
+
+ /*
+ * Buffer to hold a mix of filtered and unfiltered data. This
+ * needs to be big enough to hold Alignment + 2 * Look-ahead:
+ *
+ * Type Alignment Look-ahead
+ * x86 1 4
+ * PowerPC 4 0
+ * IA-64 16 0
+ * ARM 4 0
+ * ARM-Thumb 2 2
+ * SPARC 4 0
+ */
+ uint8_t buf[16];
+ } temp;
};
#ifdef XZ_DEC_X86
@@ -85,264 +85,264 @@ struct xz_dec_bcj
*/
static inline int bcj_x86_test_msbyte(uint8_t b)
{
- return b == 0x00 || b == 0xFF;
+ return b == 0x00 || b == 0xFF;
}
static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
{
- static const bool mask_to_allowed_status[8] = {true, true, true, false,
- true, false, false, false};
-
- static const uint8_t mask_to_bit_num[8] = {0, 1, 2, 2, 3, 3, 3, 3};
-
- size_t i;
- size_t prev_pos = (size_t) - 1;
- uint32_t prev_mask = s->x86_prev_mask;
- uint32_t src;
- uint32_t dest;
- uint32_t j;
- uint8_t b;
-
- if (size <= 4)
- return 0;
-
- size -= 4;
- for (i = 0; i < size; ++i)
- {
- if ((buf[i] & 0xFE) != 0xE8)
- continue;
-
- prev_pos = i - prev_pos;
- if (prev_pos > 3)
- {
- prev_mask = 0;
- }
- else
- {
- prev_mask = (prev_mask << (prev_pos - 1)) & 7;
- if (prev_mask != 0)
- {
- b = buf[i + 4 - mask_to_bit_num[prev_mask]];
- if (!mask_to_allowed_status[prev_mask] || bcj_x86_test_msbyte(b))
- {
- prev_pos = i;
- prev_mask = (prev_mask << 1) | 1;
- continue;
- }
- }
- }
-
- prev_pos = i;
-
- if (bcj_x86_test_msbyte(buf[i + 4]))
- {
- src = get_unaligned_le32(buf + i + 1);
- while (true)
- {
- dest = src - (s->pos + (uint32_t)i + 5);
- if (prev_mask == 0)
- break;
-
- j = mask_to_bit_num[prev_mask] * 8;
- b = (uint8_t)(dest >> (24 - j));
- if (!bcj_x86_test_msbyte(b))
- break;
-
- src = dest ^ (((uint32_t)1 << (32 - j)) - 1);
- }
-
- dest &= 0x01FFFFFF;
- dest |= (uint32_t)0 - (dest & 0x01000000);
- put_unaligned_le32(dest, buf + i + 1);
- i += 4;
- }
- else
- {
- prev_mask = (prev_mask << 1) | 1;
- }
- }
-
- prev_pos = i - prev_pos;
- s->x86_prev_mask = prev_pos > 3 ? 0 : prev_mask << (prev_pos - 1);
- return i;
+ static const bool mask_to_allowed_status[8] = {true, true, true, false,
+ true, false, false, false};
+
+ static const uint8_t mask_to_bit_num[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+ size_t i;
+ size_t prev_pos = (size_t) - 1;
+ uint32_t prev_mask = s->x86_prev_mask;
+ uint32_t src;
+ uint32_t dest;
+ uint32_t j;
+ uint8_t b;
+
+ if (size <= 4)
+ return 0;
+
+ size -= 4;
+ for (i = 0; i < size; ++i)
+ {
+ if ((buf[i] & 0xFE) != 0xE8)
+ continue;
+
+ prev_pos = i - prev_pos;
+ if (prev_pos > 3)
+ {
+ prev_mask = 0;
+ }
+ else
+ {
+ prev_mask = (prev_mask << (prev_pos - 1)) & 7;
+ if (prev_mask != 0)
+ {
+ b = buf[i + 4 - mask_to_bit_num[prev_mask]];
+ if (!mask_to_allowed_status[prev_mask] || bcj_x86_test_msbyte(b))
+ {
+ prev_pos = i;
+ prev_mask = (prev_mask << 1) | 1;
+ continue;
+ }
+ }
+ }
+
+ prev_pos = i;
+
+ if (bcj_x86_test_msbyte(buf[i + 4]))
+ {
+ src = get_unaligned_le32(buf + i + 1);
+ while (true)
+ {
+ dest = src - (s->pos + (uint32_t)i + 5);
+ if (prev_mask == 0)
+ break;
+
+ j = mask_to_bit_num[prev_mask] * 8;
+ b = (uint8_t)(dest >> (24 - j));
+ if (!bcj_x86_test_msbyte(b))
+ break;
+
+ src = dest ^ (((uint32_t)1 << (32 - j)) - 1);
+ }
+
+ dest &= 0x01FFFFFF;
+ dest |= (uint32_t)0 - (dest & 0x01000000);
+ put_unaligned_le32(dest, buf + i + 1);
+ i += 4;
+ }
+ else
+ {
+ prev_mask = (prev_mask << 1) | 1;
+ }
+ }
+
+ prev_pos = i - prev_pos;
+ s->x86_prev_mask = prev_pos > 3 ? 0 : prev_mask << (prev_pos - 1);
+ return i;
}
#endif
#ifdef XZ_DEC_POWERPC
static size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
{
- size_t i;
- uint32_t instr;
-
- for (i = 0; i + 4 <= size; i += 4)
- {
- instr = get_unaligned_be32(buf + i);
- if ((instr & 0xFC000003) == 0x48000001)
- {
- instr &= 0x03FFFFFC;
- instr -= s->pos + (uint32_t)i;
- instr &= 0x03FFFFFC;
- instr |= 0x48000001;
- put_unaligned_be32(instr, buf + i);
- }
- }
-
- return i;
+ size_t i;
+ uint32_t instr;
+
+ for (i = 0; i + 4 <= size; i += 4)
+ {
+ instr = get_unaligned_be32(buf + i);
+ if ((instr & 0xFC000003) == 0x48000001)
+ {
+ instr &= 0x03FFFFFC;
+ instr -= s->pos + (uint32_t)i;
+ instr &= 0x03FFFFFC;
+ instr |= 0x48000001;
+ put_unaligned_be32(instr, buf + i);
+ }
+ }
+
+ return i;
}
#endif
#ifdef XZ_DEC_IA64
static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
{
- static const uint8_t branch_table[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 4, 4, 6, 6, 0, 0, 7, 7, 4, 4, 0, 0, 4, 4, 0, 0};
-
- /*
- * The local variables take a little bit stack space, but it's less
- * than what LZMA2 decoder takes, so it doesn't make sense to reduce
- * stack usage here without doing that for the LZMA2 decoder too.
- */
-
- /* Loop counters */
- size_t i;
- size_t j;
-
- /* Instruction slot (0, 1, or 2) in the 128-bit instruction word */
- uint32_t slot;
-
- /* Bitwise offset of the instruction indicated by slot */
- uint32_t bit_pos;
-
- /* bit_pos split into byte and bit parts */
- uint32_t byte_pos;
- uint32_t bit_res;
-
- /* Address part of an instruction */
- uint32_t addr;
-
- /* Mask used to detect which instructions to convert */
- uint32_t mask;
-
- /* 41-bit instruction stored somewhere in the lowest 48 bits */
- uint64_t instr;
-
- /* Instruction normalized with bit_res for easier manipulation */
- uint64_t norm;
-
- for (i = 0; i + 16 <= size; i += 16)
- {
- mask = branch_table[buf[i] & 0x1F];
- for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41)
- {
- if (((mask >> slot) & 1) == 0)
- continue;
-
- byte_pos = bit_pos >> 3;
- bit_res = bit_pos & 7;
- instr = 0;
- for (j = 0; j < 6; ++j)
- instr |= (uint64_t)(buf[i + j + byte_pos]) << (8 * j);
-
- norm = instr >> bit_res;
-
- if (((norm >> 37) & 0x0F) == 0x05 && ((norm >> 9) & 0x07) == 0)
- {
- addr = (norm >> 13) & 0x0FFFFF;
- addr |= ((uint32_t)(norm >> 36) & 1) << 20;
- addr <<= 4;
- addr -= s->pos + (uint32_t)i;
- addr >>= 4;
-
- norm &= ~((uint64_t)0x8FFFFF << 13);
- norm |= (uint64_t)(addr & 0x0FFFFF) << 13;
- norm |= (uint64_t)(addr & 0x100000) << (36 - 20);
-
- instr &= (1 << bit_res) - 1;
- instr |= norm << bit_res;
-
- for (j = 0; j < 6; j++)
- buf[i + j + byte_pos] = (uint8_t)(instr >> (8 * j));
- }
- }
- }
-
- return i;
+ static const uint8_t branch_table[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 6, 6, 0, 0, 7, 7, 4, 4, 0, 0, 4, 4, 0, 0};
+
+ /*
+ * The local variables take a little bit stack space, but it's less
+ * than what LZMA2 decoder takes, so it doesn't make sense to reduce
+ * stack usage here without doing that for the LZMA2 decoder too.
+ */
+
+ /* Loop counters */
+ size_t i;
+ size_t j;
+
+ /* Instruction slot (0, 1, or 2) in the 128-bit instruction word */
+ uint32_t slot;
+
+ /* Bitwise offset of the instruction indicated by slot */
+ uint32_t bit_pos;
+
+ /* bit_pos split into byte and bit parts */
+ uint32_t byte_pos;
+ uint32_t bit_res;
+
+ /* Address part of an instruction */
+ uint32_t addr;
+
+ /* Mask used to detect which instructions to convert */
+ uint32_t mask;
+
+ /* 41-bit instruction stored somewhere in the lowest 48 bits */
+ uint64_t instr;
+
+ /* Instruction normalized with bit_res for easier manipulation */
+ uint64_t norm;
+
+ for (i = 0; i + 16 <= size; i += 16)
+ {
+ mask = branch_table[buf[i] & 0x1F];
+ for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41)
+ {
+ if (((mask >> slot) & 1) == 0)
+ continue;
+
+ byte_pos = bit_pos >> 3;
+ bit_res = bit_pos & 7;
+ instr = 0;
+ for (j = 0; j < 6; ++j)
+ instr |= (uint64_t)(buf[i + j + byte_pos]) << (8 * j);
+
+ norm = instr >> bit_res;
+
+ if (((norm >> 37) & 0x0F) == 0x05 && ((norm >> 9) & 0x07) == 0)
+ {
+ addr = (norm >> 13) & 0x0FFFFF;
+ addr |= ((uint32_t)(norm >> 36) & 1) << 20;
+ addr <<= 4;
+ addr -= s->pos + (uint32_t)i;
+ addr >>= 4;
+
+ norm &= ~((uint64_t)0x8FFFFF << 13);
+ norm |= (uint64_t)(addr & 0x0FFFFF) << 13;
+ norm |= (uint64_t)(addr & 0x100000) << (36 - 20);
+
+ instr &= (1 << bit_res) - 1;
+ instr |= norm << bit_res;
+
+ for (j = 0; j < 6; j++)
+ buf[i + j + byte_pos] = (uint8_t)(instr >> (8 * j));
+ }
+ }
+ }
+
+ return i;
}
#endif
#ifdef XZ_DEC_ARM
static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
{
- size_t i;
- uint32_t addr;
-
- for (i = 0; i + 4 <= size; i += 4)
- {
- if (buf[i + 3] == 0xEB)
- {
- addr =
- (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8) | ((uint32_t)buf[i + 2] << 16);
- addr <<= 2;
- addr -= s->pos + (uint32_t)i + 8;
- addr >>= 2;
- buf[i] = (uint8_t)addr;
- buf[i + 1] = (uint8_t)(addr >> 8);
- buf[i + 2] = (uint8_t)(addr >> 16);
- }
- }
-
- return i;
+ size_t i;
+ uint32_t addr;
+
+ for (i = 0; i + 4 <= size; i += 4)
+ {
+ if (buf[i + 3] == 0xEB)
+ {
+ addr =
+ (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8) | ((uint32_t)buf[i + 2] << 16);
+ addr <<= 2;
+ addr -= s->pos + (uint32_t)i + 8;
+ addr >>= 2;
+ buf[i] = (uint8_t)addr;
+ buf[i + 1] = (uint8_t)(addr >> 8);
+ buf[i + 2] = (uint8_t)(addr >> 16);
+ }
+ }
+
+ return i;
}
#endif
#ifdef XZ_DEC_ARMTHUMB
static size_t bcj_armthumb(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
{
- size_t i;
- uint32_t addr;
-
- for (i = 0; i + 4 <= size; i += 2)
- {
- if ((buf[i + 1] & 0xF8) == 0xF0 && (buf[i + 3] & 0xF8) == 0xF8)
- {
- addr = (((uint32_t)buf[i + 1] & 0x07) << 19) | ((uint32_t)buf[i] << 11) |
- (((uint32_t)buf[i + 3] & 0x07) << 8) | (uint32_t)buf[i + 2];
- addr <<= 1;
- addr -= s->pos + (uint32_t)i + 4;
- addr >>= 1;
- buf[i + 1] = (uint8_t)(0xF0 | ((addr >> 19) & 0x07));
- buf[i] = (uint8_t)(addr >> 11);
- buf[i + 3] = (uint8_t)(0xF8 | ((addr >> 8) & 0x07));
- buf[i + 2] = (uint8_t)addr;
- i += 2;
- }
- }
-
- return i;
+ size_t i;
+ uint32_t addr;
+
+ for (i = 0; i + 4 <= size; i += 2)
+ {
+ if ((buf[i + 1] & 0xF8) == 0xF0 && (buf[i + 3] & 0xF8) == 0xF8)
+ {
+ addr = (((uint32_t)buf[i + 1] & 0x07) << 19) | ((uint32_t)buf[i] << 11) |
+ (((uint32_t)buf[i + 3] & 0x07) << 8) | (uint32_t)buf[i + 2];
+ addr <<= 1;
+ addr -= s->pos + (uint32_t)i + 4;
+ addr >>= 1;
+ buf[i + 1] = (uint8_t)(0xF0 | ((addr >> 19) & 0x07));
+ buf[i] = (uint8_t)(addr >> 11);
+ buf[i + 3] = (uint8_t)(0xF8 | ((addr >> 8) & 0x07));
+ buf[i + 2] = (uint8_t)addr;
+ i += 2;
+ }
+ }
+
+ return i;
}
#endif
#ifdef XZ_DEC_SPARC
static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
{
- size_t i;
- uint32_t instr;
-
- for (i = 0; i + 4 <= size; i += 4)
- {
- instr = get_unaligned_be32(buf + i);
- if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF)
- {
- instr <<= 2;
- instr -= s->pos + (uint32_t)i;
- instr >>= 2;
- instr =
- ((uint32_t)0x40000000 - (instr & 0x400000)) | 0x40000000 | (instr & 0x3FFFFF);
- put_unaligned_be32(instr, buf + i);
- }
- }
-
- return i;
+ size_t i;
+ uint32_t instr;
+
+ for (i = 0; i + 4 <= size; i += 4)
+ {
+ instr = get_unaligned_be32(buf + i);
+ if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF)
+ {
+ instr <<= 2;
+ instr -= s->pos + (uint32_t)i;
+ instr >>= 2;
+ instr =
+ ((uint32_t)0x40000000 - (instr & 0x400000)) | 0x40000000 | (instr & 0x3FFFFF);
+ put_unaligned_be32(instr, buf + i);
+ }
+ }
+
+ return i;
}
#endif
@@ -356,51 +356,51 @@ static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
*/
static void bcj_apply(struct xz_dec_bcj *s, uint8_t *buf, size_t *pos, size_t size)
{
- size_t filtered;
+ size_t filtered;
- buf += *pos;
- size -= *pos;
+ buf += *pos;
+ size -= *pos;
- switch (s->type)
- {
+ switch (s->type)
+ {
#ifdef XZ_DEC_X86
- case BCJ_X86:
- filtered = bcj_x86(s, buf, size);
- break;
+ case BCJ_X86:
+ filtered = bcj_x86(s, buf, size);
+ break;
#endif
#ifdef XZ_DEC_POWERPC
- case BCJ_POWERPC:
- filtered = bcj_powerpc(s, buf, size);
- break;
+ case BCJ_POWERPC:
+ filtered = bcj_powerpc(s, buf, size);
+ break;
#endif
#ifdef XZ_DEC_IA64
- case BCJ_IA64:
- filtered = bcj_ia64(s, buf, size);
- break;
+ case BCJ_IA64:
+ filtered = bcj_ia64(s, buf, size);
+ break;
#endif
#ifdef XZ_DEC_ARM
- case BCJ_ARM:
- filtered = bcj_arm(s, buf, size);
- break;
+ case BCJ_ARM:
+ filtered = bcj_arm(s, buf, size);
+ break;
#endif
#ifdef XZ_DEC_ARMTHUMB
- case BCJ_ARMTHUMB:
- filtered = bcj_armthumb(s, buf, size);
- break;
+ case BCJ_ARMTHUMB:
+ filtered = bcj_armthumb(s, buf, size);
+ break;
#endif
#ifdef XZ_DEC_SPARC
- case BCJ_SPARC:
- filtered = bcj_sparc(s, buf, size);
- break;
+ case BCJ_SPARC:
+ filtered = bcj_sparc(s, buf, size);
+ break;
#endif
- default:
- /* Never reached but silence compiler warnings. */
- filtered = 0;
- break;
- }
-
- *pos += filtered;
- s->pos += filtered;
+ default:
+ /* Never reached but silence compiler warnings. */
+ filtered = 0;
+ break;
+ }
+
+ *pos += filtered;
+ s->pos += filtered;
}
/*
@@ -410,15 +410,15 @@ static void bcj_apply(struct xz_dec_bcj *s, uint8_t *buf, size_t *pos, size_t si
*/
static void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b)
{
- size_t copy_size;
+ size_t copy_size;
- copy_size = min_t(size_t, s->temp.filtered, b->out_size - b->out_pos);
- memcpy(b->out + b->out_pos, s->temp.buf, copy_size);
- b->out_pos += copy_size;
+ copy_size = min_t(size_t, s->temp.filtered, b->out_size - b->out_pos);
+ memcpy(b->out + b->out_pos, s->temp.buf, copy_size);
+ b->out_pos += copy_size;
- s->temp.filtered -= copy_size;
- s->temp.size -= copy_size;
- memmove(s->temp.buf, s->temp.buf + copy_size, s->temp.size);
+ s->temp.filtered -= copy_size;
+ s->temp.size -= copy_size;
+ memmove(s->temp.buf, s->temp.buf + copy_size, s->temp.size);
}
/*
@@ -427,162 +427,162 @@ static void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b)
* some buffering.
*/
XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzma2,
- struct xz_buf *b)
+ struct xz_buf *b)
{
- size_t out_start;
-
- /*
- * Flush pending already filtered data to the output buffer. Return
- * immediatelly if we couldn't flush everything, or if the next
- * filter in the chain had already returned XZ_STREAM_END.
- */
- if (s->temp.filtered > 0)
- {
- bcj_flush(s, b);
- if (s->temp.filtered > 0)
- return XZ_OK;
-
- if (s->ret == XZ_STREAM_END)
- return XZ_STREAM_END;
- }
-
- /*
- * If we have more output space than what is currently pending in
- * temp, copy the unfiltered data from temp to the output buffer
- * and try to fill the output buffer by decoding more data from the
- * next filter in the chain. Apply the BCJ filter on the new data
- * in the output buffer. If everything cannot be filtered, copy it
- * to temp and rewind the output buffer position accordingly.
- *
- * This needs to be always run when temp.size == 0 to handle a special
- * case where the output buffer is full and the next filter has no
- * more output coming but hasn't returned XZ_STREAM_END yet.
- */
- if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0)
- {
- out_start = b->out_pos;
- memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
- b->out_pos += s->temp.size;
-
- s->ret = xz_dec_lzma2_run(lzma2, b);
- if (s->ret != XZ_STREAM_END && (s->ret != XZ_OK || s->single_call))
- return s->ret;
-
- bcj_apply(s, b->out, &out_start, b->out_pos);
-
- /*
- * As an exception, if the next filter returned XZ_STREAM_END,
- * we can do that too, since the last few bytes that remain
- * unfiltered are meant to remain unfiltered.
- */
- if (s->ret == XZ_STREAM_END)
- return XZ_STREAM_END;
-
- s->temp.size = b->out_pos - out_start;
- b->out_pos -= s->temp.size;
- memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
-
- /*
- * If there wasn't enough input to the next filter to fill
- * the output buffer with unfiltered data, there's no point
- * to try decoding more data to temp.
- */
- if (b->out_pos + s->temp.size < b->out_size)
- return XZ_OK;
- }
-
- /*
- * We have unfiltered data in temp. If the output buffer isn't full
- * yet, try to fill the temp buffer by decoding more data from the
- * next filter. Apply the BCJ filter on temp. Then we hopefully can
- * fill the actual output buffer by copying filtered data from temp.
- * A mix of filtered and unfiltered data may be left in temp; it will
- * be taken care on the next call to this function.
- */
- if (b->out_pos < b->out_size)
- {
- /* Make b->out{,_pos,_size} temporarily point to s->temp. */
- s->out = b->out;
- s->out_pos = b->out_pos;
- s->out_size = b->out_size;
- b->out = s->temp.buf;
- b->out_pos = s->temp.size;
- b->out_size = sizeof(s->temp.buf);
-
- s->ret = xz_dec_lzma2_run(lzma2, b);
-
- s->temp.size = b->out_pos;
- b->out = s->out;
- b->out_pos = s->out_pos;
- b->out_size = s->out_size;
-
- if (s->ret != XZ_OK && s->ret != XZ_STREAM_END)
- return s->ret;
-
- bcj_apply(s, s->temp.buf, &s->temp.filtered, s->temp.size);
-
- /*
- * If the next filter returned XZ_STREAM_END, we mark that
- * everything is filtered, since the last unfiltered bytes
- * of the stream are meant to be left as is.
- */
- if (s->ret == XZ_STREAM_END)
- s->temp.filtered = s->temp.size;
-
- bcj_flush(s, b);
- if (s->temp.filtered > 0)
- return XZ_OK;
- }
-
- return s->ret;
+ size_t out_start;
+
+ /*
+ * Flush pending already filtered data to the output buffer. Return
+ * immediatelly if we couldn't flush everything, or if the next
+ * filter in the chain had already returned XZ_STREAM_END.
+ */
+ if (s->temp.filtered > 0)
+ {
+ bcj_flush(s, b);
+ if (s->temp.filtered > 0)
+ return XZ_OK;
+
+ if (s->ret == XZ_STREAM_END)
+ return XZ_STREAM_END;
+ }
+
+ /*
+ * If we have more output space than what is currently pending in
+ * temp, copy the unfiltered data from temp to the output buffer
+ * and try to fill the output buffer by decoding more data from the
+ * next filter in the chain. Apply the BCJ filter on the new data
+ * in the output buffer. If everything cannot be filtered, copy it
+ * to temp and rewind the output buffer position accordingly.
+ *
+ * This needs to be always run when temp.size == 0 to handle a special
+ * case where the output buffer is full and the next filter has no
+ * more output coming but hasn't returned XZ_STREAM_END yet.
+ */
+ if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0)
+ {
+ out_start = b->out_pos;
+ memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
+ b->out_pos += s->temp.size;
+
+ s->ret = xz_dec_lzma2_run(lzma2, b);
+ if (s->ret != XZ_STREAM_END && (s->ret != XZ_OK || s->single_call))
+ return s->ret;
+
+ bcj_apply(s, b->out, &out_start, b->out_pos);
+
+ /*
+ * As an exception, if the next filter returned XZ_STREAM_END,
+ * we can do that too, since the last few bytes that remain
+ * unfiltered are meant to remain unfiltered.
+ */
+ if (s->ret == XZ_STREAM_END)
+ return XZ_STREAM_END;
+
+ s->temp.size = b->out_pos - out_start;
+ b->out_pos -= s->temp.size;
+ memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
+
+ /*
+ * If there wasn't enough input to the next filter to fill
+ * the output buffer with unfiltered data, there's no point
+ * to try decoding more data to temp.
+ */
+ if (b->out_pos + s->temp.size < b->out_size)
+ return XZ_OK;
+ }
+
+ /*
+ * We have unfiltered data in temp. If the output buffer isn't full
+ * yet, try to fill the temp buffer by decoding more data from the
+ * next filter. Apply the BCJ filter on temp. Then we hopefully can
+ * fill the actual output buffer by copying filtered data from temp.
+ * A mix of filtered and unfiltered data may be left in temp; it will
+ * be taken care on the next call to this function.
+ */
+ if (b->out_pos < b->out_size)
+ {
+ /* Make b->out{,_pos,_size} temporarily point to s->temp. */
+ s->out = b->out;
+ s->out_pos = b->out_pos;
+ s->out_size = b->out_size;
+ b->out = s->temp.buf;
+ b->out_pos = s->temp.size;
+ b->out_size = sizeof(s->temp.buf);
+
+ s->ret = xz_dec_lzma2_run(lzma2, b);
+
+ s->temp.size = b->out_pos;
+ b->out = s->out;
+ b->out_pos = s->out_pos;
+ b->out_size = s->out_size;
+
+ if (s->ret != XZ_OK && s->ret != XZ_STREAM_END)
+ return s->ret;
+
+ bcj_apply(s, s->temp.buf, &s->temp.filtered, s->temp.size);
+
+ /*
+ * If the next filter returned XZ_STREAM_END, we mark that
+ * everything is filtered, since the last unfiltered bytes
+ * of the stream are meant to be left as is.
+ */
+ if (s->ret == XZ_STREAM_END)
+ s->temp.filtered = s->temp.size;
+
+ bcj_flush(s, b);
+ if (s->temp.filtered > 0)
+ return XZ_OK;
+ }
+
+ return s->ret;
}
XZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(bool single_call)
{
- struct xz_dec_bcj *s = kmalloc(sizeof(*s), GFP_KERNEL);
- if (s != NULL)
- s->single_call = single_call;
+ struct xz_dec_bcj *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (s != NULL)
+ s->single_call = single_call;
- return s;
+ return s;
}
XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id)
{
- switch (id)
- {
+ switch (id)
+ {
#ifdef XZ_DEC_X86
- case BCJ_X86:
+ case BCJ_X86:
#endif
#ifdef XZ_DEC_POWERPC
- case BCJ_POWERPC:
+ case BCJ_POWERPC:
#endif
#ifdef XZ_DEC_IA64
- case BCJ_IA64:
+ case BCJ_IA64:
#endif
#ifdef XZ_DEC_ARM
- case BCJ_ARM:
+ case BCJ_ARM:
#endif
#ifdef XZ_DEC_ARMTHUMB
- case BCJ_ARMTHUMB:
+ case BCJ_ARMTHUMB:
#endif
#ifdef XZ_DEC_SPARC
- case BCJ_SPARC:
+ case BCJ_SPARC:
#endif
- break;
+ break;
- default:
- /* Unsupported Filter ID */
- return XZ_OPTIONS_ERROR;
- }
+ default:
+ /* Unsupported Filter ID */
+ return XZ_OPTIONS_ERROR;
+ }
- s->type = id;
- s->ret = XZ_OK;
- s->pos = 0;
- s->x86_prev_mask = 0;
- s->temp.filtered = 0;
- s->temp.size = 0;
+ s->type = id;
+ s->ret = XZ_OK;
+ s->pos = 0;
+ s->x86_prev_mask = 0;
+ s->temp.filtered = 0;
+ s->temp.size = 0;
- return XZ_OK;
+ return XZ_OK;
}
#endif
diff --git a/libraries/xz-embedded/src/xz_dec_lzma2.c b/libraries/xz-embedded/src/xz_dec_lzma2.c
index 3d7b9a2e..365ace2b 100644
--- a/libraries/xz-embedded/src/xz_dec_lzma2.c
+++ b/libraries/xz-embedded/src/xz_dec_lzma2.c
@@ -43,244 +43,244 @@
*/
struct dictionary
{
- /* Beginning of the history buffer */
- uint8_t *buf;
-
- /* Old position in buf (before decoding more data) */
- size_t start;
-
- /* Position in buf */
- size_t pos;
-
- /*
- * How full dictionary is. This is used to detect corrupt input that
- * would read beyond the beginning of the uncompressed stream.
- */
- size_t full;
-
- /* Write limit; we don't write to buf[limit] or later bytes. */
- size_t limit;
-
- /*
- * End of the dictionary buffer. In multi-call mode, this is
- * the same as the dictionary size. In single-call mode, this
- * indicates the size of the output buffer.
- */
- size_t end;
-
- /*
- * Size of the dictionary as specified in Block Header. This is used
- * together with "full" to detect corrupt input that would make us
- * read beyond the beginning of the uncompressed stream.
- */
- uint32_t size;
-
- /*
- * Maximum allowed dictionary size in multi-call mode.
- * This is ignored in single-call mode.
- */
- uint32_t size_max;
-
- /*
- * Amount of memory currently allocated for the dictionary.
- * This is used only with XZ_DYNALLOC. (With XZ_PREALLOC,
- * size_max is always the same as the allocated size.)
- */
- uint32_t allocated;
-
- /* Operation mode */
- enum xz_mode mode;
+ /* Beginning of the history buffer */
+ uint8_t *buf;
+
+ /* Old position in buf (before decoding more data) */
+ size_t start;
+
+ /* Position in buf */
+ size_t pos;
+
+ /*
+ * How full dictionary is. This is used to detect corrupt input that
+ * would read beyond the beginning of the uncompressed stream.
+ */
+ size_t full;
+
+ /* Write limit; we don't write to buf[limit] or later bytes. */
+ size_t limit;
+
+ /*
+ * End of the dictionary buffer. In multi-call mode, this is
+ * the same as the dictionary size. In single-call mode, this
+ * indicates the size of the output buffer.
+ */
+ size_t end;
+
+ /*
+ * Size of the dictionary as specified in Block Header. This is used
+ * together with "full" to detect corrupt input that would make us
+ * read beyond the beginning of the uncompressed stream.
+ */
+ uint32_t size;
+
+ /*
+ * Maximum allowed dictionary size in multi-call mode.
+ * This is ignored in single-call mode.
+ */
+ uint32_t size_max;
+
+ /*
+ * Amount of memory currently allocated for the dictionary.
+ * This is used only with XZ_DYNALLOC. (With XZ_PREALLOC,
+ * size_max is always the same as the allocated size.)
+ */
+ uint32_t allocated;
+
+ /* Operation mode */
+ enum xz_mode mode;
};
/* Range decoder */
struct rc_dec
{
- uint32_t range;
- uint32_t code;
-
- /*
- * Number of initializing bytes remaining to be read
- * by rc_read_init().
- */
- uint32_t init_bytes_left;
-
- /*
- * Buffer from which we read our input. It can be either
- * temp.buf or the caller-provided input buffer.
- */
- const uint8_t *in;
- size_t in_pos;
- size_t in_limit;
+ uint32_t range;
+ uint32_t code;
+
+ /*
+ * Number of initializing bytes remaining to be read
+ * by rc_read_init().
+ */
+ uint32_t init_bytes_left;
+
+ /*
+ * Buffer from which we read our input. It can be either
+ * temp.buf or the caller-provided input buffer.
+ */
+ const uint8_t *in;
+ size_t in_pos;
+ size_t in_limit;
};
/* Probabilities for a length decoder. */
struct lzma_len_dec
{
- /* Probability of match length being at least 10 */
- uint16_t choice;
+ /* Probability of match length being at least 10 */
+ uint16_t choice;
- /* Probability of match length being at least 18 */
- uint16_t choice2;
+ /* Probability of match length being at least 18 */
+ uint16_t choice2;
- /* Probabilities for match lengths 2-9 */
- uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
+ /* Probabilities for match lengths 2-9 */
+ uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
- /* Probabilities for match lengths 10-17 */
- uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
+ /* Probabilities for match lengths 10-17 */
+ uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
- /* Probabilities for match lengths 18-273 */
- uint16_t high[LEN_HIGH_SYMBOLS];
+ /* Probabilities for match lengths 18-273 */
+ uint16_t high[LEN_HIGH_SYMBOLS];
};
struct lzma_dec
{
- /* Distances of latest four matches */
- uint32_t rep0;
- uint32_t rep1;
- uint32_t rep2;
- uint32_t rep3;
-
- /* Types of the most recently seen LZMA symbols */
- enum lzma_state state;
-
- /*
- * Length of a match. This is updated so that dict_repeat can
- * be called again to finish repeating the whole match.
- */
- uint32_t len;
-
- /*
- * LZMA properties or related bit masks (number of literal
- * context bits, a mask dervied from the number of literal
- * position bits, and a mask dervied from the number
- * position bits)
- */
- uint32_t lc;
- uint32_t literal_pos_mask; /* (1 << lp) - 1 */
- uint32_t pos_mask; /* (1 << pb) - 1 */
-
- /* If 1, it's a match. Otherwise it's a single 8-bit literal. */
- uint16_t is_match[STATES][POS_STATES_MAX];
-
- /* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */
- uint16_t is_rep[STATES];
-
- /*
- * If 0, distance of a repeated match is rep0.
- * Otherwise check is_rep1.
- */
- uint16_t is_rep0[STATES];
-
- /*
- * If 0, distance of a repeated match is rep1.
- * Otherwise check is_rep2.
- */
- uint16_t is_rep1[STATES];
-
- /* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */
- uint16_t is_rep2[STATES];
-
- /*
- * If 1, the repeated match has length of one byte. Otherwise
- * the length is decoded from rep_len_decoder.
- */
- uint16_t is_rep0_long[STATES][POS_STATES_MAX];
-
- /*
- * Probability tree for the highest two bits of the match
- * distance. There is a separate probability tree for match
- * lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273].
- */
- uint16_t dist_slot[DIST_STATES][DIST_SLOTS];
-
- /*
- * Probility trees for additional bits for match distance
- * when the distance is in the range [4, 127].
- */
- uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END];
-
- /*
- * Probability tree for the lowest four bits of a match
- * distance that is equal to or greater than 128.
- */
- uint16_t dist_align[ALIGN_SIZE];
-
- /* Length of a normal match */
- struct lzma_len_dec match_len_dec;
-
- /* Length of a repeated match */
- struct lzma_len_dec rep_len_dec;
-
- /* Probabilities of literals */
- uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
+ /* Distances of latest four matches */
+ uint32_t rep0;
+ uint32_t rep1;
+ uint32_t rep2;
+ uint32_t rep3;
+
+ /* Types of the most recently seen LZMA symbols */
+ enum lzma_state state;
+
+ /*
+ * Length of a match. This is updated so that dict_repeat can
+ * be called again to finish repeating the whole match.
+ */
+ uint32_t len;
+
+ /*
+ * LZMA properties or related bit masks (number of literal
+ * context bits, a mask dervied from the number of literal
+ * position bits, and a mask dervied from the number
+ * position bits)
+ */
+ uint32_t lc;
+ uint32_t literal_pos_mask; /* (1 << lp) - 1 */
+ uint32_t pos_mask; /* (1 << pb) - 1 */
+
+ /* If 1, it's a match. Otherwise it's a single 8-bit literal. */
+ uint16_t is_match[STATES][POS_STATES_MAX];
+
+ /* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */
+ uint16_t is_rep[STATES];
+
+ /*
+ * If 0, distance of a repeated match is rep0.
+ * Otherwise check is_rep1.
+ */
+ uint16_t is_rep0[STATES];
+
+ /*
+ * If 0, distance of a repeated match is rep1.
+ * Otherwise check is_rep2.
+ */
+ uint16_t is_rep1[STATES];
+
+ /* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */
+ uint16_t is_rep2[STATES];
+
+ /*
+ * If 1, the repeated match has length of one byte. Otherwise
+ * the length is decoded from rep_len_decoder.
+ */
+ uint16_t is_rep0_long[STATES][POS_STATES_MAX];
+
+ /*
+ * Probability tree for the highest two bits of the match
+ * distance. There is a separate probability tree for match
+ * lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273].
+ */
+ uint16_t dist_slot[DIST_STATES][DIST_SLOTS];
+
+ /*
+ * Probility trees for additional bits for match distance
+ * when the distance is in the range [4, 127].
+ */
+ uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END];
+
+ /*
+ * Probability tree for the lowest four bits of a match
+ * distance that is equal to or greater than 128.
+ */
+ uint16_t dist_align[ALIGN_SIZE];
+
+ /* Length of a normal match */
+ struct lzma_len_dec match_len_dec;
+
+ /* Length of a repeated match */
+ struct lzma_len_dec rep_len_dec;
+
+ /* Probabilities of literals */
+ uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
};
struct lzma2_dec
{
- /* Position in xz_dec_lzma2_run(). */
- enum lzma2_seq
- {
- SEQ_CONTROL,
- SEQ_UNCOMPRESSED_1,
- SEQ_UNCOMPRESSED_2,
- SEQ_COMPRESSED_0,
- SEQ_COMPRESSED_1,
- SEQ_PROPERTIES,
- SEQ_LZMA_PREPARE,
- SEQ_LZMA_RUN,
- SEQ_COPY
- } sequence;
-
- /* Next position after decoding the compressed size of the chunk. */
- enum lzma2_seq next_sequence;
-
- /* Uncompressed size of LZMA chunk (2 MiB at maximum) */
- uint32_t uncompressed;
-
- /*
- * Compressed size of LZMA chunk or compressed/uncompressed
- * size of uncompressed chunk (64 KiB at maximum)
- */
- uint32_t compressed;
-
- /*
- * True if dictionary reset is needed. This is false before
- * the first chunk (LZMA or uncompressed).
- */
- bool need_dict_reset;
-
- /*
- * True if new LZMA properties are needed. This is false
- * before the first LZMA chunk.
- */
- bool need_props;
+ /* Position in xz_dec_lzma2_run(). */
+ enum lzma2_seq
+ {
+ SEQ_CONTROL,
+ SEQ_UNCOMPRESSED_1,
+ SEQ_UNCOMPRESSED_2,
+ SEQ_COMPRESSED_0,
+ SEQ_COMPRESSED_1,
+ SEQ_PROPERTIES,
+ SEQ_LZMA_PREPARE,
+ SEQ_LZMA_RUN,
+ SEQ_COPY
+ } sequence;
+
+ /* Next position after decoding the compressed size of the chunk. */
+ enum lzma2_seq next_sequence;
+
+ /* Uncompressed size of LZMA chunk (2 MiB at maximum) */
+ uint32_t uncompressed;
+
+ /*
+ * Compressed size of LZMA chunk or compressed/uncompressed
+ * size of uncompressed chunk (64 KiB at maximum)
+ */
+ uint32_t compressed;
+
+ /*
+ * True if dictionary reset is needed. This is false before
+ * the first chunk (LZMA or uncompressed).
+ */
+ bool need_dict_reset;
+
+ /*
+ * True if new LZMA properties are needed. This is false
+ * before the first LZMA chunk.
+ */
+ bool need_props;
};
struct xz_dec_lzma2
{
- /*
- * The order below is important on x86 to reduce code size and
- * it shouldn't hurt on other platforms. Everything up to and
- * including lzma.pos_mask are in the first 128 bytes on x86-32,
- * which allows using smaller instructions to access those
- * variables. On x86-64, fewer variables fit into the first 128
- * bytes, but this is still the best order without sacrificing
- * the readability by splitting the structures.
- */
- struct rc_dec rc;
- struct dictionary dict;
- struct lzma2_dec lzma2;
- struct lzma_dec lzma;
-
- /*
- * Temporary buffer which holds small number of input bytes between
- * decoder calls. See lzma2_lzma() for details.
- */
- struct
- {
- uint32_t size;
- uint8_t buf[3 * LZMA_IN_REQUIRED];
- } temp;
+ /*
+ * The order below is important on x86 to reduce code size and
+ * it shouldn't hurt on other platforms. Everything up to and
+ * including lzma.pos_mask are in the first 128 bytes on x86-32,
+ * which allows using smaller instructions to access those
+ * variables. On x86-64, fewer variables fit into the first 128
+ * bytes, but this is still the best order without sacrificing
+ * the readability by splitting the structures.
+ */
+ struct rc_dec rc;
+ struct dictionary dict;
+ struct lzma2_dec lzma2;
+ struct lzma_dec lzma;
+
+ /*
+ * Temporary buffer which holds small number of input bytes between
+ * decoder calls. See lzma2_lzma() for details.
+ */
+ struct
+ {
+ uint32_t size;
+ uint8_t buf[3 * LZMA_IN_REQUIRED];
+ } temp;
};
/**************
@@ -293,31 +293,31 @@ struct xz_dec_lzma2
*/
static void dict_reset(struct dictionary *dict, struct xz_buf *b)
{
- if (DEC_IS_SINGLE(dict->mode))
- {
- dict->buf = b->out + b->out_pos;
- dict->end = b->out_size - b->out_pos;
- }
-
- dict->start = 0;
- dict->pos = 0;
- dict->limit = 0;
- dict->full = 0;
+ if (DEC_IS_SINGLE(dict->mode))
+ {
+ dict->buf = b->out + b->out_pos;
+ dict->end = b->out_size - b->out_pos;
+ }
+
+ dict->start = 0;
+ dict->pos = 0;
+ dict->limit = 0;
+ dict->full = 0;
}
/* Set dictionary write limit */
static void dict_limit(struct dictionary *dict, size_t out_max)
{
- if (dict->end - dict->pos <= out_max)
- dict->limit = dict->end;
- else
- dict->limit = dict->pos + out_max;
+ if (dict->end - dict->pos <= out_max)
+ dict->limit = dict->end;
+ else
+ dict->limit = dict->pos + out_max;
}
/* Return true if at least one byte can be written into the dictionary. */
static inline bool dict_has_space(const struct dictionary *dict)
{
- return dict->pos < dict->limit;
+ return dict->pos < dict->limit;
}
/*
@@ -328,12 +328,12 @@ static inline bool dict_has_space(const struct dictionary *dict)
*/
static inline uint32_t dict_get(const struct dictionary *dict, uint32_t dist)
{
- size_t offset = dict->pos - dist - 1;
+ size_t offset = dict->pos - dist - 1;
- if (dist >= dict->pos)
- offset += dict->end;
+ if (dist >= dict->pos)
+ offset += dict->end;
- return dict->full > 0 ? dict->buf[offset] : 0;
+ return dict->full > 0 ? dict->buf[offset] : 0;
}
/*
@@ -341,10 +341,10 @@ static inline uint32_t dict_get(const struct dictionary *dict, uint32_t dist)
*/
static inline void dict_put(struct dictionary *dict, uint8_t byte)
{
- dict->buf[dict->pos++] = byte;
+ dict->buf[dict->pos++] = byte;
- if (dict->full < dict->pos)
- dict->full = dict->pos;
+ if (dict->full < dict->pos)
+ dict->full = dict->pos;
}
/*
@@ -354,66 +354,66 @@ static inline void dict_put(struct dictionary *dict, uint8_t byte)
*/
static bool dict_repeat(struct dictionary *dict, uint32_t *len, uint32_t dist)
{
- size_t back;
- uint32_t left;
+ size_t back;
+ uint32_t left;
- if (dist >= dict->full || dist >= dict->size)
- return false;
+ if (dist >= dict->full || dist >= dict->size)
+ return false;
- left = min_t(size_t, dict->limit - dict->pos, *len);
- *len -= left;
+ left = min_t(size_t, dict->limit - dict->pos, *len);
+ *len -= left;
- back = dict->pos - dist - 1;
- if (dist >= dict->pos)
- back += dict->end;
+ back = dict->pos - dist - 1;
+ if (dist >= dict->pos)
+ back += dict->end;
- do
- {
- dict->buf[dict->pos++] = dict->buf[back++];
- if (back == dict->end)
- back = 0;
- } while (--left > 0);
+ do
+ {
+ dict->buf[dict->pos++] = dict->buf[back++];
+ if (back == dict->end)
+ back = 0;
+ } while (--left > 0);
- if (dict->full < dict->pos)
- dict->full = dict->pos;
+ if (dict->full < dict->pos)
+ dict->full = dict->pos;
- return true;
+ return true;
}
/* Copy uncompressed data as is from input to dictionary and output buffers. */
static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b, uint32_t *left)
{
- size_t copy_size;
+ size_t copy_size;
- while (*left > 0 && b->in_pos < b->in_size && b->out_pos < b->out_size)
- {
- copy_size = min(b->in_size - b->in_pos, b->out_size - b->out_pos);
- if (copy_size > dict->end - dict->pos)
- copy_size = dict->end - dict->pos;
- if (copy_size > *left)
- copy_size = *left;
+ while (*left > 0 && b->in_pos < b->in_size && b->out_pos < b->out_size)
+ {
+ copy_size = min(b->in_size - b->in_pos, b->out_size - b->out_pos);
+ if (copy_size > dict->end - dict->pos)
+ copy_size = dict->end - dict->pos;
+ if (copy_size > *left)
+ copy_size = *left;
- *left -= copy_size;
+ *left -= copy_size;
- memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
- dict->pos += copy_size;
+ memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
+ dict->pos += copy_size;
- if (dict->full < dict->pos)
- dict->full = dict->pos;
+ if (dict->full < dict->pos)
+ dict->full = dict->pos;
- if (DEC_IS_MULTI(dict->mode))
- {
- if (dict->pos == dict->end)
- dict->pos = 0;
+ if (DEC_IS_MULTI(dict->mode))
+ {
+ if (dict->pos == dict->end)
+ dict->pos = 0;
- memcpy(b->out + b->out_pos, b->in + b->in_pos, copy_size);
- }
+ memcpy(b->out + b->out_pos, b->in + b->in_pos, copy_size);
+ }
- dict->start = dict->pos;
+ dict->start = dict->pos;
- b->out_pos += copy_size;
- b->in_pos += copy_size;
- }
+ b->out_pos += copy_size;
+ b->in_pos += copy_size;
+ }
}
/*
@@ -423,19 +423,19 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b, uint32_
*/
static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
{
- size_t copy_size = dict->pos - dict->start;
+ size_t copy_size = dict->pos - dict->start;
- if (DEC_IS_MULTI(dict->mode))
- {
- if (dict->pos == dict->end)
- dict->pos = 0;
+ if (DEC_IS_MULTI(dict->mode))
+ {
+ if (dict->pos == dict->end)
+ dict->pos = 0;
- memcpy(b->out + b->out_pos, dict->buf + dict->start, copy_size);
- }
+ memcpy(b->out + b->out_pos, dict->buf + dict->start, copy_size);
+ }
- dict->start = dict->pos;
- b->out_pos += copy_size;
- return copy_size;
+ dict->start = dict->pos;
+ b->out_pos += copy_size;
+ return copy_size;
}
/*****************
@@ -445,9 +445,9 @@ static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
/* Reset the range decoder. */
static void rc_reset(struct rc_dec *rc)
{
- rc->range = (uint32_t) - 1;
- rc->code = 0;
- rc->init_bytes_left = RC_INIT_BYTES;
+ rc->range = (uint32_t) - 1;
+ rc->code = 0;
+ rc->init_bytes_left = RC_INIT_BYTES;
}
/*
@@ -456,22 +456,22 @@ static void rc_reset(struct rc_dec *rc)
*/
static bool rc_read_init(struct rc_dec *rc, struct xz_buf *b)
{
- while (rc->init_bytes_left > 0)
- {
- if (b->in_pos == b->in_size)
- return false;
+ while (rc->init_bytes_left > 0)
+ {
+ if (b->in_pos == b->in_size)
+ return false;
- rc->code = (rc->code << 8) + b->in[b->in_pos++];
- --rc->init_bytes_left;
- }
+ rc->code = (rc->code << 8) + b->in[b->in_pos++];
+ --rc->init_bytes_left;
+ }
- return true;
+ return true;
}
/* Return true if there may not be enough input for the next decoding loop. */
static inline bool rc_limit_exceeded(const struct rc_dec *rc)
{
- return rc->in_pos > rc->in_limit;
+ return rc->in_pos > rc->in_limit;
}
/*
@@ -480,17 +480,17 @@ static inline bool rc_limit_exceeded(const struct rc_dec *rc)
*/
static inline bool rc_is_finished(const struct rc_dec *rc)
{
- return rc->code == 0;
+ return rc->code == 0;
}
/* Read the next input byte if needed. */
static __always_inline void rc_normalize(struct rc_dec *rc)
{
- if (rc->range < RC_TOP_VALUE)
- {
- rc->range <<= RC_SHIFT_BITS;
- rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
- }
+ if (rc->range < RC_TOP_VALUE)
+ {
+ rc->range <<= RC_SHIFT_BITS;
+ rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
+ }
}
/*
@@ -506,79 +506,79 @@ static __always_inline void rc_normalize(struct rc_dec *rc)
*/
static __always_inline int rc_bit(struct rc_dec *rc, uint16_t *prob)
{
- uint32_t bound;
- int bit;
-
- rc_normalize(rc);
- bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
- if (rc->code < bound)
- {
- rc->range = bound;
- *prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
- bit = 0;
- }
- else
- {
- rc->range -= bound;
- rc->code -= bound;
- *prob -= *prob >> RC_MOVE_BITS;
- bit = 1;
- }
-
- return bit;
+ uint32_t bound;
+ int bit;
+
+ rc_normalize(rc);
+ bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
+ if (rc->code < bound)
+ {
+ rc->range = bound;
+ *prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
+ bit = 0;
+ }
+ else
+ {
+ rc->range -= bound;
+ rc->code -= bound;
+ *prob -= *prob >> RC_MOVE_BITS;
+ bit = 1;
+ }
+
+ return bit;
}
/* Decode a bittree starting from the most significant bit. */
static __always_inline uint32_t rc_bittree(struct rc_dec *rc, uint16_t *probs, uint32_t limit)
{
- uint32_t symbol = 1;
+ uint32_t symbol = 1;
- do
- {
- if (rc_bit(rc, &probs[symbol]))
- symbol = (symbol << 1) + 1;
- else
- symbol <<= 1;
- } while (symbol < limit);
+ do
+ {
+ if (rc_bit(rc, &probs[symbol]))
+ symbol = (symbol << 1) + 1;
+ else
+ symbol <<= 1;
+ } while (symbol < limit);
- return symbol;
+ return symbol;
}
/* Decode a bittree starting from the least significant bit. */
static __always_inline void rc_bittree_reverse(struct rc_dec *rc, uint16_t *probs,
- uint32_t *dest, uint32_t limit)
+ uint32_t *dest, uint32_t limit)
{
- uint32_t symbol = 1;
- uint32_t i = 0;
-
- do
- {
- if (rc_bit(rc, &probs[symbol]))
- {
- symbol = (symbol << 1) + 1;
- *dest += 1 << i;
- }
- else
- {
- symbol <<= 1;
- }
- } while (++i < limit);
+ uint32_t symbol = 1;
+ uint32_t i = 0;
+
+ do
+ {
+ if (rc_bit(rc, &probs[symbol]))
+ {
+ symbol = (symbol << 1) + 1;
+ *dest += 1 << i;
+ }
+ else
+ {
+ symbol <<= 1;
+ }
+ } while (++i < limit);
}
/* Decode direct bits (fixed fifty-fifty probability) */
static inline void rc_direct(struct rc_dec *rc, uint32_t *dest, uint32_t limit)
{
- uint32_t mask;
-
- do
- {
- rc_normalize(rc);
- rc->range >>= 1;
- rc->code -= rc->range;
- mask = (uint32_t)0 - (rc->code >> 31);
- rc->code += rc->range & mask;
- *dest = (*dest << 1) + (mask + 1);
- } while (--limit > 0);
+ uint32_t mask;
+
+ do
+ {
+ rc_normalize(rc);
+ rc->range >>= 1;
+ rc->code -= rc->range;
+ mask = (uint32_t)0 - (rc->code >> 31);
+ rc->code += rc->range & mask;
+ *dest = (*dest << 1) + (mask + 1);
+ } while (--limit > 0);
}
/********
@@ -588,128 +588,128 @@ static inline void rc_direct(struct rc_dec *rc, uint32_t *dest, uint32_t limit)
/* Get pointer to literal coder probability array. */
static uint16_t *lzma_literal_probs(struct xz_dec_lzma2 *s)
{
- uint32_t prev_byte = dict_get(&s->dict, 0);
- uint32_t low = prev_byte >> (8 - s->lzma.lc);
- uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc;
- return s->lzma.literal[low + high];
+ uint32_t prev_byte = dict_get(&s->dict, 0);
+ uint32_t low = prev_byte >> (8 - s->lzma.lc);
+ uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc;
+ return s->lzma.literal[low + high];
}
/* Decode a literal (one 8-bit byte) */
static void lzma_literal(struct xz_dec_lzma2 *s)
{
- uint16_t *probs;
- uint32_t symbol;
- uint32_t match_byte;
- uint32_t match_bit;
- uint32_t offset;
- uint32_t i;
-
- probs = lzma_literal_probs(s);
-
- if (lzma_state_is_literal(s->lzma.state))
- {
- symbol = rc_bittree(&s->rc, probs, 0x100);
- }
- else
- {
- symbol = 1;
- match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
- offset = 0x100;
-
- do
- {
- match_bit = match_byte & offset;
- match_byte <<= 1;
- i = offset + match_bit + symbol;
-
- if (rc_bit(&s->rc, &probs[i]))
- {
- symbol = (symbol << 1) + 1;
- offset &= match_bit;
- }
- else
- {
- symbol <<= 1;
- offset &= ~match_bit;
- }
- } while (symbol < 0x100);
- }
-
- dict_put(&s->dict, (uint8_t)symbol);
- lzma_state_literal(&s->lzma.state);
+ uint16_t *probs;
+ uint32_t symbol;
+ uint32_t match_byte;
+ uint32_t match_bit;
+ uint32_t offset;
+ uint32_t i;
+
+ probs = lzma_literal_probs(s);
+
+ if (lzma_state_is_literal(s->lzma.state))
+ {
+ symbol = rc_bittree(&s->rc, probs, 0x100);
+ }
+ else
+ {
+ symbol = 1;
+ match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
+ offset = 0x100;
+
+ do
+ {
+ match_bit = match_byte & offset;
+ match_byte <<= 1;
+ i = offset + match_bit + symbol;
+
+ if (rc_bit(&s->rc, &probs[i]))
+ {
+ symbol = (symbol << 1) + 1;
+ offset &= match_bit;
+ }
+ else
+ {
+ symbol <<= 1;
+ offset &= ~match_bit;
+ }
+ } while (symbol < 0x100);
+ }
+
+ dict_put(&s->dict, (uint8_t)symbol);
+ lzma_state_literal(&s->lzma.state);
}
/* Decode the length of the match into s->lzma.len. */
static void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l, uint32_t pos_state)
{
- uint16_t *probs;
- uint32_t limit;
-
- if (!rc_bit(&s->rc, &l->choice))
- {
- probs = l->low[pos_state];
- limit = LEN_LOW_SYMBOLS;
- s->lzma.len = MATCH_LEN_MIN;
- }
- else
- {
- if (!rc_bit(&s->rc, &l->choice2))
- {
- probs = l->mid[pos_state];
- limit = LEN_MID_SYMBOLS;
- s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
- }
- else
- {
- probs = l->high;
- limit = LEN_HIGH_SYMBOLS;
- s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS;
- }
- }
-
- s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit;
+ uint16_t *probs;
+ uint32_t limit;
+
+ if (!rc_bit(&s->rc, &l->choice))
+ {
+ probs = l->low[pos_state];
+ limit = LEN_LOW_SYMBOLS;
+ s->lzma.len = MATCH_LEN_MIN;
+ }
+ else
+ {
+ if (!rc_bit(&s->rc, &l->choice2))
+ {
+ probs = l->mid[pos_state];
+ limit = LEN_MID_SYMBOLS;
+ s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
+ }
+ else
+ {
+ probs = l->high;
+ limit = LEN_HIGH_SYMBOLS;
+ s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS;
+ }
+ }
+
+ s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit;
}
/* Decode a match. The distance will be stored in s->lzma.rep0. */
static void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
{
- uint16_t *probs;
- uint32_t dist_slot;
- uint32_t limit;
-
- lzma_state_match(&s->lzma.state);
-
- s->lzma.rep3 = s->lzma.rep2;
- s->lzma.rep2 = s->lzma.rep1;
- s->lzma.rep1 = s->lzma.rep0;
-
- lzma_len(s, &s->lzma.match_len_dec, pos_state);
-
- probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
- dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
-
- if (dist_slot < DIST_MODEL_START)
- {
- s->lzma.rep0 = dist_slot;
- }
- else
- {
- limit = (dist_slot >> 1) - 1;
- s->lzma.rep0 = 2 + (dist_slot & 1);
-
- if (dist_slot < DIST_MODEL_END)
- {
- s->lzma.rep0 <<= limit;
- probs = s->lzma.dist_special + s->lzma.rep0 - dist_slot - 1;
- rc_bittree_reverse(&s->rc, probs, &s->lzma.rep0, limit);
- }
- else
- {
- rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
- s->lzma.rep0 <<= ALIGN_BITS;
- rc_bittree_reverse(&s->rc, s->lzma.dist_align, &s->lzma.rep0, ALIGN_BITS);
- }
- }
+ uint16_t *probs;
+ uint32_t dist_slot;
+ uint32_t limit;
+
+ lzma_state_match(&s->lzma.state);
+
+ s->lzma.rep3 = s->lzma.rep2;
+ s->lzma.rep2 = s->lzma.rep1;
+ s->lzma.rep1 = s->lzma.rep0;
+
+ lzma_len(s, &s->lzma.match_len_dec, pos_state);
+
+ probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
+ dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
+
+ if (dist_slot < DIST_MODEL_START)
+ {
+ s->lzma.rep0 = dist_slot;
+ }
+ else
+ {
+ limit = (dist_slot >> 1) - 1;
+ s->lzma.rep0 = 2 + (dist_slot & 1);
+
+ if (dist_slot < DIST_MODEL_END)
+ {
+ s->lzma.rep0 <<= limit;
+ probs = s->lzma.dist_special + s->lzma.rep0 - dist_slot - 1;
+ rc_bittree_reverse(&s->rc, probs, &s->lzma.rep0, limit);
+ }
+ else
+ {
+ rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
+ s->lzma.rep0 <<= ALIGN_BITS;
+ rc_bittree_reverse(&s->rc, s->lzma.dist_align, &s->lzma.rep0, ALIGN_BITS);
+ }
+ }
}
/*
@@ -718,89 +718,89 @@ static void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
*/
static void lzma_rep_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
{
- uint32_t tmp;
-
- if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state]))
- {
- if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[s->lzma.state][pos_state]))
- {
- lzma_state_short_rep(&s->lzma.state);
- s->lzma.len = 1;
- return;
- }
- }
- else
- {
- if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state]))
- {
- tmp = s->lzma.rep1;
- }
- else
- {
- if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state]))
- {
- tmp = s->lzma.rep2;
- }
- else
- {
- tmp = s->lzma.rep3;
- s->lzma.rep3 = s->lzma.rep2;
- }
-
- s->lzma.rep2 = s->lzma.rep1;
- }
-
- s->lzma.rep1 = s->lzma.rep0;
- s->lzma.rep0 = tmp;
- }
-
- lzma_state_long_rep(&s->lzma.state);
- lzma_len(s, &s->lzma.rep_len_dec, pos_state);
+ uint32_t tmp;
+
+ if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state]))
+ {
+ if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[s->lzma.state][pos_state]))
+ {
+ lzma_state_short_rep(&s->lzma.state);
+ s->lzma.len = 1;
+ return;
+ }
+ }
+ else
+ {
+ if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state]))
+ {
+ tmp = s->lzma.rep1;
+ }
+ else
+ {
+ if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state]))
+ {
+ tmp = s->lzma.rep2;
+ }
+ else
+ {
+ tmp = s->lzma.rep3;
+ s->lzma.rep3 = s->lzma.rep2;
+ }
+
+ s->lzma.rep2 = s->lzma.rep1;
+ }
+
+ s->lzma.rep1 = s->lzma.rep0;
+ s->lzma.rep0 = tmp;
+ }
+
+ lzma_state_long_rep(&s->lzma.state);
+ lzma_len(s, &s->lzma.rep_len_dec, pos_state);
}
/* LZMA decoder core */
static bool lzma_main(struct xz_dec_lzma2 *s)
{
- uint32_t pos_state;
-
- /*
- * If the dictionary was reached during the previous call, try to
- * finish the possibly pending repeat in the dictionary.
- */
- if (dict_has_space(&s->dict) && s->lzma.len > 0)
- dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0);
-
- /*
- * Decode more LZMA symbols. One iteration may consume up to
- * LZMA_IN_REQUIRED - 1 bytes.
- */
- while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc))
- {
- pos_state = s->dict.pos & s->lzma.pos_mask;
-
- if (!rc_bit(&s->rc, &s->lzma.is_match[s->lzma.state][pos_state]))
- {
- lzma_literal(s);
- }
- else
- {
- if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
- lzma_rep_match(s, pos_state);
- else
- lzma_match(s, pos_state);
-
- if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0))
- return false;
- }
- }
-
- /*
- * Having the range decoder always normalized when we are outside
- * this function makes it easier to correctly handle end of the chunk.
- */
- rc_normalize(&s->rc);
-
- return true;
+ uint32_t pos_state;
+
+ /*
+ * If the dictionary was reached during the previous call, try to
+ * finish the possibly pending repeat in the dictionary.
+ */
+ if (dict_has_space(&s->dict) && s->lzma.len > 0)
+ dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0);
+
+ /*
+ * Decode more LZMA symbols. One iteration may consume up to
+ * LZMA_IN_REQUIRED - 1 bytes.
+ */
+ while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc))
+ {
+ pos_state = s->dict.pos & s->lzma.pos_mask;
+
+ if (!rc_bit(&s->rc, &s->lzma.is_match[s->lzma.state][pos_state]))
+ {
+ lzma_literal(s);
+ }
+ else
+ {
+ if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
+ lzma_rep_match(s, pos_state);
+ else
+ lzma_match(s, pos_state);
+
+ if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0))
+ return false;
+ }
+ }
+
+ /*
+ * Having the range decoder always normalized when we are outside
+ * this function makes it easier to correctly handle end of the chunk.
+ */
+ rc_normalize(&s->rc);
+
+ return true;
}
/*
@@ -809,29 +809,29 @@ static bool lzma_main(struct xz_dec_lzma2 *s)
*/
static void lzma_reset(struct xz_dec_lzma2 *s)
{
- uint16_t *probs;
- size_t i;
-
- s->lzma.state = STATE_LIT_LIT;
- s->lzma.rep0 = 0;
- s->lzma.rep1 = 0;
- s->lzma.rep2 = 0;
- s->lzma.rep3 = 0;
-
- /*
- * All probabilities are initialized to the same value. This hack
- * makes the code smaller by avoiding a separate loop for each
- * probability array.
- *
- * This could be optimized so that only that part of literal
- * probabilities that are actually required. In the common case
- * we would write 12 KiB less.
- */
- probs = s->lzma.is_match[0];
- for (i = 0; i < PROBS_TOTAL; ++i)
- probs[i] = RC_BIT_MODEL_TOTAL / 2;
-
- rc_reset(&s->rc);
+ uint16_t *probs;
+ size_t i;
+
+ s->lzma.state = STATE_LIT_LIT;
+ s->lzma.rep0 = 0;
+ s->lzma.rep1 = 0;
+ s->lzma.rep2 = 0;
+ s->lzma.rep3 = 0;
+
+ /*
+ * All probabilities are initialized to the same value. This hack
+ * makes the code smaller by avoiding a separate loop for each
+ * probability array.
+ *
+ * This could be optimized so that only that part of literal
+ * probabilities that are actually required. In the common case
+ * we would write 12 KiB less.
+ */
+ probs = s->lzma.is_match[0];
+ for (i = 0; i < PROBS_TOTAL; ++i)
+ probs[i] = RC_BIT_MODEL_TOTAL / 2;
+
+ rc_reset(&s->rc);
}
/*
@@ -841,35 +841,35 @@ static void lzma_reset(struct xz_dec_lzma2 *s)
*/
static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props)
{
- if (props > (4 * 5 + 4) * 9 + 8)
- return false;
+ if (props > (4 * 5 + 4) * 9 + 8)
+ return false;
- s->lzma.pos_mask = 0;
- while (props >= 9 * 5)
- {
- props -= 9 * 5;
- ++s->lzma.pos_mask;
- }
+ s->lzma.pos_mask = 0;
+ while (props >= 9 * 5)
+ {
+ props -= 9 * 5;
+ ++s->lzma.pos_mask;
+ }
- s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
+ s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
- s->lzma.literal_pos_mask = 0;
- while (props >= 9)
- {
- props -= 9;
- ++s->lzma.literal_pos_mask;
- }
+ s->lzma.literal_pos_mask = 0;
+ while (props >= 9)
+ {
+ props -= 9;
+ ++s->lzma.literal_pos_mask;
+ }
- s->lzma.lc = props;
+ s->lzma.lc = props;
- if (s->lzma.lc + s->lzma.literal_pos_mask > 4)
- return false;
+ if (s->lzma.lc + s->lzma.literal_pos_mask > 4)
+ return false;
- s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1;
+ s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1;
- lzma_reset(s);
+ lzma_reset(s);
- return true;
+ return true;
}
/*********
@@ -890,89 +890,89 @@ static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props)
*/
static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
{
- size_t in_avail;
- uint32_t tmp;
-
- in_avail = b->in_size - b->in_pos;
- if (s->temp.size > 0 || s->lzma2.compressed == 0)
- {
- tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
- if (tmp > s->lzma2.compressed - s->temp.size)
- tmp = s->lzma2.compressed - s->temp.size;
- if (tmp > in_avail)
- tmp = in_avail;
-
- memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
-
- if (s->temp.size + tmp == s->lzma2.compressed)
- {
- memzero(s->temp.buf + s->temp.size + tmp, sizeof(s->temp.buf) - s->temp.size - tmp);
- s->rc.in_limit = s->temp.size + tmp;
- }
- else if (s->temp.size + tmp < LZMA_IN_REQUIRED)
- {
- s->temp.size += tmp;
- b->in_pos += tmp;
- return true;
- }
- else
- {
- s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
- }
-
- s->rc.in = s->temp.buf;
- s->rc.in_pos = 0;
-
- if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp)
- return false;
-
- s->lzma2.compressed -= s->rc.in_pos;
-
- if (s->rc.in_pos < s->temp.size)
- {
- s->temp.size -= s->rc.in_pos;
- memmove(s->temp.buf, s->temp.buf + s->rc.in_pos, s->temp.size);
- return true;
- }
-
- b->in_pos += s->rc.in_pos - s->temp.size;
- s->temp.size = 0;
- }
-
- in_avail = b->in_size - b->in_pos;
- if (in_avail >= LZMA_IN_REQUIRED)
- {
- s->rc.in = b->in;
- s->rc.in_pos = b->in_pos;
-
- if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED)
- s->rc.in_limit = b->in_pos + s->lzma2.compressed;
- else
- s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED;
-
- if (!lzma_main(s))
- return false;
-
- in_avail = s->rc.in_pos - b->in_pos;
- if (in_avail > s->lzma2.compressed)
- return false;
-
- s->lzma2.compressed -= in_avail;
- b->in_pos = s->rc.in_pos;
- }
-
- in_avail = b->in_size - b->in_pos;
- if (in_avail < LZMA_IN_REQUIRED)
- {
- if (in_avail > s->lzma2.compressed)
- in_avail = s->lzma2.compressed;
-
- memcpy(s->temp.buf, b->in + b->in_pos, in_avail);
- s->temp.size = in_avail;
- b->in_pos += in_avail;
- }
-
- return true;
+ size_t in_avail;
+ uint32_t tmp;
+
+ in_avail = b->in_size - b->in_pos;
+ if (s->temp.size > 0 || s->lzma2.compressed == 0)
+ {
+ tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
+ if (tmp > s->lzma2.compressed - s->temp.size)
+ tmp = s->lzma2.compressed - s->temp.size;
+ if (tmp > in_avail)
+ tmp = in_avail;
+
+ memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
+
+ if (s->temp.size + tmp == s->lzma2.compressed)
+ {
+ memzero(s->temp.buf + s->temp.size + tmp, sizeof(s->temp.buf) - s->temp.size - tmp);
+ s->rc.in_limit = s->temp.size + tmp;
+ }
+ else if (s->temp.size + tmp < LZMA_IN_REQUIRED)
+ {
+ s->temp.size += tmp;
+ b->in_pos += tmp;
+ return true;
+ }
+ else
+ {
+ s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
+ }
+
+ s->rc.in = s->temp.buf;
+ s->rc.in_pos = 0;
+
+ if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp)
+ return false;
+
+ s->lzma2.compressed -= s->rc.in_pos;
+
+ if (s->rc.in_pos < s->temp.size)
+ {
+ s->temp.size -= s->rc.in_pos;
+ memmove(s->temp.buf, s->temp.buf + s->rc.in_pos, s->temp.size);
+ return true;
+ }
+
+ b->in_pos += s->rc.in_pos - s->temp.size;
+ s->temp.size = 0;
+ }
+
+ in_avail = b->in_size - b->in_pos;
+ if (in_avail >= LZMA_IN_REQUIRED)
+ {
+ s->rc.in = b->in;
+ s->rc.in_pos = b->in_pos;
+
+ if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED)
+ s->rc.in_limit = b->in_pos + s->lzma2.compressed;
+ else
+ s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED;
+
+ if (!lzma_main(s))
+ return false;
+
+ in_avail = s->rc.in_pos - b->in_pos;
+ if (in_avail > s->lzma2.compressed)
+ return false;
+
+ s->lzma2.compressed -= in_avail;
+ b->in_pos = s->rc.in_pos;
+ }
+
+ in_avail = b->in_size - b->in_pos;
+ if (in_avail < LZMA_IN_REQUIRED)
+ {
+ if (in_avail > s->lzma2.compressed)
+ in_avail = s->lzma2.compressed;
+
+ memcpy(s->temp.buf, b->in + b->in_pos, in_avail);
+ s->temp.size = in_avail;
+ b->in_pos += in_avail;
+ }
+
+ return true;
}
/*
@@ -981,251 +981,251 @@ static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
*/
XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, struct xz_buf *b)
{
- uint32_t tmp;
-
- while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN)
- {
- switch (s->lzma2.sequence)
- {
- case SEQ_CONTROL:
- /*
- * LZMA2 control byte
- *
- * Exact values:
- * 0x00 End marker
- * 0x01 Dictionary reset followed by
- * an uncompressed chunk
- * 0x02 Uncompressed chunk (no dictionary reset)
- *
- * Highest three bits (s->control & 0xE0):
- * 0xE0 Dictionary reset, new properties and state
- * reset, followed by LZMA compressed chunk
- * 0xC0 New properties and state reset, followed
- * by LZMA compressed chunk (no dictionary
- * reset)
- * 0xA0 State reset using old properties,
- * followed by LZMA compressed chunk (no
- * dictionary reset)
- * 0x80 LZMA chunk (no dictionary or state reset)
- *
- * For LZMA compressed chunks, the lowest five bits
- * (s->control & 1F) are the highest bits of the
- * uncompressed size (bits 16-20).
- *
- * A new LZMA2 stream must begin with a dictionary
- * reset. The first LZMA chunk must set new
- * properties and reset the LZMA state.
- *
- * Values that don't match anything described above
- * are invalid and we return XZ_DATA_ERROR.
- */
- tmp = b->in[b->in_pos++];
-
- if (tmp == 0x00)
- return XZ_STREAM_END;
-
- if (tmp >= 0xE0 || tmp == 0x01)
- {
- s->lzma2.need_props = true;
- s->lzma2.need_dict_reset = false;
- dict_reset(&s->dict, b);
- }
- else if (s->lzma2.need_dict_reset)
- {
- return XZ_DATA_ERROR;
- }
-
- if (tmp >= 0x80)
- {
- s->lzma2.uncompressed = (tmp & 0x1F) << 16;
- s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
-
- if (tmp >= 0xC0)
- {
- /*
- * When there are new properties,
- * state reset is done at
- * SEQ_PROPERTIES.
- */
- s->lzma2.need_props = false;
- s->lzma2.next_sequence = SEQ_PROPERTIES;
- }
- else if (s->lzma2.need_props)
- {
- return XZ_DATA_ERROR;
- }
- else
- {
- s->lzma2.next_sequence = SEQ_LZMA_PREPARE;
- if (tmp >= 0xA0)
- lzma_reset(s);
- }
- }
- else
- {
- if (tmp > 0x02)
- return XZ_DATA_ERROR;
-
- s->lzma2.sequence = SEQ_COMPRESSED_0;
- s->lzma2.next_sequence = SEQ_COPY;
- }
-
- break;
-
- case SEQ_UNCOMPRESSED_1:
- s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] << 8;
- s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
- break;
-
- case SEQ_UNCOMPRESSED_2:
- s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] + 1;
- s->lzma2.sequence = SEQ_COMPRESSED_0;
- break;
-
- case SEQ_COMPRESSED_0:
- s->lzma2.compressed = (uint32_t)b->in[b->in_pos++] << 8;
- s->lzma2.sequence = SEQ_COMPRESSED_1;
- break;
-
- case SEQ_COMPRESSED_1:
- s->lzma2.compressed += (uint32_t)b->in[b->in_pos++] + 1;
- s->lzma2.sequence = s->lzma2.next_sequence;
- break;
-
- case SEQ_PROPERTIES:
- if (!lzma_props(s, b->in[b->in_pos++]))
- return XZ_DATA_ERROR;
-
- s->lzma2.sequence = SEQ_LZMA_PREPARE;
-
- case SEQ_LZMA_PREPARE:
- if (s->lzma2.compressed < RC_INIT_BYTES)
- return XZ_DATA_ERROR;
-
- if (!rc_read_init(&s->rc, b))
- return XZ_OK;
-
- s->lzma2.compressed -= RC_INIT_BYTES;
- s->lzma2.sequence = SEQ_LZMA_RUN;
-
- case SEQ_LZMA_RUN:
- /*
- * Set dictionary limit to indicate how much we want
- * to be encoded at maximum. Decode new data into the
- * dictionary. Flush the new data from dictionary to
- * b->out. Check if we finished decoding this chunk.
- * In case the dictionary got full but we didn't fill
- * the output buffer yet, we may run this loop
- * multiple times without changing s->lzma2.sequence.
- */
- dict_limit(&s->dict,
- min_t(size_t, b->out_size - b->out_pos, s->lzma2.uncompressed));
- if (!lzma2_lzma(s, b))
- return XZ_DATA_ERROR;
-
- s->lzma2.uncompressed -= dict_flush(&s->dict, b);
-
- if (s->lzma2.uncompressed == 0)
- {
- if (s->lzma2.compressed > 0 || s->lzma.len > 0 || !rc_is_finished(&s->rc))
- return XZ_DATA_ERROR;
-
- rc_reset(&s->rc);
- s->lzma2.sequence = SEQ_CONTROL;
- }
- else if (b->out_pos == b->out_size ||
- (b->in_pos == b->in_size && s->temp.size < s->lzma2.compressed))
- {
- return XZ_OK;
- }
-
- break;
-
- case SEQ_COPY:
- dict_uncompressed(&s->dict, b, &s->lzma2.compressed);
- if (s->lzma2.compressed > 0)
- return XZ_OK;
-
- s->lzma2.sequence = SEQ_CONTROL;
- break;
- }
- }
-
- return XZ_OK;
+ uint32_t tmp;
+
+ while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN)
+ {
+ switch (s->lzma2.sequence)
+ {
+ case SEQ_CONTROL:
+ /*
+ * LZMA2 control byte
+ *
+ * Exact values:
+ * 0x00 End marker
+ * 0x01 Dictionary reset followed by
+ * an uncompressed chunk
+ * 0x02 Uncompressed chunk (no dictionary reset)
+ *
+ * Highest three bits (s->control & 0xE0):
+ * 0xE0 Dictionary reset, new properties and state
+ * reset, followed by LZMA compressed chunk
+ * 0xC0 New properties and state reset, followed
+ * by LZMA compressed chunk (no dictionary
+ * reset)
+ * 0xA0 State reset using old properties,
+ * followed by LZMA compressed chunk (no
+ * dictionary reset)
+ * 0x80 LZMA chunk (no dictionary or state reset)
+ *
+ * For LZMA compressed chunks, the lowest five bits
+ * (s->control & 1F) are the highest bits of the
+ * uncompressed size (bits 16-20).
+ *
+ * A new LZMA2 stream must begin with a dictionary
+ * reset. The first LZMA chunk must set new
+ * properties and reset the LZMA state.
+ *
+ * Values that don't match anything described above
+ * are invalid and we return XZ_DATA_ERROR.
+ */
+ tmp = b->in[b->in_pos++];
+
+ if (tmp == 0x00)
+ return XZ_STREAM_END;
+
+ if (tmp >= 0xE0 || tmp == 0x01)
+ {
+ s->lzma2.need_props = true;
+ s->lzma2.need_dict_reset = false;
+ dict_reset(&s->dict, b);
+ }
+ else if (s->lzma2.need_dict_reset)
+ {
+ return XZ_DATA_ERROR;
+ }
+
+ if (tmp >= 0x80)
+ {
+ s->lzma2.uncompressed = (tmp & 0x1F) << 16;
+ s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
+
+ if (tmp >= 0xC0)
+ {
+ /*
+ * When there are new properties,
+ * state reset is done at
+ * SEQ_PROPERTIES.
+ */
+ s->lzma2.need_props = false;
+ s->lzma2.next_sequence = SEQ_PROPERTIES;
+ }
+ else if (s->lzma2.need_props)
+ {
+ return XZ_DATA_ERROR;
+ }
+ else
+ {
+ s->lzma2.next_sequence = SEQ_LZMA_PREPARE;
+ if (tmp >= 0xA0)
+ lzma_reset(s);
+ }
+ }
+ else
+ {
+ if (tmp > 0x02)
+ return XZ_DATA_ERROR;
+
+ s->lzma2.sequence = SEQ_COMPRESSED_0;
+ s->lzma2.next_sequence = SEQ_COPY;
+ }
+
+ break;
+
+ case SEQ_UNCOMPRESSED_1:
+ s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] << 8;
+ s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
+ break;
+
+ case SEQ_UNCOMPRESSED_2:
+ s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] + 1;
+ s->lzma2.sequence = SEQ_COMPRESSED_0;
+ break;
+
+ case SEQ_COMPRESSED_0:
+ s->lzma2.compressed = (uint32_t)b->in[b->in_pos++] << 8;
+ s->lzma2.sequence = SEQ_COMPRESSED_1;
+ break;
+
+ case SEQ_COMPRESSED_1:
+ s->lzma2.compressed += (uint32_t)b->in[b->in_pos++] + 1;
+ s->lzma2.sequence = s->lzma2.next_sequence;
+ break;
+
+ case SEQ_PROPERTIES:
+ if (!lzma_props(s, b->in[b->in_pos++]))
+ return XZ_DATA_ERROR;
+
+ s->lzma2.sequence = SEQ_LZMA_PREPARE;
+
+ case SEQ_LZMA_PREPARE:
+ if (s->lzma2.compressed < RC_INIT_BYTES)
+ return XZ_DATA_ERROR;
+
+ if (!rc_read_init(&s->rc, b))
+ return XZ_OK;
+
+ s->lzma2.compressed -= RC_INIT_BYTES;
+ s->lzma2.sequence = SEQ_LZMA_RUN;
+
+ case SEQ_LZMA_RUN:
+ /*
+ * Set dictionary limit to indicate how much we want
+ * to be encoded at maximum. Decode new data into the
+ * dictionary. Flush the new data from dictionary to
+ * b->out. Check if we finished decoding this chunk.
+ * In case the dictionary got full but we didn't fill
+ * the output buffer yet, we may run this loop
+ * multiple times without changing s->lzma2.sequence.
+ */
+ dict_limit(&s->dict,
+ min_t(size_t, b->out_size - b->out_pos, s->lzma2.uncompressed));
+ if (!lzma2_lzma(s, b))
+ return XZ_DATA_ERROR;
+
+ s->lzma2.uncompressed -= dict_flush(&s->dict, b);
+
+ if (s->lzma2.uncompressed == 0)
+ {
+ if (s->lzma2.compressed > 0 || s->lzma.len > 0 || !rc_is_finished(&s->rc))
+ return XZ_DATA_ERROR;
+
+ rc_reset(&s->rc);
+ s->lzma2.sequence = SEQ_CONTROL;
+ }
+ else if (b->out_pos == b->out_size ||
+ (b->in_pos == b->in_size && s->temp.size < s->lzma2.compressed))
+ {
+ return XZ_OK;
+ }
+
+ break;
+
+ case SEQ_COPY:
+ dict_uncompressed(&s->dict, b, &s->lzma2.compressed);
+ if (s->lzma2.compressed > 0)
+ return XZ_OK;
+
+ s->lzma2.sequence = SEQ_CONTROL;
+ break;
+ }
+ }
+
+ return XZ_OK;
}
XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode, uint32_t dict_max)
{
- struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL);
- if (s == NULL)
- return NULL;
-
- s->dict.mode = mode;
- s->dict.size_max = dict_max;
-
- if (DEC_IS_PREALLOC(mode))
- {
- s->dict.buf = vmalloc(dict_max);
- if (s->dict.buf == NULL)
- {
- kfree(s);
- return NULL;
- }
- }
- else if (DEC_IS_DYNALLOC(mode))
- {
- s->dict.buf = NULL;
- s->dict.allocated = 0;
- }
-
- return s;
+ struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (s == NULL)
+ return NULL;
+
+ s->dict.mode = mode;
+ s->dict.size_max = dict_max;
+
+ if (DEC_IS_PREALLOC(mode))
+ {
+ s->dict.buf = vmalloc(dict_max);
+ if (s->dict.buf == NULL)
+ {
+ kfree(s);
+ return NULL;
+ }
+ }
+ else if (DEC_IS_DYNALLOC(mode))
+ {
+ s->dict.buf = NULL;
+ s->dict.allocated = 0;
+ }
+
+ return s;
}
XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props)
{
- /* This limits dictionary size to 3 GiB to keep parsing simpler. */
- if (props > 39)
- return XZ_OPTIONS_ERROR;
-
- s->dict.size = 2 + (props & 1);
- s->dict.size <<= (props >> 1) + 11;
-
- if (DEC_IS_MULTI(s->dict.mode))
- {
- if (s->dict.size > s->dict.size_max)
- return XZ_MEMLIMIT_ERROR;
-
- s->dict.end = s->dict.size;
-
- if (DEC_IS_DYNALLOC(s->dict.mode))
- {
- if (s->dict.allocated < s->dict.size)
- {
- vfree(s->dict.buf);
- s->dict.buf = vmalloc(s->dict.size);
- if (s->dict.buf == NULL)
- {
- s->dict.allocated = 0;
- return XZ_MEM_ERROR;
- }
- }
- }
- }
-
- s->lzma.len = 0;
-
- s->lzma2.sequence = SEQ_CONTROL;
- s->lzma2.need_dict_reset = true;
-
- s->temp.size = 0;
-
- return XZ_OK;
+ /* This limits dictionary size to 3 GiB to keep parsing simpler. */
+ if (props > 39)
+ return XZ_OPTIONS_ERROR;
+
+ s->dict.size = 2 + (props & 1);
+ s->dict.size <<= (props >> 1) + 11;
+
+ if (DEC_IS_MULTI(s->dict.mode))
+ {
+ if (s->dict.size > s->dict.size_max)
+ return XZ_MEMLIMIT_ERROR;
+
+ s->dict.end = s->dict.size;
+
+ if (DEC_IS_DYNALLOC(s->dict.mode))
+ {
+ if (s->dict.allocated < s->dict.size)
+ {
+ vfree(s->dict.buf);
+ s->dict.buf = vmalloc(s->dict.size);
+ if (s->dict.buf == NULL)
+ {
+ s->dict.allocated = 0;
+ return XZ_MEM_ERROR;
+ }
+ }
+ }
+ }
+
+ s->lzma.len = 0;
+
+ s->lzma2.sequence = SEQ_CONTROL;
+ s->lzma2.need_dict_reset = true;
+
+ s->temp.size = 0;
+
+ return XZ_OK;
}
XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s)
{
- if (DEC_IS_MULTI(s->dict.mode))
- vfree(s->dict.buf);
+ if (DEC_IS_MULTI(s->dict.mode))
+ vfree(s->dict.buf);
- kfree(s);
+ kfree(s);
}
diff --git a/libraries/xz-embedded/src/xz_dec_stream.c b/libraries/xz-embedded/src/xz_dec_stream.c
index 6e935ded..f8d7be05 100644
--- a/libraries/xz-embedded/src/xz_dec_stream.c
+++ b/libraries/xz-embedded/src/xz_dec_stream.c
@@ -19,146 +19,146 @@
/* Hash used to validate the Index field */
struct xz_dec_hash
{
- vli_type unpadded;
- vli_type uncompressed;
- uint32_t crc32;
+ vli_type unpadded;
+ vli_type uncompressed;
+ uint32_t crc32;
};
struct xz_dec
{
- /* Position in dec_main() */
- enum
- {
- SEQ_STREAM_HEADER,
- SEQ_BLOCK_START,
- SEQ_BLOCK_HEADER,
- SEQ_BLOCK_UNCOMPRESS,
- SEQ_BLOCK_PADDING,
- SEQ_BLOCK_CHECK,
- SEQ_INDEX,
- SEQ_INDEX_PADDING,
- SEQ_INDEX_CRC32,
- SEQ_STREAM_FOOTER
- } sequence;
-
- /* Position in variable-length integers and Check fields */
- uint32_t pos;
-
- /* Variable-length integer decoded by dec_vli() */
- vli_type vli;
-
- /* Saved in_pos and out_pos */
- size_t in_start;
- size_t out_start;
+ /* Position in dec_main() */
+ enum
+ {
+ SEQ_STREAM_HEADER,
+ SEQ_BLOCK_START,
+ SEQ_BLOCK_HEADER,
+ SEQ_BLOCK_UNCOMPRESS,
+ SEQ_BLOCK_PADDING,
+ SEQ_BLOCK_CHECK,
+ SEQ_INDEX,
+ SEQ_INDEX_PADDING,
+ SEQ_INDEX_CRC32,
+ SEQ_STREAM_FOOTER
+ } sequence;
+
+ /* Position in variable-length integers and Check fields */
+ uint32_t pos;
+
+ /* Variable-length integer decoded by dec_vli() */
+ vli_type vli;
+
+ /* Saved in_pos and out_pos */
+ size_t in_start;
+ size_t out_start;
#ifdef XZ_USE_CRC64
- /* CRC32 or CRC64 value in Block or CRC32 value in Index */
- uint64_t crc;
+ /* CRC32 or CRC64 value in Block or CRC32 value in Index */
+ uint64_t crc;
#else
- /* CRC32 value in Block or Index */
- uint32_t crc;
+ /* CRC32 value in Block or Index */
+ uint32_t crc;
#endif
- /* Type of the integrity check calculated from uncompressed data */
- enum xz_check check_type;
-
- /* Operation mode */
- enum xz_mode mode;
-
- /*
- * True if the next call to xz_dec_run() is allowed to return
- * XZ_BUF_ERROR.
- */
- bool allow_buf_error;
-
- /* Information stored in Block Header */
- struct
- {
- /*
- * Value stored in the Compressed Size field, or
- * VLI_UNKNOWN if Compressed Size is not present.
- */
- vli_type compressed;
-
- /*
- * Value stored in the Uncompressed Size field, or
- * VLI_UNKNOWN if Uncompressed Size is not present.
- */
- vli_type uncompressed;
-
- /* Size of the Block Header field */
- uint32_t size;
- } block_header;
-
- /* Information collected when decoding Blocks */
- struct
- {
- /* Observed compressed size of the current Block */
- vli_type compressed;
-
- /* Observed uncompressed size of the current Block */
- vli_type uncompressed;
-
- /* Number of Blocks decoded so far */
- vli_type count;
-
- /*
- * Hash calculated from the Block sizes. This is used to
- * validate the Index field.
- */
- struct xz_dec_hash hash;
- } block;
-
- /* Variables needed when verifying the Index field */
- struct
- {
- /* Position in dec_index() */
- enum
- {
- SEQ_INDEX_COUNT,
- SEQ_INDEX_UNPADDED,
- SEQ_INDEX_UNCOMPRESSED
- } sequence;
-
- /* Size of the Index in bytes */
- vli_type size;
-
- /* Number of Records (matches block.count in valid files) */
- vli_type count;
-
- /*
- * Hash calculated from the Records (matches block.hash in
- * valid files).
- */
- struct xz_dec_hash hash;
- } index;
-
- /*
- * Temporary buffer needed to hold Stream Header, Block Header,
- * and Stream Footer. The Block Header is the biggest (1 KiB)
- * so we reserve space according to that. buf[] has to be aligned
- * to a multiple of four bytes; the size_t variables before it
- * should guarantee this.
- */
- struct
- {
- size_t pos;
- size_t size;
- uint8_t buf[1024];
- } temp;
-
- struct xz_dec_lzma2 *lzma2;
+ /* Type of the integrity check calculated from uncompressed data */
+ enum xz_check check_type;
+
+ /* Operation mode */
+ enum xz_mode mode;
+
+ /*
+ * True if the next call to xz_dec_run() is allowed to return
+ * XZ_BUF_ERROR.
+ */
+ bool allow_buf_error;
+
+ /* Information stored in Block Header */
+ struct
+ {
+ /*
+ * Value stored in the Compressed Size field, or
+ * VLI_UNKNOWN if Compressed Size is not present.
+ */
+ vli_type compressed;
+
+ /*
+ * Value stored in the Uncompressed Size field, or
+ * VLI_UNKNOWN if Uncompressed Size is not present.
+ */
+ vli_type uncompressed;
+
+ /* Size of the Block Header field */
+ uint32_t size;
+ } block_header;
+
+ /* Information collected when decoding Blocks */
+ struct
+ {
+ /* Observed compressed size of the current Block */
+ vli_type compressed;
+
+ /* Observed uncompressed size of the current Block */
+ vli_type uncompressed;
+
+ /* Number of Blocks decoded so far */
+ vli_type count;
+
+ /*
+ * Hash calculated from the Block sizes. This is used to
+ * validate the Index field.
+ */
+ struct xz_dec_hash hash;
+ } block;
+
+ /* Variables needed when verifying the Index field */
+ struct
+ {
+ /* Position in dec_index() */
+ enum
+ {
+ SEQ_INDEX_COUNT,
+ SEQ_INDEX_UNPADDED,
+ SEQ_INDEX_UNCOMPRESSED
+ } sequence;
+
+ /* Size of the Index in bytes */
+ vli_type size;
+
+ /* Number of Records (matches block.count in valid files) */
+ vli_type count;
+
+ /*
+ * Hash calculated from the Records (matches block.hash in
+ * valid files).
+ */
+ struct xz_dec_hash hash;
+ } index;
+
+ /*
+ * Temporary buffer needed to hold Stream Header, Block Header,
+ * and Stream Footer. The Block Header is the biggest (1 KiB)
+ * so we reserve space according to that. buf[] has to be aligned
+ * to a multiple of four bytes; the size_t variables before it
+ * should guarantee this.
+ */
+ struct
+ {
+ size_t pos;
+ size_t size;
+ uint8_t buf[1024];
+ } temp;
+
+ struct xz_dec_lzma2 *lzma2;
#ifdef XZ_DEC_BCJ
- struct xz_dec_bcj *bcj;
- bool bcj_active;
+ struct xz_dec_bcj *bcj;
+ bool bcj_active;
#endif
};
#ifdef XZ_DEC_ANY_CHECK
/* Sizes of the Check field with different Check IDs */
static const uint8_t check_sizes[16] = {0, 4, 4, 4, 8, 8, 8, 16,
- 16, 16, 32, 32, 32, 64, 64, 64};
+ 16, 16, 32, 32, 32, 64, 64, 64};
#endif
/*
@@ -169,52 +169,52 @@ static const uint8_t check_sizes[16] = {0, 4, 4, 4, 8, 8, 8, 16,
*/
static bool fill_temp(struct xz_dec *s, struct xz_buf *b)
{
- size_t copy_size = min_t(size_t, b->in_size - b->in_pos, s->temp.size - s->temp.pos);
+ size_t copy_size = min_t(size_t, b->in_size - b->in_pos, s->temp.size - s->temp.pos);
- memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size);
- b->in_pos += copy_size;
- s->temp.pos += copy_size;
+ memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size);
+ b->in_pos += copy_size;
+ s->temp.pos += copy_size;
- if (s->temp.pos == s->temp.size)
- {
- s->temp.pos = 0;
- return true;
- }
+ if (s->temp.pos == s->temp.size)
+ {
+ s->temp.pos = 0;
+ return true;
+ }
- return false;
+ return false;
}
/* Decode a variable-length integer (little-endian base-128 encoding) */
static enum xz_ret dec_vli(struct xz_dec *s, const uint8_t *in, size_t *in_pos, size_t in_size)
{
- uint8_t byte;
+ uint8_t byte;
- if (s->pos == 0)
- s->vli = 0;
+ if (s->pos == 0)
+ s->vli = 0;
- while (*in_pos < in_size)
- {
- byte = in[*in_pos];
- ++*in_pos;
+ while (*in_pos < in_size)
+ {
+ byte = in[*in_pos];
+ ++*in_pos;
- s->vli |= (vli_type)(byte & 0x7F) << s->pos;
+ s->vli |= (vli_type)(byte & 0x7F) << s->pos;
- if ((byte & 0x80) == 0)
- {
- /* Don't allow non-minimal encodings. */
- if (byte == 0 && s->pos != 0)
- return XZ_DATA_ERROR;
+ if ((byte & 0x80) == 0)
+ {
+ /* Don't allow non-minimal encodings. */
+ if (byte == 0 && s->pos != 0)
+ return XZ_DATA_ERROR;
- s->pos = 0;
- return XZ_STREAM_END;
- }
+ s->pos = 0;
+ return XZ_STREAM_END;
+ }
- s->pos += 7;
- if (s->pos == 7 * VLI_BYTES_MAX)
- return XZ_DATA_ERROR;
- }
+ s->pos += 7;
+ if (s->pos == 7 * VLI_BYTES_MAX)
+ return XZ_DATA_ERROR;
+ }
- return XZ_OK;
+ return XZ_OK;
}
/*
@@ -231,73 +231,73 @@ static enum xz_ret dec_vli(struct xz_dec *s, const uint8_t *in, size_t *in_pos,
*/
static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
{
- enum xz_ret ret;
+ enum xz_ret ret;
- s->in_start = b->in_pos;
- s->out_start = b->out_pos;
+ s->in_start = b->in_pos;
+ s->out_start = b->out_pos;
#ifdef XZ_DEC_BCJ
- if (s->bcj_active)
- ret = xz_dec_bcj_run(s->bcj, s->lzma2, b);
- else
+ if (s->bcj_active)
+ ret = xz_dec_bcj_run(s->bcj, s->lzma2, b);
+ else
#endif
- ret = xz_dec_lzma2_run(s->lzma2, b);
+ ret = xz_dec_lzma2_run(s->lzma2, b);
- s->block.compressed += b->in_pos - s->in_start;
- s->block.uncompressed += b->out_pos - s->out_start;
+ s->block.compressed += b->in_pos - s->in_start;
+ s->block.uncompressed += b->out_pos - s->out_start;
- /*
- * There is no need to separately check for VLI_UNKNOWN, since
- * the observed sizes are always smaller than VLI_UNKNOWN.
- */
- if (s->block.compressed > s->block_header.compressed ||
- s->block.uncompressed > s->block_header.uncompressed)
- return XZ_DATA_ERROR;
+ /*
+ * There is no need to separately check for VLI_UNKNOWN, since
+ * the observed sizes are always smaller than VLI_UNKNOWN.
+ */
+ if (s->block.compressed > s->block_header.compressed ||
+ s->block.uncompressed > s->block_header.uncompressed)
+ return XZ_DATA_ERROR;
- if (s->check_type == XZ_CHECK_CRC32)
- s->crc = xz_crc32(b->out + s->out_start, b->out_pos - s->out_start, s->crc);
+ if (s->check_type == XZ_CHECK_CRC32)
+ s->crc = xz_crc32(b->out + s->out_start, b->out_pos - s->out_start, s->crc);
#ifdef XZ_USE_CRC64
- else if (s->check_type == XZ_CHECK_CRC64)
- s->crc = xz_crc64(b->out + s->out_start, b->out_pos - s->out_start, s->crc);
+ else if (s->check_type == XZ_CHECK_CRC64)
+ s->crc = xz_crc64(b->out + s->out_start, b->out_pos - s->out_start, s->crc);
#endif
- if (ret == XZ_STREAM_END)
- {
- if (s->block_header.compressed != VLI_UNKNOWN &&
- s->block_header.compressed != s->block.compressed)
- return XZ_DATA_ERROR;
+ if (ret == XZ_STREAM_END)
+ {
+ if (s->block_header.compressed != VLI_UNKNOWN &&
+ s->block_header.compressed != s->block.compressed)
+ return XZ_DATA_ERROR;
- if (s->block_header.uncompressed != VLI_UNKNOWN &&
- s->block_header.uncompressed != s->block.uncompressed)
- return XZ_DATA_ERROR;
+ if (s->block_header.uncompressed != VLI_UNKNOWN &&
+ s->block_header.uncompressed != s->block.uncompressed)
+ return XZ_DATA_ERROR;
- s->block.hash.unpadded += s->block_header.size + s->block.compressed;
+ s->block.hash.unpadded += s->block_header.size + s->block.compressed;
#ifdef XZ_DEC_ANY_CHECK
- s->block.hash.unpadded += check_sizes[s->check_type];
+ s->block.hash.unpadded += check_sizes[s->check_type];
#else
- if (s->check_type == XZ_CHECK_CRC32)
- s->block.hash.unpadded += 4;
- else if (IS_CRC64(s->check_type))
- s->block.hash.unpadded += 8;
+ if (s->check_type == XZ_CHECK_CRC32)
+ s->block.hash.unpadded += 4;
+ else if (IS_CRC64(s->check_type))
+ s->block.hash.unpadded += 8;
#endif
- s->block.hash.uncompressed += s->block.uncompressed;
- s->block.hash.crc32 = xz_crc32((const uint8_t *)&s->block.hash, sizeof(s->block.hash),
- s->block.hash.crc32);
+ s->block.hash.uncompressed += s->block.uncompressed;
+ s->block.hash.crc32 = xz_crc32((const uint8_t *)&s->block.hash, sizeof(s->block.hash),
+ s->block.hash.crc32);
- ++s->block.count;
- }
+ ++s->block.count;
+ }
- return ret;
+ return ret;
}
/* Update the Index size and the CRC32 value. */
static void index_update(struct xz_dec *s, const struct xz_buf *b)
{
- size_t in_used = b->in_pos - s->in_start;
- s->index.size += in_used;
- s->crc = xz_crc32(b->in + s->in_start, in_used, s->crc);
+ size_t in_used = b->in_pos - s->in_start;
+ s->index.size += in_used;
+ s->crc = xz_crc32(b->in + s->in_start, in_used, s->crc);
}
/*
@@ -310,49 +310,49 @@ static void index_update(struct xz_dec *s, const struct xz_buf *b)
*/
static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
{
- enum xz_ret ret;
-
- do
- {
- ret = dec_vli(s, b->in, &b->in_pos, b->in_size);
- if (ret != XZ_STREAM_END)
- {
- index_update(s, b);
- return ret;
- }
-
- switch (s->index.sequence)
- {
- case SEQ_INDEX_COUNT:
- s->index.count = s->vli;
-
- /*
- * Validate that the Number of Records field
- * indicates the same number of Records as
- * there were Blocks in the Stream.
- */
- if (s->index.count != s->block.count)
- return XZ_DATA_ERROR;
-
- s->index.sequence = SEQ_INDEX_UNPADDED;
- break;
-
- case SEQ_INDEX_UNPADDED:
- s->index.hash.unpadded += s->vli;
- s->index.sequence = SEQ_INDEX_UNCOMPRESSED;
- break;
-
- case SEQ_INDEX_UNCOMPRESSED:
- s->index.hash.uncompressed += s->vli;
- s->index.hash.crc32 = xz_crc32((const uint8_t *)&s->index.hash,
- sizeof(s->index.hash), s->index.hash.crc32);
- --s->index.count;
- s->index.sequence = SEQ_INDEX_UNPADDED;
- break;
- }
- } while (s->index.count > 0);
-
- return XZ_STREAM_END;
+ enum xz_ret ret;
+
+ do
+ {
+ ret = dec_vli(s, b->in, &b->in_pos, b->in_size);
+ if (ret != XZ_STREAM_END)
+ {
+ index_update(s, b);
+ return ret;
+ }
+
+ switch (s->index.sequence)
+ {
+ case SEQ_INDEX_COUNT:
+ s->index.count = s->vli;
+
+ /*
+ * Validate that the Number of Records field
+ * indicates the same number of Records as
+ * there were Blocks in the Stream.
+ */
+ if (s->index.count != s->block.count)
+ return XZ_DATA_ERROR;
+
+ s->index.sequence = SEQ_INDEX_UNPADDED;
+ break;
+
+ case SEQ_INDEX_UNPADDED:
+ s->index.hash.unpadded += s->vli;
+ s->index.sequence = SEQ_INDEX_UNCOMPRESSED;
+ break;
+
+ case SEQ_INDEX_UNCOMPRESSED:
+ s->index.hash.uncompressed += s->vli;
+ s->index.hash.crc32 = xz_crc32((const uint8_t *)&s->index.hash,
+ sizeof(s->index.hash), s->index.hash.crc32);
+ --s->index.count;
+ s->index.sequence = SEQ_INDEX_UNPADDED;
+ break;
+ }
+ } while (s->index.count > 0);
+
+ return XZ_STREAM_END;
}
/*
@@ -362,22 +362,22 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
*/
static enum xz_ret crc_validate(struct xz_dec *s, struct xz_buf *b, uint32_t bits)
{
- do
- {
- if (b->in_pos == b->in_size)
- return XZ_OK;
+ do
+ {
+ if (b->in_pos == b->in_size)
+ return XZ_OK;
- if (((s->crc >> s->pos) & 0xFF) != b->in[b->in_pos++])
- return XZ_DATA_ERROR;
+ if (((s->crc >> s->pos) & 0xFF) != b->in[b->in_pos++])
+ return XZ_DATA_ERROR;
- s->pos += 8;
+ s->pos += 8;
- } while (s->pos < bits);
+ } while (s->pos < bits);
- s->crc = 0;
- s->pos = 0;
+ s->crc = 0;
+ s->pos = 0;
- return XZ_STREAM_END;
+ return XZ_STREAM_END;
}
#ifdef XZ_DEC_ANY_CHECK
@@ -387,358 +387,358 @@ static enum xz_ret crc_validate(struct xz_dec *s, struct xz_buf *b, uint32_t bit
*/
static bool check_skip(struct xz_dec *s, struct xz_buf *b)
{
- while (s->pos < check_sizes[s->check_type])
- {
- if (b->in_pos == b->in_size)
- return false;
+ while (s->pos < check_sizes[s->check_type])
+ {
+ if (b->in_pos == b->in_size)
+ return false;
- ++b->in_pos;
- ++s->pos;
- }
+ ++b->in_pos;
+ ++s->pos;
+ }
- s->pos = 0;
+ s->pos = 0;
- return true;
+ return true;
}
#endif
/* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */
static enum xz_ret dec_stream_header(struct xz_dec *s)
{
- if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
- return XZ_FORMAT_ERROR;
+ if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
+ return XZ_FORMAT_ERROR;
- if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0) !=
- get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
- return XZ_DATA_ERROR;
+ if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0) !=
+ get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
+ return XZ_DATA_ERROR;
- if (s->temp.buf[HEADER_MAGIC_SIZE] != 0)
- return XZ_OPTIONS_ERROR;
+ if (s->temp.buf[HEADER_MAGIC_SIZE] != 0)
+ return XZ_OPTIONS_ERROR;
- /*
- * Of integrity checks, we support none (Check ID = 0),
- * CRC32 (Check ID = 1), and optionally CRC64 (Check ID = 4).
- * However, if XZ_DEC_ANY_CHECK is defined, we will accept other
- * check types too, but then the check won't be verified and
- * a warning (XZ_UNSUPPORTED_CHECK) will be given.
- */
- s->check_type = s->temp.buf[HEADER_MAGIC_SIZE + 1];
+ /*
+ * Of integrity checks, we support none (Check ID = 0),
+ * CRC32 (Check ID = 1), and optionally CRC64 (Check ID = 4).
+ * However, if XZ_DEC_ANY_CHECK is defined, we will accept other
+ * check types too, but then the check won't be verified and
+ * a warning (XZ_UNSUPPORTED_CHECK) will be given.
+ */
+ s->check_type = s->temp.buf[HEADER_MAGIC_SIZE + 1];
#ifdef XZ_DEC_ANY_CHECK
- if (s->check_type > XZ_CHECK_MAX)
- return XZ_OPTIONS_ERROR;
+ if (s->check_type > XZ_CHECK_MAX)
+ return XZ_OPTIONS_ERROR;
- if (s->check_type > XZ_CHECK_CRC32 && !IS_CRC64(s->check_type))
- return XZ_UNSUPPORTED_CHECK;
+ if (s->check_type > XZ_CHECK_CRC32 && !IS_CRC64(s->check_type))
+ return XZ_UNSUPPORTED_CHECK;
#else
- if (s->check_type > XZ_CHECK_CRC32 && !IS_CRC64(s->check_type))
- return XZ_OPTIONS_ERROR;
+ if (s->check_type > XZ_CHECK_CRC32 && !IS_CRC64(s->check_type))
+ return XZ_OPTIONS_ERROR;
#endif
- return XZ_OK;
+ return XZ_OK;
}
/* Decode the Stream Footer field (the last 12 bytes of the .xz Stream) */
static enum xz_ret dec_stream_footer(struct xz_dec *s)
{
- if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
- return XZ_DATA_ERROR;
-
- if (xz_crc32(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
- return XZ_DATA_ERROR;
-
- /*
- * Validate Backward Size. Note that we never added the size of the
- * Index CRC32 field to s->index.size, thus we use s->index.size / 4
- * instead of s->index.size / 4 - 1.
- */
- if ((s->index.size >> 2) != get_le32(s->temp.buf + 4))
- return XZ_DATA_ERROR;
-
- if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->check_type)
- return XZ_DATA_ERROR;
-
- /*
- * Use XZ_STREAM_END instead of XZ_OK to be more convenient
- * for the caller.
- */
- return XZ_STREAM_END;
+ if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
+ return XZ_DATA_ERROR;
+
+ if (xz_crc32(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
+ return XZ_DATA_ERROR;
+
+ /*
+ * Validate Backward Size. Note that we never added the size of the
+ * Index CRC32 field to s->index.size, thus we use s->index.size / 4
+ * instead of s->index.size / 4 - 1.
+ */
+ if ((s->index.size >> 2) != get_le32(s->temp.buf + 4))
+ return XZ_DATA_ERROR;
+
+ if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->check_type)
+ return XZ_DATA_ERROR;
+
+ /*
+ * Use XZ_STREAM_END instead of XZ_OK to be more convenient
+ * for the caller.
+ */
+ return XZ_STREAM_END;
}
/* Decode the Block Header and initialize the filter chain. */
static enum xz_ret dec_block_header(struct xz_dec *s)
{
- enum xz_ret ret;
+ enum xz_ret ret;
- /*
- * Validate the CRC32. We know that the temp buffer is at least
- * eight bytes so this is safe.
- */
- s->temp.size -= 4;
- if (xz_crc32(s->temp.buf, s->temp.size, 0) != get_le32(s->temp.buf + s->temp.size))
- return XZ_DATA_ERROR;
+ /*
+ * Validate the CRC32. We know that the temp buffer is at least
+ * eight bytes so this is safe.
+ */
+ s->temp.size -= 4;
+ if (xz_crc32(s->temp.buf, s->temp.size, 0) != get_le32(s->temp.buf + s->temp.size))
+ return XZ_DATA_ERROR;
- s->temp.pos = 2;
+ s->temp.pos = 2;
/*
* Catch unsupported Block Flags. We support only one or two filters
* in the chain, so we catch that with the same test.
*/
#ifdef XZ_DEC_BCJ
- if (s->temp.buf[1] & 0x3E)
+ if (s->temp.buf[1] & 0x3E)
#else
- if (s->temp.buf[1] & 0x3F)
+ if (s->temp.buf[1] & 0x3F)
#endif
- return XZ_OPTIONS_ERROR;
-
- /* Compressed Size */
- if (s->temp.buf[1] & 0x40)
- {
- if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size) != XZ_STREAM_END)
- return XZ_DATA_ERROR;
-
- s->block_header.compressed = s->vli;
- }
- else
- {
- s->block_header.compressed = VLI_UNKNOWN;
- }
-
- /* Uncompressed Size */
- if (s->temp.buf[1] & 0x80)
- {
- if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size) != XZ_STREAM_END)
- return XZ_DATA_ERROR;
-
- s->block_header.uncompressed = s->vli;
- }
- else
- {
- s->block_header.uncompressed = VLI_UNKNOWN;
- }
+ return XZ_OPTIONS_ERROR;
+
+ /* Compressed Size */
+ if (s->temp.buf[1] & 0x40)
+ {
+ if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size) != XZ_STREAM_END)
+ return XZ_DATA_ERROR;
+
+ s->block_header.compressed = s->vli;
+ }
+ else
+ {
+ s->block_header.compressed = VLI_UNKNOWN;
+ }
+
+ /* Uncompressed Size */
+ if (s->temp.buf[1] & 0x80)
+ {
+ if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size) != XZ_STREAM_END)
+ return XZ_DATA_ERROR;
+
+ s->block_header.uncompressed = s->vli;
+ }
+ else
+ {
+ s->block_header.uncompressed = VLI_UNKNOWN;
+ }
#ifdef XZ_DEC_BCJ
- /* If there are two filters, the first one must be a BCJ filter. */
- s->bcj_active = s->temp.buf[1] & 0x01;
- if (s->bcj_active)
- {
- if (s->temp.size - s->temp.pos < 2)
- return XZ_OPTIONS_ERROR;
-
- ret = xz_dec_bcj_reset(s->bcj, s->temp.buf[s->temp.pos++]);
- if (ret != XZ_OK)
- return ret;
-
- /*
- * We don't support custom start offset,
- * so Size of Properties must be zero.
- */
- if (s->temp.buf[s->temp.pos++] != 0x00)
- return XZ_OPTIONS_ERROR;
- }
+ /* If there are two filters, the first one must be a BCJ filter. */
+ s->bcj_active = s->temp.buf[1] & 0x01;
+ if (s->bcj_active)
+ {
+ if (s->temp.size - s->temp.pos < 2)
+ return XZ_OPTIONS_ERROR;
+
+ ret = xz_dec_bcj_reset(s->bcj, s->temp.buf[s->temp.pos++]);
+ if (ret != XZ_OK)
+ return ret;
+
+ /*
+ * We don't support custom start offset,
+ * so Size of Properties must be zero.
+ */
+ if (s->temp.buf[s->temp.pos++] != 0x00)
+ return XZ_OPTIONS_ERROR;
+ }
#endif
- /* Valid Filter Flags always take at least two bytes. */
- if (s->temp.size - s->temp.pos < 2)
- return XZ_DATA_ERROR;
+ /* Valid Filter Flags always take at least two bytes. */
+ if (s->temp.size - s->temp.pos < 2)
+ return XZ_DATA_ERROR;
- /* Filter ID = LZMA2 */
- if (s->temp.buf[s->temp.pos++] != 0x21)
- return XZ_OPTIONS_ERROR;
+ /* Filter ID = LZMA2 */
+ if (s->temp.buf[s->temp.pos++] != 0x21)
+ return XZ_OPTIONS_ERROR;
- /* Size of Properties = 1-byte Filter Properties */
- if (s->temp.buf[s->temp.pos++] != 0x01)
- return XZ_OPTIONS_ERROR;
+ /* Size of Properties = 1-byte Filter Properties */
+ if (s->temp.buf[s->temp.pos++] != 0x01)
+ return XZ_OPTIONS_ERROR;
- /* Filter Properties contains LZMA2 dictionary size. */
- if (s->temp.size - s->temp.pos < 1)
- return XZ_DATA_ERROR;
+ /* Filter Properties contains LZMA2 dictionary size. */
+ if (s->temp.size - s->temp.pos < 1)
+ return XZ_DATA_ERROR;
- ret = xz_dec_lzma2_reset(s->lzma2, s->temp.buf[s->temp.pos++]);
- if (ret != XZ_OK)
- return ret;
+ ret = xz_dec_lzma2_reset(s->lzma2, s->temp.buf[s->temp.pos++]);
+ if (ret != XZ_OK)
+ return ret;
- /* The rest must be Header Padding. */
- while (s->temp.pos < s->temp.size)
- if (s->temp.buf[s->temp.pos++] != 0x00)
- return XZ_OPTIONS_ERROR;
+ /* The rest must be Header Padding. */
+ while (s->temp.pos < s->temp.size)
+ if (s->temp.buf[s->temp.pos++] != 0x00)
+ return XZ_OPTIONS_ERROR;
- s->temp.pos = 0;
- s->block.compressed = 0;
- s->block.uncompressed = 0;
+ s->temp.pos = 0;
+ s->block.compressed = 0;
+ s->block.uncompressed = 0;
- return XZ_OK;
+ return XZ_OK;
}
static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
{
- enum xz_ret ret;
-
- /*
- * Store the start position for the case when we are in the middle
- * of the Index field.
- */
- s->in_start = b->in_pos;
-
- while (true)
- {
- switch (s->sequence)
- {
- case SEQ_STREAM_HEADER:
- /*
- * Stream Header is copied to s->temp, and then
- * decoded from there. This way if the caller
- * gives us only little input at a time, we can
- * still keep the Stream Header decoding code
- * simple. Similar approach is used in many places
- * in this file.
- */
- if (!fill_temp(s, b))
- return XZ_OK;
-
- /*
- * If dec_stream_header() returns
- * XZ_UNSUPPORTED_CHECK, it is still possible
- * to continue decoding if working in multi-call
- * mode. Thus, update s->sequence before calling
- * dec_stream_header().
- */
- s->sequence = SEQ_BLOCK_START;
-
- ret = dec_stream_header(s);
- if (ret != XZ_OK)
- return ret;
-
- case SEQ_BLOCK_START:
- /* We need one byte of input to continue. */
- if (b->in_pos == b->in_size)
- return XZ_OK;
-
- /* See if this is the beginning of the Index field. */
- if (b->in[b->in_pos] == 0)
- {
- s->in_start = b->in_pos++;
- s->sequence = SEQ_INDEX;
- break;
- }
-
- /*
- * Calculate the size of the Block Header and
- * prepare to decode it.
- */
- s->block_header.size = ((uint32_t)b->in[b->in_pos] + 1) * 4;
-
- s->temp.size = s->block_header.size;
- s->temp.pos = 0;
- s->sequence = SEQ_BLOCK_HEADER;
-
- case SEQ_BLOCK_HEADER:
- if (!fill_temp(s, b))
- return XZ_OK;
-
- ret = dec_block_header(s);
- if (ret != XZ_OK)
- return ret;
-
- s->sequence = SEQ_BLOCK_UNCOMPRESS;
-
- case SEQ_BLOCK_UNCOMPRESS:
- ret = dec_block(s, b);
- if (ret != XZ_STREAM_END)
- return ret;
-
- s->sequence = SEQ_BLOCK_PADDING;
-
- case SEQ_BLOCK_PADDING:
- /*
- * Size of Compressed Data + Block Padding
- * must be a multiple of four. We don't need
- * s->block.compressed for anything else
- * anymore, so we use it here to test the size
- * of the Block Padding field.
- */
- while (s->block.compressed & 3)
- {
- if (b->in_pos == b->in_size)
- return XZ_OK;
-
- if (b->in[b->in_pos++] != 0)
- return XZ_DATA_ERROR;
-
- ++s->block.compressed;
- }
-
- s->sequence = SEQ_BLOCK_CHECK;
-
- case SEQ_BLOCK_CHECK:
- if (s->check_type == XZ_CHECK_CRC32)
- {
- ret = crc_validate(s, b, 32);
- if (ret != XZ_STREAM_END)
- return ret;
- }
- else if (IS_CRC64(s->check_type))
- {
- ret = crc_validate(s, b, 64);
- if (ret != XZ_STREAM_END)
- return ret;
- }
+ enum xz_ret ret;
+
+ /*
+ * Store the start position for the case when we are in the middle
+ * of the Index field.
+ */
+ s->in_start = b->in_pos;
+
+ while (true)
+ {
+ switch (s->sequence)
+ {
+ case SEQ_STREAM_HEADER:
+ /*
+ * Stream Header is copied to s->temp, and then
+ * decoded from there. This way if the caller
+ * gives us only little input at a time, we can
+ * still keep the Stream Header decoding code
+ * simple. Similar approach is used in many places
+ * in this file.
+ */
+ if (!fill_temp(s, b))
+ return XZ_OK;
+
+ /*
+ * If dec_stream_header() returns
+ * XZ_UNSUPPORTED_CHECK, it is still possible
+ * to continue decoding if working in multi-call
+ * mode. Thus, update s->sequence before calling
+ * dec_stream_header().
+ */
+ s->sequence = SEQ_BLOCK_START;
+
+ ret = dec_stream_header(s);
+ if (ret != XZ_OK)
+ return ret;
+
+ case SEQ_BLOCK_START:
+ /* We need one byte of input to continue. */
+ if (b->in_pos == b->in_size)
+ return XZ_OK;
+
+ /* See if this is the beginning of the Index field. */
+ if (b->in[b->in_pos] == 0)
+ {
+ s->in_start = b->in_pos++;
+ s->sequence = SEQ_INDEX;
+ break;
+ }
+
+ /*
+ * Calculate the size of the Block Header and
+ * prepare to decode it.
+ */
+ s->block_header.size = ((uint32_t)b->in[b->in_pos] + 1) * 4;
+
+ s->temp.size = s->block_header.size;
+ s->temp.pos = 0;
+ s->sequence = SEQ_BLOCK_HEADER;
+
+ case SEQ_BLOCK_HEADER:
+ if (!fill_temp(s, b))
+ return XZ_OK;
+
+ ret = dec_block_header(s);
+ if (ret != XZ_OK)
+ return ret;
+
+ s->sequence = SEQ_BLOCK_UNCOMPRESS;
+
+ case SEQ_BLOCK_UNCOMPRESS:
+ ret = dec_block(s, b);
+ if (ret != XZ_STREAM_END)
+ return ret;
+
+ s->sequence = SEQ_BLOCK_PADDING;
+
+ case SEQ_BLOCK_PADDING:
+ /*
+ * Size of Compressed Data + Block Padding
+ * must be a multiple of four. We don't need
+ * s->block.compressed for anything else
+ * anymore, so we use it here to test the size
+ * of the Block Padding field.
+ */
+ while (s->block.compressed & 3)
+ {
+ if (b->in_pos == b->in_size)
+ return XZ_OK;
+
+ if (b->in[b->in_pos++] != 0)
+ return XZ_DATA_ERROR;
+
+ ++s->block.compressed;
+ }
+
+ s->sequence = SEQ_BLOCK_CHECK;
+
+ case SEQ_BLOCK_CHECK:
+ if (s->check_type == XZ_CHECK_CRC32)
+ {
+ ret = crc_validate(s, b, 32);
+ if (ret != XZ_STREAM_END)
+ return ret;
+ }
+ else if (IS_CRC64(s->check_type))
+ {
+ ret = crc_validate(s, b, 64);
+ if (ret != XZ_STREAM_END)
+ return ret;
+ }
#ifdef XZ_DEC_ANY_CHECK
- else if (!check_skip(s, b))
- {
- return XZ_OK;
- }
+ else if (!check_skip(s, b))
+ {
+ return XZ_OK;
+ }
#endif
- s->sequence = SEQ_BLOCK_START;
- break;
+ s->sequence = SEQ_BLOCK_START;
+ break;
- case SEQ_INDEX:
- ret = dec_index(s, b);
- if (ret != XZ_STREAM_END)
- return ret;
+ case SEQ_INDEX:
+ ret = dec_index(s, b);
+ if (ret != XZ_STREAM_END)
+ return ret;
- s->sequence = SEQ_INDEX_PADDING;
+ s->sequence = SEQ_INDEX_PADDING;
- case SEQ_INDEX_PADDING:
- while ((s->index.size + (b->in_pos - s->in_start)) & 3)
- {
- if (b->in_pos == b->in_size)
- {
- index_update(s, b);
- return XZ_OK;
- }
+ case SEQ_INDEX_PADDING:
+ while ((s->index.size + (b->in_pos - s->in_start)) & 3)
+ {
+ if (b->in_pos == b->in_size)
+ {
+ index_update(s, b);
+ return XZ_OK;
+ }
- if (b->in[b->in_pos++] != 0)
- return XZ_DATA_ERROR;
- }
+ if (b->in[b->in_pos++] != 0)
+ return XZ_DATA_ERROR;
+ }
- /* Finish the CRC32 value and Index size. */
- index_update(s, b);
+ /* Finish the CRC32 value and Index size. */
+ index_update(s, b);
- /* Compare the hashes to validate the Index field. */
- if (!memeq(&s->block.hash, &s->index.hash, sizeof(s->block.hash)))
- return XZ_DATA_ERROR;
+ /* Compare the hashes to validate the Index field. */
+ if (!memeq(&s->block.hash, &s->index.hash, sizeof(s->block.hash)))
+ return XZ_DATA_ERROR;
- s->sequence = SEQ_INDEX_CRC32;
+ s->sequence = SEQ_INDEX_CRC32;
- case SEQ_INDEX_CRC32:
- ret = crc_validate(s, b, 32);
- if (ret != XZ_STREAM_END)
- return ret;
+ case SEQ_INDEX_CRC32:
+ ret = crc_validate(s, b, 32);
+ if (ret != XZ_STREAM_END)
+ return ret;
- s->temp.size = STREAM_HEADER_SIZE;
- s->sequence = SEQ_STREAM_FOOTER;
+ s->temp.size = STREAM_HEADER_SIZE;
+ s->sequence = SEQ_STREAM_FOOTER;
- case SEQ_STREAM_FOOTER:
- if (!fill_temp(s, b))
- return XZ_OK;
+ case SEQ_STREAM_FOOTER:
+ if (!fill_temp(s, b))
+ return XZ_OK;
- return dec_stream_footer(s);
- }
- }
+ return dec_stream_footer(s);
+ }
+ }
- /* Never reached */
+ /* Never reached */
}
/*
@@ -768,93 +768,93 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
*/
XZ_EXTERN enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b)
{
- size_t in_start;
- size_t out_start;
- enum xz_ret ret;
-
- if (DEC_IS_SINGLE(s->mode))
- xz_dec_reset(s);
-
- in_start = b->in_pos;
- out_start = b->out_pos;
- ret = dec_main(s, b);
-
- if (DEC_IS_SINGLE(s->mode))
- {
- if (ret == XZ_OK)
- ret = b->in_pos == b->in_size ? XZ_DATA_ERROR : XZ_BUF_ERROR;
-
- if (ret != XZ_STREAM_END)
- {
- b->in_pos = in_start;
- b->out_pos = out_start;
- }
- }
- else if (ret == XZ_OK && in_start == b->in_pos && out_start == b->out_pos)
- {
- if (s->allow_buf_error)
- ret = XZ_BUF_ERROR;
-
- s->allow_buf_error = true;
- }
- else
- {
- s->allow_buf_error = false;
- }
-
- return ret;
+ size_t in_start;
+ size_t out_start;
+ enum xz_ret ret;
+
+ if (DEC_IS_SINGLE(s->mode))
+ xz_dec_reset(s);
+
+ in_start = b->in_pos;
+ out_start = b->out_pos;
+ ret = dec_main(s, b);
+
+ if (DEC_IS_SINGLE(s->mode))
+ {
+ if (ret == XZ_OK)
+ ret = b->in_pos == b->in_size ? XZ_DATA_ERROR : XZ_BUF_ERROR;
+
+ if (ret != XZ_STREAM_END)
+ {
+ b->in_pos = in_start;
+ b->out_pos = out_start;
+ }
+ }
+ else if (ret == XZ_OK && in_start == b->in_pos && out_start == b->out_pos)
+ {
+ if (s->allow_buf_error)
+ ret = XZ_BUF_ERROR;
+
+ s->allow_buf_error = true;
+ }
+ else
+ {
+ s->allow_buf_error = false;
+ }
+
+ return ret;
}
XZ_EXTERN struct xz_dec *xz_dec_init(enum xz_mode mode, uint32_t dict_max)
{
- struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL);
- if (s == NULL)
- return NULL;
+ struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (s == NULL)
+ return NULL;
- s->mode = mode;
+ s->mode = mode;
#ifdef XZ_DEC_BCJ
- s->bcj = xz_dec_bcj_create(DEC_IS_SINGLE(mode));
- if (s->bcj == NULL)
- goto error_bcj;
+ s->bcj = xz_dec_bcj_create(DEC_IS_SINGLE(mode));
+ if (s->bcj == NULL)
+ goto error_bcj;
#endif
- s->lzma2 = xz_dec_lzma2_create(mode, dict_max);
- if (s->lzma2 == NULL)
- goto error_lzma2;
+ s->lzma2 = xz_dec_lzma2_create(mode, dict_max);
+ if (s->lzma2 == NULL)
+ goto error_lzma2;
- xz_dec_reset(s);
- return s;
+ xz_dec_reset(s);
+ return s;
error_lzma2:
#ifdef XZ_DEC_BCJ
- xz_dec_bcj_end(s->bcj);
+ xz_dec_bcj_end(s->bcj);
error_bcj:
#endif
- kfree(s);
- return NULL;
+ kfree(s);
+ return NULL;
}
XZ_EXTERN void xz_dec_reset(struct xz_dec *s)
{
- s->sequence = SEQ_STREAM_HEADER;
- s->allow_buf_error = false;
- s->pos = 0;
- s->crc = 0;
- memzero(&s->block, sizeof(s->block));
- memzero(&s->index, sizeof(s->index));
- s->temp.pos = 0;
- s->temp.size = STREAM_HEADER_SIZE;
+ s->sequence = SEQ_STREAM_HEADER;
+ s->allow_buf_error = false;
+ s->pos = 0;
+ s->crc = 0;
+ memzero(&s->block, sizeof(s->block));
+ memzero(&s->index, sizeof(s->index));
+ s->temp.pos = 0;
+ s->temp.size = STREAM_HEADER_SIZE;
}
XZ_EXTERN void xz_dec_end(struct xz_dec *s)
{
- if (s != NULL)
- {
- xz_dec_lzma2_end(s->lzma2);
+ if (s != NULL)
+ {
+ xz_dec_lzma2_end(s->lzma2);
#ifdef XZ_DEC_BCJ
- xz_dec_bcj_end(s->bcj);
+ xz_dec_bcj_end(s->bcj);
#endif
- kfree(s);
- }
+ kfree(s);
+ }
}
diff --git a/libraries/xz-embedded/src/xz_lzma2.h b/libraries/xz-embedded/src/xz_lzma2.h
index 3976033a..82a425f2 100644
--- a/libraries/xz-embedded/src/xz_lzma2.h
+++ b/libraries/xz-embedded/src/xz_lzma2.h
@@ -41,18 +41,18 @@
*/
enum lzma_state
{
- STATE_LIT_LIT,
- STATE_MATCH_LIT_LIT,
- STATE_REP_LIT_LIT,
- STATE_SHORTREP_LIT_LIT,
- STATE_MATCH_LIT,
- STATE_REP_LIT,
- STATE_SHORTREP_LIT,
- STATE_LIT_MATCH,
- STATE_LIT_LONGREP,
- STATE_LIT_SHORTREP,
- STATE_NONLIT_MATCH,
- STATE_NONLIT_REP
+ STATE_LIT_LIT,
+ STATE_MATCH_LIT_LIT,
+ STATE_REP_LIT_LIT,
+ STATE_SHORTREP_LIT_LIT,
+ STATE_MATCH_LIT,
+ STATE_REP_LIT,
+ STATE_SHORTREP_LIT,
+ STATE_LIT_MATCH,
+ STATE_LIT_LONGREP,
+ STATE_LIT_SHORTREP,
+ STATE_NONLIT_MATCH,
+ STATE_NONLIT_REP
};
/* Total number of states */
@@ -64,36 +64,36 @@ enum lzma_state
/* Indicate that the latest symbol was a literal. */
static inline void lzma_state_literal(enum lzma_state *state)
{
- if (*state <= STATE_SHORTREP_LIT_LIT)
- *state = STATE_LIT_LIT;
- else if (*state <= STATE_LIT_SHORTREP)
- *state -= 3;
- else
- *state -= 6;
+ if (*state <= STATE_SHORTREP_LIT_LIT)
+ *state = STATE_LIT_LIT;
+ else if (*state <= STATE_LIT_SHORTREP)
+ *state -= 3;
+ else
+ *state -= 6;
}
/* Indicate that the latest symbol was a match. */
static inline void lzma_state_match(enum lzma_state *state)
{
- *state = *state < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH;
+ *state = *state < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH;
}
/* Indicate that the latest state was a long repeated match. */
static inline void lzma_state_long_rep(enum lzma_state *state)
{
- *state = *state < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP;
+ *state = *state < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP;
}
/* Indicate that the latest symbol was a short match. */
static inline void lzma_state_short_rep(enum lzma_state *state)
{
- *state = *state < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP;
+ *state = *state < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP;
}
/* Test if the previous symbol was a literal. */
static inline bool lzma_state_is_literal(enum lzma_state state)
{
- return state < LIT_STATES;
+ return state < LIT_STATES;
}
/* Each literal coder is divided in three sections:
@@ -147,7 +147,7 @@ static inline bool lzma_state_is_literal(enum lzma_state state)
*/
static inline uint32_t lzma_get_dist_state(uint32_t len)
{
- return len < DIST_STATES + MATCH_LEN_MIN ? len - MATCH_LEN_MIN : DIST_STATES - 1;
+ return len < DIST_STATES + MATCH_LEN_MIN ? len - MATCH_LEN_MIN : DIST_STATES - 1;
}
/*
diff --git a/libraries/xz-embedded/src/xz_private.h b/libraries/xz-embedded/src/xz_private.h
index 55a3af1c..1b616430 100644
--- a/libraries/xz-embedded/src/xz_private.h
+++ b/libraries/xz-embedded/src/xz_private.h
@@ -94,8 +94,8 @@
*/
#ifndef XZ_DEC_BCJ
#if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) || defined(XZ_DEC_IA64) || \
- defined(XZ_DEC_ARM) || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) || \
- defined(XZ_DEC_SPARC)
+ defined(XZ_DEC_ARM) || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) || \
+ defined(XZ_DEC_SPARC)
#define XZ_DEC_BCJ
#endif
#endif
@@ -141,7 +141,7 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id);
* must be called directly.
*/
XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzma2,
- struct xz_buf *b);
+ struct xz_buf *b);
/* Free the memory allocated for the BCJ filters. */
#define xz_dec_bcj_end(s) kfree(s)
diff --git a/libraries/xz-embedded/src/xz_stream.h b/libraries/xz-embedded/src/xz_stream.h
index c0e191e6..b3d2c9fd 100644
--- a/libraries/xz-embedded/src/xz_stream.h
+++ b/libraries/xz-embedded/src/xz_stream.h
@@ -50,10 +50,10 @@ typedef uint64_t vli_type;
/* Integrity Check types */
enum xz_check
{
- XZ_CHECK_NONE = 0,
- XZ_CHECK_CRC32 = 1,
- XZ_CHECK_CRC64 = 4,
- XZ_CHECK_SHA256 = 10
+ XZ_CHECK_NONE = 0,
+ XZ_CHECK_CRC32 = 1,
+ XZ_CHECK_CRC64 = 4,
+ XZ_CHECK_SHA256 = 10
};
/* Maximum possible Check ID */
diff --git a/libraries/xz-embedded/xzminidec.c b/libraries/xz-embedded/xzminidec.c
index bb62c3ac..44f60602 100644
--- a/libraries/xz-embedded/xzminidec.c
+++ b/libraries/xz-embedded/xzminidec.c
@@ -24,121 +24,121 @@ static uint8_t out[BUFSIZ];
int main(int argc, char **argv)
{
- struct xz_buf b;
- struct xz_dec *s;
- enum xz_ret ret;
- const char *msg;
-
- if (argc >= 2 && strcmp(argv[1], "--help") == 0)
- {
- fputs("Uncompress a .xz file from stdin to stdout.\n"
- "Arguments other than `--help' are ignored.\n",
- stdout);
- return 0;
- }
-
- xz_crc32_init();
+ struct xz_buf b;
+ struct xz_dec *s;
+ enum xz_ret ret;
+ const char *msg;
+
+ if (argc >= 2 && strcmp(argv[1], "--help") == 0)
+ {
+ fputs("Uncompress a .xz file from stdin to stdout.\n"
+ "Arguments other than `--help' are ignored.\n",
+ stdout);
+ return 0;
+ }
+
+ xz_crc32_init();
#ifdef XZ_USE_CRC64
- xz_crc64_init();
+ xz_crc64_init();
#endif
- /*
- * Support up to 64 MiB dictionary. The actually needed memory
- * is allocated once the headers have been parsed.
- */
- s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
- if (s == NULL)
- {
- msg = "Memory allocation failed\n";
- goto error;
- }
-
- b.in = in;
- b.in_pos = 0;
- b.in_size = 0;
- b.out = out;
- b.out_pos = 0;
- b.out_size = BUFSIZ;
-
- while (true)
- {
- if (b.in_pos == b.in_size)
- {
- b.in_size = fread(in, 1, sizeof(in), stdin);
- b.in_pos = 0;
- }
-
- ret = xz_dec_run(s, &b);
-
- if (b.out_pos == sizeof(out))
- {
- if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos)
- {
- msg = "Write error\n";
- goto error;
- }
-
- b.out_pos = 0;
- }
-
- if (ret == XZ_OK)
- continue;
+ /*
+ * Support up to 64 MiB dictionary. The actually needed memory
+ * is allocated once the headers have been parsed.
+ */
+ s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
+ if (s == NULL)
+ {
+ msg = "Memory allocation failed\n";
+ goto error;
+ }
+
+ b.in = in;
+ b.in_pos = 0;
+ b.in_size = 0;
+ b.out = out;
+ b.out_pos = 0;
+ b.out_size = BUFSIZ;
+
+ while (true)
+ {
+ if (b.in_pos == b.in_size)
+ {
+ b.in_size = fread(in, 1, sizeof(in), stdin);
+ b.in_pos = 0;
+ }
+
+ ret = xz_dec_run(s, &b);
+
+ if (b.out_pos == sizeof(out))
+ {
+ if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos)
+ {
+ msg = "Write error\n";
+ goto error;
+ }
+
+ b.out_pos = 0;
+ }
+
+ if (ret == XZ_OK)
+ continue;
#ifdef XZ_DEC_ANY_CHECK
- if (ret == XZ_UNSUPPORTED_CHECK)
- {
- fputs(argv[0], stderr);
- fputs(": ", stderr);
- fputs("Unsupported check; not verifying "
- "file integrity\n",
- stderr);
- continue;
- }
+ if (ret == XZ_UNSUPPORTED_CHECK)
+ {
+ fputs(argv[0], stderr);
+ fputs(": ", stderr);
+ fputs("Unsupported check; not verifying "
+ "file integrity\n",
+ stderr);
+ continue;
+ }
#endif
- if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos || fclose(stdout))
- {
- msg = "Write error\n";
- goto error;
- }
-
- switch (ret)
- {
- case XZ_STREAM_END:
- xz_dec_end(s);
- return 0;
-
- case XZ_MEM_ERROR:
- msg = "Memory allocation failed\n";
- goto error;
-
- case XZ_MEMLIMIT_ERROR:
- msg = "Memory usage limit reached\n";
- goto error;
-
- case XZ_FORMAT_ERROR:
- msg = "Not a .xz file\n";
- goto error;
-
- case XZ_OPTIONS_ERROR:
- msg = "Unsupported options in the .xz headers\n";
- goto error;
-
- case XZ_DATA_ERROR:
- case XZ_BUF_ERROR:
- msg = "File is corrupt\n";
- goto error;
-
- default:
- msg = "Bug!\n";
- goto error;
- }
- }
+ if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos || fclose(stdout))
+ {
+ msg = "Write error\n";
+ goto error;
+ }
+
+ switch (ret)
+ {
+ case XZ_STREAM_END:
+ xz_dec_end(s);
+ return 0;
+
+ case XZ_MEM_ERROR:
+ msg = "Memory allocation failed\n";
+ goto error;
+
+ case XZ_MEMLIMIT_ERROR:
+ msg = "Memory usage limit reached\n";
+ goto error;
+
+ case XZ_FORMAT_ERROR:
+ msg = "Not a .xz file\n";
+ goto error;
+
+ case XZ_OPTIONS_ERROR:
+ msg = "Unsupported options in the .xz headers\n";
+ goto error;
+
+ case XZ_DATA_ERROR:
+ case XZ_BUF_ERROR:
+ msg = "File is corrupt\n";
+ goto error;
+
+ default:
+ msg = "Bug!\n";
+ goto error;
+ }
+ }
error:
- xz_dec_end(s);
- fputs(argv[0], stderr);
- fputs(": ", stderr);
- fputs(msg, stderr);
- return 1;
+ xz_dec_end(s);
+ fputs(argv[0], stderr);
+ fputs(": ", stderr);
+ fputs(msg, stderr);
+ return 1;
}
diff --git a/travis/prepare.sh b/travis/prepare.sh
index edf9df73..9395bc78 100644
--- a/travis/prepare.sh
+++ b/travis/prepare.sh
@@ -2,45 +2,45 @@ set -e
if [ "$TRAVIS_OS_NAME" = "linux" ]
then
- QT_WITHOUT_DOTS=qt$(echo $QT_VERSION | grep -oP "[^\.]*" | tr -d '\n' | tr '[:upper:]' '[:lower]')
- QT_PKG_PREFIX=$(echo $QT_WITHOUT_DOTS | cut -c1-4)
- QT_PKG_INSTALL=$QT_PKG_PREFIX
- if [ "$QT_PKG_PREFIX" = "qt50" ]; then QT_PKG_PREFIX=qt QT_PKG_INSTALL=qt5; fi
- echo $QT_WITHOUT_DOTS
- echo $QT_PKG_PREFIX
- echo $QT_PKG_INSTALL
- if [ "$TRAVIS_DIST" = "precise" ]; then
- sudo add-apt-repository -y ppa:beineri/opt-${QT_WITHOUT_DOTS}
- else
- sudo add-apt-repository -y ppa:beineri/opt-${QT_WITHOUT_DOTS}-$TRAVIS_DIST
- fi
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test # for a recent GCC
- sudo add-apt-repository "deb http://llvm.org/apt/${TRAVIS_DIST}/ llvm-toolchain-${TRAVIS_DIST}-3.5 main"
+ QT_WITHOUT_DOTS=qt$(echo $QT_VERSION | grep -oP "[^\.]*" | tr -d '\n' | tr '[:upper:]' '[:lower]')
+ QT_PKG_PREFIX=$(echo $QT_WITHOUT_DOTS | cut -c1-4)
+ QT_PKG_INSTALL=$QT_PKG_PREFIX
+ if [ "$QT_PKG_PREFIX" = "qt50" ]; then QT_PKG_PREFIX=qt QT_PKG_INSTALL=qt5; fi
+ echo $QT_WITHOUT_DOTS
+ echo $QT_PKG_PREFIX
+ echo $QT_PKG_INSTALL
+ if [ "$TRAVIS_DIST" = "precise" ]; then
+ sudo add-apt-repository -y ppa:beineri/opt-${QT_WITHOUT_DOTS}
+ else
+ sudo add-apt-repository -y ppa:beineri/opt-${QT_WITHOUT_DOTS}-$TRAVIS_DIST
+ fi
+ sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test # for a recent GCC
+ sudo add-apt-repository "deb http://llvm.org/apt/${TRAVIS_DIST}/ llvm-toolchain-${TRAVIS_DIST}-3.5 main"
- sudo apt-get update -qq
- sudo apt-get install ${QT_PKG_PREFIX}base ${QT_PKG_PREFIX}svg ${QT_PKG_PREFIX}tools
+ sudo apt-get update -qq
+ sudo apt-get install ${QT_PKG_PREFIX}base ${QT_PKG_PREFIX}svg ${QT_PKG_PREFIX}tools
- sudo mkdir -p /opt/cmake-3/
- wget --no-check-certificate http://www.cmake.org/files/v3.9/cmake-3.9.3-Linux-x86_64.sh
- sudo sh cmake-3.9.3-Linux-x86_64.sh --skip-license --prefix=/opt/cmake-3/
+ sudo mkdir -p /opt/cmake-3/
+ wget --no-check-certificate http://www.cmake.org/files/v3.9/cmake-3.9.3-Linux-x86_64.sh
+ sudo sh cmake-3.9.3-Linux-x86_64.sh --skip-license --prefix=/opt/cmake-3/
- export CMAKE_PREFIX_PATH=/opt/$QT_PKG_INSTALL/lib/cmake
- export PATH=/opt/cmake-3/bin:/opt/$QT_PKG_INSTALL/bin:$PATH
+ export CMAKE_PREFIX_PATH=/opt/$QT_PKG_INSTALL/lib/cmake
+ export PATH=/opt/cmake-3/bin:/opt/$QT_PKG_INSTALL/bin:$PATH
- if [ "$CXX" = "g++" ]; then
- sudo apt-get install -y -qq g++-5
- export CXX='g++-5' CC='gcc-5'
- fi
- if [ "$CXX" = "clang++" ]; then
- wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add -
- sudo apt-get install -y -qq clang-3.5 liblldb-3.5 libclang1-3.5 libllvm3.5 lldb-3.5 llvm-3.5 llvm-3.5-runtime
- export CXX='clang++-3.5' CC='clang-3.5'
- fi
+ if [ "$CXX" = "g++" ]; then
+ sudo apt-get install -y -qq g++-5
+ export CXX='g++-5' CC='gcc-5'
+ fi
+ if [ "$CXX" = "clang++" ]; then
+ wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add -
+ sudo apt-get install -y -qq clang-3.5 liblldb-3.5 libclang1-3.5 libllvm3.5 lldb-3.5 llvm-3.5 llvm-3.5-runtime
+ export CXX='clang++-3.5' CC='clang-3.5'
+ fi
else
- brew update
- brew install qt5
- brew install cmake
- export CMAKE_PREFIX_PATH=/usr/local/lib/cmake
+ brew update
+ brew install qt5
+ brew install cmake
+ export CMAKE_PREFIX_PATH=/usr/local/lib/cmake
fi
# Output versions