refactor(ui): add WinUI stylesheet for Windows
- Introduced WinToolWidget for custom window management on Windows. - Implemented backdrop type settings for Windows in SettingsManager. - Enhanced SettingsWidget to allow selection of backdrop type. - Improved status balloon and toolbox widget styles for Windows. - Refined tab widget animations and styles for better visual feedback. - Fixed issues with loading and error widgets in ZLoadingWidget. - Updated welcome widget to support custom hyperlink colors. - General code cleanup and style adjustments across multiple files.
@@ -6,7 +6,6 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
# Feature options
|
||||
option(ENABLE_RECOVERY_DEVICE_SUPPORT "Enable recovery device support (requires libirecovery)" ON)
|
||||
set(PACKAGE_MANAGER_HINT "" CACHE STRING "Name of package manager(s) used to manage this build (e.g. paru, yay, pamac)")
|
||||
option(PACKAGE_MANAGER_MANAGED "Build as package manager managed version (auto updates will be handled by the package manager)" OFF)
|
||||
option(DEPLOY "Deploy the application (WIN32 only)" ON)
|
||||
@@ -26,39 +25,27 @@ if (APPLE)
|
||||
endif()
|
||||
|
||||
# Platform-specific paths for libraries built from source
|
||||
# if(WIN32)
|
||||
# include_directories("C:/msys64/mingw64/include")
|
||||
# link_directories("C:/msys64/mingw64/lib")
|
||||
# set(PKG_CONFIG_EXECUTABLE "C:/msys64/mingw64/bin/pkg-config.exe")
|
||||
# list(APPEND CMAKE_PREFIX_PATH "C:/lxqt")
|
||||
# set(CUSTOM_LIB_PATH "C:/msys64/mingw64/lib")
|
||||
# set(CUSTOM_INCLUDE_PATH "C:/msys64/mingw64/include")
|
||||
# set(CUSTOM_PKGCONFIG_PATH "C:/msys64/mingw64/lib/pkgconfig")
|
||||
# set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH};$ENV{PKG_CONFIG_PATH}")
|
||||
# elseif(APPLE)
|
||||
# set(CUSTOM_LIB_PATH "/usr/local/lib")
|
||||
# # Remove the problematic include path that's causing conflicts
|
||||
# # set(CUSTOM_INCLUDE_PATH "/usr/local/include")
|
||||
# set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
|
||||
# set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH}:$ENV{PKG_CONFIG_PATH}")
|
||||
# else ()
|
||||
# set(CUSTOM_LIB_PATH "/usr/local/lib")
|
||||
# set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
|
||||
# set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CUSTOM_PKGCONFIG_PATH}")
|
||||
# endif()
|
||||
if(WIN32)
|
||||
include_directories("C:/msys64/mingw64/include")
|
||||
link_directories("C:/msys64/mingw64/lib")
|
||||
set(PKG_CONFIG_EXECUTABLE "C:/msys64/mingw64/bin/pkg-config.exe")
|
||||
list(APPEND CMAKE_PREFIX_PATH "C:/lxqt")
|
||||
set(CUSTOM_LIB_PATH "C:/msys64/mingw64/lib")
|
||||
set(CUSTOM_INCLUDE_PATH "C:/msys64/mingw64/include")
|
||||
set(CUSTOM_PKGCONFIG_PATH "C:/msys64/mingw64/lib/pkgconfig")
|
||||
set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH};$ENV{PKG_CONFIG_PATH}")
|
||||
elseif(APPLE)
|
||||
set(CUSTOM_LIB_PATH "/usr/local/lib")
|
||||
# Remove the problematic include path that's causing conflicts
|
||||
# set(CUSTOM_INCLUDE_PATH "/usr/local/include")
|
||||
set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
|
||||
set(ENV{PKG_CONFIG_PATH} "${CUSTOM_PKGCONFIG_PATH}:$ENV{PKG_CONFIG_PATH}")
|
||||
else ()
|
||||
set(CUSTOM_LIB_PATH "/usr/local/lib")
|
||||
set(CUSTOM_PKGCONFIG_PATH "/usr/local/lib/pkgconfig")
|
||||
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CUSTOM_PKGCONFIG_PATH}")
|
||||
endif()
|
||||
|
||||
# foreach(_ IN LISTS CMAKE_PREFIX_PATH)
|
||||
# list(APPEND _qt_pkg_dirs
|
||||
# "${_}/lib/pkgconfig"
|
||||
# "${_}/lib64/pkgconfig"
|
||||
# "${_}/lib64/qt/pkgconfig"
|
||||
# "${_}/lib/qt/pkgconfig"
|
||||
# )
|
||||
# endforeach()
|
||||
|
||||
|
||||
# list(APPEND _qt_pkg_dirs ${CUSTOM_PKGCONFIG_PATH})
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia MultimediaWidgets Network QuickControls2 SerialPort Positioning Location QuickWidgets)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
@@ -110,6 +97,14 @@ add_custom_command(
|
||||
COMMENT "Building idevice-rs FFI libraryy"
|
||||
VERBATIM
|
||||
)
|
||||
elseif(WIN32)
|
||||
add_custom_command(
|
||||
OUTPUT ${IDEVICE_RS_LIB_PATH}
|
||||
COMMAND ${CARGO_EXECUTABLE} +stable-x86_64-pc-windows-gnu build --manifest-path ${IDEVICE_RS_SOURCE_DIR}/Cargo.toml
|
||||
WORKING_DIRECTORY ${IDEVICE_RS_SOURCE_DIR}
|
||||
COMMENT "Building idevice-rs FFI libraryy"
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT ${IDEVICE_RS_LIB_PATH}
|
||||
@@ -150,6 +145,11 @@ file(GLOB PLIST_CPP_SOURCES
|
||||
add_library(idevice_cpp STATIC ${IDEVICE_CPP_SOURCES} ${PLIST_CPP_SOURCES})
|
||||
add_dependencies(idevice_cpp idevice_rs_build)
|
||||
|
||||
if(WIN32)
|
||||
# Define LIBPLIST_STATIC to prevent functions from being marked as DLL imports
|
||||
target_compile_definitions(idevice_cpp PUBLIC LIBPLIST_STATIC)
|
||||
endif()
|
||||
|
||||
target_include_directories(idevice_cpp PUBLIC
|
||||
${IDEVICE_CPP_INCLUDE_DIR}
|
||||
${PLIST_CPP_INCLUDE_DIR}
|
||||
@@ -201,21 +201,6 @@ pkg_check_modules(AVCODEC REQUIRED IMPORTED_TARGET libavcodec)
|
||||
pkg_check_modules(AVUTIL REQUIRED IMPORTED_TARGET libavutil)
|
||||
pkg_check_modules(SWSCALE REQUIRED IMPORTED_TARGET libswscale)
|
||||
|
||||
# if(ENABLE_RECOVERY_DEVICE_SUPPORT)
|
||||
# find_library(IRECOVERY_LIBRARY
|
||||
# NAMES irecovery-1.0
|
||||
# PATHS ${CUSTOM_LIB_PATH}
|
||||
# NO_DEFAULT_PATH
|
||||
# )
|
||||
# if(IRECOVERY_LIBRARY)
|
||||
# message(STATUS "Building with recovery device support enabled")
|
||||
# else()
|
||||
# message(WARNING "libirecovery not found. Recovery device support will be disabled. This is to be expected if you are installing from Arch AUR.")
|
||||
# set(ENABLE_RECOVERY_DEVICE_SUPPORT OFF)
|
||||
# endif()
|
||||
# else()
|
||||
# message(STATUS "Recovery device support disabled")
|
||||
# endif()
|
||||
|
||||
# Add libssh for SSH connections
|
||||
pkg_check_modules(SSH REQUIRED IMPORTED_TARGET libssh)
|
||||
@@ -252,8 +237,10 @@ elseif (WIN32)
|
||||
src/core/services/dnssd/dnssd_service.h
|
||||
)
|
||||
|
||||
file(GLOB WINDOWS_PLATFORM_SOURCES src/platform/windows/*.cpp src/platform/windows/*.h)
|
||||
file(GLOB WINDOWS_PLATFORM_SOURCES src/platform/windows/*.cpp src/platform/windows/*.h src/platform/windows/widgets/*.cpp src/platform/windows/widgets/*.h)
|
||||
list(APPEND PROJECT_SOURCES ${WINDOWS_PLATFORM_SOURCES})
|
||||
list(APPEND PROJECT_SOURCES
|
||||
resources.win.qrc)
|
||||
else()
|
||||
list(APPEND PROJECT_SOURCES
|
||||
src/core/services/avahi/avahi_service.cpp
|
||||
@@ -261,17 +248,6 @@ else()
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT ENABLE_RECOVERY_DEVICE_SUPPORT)
|
||||
list(REMOVE_ITEM PROJECT_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/recoverydeviceinfowidget.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/recoverydeviceinfowidget.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/core/helpers/parse_recovery_mode.cpp
|
||||
src/recoverydeviceinfowidget.cpp
|
||||
src/recoverydeviceinfowidget.h
|
||||
src/core/helpers/parse_recovery_mode.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory(lib/uxplay)
|
||||
add_subdirectory(lib/ipatool-go)
|
||||
add_subdirectory(lib/zupdater)
|
||||
@@ -323,14 +299,8 @@ target_link_libraries(iDescriptor PRIVATE
|
||||
Qt6::Positioning
|
||||
Qt6::QuickWidgets
|
||||
Qt6::QuickControls2
|
||||
# ${IMOBILEDEVICE_LIBRARY}
|
||||
# ${IMOBILEDEVICE_GLUE_LIBRARY}
|
||||
# ${TATSU_LIBRARY}
|
||||
# ${SSL_LIBRARY}
|
||||
# ${CRYPTO_LIBRARY}
|
||||
PkgConfig::SSH
|
||||
${SSH_LIBRARY}
|
||||
# ${USBMUXD_LIBRARY}
|
||||
PkgConfig::PUGIXML
|
||||
# PkgConfig::USB
|
||||
# PkgConfig::PLIST
|
||||
@@ -350,11 +320,6 @@ target_link_libraries(iDescriptor PRIVATE
|
||||
SQLite::SQLite3
|
||||
)
|
||||
|
||||
# # Conditionally link libirecovery
|
||||
# if(ENABLE_RECOVERY_DEVICE_SUPPORT)
|
||||
# target_link_libraries(iDescriptor PRIVATE ${IRECOVERY_LIBRARY})
|
||||
# endif()
|
||||
|
||||
target_include_directories(iDescriptor PRIVATE
|
||||
# Put idevice-rs includes FIRST
|
||||
${IDEVICE_CPP_INCLUDE_DIR}
|
||||
@@ -376,7 +341,7 @@ if(APPLE)
|
||||
${CORE_SERVICES_FRAMEWORK})
|
||||
message(STATUS "Using macOS Bonjour framework for network service discovery")
|
||||
elseif (WIN32)
|
||||
target_link_libraries(iDescriptor PRIVATE PkgConfig::LIBARCHIVE)
|
||||
target_link_libraries(iDescriptor PRIVATE PkgConfig::LIBARCHIVE dwmapi ntdll)
|
||||
find_path(DNSSD_INCLUDE_DIR dns_sd.h HINTS ${BONJOUR_SDK}/Include )
|
||||
# $<$<COMPILE_LANGUAGE:CXX> fixes winres compiler errors
|
||||
target_include_directories(iDescriptor PRIVATE
|
||||
@@ -406,11 +371,6 @@ target_compile_definitions(iDescriptor PRIVATE
|
||||
SOURCE_DIR="${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
# Add compile definition for recovery device support
|
||||
if(ENABLE_RECOVERY_DEVICE_SUPPORT)
|
||||
target_compile_definitions(iDescriptor PRIVATE ENABLE_RECOVERY_DEVICE_SUPPORT)
|
||||
endif()
|
||||
|
||||
if(PACKAGE_MANAGER_MANAGED)
|
||||
target_compile_definitions(iDescriptor PRIVATE PACKAGE_MANAGER_MANAGED)
|
||||
message(STATUS "Building as package manager managed version, updates will be handled by the package manager")
|
||||
@@ -435,14 +395,8 @@ set_target_properties(iDescriptor PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
BUILD_WITH_INSTALL_RPATH TRUE
|
||||
)
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
# Required on Linux to find libirecovery-1.0.so.5 at runtime
|
||||
if (ENABLE_RECOVERY_DEVICE_SUPPORT)
|
||||
set_target_properties(iDescriptor PROPERTIES
|
||||
# Control library search order - system libs first, then /usr/local/lib
|
||||
INSTALL_RPATH "/usr/lib/x86_64-linux-gnu:/usr/lib:/usr/local/lib:$ORIGIN"
|
||||
)
|
||||
endif()
|
||||
# Add install rules for the project
|
||||
# include(GNUInstallDirs)
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>resources/win.dark.qcss</file>
|
||||
<file>resources/win.light.qcss</file>
|
||||
</qresource>
|
||||
<qresource prefix="/">
|
||||
<file>resources/win/dark/CheckBox.png</file>
|
||||
<file>resources/win/dark/CheckBoxPressed.png</file>
|
||||
<file>resources/win/dark/ComboBox.png</file>
|
||||
<file>resources/win/dark/ComboBoxDisabled.png</file>
|
||||
<file>resources/win/dark/NextMonth.png</file>
|
||||
<file>resources/win/dark/NextMonthDisabled.png</file>
|
||||
<file>resources/win/dark/PrevMonth.png</file>
|
||||
<file>resources/win/dark/PrevMonthDisabled.png</file>
|
||||
<file>resources/win/dark/RadioButton.png</file>
|
||||
<file>resources/win/dark/RadioButtonHover.png</file>
|
||||
<file>resources/win/dark/RadioButtonPressed.png</file>
|
||||
<file>resources/win/dark/ScrollBottom.png</file>
|
||||
<file>resources/win/dark/ScrollBottomHover.png</file>
|
||||
<file>resources/win/dark/ScrollBottomPressed.png</file>
|
||||
<file>resources/win/dark/ScrollLeft.png</file>
|
||||
<file>resources/win/dark/ScrollLeftHover.png</file>
|
||||
<file>resources/win/dark/ScrollLeftPressed.png</file>
|
||||
<file>resources/win/dark/ScrollRight.png</file>
|
||||
<file>resources/win/dark/ScrollRightHover.png</file>
|
||||
<file>resources/win/dark/ScrollRightPressed.png</file>
|
||||
<file>resources/win/dark/ScrollTop.png</file>
|
||||
<file>resources/win/dark/ScrollTopHover.png</file>
|
||||
<file>resources/win/dark/ScrollTopPressed.png</file>
|
||||
<file>resources/win/dark/SpinBoxDown.png</file>
|
||||
<file>resources/win/dark/SpinBoxDownDisabled.png</file>
|
||||
<file>resources/win/dark/SpinBoxUp.png</file>
|
||||
<file>resources/win/dark/SpinBoxUpDisabled.png</file>
|
||||
<file>resources/win/dark/ToggleSwitchDisabled.png</file>
|
||||
<file>resources/win/dark/ToggleSwitchOff.png</file>
|
||||
<file>resources/win/dark/ToggleSwitchOffHover.png</file>
|
||||
<file>resources/win/dark/ToggleSwitchOffPressed.png</file>
|
||||
<file>resources/win/dark/ToggleSwitchOn.png</file>
|
||||
<file>resources/win/dark/ToggleSwitchOnHover.png</file>
|
||||
<file>resources/win/dark/ToggleSwitchOnPressed.png</file>
|
||||
<file>resources/win/dark/TreeViewClose.png</file>
|
||||
<file>resources/win/dark/TreeViewOpen.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/">
|
||||
<file>resources/win/light/CheckBox.png</file>
|
||||
<file>resources/win/light/CheckBoxPressed.png</file>
|
||||
<file>resources/win/light/ComboBox.png</file>
|
||||
<file>resources/win/light/ComboBoxDisabled.png</file>
|
||||
<file>resources/win/light/NextMonth.png</file>
|
||||
<file>resources/win/light/NextMonthDisabled.png</file>
|
||||
<file>resources/win/light/PrevMonth.png</file>
|
||||
<file>resources/win/light/PrevMonthDisabled.png</file>
|
||||
<file>resources/win/light/RadioButton.png</file>
|
||||
<file>resources/win/light/RadioButtonHover.png</file>
|
||||
<file>resources/win/light/RadioButtonPressed.png</file>
|
||||
<file>resources/win/light/ScrollBottom.png</file>
|
||||
<file>resources/win/light/ScrollBottomHover.png</file>
|
||||
<file>resources/win/light/ScrollBottomPressed.png</file>
|
||||
<file>resources/win/light/ScrollLeft.png</file>
|
||||
<file>resources/win/light/ScrollLeftHover.png</file>
|
||||
<file>resources/win/light/ScrollLeftPressed.png</file>
|
||||
<file>resources/win/light/ScrollRight.png</file>
|
||||
<file>resources/win/light/ScrollRightHover.png</file>
|
||||
<file>resources/win/light/ScrollRightPressed.png</file>
|
||||
<file>resources/win/light/ScrollTop.png</file>
|
||||
<file>resources/win/light/ScrollTopHover.png</file>
|
||||
<file>resources/win/light/ScrollTopPressed.png</file>
|
||||
<file>resources/win/light/SpinBoxDown.png</file>
|
||||
<file>resources/win/light/SpinBoxDownDisabled.png</file>
|
||||
<file>resources/win/light/SpinBoxUp.png</file>
|
||||
<file>resources/win/light/SpinBoxUpDisabled.png</file>
|
||||
<file>resources/win/light/ToggleSwitchDisabled.png</file>
|
||||
<file>resources/win/light/ToggleSwitchOff.png</file>
|
||||
<file>resources/win/light/ToggleSwitchOffHover.png</file>
|
||||
<file>resources/win/light/ToggleSwitchOffPressed.png</file>
|
||||
<file>resources/win/light/ToggleSwitchOn.png</file>
|
||||
<file>resources/win/light/ToggleSwitchOnHover.png</file>
|
||||
<file>resources/win/light/ToggleSwitchOnPressed.png</file>
|
||||
<file>resources/win/light/TreeViewClose.png</file>
|
||||
<file>resources/win/light/TreeViewOpen.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 273 B |
|
After Width: | Height: | Size: 226 B |
|
After Width: | Height: | Size: 252 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 266 B |
|
After Width: | Height: | Size: 234 B |
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 259 B |
|
After Width: | Height: | Size: 233 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 232 B |
|
After Width: | Height: | Size: 226 B |
|
After Width: | Height: | Size: 225 B |
|
After Width: | Height: | Size: 233 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 235 B |
|
After Width: | Height: | Size: 227 B |
|
After Width: | Height: | Size: 238 B |
|
After Width: | Height: | Size: 236 B |
|
After Width: | Height: | Size: 224 B |
|
After Width: | Height: | Size: 404 B |
|
After Width: | Height: | Size: 642 B |
|
After Width: | Height: | Size: 368 B |
|
After Width: | Height: | Size: 625 B |
|
After Width: | Height: | Size: 329 B |
|
After Width: | Height: | Size: 336 B |
|
After Width: | Height: | Size: 354 B |
|
After Width: | Height: | Size: 356 B |
|
After Width: | Height: | Size: 259 B |
|
After Width: | Height: | Size: 283 B |
|
After Width: | Height: | Size: 278 B |
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 275 B |
|
After Width: | Height: | Size: 215 B |
|
After Width: | Height: | Size: 267 B |
|
After Width: | Height: | Size: 220 B |
|
After Width: | Height: | Size: 252 B |
|
After Width: | Height: | Size: 250 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 234 B |
|
After Width: | Height: | Size: 267 B |
|
After Width: | Height: | Size: 272 B |
|
After Width: | Height: | Size: 239 B |
|
After Width: | Height: | Size: 253 B |
|
After Width: | Height: | Size: 261 B |
|
After Width: | Height: | Size: 235 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 240 B |
|
After Width: | Height: | Size: 222 B |
|
After Width: | Height: | Size: 252 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 221 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 252 B |
|
After Width: | Height: | Size: 225 B |
|
After Width: | Height: | Size: 436 B |
|
After Width: | Height: | Size: 577 B |
|
After Width: | Height: | Size: 403 B |
|
After Width: | Height: | Size: 567 B |
|
After Width: | Height: | Size: 334 B |
|
After Width: | Height: | Size: 329 B |
|
After Width: | Height: | Size: 344 B |
|
After Width: | Height: | Size: 367 B |
|
After Width: | Height: | Size: 272 B |
|
After Width: | Height: | Size: 287 B |
|
After Width: | Height: | Size: 318 B |
|
After Width: | Height: | Size: 291 B |
|
After Width: | Height: | Size: 304 B |
@@ -57,7 +57,7 @@
|
||||
|
||||
#include "diagnosedialog.h"
|
||||
#ifdef WIN32
|
||||
#include "platform/windows/check_deps.h"
|
||||
#include "platform/windows/win_common.h"
|
||||
#endif
|
||||
#include "toolboxwidget.h"
|
||||
|
||||
|
||||
@@ -87,18 +87,23 @@ void AppsWidget::setupUI()
|
||||
|
||||
QWidget *headerWidget = new QWidget();
|
||||
headerWidget->setFixedHeight(60);
|
||||
headerWidget->setStyleSheet("border-bottom: 1px solid #363d32;");
|
||||
headerWidget->setStyleSheet(
|
||||
"border-bottom: 1px solid #363d32; border-radius: 0px;");
|
||||
|
||||
QHBoxLayout *headerLayout = new QHBoxLayout(headerWidget);
|
||||
headerLayout->setContentsMargins(20, 10, 20, 10);
|
||||
|
||||
// Create status label first
|
||||
m_statusLabel = new QLabel("Not signed in");
|
||||
m_statusLabel->setStyleSheet("margin-right: 20px;");
|
||||
m_statusLabel->setStyleSheet("margin-right: 20px; border: none;");
|
||||
|
||||
m_loginButton = new QPushButton();
|
||||
m_searchEdit = new ZLineEdit();
|
||||
m_searchEdit = new QLineEdit();
|
||||
#ifndef WIN32
|
||||
m_searchEdit->setMaximumWidth(350);
|
||||
#else
|
||||
m_searchEdit->setMaximumWidth(200);
|
||||
#endif
|
||||
|
||||
// --- Status and Login Button ---
|
||||
m_manager = AppStoreManager::sharedInstance();
|
||||
@@ -214,7 +219,7 @@ void AppsWidget::handleInit()
|
||||
}
|
||||
/*
|
||||
FIXME: ipatoolinitialze still uses the secure backends
|
||||
when if the user rejects it, the moment he/she tries to sign in
|
||||
even if the user rejects it, the moment he/she tries to sign in
|
||||
prompt(keychain or secret-service whatever the backend is) will be seen
|
||||
again
|
||||
*/
|
||||
@@ -262,10 +267,12 @@ void AppsWidget::onAppStoreInitialized(const QJsonObject &accountInfo)
|
||||
}
|
||||
|
||||
m_loginButton->setText(m_isLoggedIn ? "Sign Out" : "Sign In");
|
||||
#ifndef WIN32
|
||||
m_loginButton->setStyleSheet(
|
||||
"background-color: #007AFF; color: white; border: none; "
|
||||
"border-radius: "
|
||||
"4px; padding: 8px 16px; font-size: 14px;");
|
||||
#endif
|
||||
m_searchEdit->setPlaceholderText(m_isLoggedIn ? "Search for apps..."
|
||||
: "Sign in to search");
|
||||
}
|
||||
@@ -638,8 +645,9 @@ void AppsWidget::createAppCard(
|
||||
ZLabel *installLabel = new ZLabel("Install");
|
||||
installLabel->setAlignment(Qt::AlignCenter);
|
||||
installLabel->setStyleSheet(
|
||||
"font-size: 12px; color: #007AFF; font-weight: "
|
||||
"bold; background-color: transparent;");
|
||||
QString("font-size: 12px; color: %1; font-weight: "
|
||||
"bold; background-color: transparent;")
|
||||
.arg(COLOR_ACCENT_BLUE.name()));
|
||||
installLabel->setCursor(Qt::PointingHandCursor);
|
||||
installLabel->setFixedHeight(30);
|
||||
|
||||
|
||||
@@ -18,8 +18,16 @@
|
||||
*/
|
||||
|
||||
#include "tool.h"
|
||||
#ifdef WIN32
|
||||
#include "../platform/windows/widgets/wintoolwidget.h"
|
||||
#include "../platform/windows/win_common.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
Tool::Tool(QWidget *parent) : WinToolWidget(parent)
|
||||
#else
|
||||
Tool::Tool(QWidget *parent) : QWidget(parent)
|
||||
#endif
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
setupToolFrame(this);
|
||||
|
||||
@@ -26,7 +26,16 @@
|
||||
#include "../platform/macos/macos.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include "../platform/windows/widgets/wintoolwidget.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
class Tool : public WinToolWidget
|
||||
#else
|
||||
class Tool : public QWidget
|
||||
#endif
|
||||
|
||||
{
|
||||
public:
|
||||
explicit Tool(QWidget *parent = nullptr);
|
||||
|
||||
@@ -81,7 +81,7 @@ void CableInfoWidget::setupUI()
|
||||
m_loadingWidget = new ZLoadingWidget(true, this);
|
||||
m_loadingWidget->setupContentWidget(m_mainLayout);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(contentWidget());
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(m_loadingWidget);
|
||||
|
||||
@@ -230,7 +230,7 @@ void CableInfoWidget::updateUI()
|
||||
if (!m_cableInfo.isConnected) {
|
||||
m_errorLabel->setText(
|
||||
QString("%1 does not seem to be connected to any cable.")
|
||||
.arg(m_device->deviceInfo.productType));
|
||||
.arg(QString::fromStdString(m_device->deviceInfo.productType)));
|
||||
m_loadingWidget->showError();
|
||||
return;
|
||||
}
|
||||
@@ -243,13 +243,13 @@ void CableInfoWidget::updateUI()
|
||||
"absolute guarantee of authenticity.");
|
||||
if (m_cableInfo.isGenuine) {
|
||||
// todo: type-c to type-c
|
||||
statusText = QString("✅ Genuine %1")
|
||||
statusText = QString("Genuine %1")
|
||||
.arg(m_cableInfo.isTypeC ? "USB-C to Lightning Cable"
|
||||
: "Lightning Cable");
|
||||
statusStyle =
|
||||
"QLabel { color: #28a745; font-size: 18px; font-weight: bold; }";
|
||||
} else {
|
||||
statusText = "⚠️ Third-party Cable";
|
||||
statusText = "Third-party Cable";
|
||||
statusStyle =
|
||||
"QLabel { color: #dc3545; font-size: 18px; font-weight: bold; }";
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ void get_device_info_xml(const char *udid, LockdowndClientHandle *client,
|
||||
|
||||
if (xml_string) {
|
||||
infoXml.load_string(xml_string);
|
||||
free(xml_string);
|
||||
// FIXME: crashes on Windows
|
||||
// free(xml_string);
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,18 @@
|
||||
#endif
|
||||
#include "../../heartbeat.h"
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "../../platform/windows/win_common.h"
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
std::string safeGetXML(const char *key, pugi::xml_node dict)
|
||||
{
|
||||
@@ -453,7 +459,7 @@ void init_idescriptor_device(const iDescriptor::Uniq &uniq,
|
||||
heartbeatThread->start();
|
||||
|
||||
while (!heartbeatThread->initialCompleted()) {
|
||||
sleep(1);
|
||||
// sleep(1);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "iDescriptor.h"
|
||||
#include "infolabel.h"
|
||||
#include "privateinfolabel.h"
|
||||
// #include "toolboxwidget.h"
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
@@ -146,13 +145,14 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
|
||||
m_chargingStatusLabel =
|
||||
new QLabel(device->deviceInfo.batteryInfo.isCharging ? "Charging"
|
||||
: "Not Charging");
|
||||
|
||||
m_chargingStatusLabel->setStyleSheet(
|
||||
device->deviceInfo.batteryInfo.isCharging
|
||||
? QString("color: %1;").arg(COLOR_GREEN.name())
|
||||
: QString("color: %1;")
|
||||
.arg(qApp->palette().color(QPalette::WindowText).name()));
|
||||
|
||||
m_chargingStatusLabel->setObjectName("ChargingStatusLabel");
|
||||
m_chargingStatusLabel->setStyleSheet(mergeStyles(
|
||||
m_chargingStatusLabel,
|
||||
(device->deviceInfo.batteryInfo.isCharging
|
||||
? QString("QLabel#ChargingStatusLabel { color: %1; }")
|
||||
.arg(COLOR_GREEN.name())
|
||||
: QString("QLabel#ChargingStatusLabel { color: %1; }")
|
||||
.arg(qApp->palette().color(QPalette::WindowText).name()))));
|
||||
// Create the layout without a parent widget
|
||||
QHBoxLayout *chargingLayout = new QHBoxLayout();
|
||||
chargingLayout->setContentsMargins(0, 0, 0, 0);
|
||||
@@ -314,7 +314,11 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
|
||||
for (int i = 0; i < numRows; ++i) {
|
||||
// Left column item
|
||||
QLabel *keyLabelLeft = new QLabel(infoItems[i].first);
|
||||
#ifndef WIN32
|
||||
keyLabelLeft->setStyleSheet("font-weight: bold;");
|
||||
#else
|
||||
keyLabelLeft->setStyleSheet("font-size: 15px; font-weight: 500;");
|
||||
#endif
|
||||
gridLayout->addWidget(keyLabelLeft, i, 0);
|
||||
gridLayout->addWidget(infoItems[i].second, i, 1);
|
||||
|
||||
@@ -322,7 +326,11 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
|
||||
int rightIndex = i + numRows;
|
||||
if (rightIndex < infoItems.size()) {
|
||||
QLabel *keyLabelRight = new QLabel(infoItems[rightIndex].first);
|
||||
#ifndef WIN32
|
||||
keyLabelRight->setStyleSheet("font-weight: bold;");
|
||||
#else
|
||||
keyLabelRight->setStyleSheet("font-size: 15px; font-weight: 500;");
|
||||
#endif
|
||||
gridLayout->addWidget(keyLabelRight, i, 2);
|
||||
gridLayout->addWidget(infoItems[rightIndex].second, i, 3);
|
||||
}
|
||||
@@ -348,8 +356,6 @@ DeviceInfoWidget::DeviceInfoWidget(iDescriptorDevice *device, QWidget *parent)
|
||||
rightSideLayout->addWidget(new DiskUsageWidget(device, this));
|
||||
|
||||
rightSideLayout->addStretch();
|
||||
// // TODO: layout shift cause ?
|
||||
// // rightSideLayout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
mainLayout->addLayout(rightSideLayout);
|
||||
mainLayout->addStretch();
|
||||
@@ -420,4 +426,4 @@ void DeviceInfoWidget::updateChargingStatusIcon()
|
||||
// m_chargingStatusLabel->setStyleSheet("");
|
||||
// m_lightningIconLabel->hide();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ DeviceSidebarItem::DeviceSidebarItem(const QString &deviceName,
|
||||
setFrameStyle(QFrame::StyledPanel);
|
||||
setLineWidth(1);
|
||||
updateToggleButton();
|
||||
setObjectName("DeviceSidebarItem");
|
||||
}
|
||||
|
||||
void DeviceSidebarItem::setupUI()
|
||||
@@ -59,7 +60,9 @@ void DeviceSidebarItem::setupUI()
|
||||
QHBoxLayout *nameLayout = new QHBoxLayout();
|
||||
nameLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_deviceLabel = new QLabel(m_deviceName);
|
||||
#ifndef WIN32
|
||||
m_deviceLabel->setStyleSheet("QLabel { font-weight: bold; }");
|
||||
#endif
|
||||
m_deviceLabel->setWordWrap(true);
|
||||
nameLayout->addWidget(m_deviceLabel);
|
||||
if (m_wireless) {
|
||||
@@ -78,6 +81,9 @@ void DeviceSidebarItem::setupUI()
|
||||
m_toggleButton->setStyleSheet("QPushButton { "
|
||||
" text-align: left; "
|
||||
" padding: 2px 5px; "
|
||||
#ifdef WIN32
|
||||
" min-height: 0; "
|
||||
#endif
|
||||
" border: none; "
|
||||
" color: #666; "
|
||||
" font-size: 11px; "
|
||||
@@ -121,6 +127,9 @@ void DeviceSidebarItem::setupUI()
|
||||
QString("QPushButton { "
|
||||
" background-color: rgba(255, 255, 255, 120); "
|
||||
" border: 1px solid rgba(255, 255, 255, 200); "
|
||||
#ifdef WIN32
|
||||
" min-height: 0; "
|
||||
#endif
|
||||
" padding: 4px 8px; "
|
||||
" text-align: center; "
|
||||
" border-radius: 6px; "
|
||||
@@ -159,7 +168,20 @@ void DeviceSidebarItem::setupUI()
|
||||
setSelected(false);
|
||||
}
|
||||
|
||||
void DeviceSidebarItem::setSelected(bool selected) { m_selected = selected; }
|
||||
void DeviceSidebarItem::setSelected(bool selected)
|
||||
{
|
||||
m_selected = selected;
|
||||
|
||||
if (selected) {
|
||||
setStyleSheet(
|
||||
"QFrame#DeviceSidebarItem { background-color: rgba(255, "
|
||||
"255, 255, 45); }");
|
||||
} else {
|
||||
setStyleSheet(
|
||||
"QFrame#DeviceSidebarItem { background-color: rgba(255, "
|
||||
"255, 255, 16); }");
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSidebarItem::setCollapsed(bool collapsed)
|
||||
{
|
||||
@@ -452,68 +474,70 @@ void DevicePendingSidebarItem::mousePressEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
// FIXME: better move this to a separate file
|
||||
void DeviceSidebarItem::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
// void DeviceSidebarItem::paintEvent(QPaintEvent *event)
|
||||
// {
|
||||
// Q_UNUSED(event);
|
||||
|
||||
QPainter p(this);
|
||||
p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
// QPainter p(this);
|
||||
// p.setRenderHints(QPainter::Antialiasing |
|
||||
// QPainter::SmoothPixmapTransform);
|
||||
|
||||
const qreal dpr = devicePixelRatioF();
|
||||
const int w = width();
|
||||
const int h = height();
|
||||
const int sw = int(w * dpr);
|
||||
const int sh = int(h * dpr);
|
||||
// const qreal dpr = devicePixelRatioF();
|
||||
// const int w = width();
|
||||
// const int h = height();
|
||||
// const int sw = int(w * dpr);
|
||||
// const int sh = int(h * dpr);
|
||||
|
||||
constexpr int kCornerRadius = 10;
|
||||
constexpr int kBlurRadius = 2;
|
||||
// constexpr int kCornerRadius = 10;
|
||||
// constexpr int kBlurRadius = 2;
|
||||
|
||||
// Cache the blurred background per size
|
||||
static QPixmap cachedBg;
|
||||
static QSize cachedSize;
|
||||
// // Cache the blurred background per size
|
||||
// static QPixmap cachedBg;
|
||||
// static QSize cachedSize;
|
||||
|
||||
const QSize cacheSize(sw, sh);
|
||||
if (cachedSize != cacheSize) {
|
||||
cachedSize = cacheSize;
|
||||
// const QSize cacheSize(sw, sh);
|
||||
// if (cachedSize != cacheSize) {
|
||||
// cachedSize = cacheSize;
|
||||
|
||||
QPixmap gradPm(sw, sh);
|
||||
gradPm.fill(Qt::transparent);
|
||||
{
|
||||
QPainter gp(&gradPm);
|
||||
gp.setRenderHints(QPainter::Antialiasing |
|
||||
QPainter::SmoothPixmapTransform);
|
||||
// QPixmap gradPm(sw, sh);
|
||||
// gradPm.fill(Qt::transparent);
|
||||
// {
|
||||
// QPainter gp(&gradPm);
|
||||
// gp.setRenderHints(QPainter::Antialiasing |
|
||||
// QPainter::SmoothPixmapTransform);
|
||||
|
||||
QLinearGradient grad(0, 0, 1, 1);
|
||||
grad.setCoordinateMode(QGradient::ObjectMode);
|
||||
grad.setStops({{0.0, QColor(255, 255, 255, 255)},
|
||||
{0.35, QColor(255, 255, 255, 125)},
|
||||
{0.65, QColor(255, 255, 255, 125)},
|
||||
{1.0, QColor(255, 255, 255, 255)}});
|
||||
// QLinearGradient grad(0, 0, 1, 1);
|
||||
// grad.setCoordinateMode(QGradient::ObjectMode);
|
||||
// grad.setStops({{0.0, QColor(255, 255, 255, 255)},
|
||||
// {0.35, QColor(255, 255, 255, 125)},
|
||||
// {0.65, QColor(255, 255, 255, 125)},
|
||||
// {1.0, QColor(255, 255, 255, 255)}});
|
||||
|
||||
gp.fillRect(QRectF(0, 0, sw, sh), grad);
|
||||
}
|
||||
// gp.fillRect(QRectF(0, 0, sw, sh), grad);
|
||||
// }
|
||||
|
||||
QPixmap blurred = BackDrop::blurPixmap(gradPm, kBlurRadius);
|
||||
// QPixmap blurred = BackDrop::blurPixmap(gradPm, kBlurRadius);
|
||||
|
||||
QPixmap mask = BackDrop::getColoredPixmap(
|
||||
QBrush(Qt::white), Qt::white, 1, sw, sh, int(kCornerRadius * dpr));
|
||||
// QPixmap mask = BackDrop::getColoredPixmap(
|
||||
// QBrush(Qt::white), Qt::white, 1, sw, sh, int(kCornerRadius *
|
||||
// dpr));
|
||||
|
||||
BackDrop::cutPixmap(blurred, mask, sw, sh);
|
||||
// BackDrop::cutPixmap(blurred, mask, sw, sh);
|
||||
|
||||
blurred.setDevicePixelRatio(dpr);
|
||||
cachedBg = blurred;
|
||||
}
|
||||
// blurred.setDevicePixelRatio(dpr);
|
||||
// cachedBg = blurred;
|
||||
// }
|
||||
|
||||
QPainterPath clipPath;
|
||||
QRectF r = rect().adjusted(0.5, 0.5, -0.5, -0.5);
|
||||
clipPath.addRoundedRect(r, kCornerRadius, kCornerRadius);
|
||||
p.setClipPath(clipPath);
|
||||
p.drawPixmap(r.toRect(), cachedBg);
|
||||
// QPainterPath clipPath;
|
||||
// QRectF r = rect().adjusted(0.5, 0.5, -0.5, -0.5);
|
||||
// clipPath.addRoundedRect(r, kCornerRadius, kCornerRadius);
|
||||
// p.setClipPath(clipPath);
|
||||
// p.drawPixmap(r.toRect(), cachedBg);
|
||||
|
||||
p.setClipping(false);
|
||||
QColor borderColor = m_selected ? COLOR_BLUE : QColor("#FFFFFF");
|
||||
QPen pen(borderColor, m_selected ? 2.0 : 1.0);
|
||||
p.setPen(pen);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawRoundedRect(r, kCornerRadius, kCornerRadius);
|
||||
}
|
||||
// p.setClipping(false);
|
||||
// QColor borderColor = m_selected ? COLOR_BLUE : QColor("#FFFFFF");
|
||||
// QPen pen(borderColor, m_selected ? 2.0 : 1.0);
|
||||
// p.setPen(pen);
|
||||
// p.setBrush(Qt::NoBrush);
|
||||
// p.drawRoundedRect(r, kCornerRadius, kCornerRadius);
|
||||
// }
|
||||
@@ -45,8 +45,8 @@ public:
|
||||
void setCollapsed(bool collapsed);
|
||||
bool isCollapsed() const { return m_collapsed; }
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
// protected:
|
||||
// void paintEvent(QPaintEvent *event) override;
|
||||
signals:
|
||||
void deviceSelected(const std::string &uuid);
|
||||
void navigationRequested(const std::string &uuid, const QString §ion);
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
|
||||
#include "diagnosewidget.h"
|
||||
#ifdef WIN32
|
||||
#include "platform/windows/check_deps.h"
|
||||
#include "platform/windows/win_common.h"
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
#endif
|
||||
#include "iDescriptor-ui.h"
|
||||
#include <QApplication>
|
||||
#include <QCoreApplication>
|
||||
#include <QCryptographicHash>
|
||||
@@ -97,21 +98,37 @@ void DependencyItem::setInstalled(bool installed)
|
||||
|
||||
if (installed) {
|
||||
if (m_name == "Avahi Daemon") {
|
||||
m_statusLabel->setText("✓ Activated");
|
||||
m_statusLabel->setText("Activated");
|
||||
} else {
|
||||
m_statusLabel->setText("✓ Installed");
|
||||
m_statusLabel->setText("Installed");
|
||||
}
|
||||
m_statusLabel->setStyleSheet("color: green; font-weight: bold;");
|
||||
#ifndef WIN32
|
||||
m_statusLabel->setStyleSheet("color: green;");
|
||||
#else
|
||||
// FIXME: if we call this multiple times, the styles will keep stacking
|
||||
// and become a mess, need a better way to handle this
|
||||
m_statusLabel->setStyleSheet(mergeStyles(
|
||||
m_statusLabel,
|
||||
QString("QLabel { color: %1; }").arg(COLOR_GREEN.name())));
|
||||
#endif
|
||||
m_installButton->setVisible(false);
|
||||
} else {
|
||||
if (m_name == "Avahi Daemon") {
|
||||
m_statusLabel->setText("✗ Not activated");
|
||||
m_statusLabel->setText("Not activated");
|
||||
m_installButton->setText("Enable");
|
||||
} else {
|
||||
m_statusLabel->setText("✗ Not Installed");
|
||||
m_statusLabel->setText("Not Installed");
|
||||
m_installButton->setText("Install");
|
||||
}
|
||||
m_statusLabel->setStyleSheet("color: red; font-weight: bold;");
|
||||
#ifndef WIN32
|
||||
m_statusLabel->setStyleSheet("color: red;");
|
||||
#else
|
||||
// FIXME: if we call this multiple times, the styles will keep stacking
|
||||
// and become a mess, need a better way to handle this
|
||||
m_statusLabel->setStyleSheet(mergeStyles(
|
||||
m_statusLabel,
|
||||
QString("QLabel { color: %1; }").arg(COLOR_RED.name())));
|
||||
#endif
|
||||
m_installButton->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,22 +143,25 @@ void DiskUsageWidget::setupUI()
|
||||
// Set colors
|
||||
m_systemBar->setStyleSheet(
|
||||
"QWidget#systemBar { background-color: #a1384d; border: 1px solid"
|
||||
"#e64a5b; padding: 0; margin: 0; border-top-left-radius: 3px; "
|
||||
"#e64a5b; padding: 0; margin: 0; border-radius:0px; "
|
||||
"border-top-left-radius: 3px; "
|
||||
"border-bottom-left-radius: 3px; }");
|
||||
m_appsBar->setStyleSheet(
|
||||
"QWidget#appsBar { background-color: #4f869f; border: 1px solid "
|
||||
"#63b4da; padding: 0; margin: 0; }");
|
||||
"#63b4da; border-radius:0px; padding: 0; margin: 0; }");
|
||||
m_mediaBar->setStyleSheet("QWidget#mediaBar { background-color: #2ECC71; "
|
||||
"border: none; padding: 0; margin: 0; }");
|
||||
m_galleryBar->setStyleSheet(
|
||||
"QWidget#galleryBar { background-color: #9b59b6; border: 1px solid "
|
||||
"#8e44ad; padding: 0; margin: 0; }");
|
||||
"#8e44ad; border-radius:0px; padding: 0; margin: 0; }");
|
||||
m_othersBar->setStyleSheet(
|
||||
"QWidget#othersBar { background-color: #a28729; border: 1px solid "
|
||||
"#c4a32d; padding: 0; margin: 0; }");
|
||||
"#c4a32d; border-radius:0px; padding: 0; margin: 0; }");
|
||||
m_freeBar->setStyleSheet(
|
||||
"QWidget#freeBar { background-color: #474747; border: 1px solid "
|
||||
"#4f4f4f; padding: 0; margin: 0; border-top-right-radius: 3px; "
|
||||
"QWidget#freeBar { background-color: rgba(255, 255, 255, 10); border: "
|
||||
"1px solid "
|
||||
"#4f4f4f4f; padding: 0; margin: 0; border-radius:0px; "
|
||||
"border-top-right-radius: 3px; "
|
||||
"border-bottom-right-radius: 3px; }");
|
||||
|
||||
// remove padding margin from layout
|
||||
|
||||
@@ -239,12 +239,12 @@ QString HttpServer::generateJsonManifest() const
|
||||
|
||||
QString HttpServer::getLocalIP() const
|
||||
{
|
||||
foreach (const QNetworkInterface &interface,
|
||||
foreach (const QNetworkInterface &netIf,
|
||||
QNetworkInterface::allInterfaces()) {
|
||||
if (interface.flags().testFlag(QNetworkInterface::IsUp) &&
|
||||
!interface.flags().testFlag(QNetworkInterface::IsLoopBack)) {
|
||||
if (netIf.flags().testFlag(QNetworkInterface::IsUp) &&
|
||||
!netIf.flags().testFlag(QNetworkInterface::IsLoopBack)) {
|
||||
foreach (const QNetworkAddressEntry &entry,
|
||||
interface.addressEntries()) {
|
||||
netIf.addressEntries()) {
|
||||
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
|
||||
return entry.ip().toString();
|
||||
}
|
||||
|
||||
@@ -40,13 +40,35 @@
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "./platform/macos/macos.h"
|
||||
#elif defined(WIN32)
|
||||
#include "./platform/windows/win_common.h"
|
||||
#endif
|
||||
|
||||
#define COLOR_GREEN QColor(0, 180, 0) // Green
|
||||
#define COLOR_ORANGE QColor(255, 140, 0) // Orange
|
||||
#define COLOR_RED QColor(255, 0, 0) // Red
|
||||
#define COLOR_BLUE QColor("#2b5693")
|
||||
|
||||
#ifndef WIN32
|
||||
#define COLOR_ACCENT_BLUE QColor("#0b5ed7")
|
||||
#define COLOR_HYPERLINK QColor(0, 122, 255)
|
||||
#else
|
||||
#define COLOR_ACCENT_BLUE QColor(getWindowsAccentColor())
|
||||
#define COLOR_HYPERLINK QColor("#FF7FFFD4")
|
||||
#endif
|
||||
|
||||
inline QString mergeStyles(QWidget *widget, const QString &newStyles)
|
||||
{
|
||||
if (!widget) {
|
||||
return newStyles;
|
||||
}
|
||||
QString existing = widget->styleSheet();
|
||||
if (existing.isEmpty())
|
||||
return newStyles;
|
||||
|
||||
return existing + "\n" + newStyles;
|
||||
}
|
||||
|
||||
#define MIN_MAIN_WINDOW_SIZE QSize(900, 600)
|
||||
|
||||
class ResponsiveGraphicsView : public QGraphicsView
|
||||
|
||||
@@ -355,7 +355,7 @@ public:
|
||||
plist_get_string_val(current_node, &value);
|
||||
std::string result = value ? value : "";
|
||||
if (value)
|
||||
free(value);
|
||||
plist_mem_free(value);
|
||||
return result;
|
||||
}
|
||||
plist_t getNode() const { return current_node; }
|
||||
@@ -605,10 +605,12 @@ inline void free_directory_listing(char **entries, size_t count)
|
||||
return;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (entries[i]) {
|
||||
free(entries[i]);
|
||||
// FIXME: crashes on Windows
|
||||
// free(entries[i]);
|
||||
}
|
||||
}
|
||||
free(entries);
|
||||
// FIXME: crashes on Windows
|
||||
// free(entries);
|
||||
}
|
||||
|
||||
inline int read_file(const char *filename, uint8_t **data, size_t *length)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <QStatusBar>
|
||||
#include <QTimer>
|
||||
#ifdef WIN32
|
||||
#include "platform/windows/check_deps.h"
|
||||
#include "platform/windows/win_common.h"
|
||||
#endif
|
||||
|
||||
iFuseWidget::iFuseWidget(iDescriptorDevice *device, QWidget *parent)
|
||||
|
||||
@@ -29,9 +29,7 @@ InfoLabel::InfoLabel(const QString &text, const QString &textToCopy,
|
||||
m_textToCopy(!textToCopy.isEmpty() ? textToCopy : text)
|
||||
{
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, 0.1); "
|
||||
"border-radius: 2px; }");
|
||||
|
||||
setStyleSheet(m_style);
|
||||
m_restoreTimer = new QTimer(this);
|
||||
m_restoreTimer->setSingleShot(true);
|
||||
connect(m_restoreTimer, &QTimer::timeout, this,
|
||||
@@ -49,39 +47,26 @@ void InfoLabel::mousePressEvent(QMouseEvent *event)
|
||||
// prevent layout shifts
|
||||
setMinimumWidth(originalWidth);
|
||||
setText("Copied!");
|
||||
#ifdef WIN32
|
||||
setStyleSheet(QStringLiteral(
|
||||
"QLabel { color: #4CAF50; font-weight: bold; font-size: 14px; }"
|
||||
"QLabel:hover { background-color: rgba(255, 255, 255, 0.1); "
|
||||
"border-radius: 2px; }"));
|
||||
#else
|
||||
setStyleSheet("QLabel { color: #4CAF50; font-weight: bold; } "
|
||||
"QLabel:hover { background-color: rgba(255, 255, 255, "
|
||||
"0.1); border-radius: 2px; }");
|
||||
|
||||
#endif
|
||||
m_restoreTimer->start(1000); // Show "Copied!" for 1 second
|
||||
}
|
||||
QLabel::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void InfoLabel::enterEvent(QEnterEvent *event)
|
||||
{
|
||||
if (!m_restoreTimer->isActive()) {
|
||||
setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, "
|
||||
"0.1); border-radius: 2px; }");
|
||||
}
|
||||
QLabel::enterEvent(event);
|
||||
}
|
||||
|
||||
void InfoLabel::leaveEvent(QEvent *event)
|
||||
{
|
||||
if (!m_restoreTimer->isActive()) {
|
||||
setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, "
|
||||
"0.1); border-radius: 2px; }");
|
||||
}
|
||||
QLabel::leaveEvent(event);
|
||||
}
|
||||
|
||||
void InfoLabel::restoreOriginalText()
|
||||
{
|
||||
setText(m_originalText);
|
||||
setMinimumWidth(0);
|
||||
setStyleSheet("QLabel:hover { background-color: rgba(255, 255, 255, 0.1); "
|
||||
"border-radius: 2px; }");
|
||||
setStyleSheet(m_style);
|
||||
}
|
||||
|
||||
void InfoLabel::setOriginalText(const QString &text) { m_originalText = text; }
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define INFOLABEL_H
|
||||
|
||||
#include <QLabel>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
|
||||
class InfoLabel : public QLabel
|
||||
@@ -37,8 +38,6 @@ public:
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void enterEvent(QEnterEvent *event) override;
|
||||
void leaveEvent(QEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void restoreOriginalText();
|
||||
@@ -47,6 +46,18 @@ private:
|
||||
QString m_originalText;
|
||||
QString m_textToCopy;
|
||||
QTimer *m_restoreTimer;
|
||||
QString m_style =
|
||||
#ifdef WIN32
|
||||
QStringLiteral(
|
||||
"QLabel:hover { background-color: rgba(255, 255, 255, 0.1); "
|
||||
"border-radius: 2px; }"
|
||||
"QLabel { "
|
||||
"font-size: 14px;}");
|
||||
#else
|
||||
QStringLiteral(
|
||||
"QLabel:hover { background-color: rgba(255, 255, 255, 0.1); "
|
||||
"border-radius: 2px; }");
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // INFOLABEL_H
|
||||
@@ -322,7 +322,7 @@ void InstalledAppsWidget::fetchInstalledApps()
|
||||
plist_get_string_val(bundle_id, &bundle_id_str);
|
||||
if (bundle_id_str) {
|
||||
appData["bundleId"] = QString(bundle_id_str);
|
||||
free(bundle_id_str);
|
||||
plist_mem_free(bundle_id_str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ void InstalledAppsWidget::fetchInstalledApps()
|
||||
if (display_name_str) {
|
||||
appData["displayName"] =
|
||||
QString(display_name_str);
|
||||
free(display_name_str);
|
||||
plist_mem_free(display_name_str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ void InstalledAppsWidget::fetchInstalledApps()
|
||||
plist_get_string_val(version, &version_str);
|
||||
if (version_str) {
|
||||
appData["version"] = QString(version_str);
|
||||
free(version_str);
|
||||
plist_mem_free(version_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,20 @@
|
||||
#include <QVBoxLayout>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "platform/windows/win_common.h"
|
||||
#endif
|
||||
|
||||
LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
setWindowTitle("Login to App Store - iDescriptor");
|
||||
setModal(true);
|
||||
setFixedWidth(400);
|
||||
|
||||
#ifdef WIN32
|
||||
setupWinWindow(this);
|
||||
#endif
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setSpacing(15);
|
||||
layout->setContentsMargins(20, 20, 20, 20);
|
||||
@@ -47,8 +55,11 @@ LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent)
|
||||
|
||||
m_emailEdit = new QLineEdit();
|
||||
m_emailEdit->setPlaceholderText("Enter your email");
|
||||
#ifndef WIN32
|
||||
m_emailEdit->setStyleSheet("padding: 8px; border: 1px solid #ddd; "
|
||||
"border-radius: 4px; font-size: 14px;");
|
||||
#endif
|
||||
|
||||
layout->addWidget(m_emailEdit);
|
||||
|
||||
// Password
|
||||
@@ -59,33 +70,35 @@ LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent)
|
||||
m_passwordEdit = new QLineEdit();
|
||||
m_passwordEdit->setPlaceholderText("Enter your password");
|
||||
m_passwordEdit->setEchoMode(QLineEdit::Password);
|
||||
#ifndef WIN32
|
||||
m_passwordEdit->setStyleSheet("padding: 8px; border: 1px solid #ddd; "
|
||||
"border-radius: 4px; font-size: 14px;");
|
||||
#endif
|
||||
layout->addWidget(m_passwordEdit);
|
||||
|
||||
// Description
|
||||
QLabel *descriptionLabel =
|
||||
new QLabel("Don't worry, your credentials won't be "
|
||||
"stored or shared anywhere. This App is open-source.");
|
||||
QLabel *descriptionLabel = new QLabel(
|
||||
"You shouldn't be using your main account here and don't worry, "
|
||||
"your credentials won't be "
|
||||
"stored or shared anywhere. This App is open-source.");
|
||||
descriptionLabel->setStyleSheet("font-size: 10px; font-weight: thin;");
|
||||
descriptionLabel->setAlignment(Qt::AlignLeft);
|
||||
descriptionLabel->setWordWrap(true); // Add this line
|
||||
descriptionLabel->setWordWrap(true);
|
||||
layout->addWidget(descriptionLabel);
|
||||
|
||||
// --- Buttons and Indicator ---
|
||||
// Create a container widget for the sign-in button and the indicator
|
||||
QWidget *signInContainer = new QWidget(this);
|
||||
m_signInStackedLayout = new QStackedLayout(signInContainer);
|
||||
m_signInStackedLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
// Create the actual "Sign In" button
|
||||
m_signInButton = new QPushButton("Sign In");
|
||||
#ifndef WIN32
|
||||
m_signInButton->setStyleSheet(
|
||||
"QPushButton { padding: 8px 16px; font-size: 14px; border-radius: 4px; "
|
||||
"background-color: #007AFF; color: white; border: none; min-width: "
|
||||
"80px; }"
|
||||
"QPushButton:hover { background-color: #0056CC; }");
|
||||
|
||||
#endif
|
||||
// Create the indicator
|
||||
QWidget *indicatorWidget = new QWidget();
|
||||
QVBoxLayout *indicatorLayout = new QVBoxLayout(indicatorWidget);
|
||||
@@ -103,15 +116,15 @@ LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent)
|
||||
// Ensure the container has the same size as the button
|
||||
signInContainer->setFixedSize(m_signInButton->sizeHint());
|
||||
|
||||
// Create the "Cancel" button
|
||||
m_cancelButton = new QPushButton("Cancel");
|
||||
// add disabled style to cancel button
|
||||
#ifndef WIN32
|
||||
m_cancelButton->setStyleSheet(
|
||||
"QPushButton { padding: 8px 16px; font-size: 14px; border-radius: 4px; "
|
||||
"background-color: #f0f0f0; color: #333; border: 1px solid #ddd; "
|
||||
"min-width: 80px; }"
|
||||
"QPushButton:disabled { background-color: #eee; color: #aaa; border: "
|
||||
"1px solid #ddd; }");
|
||||
#endif
|
||||
|
||||
// Layout for the buttons
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout();
|
||||
|
||||
@@ -23,14 +23,15 @@
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QStyleFactory>
|
||||
#include <QtGlobal>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "platform/windows/check_deps.h"
|
||||
#include "platform/windows/win_common.h"
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
@@ -45,6 +46,15 @@ int main(int argc, char *argv[])
|
||||
// " "their default values.");
|
||||
// }
|
||||
#ifdef WIN32
|
||||
QFile styleFile(detectDarkModeWindows() ? ":/resources/win.dark.qcss"
|
||||
: ":/resources/win.light.qcss");
|
||||
if (styleFile.open(QFile::ReadOnly | QFile::Text)) {
|
||||
const QString style = QString::fromUtf8(styleFile.readAll())
|
||||
.arg(COLOR_ACCENT_BLUE.name());
|
||||
qDebug() << "Loaded Windows style sheet successfully.";
|
||||
a.setStyleSheet(style);
|
||||
}
|
||||
|
||||
QString appPath = QCoreApplication::applicationDirPath();
|
||||
QString gstPluginPath =
|
||||
QDir::toNativeSeparators(appPath + "/gstreamer-1.0");
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "./ui_mainwindow.h"
|
||||
#include "appswidget.h"
|
||||
#include "devicemanagerwidget.h"
|
||||
#include "iDescriptor-ui.h"
|
||||
@@ -26,9 +25,6 @@
|
||||
#include "ifusediskunmountbutton.h"
|
||||
#include "ifusemanager.h"
|
||||
#include "jailbrokenwidget.h"
|
||||
// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
|
||||
// #include "libirecovery.h"
|
||||
// #endif
|
||||
#include "toolboxwidget.h"
|
||||
#include "welcomewidget.h"
|
||||
#include <QHBoxLayout>
|
||||
@@ -51,112 +47,38 @@
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "platform/windows/check_deps.h"
|
||||
#include "platform/windows/win_common.h"
|
||||
#endif
|
||||
|
||||
using namespace IdeviceFFI;
|
||||
|
||||
// void handleCallback(const idevice_event_t *event, void *userData)
|
||||
// {
|
||||
// printf("Device event received: ");
|
||||
|
||||
// switch (event->event) {
|
||||
// case IDEVICE_DEVICE_ADD: {
|
||||
// /* this should never happen iDescriptor does not support network
|
||||
// devices but for some reason even though we are only listening for USB
|
||||
// devices, we still get network devices on macOS*/ if (event->conn_type
|
||||
// == CONNECTION_NETWORK) {
|
||||
// return;
|
||||
// }
|
||||
// qDebug() << "Device added: " << QString::fromUtf8(event->udid);
|
||||
|
||||
// QMetaObject::invokeMethod(
|
||||
// AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection,
|
||||
// Q_ARG(QString, QString::fromUtf8(event->udid)),
|
||||
// Q_ARG(idevice_connection_type, event->conn_type),
|
||||
// Q_ARG(AddType, AddType::Regular));
|
||||
// break;
|
||||
// }
|
||||
|
||||
// case IDEVICE_DEVICE_REMOVE: {
|
||||
// QMetaObject::invokeMethod(AppContext::sharedInstance(),
|
||||
// "removeDevice",
|
||||
// Qt::QueuedConnection,
|
||||
// Q_ARG(QString, QString(event->udid)));
|
||||
// break;
|
||||
// }
|
||||
|
||||
// case IDEVICE_DEVICE_PAIRED: {
|
||||
// if (event->conn_type == CONNECTION_NETWORK) {
|
||||
// qDebug()
|
||||
// << "Network devices are not supported but a network device
|
||||
// was "
|
||||
// "received in event listener. Please report this issue.";
|
||||
// return;
|
||||
// }
|
||||
// qDebug() << "Device paired: " << QString::fromUtf8(event->udid);
|
||||
|
||||
// QMetaObject::invokeMethod(
|
||||
// AppContext::sharedInstance(), "addDevice", Qt::QueuedConnection,
|
||||
// Q_ARG(QString, QString::fromUtf8(event->udid)),
|
||||
// Q_ARG(idevice_connection_type, event->conn_type),
|
||||
// Q_ARG(AddType, AddType::Pairing));
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// qDebug() << "Unhandled event: " << event->event;
|
||||
// }
|
||||
// }
|
||||
|
||||
// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
|
||||
// void handleCallbackRecovery(const irecv_device_event_t *event, void
|
||||
// *userData)
|
||||
// {
|
||||
|
||||
// switch (event->type) {
|
||||
// case IRECV_DEVICE_ADD:
|
||||
// qDebug() << "Recovery device added: ";
|
||||
// QMetaObject::invokeMethod(AppContext::sharedInstance(),
|
||||
// "addRecoveryDevice", Qt::QueuedConnection,
|
||||
// Q_ARG(uint64_t, event->device_info->ecid));
|
||||
// break;
|
||||
// case IRECV_DEVICE_REMOVE:
|
||||
// qDebug() << "Recovery device removed: ";
|
||||
// QMetaObject::invokeMethod(AppContext::sharedInstance(),
|
||||
// "removeRecoveryDevice",
|
||||
// Qt::QueuedConnection, Q_ARG(uint64_t,
|
||||
// event->device_info->ecid));
|
||||
// break;
|
||||
// default:
|
||||
// printf("Unhandled recovery event: %d\n", event->type);
|
||||
// }
|
||||
// }
|
||||
// irecv_device_event_context_t context;
|
||||
// #endif
|
||||
|
||||
MainWindow *MainWindow::sharedInstance()
|
||||
{
|
||||
static MainWindow instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), ui(new Ui::MainWindow)
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setMinimumSize(MIN_MAIN_WINDOW_SIZE);
|
||||
resize(MIN_MAIN_WINDOW_SIZE);
|
||||
m_ZTabWidget = new ZTabWidget(this);
|
||||
m_ZTabWidget->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false);
|
||||
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
QWidget *centralWidget = new QWidget(this);
|
||||
setCentralWidget(centralWidget);
|
||||
auto mainLayout = new QVBoxLayout(centralWidget);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_ZTabWidget = new ZTabWidget(this);
|
||||
#ifdef __APPLE__
|
||||
setupMacOSWindow(this);
|
||||
setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false);
|
||||
#endif
|
||||
setCentralWidget(m_ZTabWidget);
|
||||
mainLayout->addWidget(m_ZTabWidget);
|
||||
#ifdef WIN32
|
||||
setupWinWindow(this);
|
||||
#endif
|
||||
|
||||
m_mainStackedWidget = new QStackedWidget();
|
||||
WelcomeWidget *welcomePage = new WelcomeWidget(this);
|
||||
@@ -200,25 +122,35 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
m_connectedDeviceCountLabel->setStyleSheet(
|
||||
"QLabel:hover { background-color : #13131319; }");
|
||||
|
||||
ui->statusbar->addWidget(m_connectedDeviceCountLabel);
|
||||
QWidget *statusbar = new QWidget();
|
||||
QHBoxLayout *statusLayout = new QHBoxLayout(statusbar);
|
||||
statusLayout->setContentsMargins(0, 0, 0, 0);
|
||||
statusbar->setObjectName("StatusBar");
|
||||
statusbar->setStyleSheet(
|
||||
"QWidget#StatusBar { background-color: transparent; }");
|
||||
statusLayout->addWidget(m_connectedDeviceCountLabel);
|
||||
// TODO: implement downloads/uploads progress stuff
|
||||
|
||||
StatusBalloon *statusBalloon = StatusBalloon::sharedInstance();
|
||||
|
||||
ui->statusbar->addWidget(statusBalloon->getButton());
|
||||
statusLayout->addWidget(statusBalloon->getButton());
|
||||
statusLayout->addStretch(1);
|
||||
|
||||
ui->statusbar->setContentsMargins(0, 0, 0, 0);
|
||||
statusLayout->setContentsMargins(0, 0, 0, 0);
|
||||
QLabel *appVersionLabel = new QLabel(QString("v%1").arg(APP_VERSION));
|
||||
appVersionLabel->setContentsMargins(5, 0, 5, 0);
|
||||
appVersionLabel->setStyleSheet(
|
||||
"QLabel:hover { background-color : #13131319; }");
|
||||
ui->statusbar->addPermanentWidget(appVersionLabel);
|
||||
ui->statusbar->addPermanentWidget(githubButton);
|
||||
ui->statusbar->addPermanentWidget(settingsButton);
|
||||
#ifdef WIN32
|
||||
ui->statusbar->setStyleSheet(
|
||||
"QStatusBar { border-top: 1px solid #dcdcdc; }");
|
||||
#endif
|
||||
statusLayout->addWidget(appVersionLabel);
|
||||
statusLayout->addWidget(githubButton);
|
||||
statusLayout->addWidget(settingsButton);
|
||||
// #ifdef WIN32
|
||||
// statusLayout->setStyleSheet("QStatusBar { border-top: 1px solid
|
||||
// #dcdcdc;
|
||||
// }");
|
||||
// #endif
|
||||
|
||||
mainLayout->addWidget(statusbar);
|
||||
|
||||
#ifdef __linux__
|
||||
QList<QString> mounted_iFusePaths = iFuseManager::getMountPoints();
|
||||
@@ -226,7 +158,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
for (const QString &path : mounted_iFusePaths) {
|
||||
auto *p = new iFuseDiskUnmountButton(path);
|
||||
|
||||
ui->statusbar->addPermanentWidget(p);
|
||||
statusbar->addWidget(p);
|
||||
connect(p, &iFuseDiskUnmountButton::clicked, this, [this, p, path]() {
|
||||
bool ok = iFuseManager::linuxUnmount(path);
|
||||
if (!ok) {
|
||||
@@ -235,7 +167,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
". Please try again.");
|
||||
return;
|
||||
}
|
||||
ui->statusbar->removeWidget(p);
|
||||
statusbar->removeWidget(p);
|
||||
p->deleteLater();
|
||||
});
|
||||
}
|
||||
@@ -521,7 +453,6 @@ MainWindow::~MainWindow()
|
||||
// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
|
||||
// irecv_device_event_unsubscribe(context);
|
||||
// #endif
|
||||
delete ui;
|
||||
m_deviceMonitor->requestInterruption();
|
||||
// FIXME:QThread: Destroyed while thread '' is still running
|
||||
// m_deviceMonitor->wait();
|
||||
|
||||
@@ -22,23 +22,13 @@
|
||||
#include "ZDownloader.h"
|
||||
#include "ZUpdater.h"
|
||||
#include "devicemanagerwidget.h"
|
||||
#include "iDescriptor.h"
|
||||
#include <QMainWindow>
|
||||
// #ifdef ENABLE_RECOVERY_DEVICE_SUPPORT
|
||||
// #include "libirecovery.h"
|
||||
// #endif
|
||||
#include "devicemonitor.h"
|
||||
#include "iDescriptor.h"
|
||||
#include "ztabwidget.h"
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QStackedWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui
|
||||
{
|
||||
class MainWindow;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -54,11 +44,17 @@ public slots:
|
||||
private:
|
||||
void createMenus();
|
||||
|
||||
Ui::MainWindow *ui;
|
||||
ZTabWidget *m_ZTabWidget;
|
||||
DeviceManagerWidget *m_deviceManager;
|
||||
QStackedWidget *m_mainStackedWidget;
|
||||
QLabel *m_connectedDeviceCountLabel;
|
||||
DeviceMonitorThread *m_deviceMonitor;
|
||||
QLabel *m_titleLabel;
|
||||
QPushButton *m_minBtn;
|
||||
QPushButton *m_maxBtn;
|
||||
QPushButton *m_closeBtn;
|
||||
QWidget *m_titleBar;
|
||||
QWidget *m_contentArea;
|
||||
QHBoxLayout *m_titleBarLayout;
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* iDescriptor: A free and open-source idevice management tool.
|
||||
*
|
||||
* Copyright (C) 2025 Uncore <https://github.com/uncor3>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../../settingsmanager.h"
|
||||
#include "win_common.h"
|
||||
|
||||
void enableAcrylic(HWND hwnd)
|
||||
{
|
||||
const HINSTANCE hModule = LoadLibraryA("user32.dll");
|
||||
if (hModule) {
|
||||
struct ACCENTPOLICY {
|
||||
int nAccentState;
|
||||
int nFlags;
|
||||
DWORD nColor;
|
||||
int nAnimationId;
|
||||
};
|
||||
struct WINCOMPATTRDATA {
|
||||
int nAttribute;
|
||||
PVOID pData;
|
||||
ULONG ulDataSize;
|
||||
};
|
||||
|
||||
typedef BOOL(WINAPI *
|
||||
pSetWindowCompositionAttribute)(HWND, WINCOMPATTRDATA *);
|
||||
const auto SetWindowCompositionAttribute =
|
||||
(pSetWindowCompositionAttribute)GetProcAddress(
|
||||
hModule, "SetWindowCompositionAttribute");
|
||||
|
||||
if (SetWindowCompositionAttribute) {
|
||||
ACCENTPOLICY policy{};
|
||||
policy.nAccentState = 4; // ACCENT_ENABLE_ACRYLICBLURBEHIND
|
||||
policy.nFlags = 2;
|
||||
|
||||
policy.nColor = 0xD0202020;
|
||||
|
||||
WINCOMPATTRDATA data{};
|
||||
data.nAttribute = 19;
|
||||
data.pData = &policy;
|
||||
data.ulDataSize = sizeof(policy);
|
||||
|
||||
SetWindowCompositionAttribute(hwnd, &data);
|
||||
}
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DWMWA_SYSTEMBACKDROP_TYPE
|
||||
#define DWMWA_SYSTEMBACKDROP_TYPE 38
|
||||
#endif
|
||||
|
||||
#ifndef DWMWA_MICA_EFFECT
|
||||
#define DWMWA_MICA_EFFECT 1029
|
||||
#endif
|
||||
void enableMica(HWND hwnd)
|
||||
{
|
||||
if (!hwnd)
|
||||
return;
|
||||
SettingsManager *sm = SettingsManager::sharedInstance();
|
||||
WIN_BACKDROP type = sm->winBackdropType();
|
||||
MARGINS margins = {-1};
|
||||
DwmExtendFrameIntoClientArea(hwnd, &margins);
|
||||
|
||||
DWORD build = 0;
|
||||
RTL_OSVERSIONINFOW rovi = {0};
|
||||
rovi.dwOSVersionInfoSize = sizeof(rovi);
|
||||
|
||||
using RtlGetVersionPtr = LONG(WINAPI *)(PRTL_OSVERSIONINFOW);
|
||||
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
|
||||
if (ntdll) {
|
||||
auto pRtlGetVersion = reinterpret_cast<RtlGetVersionPtr>(
|
||||
GetProcAddress(ntdll, "RtlGetVersion"));
|
||||
if (pRtlGetVersion && pRtlGetVersion(&rovi) == 0) {
|
||||
build = rovi.dwBuildNumber;
|
||||
}
|
||||
}
|
||||
|
||||
if (build >= 22523) {
|
||||
DwmSetWindowAttribute(hwnd, DWMWA_SYSTEMBACKDROP_TYPE, &type,
|
||||
sizeof(type));
|
||||
} else if (build >= 22000) {
|
||||
// Undocumented old method
|
||||
BOOL mica = TRUE;
|
||||
DwmSetWindowAttribute(hwnd, DWMWA_MICA_EFFECT, &mica, sizeof(mica));
|
||||
}
|
||||
}
|
||||