forked from CastroFidel/winehelper
Compare commits
14 Commits
dfc6c1c836
...
devel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4afdbaa220 | ||
|
|
81013bfe71 | ||
|
|
caccc333db | ||
|
|
151d0ffc48 | ||
|
|
ad91466475 | ||
|
|
5e4d94bb57 | ||
|
|
5b572ff540 | ||
|
|
c68bcc9abf | ||
|
|
1ad2c6cfa8 | ||
|
|
16a686dc37 | ||
|
|
c9d5619ab9 | ||
|
|
74311e9c04 | ||
|
|
eb9bef83e2 | ||
|
|
c7eddb8b53 |
7
GENERAL
Normal file
7
GENERAL
Normal file
@@ -0,0 +1,7 @@
|
||||
# Руководство пользователя
|
||||
Подробное и актуальное руководство по использованию WineHelper смотрите на сайте: https://www.altlinux.org/Winehelper
|
||||
|
||||
# Совместимость ПО и сертификаты
|
||||
С полным списком совместимого ПО и сертификатами можно ознакомиться по следующим ссылкам:
|
||||
Для 10 платформы: https://www.basealt.ru/fileadmin/user_upload/compatibility/P10-view2.html
|
||||
Для 11 платформы: https://www.basealt.ru/fileadmin/user_upload/compatibility/P11-view2.html
|
||||
@@ -4,7 +4,7 @@ _winehelper_completions() {
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
opts="--help --version --debug install installed install-dxvk install-vkd3d -r -i remove-all --clear-pfx killall remove-prefix backup-prefix restore-prefix create-prefix --changelog changelog change-wine"
|
||||
opts="--help --version --debug install installed install-dxvk install-vkd3d -r -i remove-all --clear-pfx killall remove-prefix backup-prefix restore-prefix create-prefix --changelog changelog change-wine clear-winetricks-cache"
|
||||
wine_cmd="winecfg winereg winefile wineconsole winetricks desktop regedit explorer cmd run"
|
||||
|
||||
case "${prev}" in
|
||||
|
||||
@@ -21,6 +21,7 @@ _winehelper() {
|
||||
'backup-prefix[Создать резерную копию префикса]'
|
||||
'restore-prefix[восстановить префикс из резервной копии "путь/до/whpack"]'
|
||||
'change-wine[Изменить версию Wine/Proton для префикса]'
|
||||
'clear-winetricks-cache[Очистить кэш Winetricks]'
|
||||
)
|
||||
|
||||
wine_cmd=(
|
||||
|
||||
@@ -3,37 +3,33 @@
|
||||
########################################################################
|
||||
export PROG_URL="https://www.nalog.gov.ru"
|
||||
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
|
||||
export WINEPREFIX="declaration"
|
||||
export WINEPREFIX="nalog"
|
||||
export PROG_NAME="Декларация"
|
||||
export PROG_ICON="declarac"
|
||||
export BASE_PFX="defpfx_x86_v01"
|
||||
export BASE_PFX="none"
|
||||
export WINEARCH="win32"
|
||||
export INSTALL_DLL="msxml3 msxml4 msxml6 corefonts wsh57 vcrun6 jet40 gdiplus"
|
||||
export WH_WINDOWS_VER="10"
|
||||
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48"
|
||||
|
||||
DECL_FILE="${WH_TMP_DIR}/decl.html"
|
||||
curl -o "$DECL_FILE" -A "Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" "https://www.nalog.gov.ru/rn77/program/5961249/"
|
||||
|
||||
if [[ ! -f "$DECL_FILE" ]] \
|
||||
|| grep -q "Forbidden" "$DECL_FILE"
|
||||
then
|
||||
fatal "The site page is unavailable or the request limit has been exceeded."
|
||||
fi
|
||||
|
||||
VER_YEAR=$(grep -oP 'href="\K[^"]*.msi[^"]*' "$DECL_FILE" | awk -F'/' '{print $(NF-2)}' | head -n 1)
|
||||
try_get_page "https://www.nalog.gov.ru/rn77/program/5961249/"
|
||||
VER_YEAR=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF-2)}' | head -n 1)
|
||||
YEAR="${VER_YEAR//decl/}"
|
||||
VER_MSI_SLASH=$(grep -oP 'href="\K[^"]*.msi[^"]*' "$DECL_FILE" | awk -F'/' '{print $(NF-1)}' | head -n 1)
|
||||
VER_MSI=$(grep -oP 'href="\K[^"]*.msi[^"]*' "$DECL_FILE" | awk -F'/' '{print $(NF)}' | head -n 1)
|
||||
|
||||
VER_MSI_SLASH=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF-1)}' | head -n 1)
|
||||
VER_MSI=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF)}' | head -n 1)
|
||||
AUTOINSTALL_MSI="${WH_TMP_DIR}/${VER_MSI}"
|
||||
|
||||
prepair_wine
|
||||
if try_download "https://data.nalog.ru/files/${VER_YEAR}/${VER_MSI_SLASH}/$VER_MSI" "${AUTOINSTALL_MSI}" ; then
|
||||
wine_run_install "${AUTOINSTALL_MSI}" "/q"
|
||||
if try_download "https://data.nalog.ru/files/${VER_YEAR}/${VER_MSI_SLASH}/${VER_MSI}" "${AUTOINSTALL_MSI}" ; then
|
||||
wine_run_install "${AUTOINSTALL_MSI}" /q
|
||||
try_remove_file "${AUTOINSTALL_MSI}"
|
||||
|
||||
WIN_FILE_EXEC="$DRIVE_C/АО ГНИВЦ/Декларация ${YEAR}/Decl${YEAR}.exe"
|
||||
create_desktop "$PROG_NAME $YEAR" "$WIN_FILE_EXEC" "$PROG_ICON"
|
||||
remove_desktop "Декларация $((YEAR - 1))"
|
||||
fi
|
||||
|
||||
# Удаляем ярлык предыдущей версии
|
||||
remove_desktop "Декларация $((YEAR - 1))"
|
||||
|
||||
print_info "Программа Декларация $YEAR успешно установлена"
|
||||
else
|
||||
fatal "Не удалось скачать установочный файл"
|
||||
fi
|
||||
|
||||
@@ -6,32 +6,24 @@ export WH_WINE_USE="wine_x_tkg_10-0_amd64"
|
||||
export WINEPREFIX="nalog"
|
||||
export PROG_NAME="Налогоплательщик ЮЛ"
|
||||
export PROG_ICON="npul"
|
||||
export BASE_PFX="defpfx_x86_v01"
|
||||
export BASE_PFX="none"
|
||||
export WINEARCH="win32"
|
||||
export INSTALL_DLL="msxml3 msxml4 msxml6 corefonts wsh57 vcrun6 jet40 gdiplus"
|
||||
export WH_WINDOWS_VER="10"
|
||||
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48"
|
||||
|
||||
NPUL_FILE="${WH_TMP_DIR}/npul.html"
|
||||
curl -o "$NPUL_FILE" -A "Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" "https://www.nalog.gov.ru/rn77/program/5961229/"
|
||||
|
||||
if [[ ! -f "$NPUL_FILE" ]] \
|
||||
|| grep -q "Forbidden" "$NPUL_FILE"
|
||||
then
|
||||
fatal "Страница сайта не доступна, или превышено количество запросов к странице."
|
||||
fi
|
||||
|
||||
VER_MSI=$(grep -oP 'NalogUL\K[0-9.]+(?=\.msi)' "$NPUL_FILE" | tail -n 1)
|
||||
VER_MSI_SLASH=$(grep -oP '[0-9]+\.[0-9]+/NalogUL[0-9]+\.msi' "$NPUL_FILE" | tail -n 1)
|
||||
VER_EXE=$(grep -oP 'NalogUL\K[0-9.]+(?=\.exe)' "$NPUL_FILE" | tail -n 1)
|
||||
VER_EXE_SLASH=$(grep -oP '[0-9]+\.[0-9]+\.[0-9]+/NalogUL[0-9]+\.exe' "$NPUL_FILE" | tail -n 1)
|
||||
try_get_page "https://data.nalog.ru/rn77/program/5961229/"
|
||||
VER_MSI=$(read_page | grep -oP 'NalogUL\d+\.msi' | tail -1 | grep -oP '\d+')
|
||||
VER_MSI_URL="${VER_MSI:0:1}.${VER_MSI:1}" # 492 → 4.92
|
||||
VER_EXE=$(read_page | grep -oP 'NalogUL\d+\.exe' | tail -1 | grep -oP '\d+')
|
||||
VER_EXE_URL="${VER_EXE:0:1}.${VER_EXE:1:2}.${VER_EXE:3}" # 4924 → 4.92.4
|
||||
|
||||
AUTOINSTALL_MSI="${WH_TMP_DIR}/NalogUL${VER_MSI}.msi"
|
||||
AUTOINSTALL_EXE="${WH_TMP_DIR}/NalogUL${VER_EXE}.exe"
|
||||
|
||||
prepair_wine
|
||||
if try_download "https://data.nalog.ru/files/nalul/${VER_MSI_SLASH}" "${AUTOINSTALL_MSI}" ; then
|
||||
if try_download "https://data.nalog.ru/files/nalul/${VER_MSI_URL}/NalogUL${VER_MSI}.msi" "${AUTOINSTALL_MSI}" ; then
|
||||
wine_run_install "${AUTOINSTALL_MSI}" /quiet INSTALLDIR="c:\npul"
|
||||
try_remove_file "${AUTOINSTALL_MSI}"
|
||||
try_remove_file "${AUTOINSTALL_MSI}"
|
||||
|
||||
PRINT_INSTALLER="$(find "$DRIVE_C/npul/INPUTDOC" -name "*.msi")"
|
||||
wine_run_install "${PRINT_INSTALLER}" "/q"
|
||||
@@ -42,7 +34,7 @@ if try_download "https://data.nalog.ru/files/nalul/${VER_MSI_SLASH}" "${AUTOINST
|
||||
fi
|
||||
|
||||
if [[ -n "$VER_EXE" ]] \
|
||||
&& try_download "https://data.nalog.ru/files/nalul/${VER_EXE_SLASH}" "${AUTOINSTALL_EXE}"
|
||||
&& try_download "https://data.nalog.ru/files/nalul/${VER_EXE_URL}/NalogUL${VER_EXE}.exe" "${AUTOINSTALL_EXE}"
|
||||
then
|
||||
wine_run_install "${AUTOINSTALL_EXE}" "/SILENT"
|
||||
try_remove_file "${AUTOINSTALL_EXE}"
|
||||
@@ -53,4 +45,3 @@ fi
|
||||
touch "$DRIVE_C/npul/INPUTDOC/linux.txt"
|
||||
WIN_FILE_EXEC="$DRIVE_C/npul/INPUTDOC/inputdoc.exe"
|
||||
create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON"
|
||||
try_remove_file "$NPUL_FILE"
|
||||
|
||||
@@ -2,24 +2,26 @@
|
||||
# info_ru: Подготовка документов для государственной регистрации (ППДГР)
|
||||
########################################################################
|
||||
export PROG_URL="https://www.nalog.gov.ru"
|
||||
export AUTOINSTALL_EXE="${WH_TMP_DIR}/SetupPPDGR2.msi"
|
||||
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
|
||||
export WINEPREFIX="ppdgr2"
|
||||
export WINEPREFIX="nalog"
|
||||
export PROG_NAME="ППДГР-2"
|
||||
# export PROG_VERSION=""
|
||||
export PROG_ICON="ppdgr"
|
||||
# export ADD_MIME_TYPE=""
|
||||
export BASE_PFX="defpfx_dn48_x86_v01"
|
||||
export BASE_PFX="none"
|
||||
export WINEARCH="win32"
|
||||
export INSTALL_DLL="dotnet48 msxml3 msxml4 msxml6 corefonts lucida wsh57 vcrun6 jet40 gdiplus"
|
||||
export WH_WINDOWS_VER="10"
|
||||
var_winedlloverride_update "msxml4=b,wininet=b"
|
||||
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48"
|
||||
|
||||
try_get_page "https://www.nalog.gov.ru/rn77/program/5961277/"
|
||||
VER_MSI_SLASH=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF-1)}' | head -n 1)
|
||||
AUTOINSTALL_EXE="${WH_TMP_DIR}/SetupPPDGR2.msi"
|
||||
|
||||
prepair_wine
|
||||
if try_download "https://data.nalog.ru/files/ppdgr/2.7.0/SetupPPDGR2.msi" "${AUTOINSTALL_EXE}" ; then
|
||||
if try_download "https://data.nalog.ru/files/ppdgr/${VER_MSI_SLASH}/SetupPPDGR2.msi" "${AUTOINSTALL_EXE}" ; then
|
||||
wine_run_install "${AUTOINSTALL_EXE}" /q
|
||||
try_remove_file "${AUTOINSTALL_EXE}"
|
||||
|
||||
WIN_FILE_EXEC="$DRIVE_C/АО ГНИВЦ/ППДГР-2/PPDGR2.exe"
|
||||
create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON"
|
||||
fi
|
||||
https://data.nalog.ru/files/ppdgr/2.7.3/SetupPPDGR2.msi
|
||||
|
||||
@@ -44,13 +44,13 @@ ADDONS_PATH_OPENSSH="${ADDONS_PATH}/OpenSSH"
|
||||
if try_download "$SCADOFFICE_ADDONS_URL" "${ADDONS_PACK}" ; then
|
||||
create_new_dir "${ADDONS_PATH}"
|
||||
unpack "${ADDONS_PACK}" "${ADDONS_PATH}"
|
||||
wine_run regedit "${ADDONS_PATH_REG}"/*.reg
|
||||
wine_run "${ADDONS_PATH_REG}"/*.reg
|
||||
|
||||
# Установка ODBC
|
||||
rm -fR "$DRIVE_C/Program Files (x86)/Common Files/System"
|
||||
cp -r "${ADDONS_PATH_MDAC}/System" "$DRIVE_C/Program Files (x86)/Common Files/System"
|
||||
cp -r "${ADDONS_PATH_MDAC}"/*.* "$DRIVE_C/windows/system32/"
|
||||
wine_run regedit "${ADDONS_PATH_MDAC}"/*.reg
|
||||
wine_run "${ADDONS_PATH_MDAC}"/*.reg
|
||||
|
||||
# Установка SSH
|
||||
cp -r "${ADDONS_PATH_OPENSSH}" "$DRIVE_C/windows/system32/"
|
||||
|
||||
@@ -2,20 +2,21 @@
|
||||
# info_ru: Справочник кодов обозначения налоговых органов для целей учета налогоплательщиков
|
||||
########################################################################
|
||||
export PROG_URL="https://www.nalog.gov.ru"
|
||||
export AUTOINSTALL_EXE="${WH_TMP_DIR}/soun_ins.exe"
|
||||
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
|
||||
export WINEPREFIX="soun"
|
||||
export WINEPREFIX="nalog"
|
||||
export PROG_NAME="СОУН"
|
||||
# export PROG_VERSION=""
|
||||
export PROG_ICON="soun"
|
||||
# export ADD_MIME_TYPE=""
|
||||
export BASE_PFX="defpfx_x86_v01"
|
||||
export BASE_PFX="none"
|
||||
export WINEARCH="win32"
|
||||
export INSTALL_DLL="corefonts"
|
||||
export WH_WINDOWS_VER="10"
|
||||
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48"
|
||||
|
||||
try_get_page "https://www.nalog.gov.ru/rn77/program/5961268/"
|
||||
VER_MSI_SLASH=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF-1)}' | head -n 1)
|
||||
AUTOINSTALL_EXE="${WH_TMP_DIR}/soun_ins.exe"
|
||||
|
||||
prepair_wine
|
||||
if try_download "https://data.nalog.ru/files/Soun/2.6.2/soun_ins.exe" "${AUTOINSTALL_EXE}" ; then
|
||||
if try_download "https://data.nalog.ru/files/Soun/${VER_MSI_SLASH}/soun_ins.exe" "${AUTOINSTALL_EXE}" ; then
|
||||
# TODO: Тихий режим или предупреждение
|
||||
wine_run_install "${AUTOINSTALL_EXE}"
|
||||
try_remove_file "${AUTOINSTALL_EXE}"
|
||||
|
||||
@@ -2,22 +2,23 @@
|
||||
# info_ru: Программа проверки файлов на соответствие форматам представления в электронном виде налоговых деклараций, бухгалтерской отчетности.
|
||||
########################################################################
|
||||
export PROG_URL="https://www.nalog.gov.ru"
|
||||
export LAUNCH_PARAMETERS="/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-"
|
||||
export AUTOINSTALL_EXE="${WH_TMP_DIR}/tester2269.exe"
|
||||
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
|
||||
export WINEPREFIX="nalog"
|
||||
export PROG_NAME="Тестер"
|
||||
# export PROG_VERSION=""
|
||||
export PROG_ICON="tester"
|
||||
# export ADD_MIME_TYPE=""
|
||||
export BASE_PFX="defpfx_x86_v01"
|
||||
export BASE_PFX="none"
|
||||
export WINEARCH="win32"
|
||||
export INSTALL_DLL="msxml3 msxml4 msxml6 corefonts wsh57 vcrun6 jet40 gdiplus"
|
||||
export WH_WINDOWS_VER="10"
|
||||
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48"
|
||||
|
||||
try_get_page "https://www.nalog.gov.ru/rn77/program/5961279/"
|
||||
VER_EXE_SLASH=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF-1)}' | tail -n 1)
|
||||
VER_EXE=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF)}' | tail -n 1)
|
||||
AUTOINSTALL_EXE="${WH_TMP_DIR}/${VER_EXE}"
|
||||
|
||||
prepair_wine
|
||||
if try_download "https://data.nalog.ru/files/tester/2.269/tester2269.exe" "${AUTOINSTALL_EXE}" ; then
|
||||
wine_run_install "${AUTOINSTALL_EXE}"
|
||||
if try_download "https://data.nalog.ru/files/tester/${VER_EXE_SLASH}/${VER_EXE}" "${AUTOINSTALL_EXE}" ; then
|
||||
wine_run_install "${AUTOINSTALL_EXE}" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
|
||||
try_remove_file "${AUTOINSTALL_EXE}"
|
||||
|
||||
WIN_FILE_EXEC="$DRIVE_C/Tester/tester.exe"
|
||||
|
||||
53
winehelper
53
winehelper
@@ -7,7 +7,7 @@ if [[ $(id -u) -eq 0 ]] ; then
|
||||
fi
|
||||
|
||||
##### DEFAULT PATH #####
|
||||
export SCRIPT_NAME USER_WORK_PATH RUN_SCRIPT DATA_PATH CHANGELOG_FILE WH_ICON_PATH LICENSE_FILE AGREEMENT THIRD_PARTY_FILE
|
||||
export SCRIPT_NAME USER_WORK_PATH RUN_SCRIPT DATA_PATH CHANGELOG_FILE WH_ICON_PATH LICENSE_FILE AGREEMENT THIRD_PARTY_FILE WH_ICON_TRAY GENERAL
|
||||
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then
|
||||
@@ -17,11 +17,12 @@ if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then
|
||||
RUN_SCRIPT="/usr/bin/$SCRIPT_NAME"
|
||||
DATA_PATH="/usr/share/$SCRIPT_NAME"
|
||||
WH_ICON_PATH="/usr/share/icons/hicolor/scalable/apps/winehelper.svg"
|
||||
WH_ICON_TRAY=" /usr/share/icons/hicolor/symbolic/apps/winehelper-symbolic.svg"
|
||||
WH_ICON_TRAY="/usr/share/icons/hicolor/symbolic/apps/winehelper-symbolic.svg"
|
||||
CHANGELOG_FILE="/usr/share/doc/winehelper-$WH_VERSION/CHANGELOG"
|
||||
LICENSE_FILE="/usr/share/doc/winehelper-$WH_VERSION/LICENSE"
|
||||
AGREEMENT="/usr/share/doc/winehelper-$WH_VERSION/LICENSE_AGREEMENT"
|
||||
THIRD_PARTY_FILE="/usr/share/doc/winehelper-$WH_VERSION/THIRD-PARTY"
|
||||
GENERAL="/usr/share/doc/winehelper-$WH_VERSION/GENERAL"
|
||||
else
|
||||
# переменные для тестового запуска WineHelper из репозитория
|
||||
USER_WORK_PATH="$HOME/test-$SCRIPT_NAME"
|
||||
@@ -33,6 +34,7 @@ else
|
||||
LICENSE_FILE="$DATA_PATH/LICENSE"
|
||||
AGREEMENT="$DATA_PATH/LICENSE_AGREEMENT"
|
||||
THIRD_PARTY_FILE="$DATA_PATH/THIRD-PARTY"
|
||||
GENERAL="$DATA_PATH/GENERAL"
|
||||
WH_DEVEL="1"
|
||||
|
||||
# минимальная проверка синтаксиса скриптов
|
||||
@@ -52,21 +54,21 @@ fi
|
||||
|
||||
##### MESSAGES FUNCTIONS #####
|
||||
if [[ $WH_USE_GUI != "1" ]] ; then
|
||||
print_error () { printf "\E[31m%s Ошибка: $@ %s\e[0m\n" ;}
|
||||
print_warning () { printf "\E[33m%s Предупреждение: $@ %s\e[0m\n" ;}
|
||||
print_info () { printf "\E[36m%s Информация: \"$@\" %s\e[0m\n" ;}
|
||||
print_ok () { printf "\E[35m%s Успех: $@ %s\e[0m\n" ;}
|
||||
print_error () { printf "\E[31m%s Ошибка: $* %s\e[0m\n" ;}
|
||||
print_warning () { printf "\E[33m%s Предупреждение: $* %s\e[0m\n" ;}
|
||||
print_info () { printf "\E[36m%s Информация: \"$*\" %s\e[0m\n" ;}
|
||||
print_ok () { printf "\E[35m%s Успех: $* %s\e[0m\n" ;}
|
||||
else
|
||||
print_error () { echo -e "Ошибка: $@" ;}
|
||||
print_warning () { echo -e "Предупреждение: $@" ;}
|
||||
print_info () { echo -e "Информация: \"$@\"" ;}
|
||||
print_ok () { echo -e "Успех: $@" ;}
|
||||
print_error () { echo -e "Ошибка: $*" ;}
|
||||
print_warning () { echo -e "Предупреждение: $*" ;}
|
||||
print_info () { echo -e "Информация: \"$*\"" ;}
|
||||
print_ok () { echo -e "Успех: $*" ;}
|
||||
fi
|
||||
|
||||
print_var () { for vp in $@ ; do echo "${vp}=${!vp}" ; done ;}
|
||||
|
||||
fatal () {
|
||||
print_error "$@"
|
||||
print_error "$@ Аварийное завершение работы WineHelper!"
|
||||
[[ -n "$WINESERVER" ]] && "$WINESERVER" -w
|
||||
exit 1
|
||||
}
|
||||
@@ -326,6 +328,7 @@ unpack () {
|
||||
try_get_page () {
|
||||
local url_page="$1"
|
||||
export OUT_PAGE_TMP="${WH_TMP_DIR}/url_page.tmp"
|
||||
try_remove_file "$OUT_PAGE_TMP"
|
||||
print_info "Чтение страницы: $url_page"
|
||||
if ! curl -o "$OUT_PAGE_TMP" -A "Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" "$url_page" \
|
||||
|| grep -q "Forbidden" "$OUT_PAGE_TMP"
|
||||
@@ -342,7 +345,6 @@ read_page () {
|
||||
&& [[ -f "$OUT_PAGE_TMP" ]]
|
||||
then
|
||||
cat "$OUT_PAGE_TMP"
|
||||
try_remove_file "$OUT_PAGE_TMP"
|
||||
unset OUT_PAGE_TMP
|
||||
else
|
||||
echo "Используй try_get_page перед read_page"
|
||||
@@ -1539,6 +1541,7 @@ run_autoinstall () {
|
||||
else print_license_agreement
|
||||
fi
|
||||
source "$INSTALL_SCRIPT" "$@"
|
||||
[[ -n $OUT_PAGE_TMP ]] && try_remove_file "$OUT_PAGE_TMP"
|
||||
print_info "Завершена установка $INSTALL_SCRIPT_NAME"
|
||||
else
|
||||
fatal "Скрипт автоматической установки для $INSTALL_SCRIPT_NAME не найден!"
|
||||
@@ -2290,6 +2293,30 @@ run_change_wine_version() {
|
||||
print_ok "Версия Wine для префикса $PREFIX_NAME успешно изменена на $WH_WINE_USE."
|
||||
}
|
||||
|
||||
clear_winetricks_cache() {
|
||||
local winetricks_cache_dir="$HOME/.cache/winetricks"
|
||||
local winehelper_wt_cache_dir="$HOME/.cache/winehelper/winetricks"
|
||||
|
||||
if [[ ! -d "$winetricks_cache_dir" ]] && [[ ! -d "$winehelper_wt_cache_dir" ]]; then
|
||||
print_info "Кэш Winetricks не найден. Очистка не требуется."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ ! $1 =~ --force|-y ]] ; then
|
||||
print_warning "Вы собираетесь очистить кэш Winetricks."
|
||||
echo "Будут удалены все скачанные установщики Winetricks и списки компонентов."
|
||||
if ! print_confirmation "Продолжить?"
|
||||
then
|
||||
print_info "Операция отменена."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
print_info "Очистка кэша Winetricks..."
|
||||
try_remove_dir "$winetricks_cache_dir"
|
||||
try_remove_dir "$winehelper_wt_cache_dir"
|
||||
print_ok "Кэш Winetricks успешно очищен."
|
||||
}
|
||||
|
||||
wh_info () {
|
||||
echo "Использование: $SCRIPT_NAME [команда]
|
||||
|
||||
@@ -2309,6 +2336,7 @@ wh_info () {
|
||||
remove-prefix [имя_префикса] удалить префикс и все связанные данные
|
||||
backup-prefix [имя_префикса] создать резервную копию префикса
|
||||
restore-prefix \"путь/до/whpack\" восстановить префикс из резервной копии
|
||||
clear-winetricks-cache очистить кэш Winetricks
|
||||
|
||||
Параметры:
|
||||
--help показать эту справку и выйти
|
||||
@@ -2367,6 +2395,7 @@ case "$arg1" in
|
||||
remove-prefix) remove_prefix "$@" ;;
|
||||
create-base-pfx) create_base_pfx "$@" ;;
|
||||
init-prefix) prepair_wine ; wait_wineserver ;;
|
||||
clear-winetricks-cache) clear_winetricks_cache "$@" ;;
|
||||
*)
|
||||
if [[ -f "$arg1" ]] ; then
|
||||
WIN_FILE_EXEC="$(readlink -f "$arg1")"
|
||||
|
||||
@@ -13,8 +13,8 @@ from functools import partial
|
||||
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QTabBar,
|
||||
QTextEdit, QFileDialog, QMessageBox, QLineEdit, QCheckBox, QStackedWidget, QScrollArea, QFormLayout, QGroupBox, QRadioButton, QComboBox,
|
||||
QListWidget, QListWidgetItem, QGridLayout, QFrame, QDialog, QTextBrowser, QInputDialog, QDialogButtonBox, QSystemTrayIcon, QMenu)
|
||||
from PyQt5.QtCore import Qt, QProcess, QSize, QTimer, QProcessEnvironment, QPropertyAnimation, QEasingCurve, pyqtSignal
|
||||
from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor, QTextCharFormat
|
||||
from PyQt5.QtCore import Qt, QProcess, QSize, QTimer, QProcessEnvironment, QPropertyAnimation, QEasingCurve, pyqtSignal, QRect
|
||||
from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor, QTextCharFormat, QColor, QPalette
|
||||
from PyQt5.QtNetwork import QLocalServer, QLocalSocket
|
||||
|
||||
|
||||
@@ -26,9 +26,11 @@ class Var:
|
||||
DATA_PATH = os.environ.get("DATA_PATH")
|
||||
CHANGELOG_FILE = os.environ.get("CHANGELOG_FILE")
|
||||
WH_ICON_PATH = os.environ.get("WH_ICON_PATH")
|
||||
WH_ICON_TRAY = os.environ.get("WH_ICON_TRAY")
|
||||
LICENSE_FILE = os.environ.get("LICENSE_FILE")
|
||||
LICENSE_AGREEMENT_FILE = os.environ.get("AGREEMENT")
|
||||
THIRD_PARTY_FILE = os.environ.get("THIRD_PARTY_FILE")
|
||||
GENERAL = os.environ.get("GENERAL")
|
||||
|
||||
class DependencyManager:
|
||||
"""Класс для управления проверкой и установкой системных зависимостей."""
|
||||
@@ -444,6 +446,7 @@ class WinetricksManagerDialog(QDialog):
|
||||
self.previous_tab_widget = None
|
||||
self.cache_dir = os.path.join(os.path.expanduser("~"), ".cache", "winehelper", "winetricks")
|
||||
os.makedirs(self.cache_dir, exist_ok=True)
|
||||
self.is_reloading_after_cache_clear = False
|
||||
|
||||
self.setWindowTitle(f"Менеджер компонентов для префикса: {os.path.basename(prefix_path)}")
|
||||
self.setMinimumSize(800, 500)
|
||||
@@ -476,8 +479,14 @@ class WinetricksManagerDialog(QDialog):
|
||||
self.log_output.setText(self.INFO_TEXT)
|
||||
main_layout.addWidget(self.log_output)
|
||||
|
||||
# Кнопки управления, выровненные по правому краю
|
||||
# Кнопки управления
|
||||
button_layout = QHBoxLayout()
|
||||
|
||||
self.clear_cache_button = QPushButton("Очистить кеш")
|
||||
self.clear_cache_button.setStyleSheet("background-color: red; color: white;")
|
||||
self.clear_cache_button.clicked.connect(self.clear_winetricks_cache)
|
||||
button_layout.addWidget(self.clear_cache_button)
|
||||
|
||||
button_layout.addStretch(1)
|
||||
|
||||
self.apply_button = QPushButton("Применить")
|
||||
@@ -734,9 +743,18 @@ class WinetricksManagerDialog(QDialog):
|
||||
self._log(output)
|
||||
self._log("--------------------------------------------------")
|
||||
|
||||
# Проверяем, были ли ошибки во время загрузки какой-либо из категорий
|
||||
has_errors = any(status == 'error' for status in self.category_statuses.values())
|
||||
|
||||
self.loading_count -= 1
|
||||
if self.loading_count == 0:
|
||||
self._update_ui_state()
|
||||
if self.is_reloading_after_cache_clear:
|
||||
if has_errors:
|
||||
self._log("\n=== Ошибка при обновлении списков. Проверьте лог выше. ===", "red")
|
||||
else:
|
||||
self._log("\n=== Списки успешно обновлены ===")
|
||||
self.is_reloading_after_cache_clear = False # Сбрасываем флаг
|
||||
|
||||
def _on_item_changed(self, item):
|
||||
"""Обрабатывает изменение состояния чекбокса, предотвращая снятие галочки с установленных."""
|
||||
@@ -893,6 +911,64 @@ class WinetricksManagerDialog(QDialog):
|
||||
self.installation_complete.emit()
|
||||
self.installation_finished = True
|
||||
|
||||
def clear_winetricks_cache(self):
|
||||
"""Запускает очистку кэша Winetricks."""
|
||||
reply = self._show_message_box(
|
||||
"Очистка кэша Winetricks",
|
||||
"Вы собираетесь удалить все скачанные установщики и списки компонентов Winetricks.\n\n"
|
||||
"Это действие может потребоваться, если у вас возникают проблемы со скачиванием или установкой компонентов.\n\n"
|
||||
"Продолжить?",
|
||||
QMessageBox.Question,
|
||||
{"buttons": {"Да": QMessageBox.YesRole, "Нет": QMessageBox.NoRole}, "default": "Нет"}
|
||||
)
|
||||
|
||||
if reply != "Да":
|
||||
return
|
||||
|
||||
# Блокируем UI на время выполнения
|
||||
self.tabs.setEnabled(False)
|
||||
self.clear_cache_button.setEnabled(False)
|
||||
self.apply_button.setEnabled(False)
|
||||
self.reinstall_button.setEnabled(False)
|
||||
self.close_button.setEnabled(False)
|
||||
|
||||
self.log_output.clear()
|
||||
|
||||
self.cache_clear_process = QProcess(self)
|
||||
self.cache_clear_process.setProcessChannelMode(QProcess.MergedChannels)
|
||||
|
||||
def handle_output():
|
||||
output = self.cache_clear_process.readAll().data().decode('utf-8', 'ignore').strip()
|
||||
if output:
|
||||
self._log(output)
|
||||
|
||||
def handle_finish(exit_code, exit_status):
|
||||
if exit_code == 0:
|
||||
self.is_reloading_after_cache_clear = True # Устанавливаем флаг перед перезагрузкой
|
||||
self.category_statuses.clear() # Очищаем статусы перед новой загрузкой
|
||||
# Воссоздаем директорию кэша, так как скрипт ее полностью удалил
|
||||
os.makedirs(self.cache_dir, exist_ok=True)
|
||||
self._log("Обновление списков...")
|
||||
self.initial_states.clear()
|
||||
self.load_all_categories()
|
||||
else:
|
||||
self._log(f"\n=== Ошибка (код: {exit_code}) ===", "red")
|
||||
|
||||
# Восстанавливаем UI
|
||||
self.tabs.setEnabled(True)
|
||||
self.clear_cache_button.setEnabled(True)
|
||||
self.close_button.setEnabled(True)
|
||||
self._update_ui_state() # Обновляем состояние кнопок Применить/Переустановить
|
||||
|
||||
self.cache_clear_process.readyRead.connect(handle_output)
|
||||
self.cache_clear_process.finished.connect(handle_finish)
|
||||
|
||||
winehelper_path = self.parent().winehelper_path if hasattr(self.parent(), 'winehelper_path') else Var.RUN_SCRIPT
|
||||
args = ["clear-winetricks-cache", "--force"]
|
||||
|
||||
self._log(f"Выполнение: {shlex.quote(winehelper_path)} {' '.join(args)}\n")
|
||||
self.cache_clear_process.start(winehelper_path, args)
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""Обрабатывает закрытие окна, чтобы предотвратить выход во время установки."""
|
||||
# Проверяем, запущен ли процесс установки/переустановки
|
||||
@@ -936,6 +1012,8 @@ class WinetricksManagerDialog(QDialog):
|
||||
"""Добавляет сообщение в лог с возможностью указания цвета."""
|
||||
if color:
|
||||
self.log_output.append(f'<span style="color:{color};">{message}</span>')
|
||||
# Сбрасываем формат, чтобы следующий текст не наследовал цвет
|
||||
self.log_output.setCurrentCharFormat(QTextCharFormat())
|
||||
else:
|
||||
self.log_output.append(message)
|
||||
self.log_output.moveCursor(QTextCursor.End)
|
||||
@@ -1737,6 +1815,18 @@ class WineHelperGUI(QMainWindow):
|
||||
self.raise_()
|
||||
self.activateWindow()
|
||||
|
||||
def create_colorized_icon(self, icon_path, color):
|
||||
"""Загружает иконку (SVG) и применяет к ней указанный цвет."""
|
||||
target_pixmap = QPixmap(icon_path)
|
||||
if target_pixmap.isNull():
|
||||
return QIcon()
|
||||
|
||||
painter = QPainter(target_pixmap)
|
||||
painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
|
||||
painter.fillRect(target_pixmap.rect(), QColor(color))
|
||||
painter.end()
|
||||
return QIcon(target_pixmap)
|
||||
|
||||
def create_tray_icon(self):
|
||||
"""Создает и настраивает иконку в системном трее."""
|
||||
if not QSystemTrayIcon.isSystemTrayAvailable():
|
||||
@@ -1745,11 +1835,23 @@ class WineHelperGUI(QMainWindow):
|
||||
|
||||
self.tray_icon = QSystemTrayIcon(self)
|
||||
|
||||
icon_path = Var.WH_ICON_PATH
|
||||
if icon_path and os.path.exists(icon_path):
|
||||
pixmap = QPixmap(icon_path)
|
||||
if not pixmap.isNull():
|
||||
self.tray_icon.setIcon(QIcon(pixmap))
|
||||
# --- Определение цвета иконки в зависимости от темы ---
|
||||
if Var.WH_ICON_TRAY and os.path.exists(Var.WH_ICON_TRAY):
|
||||
# Получаем цвет текста окна из палитры приложения.
|
||||
# Это хороший индикатор для определения контрастного цвета.
|
||||
window_text_color = self.palette().color(QPalette.WindowText)
|
||||
|
||||
# Если цвет текста светлый (высокая яркость), значит, тема темная.
|
||||
# И наоборот: если цвет текста темный, тема светлая.
|
||||
# Яркость > 127 обычно указывает на светлый цвет.
|
||||
is_dark_theme = window_text_color.lightness() > 127
|
||||
|
||||
if is_dark_theme:
|
||||
# Для темных тем используем белую иконку
|
||||
self.tray_icon.setIcon(self.create_colorized_icon(Var.WH_ICON_TRAY, Qt.white))
|
||||
else:
|
||||
# Для светлых тем используем черную иконку
|
||||
self.tray_icon.setIcon(self.create_colorized_icon(Var.WH_ICON_TRAY, Qt.black))
|
||||
|
||||
# Создаем и сохраняем меню как атрибут класса, чтобы оно не удалялось
|
||||
self.tray_menu = QMenu(self)
|
||||
@@ -1792,10 +1894,7 @@ class WineHelperGUI(QMainWindow):
|
||||
title = "Автоматическая установка"
|
||||
html_content = ("<h3>Автоматическая установка</h3>"
|
||||
"<p>Скрипты из этого списка скачают, установят и настроят приложение за вас. Просто выберите программу и нажмите «Установить».</p>"
|
||||
"<p>Для доступа к экспериментальным скриптам установки отметьте опцию <b>«Показать тестовые версии»</b> внизу списка.</p>"
|
||||
"<br><h3>Совместимость с дистрибутивами Альт</h3>"
|
||||
"<p>С полным списком совместимого ПО и сертификатами (не только для WineHelper) можно ознакомиться по следующим ссылкам:<br>"
|
||||
"<a href='https://www.basealt.ru/fileadmin/user_upload/compatibility/P10-view2.html'>Для 10 платформы</a> | <a href='https://www.basealt.ru/fileadmin/user_upload/compatibility/P11-view2.html'>Для 11 платформы</a></p>")
|
||||
"<p>Для доступа к экспериментальным скриптам установки отметьте опцию <b>«Показать тестовые версии»</b> внизу списка.</p>")
|
||||
show_global = False
|
||||
elif tab_name == "Ручная установка":
|
||||
title = "Ручная установка"
|
||||
@@ -2201,6 +2300,7 @@ class WineHelperGUI(QMainWindow):
|
||||
self.install_tabs_data['auto'] = {
|
||||
'buttons': buttons, 'layout': layout, 'search_edit': search_edit, 'scroll_area': scroll_area
|
||||
}
|
||||
self.install_tabs_data['auto']['test_buttons'] = []
|
||||
|
||||
# Добавляем чекбокс для тестовых версий
|
||||
test_checkbox = QCheckBox("Показать тестовые версии")
|
||||
@@ -2236,43 +2336,68 @@ class WineHelperGUI(QMainWindow):
|
||||
if not data:
|
||||
return
|
||||
|
||||
script_folders = ["autoinstall"]
|
||||
if data['test_checkbox'].isChecked():
|
||||
script_folders.append("testinstall")
|
||||
is_checked = data['test_checkbox'].isChecked()
|
||||
test_buttons = data.get('test_buttons', [])
|
||||
|
||||
# Перед удалением кнопок останавливаем все связанные с ними таймеры анимации
|
||||
for btn in data['buttons']:
|
||||
if btn in self.icon_animators:
|
||||
anim_data = self.icon_animators.pop(btn)
|
||||
if 'main_timer' in anim_data:
|
||||
anim_data['main_timer'].stop()
|
||||
if 'animation' in anim_data and anim_data['animation']:
|
||||
anim_data['animation'].stop()
|
||||
|
||||
# Сбрасываем ссылку на активную кнопку, если она была удалена
|
||||
if self.current_active_button in data['buttons']:
|
||||
self.current_active_button = None
|
||||
|
||||
# Очищаем старые кнопки и layout
|
||||
for btn in data['buttons']:
|
||||
btn.parent().deleteLater()
|
||||
data['buttons'].clear()
|
||||
|
||||
# Заполняем layout новыми кнопками
|
||||
scripts = []
|
||||
for folder in script_folders:
|
||||
script_path = os.path.join(Var.DATA_PATH, folder)
|
||||
# Если нужно показать тестовые версии и они еще не добавлены
|
||||
if is_checked and not test_buttons:
|
||||
test_script_folder = "testinstall"
|
||||
script_path = os.path.join(Var.DATA_PATH, test_script_folder)
|
||||
if os.path.isdir(script_path):
|
||||
try:
|
||||
folder_scripts = sorted(os.listdir(script_path))
|
||||
self._populate_install_grid(data['layout'], folder_scripts, folder, data['buttons'])
|
||||
scripts.extend(folder_scripts)
|
||||
except OSError as e:
|
||||
print(f"Не удалось прочитать директорию {script_path}: {e}")
|
||||
# Запоминаем, какие кнопки являются тестовыми
|
||||
new_test_buttons = []
|
||||
self._populate_install_grid(data['layout'], folder_scripts, test_script_folder, new_test_buttons)
|
||||
data['test_buttons'] = new_test_buttons
|
||||
data['buttons'].extend(new_test_buttons)
|
||||
self.autoinstall_scripts.extend(folder_scripts)
|
||||
|
||||
self.autoinstall_scripts = scripts
|
||||
# Применяем текущий фильтр поиска к обновленному списку
|
||||
self.filter_buttons('auto')
|
||||
# Применяем фильтр и прокручиваем к первому новому элементу
|
||||
self.filter_buttons('auto')
|
||||
if new_test_buttons:
|
||||
first_new_button = new_test_buttons[0]
|
||||
frame = first_new_button.parent()
|
||||
if isinstance(frame, QFrame):
|
||||
# Даем время на отрисовку перед прокруткой
|
||||
QTimer.singleShot(100, lambda: data['scroll_area'].ensureWidgetVisible(frame, 50, 50))
|
||||
|
||||
except OSError as e:
|
||||
print(f"Не удалось прочитать директорию {test_script_folder}: {e}")
|
||||
|
||||
# Если нужно скрыть тестовые версии и они были добавлены
|
||||
elif not is_checked and test_buttons:
|
||||
# Если текущая активная кнопка находится среди удаляемых, сбрасываем ее
|
||||
if self.current_active_button in test_buttons:
|
||||
self._reset_info_panel_to_default("Автоматическая установка")
|
||||
self.current_active_button = None
|
||||
|
||||
# Останавливаем анимацию и удаляем виджеты тестовых кнопок
|
||||
for btn in test_buttons:
|
||||
if btn in self.icon_animators:
|
||||
anim_data = self.icon_animators.pop(btn)
|
||||
if 'main_timer' in anim_data:
|
||||
anim_data['main_timer'].stop()
|
||||
if 'animation' in anim_data and anim_data['animation']:
|
||||
anim_data['animation'].stop()
|
||||
|
||||
# Удаляем кнопку из основного списка
|
||||
if btn in data['buttons']:
|
||||
data['buttons'].remove(btn)
|
||||
|
||||
# Удаляем фрейм кнопки из layout
|
||||
frame = btn.parent()
|
||||
if frame:
|
||||
frame.deleteLater()
|
||||
|
||||
# Очищаем список тестовых кнопок
|
||||
data['test_buttons'].clear()
|
||||
# Обновляем список скриптов
|
||||
self.autoinstall_scripts = [s for s in self.autoinstall_scripts if not os.path.exists(os.path.join(Var.DATA_PATH, "testinstall", s))]
|
||||
|
||||
# В любом случае применяем фильтр, чтобы скрыть/показать кнопки в соответствии с поиском
|
||||
if data['test_checkbox'].isChecked():
|
||||
self.filter_buttons('auto')
|
||||
|
||||
def create_installed_tab(self):
|
||||
"""Создает вкладку для отображения установленных программ в виде кнопок"""
|
||||
@@ -3234,17 +3359,44 @@ class WineHelperGUI(QMainWindow):
|
||||
help_subtabs = QTabWidget()
|
||||
help_layout.addWidget(help_subtabs)
|
||||
|
||||
# Подвкладка "Руководство"
|
||||
guide_tab = QWidget()
|
||||
guide_layout = QVBoxLayout(guide_tab)
|
||||
guide_text = QTextBrowser()
|
||||
guide_text.setOpenExternalLinks(True)
|
||||
guide_text.setHtml("""
|
||||
<h2>Руководство пользователя</h2>
|
||||
<p>Подробное и актуальное руководство по использованию WineHelper смотрите на <a href="https://www.altlinux.org/Winehelper">https://www.altlinux.org/Winehelper</a></p>
|
||||
""")
|
||||
guide_layout.addWidget(guide_text)
|
||||
help_subtabs.addTab(guide_tab, "Руководство")
|
||||
# Подвкладка "Общее"
|
||||
general_tab = QWidget()
|
||||
general_layout = QVBoxLayout(general_tab)
|
||||
general_text = QTextBrowser()
|
||||
general_text.setOpenExternalLinks(True)
|
||||
|
||||
try:
|
||||
if not Var.GENERAL or not os.path.exists(Var.GENERAL):
|
||||
raise FileNotFoundError
|
||||
|
||||
with open(Var.GENERAL, 'r', encoding='utf-8') as f:
|
||||
general_content = f.read()
|
||||
|
||||
html_content = ""
|
||||
url_re = re.compile(r'(https?://[^\s]+)')
|
||||
|
||||
for line in general_content.splitlines():
|
||||
line = line.strip()
|
||||
if not line:
|
||||
html_content += "<br>"
|
||||
continue
|
||||
|
||||
line = html.escape(line)
|
||||
line = url_re.sub(r'<a href="\1">\1</a>', line)
|
||||
|
||||
if line.startswith('# '):
|
||||
html_content += f'<h2>{line[2:]}</h2>'
|
||||
elif line.startswith('Для '):
|
||||
html_content += f'<p style="margin-left: 10px;">• {line}</p>'
|
||||
else:
|
||||
html_content += f'<p>{line}</p>'
|
||||
|
||||
general_text.setHtml(html_content)
|
||||
except (FileNotFoundError, TypeError):
|
||||
general_text.setHtml(f'<h2>Ошибка</h2><p>Не удалось загрузить файл с общей информацией по пути:<br>{Var.GENERAL}</p>')
|
||||
|
||||
general_layout.addWidget(general_text)
|
||||
help_subtabs.addTab(general_tab, "Общее")
|
||||
|
||||
# Подвкладка "Авторы"
|
||||
authors_tab = QWidget()
|
||||
@@ -4903,7 +5055,7 @@ def main():
|
||||
window.server = server
|
||||
window.show()
|
||||
# Создаем иконку в системном трее после создания окна
|
||||
window.create_tray_icon()
|
||||
# window.create_tray_icon() # Временно отключено
|
||||
return app.exec_()
|
||||
|
||||
return 1
|
||||
|
||||
Reference in New Issue
Block a user