NOISSUE tabs -> spaces
This commit is contained in:
+2
-2
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"project_id": "MultiMC5",
|
||||
"conduit_uri": "http://ph.multimc.org"
|
||||
"project_id": "MultiMC5",
|
||||
"conduit_uri": "http://ph.multimc.org"
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
UseTab: true
|
||||
UseTab: false
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
+90
-90
@@ -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 ################################
|
||||
|
||||
+175
-175
@@ -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.
|
||||
|
||||
+12
-12
@@ -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}
|
||||
)
|
||||
+87
-87
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+20
-20
@@ -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);
|
||||
}
|
||||
|
||||
+12
-12
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+275
-275
@@ -27,394 +27,394 @@
|
||||
|
||||
IconList::IconList(const QStringList &builtinPaths, QString path, QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
QSet<QString> builtinNames;
|
||||
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);
|
||||
}
|
||||
// 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)));
|
||||
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);
|
||||
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();
|
||||
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_remove = current_set;
|
||||
to_remove -= new_set;
|
||||
|
||||
QSet<QString> to_add = new_set;
|
||||
to_add -= current_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 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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
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;
|
||||
// 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();
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
int row = index.row();
|
||||
|
||||
if (row < 0 || row >= icons.size())
|
||||
return QVariant();
|
||||
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();
|
||||
}
|
||||
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());
|
||||
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;
|
||||
QString suffix = fileinfo.suffix();
|
||||
if (suffix != "jpeg" && suffix != "png" && suffix != "jpg" && suffix != "ico" && suffix != "svg")
|
||||
continue;
|
||||
|
||||
if (!QFile::copy(file, target))
|
||||
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"
|
||||
|
||||
+36
-36
@@ -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;
|
||||
};
|
||||
|
||||
+54
-54
@@ -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;
|
||||
}
|
||||
|
||||
+18
-18
@@ -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);
|
||||
};
|
||||
|
||||
+16
-16
@@ -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 (!patchesDir(to->instanceRoot()).exists())
|
||||
{
|
||||
QDir(to->instanceRoot()).mkdir("patches");
|
||||
}
|
||||
|
||||
if (isApplied(to))
|
||||
{
|
||||
if (!remove(to))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (isApplied(to))
|
||||
{
|
||||
if (!remove(to))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
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/");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
+120
-120
@@ -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;
|
||||
}
|
||||
|
||||
+167
-167
@@ -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;
|
||||
void setProvider(BaseInstanceProvider * provider);
|
||||
BaseInstanceProvider * provider() const;
|
||||
|
||||
/// get the type of this instance
|
||||
QString instanceType() const;
|
||||
/// get the type of this instance
|
||||
QString instanceType() const;
|
||||
|
||||
/// Path to the instance's root directory.
|
||||
QString instanceRoot() const;
|
||||
/// Path to the instance's root directory.
|
||||
QString instanceRoot() const;
|
||||
|
||||
QString name() const;
|
||||
void setName(QString val);
|
||||
QString name() const;
|
||||
void setName(QString val);
|
||||
|
||||
/// Value used for instance window titles
|
||||
QString windowTitle() const;
|
||||
/// Value used for instance window titles
|
||||
QString windowTitle() const;
|
||||
|
||||
QString iconKey() const;
|
||||
void setIconKey(QString val);
|
||||
QString iconKey() const;
|
||||
void setIconKey(QString val);
|
||||
|
||||
QString notes() const;
|
||||
void setNotes(QString val);
|
||||
QString notes() const;
|
||||
void setNotes(QString val);
|
||||
|
||||
QString group() const;
|
||||
void setGroupInitial(QString val);
|
||||
void setGroupPost(QString val);
|
||||
QString group() const;
|
||||
void setGroupInitial(QString val);
|
||||
void setGroupPost(QString val);
|
||||
|
||||
QString getPreLaunchCommand();
|
||||
QString getPostExitCommand();
|
||||
QString getWrapperCommand();
|
||||
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;
|
||||
};
|
||||
/// 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;
|
||||
virtual QStringList extraArguments() const;
|
||||
|
||||
/// Traits. Normally inside the version, depends on instance implementation.
|
||||
virtual QSet <QString> traits() const = 0;
|
||||
/// 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());
|
||||
/**
|
||||
* 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();
|
||||
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;
|
||||
/*!
|
||||
* \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 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 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();
|
||||
/// returns the current launch task (if any)
|
||||
std::shared_ptr<LaunchTask> getLaunchTask();
|
||||
|
||||
/*!
|
||||
* Create envrironment variables for running the instance
|
||||
*/
|
||||
virtual QProcessEnvironment createEnvironment() = 0;
|
||||
/*!
|
||||
* 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 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;
|
||||
/*!
|
||||
* Returns the root folder to use for looking up log files
|
||||
*/
|
||||
virtual QString getLogFileRoot() = 0;
|
||||
|
||||
virtual QString getStatusbarDescription() = 0;
|
||||
virtual QString getStatusbarDescription() = 0;
|
||||
|
||||
/// FIXME: this really should be elsewhere...
|
||||
virtual QString instanceConfigFolder() const = 0;
|
||||
/// FIXME: this really should be elsewhere...
|
||||
virtual QString instanceConfigFolder() const = 0;
|
||||
|
||||
/// get variables this instance exports
|
||||
virtual QMap<QString, QString> getVariables() const = 0;
|
||||
/// get variables this instance exports
|
||||
virtual QMap<QString, QString> getVariables() const = 0;
|
||||
|
||||
virtual QString typeName() 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 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 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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
virtual bool canLaunch() const;
|
||||
virtual bool canEdit() const = 0;
|
||||
virtual bool canExport() const = 0;
|
||||
|
||||
bool reloadSettings();
|
||||
bool reloadSettings();
|
||||
|
||||
/**
|
||||
* 'print' a verbose desription of the instance into a QStringList
|
||||
*/
|
||||
virtual QStringList verboseDescription(AuthSessionPtr session) = 0;
|
||||
/**
|
||||
* 'print' a verbose desription of the instance into a QStringList
|
||||
*/
|
||||
virtual QStringList verboseDescription(AuthSessionPtr session) = 0;
|
||||
|
||||
Status currentStatus() const;
|
||||
Status currentStatus() const;
|
||||
|
||||
int getConsoleMaxLines() const;
|
||||
bool shouldStopOnConsoleOverflow() 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>)
|
||||
|
||||
@@ -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 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 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;
|
||||
};
|
||||
|
||||
+24
-24
@@ -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;
|
||||
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;
|
||||
/*!
|
||||
* 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;
|
||||
/*!
|
||||
* 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 bool operator<(BaseVersion &a)
|
||||
{
|
||||
return name() < a.name();
|
||||
};
|
||||
virtual bool operator>(BaseVersion &a)
|
||||
{
|
||||
return name() > a.name();
|
||||
};
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<BaseVersion> BaseVersionPtr;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+67
-67
@@ -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;
|
||||
};
|
||||
|
||||
+356
-356
@@ -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
|
||||
# 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
|
||||
# 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
|
||||
# Use tracking separate from memory management
|
||||
Usable.h
|
||||
|
||||
# Prefix tree where node names are strings between separators
|
||||
SeparatorPrefixTree.h
|
||||
# Prefix tree where node names are strings between separators
|
||||
SeparatorPrefixTree.h
|
||||
|
||||
# WARNING: globals live here
|
||||
Env.h
|
||||
Env.cpp
|
||||
# WARNING: globals live here
|
||||
Env.h
|
||||
Env.cpp
|
||||
|
||||
# String filters
|
||||
Filter.h
|
||||
Filter.cpp
|
||||
# String filters
|
||||
Filter.h
|
||||
Filter.cpp
|
||||
|
||||
# JSON parsing helpers
|
||||
Json.h
|
||||
Json.cpp
|
||||
# JSON parsing helpers
|
||||
Json.h
|
||||
Json.cpp
|
||||
|
||||
FileSystem.h
|
||||
FileSystem.cpp
|
||||
FileSystem.h
|
||||
FileSystem.cpp
|
||||
|
||||
Exception.h
|
||||
Exception.h
|
||||
|
||||
# RW lock protected map
|
||||
RWStorage.h
|
||||
# RW lock protected map
|
||||
RWStorage.h
|
||||
|
||||
# A variable that has an implicit default value and keeps track of changes
|
||||
DefaultVariable.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
|
||||
# a smart pointer wrapper intended for safer use with Qt signal/slot mechanisms
|
||||
QObjectPtr.h
|
||||
|
||||
# Compression support
|
||||
GZip.h
|
||||
GZip.cpp
|
||||
# Compression support
|
||||
GZip.h
|
||||
GZip.cpp
|
||||
|
||||
# Command line parameter parsing
|
||||
Commandline.h
|
||||
Commandline.cpp
|
||||
# Command line parameter parsing
|
||||
Commandline.h
|
||||
Commandline.cpp
|
||||
|
||||
# Version number string support
|
||||
Version.h
|
||||
Version.cpp
|
||||
# Version number string support
|
||||
Version.h
|
||||
Version.cpp
|
||||
|
||||
# A Recursive file system watcher
|
||||
RecursiveFileSystemWatcher.h
|
||||
RecursiveFileSystemWatcher.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
|
||||
# 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
|
||||
# Assets
|
||||
minecraft/AssetsUtils.h
|
||||
minecraft/AssetsUtils.cpp
|
||||
|
||||
# Forge and all things forge related
|
||||
minecraft/forge/ForgeXzDownload.h
|
||||
minecraft/forge/ForgeXzDownload.cpp
|
||||
# Forge and all things forge related
|
||||
minecraft/forge/ForgeXzDownload.h
|
||||
minecraft/forge/ForgeXzDownload.cpp
|
||||
|
||||
# Skin upload utilities
|
||||
minecraft/SkinUpload.cpp
|
||||
minecraft/SkinUpload.h
|
||||
)
|
||||
# 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}
|
||||
)
|
||||
|
||||
+328
-328
@@ -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);
|
||||
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;
|
||||
// \ 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";
|
||||
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;
|
||||
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);
|
||||
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";
|
||||
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;
|
||||
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);
|
||||
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";
|
||||
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;
|
||||
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";
|
||||
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";
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
// 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";
|
||||
}
|
||||
}
|
||||
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("");
|
||||
return help.join("");
|
||||
}
|
||||
|
||||
QString Parser::compileUsage(QString progName, bool useFlags)
|
||||
{
|
||||
QStringList usage;
|
||||
usage << "Usage: " << progName;
|
||||
QStringList usage;
|
||||
usage << "Usage: " << progName;
|
||||
|
||||
QString optPrefix, flagPrefix;
|
||||
getPrefix(optPrefix, flagPrefix);
|
||||
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 << "]";
|
||||
}
|
||||
// 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 ? ">" : "]");
|
||||
}
|
||||
// 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("");
|
||||
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);
|
||||
map[name] = QVariant(arg);
|
||||
|
||||
expecting.removeFirst();
|
||||
continue;
|
||||
}
|
||||
expecting.removeFirst();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.startsWith(optionPrefix))
|
||||
// we have an option
|
||||
{
|
||||
// qDebug("Found option %s", qPrintable(arg));
|
||||
if (arg.startsWith(optionPrefix))
|
||||
// we have an option
|
||||
{
|
||||
// qDebug("Found option %s", qPrintable(arg));
|
||||
|
||||
QString name = arg.mid(optionPrefix.length());
|
||||
QString equals;
|
||||
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_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));
|
||||
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));
|
||||
}
|
||||
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;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix));
|
||||
}
|
||||
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));
|
||||
if (arg.startsWith(flagPrefix))
|
||||
// we have (a) flag(s)
|
||||
{
|
||||
// qDebug("Found flags %s", qPrintable(arg));
|
||||
|
||||
QString flags = arg.mid(flagPrefix.length());
|
||||
QString equals;
|
||||
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);
|
||||
}
|
||||
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);
|
||||
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));
|
||||
if (!m_flags.contains(flag))
|
||||
throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix));
|
||||
|
||||
OptionDef *option = m_flags[flag];
|
||||
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));
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// must be a positional argument
|
||||
if (!positionals.hasNext())
|
||||
throw ParsingError(QString("Don't know what to do with '%1'").arg(arg));
|
||||
// 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();
|
||||
PositionalDef *param = positionals.next();
|
||||
|
||||
map[param->name] = arg;
|
||||
}
|
||||
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));
|
||||
// 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
// 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;
|
||||
return map;
|
||||
}
|
||||
|
||||
// clear defs
|
||||
void Parser::clear()
|
||||
{
|
||||
m_flags.clear();
|
||||
m_params.clear();
|
||||
m_options.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<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;
|
||||
}
|
||||
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
|
||||
|
||||
+142
-142
@@ -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 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 set the flag style
|
||||
* @param style
|
||||
*/
|
||||
void setFlagStyle(FlagStyle::Enum style);
|
||||
|
||||
/**
|
||||
* @brief get the flag style
|
||||
* @return
|
||||
*/
|
||||
FlagStyle::Enum flagStyle();
|
||||
/**
|
||||
* @brief get the flag style
|
||||
* @return
|
||||
*/
|
||||
FlagStyle::Enum flagStyle();
|
||||
|
||||
/**
|
||||
* @brief set the argument style
|
||||
* @param style
|
||||
*/
|
||||
void setArgumentStyle(ArgumentStyle::Enum style);
|
||||
/**
|
||||
* @brief set the argument style
|
||||
* @param style
|
||||
*/
|
||||
void setArgumentStyle(ArgumentStyle::Enum style);
|
||||
|
||||
/**
|
||||
* @brief get the argument style
|
||||
* @return
|
||||
*/
|
||||
ArgumentStyle::Enum argumentStyle();
|
||||
/**
|
||||
* @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 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 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 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 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 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 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 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 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();
|
||||
/**
|
||||
* @brief clear all definitions
|
||||
*/
|
||||
void clear();
|
||||
|
||||
~Parser();
|
||||
~Parser();
|
||||
|
||||
private:
|
||||
FlagStyle::Enum m_flagStyle;
|
||||
ArgumentStyle::Enum m_argStyle;
|
||||
FlagStyle::Enum m_flagStyle;
|
||||
ArgumentStyle::Enum m_argStyle;
|
||||
|
||||
enum OptionType
|
||||
{
|
||||
otSwitch,
|
||||
otOption
|
||||
};
|
||||
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;
|
||||
};
|
||||
// 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 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;
|
||||
};
|
||||
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;
|
||||
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);
|
||||
void getPrefix(QString &opt, QString &flag);
|
||||
};
|
||||
}
|
||||
|
||||
+27
-27
@@ -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;
|
||||
};
|
||||
|
||||
+103
-103
@@ -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);
|
||||
}
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
|
||||
+19
-19
@@ -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;
|
||||
};
|
||||
|
||||
+18
-18
@@ -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;
|
||||
};
|
||||
|
||||
+299
-299
@@ -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
|
||||
//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);
|
||||
auto src = PathCombine(m_src.absolutePath(), offset);
|
||||
auto dst = PathCombine(m_dst.absolutePath(), offset);
|
||||
|
||||
QFileInfo currentSrc(src);
|
||||
if (!currentSrc.exists())
|
||||
return false;
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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 a = QDir::currentPath();
|
||||
QString currentAbsolute = a.absolutePath();
|
||||
|
||||
QDir b(path);
|
||||
QString newAbsolute = b.absolutePath();
|
||||
QDir b(path);
|
||||
QString newAbsolute = b.absolutePath();
|
||||
|
||||
if (newAbsolute.startsWith(currentAbsolute))
|
||||
{
|
||||
return a.relativeFilePath(newAbsolute);
|
||||
}
|
||||
else
|
||||
{
|
||||
return newAbsolute;
|
||||
}
|
||||
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);;
|
||||
}
|
||||
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;
|
||||
// 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;
|
||||
HRESULT hres;
|
||||
|
||||
if (!called_coinit)
|
||||
{
|
||||
hres = CoInitialize(NULL);
|
||||
called_coinit = true;
|
||||
if (!called_coinit)
|
||||
{
|
||||
hres = CoInitialize(NULL);
|
||||
called_coinit = true;
|
||||
|
||||
if (!SUCCEEDED(hres))
|
||||
{
|
||||
qWarning("Failed to initialize COM. Error 0x%08lX", hres);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
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);
|
||||
IShellLink *link;
|
||||
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink,
|
||||
(LPVOID *)&link);
|
||||
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
IPersistFile *persistFile;
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
IPersistFile *persistFile;
|
||||
|
||||
link->SetPath(targetPath);
|
||||
link->SetArguments(args);
|
||||
link->SetPath(targetPath);
|
||||
link->SetArguments(args);
|
||||
|
||||
hres = link->QueryInterface(IID_IPersistFile, (LPVOID *)&persistFile);
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
WCHAR wstr[MAX_PATH];
|
||||
hres = link->QueryInterface(IID_IPersistFile, (LPVOID *)&persistFile);
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
WCHAR wstr[MAX_PATH];
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
|
||||
MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
|
||||
|
||||
hres = persistFile->Save(wstr, TRUE);
|
||||
persistFile->Release();
|
||||
}
|
||||
link->Release();
|
||||
}
|
||||
return hres;
|
||||
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. | ||||