Commit 0fe97096 authored by Roman Alifanov's avatar Roman Alifanov

implemented `epm play --product-alternatives` support

parent d2dbfef2
...@@ -48,9 +48,13 @@ class ApplicationManager: ...@@ -48,9 +48,13 @@ class ApplicationManager:
parts = line.split(' - ', 1) # Ограничить сплит до 2 частей parts = line.split(' - ', 1) # Ограничить сплит до 2 частей
if len(parts) == 2: if len(parts) == 2:
name, dscr = map(str.strip, parts) name, dscr = map(str.strip, parts)
alternatives = ApplicationManager.get_alternatives(name)
applications.append({ applications.append({
'name': name.replace('&', '&'), 'name': name.replace('&', '&'),
'dscr': dscr.replace('&', '&') 'dscr': dscr.replace('&', '&'),
"alt": alternatives.split()
}) })
else: else:
# Логгирование некорректной строки для диагностики # Логгирование некорректной строки для диагностики
...@@ -59,6 +63,14 @@ class ApplicationManager: ...@@ -59,6 +63,14 @@ class ApplicationManager:
return applications return applications
@staticmethod @staticmethod
def get_alternatives(name):
alternatives, stderr = subprocess.Popen([
"epm", "play", "--product-alternatives", name
], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, bufsize=1
).communicate()
return alternatives
@staticmethod
def parse_installed_applications_output(output): def parse_installed_applications_output(output):
lines = output.splitlines()[1:] lines = output.splitlines()[1:]
return [line.split(' - ')[0].strip().split()[0] for line in lines] return [line.split(' - ')[0].strip().split()[0] for line in lines]
...@@ -77,7 +77,6 @@ class ApplicationRow(Adw.ActionRow): ...@@ -77,7 +77,6 @@ class ApplicationRow(Adw.ActionRow):
super().__init__(title=app['name'], subtitle=app['dscr']) super().__init__(title=app['name'], subtitle=app['dscr'])
self.app = app self.app = app
self.is_installed = is_installed self.is_installed = is_installed
self.set_selectable(False) self.set_selectable(False)
self.set_activatable(True) self.set_activatable(True)
...@@ -86,6 +85,22 @@ class ApplicationRow(Adw.ActionRow): ...@@ -86,6 +85,22 @@ class ApplicationRow(Adw.ActionRow):
self.add_prefix(self.icon_image) self.add_prefix(self.icon_image)
IconLoader.load_icon_async(self.app['name'], self.set_icon) IconLoader.load_icon_async(self.app['name'], self.set_icon)
self.have_alternatives = False
alternatives = Gtk.StringList()
if app["alt"]:
self.have_alternatives = True
alternatives.append("default")
for alternative in app["alt"]:
alternatives.append(alternative)
self.alt_dropdown = Gtk.DropDown()
self.alt_dropdown.props.model = alternatives
self.alt_dropdown.set_valign(Gtk.Align.CENTER)
self.alt_dropdown.set_halign(Gtk.Align.CENTER)
self.add_suffix(self.alt_dropdown)
self.checkbox = Gtk.CheckButton() self.checkbox = Gtk.CheckButton()
self.checkbox.add_css_class("selection-mode") self.checkbox.add_css_class("selection-mode")
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
from gi.repository import Gtk, Adw, GObject from gi.repository import Gtk, Adw, GObject, GLib
import gettext import gettext
...@@ -114,19 +114,30 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow): ...@@ -114,19 +114,30 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow):
self.props.is_loading = True self.props.is_loading = True
self.update_button_status()
ApplicationManager.get_available_applications(self.on_applications_loaded) ApplicationManager.get_available_applications(self.on_applications_loaded)
ApplicationManager.get_installed_applications(self.on_installed_apps_loaded) ApplicationManager.get_installed_applications(self.on_installed_apps_loaded)
def on_installed_apps_loaded(self, installed_apps, error=None): def on_installed_apps_loaded(self, installed_apps, error=None):
if error: if error:
print(f"Error: {error}") print(f"Error: {error}")
else: self.props.is_loading = False
return
self.installed_apps = installed_apps self.installed_apps = installed_apps
self.clear_choice_listbox() self.clear_choice_listbox()
self.rows = {} self.rows = {}
GLib.timeout_add(100, self.check_applications_loaded)
def check_applications_loaded(self):
if self.applications is not None:
print("Applications loaded. Updating UI...")
self.populate_choice_listbox()
self.update_button_status()
return False
return True
def populate_choice_listbox(self):
for app in self.applications: for app in self.applications:
self.add_application_row(app) self.add_application_row(app)
...@@ -152,7 +163,7 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow): ...@@ -152,7 +163,7 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow):
def update_button_status(self): def update_button_status(self):
"""Update the button status based on the current selection.""" """Update the button status based on the current selection."""
to_install, to_remove = self.get_install_remove_lists() to_install, to_remove = self.get_current_status()
button_states = { button_states = {
(True, True): (_("Remove and install applications"), "suggested-action"), (True, True): (_("Remove and install applications"), "suggested-action"),
...@@ -171,6 +182,22 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow): ...@@ -171,6 +182,22 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow):
# Add the new CSS class # Add the new CSS class
self.apply_button.add_css_class(css_class) self.apply_button.add_css_class(css_class)
def get_current_status(self):
installed_apps = self.installed_apps or []
rows = self.rows or {}
to_install = [
app_name for app_name, row in rows.items()
if row.checkbox.get_active() and app_name not in installed_apps
]
to_remove = [
app_name for app_name, row in rows.items()
if not row.checkbox.get_active() and app_name in installed_apps
]
return to_install, to_remove
def on_search_changed(self, search_entry): def on_search_changed(self, search_entry):
self.choice_listbox.invalidate_filter() # Обновление фильтра при изменении поиска self.choice_listbox.invalidate_filter() # Обновление фильтра при изменении поиска
...@@ -233,7 +260,8 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow): ...@@ -233,7 +260,8 @@ class EepmPlayGuiWindow(Adw.ApplicationWindow):
rows = self.rows or {} rows = self.rows or {}
to_install = [ to_install = [
app_name for app_name, row in rows.items() app_name + "=" + row.alt_dropdown.props.selected_item.props.string if row.have_alternatives and row.alt_dropdown.props.selected_item.props.string != "default" else app_name
for app_name, row in rows.items()
if row.checkbox.get_active() and app_name not in installed_apps if row.checkbox.get_active() and app_name not in installed_apps
] ]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment