diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2c51073..77c993e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,7 +6,7 @@ before_script: Linux_x64: stage: build script: - - zypper -q install -y find libgit2-devel make gcc gcc-c++ libQt5Concurrent-devel libQt5Core-devel libQt5Gui-devel libQt5QuickControls2-devel libqt5-qtbase-devel libqt5-qtdeclarative-devel quazip-qt5-devel + - zypper -q install -y find libgit2-devel make gcc gcc-c++ libQt6Concurrent-devel libQt6Core-devel libQt6Gui-devel libQt6QuickControls2-devel libqt6-qtbase-devel libqt6-qtdeclarative-devel quazip-qt6-devel - make -f CI.mk linuxdeploy - make -f CI.mk finalize artifacts: @@ -23,7 +23,7 @@ Win32: - mingw32 stage: build script: - - zypper -q remove -y patterns-base-fips + - zypper -q remove -y patterns-base-fips busybox-which - zypper -q install -y find wine-staging wine-staging-32bit wget make p7zip tar gzip || true - make -f CI.mk windeploy - make -f CI.mk finalize diff --git a/AddonsPanel.qml b/AddonsPanel.qml index 4c225b4..53a2670 100644 --- a/AddonsPanel.qml +++ b/AddonsPanel.qml @@ -14,11 +14,10 @@ * along with this program. If not, see . */ -import QtQuick 2.9 -import GitAddonsManager.engine 1.0 -import QtQuick.Controls 2.4 -import QtQuick.Layouts 1.3 -import QtQuick.Controls.Material 2.4 +import QtQuick +import GitAddonsManager.engine +import QtQuick.Controls +import QtQuick.Layouts Page { title: "Addons" @@ -31,7 +30,7 @@ Page { action: addAction ToolTip.visible: hovered ToolTip.text: "Download a new addon from a git repository" - Material.foreground: Material.background + //Material.foreground: Material.background } ToolButton { hoverEnabled: true @@ -39,7 +38,7 @@ Page { icon.name: availableUpdates > 0 ? "update-high" : "update-none" ToolTip.visible: hovered ToolTip.text: "Upgrade all addons" - Material.foreground: Material.background + //Material.foreground: Material.background } Item { @@ -52,7 +51,7 @@ Page { action: refreshAction ToolTip.visible: hovered ToolTip.text: "Refresh addons list and check for updates" - Material.foreground: Material.background + //Material.foreground: Material.background } } } @@ -68,7 +67,7 @@ Page { model: Engine.addons id: listView - section.property: "modelData.path" + section.property: "path" section.criteria: ViewSection.FullString section.delegate: Button { @@ -81,7 +80,7 @@ Page { delegate: MouseArea { property Addon addon: Engine.addons[index] - width: parent.width + implicitWidth: listView.width implicitHeight: row.height hoverEnabled: true id: ma @@ -233,7 +232,7 @@ Page { readOnly: true anchors.fill: parent wrapMode: Text.NoWrap - font.family: monospaced.name + font.family: "Hack" } } } diff --git a/CI.mk b/CI.mk index e9ba039..6f65f1d 100644 --- a/CI.mk +++ b/CI.mk @@ -1,14 +1,15 @@ # Intended for gitlab CI -qt7z:=5.11.1-0-201806180838£-Windows-Windows_7-Mingw53-Windows-Windows_7-X86.7z +qt7z:=6.7.2-0-202406110335£-Windows-Windows_10_22H2-Mingw-Windows-Windows_10_22H2-X86_64.7z pwd:=$(shell pwd) wineenv=$(WINEPREFIX) $(WINEENV) WINEDEBUG=-all winepath=$(wineenv) winepath wine=$(WINEPATH) $(wineenv) wine +winepwd:=$(shell $(wine) winepath -w $(pwd)) WINEPREFIX=WINEPREFIX="$(pwd)/wine" -WINEPATH=WINEPATH='C:\Program Files (x86)\CMake\bin;$(shell $(winepath) -w "$(pwd)/mingw32/bin");$(shell $(winepath) -w "$(pwd)/Qt/5.11.1/mingw53_32/bin")' QTDIR="Z:$(pwd)/Qt/5.11.1/mingw53_32/" +WINEPATH=WINEPATH='C:\Program Files (x86)\CMake\bin;$(shell $(winepath) -w "$(pwd)/mingw64/bin");$(shell $(winepath) -w "$(pwd)/Qt/6.7.2/mingw_64/bin")' QTDIR="Z:$(pwd)/Qt/6.7.2/mingw_64/" qmake_opts="QMAKE_INCDIR+=Z:$(pwd)/libgit2-0.27.2/include Z:$(pwd)/quazip/quazip" "QMAKE_LIBDIR+=Z:$(pwd)/libgit2-0.27.2/build/ Z:$(pwd)/quazip/build/release Z:$(pwd)/libz/build" -spec win32-g++ LIBS+=-lquazip -qmake=$(wine) $(pwd)/Qt/5.11.1/mingw53_32/bin/qmake.exe +qmake=$(wine) $(pwd)/Qt/6.7.2/mingw_64/bin/qmake.exe .PHONY: build winbuild windeploy linuxdeploy finalize @@ -16,57 +17,62 @@ finalize: cd GitAddonsManager && echo "# DO NOT EDIT" > .installedFiles && find ! -path . >> .installedFiles build: - mkdir -p build && cd build && qmake-qt5 .. -spec linux-g++ DEFINES+='GAM_BUILD_NAME=\\\"Linux_x64\\\"' PKGCONFIG=quazip1-qt5 CONFIG+=link_pkgconfig && make + mkdir -p build && cd build && qmake-qt6 .. -spec linux-g++ DEFINES+='GAM_BUILD_NAME=\\\"Linux_x64\\\"' PKGCONFIG=quazip1-qt6 CONFIG+=link_pkgconfig && make linuxdeploy: build mkdir GitAddonsManager cp build/GitAddonsManager -f GitAddonsManager/GitAddonsManager -cmake-3.12.0-rc3-win32-x86.msi: - wget https://cmake.org/files/v3.12/cmake-3.12.0-rc3-win32-x86.msi +cmake-3.30.1-windows-x86_64.msi: + wget https://github.com/Kitware/CMake/releases/download/v3.30.1/cmake-3.30.1-windows-x86_64.msi -wine/drive_c/Program\ Files\ (x86)/CMake: cmake-3.12.0-rc3-win32-x86.msi - $(wine) msiexec /quiet /i cmake-3.12.0-rc3-win32-x86.msi +wine/drive_c/Program\ Files\ (x86)/CMake: cmake-3.30.1-windows-x86_64.msi + $(wine) msiexec /quiet /i cmake-3.30.1-windows-x86_64.msi -qt-opensource-windows-x86-5.11.1.exe: - wget http://download.qt.io/official_releases/qt/5.11/5.11.1/qt-opensource-windows-x86-5.11.1.exe +qt-opensource-windows-x86-6.7.2.exe: + wget http://download.qt.io/official_releases/qt/6.7/6.7.2/qt-opensource-windows-x86-6.7.2.exe -5.11.1-0-201806180838%-Windows-Windows_7-Mingw53-Windows-Windows_7-X86.7z: - wget http://ftp.fau.de/qtproject/online/qtsdkrepository/windows_x86/desktop/qt5_5111/qt.qt5.5111.win32_mingw53/$@ +6.7.2-0-202406110335%-Windows-Windows_10_22H2-Mingw-Windows-Windows_10_22H2-X86_64.7z: + wget https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt6_672/qt.qt6.672.win64_mingw/$@ -qt-modules:=Qt/5.11.1/mingw53_32/bin/qmake.exe Qt/5.11.1/mingw53_32/bin/windeployqt.exe Qt/5.11.1/mingw53_32/bin/Qt5QuickControls2.dll Qt/5.11.1/mingw53_32/bin/Qt5Svg.dll Qt/5.11.1/mingw53_32/bin/Qt5Quick.dll Qt/5.11.1/mingw53_32/qml/QtQuick Qt/5.11.1/mingw53_32/qml/QtQuick/PrivateWidgets/widgetsplugin.dll Qt/5.11.1/mingw53_32/qml/QtGraphicalEffects Qt/5.11.1/mingw53_32/translations +qt-modules:=Qt/6.7.2/mingw_64/bin/qmake.exe Qt/6.7.2/mingw_64/bin/windeployqt.exe Qt/6.7.2/mingw_64/bin/Qt6Svg.dll Qt/6.7.2/mingw_64/bin/Qt6Quick.dll Qt/6.7.2/mingw_64/qml/QtQuick Qt/6.7.2/mingw_64/translations Qt/6.7.2/mingw_64/bin/Qt5Compat.dll -Qt/5.11.1/mingw53_32/bin/qmake.exe: $(subst £,qtbase,$(qt7z)) +Qt/6.7.2/mingw_64/bin/qmake.exe: $(subst £,qtbase,$(qt7z)) -Qt/5.11.1/mingw53_32/bin/windeployqt.exe: $(subst £,qttools,$(qt7z)) +Qt/6.7.2/mingw_64/bin/windeployqt.exe: $(subst £,qttools,$(qt7z)) -Qt/5.11.1/mingw53_32/bin/Qt5QuickControls2.dll: $(subst £,qtquickcontrols2,$(qt7z)) +Qt/6.7.2/mingw_64/bin/Qt6QuickControls2.dll: $(subst £,qtquickcontrols2,$(qt7z)) -Qt/5.11.1/mingw53_32/qml/QtQuick/PrivateWidgets/widgetsplugin.dll: $(subst £,qtquickcontrols,$(qt7z)) +Qt/6.7.2/mingw_64/qml/QtQuick/PrivateWidgets/widgetsplugin.dll: $(subst £,qtquickcontrols,$(qt7z)) -Qt/5.11.1/mingw53_32/bin/Qt5Quick.dll: $(subst £,qtdeclarative,$(qt7z)) +Qt/6.7.2/mingw_64/bin/Qt6Quick.dll: $(subst £,qtdeclarative,$(qt7z)) -Qt/5.11.1/mingw53_32/bin/Qt5Svg.dll: $(subst £,qtsvg,$(qt7z)) +Qt/6.7.2/mingw_64/bin/Qt6Svg.dll: $(subst £,qtsvg,$(qt7z)) -Qt/5.11.1/mingw53_32/qml/QtGraphicalEffects: $(subst £,qtgraphicaleffects,$(qt7z)) +Qt/6.7.2/mingw_64/qml/QtGraphicalEffects: $(subst £,qtgraphicaleffects,$(qt7z)) -Qt/5.11.1/mingw53_32/translations: $(subst £,qttranslations,$(qt7z)) +Qt/6.7.2/mingw_64/translations: $(subst £,qttranslations,$(qt7z)) $(qt-modules): 7zr x $< -oQt -aos touch -c $@ - -Qt/5.11.1/mingw53_32/bin/qt.conf: Qt/5.11.1/mingw53_32/bin/qmake.exe - echo "[paths]" > $(pwd)/Qt/5.11.1/mingw53_32/bin/qt.conf - echo "Prefix=../" >> $(pwd)/Qt/5.11.1/mingw53_32/bin/qt.conf -Qt: $(qt-modules) Qt/5.11.1/mingw53_32/bin/qt.conf - sed -i.bak 's/Enterprise/OpenSource/' $(pwd)/Qt/5.11.1/mingw53_32/mkspecs/qconfig.pri +Qt/6.7.2/mingw_64/bin/Qt5Compat.dll: + wget https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt6_672/qt.qt6.672.qt5compat.win64_mingw/6.7.2-0-202406110335qt5compat-Windows-Windows_10_22H2-Mingw-Windows-Windows_10_22H2-X86_64.7z + 7zr x 6.7.2-0-202406110335qt5compat-Windows-Windows_10_22H2-Mingw-Windows-Windows_10_22H2-X86_64.7z -oQt -aos + touch -c $@ + +Qt/6.7.2/mingw_64/bin/qt.conf: Qt/6.7.2/mingw_64/bin/qmake.exe + echo "[paths]" > $(pwd)/Qt/6.7.2/mingw_64/bin/qt.conf + echo "Prefix=../" >> $(pwd)/Qt/6.7.2/mingw_64/bin/qt.conf + +Qt: $(qt-modules) Qt/6.7.2/mingw_64/bin/qt.conf + sed -i.bak 's/Enterprise/OpenSource/' $(pwd)/Qt/6.7.2/mingw_64/mkspecs/qconfig.pri mingw.7z: - wget https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/8.1.0/threads-posix/dwarf/i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z/download -O mingw.7z + wget https://github.com/niXman/mingw-builds-binaries/releases/download/13.2.0-rt_v11-rev0/x86_64-13.2.0-release-posix-seh-msvcrt-rt_v11-rev0.7z -O mingw.7z -mingw32/bin/gcc.exe: mingw.7z +mingw64/bin/gcc.exe: mingw.7z 7zr x mingw.7z touch -c $@ @@ -77,44 +83,50 @@ libgit2-0.27.2/CMakeLists.txt: libgit2-v0.27.2.tar.gz tar -xf libgit2-v0.27.2.tar.gz touch -c $@ -libgit2-0.27.2/build/libgit2.dll: wine/drive_c/Program\ Files\ (x86)/CMake libgit2-0.27.2/CMakeLists.txt mingw32/bin/gcc.exe +libgit2-0.27.2/release/bin/libgit2.dll: wine/drive_c/Program\ Files\ (x86)/CMake libgit2-0.27.2/CMakeLists.txt mingw64/bin/gcc.exe mkdir -p libgit2-0.27.2/build - cd libgit2-0.27.2/build && $(wine) cmake .. -DCMAKE_BINARY_DIR=libgit2-0.27.2/build -G"MinGW Makefiles" -DBUILD_CLAR=OFF + cd libgit2-0.27.2/build && $(wine) cmake .. -DCMAKE_BINARY_DIR=libgit2-0.27.2/build -G"MinGW Makefiles" -DBUILD_CLAR=OFF --install-prefix="$(winepwd)/libgit2-0.27.2/release" -DCMAKE_BUILD_TYPE=Release $(wine) mingw32-make -C libgit2-0.27.2/build -j $(shell nproc) + $(wine) mingw32-make -C libgit2-0.27.2/build install zlib/CMakeLists.txt: git clone https://github.com/madler/zlib.git zlib/build/libzlib.dll: zlib/CMakeLists.txt mkdir -p zlib/build - cd zlib/build && $(wine) cmake .. -DCMAKE_BINARY_DIR=zlib/build -G"MinGW Makefiles" + cd zlib/build && $(wine) cmake .. -DCMAKE_BINARY_DIR=zlib/build -G"MinGW Makefiles" --install-prefix="$(winepwd)/zlib/release" -DCMAKE_BUILD_TYPE=Release $(wine) mingw32-make -C zlib/build -j $(shell nproc) + $(wine) mingw32-make -C zlib/build install -quazip/quazip.pro: +quazip/CMakeLists.txt: git clone https://github.com/stachenov/quazip.git - cd quazip && git checkout v0.9.x + cd quazip -quazip/build/release/quazip.dll: quazip/quazip.pro +quazip/release/bin/libquazip1-qt6.dll: quazip/CMakeLists.txt mkdir -p quazip/build - cd quazip/build && $(qmake) ../quazip/quazip.pro QMAKE_LIBDIR+="Z:$(pwd)/zlib/build" LIBS+=-lzlib QMAKE_INCDIR+="Z:$(pwd)/zlib" -spec win32-g++ - $(wine) mingw32-make -C quazip/build + cd quazip/build && $(wine) cmake ../ -G"MinGW Makefiles" -DZLIB_LIBRARY=$(pwd)/zlib/build/libzlib.dll.a -DZLIB_INCLUDE_DIR=$(pwd)/zlib -DQUAZIP_ENABLE_TESTS=OFF -DQUAZIP_BZIP2=OFF --install-prefix="$(winepwd)/quazip/release" -DCMAKE_BUILD_TYPE=Release + $(wine) mingw32-make -C quazip/build -j $(shell nproc) + $(wine) mingw32-make -C quazip/build install -build_win32/GitAddonsManager.exe: Qt libgit2-0.27.2/build/libgit2.dll zlib/build/libzlib.dll quazip/build/release/quazip.dll - mkdir -p build_win32 && cd build_win32 && $(qmake) $(qmake_opts) ../GitAddonsManager.pro GIT_DESCRIBE="$(shell git describe --tags --long)" DEFINES+='GAM_BUILD_NAME=\\\"Win32\\\"' - $(wine) mingw32-make -C build_win32 +build_win64/GitAddonsManager.exe: Qt libgit2-0.27.2/release/bin/libgit2.dll zlib/build/libzlib.dll quazip/release/bin/libquazip1-qt6.dll + mkdir -p build_win64 && cd build_win64 && $(wine) cmake ../ -DGIT_DESCRIBE="$(shell git describe --tags --long)" -DGAM_BUILD_NAME=Win64 -G"MinGW Makefiles" -DQuaZip-Qt6_DIR=$(pwd)/quazip1-qt6/lib/cmake/QuaZip-Qt6-1.4/ -DLIBGIT2_LIBRARY=$(pwd)/libgit2-0.27.2/release/bin/libgit2.dll -DLIBGIT2_INCLUDE_DIR=$(pwd)/libgit2-0.27.2/release/include -DCMAKE_BUILD_TYPE=Release -DBUILD_CLAR=OFF --install-prefix="$(winepwd)/release" + $(wine) mingw32-make -C build_win64 -j $(shell nproc) + $(wine) mingw32-make -C build_win64 install -winbuild: build_win32/GitAddonsManager.exe +winbuild: build_win64/GitAddonsManager.exe -build_win32/release/GitAddonsManager.exe: winbuild +build_win64/release/GitAddonsManager.exe: winbuild -windeploy: build_win32/release/GitAddonsManager.exe libgit2-0.27.2/build/libgit2.dll +windeploy: build_win64/release/GitAddonsManager.exe libgit2-0.27.2/release/bin/libgit2.dll mkdir -p GitAddonsManager/ - cp libgit2-0.27.2/build/libgit2.dll -f GitAddonsManager/libgit2.dll + cp libgit2-0.27.2/release/bin/libgit2.dll -f GitAddonsManager/libgit2.dll cp zlib/build/libzlib.dll -f GitAddonsManager/libzlib.dll - cp quazip/build/release/quazip.dll -f GitAddonsManager/quazip.dll - cp mingw32/opt/bin/libeay32.dll -f GitAddonsManager/libeay32.dll - cp mingw32/opt/bin/ssleay32.dll -f GitAddonsManager/ssleay32.dll - cp build_win32/release/GitAddonsManager.exe -f GitAddonsManager/ + cp quazip/release/bin/libquazip1-qt6.dll -f GitAddonsManager/libquazip1-qt6.dll + cp Qt/6.7.2/mingw_64/bin/Qt6Core5Compat.dll GitAddonsManager/Qt6Core5Compat.dll + cp mingw64/bin/libstdc++-6.dll GitAddonsManager/libstdc++-6.dll + cp mingw64/bin/libgcc_s_seh-1.dll GitAddonsManager/libgcc_s_seh-1.dll + cp mingw64/bin/libwinpthread-1.dll GitAddonsManager/libwinpthread-1.dll + cp release/bin/GitAddonsManager.exe -f GitAddonsManager/ mkdir -p tmpqmls && cp -f *.qml tmpqmls/ - $(wine) Qt/5.11.1/mingw53_32/bin/windeployqt.exe --qmldir tmpqmls GitAddonsManager/GitAddonsManager.exe + $(wine) Qt/6.7.2/mingw_64/bin/windeployqt.exe --qmldir tmpqmls GitAddonsManager/GitAddonsManager.exe rm -fr tmpqmls diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d1fb7a8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.1.0) +project(GitAddonsManager LANGUAGES CXX) +find_package(Qt6 COMPONENTS Quick Core QuickControls2 Concurrent Network Widgets REQUIRED) +find_package(Qt6LinguistTools) +find_package(QuaZip-Qt6) +if (NOT WIN32) + find_package(PkgConfig REQUIRED) + pkg_check_modules(LIBGIT2 REQUIRED IMPORTED_TARGET libgit2) +else() + include_directories(${LIBGIT2_INCLUDE_DIR}) +endif() + +add_compile_definitions(QT_DEPRECATED_WARNINGS) + +qt_standard_project_setup() + +qt_add_resources(RESOURCES + qml.qrc +) + +if (qt6QuickCompiler_FOUND) + qtquick_compiler_add_resources(RESOURCES qml.qrc) + message(STATUS "Using qtquickcompiler") +else() + message(STATUS "qtquickcompiler not found, skipping") +endif() + +set(qml_files + AddonsPanel.qml + AddonUpdateButton.qml + ColorPicker.qml + main.qml + MaterialSettings.qml + Options.qml + StyleSettingsBase.qml + Tray.qml + UniversalSettings.qml + Update.qml +) + +qt_add_executable(GitAddonsManager + addon.h control.h utils.h + main.cpp addon.cpp control.cpp + CI.mk .gitlab-ci.yml + ${RESOURCES} + MANUAL_FINALIZATION +) + +set_property(TARGET GitAddonsManager PROPERTY CXX_STANDARD 20) + +add_compile_definitions( + GIT_DESCRIBE="${GIT_DESCRIBE}" + GAM_EXEC="GitAddonsManager${CMAKE_EXECUTABLE_SUFFIX}" + GAM_BUILD_NAME="${GAM_BUILD_NAME}" + ) + +target_link_libraries(GitAddonsManager PUBLIC Qt6::Core) +target_link_libraries(GitAddonsManager PUBLIC Qt6::Quick) +target_link_libraries(GitAddonsManager PUBLIC Qt6::QuickControls2) +target_link_libraries(GitAddonsManager PUBLIC Qt6::Concurrent) +target_link_libraries(GitAddonsManager PUBLIC Qt6::Network) +target_link_libraries(GitAddonsManager PUBLIC Qt6::Widgets) +target_link_libraries(GitAddonsManager PUBLIC QuaZip::QuaZip) +if (NOT WIN32) + target_link_libraries(GitAddonsManager PUBLIC PkgConfig::LIBGIT2) +else() + target_link_libraries(GitAddonsManager PUBLIC ${LIBGIT2_LIBRARY}) +endif() + + +# qt6_add_qml_module(GitAddonsManager +# URI raffarti.GitAddonsManager +# VERSION 1.0 +# SOURCES +# sound.cpp sound.h +# QML_FILES +# main.qml +# Sounds.qml +# Sound.qml +# # ENABLE_TYPE_COMPILER +# ) +target_link_libraries(GitAddonsManager PRIVATE Qt6::QmlPrivate Qt6::QuickPrivate) +set(APPNAME GitAddonsManager) + +install(TARGETS GitAddonsManager + CONFIGURATIONS Release + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) + +qt_finalize_executable(GitAddonsManager) diff --git a/GitAddonsManager.pro b/GitAddonsManager.pro deleted file mode 100644 index b5bf8a1..0000000 --- a/GitAddonsManager.pro +++ /dev/null @@ -1,61 +0,0 @@ -QT += quick widgets concurrent quickcontrols2 network -CONFIG += c++1z - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which as been marked deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - main.cpp \ - addon.cpp \ - control.cpp - -RESOURCES += qml.qrc - -# Additional import path used to resolve QML modules in Qt Creator's code model -QML_IMPORT_PATH = - -# Additional import path used to resolve QML modules just for Qt Quick Designer -QML_DESIGNER_IMPORT_PATH = - -# Default rules for deployment. -qnx: target.path = /tmp/$${TARGET}/bin -else: unix:!android: target.path = /opt/$${TARGET}/bin -!isEmpty(target.path): INSTALLS += target - -HEADERS += \ - addon.h \ - control.h \ - utils.h - -LIBS += -lgit2 - -win32 { - DEFINES += _WIN32_WINNT=0x06010000 GAM_EXEC=\\\"$${TARGET}.exe\\\" -} -unix { - DEFINES += GAM_EXEC=\\\"$${TARGET}\\\" -} - -isEmpty(GIT_DESCRIBE){ - GIT_DESCRIBE = $$system(git describe --tags --long) -} -isEmpty(GIT_DESCRIBE){ - message("WARNING: empty git describe") -} else { - message("Git describe: $$GIT_DESCRIBE") -} - -DEFINES += GIT_DESCRIBE=\\\"$$GIT_DESCRIBE\\\" - -DISTFILES += \ - README.md - -QMAKE_CXXFLAGS += -fconcepts diff --git a/MaterialSettings.qml b/MaterialSettings.qml new file mode 100644 index 0000000..518fbc1 --- /dev/null +++ b/MaterialSettings.qml @@ -0,0 +1,52 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import GitAddonsManager.engine +import QtCore + +StyleSettingsBase { + + ComboBox { + id: materialTheme + visible: Engine.style == "Material" + model: ["Light", "Dark"] + onCurrentIndexChanged: window.Material.theme = currentIndex + } + ColorPicker { + id: materialPrimary + visible: Engine.style == "Material" + text: qsTr("Primary:") + model: materialTheme.currentIndex === Material.Dark ? materialDarkColors : materialColors + currentIndex: Material.Indigo + onColorChanged: window.Material.primary = color + } + ColorPicker { + id: materialAccent + visible: Engine.style == "Material" + text: qsTr("Accent:") + model: materialTheme.currentIndex === Material.Dark ? materialDarkColors : materialColors + currentIndex: Material.Pink + onColorChanged: window.Material.accent = color + } + ListModel { + id: materialDarkColors + dynamicRoles: true + Component.onCompleted: { + for (var i = 0; i < 19; i++) + append({"color": Material.color(i,Material.Shade200)})} + } + ListModel { + id: materialColors + dynamicRoles: true + Component.onCompleted: { + for (var i = 0; i < 19; i++) + append({"color": Material.color(i)})} + } + + Settings { + category: "Material" + property alias primary: materialPrimary.currentIndex + property alias accent: materialAccent.currentIndex + property alias theme: materialTheme.currentIndex + } +} diff --git a/Options.qml b/Options.qml index a2e39d9..7d32359 100644 --- a/Options.qml +++ b/Options.qml @@ -14,13 +14,11 @@ * along with this program. If not, see . */ -import QtQuick 2.9 -import QtQuick.Controls 2.4 -import GitAddonsManager.engine 1.0 -import QtQuick.Layouts 1.3 -import QtQuick.Controls.Material 2.2 -import QtQuick.Controls.Universal 2.2 -import Qt.labs.settings 1.0 +import QtQuick +import QtQuick.Controls +import GitAddonsManager.engine +import QtQuick.Layouts +import QtCore Pane { ColumnLayout { @@ -43,7 +41,7 @@ Pane { Button { enabled: Control.status == Control.Ready && addonsReady text: qsTr("Browse") - onClicked: {fileDialog.selector = index; fileDialog.folder = "file://" + Engine.addonsPaths[index]; fileDialog.visible = true} + onClicked: {fileDialog.selector = index; fileDialog.currentFolder = "file://" + Engine.addonsPaths[index]; fileDialog.visible = true} hoverEnabled: true ToolTip.visible: hovered ToolTip.text: qsTr("Choose the folder containing the addons") @@ -60,6 +58,16 @@ Pane { onClicked: {fileDialog.selector = -1; fileDialog.visible = true} } + CheckBox { + Layout.fillWidth: true + checked: Engine.useRepoDirectory + onCheckedChanged: Engine.useRepoDirectory = checked + text: qsTr("Use a dedicated repository directory") + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Directories needed to update addons but not directly containing addons will be grouped in a dedicated directory.") + } + CheckBox { Layout.fillWidth: true tristate: Engine.minimizeToTray == Engine.MinimizeToTrayAsk @@ -76,95 +84,21 @@ Pane { GroupBox { Layout.fillWidth: true title: qsTr("Style") - Flow { - anchors.fill: parent - spacing: 4 - ComboBox { - model: Engine.availableStyles - currentIndex: Engine.availableStyles.indexOf(Engine.style) - onActivated: { - Engine.style = Engine.availableStyles[currentIndex] - restartDialog.visible = true - } - ToolTip.text: qsTr("Requires restart") - ToolTip.visible: hovered - hoverEnabled: true - } - ComboBox { - id: materialTheme - visible: Engine.style == "Material" - model: ["Light", "Dark"] - onCurrentIndexChanged: window.Material.theme = currentIndex - } - ComboBox { - id: universalTheme - visible: Engine.style == "Universal" - model: ["Light", "Dark", "System"] - onActivated: window.Universal.theme = currentIndex - } - ListModel { - id: materialColors - dynamicRoles: true - Component.onCompleted: { - for (var i = 0; i < 19; i++) - append({"color": Material.color(i)})} - } - ListModel { - id: materialDarkColors - dynamicRoles: true - Component.onCompleted: { - for (var i = 0; i < 19; i++) - append({"color": Material.color(i,Material.Shade200)})} - } - ListModel { - id: universalColors - dynamicRoles: true - Component.onCompleted: { - for (var i = 0; i < 20; i++) - append({"color": Universal.color(i)})} - } - ColorPicker { - id: materialPrimary - visible: Engine.style == "Material" - text: qsTr("Primary:") - model: materialTheme.currentIndex === Material.Dark ? materialDarkColors : materialColors - currentIndex: Material.Indigo - onColorChanged: window.Material.primary = color - } - ColorPicker { - id: materialAccent - visible: Engine.style == "Material" - text: qsTr("Accent:") - model: materialTheme.currentIndex === Material.Dark ? materialDarkColors : materialColors - currentIndex: Material.Pink - onColorChanged: window.Material.accent = color - } - ColorPicker { - id: universalAccent - visible: Engine.style == "Universal" - text: qsTr("Accent:") - model: universalColors - currentIndex: Universal.Cobalt - onColorChanged: window.Universal.accent = color - } - - Settings { - category: "Material" - property alias primary: materialPrimary.currentIndex - property alias accent: materialAccent.currentIndex - property alias theme: materialTheme.currentIndex - } - Settings { - category: "Universal" - property alias accent: universalAccent.currentIndex - property alias theme: universalTheme.currentIndex - } + Component.onCompleted: { + var settings + if (Engine.style == "Material") + settings = Qt.createComponent("MaterialSettings.qml") + else if (Engine.style == "Universal") + settings = Qt.createComponent("UniversalSettings.qml") + else + settings = Qt.createComponent("StyleSettingsBase.qml") + settings.createObject(this.contentItem) } } Dialog { id: restartDialog - parent: overlay + parent: window.overlay x: (parent.width - width) / 2 y: (parent.height - height) / 2 standardButtons: Dialog.Yes | Dialog.No diff --git a/StyleSettingsBase.qml b/StyleSettingsBase.qml new file mode 100644 index 0000000..0a7fb75 --- /dev/null +++ b/StyleSettingsBase.qml @@ -0,0 +1,18 @@ +import QtQuick +import QtQuick.Controls +import GitAddonsManager.engine + +Flow { + spacing: 4 + ComboBox { + model: Engine.availableStyles + currentIndex: Engine.availableStyles.indexOf(Engine.style) + onActivated: { + Engine.style = Engine.availableStyles[currentIndex] + restartDialog.visible = true + } + ToolTip.text: qsTr("Requires restart") + ToolTip.visible: hovered + hoverEnabled: true + } +} diff --git a/Tray.qml b/Tray.qml index fba55ad..ebca30a 100644 --- a/Tray.qml +++ b/Tray.qml @@ -14,14 +14,14 @@ * along with this program. If not, see . */ -import QtQuick 2.0 -import Qt.labs.platform 1.0 -import GitAddonsManager.engine 1.0 +import QtQuick +import Qt.labs.platform +import GitAddonsManager.engine SystemTrayIcon { visible: true - iconName: availableUpdates > 0 ? "update-high" : "update-none" + icon.name: availableUpdates > 0 ? "update-high" : "update-none" onActivated: { window.show() window.raise() diff --git a/UniversalSettings.qml b/UniversalSettings.qml new file mode 100644 index 0000000..4bde44d --- /dev/null +++ b/UniversalSettings.qml @@ -0,0 +1,36 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Universal +import GitAddonsManager.engine +import QtCore + +StyleSettingsBase { + + ComboBox { + id: universalTheme + visible: Engine.style == "Universal" + model: ["Light", "Dark", "System"] + onActivated: window.Universal.theme = currentIndex + } + ListModel { + id: universalColors + dynamicRoles: true + Component.onCompleted: { + for (var i = 0; i < 20; i++) + append({"color": Universal.color(i)})} + } + + ColorPicker { + id: universalAccent + visible: Engine.style == "Universal" + text: qsTr("Accent:") + model: universalColors + currentIndex: Universal.Cobalt + onColorChanged: window.Universal.accent = color + } + Settings { + category: "Universal" + property alias accent: universalAccent.currentIndex + property alias theme: universalTheme.currentIndex + } +} diff --git a/addon.cpp b/addon.cpp index d46337e..b34ba13 100644 --- a/addon.cpp +++ b/addon.cpp @@ -111,19 +111,20 @@ void Addon::scanBranches() if (!git_reflog_read(&reflog, m_repo.get(), "HEAD")) { for (size_t i = 0; i < git_reflog_entrycount(reflog); i++) { auto entry = git_reflog_entry_byindex(reflog, i); - QRegExp rex("checkout: moving from \\S+ to (.*)"); - if (rex.indexIn(git_reflog_entry_message(entry)) != -1) { + QRegularExpression rex("checkout: moving from \\S+ to (.*)"); + auto match = rex.match(git_reflog_entry_message(entry)); + if (match.hasMatch()) { auto f = &git_branch_upstream_remote; - git_branch_lookup(&ref, m_repo.get(), rex.cap(1).toLocal8Bit(), GIT_BRANCH_LOCAL); + git_branch_lookup(&ref, m_repo.get(), match.captured(1).toLocal8Bit(), GIT_BRANCH_LOCAL); if (!ref) { f = &git_branch_remote_name; - git_branch_lookup(&ref, m_repo.get(), rex.cap(1).toLocal8Bit(), GIT_BRANCH_REMOTE); + git_branch_lookup(&ref, m_repo.get(), match.captured(1).toLocal8Bit(), GIT_BRANCH_REMOTE); } if (!ref) break; git_buf buf = GIT_BUF_INIT_CONST(0, nullptr); if (!f(&buf, m_repo.get(), git_reference_name(ref))) { data.cr = buf.ptr; - data.cb = rex.cap(1); + data.cb = match.captured(1); } ref.reset(); break; diff --git a/control.cpp b/control.cpp index 4cd3f32..2463cc3 100644 --- a/control.cpp +++ b/control.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "addon.h" #include @@ -34,14 +33,14 @@ #include Control *Control::m_instance = nullptr; +QStringList Control::m_availableStyles; QNetworkAccessManager *nam = nullptr; Control::Control(QObject *parent) : QObject(parent), m_progress(0), m_total(0), m_status(Status::Ready), m_statusMessage(""), m_pool(new QThreadPool(this)), - m_style(QQuickStyle::name()),m_availableStyles(QQuickStyle::availableStyles()) + m_style(QQuickStyle::name()) { connect(this, &Control::addonsPathChanged, this, &Control::scanForAddons); - connect(this, &Control::addonsPathsChanged, this, &Control::saveAddonsPaths); } void Control::init() { @@ -55,10 +54,14 @@ void Control::init() { for (int i = 0; i < paths.length(); i++) setAddonsPath(-1, paths[i]); } + setUseRepoDirectory(settings.value("useRepoDirectory", false).toBool()); setFirstBoot(settings.value("firstBoot",true).toBool()); setMinimizeToTray((MinimizeToTray)settings.value("minimizeToTray",(int)MinimizeToTrayAsk).toInt()); nam = new QNetworkAccessManager(this); checkForUpdates(); + + connect(this, &Control::addonsPathsChanged, this, &Control::saveAddonsPaths); + connect(this, &Control::useRepoDirectoryChanged, this, &Control::saveUseRepoDirectory); } QStringList Control::addonsPaths() const @@ -232,7 +235,7 @@ void Control::completeUpdate(const QString &path) setProgress(0); setTotal(-1); } - walkFoldersIf({root.absolutePath()},[&newRoot, &files, &root, &oldFiles](const QFileInfo &info){ + walkFoldersIf(QFileInfo{root.absolutePath()},[&newRoot, &files, &root, &oldFiles](const QFileInfo &info){ QFileInfo dest(newRoot.absoluteFilePath(root.relativeFilePath(info.absoluteFilePath()))); files << info.absoluteFilePath(); if (dest.exists()) @@ -294,6 +297,8 @@ void Control::setAddonsPath(int index, QString addonsPath) emit addonsChanged(m_addons); else i++; } + if (index < 0) + return; m_addonsPaths.removeAt(index); emit addonsPathsChanged(m_addonsPaths); return; @@ -317,6 +322,12 @@ void Control::setAddonsPath(int index, QString addonsPath) emit addonsPathsChanged(m_addonsPaths); } +void Control::saveUseRepoDirectory(bool use) +{ + QSettings settings; + settings.setValue("useRepoDirectory", use); +} + void Control::saveAddonsPaths() { QSettings settings; @@ -505,16 +516,17 @@ void Control::checkForUpdates() { #ifdef GAM_BUILD_NAME QNetworkRequest req(QUrl(QString("https://gitlab.com/woblight/GitAddonsManager/-/jobs/artifacts/master/download?job=%1").arg(GAM_BUILD_NAME))); - req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); connect(nam, &QNetworkAccessManager::finished, [](auto reply){ QApplication::setApplicationDisplayName(reply->errorString()); }); auto reply = nam->head(req); setUpdateStatus(UpdateStatus::CheckingForUpdate); connect(reply, &QNetworkReply::finished,[this, reply](){ - QRegExp shaCapt(QString("GitAddonsManager_%1-(\\w{40})\\.zip").arg(GAM_BUILD_NAME)); - if (shaCapt.indexIn(reply->url().toString()) != -1) { - if (!QString(GIT_DESCRIBE).endsWith(shaCapt.cap(1).chopped(33))) + QRegularExpression shaCapt(QString("GitAddonsManager_%1-(\\w{40})\\.zip").arg(GAM_BUILD_NAME)); + auto match = shaCapt.match(reply->url().toString()); + if (match.hasMatch()) { + if (!QString(GIT_DESCRIBE).endsWith(match.captured(1).chopped(33))) setUpdateStatus(UpdateStatus::UpdateAvailable); else setUpdateStatus(UpdateStatus::NoUpdate); }; @@ -532,7 +544,7 @@ void Control::downloadUpdate() } QNetworkRequest req(QUrl(QString("https://gitlab.com/woblight/GitAddonsManager/-/jobs/artifacts/master/download?job=%1").arg(GAM_BUILD_NAME))); - req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); auto reply = nam->get(req); setUpdateStatus(UpdateStatus::DownloadingUpdate); connect(reply, &QNetworkReply::readyRead,[reply, zip]() { @@ -640,3 +652,16 @@ int check_git_return(int code) if (code < 0 && giterr_last() && code != GIT_ITEROVER && code != GIT_ENOTFOUND) throw GitException(code); else return code; } + +bool Control::useRepoDirectory() const +{ + return m_useRepoDirectory; +} + +void Control::setUseRepoDirectory(bool newUseRepoDirectory) +{ + if (m_useRepoDirectory == newUseRepoDirectory) + return; + m_useRepoDirectory = newUseRepoDirectory; + emit useRepoDirectoryChanged(newUseRepoDirectory); +} diff --git a/control.h b/control.h index 775f6d0..d1555c9 100644 --- a/control.h +++ b/control.h @@ -59,8 +59,12 @@ public: Q_PROPERTY(QString statusMessage READ statusMessage WRITE setStatusMessage NOTIFY statusMessageChanged) Q_PROPERTY(bool firstBoot READ firstBoot WRITE setFirstBoot NOTIFY firstBootChanged) Q_PROPERTY(QString style READ style WRITE setStyle NOTIFY styleChanged) - Q_PROPERTY(QStringList availableStyles READ availableStyles WRITE setAvailableStyles NOTIFY availableStylesChanged) + Q_PROPERTY(QStringList availableStyles READ availableStyles CONSTANT) Q_PROPERTY(QStringList addonsPaths READ addonsPaths WRITE setAddonsPaths NOTIFY addonsPathsChanged) + Q_PROPERTY(bool useRepoDirectory READ useRepoDirectory WRITE setUseRepoDirectory NOTIFY useRepoDirectoryChanged) + + + static QStringList m_availableStyles; ~Control(); @@ -121,6 +125,9 @@ public: static void removeTocSuffixes(QString &string); + bool useRepoDirectory() const; + void setUseRepoDirectory(bool newUseRepoDirectory); + private: static Control *m_instance; explicit Control(QObject *parent = nullptr); @@ -144,12 +151,12 @@ private: QString m_style; - QStringList m_availableStyles; - UpdateStatus m_updateStatus = UpdateStatus::NoUpdate; QStringList m_addonsPaths; + bool m_useRepoDirectory; + signals: void addonsChanged(QList addons); @@ -175,6 +182,8 @@ signals: void addonsPathChanged(int i, QString path); + void useRepoDirectoryChanged(bool use); + public slots: void setAddons(QList addons); void saveAddonsPaths(); @@ -194,6 +203,7 @@ public slots: void setUpdateStatus(UpdateStatus updateStatus); void setAddonsPaths(QStringList addonsPaths); void setAddonsPath(int i, QString path = QString()); + void saveUseRepoDirectory(bool use); }; Q_DECLARE_METATYPE(Control::MinimizeToTray) diff --git a/main.cpp b/main.cpp index 51532ea..b5b812b 100644 --- a/main.cpp +++ b/main.cpp @@ -29,7 +29,6 @@ int main(int argc, char *argv[]) { - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); QCommandLineParser parser; @@ -51,7 +50,10 @@ int main(int argc, char *argv[]) QQmlApplicationEngine engine; bool ok; QSettings setts; - QStringList styles = QQuickStyle::availableStyles(); + QStringList styles = {"Fusion","Material","Imagine","Universal","Basic"}; + if (!styles.contains(QQuickStyle::name())) + styles.prepend(QQuickStyle::name()); + Control::m_availableStyles = styles; QString style = setts.value("style").toString(); if (style.isNull()) style = QInputDialog::getItem(nullptr, QObject::tr("Choose a style"), QObject::tr("You will be able to pick another style later by visiting the Options tab."), styles, styles.indexOf(QQuickStyle::name()), false, &ok); diff --git a/main.qml b/main.qml index b6e3508..6acbe5d 100644 --- a/main.qml +++ b/main.qml @@ -14,14 +14,13 @@ * along with this program. If not, see . */ -import QtQuick 2.9 -import GitAddonsManager.engine 1.0 -import QtQuick.Controls 2.4 -import QtQuick.Dialogs 1.0 -import QtQuick.Layouts 1.3 +import QtQuick +import GitAddonsManager.engine +import QtQuick.Controls +import QtQuick.Dialogs +import QtQuick.Layouts ApplicationWindow { - FontLoader { id: monospaced; name: "Hack" } visible: true width: 640 height: 480 @@ -31,6 +30,8 @@ ApplicationWindow { property bool addonsReady: false Component.onCompleted: { availableUpdates = Qt.binding(function(){ + if (!addonsReady) + return -1; var count = 0 for (var i = 0; i < Engine.addons.length; i++) { var addon = Engine.addons[i] @@ -184,12 +185,11 @@ ApplicationWindow { } } } - FileDialog { + FolderDialog { id: fileDialog property int selector: -1 title: qsTr("Choose addons directory") - onAccepted: Engine.setAddonsPath(selector, fileUrl.toString().replace("file://","")) - selectFolder: true + onAccepted: Engine.setAddonsPath(selector, fileDialog.selectedFolder.toString().replace("file://","")) visible: Engine.addonsPaths.length == 0 } Dialog { diff --git a/qml.qrc b/qml.qrc index a14a573..d110d07 100644 --- a/qml.qrc +++ b/qml.qrc @@ -26,5 +26,8 @@ fonts/Hack-Italic.ttf fonts/Hack-Regular.ttf Update.qml + MaterialSettings.qml + StyleSettingsBase.qml + UniversalSettings.qml