Compare commits

...

1 Commits

Author SHA1 Message Date
Sergey Palcheh
4d653cdd41 changed the installation of wine versions 2025-11-19 11:42:21 +06:00
2 changed files with 122 additions and 65 deletions

View File

@@ -1700,7 +1700,7 @@ select_wine_version() {
system_wine_version=$(wine --version 2>/dev/null)
[[ -n "$system_wine_version" ]] && system_wine_display_name="$system_wine_version"
fi
options+=("--- System ---")
options+=("--- SYSTEM ---")
options+=("$system_wine_display_name")
# --- Other versions from sha256sum.list ---
@@ -1718,13 +1718,13 @@ select_wine_version() {
}
while IFS= read -r line; do
if [[ "$line" =~ ^#+[[:space:]]([^#[:space:]]+)[[:space:]]#* ]]; then
if [[ "$line" =~ ^#+[[:space:]](.*[^#[:space:]])[[:space:]]#* ]] ; then
flush_group
current_group="${BASH_REMATCH[1]}"
# Отображаем только группы, которые являются сборками WINE или PROTON
case "$current_group" in
WINE|WINE_LG|PROTON_LG|PROTON_STEAM)
local pretty_key=$(echo "$current_group" | tr '_' ' ' | sed -e "s/\b\(.\)/\u\1/g")
"WINE WOW64"|"WINE AMD64"|"WINE I586")
local pretty_key="$current_group"
options+=("--- $pretty_key ---")
;;
*)

View File

@@ -1129,28 +1129,28 @@ class WineVersionSelectionDialog(QDialog):
self.search_edit.textChanged.connect(self.filter_versions)
main_layout.addWidget(self.search_edit)
self.version_tabs = QTabWidget()
main_layout.addWidget(self.version_tabs)
self.main_tabs = QTabWidget()
main_layout.addWidget(self.main_tabs)
self.load_versions()
def load_versions(self):
"""Запускает процесс получения списка версий Wine."""
self.version_tabs.clear()
self.main_tabs.clear()
loading_widget = QWidget()
loading_layout = QVBoxLayout(loading_widget)
status_label = QLabel("Загрузка, пожалуйста, подождите...")
status_label.setAlignment(Qt.AlignCenter)
loading_layout.addWidget(status_label)
self.version_tabs.addTab(loading_widget, "Загрузка...")
self.version_tabs.setEnabled(False)
self.main_tabs.addTab(loading_widget, "Загрузка...")
self.main_tabs.setEnabled(False)
QApplication.processEvents()
self._parse_sha256_list()
self.populate_ui()
self.version_tabs.setEnabled(True)
self.main_tabs.setEnabled(True)
def _parse_sha256_list(self):
"""Парсит sha256sum.list для получения списка версий."""
@@ -1170,10 +1170,10 @@ class WineVersionSelectionDialog(QDialog):
if not line:
continue
match = re.match(r'^#+\s*([^#]+?)\s*#*$', line)
match = re.match(r'^#+\s*(.*?)\s*#*$', line)
if match:
group_name = match.group(1)
allowed_groups = {"WINE", "WINE_LG", "PROTON_LG", "PROTON_STEAM"}
group_name = match.group(1).strip()
allowed_groups = {"WINE WOW64", "WINE AMD64", "WINE I586"}
# Отображаем только группы, которые являются сборками WINE или PROTON
if group_name in allowed_groups:
current_group = group_name
@@ -1194,9 +1194,59 @@ class WineVersionSelectionDialog(QDialog):
QMessageBox.warning(self, "Ошибка", f"Не удалось прочитать файл версий:\n{e}")
self.wine_versions_data = {}
def _get_installed_versions(self):
"""Возвращает список локально установленных версий Wine."""
dist_path = os.path.join(Var.USER_WORK_PATH, "dist")
if not os.path.isdir(dist_path):
return []
try:
return sorted([
name for name in os.listdir(dist_path)
if os.path.isdir(os.path.join(dist_path, name))
], reverse=True)
except OSError:
return []
def populate_ui(self):
"""Заполняет UI отфильтрованными версиями."""
self.version_tabs.clear()
self.main_tabs.clear()
# --- Вкладка "Установленные" ---
installed_tab = QWidget()
self.main_tabs.addTab(installed_tab, "Установленные")
installed_layout = QVBoxLayout(installed_tab)
installed_scroll_area = QScrollArea()
installed_scroll_area.setWidgetResizable(True)
installed_layout.addWidget(installed_scroll_area)
installed_content = QWidget()
installed_scroll_area.setWidget(installed_content)
self.installed_grid_layout = QGridLayout(installed_content)
self.installed_grid_layout.setAlignment(Qt.AlignTop)
installed_versions_for_grid = []
# Системная версия
if shutil.which('wine'):
try:
result = subprocess.run(['wine', '--version'], capture_output=True, text=True, check=True, encoding='utf-8')
self.system_wine_display_name = result.stdout.strip()
except (FileNotFoundError, subprocess.CalledProcessError) as e:
print(f"Не удалось получить версию системного wine: {e}")
self.system_wine_display_name = "Системная версия"
installed_versions_for_grid.append((self.system_wine_display_name, "system"))
# Локально установленные версии
local_versions = self._get_installed_versions()
installed_versions_for_grid.extend(local_versions)
self._create_grid_buttons(self.installed_grid_layout, installed_versions_for_grid)
# --- Вкладка "Скачать" ---
download_tab = QWidget()
download_layout = QVBoxLayout(download_tab)
self.version_tabs = QTabWidget() # Вложенные табы для категорий
download_layout.addWidget(self.version_tabs)
download_tab.setLayout(download_layout)
self.main_tabs.addTab(download_tab, "Скачать")
if not self.wine_versions_data:
error_widget = QWidget()
@@ -1205,55 +1255,33 @@ class WineVersionSelectionDialog(QDialog):
error_label.setAlignment(Qt.AlignCenter)
error_layout.addWidget(error_label)
self.version_tabs.addTab(error_widget, "Ошибка")
self.filter_versions()
return
# --- Фильтрация и сортировка групп в зависимости от архитектуры ---
is_win64 = self.architecture == "win64"
re_32bit = re.compile(r'i[3-6]86|x86(?!_64)')
re_64bit = re.compile(r'amd64|x86_64|wow64')
# --- System Tab ---
if shutil.which('wine'):
self.system_wine_display_name = "Системная версия"
try:
# Пытаемся получить версию системного wine
result = subprocess.run(['wine', '--version'], capture_output=True, text=True, check=True, encoding='utf-8')
version_line = result.stdout.strip()
# Вывод обычно "wine-X.Y.Z"
self.system_wine_display_name = version_line
except (FileNotFoundError, subprocess.CalledProcessError) as e:
print(f"Не удалось получить версию системного wine: {e}")
# Если wine возвращает ошибку, используем имя по умолчанию "Системная версия"
if is_win64:
allowed_groups_for_arch = {"WINE AMD64", "WINE WOW64"}
tab_order = ["WINE AMD64", "WINE WOW64"]
else: # win32
allowed_groups_for_arch = {"WINE I586","WINE AMD64", "WINE WOW64"}
tab_order = ["WINE I586","WINE AMD64", "WINE WOW64"]
self._create_version_tab("Системный", [(self.system_wine_display_name, "system")])
# Определяем желаемый порядок вкладок
tab_order = ["WINE", "WINE_LG", "PROTON_LG", "PROTON_STEAM"]
# Сортируем ключи в соответствии с заданным порядком
group_keys = sorted(self.wine_versions_data.keys(), key=lambda k: tab_order.index(k) if k in tab_order else len(tab_order))
# Получаем только те ключи, которые есть в данных и разрешены для данной архитектуры
available_keys = [key for key in self.wine_versions_data.keys() if key in allowed_groups_for_arch]
# Сортируем доступные ключи в соответствии с заданным порядком
group_keys = sorted(available_keys, key=lambda k: tab_order.index(k))
for key in group_keys:
versions = self.wine_versions_data.get(key, [])
filtered_versions = []
for name in sorted(versions, reverse=True):
if is_win64:
if re_64bit.search(name) or not re_32bit.search(name):
filtered_versions.append(name)
else:
filtered_versions.append(name)
if not filtered_versions:
if not versions:
continue
pretty_key = key.replace('_', ' ').title()
if key.endswith('_LG'):
pretty_key = pretty_key.replace(' Lg', ' LG')
self._create_version_tab(pretty_key, filtered_versions)
self._create_version_tab(key, sorted(versions, reverse=True))
self.filter_versions()
def _create_version_tab(self, title, versions_list):
def _create_version_tab(self, title, versions_list, is_download_tab=True):
"""Создает вкладку с сеткой кнопок для переданного списка версий."""
tab_page = QWidget()
tab_layout = QVBoxLayout(tab_page)
@@ -1269,6 +1297,13 @@ class WineVersionSelectionDialog(QDialog):
grid_layout = QGridLayout(scroll_content)
grid_layout.setAlignment(Qt.AlignTop)
self._create_grid_buttons(grid_layout, versions_list, is_download_tab=is_download_tab)
self.version_tabs.addTab(tab_page, title)
def _create_grid_buttons(self, grid_layout, versions_list, is_download_tab=False):
is_win64_prefix = self.architecture == "win64"
re_32bit_version = re.compile(r'i[3-6]86|i586')
num_columns = 3
row, col = 0, 0
for version_data in versions_list:
@@ -1279,36 +1314,58 @@ class WineVersionSelectionDialog(QDialog):
btn = QPushButton(display_name)
btn.clicked.connect(partial(self.on_version_selected, value_name))
# Выделяем системную версию Wine
if value_name == "system":
btn.setText(f"{display_name} (Системный)")
btn.setToolTip("Системная версия Wine, установленная в вашей ОС.")
# Отключение 32-битных версий Wine при выбранном 64-битного префикса (вкладка "Установленные")
if not is_download_tab and is_win64_prefix:
if re_32bit_version.search(value_name):
btn.setEnabled(False)
btn.setToolTip("Эта 32-битная версия Wine несовместима с 64-битным префиксом.")
grid_layout.addWidget(btn, row, col)
col += 1
if col >= num_columns:
col = 0
row += 1
self.version_tabs.addTab(tab_page, title)
def filter_versions(self):
"""Фильтрует видимость кнопок версий на основе текста поиска."""
search_text = self.search_edit.text().lower()
for i in range(self.version_tabs.count()):
tab_widget = self.version_tabs.widget(i)
# The grid layout is inside a scroll area content widget
grid_layout = tab_widget.findChild(QGridLayout)
if not grid_layout:
continue
# Фильтр для вкладки "Установленные"
if hasattr(self, 'installed_grid_layout'):
self._filter_grid(self.installed_grid_layout, search_text)
any_visible_in_tab = False
for j in range(grid_layout.count()):
btn_widget = grid_layout.itemAt(j).widget()
# Фильтр для вкладок "Скачать"
if hasattr(self, 'version_tabs'):
for i in range(self.version_tabs.count()):
tab_widget = self.version_tabs.widget(i)
grid_layout = tab_widget.findChild(QGridLayout)
if grid_layout:
any_visible = self._filter_grid(grid_layout, search_text)
self.version_tabs.setTabEnabled(i, any_visible)
def _filter_grid(self, grid_layout, search_text):
"""Helper-функция для фильтрации кнопок в одной сетке."""
any_visible_in_grid = False
if not grid_layout:
return False
for j in range(grid_layout.count()):
item = grid_layout.itemAt(j)
if item:
btn_widget = item.widget()
if isinstance(btn_widget, QPushButton):
is_match = search_text in btn_widget.text().lower()
btn_widget.setVisible(is_match)
if is_match:
any_visible_in_tab = True
any_visible_in_grid = True
# Enable/disable tab based on content
self.version_tabs.setTabEnabled(i, any_visible_in_tab)
return any_visible_in_grid
def on_version_selected(self, version_name):
"""Обрабатывает выбор версии."""