mirror of
https://github.com/morgan9e/warehouse
synced 2026-04-15 00:34:42 +09:00
Fully complete the Install From The Web window, for installing new paks
This commit is contained in:
@@ -5,13 +5,13 @@
|
||||
### Features that have all work done and will release in the next update (ready to ship)
|
||||
|
||||
- Remembering filters on app close
|
||||
- Loading pages display the current working task, and how much is left
|
||||
|
||||
### Features that might release in the next update, but will release in some update
|
||||
|
||||
- Installing flatpaks from a search
|
||||
- Edit flatpak pins
|
||||
- Uninstall unused packages
|
||||
- Loading pages display the current working task, and how much is left
|
||||
|
||||
# Features Being Considered
|
||||
|
||||
|
||||
2
data/icons/left-large-symbolic.svg
Normal file
2
data/icons/left-large-symbolic.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="16px" viewBox="0 0 16 16" width="16px"><filter id="a" height="100%" width="100%" x="0%" y="0%"><feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/></filter><mask id="b"><g filter="url(#a)"><path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.5"/></g></mask><clipPath id="c"><path d="m 0 0 h 1600 v 1200 h -1600 z"/></clipPath><mask id="d"><g filter="url(#a)"><path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.7"/></g></mask><clipPath id="e"><path d="m 0 0 h 1600 v 1200 h -1600 z"/></clipPath><mask id="f"><g filter="url(#a)"><path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.35"/></g></mask><clipPath id="g"><path d="m 0 0 h 1600 v 1200 h -1600 z"/></clipPath><g mask="url(#b)"><g clip-path="url(#c)" transform="matrix(1 0 0 1 -980 -140)"><path d="m 550 182 c -0.351562 0.003906 -0.695312 0.101562 -1 0.28125 v 3.4375 c 0.304688 0.179688 0.648438 0.277344 1 0.28125 c 1.105469 0 2 -0.894531 2 -2 s -0.894531 -2 -2 -2 z m 0 5 c -0.339844 0 -0.679688 0.058594 -1 0.175781 v 6.824219 h 4 v -4 c 0 -1.65625 -1.34375 -3 -3 -3 z m 0 0"/></g></g><g mask="url(#d)"><g clip-path="url(#e)" transform="matrix(1 0 0 1 -980 -140)"><path d="m 569 182 v 4 c 1.105469 0 2 -0.894531 2 -2 s -0.894531 -2 -2 -2 z m 0 5 v 7 h 3 v -4 c 0 -1.65625 -1.34375 -3 -3 -3 z m 0 0"/></g></g><g mask="url(#f)"><g clip-path="url(#g)" transform="matrix(1 0 0 1 -980 -140)"><path d="m 573 182.269531 v 3.449219 c 0.613281 -0.355469 0.996094 -1.007812 1 -1.71875 c 0 -0.714844 -0.382812 -1.375 -1 -1.730469 z m 0 4.90625 v 6.824219 h 2 v -4 c 0 -1.269531 -0.800781 -2.402344 -2 -2.824219 z m 0 0"/></g></g><path d="m 10.9375 0.996094 c -0.292969 0 -0.558594 0.128906 -0.742188 0.328125 l -6.671874 6.671875 l 6.671874 6.675781 c 0.011719 0.011719 0.023438 0.023437 0.035157 0.03125 c 0.179687 0.183594 0.429687 0.292969 0.707031 0.292969 h 1 v -1 c 0 -0.273438 -0.113281 -0.523438 -0.292969 -0.707032 c -0.011719 -0.007812 -0.019531 -0.019531 -0.035156 -0.03125 l -5.257813 -5.257812 l 5.292969 -5.292969 c 0.179688 -0.183593 0.292969 -0.433593 0.292969 -0.707031 v -1 z m 0 0" fill="#222222"/></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -87,7 +87,7 @@ template $OrphansWindow: Adw.Window {
|
||||
}
|
||||
|
||||
Label installing_status {
|
||||
label: _("");
|
||||
label: "";
|
||||
justify: center;
|
||||
|
||||
styles [
|
||||
|
||||
@@ -4,89 +4,88 @@ using Adw 1;
|
||||
template $SearchInstallWindow: Adw.Window {
|
||||
default-width: 500;
|
||||
default-height: 450;
|
||||
title: _("Install From The Web…");
|
||||
title: "";
|
||||
modal: true;
|
||||
|
||||
Adw.ToolbarView main_toolbar_view {
|
||||
content:
|
||||
Stack outer_stack {
|
||||
Adw.NavigationView nav_view {
|
||||
Adw.NavigationPage search_page {
|
||||
title: _("Search Criteria");
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
HeaderBar header_bar {
|
||||
show-title-buttons: false;
|
||||
|
||||
[start]
|
||||
Button cancel_button {
|
||||
label: _("Cancel");
|
||||
HeaderBar {
|
||||
}
|
||||
|
||||
[end]
|
||||
content:
|
||||
Adw.StatusPage {
|
||||
title: _("Choose a Remote to Search");
|
||||
valign: start;
|
||||
child:
|
||||
Adw.Clamp {
|
||||
ListBox remotes_list {
|
||||
selection-mode: none;
|
||||
styles ["boxed-list"]
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.NavigationPage results_page {
|
||||
title: _("Results");
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
HeaderBar {
|
||||
[start]
|
||||
Button back_button {
|
||||
tooltip-text: _("Back");
|
||||
icon-name: "left-large-symbolic";
|
||||
}
|
||||
}
|
||||
[bottom]
|
||||
ActionBar action_bar {
|
||||
revealed: false;
|
||||
[center]
|
||||
Button install_button {
|
||||
label: _("Install");
|
||||
|
||||
styles [
|
||||
margin-top: 6;
|
||||
margin-bottom: 6;
|
||||
styles[
|
||||
"pill",
|
||||
"suggested-action"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Adw.ButtonContent {
|
||||
label: _("Install");
|
||||
icon-name: "plus-large-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
[top]
|
||||
Adw.Clamp {
|
||||
Box {
|
||||
margin-top: 6;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
|
||||
styles [
|
||||
"linked"
|
||||
]
|
||||
|
||||
[start]
|
||||
SearchEntry search_entry {
|
||||
hexpand: true;
|
||||
placeholder-text: _("Search for Flatpaks…");
|
||||
}
|
||||
|
||||
[start]
|
||||
MenuButton remotes_dropdown {
|
||||
label: _("All Remotes");
|
||||
}
|
||||
|
||||
[start]
|
||||
Button search_button {
|
||||
tooltip-text: _("Search");
|
||||
icon-name: "system-search-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
content: Adw.ToastOverlay toast_overlay {
|
||||
Stack main_stack {
|
||||
Overlay main_overlay {
|
||||
[overlay]
|
||||
ProgressBar progress_bar {
|
||||
pulse-step: 0.7;
|
||||
can-target: false;
|
||||
|
||||
styles [
|
||||
"osd"
|
||||
]
|
||||
}
|
||||
|
||||
ScrolledWindow {
|
||||
Adw.Clamp {
|
||||
ListBox results_list_box {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
Box search_box {
|
||||
margin-top: 4;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-bottom: 6;
|
||||
SearchEntry search_entry {
|
||||
hexpand: true;
|
||||
valign: start;
|
||||
selection-mode: none;
|
||||
}
|
||||
Button search_button {
|
||||
icon-name: "right-large-symbolic";
|
||||
tooltip-text: _("Start Search");
|
||||
}
|
||||
styles ["linked"]
|
||||
}
|
||||
}
|
||||
content:
|
||||
Stack inner_stack {
|
||||
|
||||
styles [
|
||||
"boxed-list"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.StatusPage blank_page {
|
||||
title: _("Search for Flatpaks");
|
||||
icon-name: "flatpak-symbolic";
|
||||
description: _("Search for Flatpaks that you want to install");
|
||||
}
|
||||
|
||||
Adw.StatusPage no_results {
|
||||
@@ -95,22 +94,29 @@ template $SearchInstallWindow: Adw.Window {
|
||||
description: _("Try a different search term");
|
||||
}
|
||||
|
||||
Adw.StatusPage blank_page {
|
||||
title: _("Search for Flatpaks");
|
||||
icon-name: "flatpak-symbolic";
|
||||
description: _("Search for Flatpaks that you want to install");
|
||||
}
|
||||
|
||||
Adw.StatusPage loading_page {
|
||||
title: C_("Shown with a spinner while search operation is pending", "Searching");
|
||||
|
||||
Spinner {
|
||||
spinning: true;
|
||||
height-request: 32;
|
||||
width-request: 32;
|
||||
margin-top: 0;
|
||||
Box loading_page {
|
||||
orientation: vertical;
|
||||
spacing: 10;
|
||||
margin-top: 40;
|
||||
margin-bottom: 20;
|
||||
halign: center;
|
||||
valign: center;
|
||||
|
||||
Spinner {
|
||||
margin-bottom: 35;
|
||||
width-request: 30;
|
||||
height-request: 30;
|
||||
opacity: 0.5;
|
||||
spinning: true;
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Searching");
|
||||
|
||||
styles [
|
||||
"title-1",
|
||||
"title"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +125,74 @@ template $SearchInstallWindow: Adw.Window {
|
||||
title: _("Too Many Results");
|
||||
description: _("Try being more specific with your search");
|
||||
}
|
||||
|
||||
ScrolledWindow results_scroll {
|
||||
vexpand: true;
|
||||
Adw.Clamp {
|
||||
ListBox results_list {
|
||||
margin-top: 6;
|
||||
margin-bottom: 12;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
hexpand: true;
|
||||
valign: start;
|
||||
selection-mode: none;
|
||||
styles ["boxed-list"]
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.ToolbarView installing {
|
||||
[top]
|
||||
HeaderBar {
|
||||
}
|
||||
content:
|
||||
Overlay overlay {
|
||||
[overlay]
|
||||
ProgressBar progress_bar {
|
||||
visible: false;
|
||||
can-target: false;
|
||||
styles ["osd"]
|
||||
}
|
||||
Box {
|
||||
orientation: vertical;
|
||||
spacing: 10;
|
||||
margin-top: 40;
|
||||
margin-bottom: 20;
|
||||
halign: center;
|
||||
valign: center;
|
||||
|
||||
Spinner {
|
||||
margin-bottom: 35;
|
||||
width-request: 30;
|
||||
height-request: 30;
|
||||
opacity: 0.5;
|
||||
spinning: true;
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Installing");
|
||||
|
||||
styles [
|
||||
"title-1",
|
||||
"title"
|
||||
]
|
||||
}
|
||||
|
||||
Label installing_status {
|
||||
label: "";
|
||||
justify: center;
|
||||
|
||||
styles [
|
||||
"description",
|
||||
"body"
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,6 +36,13 @@ template $WarehouseWindow: Adw.ApplicationWindow {
|
||||
icon-name: "selection-mode-symbolic";
|
||||
tooltip-text: _("Toggle Selection Mode");
|
||||
}
|
||||
|
||||
[end]
|
||||
MenuButton install_button {
|
||||
icon-name: "plus-large-symbolic";
|
||||
tooltip-text: _("Install New Flatpak");
|
||||
menu-model: install_menu;
|
||||
}
|
||||
}
|
||||
|
||||
[top]
|
||||
@@ -137,7 +144,7 @@ template $WarehouseWindow: Adw.ApplicationWindow {
|
||||
}
|
||||
|
||||
Label uninstalling_status {
|
||||
label: _("");
|
||||
label: "";
|
||||
justify: center;
|
||||
styles ["description", "body"]
|
||||
}
|
||||
@@ -237,11 +244,6 @@ template $WarehouseWindow: Adw.ApplicationWindow {
|
||||
|
||||
menu primary_menu {
|
||||
section {
|
||||
item {
|
||||
label: _("Install From File…");
|
||||
action: "app.install-from-file";
|
||||
}
|
||||
|
||||
item {
|
||||
label: _("Manage Leftover Data…");
|
||||
action: "app.manage-data-folders";
|
||||
@@ -256,11 +258,6 @@ menu primary_menu {
|
||||
action: "app.show-remotes-window";
|
||||
}
|
||||
|
||||
// item {
|
||||
// label: _("Install From The Web…");
|
||||
// action: "app.open-search-install";
|
||||
// }
|
||||
|
||||
item {
|
||||
label: _("_Keyboard Shortcuts");
|
||||
action: "win.show-help-overlay";
|
||||
@@ -292,11 +289,16 @@ menu copy_menu {
|
||||
}
|
||||
}
|
||||
|
||||
menu row_menu {
|
||||
menu install_menu {
|
||||
section {
|
||||
item {
|
||||
label: _("Open App");
|
||||
//action: "win.open-app";
|
||||
label: _("Install From File…");
|
||||
action: "app.install-from-file";
|
||||
}
|
||||
|
||||
item {
|
||||
label: _("Install From The Web…");
|
||||
action: "app.open-search-install";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
src/main.py
11
src/main.py
@@ -32,6 +32,7 @@ from .orphans_window import OrphansWindow
|
||||
from .filter_window import FilterWindow
|
||||
from .search_install_window import SearchInstallWindow
|
||||
from .const import Config
|
||||
from .common import myUtils
|
||||
|
||||
|
||||
class WarehouseApplication(Adw.Application):
|
||||
@@ -70,7 +71,7 @@ class WarehouseApplication(Adw.Application):
|
||||
self.create_action("set-filter", self.filters_shortcut, ["<primary>t"])
|
||||
self.create_action("install-from-file", self.install_from_file, ["<primary>o"])
|
||||
self.create_action("open-menu", self.main_menu_shortcut, ["F10"])
|
||||
# self.create_action("open-search-install", self.open_search_install, ["<primary>i"])
|
||||
self.create_action("open-search-install", self.open_search_install, ["<primary>i"])
|
||||
|
||||
gtk_version = (
|
||||
str(Gtk.MAJOR_VERSION)
|
||||
@@ -99,6 +100,14 @@ class WarehouseApplication(Adw.Application):
|
||||
lang=lang,
|
||||
)
|
||||
|
||||
my_utils = myUtils(self)
|
||||
total = 0
|
||||
for rem in my_utils.get_host_remotes():
|
||||
if my_utils.get_install_type(rem[7]) != "disabled":
|
||||
total += 1
|
||||
if total < 2:
|
||||
self.lookup_action(f"open-search-install").set_enabled(False)
|
||||
|
||||
def open_search_install(self, widget, _):
|
||||
SearchInstallWindow(self.props.active_window).present()
|
||||
|
||||
|
||||
@@ -4,6 +4,34 @@ import subprocess
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
class RemoteRow(Adw.ActionRow):
|
||||
def __init__(self, remote, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
my_utils = myUtils(self)
|
||||
self.install_type = my_utils.get_install_type(remote[7])
|
||||
if self.install_type == "disabled":
|
||||
self.set_visible(False)
|
||||
return
|
||||
self.set_activatable(True)
|
||||
self.remote = remote
|
||||
if remote[1] == "-":
|
||||
self.set_title(remote[0])
|
||||
else:
|
||||
self.set_title(remote[1])
|
||||
self.set_subtitle(_("{} wide").format(self.install_type))
|
||||
self.add_suffix(Gtk.Image.new_from_icon_name("right-large-symbolic"))
|
||||
|
||||
class ResultRow(Adw.ActionRow):
|
||||
def __init__(self, flatpak, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
my_utils = myUtils(self)
|
||||
self.flatpak = flatpak
|
||||
self.set_title(GLib.markup_escape_text(flatpak[0]))
|
||||
self.set_subtitle(GLib.markup_escape_text(flatpak[1]))
|
||||
self.check = Gtk.CheckButton()
|
||||
self.check.add_css_class("selection-mode")
|
||||
self.add_suffix(self.check)
|
||||
self.set_activatable_widget(self.check)
|
||||
|
||||
@Gtk.Template(
|
||||
resource_path="/io/github/flattool/Warehouse/../data/ui/search_install.ui"
|
||||
@@ -13,144 +41,179 @@ class SearchInstallWindow(
|
||||
): # TODO: stop execution of thread when search is changed
|
||||
__gtype_name__ = "SearchInstallWindow"
|
||||
|
||||
results_list_box = Gtk.Template.Child()
|
||||
main_stack = Gtk.Template.Child()
|
||||
main_overlay = Gtk.Template.Child()
|
||||
no_results = Gtk.Template.Child()
|
||||
too_many = Gtk.Template.Child()
|
||||
cancel_button = Gtk.Template.Child()
|
||||
blank_page = Gtk.Template.Child()
|
||||
loading_page = Gtk.Template.Child()
|
||||
search_button = Gtk.Template.Child()
|
||||
back_button = Gtk.Template.Child()
|
||||
nav_view = Gtk.Template.Child()
|
||||
search_page = Gtk.Template.Child()
|
||||
results_page = Gtk.Template.Child()
|
||||
remotes_list = Gtk.Template.Child()
|
||||
search_entry = Gtk.Template.Child()
|
||||
remotes_dropdown = Gtk.Template.Child()
|
||||
|
||||
is_debug = GLib.environ_getenv(GLib.get_environ(), "G_MESSAGES_DEBUG") == "all"
|
||||
blank_page = Gtk.Template.Child()
|
||||
inner_stack = Gtk.Template.Child()
|
||||
outer_stack = Gtk.Template.Child()
|
||||
loading_page = Gtk.Template.Child()
|
||||
results_scroll = Gtk.Template.Child()
|
||||
results_list = Gtk.Template.Child()
|
||||
too_many = Gtk.Template.Child()
|
||||
action_bar = Gtk.Template.Child()
|
||||
search_button = Gtk.Template.Child()
|
||||
no_results = Gtk.Template.Child()
|
||||
install_button = Gtk.Template.Child()
|
||||
installing = Gtk.Template.Child()
|
||||
installing_status = Gtk.Template.Child()
|
||||
search_box = Gtk.Template.Child()
|
||||
toast_overlay = Gtk.Template.Child()
|
||||
progress_bar = Gtk.Template.Child()
|
||||
|
||||
def key_handler(self, controller, keyval, keycode, state):
|
||||
if keyval == Gdk.KEY_Escape or (keyval == Gdk.KEY_w and state == Gdk.ModifierType.CONTROL_MASK):
|
||||
self.close()
|
||||
|
||||
def search_response(self, a, b):
|
||||
self.results_list_box.remove_all()
|
||||
print(self.search_results)
|
||||
if (self.is_debug and len(self.search_results) == 5) or (
|
||||
len(self.search_results) == 1 and len(self.search_results[0]) == 1
|
||||
): # This is unreliable with G_DEBUG
|
||||
self.main_stack.set_visible_child(self.no_results)
|
||||
def reset(self):
|
||||
self.results = []
|
||||
self.results_list.remove_all()
|
||||
self.inner_stack.set_visible_child(self.blank_page)
|
||||
|
||||
def check_handler(self, button, row):
|
||||
if button.get_active():
|
||||
self.selected.append(row.flatpak)
|
||||
else:
|
||||
self.selected.remove(row.flatpak)
|
||||
if len(self.selected) == 0:
|
||||
self.set_title(self.title)
|
||||
self.action_bar.set_revealed(False)
|
||||
else:
|
||||
self.set_title(_("{} Selected").format(len(self.selected)))
|
||||
self.action_bar.set_revealed(True)
|
||||
|
||||
def generate_remotes_list(self):
|
||||
total = 0
|
||||
for rem in self.host_remotes:
|
||||
if self.my_utils.get_install_type(rem[7]) != "disabled":
|
||||
total += 1
|
||||
if total < 2:
|
||||
self.nav_view.push(self.results_page)
|
||||
self.back_button.set_visible(False)
|
||||
self.back_button.set_sensitive(False)
|
||||
self.search_remote = self.host_remotes[0][0]
|
||||
self.install_type = self.host_remotes[0][7]
|
||||
self.nav_view.connect("popped", lambda *_: self.nav_view.push(self.results_page))
|
||||
self.nav_view.set_animate_transitions(False)
|
||||
self.title = _("Search {}").format(self.search_remote)
|
||||
self.set_title(self.title)
|
||||
self.search_entry.set_placeholder_text(_("Search {}").format(self.search_remote))
|
||||
self.search_entry.grab_focus()
|
||||
return
|
||||
if len(self.search_results) > 50:
|
||||
self.main_stack.set_visible_child(self.too_many)
|
||||
self.nav_view.connect("popped", lambda *_: self.set_title(""))
|
||||
for remote in self.host_remotes:
|
||||
row = RemoteRow(remote)
|
||||
row.connect("activated", self.remote_choice)
|
||||
self.remotes_list.append(row)
|
||||
|
||||
def generate_results_list(self):
|
||||
for pak in self.results:
|
||||
row = ResultRow(pak)
|
||||
row.check.set_active(row.flatpak in self.selected)
|
||||
row.check.connect("toggled", self.check_handler, row)
|
||||
if self.search_remote in row.flatpak[5]:
|
||||
self.results_list.append(row)
|
||||
if self.results_list.get_row_at_index(0):
|
||||
self.inner_stack.set_visible_child(self.results_scroll)
|
||||
else:
|
||||
self.inner_stack.set_visible_child(self.no_results)
|
||||
|
||||
def remote_choice(self, row):
|
||||
self.reset()
|
||||
self.selected = []
|
||||
self.install_type = row.install_type
|
||||
self.search_remote = row.remote[0]
|
||||
self.search_entry.set_placeholder_text(_("Search {}").format(self.search_remote))
|
||||
self.title = _("Search {}").format(self.search_remote)
|
||||
self.set_title(self.title)
|
||||
self.nav_view.push(self.results_page)
|
||||
self.search_entry.grab_focus()
|
||||
self.action_bar.set_revealed(len(self.selected) > 0)
|
||||
|
||||
def search_handler(self, *args):
|
||||
self.reset()
|
||||
self.inner_stack.set_visible_child(self.loading_page)
|
||||
query = self.search_entry.get_text().strip()
|
||||
if query == "":
|
||||
self.inner_stack.set_visible_child(self.blank_page)
|
||||
return
|
||||
self.main_stack.set_visible_child(self.main_overlay)
|
||||
for i in range(len(self.search_results)):
|
||||
try:
|
||||
print("creating row {}".format(str(i)))
|
||||
row = Adw.ActionRow(
|
||||
title=GLib.markup_escape_text(self.search_results[i][0]),
|
||||
subtitle=self.search_results[i][2],
|
||||
)
|
||||
print("row {} is {}".format(str(i), self.search_results[i][0]))
|
||||
check = Gtk.CheckButton()
|
||||
check.add_css_class("selection-mode")
|
||||
check.connect("toggled", self.on_check)
|
||||
label = Gtk.Label(
|
||||
label=self.search_results[i][3],
|
||||
justify=Gtk.Justification.RIGHT,
|
||||
wrap=True,
|
||||
hexpand=True,
|
||||
)
|
||||
row.add_suffix(label)
|
||||
row.add_suffix(check)
|
||||
row.set_activatable_widget(check)
|
||||
self.results_list_box.append(row)
|
||||
except:
|
||||
print("Could not create row")
|
||||
|
||||
def on_check(self, button):
|
||||
print(button.get_active())
|
||||
|
||||
def search_thread(self):
|
||||
command = [
|
||||
"flatpak-spawn",
|
||||
"--host",
|
||||
"flatpak",
|
||||
"search",
|
||||
"--columns=all",
|
||||
self.to_search,
|
||||
]
|
||||
if self.remote_to_search:
|
||||
command += self.remote_to_search
|
||||
|
||||
def search_thread(*args):
|
||||
command = ['flatpak-spawn', '--host', 'flatpak', 'search', '--columns=all', query]
|
||||
output = subprocess.run(
|
||||
command, capture_output=True, text=True, env=self.new_env
|
||||
).stdout
|
||||
lines = output.strip().split("\n")
|
||||
columns = lines[0].split("\t")
|
||||
data = [columns]
|
||||
for line in lines[1:]:
|
||||
row = line.split("\t")
|
||||
data.append(row)
|
||||
data = sorted(data, key=lambda item: item[0].lower())
|
||||
self.search_results = data
|
||||
).stdout.strip().split('\n')
|
||||
for elm in output:
|
||||
self.results.append(elm.split("\t"))
|
||||
|
||||
def on_search(self, widget):
|
||||
self.main_stack.set_visible_child(self.loading_page)
|
||||
self.to_search = self.search_entry.get_text()
|
||||
if len(self.to_search) < 1 or " " in self.to_search:
|
||||
self.results_list_box.remove_all()
|
||||
self.main_stack.set_visible_child(self.blank_page)
|
||||
def done(*args):
|
||||
if len(self.results) > 50:
|
||||
self.inner_stack.set_visible_child(self.too_many)
|
||||
return
|
||||
task = Gio.Task.new(None, None, self.search_response)
|
||||
task.run_in_thread(lambda *_: self.search_thread())
|
||||
if ['No matches found'] in self.results:
|
||||
self.inner_stack.set_visible_child(self.no_results)
|
||||
return
|
||||
self.generate_results_list()
|
||||
|
||||
def set_choice(self, index):
|
||||
print(index)
|
||||
task = Gio.Task.new(None, None, done)
|
||||
task.run_in_thread(search_thread)
|
||||
|
||||
def remotes_chooser_creator(self):
|
||||
remotes_pop = Gtk.Popover()
|
||||
remotes_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
# remotes_pop.set_size_request(400, 1) # why?
|
||||
remotes_pop.set_child(remotes_box) # don't use ScrolledWindows in popovers!
|
||||
def install_handler(self, *args):
|
||||
paks = []
|
||||
for pak in self.selected:
|
||||
paks.append(pak[2])
|
||||
self.outer_stack.set_visible_child(self.installing)
|
||||
self.set_title(_("Install From The Web"))
|
||||
|
||||
# why not just comment this code out and leave it unimplemented— it does nothing of use
|
||||
for i in range(1, 3):
|
||||
x = 0
|
||||
height = remotes_pop.get_size(x)
|
||||
all = Gtk.Button(label="all")
|
||||
all.add_css_class("flat")
|
||||
remotes_box.append(all)
|
||||
print(x)
|
||||
def thread(*args):
|
||||
self.my_utils.install_flatpak(paks, self.search_remote, self.install_type, self.progress_bar, self.installing_status)
|
||||
|
||||
self.remotes_dropdown.set_popover(remotes_pop)
|
||||
def done(*args):
|
||||
self.parent_window.refresh_list_of_flatpaks(None, False)
|
||||
self.disconnect(self.no_close_id) # Make window able to close
|
||||
if self.my_utils.install_success:
|
||||
self.close()
|
||||
self.parent_window.toast_overlay.add_toast(Adw.Toast.new(_("Installed successfully")))
|
||||
else:
|
||||
self.progress_bar.set_visible(False)
|
||||
self.nav_view.pop()
|
||||
self.outer_stack.set_visible_child(self.nav_view)
|
||||
self.toast_overlay.add_toast(Adw.Toast.new(_("Some apps didn't install")))
|
||||
|
||||
self.no_close_id = self.connect(
|
||||
"close-request", lambda event: True
|
||||
) # Make window unable to close
|
||||
task = Gio.Task.new(None, None, done)
|
||||
task.run_in_thread(thread)
|
||||
|
||||
def __init__(self, parent_window, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Create Variables
|
||||
self.my_utils = myUtils(self)
|
||||
self.search_results = []
|
||||
self.to_search = ""
|
||||
self.new_env = dict(os.environ)
|
||||
self.new_env["LC_ALL"] = "C"
|
||||
event_controller = Gtk.EventControllerKey()
|
||||
event_controller.connect("key-pressed", self.key_handler)
|
||||
self.cancel_button.connect("clicked", lambda *_: self.close())
|
||||
self.host_remotes = self.my_utils.get_host_remotes()
|
||||
self.parent_window = parent_window
|
||||
self.results = []
|
||||
self.selected = []
|
||||
self.search_remote = ""
|
||||
self.install_type = ""
|
||||
self.title = _("Install From The Web")
|
||||
|
||||
self.back_button.connect("clicked", lambda *_: self.nav_view.pop())
|
||||
self.search_entry.connect("activate", self.search_handler)
|
||||
self.search_button.connect("clicked", self.search_handler)
|
||||
self.install_button.connect("clicked", self.install_handler)
|
||||
|
||||
# Apply Widgets
|
||||
self.add_controller(event_controller)
|
||||
self.set_transient_for(parent_window)
|
||||
# self.search_bar.connect_entry(self.search_entry)
|
||||
self.search_entry.connect("activate", self.on_search)
|
||||
self.search_button.connect("clicked", self.on_search)
|
||||
self.search_entry.connect("changed", lambda *_: self.search_entry.grab_focus())
|
||||
# self.search_entry.set_key_capture_widget(self.results_list_box)
|
||||
self.search_entry.grab_focus()
|
||||
|
||||
self.host_remotes = self.my_utils.get_host_remotes()
|
||||
if len(self.host_remotes) > 1:
|
||||
self.remotes_chooser_creator()
|
||||
|
||||
self.remote_to_search = []
|
||||
self.main_stack.set_visible_child(self.blank_page)
|
||||
self.generate_remotes_list()
|
||||
self.set_size_request(260, 230)
|
||||
self.set_modal(True)
|
||||
self.set_resizable(True)
|
||||
|
||||
@@ -34,5 +34,6 @@
|
||||
<file preprocess="xml-stripblanks" alias="important-small-symbolic.svg">../data/icons/important-small-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks" alias="eye-not-looking-symbolic.svg">../data/icons/eye-not-looking-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks" alias="eye-open-negative-filled-symbolic.svg">../data/icons/eye-open-negative-filled-symbolic.svg</file>
|
||||
<file preprocess="xml-stripblanks" alias="left-large-symbolic.svg">../data/icons/left-large-symbolic.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -67,6 +67,7 @@ class WarehouseWindow(Adw.ApplicationWindow):
|
||||
no_matches = Gtk.Template.Child()
|
||||
reset_filters_button = Gtk.Template.Child()
|
||||
uninstalling_status = Gtk.Template.Child()
|
||||
install_button = Gtk.Template.Child()
|
||||
|
||||
main_progress_bar = Gtk.ProgressBar(visible=False, can_target=False)
|
||||
main_progress_bar.add_css_class("osd")
|
||||
|
||||
Reference in New Issue
Block a user