Further work on install page

This commit is contained in:
Heliguy
2024-08-21 01:15:36 -04:00
parent d7a77b1a4d
commit bfc2ecd13e
4 changed files with 210 additions and 116 deletions

View File

@@ -11,6 +11,8 @@ template $InstallPage : Adw.BreakpointBin {
setters {
split_view.collapsed: true;
split_view.show-content: false;
results_action_bar.visible: true;
pending_action_bar.visible: true;
}
}
@@ -48,11 +50,29 @@ template $InstallPage : Adw.BreakpointBin {
Adw.ToolbarView {
[top]
Adw.HeaderBar {
[start]
ToggleButton sidebar_button {
icon-name: "dock-left-symbolic";
tooltip-text: _("Show Sidebar");
}
}
Adw.PreferencesPage {
Adw.PreferencesGroup remotes_group {
title: "Choose a Remote";
description: "Choose a remote to search for packages in";
title: _("Search in a Remote");
description: _("Choose a remote to search for new packages");
}
Adw.PreferencesGroup local_group {
title: _("Add a File");
description: _("Install a package from a file on your system");
Adw.ActionRow open_row {
title: _("Open");
subtitle: _("Add the file you want to install");
activatable: true;
[suffix]
Image {
icon-name: "folder-open-symbolic";
}
}
}
}
}
@@ -64,17 +84,6 @@ template $InstallPage : Adw.BreakpointBin {
Adw.ToolbarView sidebar_tbv {
[top]
Adw.HeaderBar header_bar {
show-back-button: false;
[start]
ToggleButton sidebar_button {
icon-name: "dock-left-symbolic";
tooltip-text: _("Show Sidebar");
}
[start]
Button back_button {
icon-name: "left-large-symbolic";
tooltip-text: _("Back");
}
}
[top]
Adw.Clamp {
@@ -109,6 +118,22 @@ template $InstallPage : Adw.BreakpointBin {
}
}
}
[bottom]
ActionBar results_action_bar {
visible: false;
revealed: false;
[center]
Button review_button {
sensitive: bind results_action_bar.revealed;
margin-top: 3;
margin-bottom: 3;
styles ["pill", "suggested-action"]
Adw.ButtonContent {
icon-name: "view-list-bullet-symbolic";
label: _("Review and Install");
}
}
}
}
}
}
@@ -116,41 +141,36 @@ template $InstallPage : Adw.BreakpointBin {
}
;
content:
Adw.NavigationPage results_page {
Adw.NavigationPage pending_page {
title: _("Pending Packages");
Adw.ToolbarView {
[top]
Adw.HeaderBar {
[start]
Button clear_button {
label: _("Remove All");
}
Stack pending_stack {
Adw.StatusPage no_added_packages_status {
icon-name: "flatpak-symbolic";
title: _("Install New Packages");
description: _("Search for a package or add one from a file");
}
Adw.PreferencesPage added_pref_page {
}
}
Adw.PreferencesPage added_pref_page {
}
// Button open_button {
// visible: false;
// Adw.ButtonContent {
// can-shrink: true;
// icon-name: "folder-open-symbolic";
// label: _("Add File");
// }
// }
[bottom]
Box {
homogeneous: true;
styles ["toolbar"]
Button remove_all_button {
styles ["raised"]
Adw.ButtonContent {
can-shrink: true;
icon-name: "minus-large-symbolic";
label: _("Remove All");
}
}
Button open_button {
styles ["raised"]
Adw.ButtonContent {
can-shrink: true;
icon-name: "folder-open-symbolic";
label: _("Add File");
}
}
ActionBar pending_action_bar {
revealed: false;
[center]
Button install_button {
styles ["raised", "suggested-action"]
sensitive: bind pending_action_bar.revealed;
styles ["pill", "suggested-action"]
Adw.ButtonContent {
can-shrink: true;
icon-name: "arrow-pointing-at-line-down-symbolic";
@@ -163,4 +183,4 @@ template $InstallPage : Adw.BreakpointBin {
;
}
}
}
}

View File

@@ -7,6 +7,23 @@ from .result_row import ResultRow
import os, subprocess
class AddedPackage:
def __eq__(self, other):
return (
self.name == other.name and \
self.app_id == other.app_id and \
self.branch == other.branch and \
self.version == other.version and \
self.remote == other.remote and \
self.installation == other.installation
)
def is_similar(self, other):
return (
self.app_id == other.app_id and \
self.branch == other.branch and \
self.version == other.version
)
def __init__(self, name, app_id, branch, version, remote, installation):
self.name = name
self.app_id = app_id
@@ -18,8 +35,6 @@ class AddedPackage:
class AddedGroup(Adw.PreferencesGroup):
__gtype_name__ = "AddedGroup"
package_rows = []
def add_row(self, row):
self.package_rows.append(row)
self.add(row)
@@ -35,6 +50,7 @@ class AddedGroup(Adw.PreferencesGroup):
self.remote = remote
self.installation = installation
self.package_rows = []
self.set_title(f"{remote.title}")
self.set_description(_("Installation: {}").format(installation))
@@ -47,11 +63,17 @@ class InstallPage(Adw.BreakpointBin):
remotes_group = gtc()
sb_page_view = gtc()
results = gtc()
back_button = gtc()
search_entry = gtc()
search_apply_button = gtc()
results_list = gtc()
added_pref_page = gtc()
results_action_bar = gtc()
pending_action_bar = gtc()
review_button = gtc()
split_view = gtc()
sidebar_button = gtc()
pending_stack = gtc()
no_added_packages_status = gtc()
# Referred to in the main window
# It is used to determine if a new page should be made or not
@@ -62,12 +84,23 @@ class InstallPage(Adw.BreakpointBin):
current_remote = None
def start_loading(self):
self.pending_stack.set_visible_child(self.no_added_packages_status)
self.added_packages.clear()
for row in self.remote_rows:
self.remotes_group.remove(row)
self.remote_rows.clear()
self.added_packages.clear()
for _, group in self.added_package_groups.items():
self.added_pref_page.remove(group)
self.added_package_groups.clear()
self.results_action_bar.set_revealed(False)
self.pending_action_bar.set_revealed(False)
self.search_entry.set_text("")
self.results_list.remove_all()
self.sb_page_view.pop()
def end_loading(self):
for installation in HostInfo.installations:
for remote in HostInfo.remotes[installation]:
@@ -84,8 +117,9 @@ class InstallPage(Adw.BreakpointBin):
self.current_remote = remote
self.results.set_title(_("Search {}").format(remote.title))
self.sb_page_view.push(self.results)
self.search_entry.set_text("firefox")
self.search_entry.grab_focus()
self.search_entry.set_text("")
self.results_list.remove_all()
def on_search(self, _):
text = self.search_entry.get_text().strip().lower().replace(" ", "")
@@ -103,7 +137,7 @@ class InstallPage(Adw.BreakpointBin):
try:
output = subprocess.run(['flatpak-spawn', '--host', 'flatpak', 'search', '--columns=all', installation, text], text=True, check=True, capture_output=True).stdout.split("\n")
for i, line in enumerate(output):
for line in output:
info = line.split("\t")
if len(info) != 6:
continue
@@ -118,83 +152,104 @@ class InstallPage(Adw.BreakpointBin):
if not self.current_remote.name in remotes.split(','):
continue
is_added = False
try:
for package in self.added_packages:
if package.name == name and package.app_id == app_id and package.version == version and package.branch == branch:
is_added = True
break
current = AddedPackage(name, app_id, branch, version, self.current_remote, self.current_installation)
row = ResultRow(current)
row.connect("activated", self.add_package)
self.results_list.append(row)
for other in self.added_packages:
if current.is_similar(other):
row.set_is_added(True)
break
except KeyError:
print("passing key error")
if not is_added:
row = ResultRow(name, app_id, branch, version)
row.connect("activated", self.add_package, i, name, app_id, branch, version)
self.results_list.append(row)
except subprocess.CalledProcessError as cpe:
print(cpe.stderr)
except Exception as e:
print(e)
except subprocess.CalledProcessError as cpe:
print(cpe)
thread()
def add_package(self, row):
row.set_is_added(True)
self.added_packages.append(row.package)
self.list_focus_grabber(row)
added_row = ResultRow(row.package, True)
self.results_action_bar.set_revealed(True)
self.pending_action_bar.set_revealed(True)
try:
key = f"{row.package.remote}<>{row.package.installation}"
group = self.added_package_groups[key]
group.add_row(added_row)
except KeyError:
group = AddedGroup(row.package.remote, row.package.installation)
group.add_row(added_row)
self.added_package_groups[key] = group
self.added_pref_page.add(group)
added_row.connect("activated", self.rem_package, group)
self.pending_stack.set_visible_child(self.added_pref_page)
def rem_package(self, row, group):
if not row.package in self.added_packages:
return
self.added_packages.remove(row.package)
if len(self.added_packages) == 0:
self.results_action_bar.set_revealed(False)
self.pending_action_bar.set_revealed(False)
i = 0
while rover := self.results_list.get_row_at_index(i):
i += 1
if not rover.is_added:
continue
if row.package.is_similar(rover.package):
rover.set_is_added(False)
break
group.rem_row(row)
if len(group.package_rows) == 0:
self.added_pref_page.remove(group)
self.added_package_groups.pop(f'{row.package.remote}<>{row.package.installation}', None)
if len(self.added_package_groups) == 0:
self.pending_stack.set_visible_child(self.no_added_packages_status)
def list_focus_grabber(self, row):
i = 0
prev_visible_row = None
prev_unadded_row = None
while rover := self.results_list.get_row_at_index(i):
i += 1
if rover is row:
break
if rover.get_visible():
prev_visible_row = rover
if not rover.is_added:
prev_unadded_row = rover
while rover := self.results_list.get_row_at_index(i):
i += 1
if rover.get_visible():
if not rover.is_added:
rover.grab_focus()
return
if prev_visible_row:
prev_visible_row.grab_focus()
def add_package(self, row, index, name, app_id, branch, version):
key = f"{self.current_remote}<>{self.current_installation}"
package = AddedPackage(name, app_id, branch, version, self.current_remote, self.current_installation)
added_row = ResultRow(name, app_id, branch, version, row)
self.added_packages.append(package)
group = None
try:
group = self.added_package_groups[key]
group.add_row(added_row)
except KeyError:
group = AddedGroup(self.current_remote, self.current_installation)
self.added_package_groups[key] = group
self.added_pref_page.add(group)
group.add_row(added_row)
except Exception as e:
print(e)
return
added_row.connect("activated", self.remove_package, group)
row.set_visible(False)
self.list_focus_grabber(row)
def remove_package(self, row, group):
row.original_row.set_visible(True)
group.rem_row(row)
if len(group.package_rows) == 0:
group.set_visible(False)
if prev_unadded_row:
prev_unadded_row.grab_focus()
def __init__(self, main_window, **kwargs):
super().__init__(**kwargs)
self.instance = self
self.main_window = main_window
self.remote_rows = []
self.added_packages = [] # remote<>installation
self.added_packages = []
self.added_package_groups = {} # remote<>installation
self.back_button.connect("clicked", lambda *_: self.sb_page_view.pop())
# self.back_button.connect("clicked", lambda *_: self.sb_page_view.pop())
# self.search_entry.connect("search-changed", self.on_search)
self.search_entry.connect("activate", self.on_search)
self.search_apply_button.connect("clicked", self.on_search)
self.search_apply_button.connect("clicked", self.on_search)
self.review_button.connect("clicked", lambda *_: self.split_view.set_show_content(True))
ms = main_window.main_split
ms.connect("notify::show-sidebar", lambda *_: self.sidebar_button.set_active(ms.get_show_sidebar()))
self.sidebar_button.connect("toggled", lambda *_: ms.set_show_sidebar(self.sidebar_button.get_active()))

View File

@@ -5,6 +5,7 @@ template $ResultRow : Adw.ActionRow {
activatable: true;
title: "No title set";
subtitle: "No subtitle set";
tooltip-text: _("Add Package to Queue");
Box {
orientation: vertical;
@@ -36,4 +37,15 @@ template $ResultRow : Adw.ActionRow {
Image sub_image {
icon-name: "minus-large-symbolic";
}
}
[suffix]
Image selected_image {
icon-name: "check-plain-symbolic";
visible: false;
}
[suffix]
Image already_installed_image {
visible: false;
icon-name: "selection-mode-symbolic";
styles ["success"]
}
}

View File

@@ -1,4 +1,4 @@
from gi.repository import Adw, Gtk, GLib, Gio
from gi.repository import Adw, Gtk, GLib, Gio, Gdk
from .host_info import HostInfo
from .error_toast import ErrorToast
import os, subprocess
@@ -12,25 +12,32 @@ class ResultRow(Adw.ActionRow):
branch_label = gtc()
add_image = gtc()
sub_image = gtc()
selected_image = gtc()
def idle_stuff(self):
self.set_title(GLib.markup_escape_text(self.name))
self.set_subtitle(self.app_id)
self.version_label.set_label(GLib.markup_escape_text(self.version))
self.branch_label.set_label(GLib.markup_escape_text(self.branch))
self.set_title(GLib.markup_escape_text(self.package.name))
self.set_subtitle(self.package.app_id)
self.version_label.set_label(GLib.markup_escape_text(self.package.version))
self.branch_label.set_label(GLib.markup_escape_text(self.package.branch))
self.version_label.set_visible(len(self.version_label.get_label()) != 0)
self.branch_label.set_visible(len(self.branch_label.get_label()) != 0)
self.sub_image.set_visible(bool(self.original_row))
self.add_image.set_visible(not bool(self.original_row))
self.set_tooltip_text(_("Remove Package from Queue") if bool(self.original_row) else _("Add Package to Queue"))
if self.is_added:
self.set_tooltip_text(_("Remove Package from Queue"))
def __init__(self, name, app_id, branch, version, original_row=None, **kwargs):
def set_is_added(self, is_added):
self.is_added = is_added
self.set_sensitive(not is_added)
self.add_image.set_visible(not is_added)
self.selected_image.set_visible(is_added)
self.set_tooltip_text(_("This package is queued") if is_added else _("Add Package to Queue"))
def __init__(self, package, is_added=False, **kwargs):
super().__init__(**kwargs)
self.name = name
self.app_id = app_id
self.branch = branch
self.version = version
self.original_row = original_row
self.is_added = is_added
self.package = package
GLib.idle_add(self.idle_stuff)
self.sub_image.set_visible(is_added)
self.add_image.set_visible(not is_added)
GLib.idle_add(self.idle_stuff)