mirror of
https://github.com/morgan9e/warehouse
synced 2026-04-13 15:55:05 +09:00
Convert more spaces to tabs for indentation
This commit is contained in:
@@ -2,59 +2,59 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $ChangeVersionPage : Adw.NavigationPage {
|
||||
title: _("Change Versions");
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
}
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
ScrolledWindow scrolled_window {}
|
||||
}
|
||||
[bottom]
|
||||
ActionBar action_bar {
|
||||
revealed: false;
|
||||
[center]
|
||||
Button apply_button {
|
||||
sensitive: bind action_bar.revealed;
|
||||
halign: center;
|
||||
margin-top: 3;
|
||||
margin-bottom: 3;
|
||||
Adw.ButtonContent {
|
||||
label: _("Change Version");
|
||||
icon-name: "double-ended-arrows-vertical-symbolic";
|
||||
}
|
||||
styles ["suggested-action", "pill"]
|
||||
}
|
||||
}
|
||||
}
|
||||
title: _("Change Versions");
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
}
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
ScrolledWindow scrolled_window {}
|
||||
}
|
||||
[bottom]
|
||||
ActionBar action_bar {
|
||||
revealed: false;
|
||||
[center]
|
||||
Button apply_button {
|
||||
sensitive: bind action_bar.revealed;
|
||||
halign: center;
|
||||
margin-top: 3;
|
||||
margin-bottom: 3;
|
||||
Adw.ButtonContent {
|
||||
label: _("Change Version");
|
||||
icon-name: "double-ended-arrows-vertical-symbolic";
|
||||
}
|
||||
styles ["suggested-action", "pill"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Adw.Clamp versions_clamp {
|
||||
Box {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
spacing: 12;
|
||||
orientation: vertical;
|
||||
halign: fill;
|
||||
hexpand: true;
|
||||
Box {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
spacing: 12;
|
||||
orientation: vertical;
|
||||
halign: fill;
|
||||
hexpand: true;
|
||||
|
||||
CheckButton root_group_check_button {
|
||||
visible: false;
|
||||
active: true;
|
||||
}
|
||||
CheckButton root_group_check_button {
|
||||
visible: false;
|
||||
active: true;
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup mask_group {
|
||||
Adw.SwitchRow mask_row {
|
||||
title: _("Disable Updates");
|
||||
active: true;
|
||||
}
|
||||
}
|
||||
Adw.PreferencesGroup mask_group {
|
||||
Adw.SwitchRow mask_row {
|
||||
title: _("Disable Updates");
|
||||
active: true;
|
||||
}
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup versions_group {
|
||||
title: _("Select a Release");
|
||||
description: _("This will uninstall the current release and install the chosen one instead. Note that downgrading can cause issues.");
|
||||
}
|
||||
}
|
||||
Adw.PreferencesGroup versions_group {
|
||||
title: _("Select a Release");
|
||||
description: _("This will uninstall the current release and install the chosen one instead. Note that downgrading can cause issues.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,42 +2,42 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $AppRow : Adw.ActionRow {
|
||||
activatable: true;
|
||||
[prefix]
|
||||
Image image {
|
||||
icon-size: large;
|
||||
icon-name: "application-x-executable-symbolic";
|
||||
}
|
||||
[suffix]
|
||||
Image eol_package_package_status_icon {
|
||||
icon-name: "error-symbolic";
|
||||
tooltip-text: _("This package is End Of Life, and will not receive any security updates");
|
||||
visible: false;
|
||||
styles["error"]
|
||||
}
|
||||
[suffix]
|
||||
Image eol_runtime_status_icon {
|
||||
icon-name: "error-symbolic";
|
||||
tooltip-text: _("This app's runtime is End Of Life, and will not receive any security updates");
|
||||
visible: false;
|
||||
styles["error"]
|
||||
}
|
||||
[suffix]
|
||||
Image pinned_status_icon {
|
||||
icon-name: "pin-symbolic";
|
||||
tooltip-text: _("This runtime will never be automatically removed");
|
||||
visible: false;
|
||||
}
|
||||
[suffix]
|
||||
Image masked_status_icon {
|
||||
icon-name: "software-update-urgent-symbolic";
|
||||
tooltip-text: _("Updates are disabled for this package");
|
||||
visible: false;
|
||||
}
|
||||
[suffix]
|
||||
CheckButton check_button {
|
||||
margin-start: 6;
|
||||
styles["selection-mode"]
|
||||
visible: false;
|
||||
}
|
||||
activatable: true;
|
||||
[prefix]
|
||||
Image image {
|
||||
icon-size: large;
|
||||
icon-name: "application-x-executable-symbolic";
|
||||
}
|
||||
[suffix]
|
||||
Image eol_package_package_status_icon {
|
||||
icon-name: "error-symbolic";
|
||||
tooltip-text: _("This package is End Of Life, and will not receive any security updates");
|
||||
visible: false;
|
||||
styles["error"]
|
||||
}
|
||||
[suffix]
|
||||
Image eol_runtime_status_icon {
|
||||
icon-name: "error-symbolic";
|
||||
tooltip-text: _("This app's runtime is End Of Life, and will not receive any security updates");
|
||||
visible: false;
|
||||
styles["error"]
|
||||
}
|
||||
[suffix]
|
||||
Image pinned_status_icon {
|
||||
icon-name: "pin-symbolic";
|
||||
tooltip-text: _("This runtime will never be automatically removed");
|
||||
visible: false;
|
||||
}
|
||||
[suffix]
|
||||
Image masked_status_icon {
|
||||
icon-name: "software-update-urgent-symbolic";
|
||||
tooltip-text: _("Updates are disabled for this package");
|
||||
visible: false;
|
||||
}
|
||||
[suffix]
|
||||
CheckButton check_button {
|
||||
margin-start: 6;
|
||||
styles["selection-mode"]
|
||||
visible: false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $AttemptInstallDialog : Adw.AlertDialog {
|
||||
heading: _("Attempt an Install?");
|
||||
heading: _("Attempt an Install?");
|
||||
body: _("Warehouse will try to install the matching packages.");
|
||||
responses [
|
||||
cancel: _("Cancel"),
|
||||
|
||||
@@ -2,56 +2,56 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $LoadingStatus : ScrolledWindow {
|
||||
Box {
|
||||
orientation: vertical;
|
||||
valign: center;
|
||||
halign: fill;
|
||||
spacing: 12;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
Adw.Spinner {
|
||||
height-request: 30;
|
||||
margin-bottom: 12;
|
||||
opacity: 0.5;
|
||||
}
|
||||
Label title_label {
|
||||
label: "No Title Set";
|
||||
wrap: true;
|
||||
justify: center;
|
||||
styles ["title-1"]
|
||||
}
|
||||
Label description_label {
|
||||
label: "No Description Set";
|
||||
wrap: true;
|
||||
justify: center;
|
||||
styles ["description", "body"]
|
||||
}
|
||||
Adw.Clamp progress_clamp {
|
||||
margin-start: 24;
|
||||
margin-end: 24;
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
maximum-size: 400;
|
||||
Box {
|
||||
halign: fill;
|
||||
hexpand: true;
|
||||
spacing: 12;
|
||||
ProgressBar progress_bar {
|
||||
halign: fill;
|
||||
hexpand: true;
|
||||
valign: center;
|
||||
}
|
||||
Label progress_label {
|
||||
valign: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
Button button {
|
||||
label: _("Cancel");
|
||||
styles ["pill"]
|
||||
halign: center;
|
||||
}
|
||||
}
|
||||
Box {
|
||||
orientation: vertical;
|
||||
valign: center;
|
||||
halign: fill;
|
||||
spacing: 12;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
Adw.Spinner {
|
||||
height-request: 30;
|
||||
margin-bottom: 12;
|
||||
opacity: 0.5;
|
||||
}
|
||||
Label title_label {
|
||||
label: "No Title Set";
|
||||
wrap: true;
|
||||
justify: center;
|
||||
styles ["title-1"]
|
||||
}
|
||||
Label description_label {
|
||||
label: "No Description Set";
|
||||
wrap: true;
|
||||
justify: center;
|
||||
styles ["description", "body"]
|
||||
}
|
||||
Adw.Clamp progress_clamp {
|
||||
margin-start: 24;
|
||||
margin-end: 24;
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
maximum-size: 400;
|
||||
Box {
|
||||
halign: fill;
|
||||
hexpand: true;
|
||||
spacing: 12;
|
||||
ProgressBar progress_bar {
|
||||
halign: fill;
|
||||
hexpand: true;
|
||||
valign: center;
|
||||
}
|
||||
Label progress_label {
|
||||
valign: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
Button button {
|
||||
label: _("Cancel");
|
||||
styles ["pill"]
|
||||
halign: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,23 +2,23 @@ from gi.repository import Gtk, GLib
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/gtk/loading_status.ui")
|
||||
class LoadingStatus(Gtk.ScrolledWindow):
|
||||
__gtype_name__ = 'LoadingStatus'
|
||||
gtc = Gtk.Template.Child
|
||||
__gtype_name__ = 'LoadingStatus'
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
title_label = gtc()
|
||||
description_label = gtc()
|
||||
progress_clamp = gtc()
|
||||
progress_bar = gtc()
|
||||
progress_label = gtc()
|
||||
button = gtc()
|
||||
title_label = gtc()
|
||||
description_label = gtc()
|
||||
progress_clamp = gtc()
|
||||
progress_bar = gtc()
|
||||
progress_label = gtc()
|
||||
button = gtc()
|
||||
|
||||
def __init__(self, title, description, show_progress=False, on_cancel=None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
def __init__(self, title, description, show_progress=False, on_cancel=None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.title_label.set_label(GLib.markup_escape_text(title))
|
||||
self.description_label.set_label(GLib.markup_escape_text(description))
|
||||
self.progress_clamp.set_visible(show_progress)
|
||||
if on_cancel is None:
|
||||
self.button.set_visible(False)
|
||||
else:
|
||||
self.button.connect("clicked", lambda *_: on_cancel())
|
||||
self.title_label.set_label(GLib.markup_escape_text(title))
|
||||
self.description_label.set_label(GLib.markup_escape_text(description))
|
||||
self.progress_clamp.set_visible(show_progress)
|
||||
if on_cancel is None:
|
||||
self.button.set_visible(False)
|
||||
else:
|
||||
self.button.connect("clicked", lambda *_: on_cancel())
|
||||
|
||||
@@ -2,18 +2,18 @@ from gi.repository import Gtk
|
||||
from .host_info import HostInfo
|
||||
|
||||
class SidebarButton(Gtk.Button):
|
||||
__gtype_name__ = "SidebarButton"
|
||||
__gtype_name__ = "SidebarButton"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
main_split = HostInfo.main_window.main_split
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
main_split = HostInfo.main_window.main_split
|
||||
|
||||
# Connections
|
||||
main_split.connect("notify::collapsed", lambda *_: self.set_visible(main_split.get_collapsed()))
|
||||
self.connect("clicked", lambda *_: main_split.set_show_sidebar(True))
|
||||
# Connections
|
||||
main_split.connect("notify::collapsed", lambda *_: self.set_visible(main_split.get_collapsed()))
|
||||
self.connect("clicked", lambda *_: main_split.set_show_sidebar(True))
|
||||
|
||||
# Apply
|
||||
self.set_icon_name("dock-left-symbolic")
|
||||
self.set_tooltip_text(_("Show Sidebar"))
|
||||
# Apply
|
||||
self.set_icon_name("dock-left-symbolic")
|
||||
self.set_tooltip_text(_("Show Sidebar"))
|
||||
|
||||
@@ -2,40 +2,40 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $FileInstallDialog : Adw.Dialog {
|
||||
follows-content-size: true;
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
show-start-title-buttons: false;
|
||||
show-end-title-buttons: false;
|
||||
[start]
|
||||
Button cancel_button {
|
||||
label: _("Cancel");
|
||||
}
|
||||
[end]
|
||||
Button apply_button {
|
||||
styles ["suggested-action"]
|
||||
label: _("Install");
|
||||
}
|
||||
}
|
||||
ScrolledWindow content_page {
|
||||
propagate-natural-height: true;
|
||||
propagate-natural-width: true;
|
||||
Adw.Clamp {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-bottom: 12;
|
||||
margin-top: 6;
|
||||
Box {
|
||||
orientation: vertical;
|
||||
spacing: 12;
|
||||
Adw.PreferencesGroup packages_group {
|
||||
title: _("Review Selection");
|
||||
}
|
||||
$InstallationChooser installation_chooser {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
follows-content-size: true;
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
show-start-title-buttons: false;
|
||||
show-end-title-buttons: false;
|
||||
[start]
|
||||
Button cancel_button {
|
||||
label: _("Cancel");
|
||||
}
|
||||
[end]
|
||||
Button apply_button {
|
||||
styles ["suggested-action"]
|
||||
label: _("Install");
|
||||
}
|
||||
}
|
||||
ScrolledWindow content_page {
|
||||
propagate-natural-height: true;
|
||||
propagate-natural-width: true;
|
||||
Adw.Clamp {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-bottom: 12;
|
||||
margin-top: 6;
|
||||
Box {
|
||||
orientation: vertical;
|
||||
spacing: 12;
|
||||
Adw.PreferencesGroup packages_group {
|
||||
title: _("Review Selection");
|
||||
}
|
||||
$InstallationChooser installation_chooser {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,106 +2,106 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $InstallPage : Adw.BreakpointBin {
|
||||
width-request: 1;
|
||||
width-request: 1;
|
||||
height-request: 1;
|
||||
|
||||
Adw.Breakpoint break_point {
|
||||
Adw.Breakpoint break_point {
|
||||
condition ("max-width: 600")
|
||||
|
||||
setters {
|
||||
multi_view.layout: skinny;
|
||||
multi_view.layout: skinny;
|
||||
}
|
||||
}
|
||||
|
||||
Adw.NavigationPage {
|
||||
title: _("Install Packages");
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
Stack status_stack {
|
||||
Adw.ToolbarView loading_view {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
[start]
|
||||
$SidebarButton {}
|
||||
}
|
||||
}
|
||||
Adw.ToolbarView installing_view {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
[start]
|
||||
$SidebarButton {}
|
||||
}
|
||||
}
|
||||
Adw.MultiLayoutView multi_view {
|
||||
Adw.Layout wide {
|
||||
Adw.NavigationSplitView split_view {
|
||||
sidebar-width-fraction: 0.5;
|
||||
max-sidebar-width: 999999999;
|
||||
sidebar:
|
||||
Adw.NavigationPage {
|
||||
title: _("Select Source");
|
||||
Adw.LayoutSlot {
|
||||
id: "select_page";
|
||||
}
|
||||
}
|
||||
;
|
||||
content:
|
||||
Adw.NavigationPage {
|
||||
title: _("Pending Packages");
|
||||
Adw.LayoutSlot {
|
||||
id: "pending_page";
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
||||
Adw.Layout skinny {
|
||||
Adw.BottomSheet bottom_sheet {
|
||||
[content]
|
||||
Box {
|
||||
margin-bottom: bind bottom_sheet.bottom-bar-height;
|
||||
Adw.LayoutSlot {
|
||||
id: "select_page";
|
||||
}
|
||||
}
|
||||
[sheet]
|
||||
Adw.LayoutSlot {
|
||||
id: "pending_page";
|
||||
}
|
||||
}
|
||||
}
|
||||
[select_page]
|
||||
$SelectPage select_page {}
|
||||
[pending_page]
|
||||
$PendingPage pending_page {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.NavigationPage {
|
||||
title: _("Install Packages");
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
Stack status_stack {
|
||||
Adw.ToolbarView loading_view {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
[start]
|
||||
$SidebarButton {}
|
||||
}
|
||||
}
|
||||
Adw.ToolbarView installing_view {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
[start]
|
||||
$SidebarButton {}
|
||||
}
|
||||
}
|
||||
Adw.MultiLayoutView multi_view {
|
||||
Adw.Layout wide {
|
||||
Adw.NavigationSplitView split_view {
|
||||
sidebar-width-fraction: 0.5;
|
||||
max-sidebar-width: 999999999;
|
||||
sidebar:
|
||||
Adw.NavigationPage {
|
||||
title: _("Select Source");
|
||||
Adw.LayoutSlot {
|
||||
id: "select_page";
|
||||
}
|
||||
}
|
||||
;
|
||||
content:
|
||||
Adw.NavigationPage {
|
||||
title: _("Pending Packages");
|
||||
Adw.LayoutSlot {
|
||||
id: "pending_page";
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
||||
Adw.Layout skinny {
|
||||
Adw.BottomSheet bottom_sheet {
|
||||
[content]
|
||||
Box {
|
||||
margin-bottom: bind bottom_sheet.bottom-bar-height;
|
||||
Adw.LayoutSlot {
|
||||
id: "select_page";
|
||||
}
|
||||
}
|
||||
[sheet]
|
||||
Adw.LayoutSlot {
|
||||
id: "pending_page";
|
||||
}
|
||||
}
|
||||
}
|
||||
[select_page]
|
||||
$SelectPage select_page {}
|
||||
[pending_page]
|
||||
$PendingPage pending_page {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Revealer bottom_child {
|
||||
reveal-child: false;
|
||||
Box {
|
||||
margin-top: 12;
|
||||
margin-bottom: 14;
|
||||
spacing: 12;
|
||||
halign: center;
|
||||
valign: center;
|
||||
styles ["flat"]
|
||||
[start]
|
||||
Image {
|
||||
icon-name: "flatpak-symbolic";
|
||||
icon-size: normal;
|
||||
}
|
||||
[center]
|
||||
Label bottom_label {
|
||||
label: _("Pending Packages");
|
||||
styles ["heading"]
|
||||
}
|
||||
[end]
|
||||
Image {
|
||||
icon-name: "right-large-symbolic";
|
||||
icon-size: normal;
|
||||
}
|
||||
}
|
||||
reveal-child: false;
|
||||
Box {
|
||||
margin-top: 12;
|
||||
margin-bottom: 14;
|
||||
spacing: 12;
|
||||
halign: center;
|
||||
valign: center;
|
||||
styles ["flat"]
|
||||
[start]
|
||||
Image {
|
||||
icon-name: "flatpak-symbolic";
|
||||
icon-size: normal;
|
||||
}
|
||||
[center]
|
||||
Label bottom_label {
|
||||
label: _("Pending Packages");
|
||||
styles ["heading"]
|
||||
}
|
||||
[end]
|
||||
Image {
|
||||
icon-name: "right-large-symbolic";
|
||||
icon-size: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,89 +9,89 @@ from .error_toast import ErrorToast
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/install_page.ui")
|
||||
class InstallPage(Adw.BreakpointBin):
|
||||
__gtype_name__ = "InstallPage"
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
break_point = gtc()
|
||||
split_view = gtc()
|
||||
multi_view = gtc()
|
||||
select_page = gtc()
|
||||
pending_page = gtc()
|
||||
status_stack = gtc()
|
||||
loading_view = gtc()
|
||||
installing_view = gtc()
|
||||
bottom_sheet = gtc()
|
||||
bottom_child = gtc()
|
||||
bottom_label = gtc()
|
||||
|
||||
# Referred to in the main window
|
||||
# It is used to determine if a new page should be made or not
|
||||
# This must be set to the created object from within the class's __init__ method
|
||||
instance = None
|
||||
page_name = "install"
|
||||
|
||||
current_installation = ""
|
||||
current_remote = None
|
||||
did_error = False
|
||||
|
||||
def start_loading(self):
|
||||
self.total_added_packages = 0
|
||||
self.bottom_bar_visual_handler(False)
|
||||
self.status_stack.set_visible_child(self.loading_view)
|
||||
self.select_page.start_loading()
|
||||
self.pending_page.reset()
|
||||
|
||||
def end_loading(self):
|
||||
self.select_page.end_loading()
|
||||
self.status_stack.set_visible_child(self.multi_view)
|
||||
|
||||
def install_callback(self):
|
||||
HostInfo.main_window.refresh_handler()
|
||||
if not self.did_error:
|
||||
HostInfo.main_window.toast_overlay.add_toast(Adw.Toast(title=_("Installed Packages")))
|
||||
|
||||
def install_error_callback(self, user_facing_label, error_message):
|
||||
self.did_error = True
|
||||
GLib.idle_add(lambda *_: HostInfo.main_window.toast_overlay.add_toast(ErrorToast(user_facing_label, error_message).toast))
|
||||
|
||||
def install_packages(self, package_requests):
|
||||
self.did_error = False
|
||||
if PackageInstallWorker.install(package_requests, self.installing_status, self.install_callback, self.install_error_callback):
|
||||
self.status_stack.set_visible_child(self.installing_view)
|
||||
|
||||
def bottom_bar_visual_handler(self, is_added):
|
||||
total = self.total_added_packages
|
||||
if total == 0:
|
||||
self.bottom_child.set_reveal_child(False)
|
||||
self.bottom_sheet.set_bottom_bar(None)
|
||||
elif total == 1:
|
||||
self.bottom_label.set_label(_("{} Pending Package").format(1))
|
||||
if is_added:
|
||||
self.bottom_sheet.set_bottom_bar(self.bottom_child)
|
||||
self.bottom_child.set_reveal_child(True)
|
||||
else:
|
||||
self.bottom_label.set_label(_("{} Pending Packages").format(total))
|
||||
|
||||
def package_added(self):
|
||||
self.total_added_packages += 1
|
||||
self.bottom_bar_visual_handler(True)
|
||||
|
||||
def package_removed(self):
|
||||
self.total_added_packages -= 1
|
||||
self.bottom_bar_visual_handler(False)
|
||||
|
||||
def __init__(self, main_window, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.instance = self
|
||||
|
||||
# Extra Object Creation
|
||||
self.installing_status = LoadingStatus(_("Installing Packages"), _("This could take a while"), True, PackageInstallWorker.cancel)
|
||||
self.total_added_packages = 0
|
||||
|
||||
# Connections
|
||||
|
||||
# Apply
|
||||
self.select_page.results_page.pending_page = self.pending_page
|
||||
self.select_page.results_page.install_page = self
|
||||
self.loading_view.set_content(LoadingStatus(_("Loading Installation Options"), _("This should only take a moment")))
|
||||
self.installing_view.set_content(self.installing_status)
|
||||
__gtype_name__ = "InstallPage"
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
break_point = gtc()
|
||||
split_view = gtc()
|
||||
multi_view = gtc()
|
||||
select_page = gtc()
|
||||
pending_page = gtc()
|
||||
status_stack = gtc()
|
||||
loading_view = gtc()
|
||||
installing_view = gtc()
|
||||
bottom_sheet = gtc()
|
||||
bottom_child = gtc()
|
||||
bottom_label = gtc()
|
||||
|
||||
# Referred to in the main window
|
||||
# It is used to determine if a new page should be made or not
|
||||
# This must be set to the created object from within the class's __init__ method
|
||||
instance = None
|
||||
page_name = "install"
|
||||
|
||||
current_installation = ""
|
||||
current_remote = None
|
||||
did_error = False
|
||||
|
||||
def start_loading(self):
|
||||
self.total_added_packages = 0
|
||||
self.bottom_bar_visual_handler(False)
|
||||
self.status_stack.set_visible_child(self.loading_view)
|
||||
self.select_page.start_loading()
|
||||
self.pending_page.reset()
|
||||
|
||||
def end_loading(self):
|
||||
self.select_page.end_loading()
|
||||
self.status_stack.set_visible_child(self.multi_view)
|
||||
|
||||
def install_callback(self):
|
||||
HostInfo.main_window.refresh_handler()
|
||||
if not self.did_error:
|
||||
HostInfo.main_window.toast_overlay.add_toast(Adw.Toast(title=_("Installed Packages")))
|
||||
|
||||
def install_error_callback(self, user_facing_label, error_message):
|
||||
self.did_error = True
|
||||
GLib.idle_add(lambda *_: HostInfo.main_window.toast_overlay.add_toast(ErrorToast(user_facing_label, error_message).toast))
|
||||
|
||||
def install_packages(self, package_requests):
|
||||
self.did_error = False
|
||||
if PackageInstallWorker.install(package_requests, self.installing_status, self.install_callback, self.install_error_callback):
|
||||
self.status_stack.set_visible_child(self.installing_view)
|
||||
|
||||
def bottom_bar_visual_handler(self, is_added):
|
||||
total = self.total_added_packages
|
||||
if total == 0:
|
||||
self.bottom_child.set_reveal_child(False)
|
||||
self.bottom_sheet.set_bottom_bar(None)
|
||||
elif total == 1:
|
||||
self.bottom_label.set_label(_("{} Pending Package").format(1))
|
||||
if is_added:
|
||||
self.bottom_sheet.set_bottom_bar(self.bottom_child)
|
||||
self.bottom_child.set_reveal_child(True)
|
||||
else:
|
||||
self.bottom_label.set_label(_("{} Pending Packages").format(total))
|
||||
|
||||
def package_added(self):
|
||||
self.total_added_packages += 1
|
||||
self.bottom_bar_visual_handler(True)
|
||||
|
||||
def package_removed(self):
|
||||
self.total_added_packages -= 1
|
||||
self.bottom_bar_visual_handler(False)
|
||||
|
||||
def __init__(self, main_window, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.instance = self
|
||||
|
||||
# Extra Object Creation
|
||||
self.installing_status = LoadingStatus(_("Installing Packages"), _("This could take a while"), True, PackageInstallWorker.cancel)
|
||||
self.total_added_packages = 0
|
||||
|
||||
# Connections
|
||||
|
||||
# Apply
|
||||
self.select_page.results_page.pending_page = self.pending_page
|
||||
self.select_page.results_page.install_page = self
|
||||
self.loading_view.set_content(LoadingStatus(_("Loading Installation Options"), _("This should only take a moment")))
|
||||
self.installing_view.set_content(self.installing_status)
|
||||
|
||||
@@ -2,40 +2,40 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $PendingPage : Adw.NavigationPage {
|
||||
title: _("Pending Packages");
|
||||
Stack stack {
|
||||
Adw.ToolbarView none_pending {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
}
|
||||
Adw.StatusPage {
|
||||
icon-name: "flatpak-symbolic";
|
||||
title: _("Add Packages");
|
||||
description: _("Packages queued to install will show up here");
|
||||
}
|
||||
}
|
||||
Adw.ToolbarView main_view {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
}
|
||||
Adw.PreferencesPage preferences_page {
|
||||
}
|
||||
[bottom]
|
||||
ActionBar pending_action_bar {
|
||||
revealed: true;
|
||||
[center]
|
||||
Button install_button {
|
||||
margin-top: 3;
|
||||
margin-bottom: 3;
|
||||
sensitive: bind pending_action_bar.revealed;
|
||||
styles ["pill", "suggested-action"]
|
||||
Adw.ButtonContent {
|
||||
can-shrink: true;
|
||||
icon-name: "arrow-pointing-at-line-down-symbolic";
|
||||
label: _("Install");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
title: _("Pending Packages");
|
||||
Stack stack {
|
||||
Adw.ToolbarView none_pending {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
}
|
||||
Adw.StatusPage {
|
||||
icon-name: "flatpak-symbolic";
|
||||
title: _("Add Packages");
|
||||
description: _("Packages queued to install will show up here");
|
||||
}
|
||||
}
|
||||
Adw.ToolbarView main_view {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
}
|
||||
Adw.PreferencesPage preferences_page {
|
||||
}
|
||||
[bottom]
|
||||
ActionBar pending_action_bar {
|
||||
revealed: true;
|
||||
[center]
|
||||
Button install_button {
|
||||
margin-top: 3;
|
||||
margin-bottom: 3;
|
||||
sensitive: bind pending_action_bar.revealed;
|
||||
styles ["pill", "suggested-action"]
|
||||
Adw.ButtonContent {
|
||||
can-shrink: true;
|
||||
icon-name: "arrow-pointing-at-line-down-symbolic";
|
||||
label: _("Install");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,126 +3,126 @@ from .host_info import HostInfo
|
||||
from .result_row import ResultRow
|
||||
|
||||
class AddedGroup(Adw.PreferencesGroup):
|
||||
__gtype_name__ = "AddedGroup"
|
||||
|
||||
def add_row(self, row):
|
||||
self.rows.append(row)
|
||||
self.add(row)
|
||||
|
||||
def rem_row(self, row):
|
||||
if row in self.rows:
|
||||
self.rows.remove(row)
|
||||
self.remove(row)
|
||||
|
||||
def remove_all(self, *args):
|
||||
while len(self.rows) > 0 and (row := self.rows[0]):
|
||||
row.activate()
|
||||
|
||||
def __init__(self, remote, installation, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.remote = remote
|
||||
self.installation = installation
|
||||
self.rows = []
|
||||
|
||||
self.set_title(f"{remote.title}")
|
||||
self.set_description(_("Installation: {}").format(installation))
|
||||
|
||||
remove_all = Gtk.Button(
|
||||
child=Adw.ButtonContent(
|
||||
icon_name="list-remove-all-symbolic",
|
||||
label=_("Remove All"),
|
||||
),
|
||||
valign = Gtk.Align.CENTER,
|
||||
)
|
||||
remove_all.add_css_class("flat")
|
||||
remove_all.connect("clicked", self.remove_all)
|
||||
self.set_header_suffix(remove_all)
|
||||
|
||||
__gtype_name__ = "AddedGroup"
|
||||
|
||||
def add_row(self, row):
|
||||
self.rows.append(row)
|
||||
self.add(row)
|
||||
|
||||
def rem_row(self, row):
|
||||
if row in self.rows:
|
||||
self.rows.remove(row)
|
||||
self.remove(row)
|
||||
|
||||
def remove_all(self, *args):
|
||||
while len(self.rows) > 0 and (row := self.rows[0]):
|
||||
row.activate()
|
||||
|
||||
def __init__(self, remote, installation, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.remote = remote
|
||||
self.installation = installation
|
||||
self.rows = []
|
||||
|
||||
self.set_title(f"{remote.title}")
|
||||
self.set_description(_("Installation: {}").format(installation))
|
||||
|
||||
remove_all = Gtk.Button(
|
||||
child=Adw.ButtonContent(
|
||||
icon_name="list-remove-all-symbolic",
|
||||
label=_("Remove All"),
|
||||
),
|
||||
valign = Gtk.Align.CENTER,
|
||||
)
|
||||
remove_all.add_css_class("flat")
|
||||
remove_all.connect("clicked", self.remove_all)
|
||||
self.set_header_suffix(remove_all)
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/pending_page.ui")
|
||||
class PendingPage(Adw.NavigationPage):
|
||||
__gtype_name__ = "PendingPage"
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
stack = gtc()
|
||||
main_view = gtc()
|
||||
none_pending = gtc()
|
||||
preferences_page = gtc()
|
||||
install_button = gtc()
|
||||
|
||||
def add_package_row(self, row):
|
||||
self.added_packages.append(row.package)
|
||||
row.set_state(ResultRow.PackageState.SELECTED)
|
||||
key = f"{row.package.remote}<>{row.package.installation}"
|
||||
added_row = ResultRow(row.package, ResultRow.PackageState.ADDED, row.origin_list_box)
|
||||
group = None
|
||||
try:
|
||||
group = self.groups[key]
|
||||
group.add_row(added_row)
|
||||
except KeyError:
|
||||
group = AddedGroup(added_row.package.remote, added_row.package.installation)
|
||||
group.add_row(added_row)
|
||||
self.groups[key] = group
|
||||
self.preferences_page.add(group)
|
||||
|
||||
added_row.connect("activated", self.remove_package_row, group)
|
||||
self.stack.set_visible_child(self.main_view)
|
||||
|
||||
def remove_package_row(self, row, group):
|
||||
# row.origin_row.set_state(ResultRow.PackageState.NEW)
|
||||
for item in row.origin_list_box:
|
||||
if item.state == ResultRow.PackageState.SELECTED and item.package.is_similar(row.package):
|
||||
item.set_state(ResultRow.PackageState.NEW)
|
||||
break
|
||||
|
||||
group.rem_row(row)
|
||||
if row.package in self.added_packages:
|
||||
self.added_packages.remove(row.package)
|
||||
|
||||
if len(group.rows) == 0:
|
||||
key = f"{row.package.remote}<>{row.package.installation}"
|
||||
self.groups.pop(key, None)
|
||||
self.preferences_page.remove(group)
|
||||
|
||||
if len(self.added_packages) == 0:
|
||||
self.stack.set_visible_child(self.none_pending)
|
||||
|
||||
install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row]
|
||||
install_page.package_removed()
|
||||
|
||||
def on_install(self, *args):
|
||||
package_requests = []
|
||||
for key, group in self.groups.items():
|
||||
item = {
|
||||
"remote": group.remote.name,
|
||||
"installation": group.installation,
|
||||
"package_names": [],
|
||||
"extra_flags": [],
|
||||
}
|
||||
for row in group.rows:
|
||||
item['package_names'].append(row.package.app_id)
|
||||
|
||||
package_requests.append(item)
|
||||
|
||||
install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row]
|
||||
install_page.install_packages(package_requests)
|
||||
|
||||
def reset(self):
|
||||
for key, group in self.groups.items():
|
||||
self.preferences_page.remove(group)
|
||||
|
||||
self.groups.clear()
|
||||
self.added_packages.clear()
|
||||
self.stack.set_visible_child(self.none_pending)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
self.groups = {} # remote<>installation: adw.preference_group
|
||||
self.added_packages = []
|
||||
|
||||
# Connections
|
||||
self.install_button.connect("clicked", self.on_install)
|
||||
|
||||
# Apply
|
||||
__gtype_name__ = "PendingPage"
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
stack = gtc()
|
||||
main_view = gtc()
|
||||
none_pending = gtc()
|
||||
preferences_page = gtc()
|
||||
install_button = gtc()
|
||||
|
||||
def add_package_row(self, row):
|
||||
self.added_packages.append(row.package)
|
||||
row.set_state(ResultRow.PackageState.SELECTED)
|
||||
key = f"{row.package.remote}<>{row.package.installation}"
|
||||
added_row = ResultRow(row.package, ResultRow.PackageState.ADDED, row.origin_list_box)
|
||||
group = None
|
||||
try:
|
||||
group = self.groups[key]
|
||||
group.add_row(added_row)
|
||||
except KeyError:
|
||||
group = AddedGroup(added_row.package.remote, added_row.package.installation)
|
||||
group.add_row(added_row)
|
||||
self.groups[key] = group
|
||||
self.preferences_page.add(group)
|
||||
|
||||
added_row.connect("activated", self.remove_package_row, group)
|
||||
self.stack.set_visible_child(self.main_view)
|
||||
|
||||
def remove_package_row(self, row, group):
|
||||
# row.origin_row.set_state(ResultRow.PackageState.NEW)
|
||||
for item in row.origin_list_box:
|
||||
if item.state == ResultRow.PackageState.SELECTED and item.package.is_similar(row.package):
|
||||
item.set_state(ResultRow.PackageState.NEW)
|
||||
break
|
||||
|
||||
group.rem_row(row)
|
||||
if row.package in self.added_packages:
|
||||
self.added_packages.remove(row.package)
|
||||
|
||||
if len(group.rows) == 0:
|
||||
key = f"{row.package.remote}<>{row.package.installation}"
|
||||
self.groups.pop(key, None)
|
||||
self.preferences_page.remove(group)
|
||||
|
||||
if len(self.added_packages) == 0:
|
||||
self.stack.set_visible_child(self.none_pending)
|
||||
|
||||
install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row]
|
||||
install_page.package_removed()
|
||||
|
||||
def on_install(self, *args):
|
||||
package_requests = []
|
||||
for key, group in self.groups.items():
|
||||
item = {
|
||||
"remote": group.remote.name,
|
||||
"installation": group.installation,
|
||||
"package_names": [],
|
||||
"extra_flags": [],
|
||||
}
|
||||
for row in group.rows:
|
||||
item['package_names'].append(row.package.app_id)
|
||||
|
||||
package_requests.append(item)
|
||||
|
||||
install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row]
|
||||
install_page.install_packages(package_requests)
|
||||
|
||||
def reset(self):
|
||||
for key, group in self.groups.items():
|
||||
self.preferences_page.remove(group)
|
||||
|
||||
self.groups.clear()
|
||||
self.added_packages.clear()
|
||||
self.stack.set_visible_child(self.none_pending)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
self.groups = {} # remote<>installation: adw.preference_group
|
||||
self.added_packages = []
|
||||
|
||||
# Connections
|
||||
self.install_button.connect("clicked", self.on_install)
|
||||
|
||||
# Apply
|
||||
|
||||
@@ -2,48 +2,48 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $ResultRow : Adw.ActionRow {
|
||||
activatable: true;
|
||||
title: "No title set";
|
||||
subtitle: "No subtitle set";
|
||||
tooltip-text: _("Add Package to Queue");
|
||||
activatable: true;
|
||||
title: "No title set";
|
||||
subtitle: "No subtitle set";
|
||||
tooltip-text: _("Add Package to Queue");
|
||||
|
||||
Box {
|
||||
orientation: vertical;
|
||||
valign: center;
|
||||
spacing: 4;
|
||||
margin-end: 4;
|
||||
Label version_label {
|
||||
styles ["subtitle"]
|
||||
label: "";
|
||||
justify: right;
|
||||
halign: end;
|
||||
hexpand: true;
|
||||
wrap: true;
|
||||
}
|
||||
Label branch_label {
|
||||
styles ["subtitle"]
|
||||
label: "";
|
||||
justify: right;
|
||||
halign: end;
|
||||
hexpand: true;
|
||||
wrap: true;
|
||||
}
|
||||
}
|
||||
[suffix]
|
||||
Image add_image {
|
||||
icon-name: "plus-large-symbolic";
|
||||
}
|
||||
[suffix]
|
||||
Image selected_image {
|
||||
icon-name: "check-plain-symbolic";
|
||||
}
|
||||
[suffix]
|
||||
Image sub_image {
|
||||
icon-name: "minus-large-symbolic";
|
||||
}
|
||||
[suffix]
|
||||
Image installed_image {
|
||||
icon-name: "selection-mode-symbolic";
|
||||
styles ["success"]
|
||||
}
|
||||
Box {
|
||||
orientation: vertical;
|
||||
valign: center;
|
||||
spacing: 4;
|
||||
margin-end: 4;
|
||||
Label version_label {
|
||||
styles ["subtitle"]
|
||||
label: "";
|
||||
justify: right;
|
||||
halign: end;
|
||||
hexpand: true;
|
||||
wrap: true;
|
||||
}
|
||||
Label branch_label {
|
||||
styles ["subtitle"]
|
||||
label: "";
|
||||
justify: right;
|
||||
halign: end;
|
||||
hexpand: true;
|
||||
wrap: true;
|
||||
}
|
||||
}
|
||||
[suffix]
|
||||
Image add_image {
|
||||
icon-name: "plus-large-symbolic";
|
||||
}
|
||||
[suffix]
|
||||
Image selected_image {
|
||||
icon-name: "check-plain-symbolic";
|
||||
}
|
||||
[suffix]
|
||||
Image sub_image {
|
||||
icon-name: "minus-large-symbolic";
|
||||
}
|
||||
[suffix]
|
||||
Image installed_image {
|
||||
icon-name: "selection-mode-symbolic";
|
||||
styles ["success"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,67 +3,67 @@ from enum import Enum
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/result_row.ui")
|
||||
class ResultRow(Adw.ActionRow):
|
||||
__gtype_name__ = "ResultRow"
|
||||
gtc = Gtk.Template.Child
|
||||
__gtype_name__ = "ResultRow"
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
version_label = gtc()
|
||||
branch_label = gtc()
|
||||
add_image = gtc()
|
||||
sub_image = gtc()
|
||||
selected_image = gtc()
|
||||
installed_image = gtc()
|
||||
version_label = gtc()
|
||||
branch_label = gtc()
|
||||
add_image = gtc()
|
||||
sub_image = gtc()
|
||||
selected_image = gtc()
|
||||
installed_image = gtc()
|
||||
|
||||
class PackageState(Enum):
|
||||
NEW = 0
|
||||
SELECTED = 1
|
||||
ADDED = 2
|
||||
INSTALLED = 3
|
||||
class PackageState(Enum):
|
||||
NEW = 0
|
||||
SELECTED = 1
|
||||
ADDED = 2
|
||||
INSTALLED = 3
|
||||
|
||||
def idle_stuff(self):
|
||||
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)
|
||||
def idle_stuff(self):
|
||||
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)
|
||||
|
||||
def set_state(self, state):
|
||||
if state == self.state:
|
||||
return
|
||||
def set_state(self, state):
|
||||
if state == self.state:
|
||||
return
|
||||
|
||||
self.state = state
|
||||
self.add_image.set_visible(False)
|
||||
self.sub_image.set_visible(False)
|
||||
self.selected_image.set_visible(False)
|
||||
self.installed_image.set_visible(False)
|
||||
match state:
|
||||
case self.PackageState.NEW:
|
||||
self.set_sensitive(True)
|
||||
self.set_tooltip_text(_("Add Package to Queue"))
|
||||
self.add_image.set_visible(True)
|
||||
case self.PackageState.SELECTED:
|
||||
self.set_sensitive(False)
|
||||
self.set_tooltip_text(_("Package has been Added to Queue"))
|
||||
self.selected_image.set_visible(True)
|
||||
case self.PackageState.ADDED:
|
||||
self.set_sensitive(True)
|
||||
self.set_tooltip_text(_("Remove Package from Queue"))
|
||||
self.sub_image.set_visible(True)
|
||||
case self.PackageState.INSTALLED:
|
||||
self.set_sensitive(False)
|
||||
self.set_tooltip_text(_("This Package is Already Installed"))
|
||||
self.installed_image.set_visible(True)
|
||||
self.state = state
|
||||
self.add_image.set_visible(False)
|
||||
self.sub_image.set_visible(False)
|
||||
self.selected_image.set_visible(False)
|
||||
self.installed_image.set_visible(False)
|
||||
match state:
|
||||
case self.PackageState.NEW:
|
||||
self.set_sensitive(True)
|
||||
self.set_tooltip_text(_("Add Package to Queue"))
|
||||
self.add_image.set_visible(True)
|
||||
case self.PackageState.SELECTED:
|
||||
self.set_sensitive(False)
|
||||
self.set_tooltip_text(_("Package has been Added to Queue"))
|
||||
self.selected_image.set_visible(True)
|
||||
case self.PackageState.ADDED:
|
||||
self.set_sensitive(True)
|
||||
self.set_tooltip_text(_("Remove Package from Queue"))
|
||||
self.sub_image.set_visible(True)
|
||||
case self.PackageState.INSTALLED:
|
||||
self.set_sensitive(False)
|
||||
self.set_tooltip_text(_("This Package is Already Installed"))
|
||||
self.installed_image.set_visible(True)
|
||||
|
||||
def __init__(self, package, package_state, origin_list_box, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
def __init__(self, package, package_state, origin_list_box, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
self.state = None
|
||||
self.package = package
|
||||
self.origin_list_box = origin_list_box
|
||||
# Extra Object Creation
|
||||
self.state = None
|
||||
self.package = package
|
||||
self.origin_list_box = origin_list_box
|
||||
|
||||
# Connections
|
||||
# Connections
|
||||
|
||||
# Apply
|
||||
GLib.idle_add(self.idle_stuff)
|
||||
self.set_state(package_state)
|
||||
# Apply
|
||||
GLib.idle_add(self.idle_stuff)
|
||||
self.set_state(package_state)
|
||||
|
||||
@@ -2,53 +2,53 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $ResultsPage : Adw.NavigationPage {
|
||||
title: _("Search a Remote");
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {}
|
||||
[top]
|
||||
Adw.Clamp {
|
||||
maximum-size: 577;
|
||||
margin-top: 3;
|
||||
margin-bottom: 3;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
SearchEntry search_entry {
|
||||
search-delay: 500;
|
||||
halign: fill;
|
||||
// hexpand: true;
|
||||
placeholder-text: _("Search for Packages");
|
||||
}
|
||||
}
|
||||
Stack stack {
|
||||
Adw.StatusPage new_search {
|
||||
icon-name: "loupe-large-symbolic";
|
||||
title: _("Search for Flatpaks");
|
||||
description: _("Search for Flatpaks you want to install");
|
||||
}
|
||||
Adw.StatusPage too_many {
|
||||
icon-name: "error-symbolic";
|
||||
title: _("Too Many Results");
|
||||
description: _("Try being more specific with your search");
|
||||
}
|
||||
ScrolledWindow results_view {
|
||||
Adw.Clamp {
|
||||
ListBox results_list {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
styles ["boxed-list"]
|
||||
selection-mode: none;
|
||||
valign: start;
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.StatusPage no_results {
|
||||
icon-name: "loupe-large-symbolic";
|
||||
title: _("No Results Found");
|
||||
description: _("Try a different search term");
|
||||
}
|
||||
}
|
||||
}
|
||||
title: _("Search a Remote");
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {}
|
||||
[top]
|
||||
Adw.Clamp {
|
||||
maximum-size: 577;
|
||||
margin-top: 3;
|
||||
margin-bottom: 3;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
SearchEntry search_entry {
|
||||
search-delay: 500;
|
||||
halign: fill;
|
||||
// hexpand: true;
|
||||
placeholder-text: _("Search for Packages");
|
||||
}
|
||||
}
|
||||
Stack stack {
|
||||
Adw.StatusPage new_search {
|
||||
icon-name: "loupe-large-symbolic";
|
||||
title: _("Search for Flatpaks");
|
||||
description: _("Search for Flatpaks you want to install");
|
||||
}
|
||||
Adw.StatusPage too_many {
|
||||
icon-name: "error-symbolic";
|
||||
title: _("Too Many Results");
|
||||
description: _("Try being more specific with your search");
|
||||
}
|
||||
ScrolledWindow results_view {
|
||||
Adw.Clamp {
|
||||
ListBox results_list {
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
styles ["boxed-list"]
|
||||
selection-mode: none;
|
||||
valign: start;
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.StatusPage no_results {
|
||||
icon-name: "loupe-large-symbolic";
|
||||
title: _("No Results Found");
|
||||
description: _("Try a different search term");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,137 +6,137 @@ from .error_toast import ErrorToast
|
||||
import 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 __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 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
|
||||
self.branch = branch
|
||||
self.version = version
|
||||
self.remote = remote
|
||||
self.installation = installation
|
||||
def __init__(self, name, app_id, branch, version, remote, installation):
|
||||
self.name = name
|
||||
self.app_id = app_id
|
||||
self.branch = branch
|
||||
self.version = version
|
||||
self.remote = remote
|
||||
self.installation = installation
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/results_page.ui")
|
||||
class ResultsPage(Adw.NavigationPage):
|
||||
__gtype_name__ = "ResultsPage"
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
search_entry = gtc()
|
||||
results_list = gtc()
|
||||
stack = gtc()
|
||||
new_search = gtc()
|
||||
too_many = gtc()
|
||||
results_view= gtc()
|
||||
no_results = gtc()
|
||||
|
||||
def show_remote(self, row, remote, installation, nav_view=None):
|
||||
self.remote = remote
|
||||
self.installation = installation
|
||||
self.set_title(_("Search {}").format(remote.title))
|
||||
self.search_entry.set_text("")
|
||||
self.search_entry.grab_focus()
|
||||
if nav_view:
|
||||
nav_view.push(self)
|
||||
|
||||
def add_package_row(self, row):
|
||||
self.pending_page.add_package_row(row)
|
||||
if not self.install_page is None:
|
||||
self.install_page.package_added()
|
||||
|
||||
def on_search(self, *args):
|
||||
self.packages.clear()
|
||||
self.stack.set_visible_child(self.loading)
|
||||
self.results_list.remove_all()
|
||||
search_text = self.search_entry.get_text()
|
||||
if search_text == "":
|
||||
self.stack.set_visible_child(self.new_search)
|
||||
return
|
||||
|
||||
def thread(*args):
|
||||
installation = ""
|
||||
if self.installation == "user" or self.installation == "system":
|
||||
installation = f"--{self.installation}"
|
||||
else:
|
||||
installation = f"--installation={self.installation}"
|
||||
|
||||
try:
|
||||
output = subprocess.run(
|
||||
['flatpak-spawn', '--host', 'flatpak', 'search', '--columns=all', installation, self.search_entry.get_text()],
|
||||
check=True, text=True, capture_output=True
|
||||
).stdout.split('\n')
|
||||
if len(output) > 100:
|
||||
GLib.idle_add(lambda *_: self.stack.set_visible_child(self.too_many))
|
||||
return
|
||||
|
||||
for line in output:
|
||||
line = line.strip()
|
||||
|
||||
info = line.split('\t')
|
||||
if len(info) != 6:
|
||||
continue
|
||||
|
||||
remotes = info[5].split(',')
|
||||
if not self.remote.name in remotes:
|
||||
continue
|
||||
|
||||
package = AddedPackage(info[0], info[2], info[4], info[3], self.remote, self.installation)
|
||||
row = ResultRow(package, ResultRow.PackageState.NEW, self.results_list)
|
||||
for item in self.pending_page.added_packages:
|
||||
if package.is_similar(item):
|
||||
row.set_state(ResultRow.PackageState.SELECTED)
|
||||
|
||||
if package.app_id in HostInfo.id_to_flatpak:
|
||||
installed_package = HostInfo.id_to_flatpak[package.app_id]
|
||||
if installed_package.info["id"] == package.app_id and installed_package.info["branch"] == package.branch:
|
||||
row.set_state(ResultRow.PackageState.INSTALLED)
|
||||
|
||||
row.connect("activated", self.add_package_row)
|
||||
self.packages.append(package)
|
||||
GLib.idle_add(lambda *_, _row=row: self.results_list.append(_row))
|
||||
|
||||
if len(self.packages) > 0:
|
||||
GLib.idle_add(lambda *_: self.stack.set_visible_child(self.results_view))
|
||||
else:
|
||||
GLib.idle_add(lambda *_: self.stack.set_visible_child(self.no_results))
|
||||
|
||||
except subprocess.CalledProcessError as cpe:
|
||||
GLib.idle_add(lambda *_, cpe=cpe: HostInfo.main_window.toast_overlay.add_toast(ErrorToast("Could not search for package", cpe.stderr).toast))
|
||||
GLib.idle_add(lambda *_: self.install_page.select_page.nav_view.pop())
|
||||
|
||||
Gio.Task().run_in_thread(thread)
|
||||
|
||||
def on_back(self, *args):
|
||||
self.results_list.remove_all()
|
||||
self.stack.set_visible_child(self.new_search)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
self.remote = None
|
||||
self.installation = None
|
||||
self.packages = []
|
||||
self.pending_page = None
|
||||
self.loading = LoadingStatus(_("Searching"), _("This should only take a moment"))
|
||||
self.install_page = None
|
||||
|
||||
# Connections
|
||||
self.search_entry.connect("search-changed", self.on_search)
|
||||
|
||||
# Apply
|
||||
self.stack.add_child(self.loading)
|
||||
__gtype_name__ = "ResultsPage"
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
search_entry = gtc()
|
||||
results_list = gtc()
|
||||
stack = gtc()
|
||||
new_search = gtc()
|
||||
too_many = gtc()
|
||||
results_view= gtc()
|
||||
no_results = gtc()
|
||||
|
||||
def show_remote(self, row, remote, installation, nav_view=None):
|
||||
self.remote = remote
|
||||
self.installation = installation
|
||||
self.set_title(_("Search {}").format(remote.title))
|
||||
self.search_entry.set_text("")
|
||||
self.search_entry.grab_focus()
|
||||
if nav_view:
|
||||
nav_view.push(self)
|
||||
|
||||
def add_package_row(self, row):
|
||||
self.pending_page.add_package_row(row)
|
||||
if not self.install_page is None:
|
||||
self.install_page.package_added()
|
||||
|
||||
def on_search(self, *args):
|
||||
self.packages.clear()
|
||||
self.stack.set_visible_child(self.loading)
|
||||
self.results_list.remove_all()
|
||||
search_text = self.search_entry.get_text()
|
||||
if search_text == "":
|
||||
self.stack.set_visible_child(self.new_search)
|
||||
return
|
||||
|
||||
def thread(*args):
|
||||
installation = ""
|
||||
if self.installation == "user" or self.installation == "system":
|
||||
installation = f"--{self.installation}"
|
||||
else:
|
||||
installation = f"--installation={self.installation}"
|
||||
|
||||
try:
|
||||
output = subprocess.run(
|
||||
['flatpak-spawn', '--host', 'flatpak', 'search', '--columns=all', installation, self.search_entry.get_text()],
|
||||
check=True, text=True, capture_output=True
|
||||
).stdout.split('\n')
|
||||
if len(output) > 100:
|
||||
GLib.idle_add(lambda *_: self.stack.set_visible_child(self.too_many))
|
||||
return
|
||||
|
||||
for line in output:
|
||||
line = line.strip()
|
||||
|
||||
info = line.split('\t')
|
||||
if len(info) != 6:
|
||||
continue
|
||||
|
||||
remotes = info[5].split(',')
|
||||
if not self.remote.name in remotes:
|
||||
continue
|
||||
|
||||
package = AddedPackage(info[0], info[2], info[4], info[3], self.remote, self.installation)
|
||||
row = ResultRow(package, ResultRow.PackageState.NEW, self.results_list)
|
||||
for item in self.pending_page.added_packages:
|
||||
if package.is_similar(item):
|
||||
row.set_state(ResultRow.PackageState.SELECTED)
|
||||
|
||||
if package.app_id in HostInfo.id_to_flatpak:
|
||||
installed_package = HostInfo.id_to_flatpak[package.app_id]
|
||||
if installed_package.info["id"] == package.app_id and installed_package.info["branch"] == package.branch:
|
||||
row.set_state(ResultRow.PackageState.INSTALLED)
|
||||
|
||||
row.connect("activated", self.add_package_row)
|
||||
self.packages.append(package)
|
||||
GLib.idle_add(lambda *_, _row=row: self.results_list.append(_row))
|
||||
|
||||
if len(self.packages) > 0:
|
||||
GLib.idle_add(lambda *_: self.stack.set_visible_child(self.results_view))
|
||||
else:
|
||||
GLib.idle_add(lambda *_: self.stack.set_visible_child(self.no_results))
|
||||
|
||||
except subprocess.CalledProcessError as cpe:
|
||||
GLib.idle_add(lambda *_, cpe=cpe: HostInfo.main_window.toast_overlay.add_toast(ErrorToast("Could not search for package", cpe.stderr).toast))
|
||||
GLib.idle_add(lambda *_: self.install_page.select_page.nav_view.pop())
|
||||
|
||||
Gio.Task().run_in_thread(thread)
|
||||
|
||||
def on_back(self, *args):
|
||||
self.results_list.remove_all()
|
||||
self.stack.set_visible_child(self.new_search)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
self.remote = None
|
||||
self.installation = None
|
||||
self.packages = []
|
||||
self.pending_page = None
|
||||
self.loading = LoadingStatus(_("Searching"), _("This should only take a moment"))
|
||||
self.install_page = None
|
||||
|
||||
# Connections
|
||||
self.search_entry.connect("search-changed", self.on_search)
|
||||
|
||||
# Apply
|
||||
self.stack.add_child(self.loading)
|
||||
|
||||
@@ -2,49 +2,49 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $SelectPage : Adw.NavigationPage {
|
||||
title: _("Install Packages");
|
||||
title: _("Install Packages");
|
||||
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
Adw.NavigationView nav_view {
|
||||
Adw.NavigationPage select_nav_page {
|
||||
title: _("Install Packages");
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
[start]
|
||||
$SidebarButton {}
|
||||
}
|
||||
Adw.PreferencesPage {
|
||||
Adw.PreferencesGroup remotes_group {
|
||||
title: _("Search in a Remote");
|
||||
description: _("Choose a remote to search for new packages");
|
||||
}
|
||||
Adw.PreferencesGroup no_remotes {
|
||||
title: _("Online Searches Disabled");
|
||||
description: _("Your system has no remotes added to search from");
|
||||
visible: bind remotes_group.visible inverted;
|
||||
Adw.ActionRow add_remote_row {
|
||||
title: _("Add a Remote");
|
||||
subtitle: _("Add a remote to your system to enable online searching");
|
||||
activatable: true;
|
||||
[suffix]
|
||||
Image {
|
||||
icon-name: "right-large-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.PreferencesGroup local_group {
|
||||
title: _("Add Packages");
|
||||
description: _("Install packages from files on your system");
|
||||
Adw.ButtonRow open_row {
|
||||
title: _("Open Files");
|
||||
start-icon-name: "folder-open-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$ResultsPage results_page {}
|
||||
}
|
||||
}
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
Adw.NavigationView nav_view {
|
||||
Adw.NavigationPage select_nav_page {
|
||||
title: _("Install Packages");
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
[start]
|
||||
$SidebarButton {}
|
||||
}
|
||||
Adw.PreferencesPage {
|
||||
Adw.PreferencesGroup remotes_group {
|
||||
title: _("Search in a Remote");
|
||||
description: _("Choose a remote to search for new packages");
|
||||
}
|
||||
Adw.PreferencesGroup no_remotes {
|
||||
title: _("Online Searches Disabled");
|
||||
description: _("Your system has no remotes added to search from");
|
||||
visible: bind remotes_group.visible inverted;
|
||||
Adw.ActionRow add_remote_row {
|
||||
title: _("Add a Remote");
|
||||
subtitle: _("Add a remote to your system to enable online searching");
|
||||
activatable: true;
|
||||
[suffix]
|
||||
Image {
|
||||
icon-name: "right-large-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.PreferencesGroup local_group {
|
||||
title: _("Add Packages");
|
||||
description: _("Install packages from files on your system");
|
||||
Adw.ButtonRow open_row {
|
||||
title: _("Open Files");
|
||||
start-icon-name: "folder-open-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$ResultsPage results_page {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,83 +7,83 @@ from .file_install_dialog import FileInstallDialog
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/select_page.ui")
|
||||
class SelectPage(Adw.NavigationPage):
|
||||
__gtype_name__ = "SelectPage"
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
nav_view = gtc()
|
||||
results_page = gtc()
|
||||
remotes_group = gtc()
|
||||
add_remote_row = gtc()
|
||||
open_row = gtc()
|
||||
|
||||
def start_loading(self):
|
||||
self.nav_view.pop()
|
||||
for row in self.remote_rows:
|
||||
self.remotes_group.remove(row)
|
||||
self.remote_rows.clear()
|
||||
|
||||
def end_loading(self):
|
||||
for installation, remotes in HostInfo.remotes.items():
|
||||
for remote in remotes:
|
||||
if remote.disabled:
|
||||
continue
|
||||
|
||||
row = Adw.ActionRow(title=remote.title, subtitle=_("Installation: {}").format(installation), activatable=True)
|
||||
row.add_suffix(Gtk.Image(icon_name="right-large-symbolic"))
|
||||
row.connect("activated", self.results_page.show_remote, remote, installation, self.nav_view)
|
||||
self.remotes_group.add(row)
|
||||
self.remote_rows.append(row)
|
||||
|
||||
self.remotes_group.set_visible(len(self.remote_rows) != 0)
|
||||
|
||||
def local_install_apply_callback(self, installation, file_names):
|
||||
install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row]
|
||||
requests = []
|
||||
for file in file_names:
|
||||
# sadly flatpak doesn't support multiple local installs in one command :(
|
||||
requests.append({
|
||||
"remote": "local_file",
|
||||
"installation": installation,
|
||||
"package_names": [file.get_path()],
|
||||
"extra_flags": [],
|
||||
})
|
||||
|
||||
install_page.install_packages(requests)
|
||||
|
||||
def file_dialog_handler(self, files):
|
||||
FileInstallDialog(self, files, self.local_install_apply_callback).present(HostInfo.main_window)
|
||||
|
||||
def file_choose_callback(self, object, result):
|
||||
try:
|
||||
files = object.open_multiple_finish(result)
|
||||
if not files:
|
||||
HostInfo.main_window.toast_overlay.add_toast(ErrorToast(_("Could not add files"), _("No files were found to install")))
|
||||
return
|
||||
|
||||
self.file_dialog_handler(files)
|
||||
|
||||
except GLib.GError as gle:
|
||||
if not (gle.domain == "gtk-dialog-error-quark" and gle.code == 2):
|
||||
HostInfo.main_window.toast_overlay.add_toast(ErrorToast(_("Could not add files"), str(gle)).toast)
|
||||
|
||||
def on_open(self, *args):
|
||||
file_filter = Gtk.FileFilter(name=_("Flatpaks"))
|
||||
file_filter.add_suffix("flatpak")
|
||||
file_filter.add_suffix("flatpakref")
|
||||
filters = Gio.ListStore.new(Gtk.FileFilter)
|
||||
filters.append(file_filter)
|
||||
file_chooser = Gtk.FileDialog()
|
||||
file_chooser.set_filters(filters)
|
||||
file_chooser.set_default_filter(file_filter)
|
||||
file_chooser.open_multiple(HostInfo.main_window, None, self.file_choose_callback)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
self.remote_rows = []
|
||||
|
||||
# Connections
|
||||
self.add_remote_row.connect("activated", lambda *_: HostInfo.main_window.activate_row(HostInfo.main_window.remotes_row))
|
||||
self.nav_view.connect("popped", self.results_page.on_back)
|
||||
self.open_row.connect("activated", self.on_open)
|
||||
__gtype_name__ = "SelectPage"
|
||||
gtc = Gtk.Template.Child
|
||||
|
||||
nav_view = gtc()
|
||||
results_page = gtc()
|
||||
remotes_group = gtc()
|
||||
add_remote_row = gtc()
|
||||
open_row = gtc()
|
||||
|
||||
def start_loading(self):
|
||||
self.nav_view.pop()
|
||||
for row in self.remote_rows:
|
||||
self.remotes_group.remove(row)
|
||||
self.remote_rows.clear()
|
||||
|
||||
def end_loading(self):
|
||||
for installation, remotes in HostInfo.remotes.items():
|
||||
for remote in remotes:
|
||||
if remote.disabled:
|
||||
continue
|
||||
|
||||
row = Adw.ActionRow(title=remote.title, subtitle=_("Installation: {}").format(installation), activatable=True)
|
||||
row.add_suffix(Gtk.Image(icon_name="right-large-symbolic"))
|
||||
row.connect("activated", self.results_page.show_remote, remote, installation, self.nav_view)
|
||||
self.remotes_group.add(row)
|
||||
self.remote_rows.append(row)
|
||||
|
||||
self.remotes_group.set_visible(len(self.remote_rows) != 0)
|
||||
|
||||
def local_install_apply_callback(self, installation, file_names):
|
||||
install_page = HostInfo.main_window.pages[HostInfo.main_window.install_row]
|
||||
requests = []
|
||||
for file in file_names:
|
||||
# sadly flatpak doesn't support multiple local installs in one command :(
|
||||
requests.append({
|
||||
"remote": "local_file",
|
||||
"installation": installation,
|
||||
"package_names": [file.get_path()],
|
||||
"extra_flags": [],
|
||||
})
|
||||
|
||||
install_page.install_packages(requests)
|
||||
|
||||
def file_dialog_handler(self, files):
|
||||
FileInstallDialog(self, files, self.local_install_apply_callback).present(HostInfo.main_window)
|
||||
|
||||
def file_choose_callback(self, object, result):
|
||||
try:
|
||||
files = object.open_multiple_finish(result)
|
||||
if not files:
|
||||
HostInfo.main_window.toast_overlay.add_toast(ErrorToast(_("Could not add files"), _("No files were found to install")))
|
||||
return
|
||||
|
||||
self.file_dialog_handler(files)
|
||||
|
||||
except GLib.GError as gle:
|
||||
if not (gle.domain == "gtk-dialog-error-quark" and gle.code == 2):
|
||||
HostInfo.main_window.toast_overlay.add_toast(ErrorToast(_("Could not add files"), str(gle)).toast)
|
||||
|
||||
def on_open(self, *args):
|
||||
file_filter = Gtk.FileFilter(name=_("Flatpaks"))
|
||||
file_filter.add_suffix("flatpak")
|
||||
file_filter.add_suffix("flatpakref")
|
||||
filters = Gio.ListStore.new(Gtk.FileFilter)
|
||||
filters.append(file_filter)
|
||||
file_chooser = Gtk.FileDialog()
|
||||
file_chooser.set_filters(filters)
|
||||
file_chooser.set_default_filter(file_filter)
|
||||
file_chooser.open_multiple(HostInfo.main_window, None, self.file_choose_callback)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
self.remote_rows = []
|
||||
|
||||
# Connections
|
||||
self.add_remote_row.connect("activated", lambda *_: HostInfo.main_window.activate_row(HostInfo.main_window.remotes_row))
|
||||
self.nav_view.connect("popped", self.results_page.on_back)
|
||||
self.open_row.connect("activated", self.on_open)
|
||||
|
||||
448
src/main.py
448
src/main.py
@@ -31,228 +31,228 @@ from .const import Config
|
||||
from .error_toast import ErrorToast
|
||||
|
||||
class WarehouseApplication(Adw.Application):
|
||||
"""The main application singleton class."""
|
||||
|
||||
troubleshooting = "OS: {os}\nWarehouse version: {wv}\nGTK: {gtk}\nlibadwaita: {adw}\nApp ID: {app_id}\nProfile: {profile}\nLanguage: {lang}"
|
||||
version = Config.VERSION
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
application_id="io.github.flattool.Warehouse",
|
||||
flags=Gio.ApplicationFlags.DEFAULT_FLAGS,
|
||||
)
|
||||
self.create_action("about", self.on_about_action)
|
||||
self.create_action("preferences", self.on_preferences_action)
|
||||
self.create_action("quit", lambda *_: self.quit(), ["<primary>q"])
|
||||
self.create_action("open-menu", lambda *_: self.props.active_window.main_menu.popup(), ["F10"])
|
||||
self.create_action("refresh", lambda *_: self.props.active_window.refresh_handler(), ["<primary>r", "F5"])
|
||||
self.create_action("open-files", self.on_open_files_shortcut, ["<primary>o"])
|
||||
|
||||
self.create_action("show-packages-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("p"), ["<primary>p"])
|
||||
self.create_action("show-remotes-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("m"), ["<primary>m"])
|
||||
self.create_action("show-user-data-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("d"), ["<primary>d"])
|
||||
self.create_action("show-snapshots-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("s"), ["<primary>s"])
|
||||
self.create_action("show-install-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("i"), ["<primary>i"])
|
||||
|
||||
self.create_action("toggle-select-mode", self.on_toggle_select_mode_shortcut, ["<primary>b", "<primary>Return"])
|
||||
self.create_action("toggle-selection-kp-enter", self.on_toggle_select_mode_shortcut, ["<primary>KP_Enter"]) # Doesn't show in the shortcuts window
|
||||
self.create_action("search-mode", self.on_search_mode_shortcut, ["<primary>f"])
|
||||
self.create_action("filter", self.on_filter_shortcut, ["<primary>t"])
|
||||
self.create_action("new", self.on_new_shortcut, ["<primary>n"])
|
||||
self.create_action("active-data-view", lambda *_: self.on_data_view_shortcut(True), ["<Alt>1"])
|
||||
self.create_action("leftover-data-view", lambda *_: self.on_data_view_shortcut(False), ["<Alt>2"])
|
||||
|
||||
self.is_dialog_open = False
|
||||
|
||||
gtk_version = (
|
||||
str(Gtk.MAJOR_VERSION)
|
||||
+ "."
|
||||
+ str(Gtk.MINOR_VERSION)
|
||||
+ "."
|
||||
+ str(Gtk.MICRO_VERSION)
|
||||
)
|
||||
adw_version = (
|
||||
str(Adw.MAJOR_VERSION)
|
||||
+ "."
|
||||
+ str(Adw.MINOR_VERSION)
|
||||
+ "."
|
||||
+ str(Adw.MICRO_VERSION)
|
||||
)
|
||||
os_string = GLib.get_os_info("NAME") + " " + GLib.get_os_info("VERSION")
|
||||
lang = GLib.environ_getenv(GLib.get_environ(), "LANG")
|
||||
|
||||
self.troubleshooting = self.troubleshooting.format(
|
||||
os=os_string,
|
||||
wv=self.version,
|
||||
gtk=gtk_version,
|
||||
adw=adw_version,
|
||||
profile=Config.PROFILE,
|
||||
app_id=self.get_application_id(),
|
||||
lang=lang,
|
||||
)
|
||||
|
||||
def on_open_files_shortcut(self, *args):
|
||||
window = self.props.active_window
|
||||
|
||||
def file_choose_callback(object, result):
|
||||
try:
|
||||
files = object.open_multiple_finish(result)
|
||||
if not files:
|
||||
window.toast_overlay.add_toast(ErrorToast(_("Could not add files"), _("No files were found")).toast)
|
||||
return
|
||||
|
||||
window.on_file_drop(None, files, None, None)
|
||||
except GLib.GError as gle:
|
||||
if not (gle.domain == "gtk-dialog-error-quark" and gle.code == 2):
|
||||
window.toast_overlay.add_toast(ErrorToast(_("Could not add files"), str(gle)).toast)
|
||||
|
||||
file_filter = Gtk.FileFilter(name=_("Flatpaks & Remotes"))
|
||||
file_filter.add_suffix("flatpak")
|
||||
file_filter.add_suffix("flatpakref")
|
||||
file_filter.add_suffix("flatpakrepo")
|
||||
filters = Gio.ListStore.new(Gtk.FileFilter)
|
||||
filters.append(file_filter)
|
||||
file_chooser = Gtk.FileDialog()
|
||||
file_chooser.set_filters(filters)
|
||||
file_chooser.set_default_filter(file_filter)
|
||||
file_chooser.open_multiple(window, None, file_choose_callback)
|
||||
|
||||
def on_toggle_select_mode_shortcut(self, *args):
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().select_button
|
||||
button.set_active(not button.get_active())
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_search_mode_shortcut(self, *args):
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().search_button
|
||||
button.set_active(True)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_filter_shortcut(self, *args):
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().filter_button
|
||||
button.set_active(not button.get_active())
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().sort_button
|
||||
button.set_active(True)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().show_disabled_button
|
||||
if button.get_visible():
|
||||
button.set_active(not button.get_active())
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_new_shortcut(self, *args):
|
||||
page = self.props.active_window.stack.get_visible_child()
|
||||
try:
|
||||
page.new_custom_handler()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
page.on_new()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_delete_shortcut(self, *args):
|
||||
page = self.props.active_window.stack.get_visible_child()
|
||||
try:
|
||||
if not page.select_button.get_active():
|
||||
return
|
||||
|
||||
page.select_trash_handler()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_data_view_shortcut(self, is_active):
|
||||
page = self.props.active_window.stack.get_visible_child()
|
||||
try:
|
||||
adp = page.adp
|
||||
ldp = page.ldp
|
||||
page.stack.set_visible_child(adp if is_active else ldp)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def do_activate(self):
|
||||
"""Called when the application is activated.
|
||||
|
||||
We raise the application's main window, creating it if
|
||||
necessary.
|
||||
"""
|
||||
win = self.props.active_window
|
||||
if not win:
|
||||
win = WarehouseWindow(application=self)
|
||||
win.present()
|
||||
|
||||
def on_about_action(self, widget, _a):
|
||||
"""Callback for the app.about action."""
|
||||
about = Adw.AboutDialog(
|
||||
application_name="Warehouse",
|
||||
application_icon="io.github.flattool.Warehouse",
|
||||
developer_name="Heliguy",
|
||||
version=self.version,
|
||||
developers=[
|
||||
"Heliguy https://github.com/heliguy4599",
|
||||
"kramo https://kramo.page",
|
||||
],
|
||||
artists=[
|
||||
"Heliguy https://github.com/heliguy4599",
|
||||
"kramo https://kramo.page",
|
||||
"Amy https://github.com/AtiusAmy",
|
||||
"eryn https://github.com/hericiumvevo",
|
||||
],
|
||||
copyright="© 2023 Heliguy",
|
||||
license_type=Gtk.License.GPL_3_0_ONLY,
|
||||
debug_info=self.troubleshooting,
|
||||
# Translators: do one of the following, one per line: Your Name, Your Name <email@email.org>, Your Name https://your.website
|
||||
translator_credits=_("translator-credits"),
|
||||
debug_info_filename="{}.txt".format(self.get_application_id()),
|
||||
website="https://github.com/flattool/warehouse",
|
||||
support_url="https://matrix.to/#/#warehouse-development:matrix.org",
|
||||
issue_url="https://github.com/flattool/warehouse/issues",
|
||||
)
|
||||
about.add_link(_("Donate"), "https://ko-fi.com/heliguy")
|
||||
about.add_credit_section(
|
||||
_("Contributors"),
|
||||
[
|
||||
# Contributors: do one of the following, one per line: Your Name, Your Name <email@email.org>, Your Name https://your.website
|
||||
"Win <winsdominoes2018@gmail.com>",
|
||||
"Óscar Fernández Díaz",
|
||||
"Runar https://github.com/runarcn",
|
||||
"skøldis <warehouse@turtle.garden>",
|
||||
"Maxim Therrien <maxim@mtsd.ca>",
|
||||
],
|
||||
)
|
||||
about.present(self.props.active_window)
|
||||
|
||||
def on_preferences_action(self, widget, _):
|
||||
"""Callback for the app.preferences action."""
|
||||
print("app.preferences action activated")
|
||||
|
||||
def create_action(self, name, callback, shortcuts=None):
|
||||
"""Add an application action.
|
||||
|
||||
Args:
|
||||
name: the name of the action
|
||||
callback: the function to be called when the action is activated
|
||||
shortcuts: an optional list of accelerators
|
||||
"""
|
||||
action = Gio.SimpleAction.new(name, None)
|
||||
action.connect("activate", callback)
|
||||
self.add_action(action)
|
||||
if shortcuts:
|
||||
self.set_accels_for_action(f"app.{name}", shortcuts)
|
||||
|
||||
"""The main application singleton class."""
|
||||
|
||||
troubleshooting = "OS: {os}\nWarehouse version: {wv}\nGTK: {gtk}\nlibadwaita: {adw}\nApp ID: {app_id}\nProfile: {profile}\nLanguage: {lang}"
|
||||
version = Config.VERSION
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
application_id="io.github.flattool.Warehouse",
|
||||
flags=Gio.ApplicationFlags.DEFAULT_FLAGS,
|
||||
)
|
||||
self.create_action("about", self.on_about_action)
|
||||
self.create_action("preferences", self.on_preferences_action)
|
||||
self.create_action("quit", lambda *_: self.quit(), ["<primary>q"])
|
||||
self.create_action("open-menu", lambda *_: self.props.active_window.main_menu.popup(), ["F10"])
|
||||
self.create_action("refresh", lambda *_: self.props.active_window.refresh_handler(), ["<primary>r", "F5"])
|
||||
self.create_action("open-files", self.on_open_files_shortcut, ["<primary>o"])
|
||||
|
||||
self.create_action("show-packages-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("p"), ["<primary>p"])
|
||||
self.create_action("show-remotes-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("m"), ["<primary>m"])
|
||||
self.create_action("show-user-data-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("d"), ["<primary>d"])
|
||||
self.create_action("show-snapshots-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("s"), ["<primary>s"])
|
||||
self.create_action("show-install-page", lambda *_: self.props.active_window.switch_page_shortcut_handler("i"), ["<primary>i"])
|
||||
|
||||
self.create_action("toggle-select-mode", self.on_toggle_select_mode_shortcut, ["<primary>b", "<primary>Return"])
|
||||
self.create_action("toggle-selection-kp-enter", self.on_toggle_select_mode_shortcut, ["<primary>KP_Enter"]) # Doesn't show in the shortcuts window
|
||||
self.create_action("search-mode", self.on_search_mode_shortcut, ["<primary>f"])
|
||||
self.create_action("filter", self.on_filter_shortcut, ["<primary>t"])
|
||||
self.create_action("new", self.on_new_shortcut, ["<primary>n"])
|
||||
self.create_action("active-data-view", lambda *_: self.on_data_view_shortcut(True), ["<Alt>1"])
|
||||
self.create_action("leftover-data-view", lambda *_: self.on_data_view_shortcut(False), ["<Alt>2"])
|
||||
|
||||
self.is_dialog_open = False
|
||||
|
||||
gtk_version = (
|
||||
str(Gtk.MAJOR_VERSION)
|
||||
+ "."
|
||||
+ str(Gtk.MINOR_VERSION)
|
||||
+ "."
|
||||
+ str(Gtk.MICRO_VERSION)
|
||||
)
|
||||
adw_version = (
|
||||
str(Adw.MAJOR_VERSION)
|
||||
+ "."
|
||||
+ str(Adw.MINOR_VERSION)
|
||||
+ "."
|
||||
+ str(Adw.MICRO_VERSION)
|
||||
)
|
||||
os_string = GLib.get_os_info("NAME") + " " + GLib.get_os_info("VERSION")
|
||||
lang = GLib.environ_getenv(GLib.get_environ(), "LANG")
|
||||
|
||||
self.troubleshooting = self.troubleshooting.format(
|
||||
os=os_string,
|
||||
wv=self.version,
|
||||
gtk=gtk_version,
|
||||
adw=adw_version,
|
||||
profile=Config.PROFILE,
|
||||
app_id=self.get_application_id(),
|
||||
lang=lang,
|
||||
)
|
||||
|
||||
def on_open_files_shortcut(self, *args):
|
||||
window = self.props.active_window
|
||||
|
||||
def file_choose_callback(object, result):
|
||||
try:
|
||||
files = object.open_multiple_finish(result)
|
||||
if not files:
|
||||
window.toast_overlay.add_toast(ErrorToast(_("Could not add files"), _("No files were found")).toast)
|
||||
return
|
||||
|
||||
window.on_file_drop(None, files, None, None)
|
||||
except GLib.GError as gle:
|
||||
if not (gle.domain == "gtk-dialog-error-quark" and gle.code == 2):
|
||||
window.toast_overlay.add_toast(ErrorToast(_("Could not add files"), str(gle)).toast)
|
||||
|
||||
file_filter = Gtk.FileFilter(name=_("Flatpaks & Remotes"))
|
||||
file_filter.add_suffix("flatpak")
|
||||
file_filter.add_suffix("flatpakref")
|
||||
file_filter.add_suffix("flatpakrepo")
|
||||
filters = Gio.ListStore.new(Gtk.FileFilter)
|
||||
filters.append(file_filter)
|
||||
file_chooser = Gtk.FileDialog()
|
||||
file_chooser.set_filters(filters)
|
||||
file_chooser.set_default_filter(file_filter)
|
||||
file_chooser.open_multiple(window, None, file_choose_callback)
|
||||
|
||||
def on_toggle_select_mode_shortcut(self, *args):
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().select_button
|
||||
button.set_active(not button.get_active())
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_search_mode_shortcut(self, *args):
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().search_button
|
||||
button.set_active(True)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_filter_shortcut(self, *args):
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().filter_button
|
||||
button.set_active(not button.get_active())
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().sort_button
|
||||
button.set_active(True)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
button = self.props.active_window.stack.get_visible_child().show_disabled_button
|
||||
if button.get_visible():
|
||||
button.set_active(not button.get_active())
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_new_shortcut(self, *args):
|
||||
page = self.props.active_window.stack.get_visible_child()
|
||||
try:
|
||||
page.new_custom_handler()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
page.on_new()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_delete_shortcut(self, *args):
|
||||
page = self.props.active_window.stack.get_visible_child()
|
||||
try:
|
||||
if not page.select_button.get_active():
|
||||
return
|
||||
|
||||
page.select_trash_handler()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_data_view_shortcut(self, is_active):
|
||||
page = self.props.active_window.stack.get_visible_child()
|
||||
try:
|
||||
adp = page.adp
|
||||
ldp = page.ldp
|
||||
page.stack.set_visible_child(adp if is_active else ldp)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def do_activate(self):
|
||||
"""Called when the application is activated.
|
||||
|
||||
We raise the application's main window, creating it if
|
||||
necessary.
|
||||
"""
|
||||
win = self.props.active_window
|
||||
if not win:
|
||||
win = WarehouseWindow(application=self)
|
||||
win.present()
|
||||
|
||||
def on_about_action(self, widget, _a):
|
||||
"""Callback for the app.about action."""
|
||||
about = Adw.AboutDialog(
|
||||
application_name="Warehouse",
|
||||
application_icon="io.github.flattool.Warehouse",
|
||||
developer_name="Heliguy",
|
||||
version=self.version,
|
||||
developers=[
|
||||
"Heliguy https://github.com/heliguy4599",
|
||||
"kramo https://kramo.page",
|
||||
],
|
||||
artists=[
|
||||
"Heliguy https://github.com/heliguy4599",
|
||||
"kramo https://kramo.page",
|
||||
"Amy https://github.com/AtiusAmy",
|
||||
"eryn https://github.com/hericiumvevo",
|
||||
],
|
||||
copyright="© 2023 Heliguy",
|
||||
license_type=Gtk.License.GPL_3_0_ONLY,
|
||||
debug_info=self.troubleshooting,
|
||||
# Translators: do one of the following, one per line: Your Name, Your Name <email@email.org>, Your Name https://your.website
|
||||
translator_credits=_("translator-credits"),
|
||||
debug_info_filename="{}.txt".format(self.get_application_id()),
|
||||
website="https://github.com/flattool/warehouse",
|
||||
support_url="https://matrix.to/#/#warehouse-development:matrix.org",
|
||||
issue_url="https://github.com/flattool/warehouse/issues",
|
||||
)
|
||||
about.add_link(_("Donate"), "https://ko-fi.com/heliguy")
|
||||
about.add_credit_section(
|
||||
_("Contributors"),
|
||||
[
|
||||
# Contributors: do one of the following, one per line: Your Name, Your Name <email@email.org>, Your Name https://your.website
|
||||
"Win <winsdominoes2018@gmail.com>",
|
||||
"Óscar Fernández Díaz",
|
||||
"Runar https://github.com/runarcn",
|
||||
"skøldis <warehouse@turtle.garden>",
|
||||
"Maxim Therrien <maxim@mtsd.ca>",
|
||||
],
|
||||
)
|
||||
about.present(self.props.active_window)
|
||||
|
||||
def on_preferences_action(self, widget, _):
|
||||
"""Callback for the app.preferences action."""
|
||||
print("app.preferences action activated")
|
||||
|
||||
def create_action(self, name, callback, shortcuts=None):
|
||||
"""Add an application action.
|
||||
|
||||
Args:
|
||||
name: the name of the action
|
||||
callback: the function to be called when the action is activated
|
||||
shortcuts: an optional list of accelerators
|
||||
"""
|
||||
action = Gio.SimpleAction.new(name, None)
|
||||
action.connect("activate", callback)
|
||||
self.add_action(action)
|
||||
if shortcuts:
|
||||
self.set_accels_for_action(f"app.{name}", shortcuts)
|
||||
|
||||
def main(version):
|
||||
"""The application's entry point."""
|
||||
app = WarehouseApplication()
|
||||
return app.run(sys.argv)
|
||||
"""The application's entry point."""
|
||||
app = WarehouseApplication()
|
||||
return app.run(sys.argv)
|
||||
|
||||
@@ -2,161 +2,161 @@ using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $WarehouseWindow: Adw.ApplicationWindow {
|
||||
title: "Warehouse";
|
||||
width-request: 363;
|
||||
default-width: 921;
|
||||
default-height: 450;
|
||||
Adw.Breakpoint main_breakpoint {
|
||||
condition ("min-width: 865")
|
||||
setters {
|
||||
main_split.collapsed: false;
|
||||
main_split.max-sidebar-width: 999999999;
|
||||
}
|
||||
}
|
||||
content:
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
Overlay {
|
||||
[overlay]
|
||||
Revealer file_drop_revealer {
|
||||
can-target: false;
|
||||
transition-type: crossfade;
|
||||
Adw.StatusPage file_drop_view {
|
||||
icon-name: "folder-open-symbolic";
|
||||
title: _("Drop to Open");
|
||||
description: _("Install Flatpaks or Add a Remote");
|
||||
styles ["drag-overlay-status-page"]
|
||||
}
|
||||
}
|
||||
Adw.OverlaySplitView main_split {
|
||||
collapsed: true;
|
||||
show-sidebar: true;
|
||||
sidebar-width-fraction: 0.2;
|
||||
min-sidebar-width: 250;
|
||||
sidebar:
|
||||
Adw.NavigationPage {
|
||||
title: "Warehouse";
|
||||
Adw.ToolbarView main_toolbar_view {
|
||||
[top]
|
||||
Adw.HeaderBar header_bar {
|
||||
[start]
|
||||
Button refresh_button {
|
||||
icon-name: "arrow-circular-top-right-symbolic";
|
||||
tooltip-text: _("Refresh List");
|
||||
}
|
||||
[end]
|
||||
MenuButton main_menu {
|
||||
icon-name: "open-menu-symbolic";
|
||||
tooltip-text: _("Main Menu");
|
||||
menu-model: primary_menu;
|
||||
}
|
||||
}
|
||||
content:
|
||||
ScrolledWindow {
|
||||
ListBox navigation_row_listbox {
|
||||
styles ["navigation-sidebar"]
|
||||
Box packages_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image icon {
|
||||
icon-name: "flatpak-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("Packages");
|
||||
}
|
||||
}
|
||||
Box remotes_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image {
|
||||
icon-name: "server-pick-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("Remotes");
|
||||
}
|
||||
}
|
||||
|
||||
Box user_data_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image {
|
||||
icon-name: "file-manager-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("User Data");
|
||||
}
|
||||
}
|
||||
Box snapshots_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image {
|
||||
icon-name: "snapshots-alt-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("Snapshots");
|
||||
}
|
||||
}
|
||||
Box install_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image {
|
||||
icon-name: "arrow-pointing-at-line-down-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("Install Packages");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
||||
;
|
||||
content:
|
||||
Stack stack {
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
title: "Warehouse";
|
||||
width-request: 363;
|
||||
default-width: 921;
|
||||
default-height: 450;
|
||||
Adw.Breakpoint main_breakpoint {
|
||||
condition ("min-width: 865")
|
||||
setters {
|
||||
main_split.collapsed: false;
|
||||
main_split.max-sidebar-width: 999999999;
|
||||
}
|
||||
}
|
||||
content:
|
||||
Adw.ToastOverlay toast_overlay {
|
||||
Overlay {
|
||||
[overlay]
|
||||
Revealer file_drop_revealer {
|
||||
can-target: false;
|
||||
transition-type: crossfade;
|
||||
Adw.StatusPage file_drop_view {
|
||||
icon-name: "folder-open-symbolic";
|
||||
title: _("Drop to Open");
|
||||
description: _("Install Flatpaks or Add a Remote");
|
||||
styles ["drag-overlay-status-page"]
|
||||
}
|
||||
}
|
||||
Adw.OverlaySplitView main_split {
|
||||
collapsed: true;
|
||||
show-sidebar: true;
|
||||
sidebar-width-fraction: 0.2;
|
||||
min-sidebar-width: 250;
|
||||
sidebar:
|
||||
Adw.NavigationPage {
|
||||
title: "Warehouse";
|
||||
Adw.ToolbarView main_toolbar_view {
|
||||
[top]
|
||||
Adw.HeaderBar header_bar {
|
||||
[start]
|
||||
Button refresh_button {
|
||||
icon-name: "arrow-circular-top-right-symbolic";
|
||||
tooltip-text: _("Refresh List");
|
||||
}
|
||||
[end]
|
||||
MenuButton main_menu {
|
||||
icon-name: "open-menu-symbolic";
|
||||
tooltip-text: _("Main Menu");
|
||||
menu-model: primary_menu;
|
||||
}
|
||||
}
|
||||
content:
|
||||
ScrolledWindow {
|
||||
ListBox navigation_row_listbox {
|
||||
styles ["navigation-sidebar"]
|
||||
Box packages_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image icon {
|
||||
icon-name: "flatpak-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("Packages");
|
||||
}
|
||||
}
|
||||
Box remotes_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image {
|
||||
icon-name: "server-pick-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("Remotes");
|
||||
}
|
||||
}
|
||||
|
||||
Box user_data_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image {
|
||||
icon-name: "file-manager-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("User Data");
|
||||
}
|
||||
}
|
||||
Box snapshots_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image {
|
||||
icon-name: "snapshots-alt-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("Snapshots");
|
||||
}
|
||||
}
|
||||
Box install_row {
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
margin-start: 6;
|
||||
margin-end: 6;
|
||||
spacing: 12;
|
||||
Image {
|
||||
icon-name: "arrow-pointing-at-line-down-symbolic";
|
||||
}
|
||||
Label {
|
||||
label: _("Install Packages");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
||||
;
|
||||
content:
|
||||
Stack stack {
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
menu primary_menu {
|
||||
section {
|
||||
/*item {
|
||||
label: _("_Preferences");
|
||||
action: "app.preferences";
|
||||
}*/
|
||||
// item {
|
||||
// label: _("Refresh List");
|
||||
// action: "app.refresh-list";
|
||||
// }
|
||||
item {
|
||||
label: _("_Open Files");
|
||||
action: "app.open-files";
|
||||
}
|
||||
item {
|
||||
label: _("_Keyboard Shortcuts");
|
||||
action: "win.show-help-overlay";
|
||||
}
|
||||
item {
|
||||
label: _("_About Warehouse");
|
||||
action: "app.about";
|
||||
}
|
||||
}
|
||||
section {
|
||||
/*item {
|
||||
label: _("_Preferences");
|
||||
action: "app.preferences";
|
||||
}*/
|
||||
// item {
|
||||
// label: _("Refresh List");
|
||||
// action: "app.refresh-list";
|
||||
// }
|
||||
item {
|
||||
label: _("_Open Files");
|
||||
action: "app.open-files";
|
||||
}
|
||||
item {
|
||||
label: _("_Keyboard Shortcuts");
|
||||
action: "win.show-help-overlay";
|
||||
}
|
||||
item {
|
||||
label: _("_About Warehouse");
|
||||
action: "app.about";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,218 +28,218 @@ from .const import Config
|
||||
|
||||
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/main_window/window.ui")
|
||||
class WarehouseWindow(Adw.ApplicationWindow):
|
||||
__gtype_name__ = "WarehouseWindow"
|
||||
gtc = Gtk.Template.Child
|
||||
main_breakpoint = gtc()
|
||||
toast_overlay = gtc()
|
||||
file_drop_revealer = gtc()
|
||||
main_split = gtc()
|
||||
file_drop_view = gtc()
|
||||
stack = gtc()
|
||||
refresh_button = gtc()
|
||||
main_menu = gtc()
|
||||
navigation_row_listbox = gtc()
|
||||
packages_row = gtc()
|
||||
remotes_row = gtc()
|
||||
user_data_row = gtc()
|
||||
snapshots_row = gtc()
|
||||
install_row = gtc()
|
||||
__gtype_name__ = "WarehouseWindow"
|
||||
gtc = Gtk.Template.Child
|
||||
main_breakpoint = gtc()
|
||||
toast_overlay = gtc()
|
||||
file_drop_revealer = gtc()
|
||||
main_split = gtc()
|
||||
file_drop_view = gtc()
|
||||
stack = gtc()
|
||||
refresh_button = gtc()
|
||||
main_menu = gtc()
|
||||
navigation_row_listbox = gtc()
|
||||
packages_row = gtc()
|
||||
remotes_row = gtc()
|
||||
user_data_row = gtc()
|
||||
snapshots_row = gtc()
|
||||
install_row = gtc()
|
||||
|
||||
def start_loading(self, *args):
|
||||
for _, page in self.pages.items():
|
||||
if page.instance:
|
||||
page.instance.start_loading()
|
||||
def start_loading(self, *args):
|
||||
for _, page in self.pages.items():
|
||||
if page.instance:
|
||||
page.instance.start_loading()
|
||||
|
||||
def end_loading(self, *args):
|
||||
for _, page in self.pages.items():
|
||||
if page.instance:
|
||||
page.instance.end_loading()
|
||||
|
||||
self.refresh_button.set_sensitive(True)
|
||||
self.refresh_requested = False
|
||||
self.remove_refresh_lockout("refresh handler direct")
|
||||
|
||||
def do_refresh(self):
|
||||
self.start_loading()
|
||||
self.refresh_button.set_sensitive(False)
|
||||
HostInfo.get_flatpaks(callback=self.end_loading)
|
||||
def end_loading(self, *args):
|
||||
for _, page in self.pages.items():
|
||||
if page.instance:
|
||||
page.instance.end_loading()
|
||||
|
||||
self.refresh_button.set_sensitive(True)
|
||||
self.refresh_requested = False
|
||||
self.remove_refresh_lockout("refresh handler direct")
|
||||
|
||||
def do_refresh(self):
|
||||
self.start_loading()
|
||||
self.refresh_button.set_sensitive(False)
|
||||
HostInfo.get_flatpaks(callback=self.end_loading)
|
||||
|
||||
def refresh_handler(self, *args):
|
||||
if len(self.refresh_lockouts) == 0:
|
||||
self.add_refresh_lockout("refresh handler direct")
|
||||
self.do_refresh()
|
||||
elif "refresh handler direct" in self.refresh_lockouts:
|
||||
return
|
||||
else:
|
||||
self.refresh_requested = True
|
||||
|
||||
def add_refresh_lockout(self, reason):
|
||||
self.refresh_lockouts.append(reason)
|
||||
self.refresh_button.set_sensitive(False)
|
||||
|
||||
def remove_refresh_lockout(self, reason):
|
||||
if reason in self.refresh_lockouts:
|
||||
self.refresh_lockouts.remove(reason)
|
||||
|
||||
if len(self.refresh_lockouts) == 0:
|
||||
if self.refresh_requested:
|
||||
self.do_refresh()
|
||||
else:
|
||||
self.refresh_button.set_sensitive(True)
|
||||
def refresh_handler(self, *args):
|
||||
if len(self.refresh_lockouts) == 0:
|
||||
self.add_refresh_lockout("refresh handler direct")
|
||||
self.do_refresh()
|
||||
elif "refresh handler direct" in self.refresh_lockouts:
|
||||
return
|
||||
else:
|
||||
self.refresh_requested = True
|
||||
|
||||
def add_refresh_lockout(self, reason):
|
||||
self.refresh_lockouts.append(reason)
|
||||
self.refresh_button.set_sensitive(False)
|
||||
|
||||
def remove_refresh_lockout(self, reason):
|
||||
if reason in self.refresh_lockouts:
|
||||
self.refresh_lockouts.remove(reason)
|
||||
|
||||
if len(self.refresh_lockouts) == 0:
|
||||
if self.refresh_requested:
|
||||
self.do_refresh()
|
||||
else:
|
||||
self.refresh_button.set_sensitive(True)
|
||||
|
||||
def navigation_handler(self, _, row):
|
||||
row = row.get_child()
|
||||
page = self.pages[row]
|
||||
self.stack.set_visible_child(page)
|
||||
self.settings.set_string("page-shown", page.page_name)
|
||||
if self.main_split.get_collapsed():
|
||||
self.main_split.set_show_sidebar(False)
|
||||
def navigation_handler(self, _, row):
|
||||
row = row.get_child()
|
||||
page = self.pages[row]
|
||||
self.stack.set_visible_child(page)
|
||||
self.settings.set_string("page-shown", page.page_name)
|
||||
if self.main_split.get_collapsed():
|
||||
self.main_split.set_show_sidebar(False)
|
||||
|
||||
def activate_row(self, nav_row):
|
||||
idx = 0
|
||||
while row := self.navigation_row_listbox.get_row_at_index(idx):
|
||||
idx += 1
|
||||
if row.get_child() is nav_row:
|
||||
row.activate()
|
||||
nav_row.grab_focus()
|
||||
break
|
||||
def activate_row(self, nav_row):
|
||||
idx = 0
|
||||
while row := self.navigation_row_listbox.get_row_at_index(idx):
|
||||
idx += 1
|
||||
if row.get_child() is nav_row:
|
||||
row.activate()
|
||||
nav_row.grab_focus()
|
||||
break
|
||||
|
||||
def show_saved_page(self):
|
||||
page_to_show = self.settings.get_string("page-shown")
|
||||
page_found = False
|
||||
for row, page in self.pages.items():
|
||||
self.stack.add_child(page)
|
||||
def show_saved_page(self):
|
||||
page_to_show = self.settings.get_string("page-shown")
|
||||
page_found = False
|
||||
for row, page in self.pages.items():
|
||||
self.stack.add_child(page)
|
||||
|
||||
if page.page_name == page_to_show:
|
||||
page_found = True
|
||||
self.activate_row(row)
|
||||
if page.page_name == page_to_show:
|
||||
page_found = True
|
||||
self.activate_row(row)
|
||||
|
||||
if not page_found:
|
||||
self.navigation_row_listbox.get_row_at_index(0).activate()
|
||||
|
||||
def on_file_drop(self, drop_target, value, x, y):
|
||||
try:
|
||||
paks = []
|
||||
remotes = []
|
||||
for file in value:
|
||||
path = file.get_path()
|
||||
if path.endswith(".flatpak") or path.endswith(".flatpakref"):
|
||||
paks.append(Gio.File.new_for_path(path))
|
||||
elif path.endswith(".flatpakrepo"):
|
||||
remotes.append(path)
|
||||
else:
|
||||
dialog = Adw.AlertDialog(
|
||||
heading=_("Unsupported Filetype"),
|
||||
body=_("Only .flatpak, .flatpakref, and .flatpakrepo files are supported."),
|
||||
)
|
||||
dialog.add_response("continue", _("OK"))
|
||||
dialog.present(self)
|
||||
return
|
||||
|
||||
if len(remotes) > 0 and len(paks) > 0:
|
||||
dialog = Adw.AlertDialog(
|
||||
heading=_("Mixed Filetypes"),
|
||||
body=_("Flatpaks and remotes cannot be installed at the same time."),
|
||||
)
|
||||
dialog.add_css_class("error")
|
||||
dialog.add_response("continue", _("OK"))
|
||||
dialog.present(self)
|
||||
return
|
||||
|
||||
if len(remotes) > 1:
|
||||
dialog = Adw.AlertDialog(
|
||||
heading=_("Too Many Remotes"),
|
||||
body=_("Only one remote at a time is supported."),
|
||||
)
|
||||
dialog.add_response("continue", _("OK"))
|
||||
dialog.present(self)
|
||||
return
|
||||
|
||||
if len(remotes) == 1:
|
||||
# Adding a remote
|
||||
self.activate_row(self.remotes_row)
|
||||
remotes_page = self.pages[self.remotes_row]
|
||||
remotes_page.local_file_handler(remotes[0])
|
||||
elif len(paks) > 0:
|
||||
# Add packages
|
||||
self.activate_row(self.install_row)
|
||||
install_page = self.pages[self.install_row]
|
||||
install_page.select_page.file_dialog_handler(paks)
|
||||
|
||||
except Exception as e:
|
||||
self.toast_overlay.add_toast(ErrorToast(_("Could not open files"), str(e)).toast)
|
||||
|
||||
def on_drop_enter(self, *args):
|
||||
self.main_split.add_css_class("blurred")
|
||||
self.file_drop_revealer.set_reveal_child(True)
|
||||
return 1
|
||||
|
||||
def on_drop_leave(self, *args):
|
||||
self.main_split.remove_css_class("blurred")
|
||||
self.file_drop_revealer.set_reveal_child(False)
|
||||
|
||||
def switch_page_shortcut_handler(self, letter):
|
||||
self.activate_row(self.shortcut_to_pages[letter])
|
||||
|
||||
def key_handler(self, controller, keyval, keycode, state):
|
||||
page = self.stack.get_visible_child()
|
||||
if keyval == Gdk.KEY_BackSpace or keyval == Gdk.KEY_Delete:
|
||||
try:
|
||||
if page.select_button.get_active():
|
||||
page.on_backspace_handler()
|
||||
except AttributeError:
|
||||
pass
|
||||
elif keyval == Gdk.KEY_Escape:
|
||||
try:
|
||||
page.on_escape_handler()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
if not page_found:
|
||||
self.navigation_row_listbox.get_row_at_index(0).activate()
|
||||
|
||||
def on_file_drop(self, drop_target, value, x, y):
|
||||
try:
|
||||
paks = []
|
||||
remotes = []
|
||||
for file in value:
|
||||
path = file.get_path()
|
||||
if path.endswith(".flatpak") or path.endswith(".flatpakref"):
|
||||
paks.append(Gio.File.new_for_path(path))
|
||||
elif path.endswith(".flatpakrepo"):
|
||||
remotes.append(path)
|
||||
else:
|
||||
dialog = Adw.AlertDialog(
|
||||
heading=_("Unsupported Filetype"),
|
||||
body=_("Only .flatpak, .flatpakref, and .flatpakrepo files are supported."),
|
||||
)
|
||||
dialog.add_response("continue", _("OK"))
|
||||
dialog.present(self)
|
||||
return
|
||||
|
||||
if len(remotes) > 0 and len(paks) > 0:
|
||||
dialog = Adw.AlertDialog(
|
||||
heading=_("Mixed Filetypes"),
|
||||
body=_("Flatpaks and remotes cannot be installed at the same time."),
|
||||
)
|
||||
dialog.add_css_class("error")
|
||||
dialog.add_response("continue", _("OK"))
|
||||
dialog.present(self)
|
||||
return
|
||||
|
||||
if len(remotes) > 1:
|
||||
dialog = Adw.AlertDialog(
|
||||
heading=_("Too Many Remotes"),
|
||||
body=_("Only one remote at a time is supported."),
|
||||
)
|
||||
dialog.add_response("continue", _("OK"))
|
||||
dialog.present(self)
|
||||
return
|
||||
|
||||
if len(remotes) == 1:
|
||||
# Adding a remote
|
||||
self.activate_row(self.remotes_row)
|
||||
remotes_page = self.pages[self.remotes_row]
|
||||
remotes_page.local_file_handler(remotes[0])
|
||||
elif len(paks) > 0:
|
||||
# Add packages
|
||||
self.activate_row(self.install_row)
|
||||
install_page = self.pages[self.install_row]
|
||||
install_page.select_page.file_dialog_handler(paks)
|
||||
|
||||
except Exception as e:
|
||||
self.toast_overlay.add_toast(ErrorToast(_("Could not open files"), str(e)).toast)
|
||||
|
||||
def on_drop_enter(self, *args):
|
||||
self.main_split.add_css_class("blurred")
|
||||
self.file_drop_revealer.set_reveal_child(True)
|
||||
return 1
|
||||
|
||||
def on_drop_leave(self, *args):
|
||||
self.main_split.remove_css_class("blurred")
|
||||
self.file_drop_revealer.set_reveal_child(False)
|
||||
|
||||
def switch_page_shortcut_handler(self, letter):
|
||||
self.activate_row(self.shortcut_to_pages[letter])
|
||||
|
||||
def key_handler(self, controller, keyval, keycode, state):
|
||||
page = self.stack.get_visible_child()
|
||||
if keyval == Gdk.KEY_BackSpace or keyval == Gdk.KEY_Delete:
|
||||
try:
|
||||
if page.select_button.get_active():
|
||||
page.on_backspace_handler()
|
||||
except AttributeError:
|
||||
pass
|
||||
elif keyval == Gdk.KEY_Escape:
|
||||
try:
|
||||
page.on_escape_handler()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Extra Object Creation
|
||||
HostInfo.main_window = self
|
||||
ErrorToast.main_window = self
|
||||
self.settings = Gio.Settings.new("io.github.flattool.Warehouse")
|
||||
self.pages = {
|
||||
self.packages_row: PackagesPage(main_window=self),
|
||||
self.remotes_row: RemotesPage(main_window=self),
|
||||
self.user_data_row: UserDataPage(main_window=self),
|
||||
self.snapshots_row: SnapshotPage(main_window=self),
|
||||
self.install_row: InstallPage(main_window=self),
|
||||
}
|
||||
self.shortcut_to_pages = {
|
||||
"p": self.packages_row,
|
||||
"m": self.remotes_row,
|
||||
"d": self.user_data_row,
|
||||
"s": self.snapshots_row,
|
||||
"i": self.install_row,
|
||||
}
|
||||
self.navigation_row_listbox.connect("row-activated", self.navigation_handler)
|
||||
self.show_saved_page()
|
||||
self.refresh_lockouts = []
|
||||
self.refresh_requested = False
|
||||
file_drop = Gtk.DropTarget.new(Gdk.FileList, Gdk.DragAction.COPY)
|
||||
event_controller = Gtk.EventControllerKey()
|
||||
# Extra Object Creation
|
||||
HostInfo.main_window = self
|
||||
ErrorToast.main_window = self
|
||||
self.settings = Gio.Settings.new("io.github.flattool.Warehouse")
|
||||
self.pages = {
|
||||
self.packages_row: PackagesPage(main_window=self),
|
||||
self.remotes_row: RemotesPage(main_window=self),
|
||||
self.user_data_row: UserDataPage(main_window=self),
|
||||
self.snapshots_row: SnapshotPage(main_window=self),
|
||||
self.install_row: InstallPage(main_window=self),
|
||||
}
|
||||
self.shortcut_to_pages = {
|
||||
"p": self.packages_row,
|
||||
"m": self.remotes_row,
|
||||
"d": self.user_data_row,
|
||||
"s": self.snapshots_row,
|
||||
"i": self.install_row,
|
||||
}
|
||||
self.navigation_row_listbox.connect("row-activated", self.navigation_handler)
|
||||
self.show_saved_page()
|
||||
self.refresh_lockouts = []
|
||||
self.refresh_requested = False
|
||||
file_drop = Gtk.DropTarget.new(Gdk.FileList, Gdk.DragAction.COPY)
|
||||
event_controller = Gtk.EventControllerKey()
|
||||
|
||||
# Apply
|
||||
self.add_controller(file_drop)
|
||||
self.add_controller(event_controller)
|
||||
self.settings.bind("window-width", self, "default-width", Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind("window-height", self, "default-height", Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind("is-maximized", self, "maximized", Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind("is-fullscreen", self, "fullscreened", Gio.SettingsBindFlags.DEFAULT)
|
||||
if Config.DEVEL:
|
||||
self.add_css_class("devel")
|
||||
# Apply
|
||||
self.add_controller(file_drop)
|
||||
self.add_controller(event_controller)
|
||||
self.settings.bind("window-width", self, "default-width", Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind("window-height", self, "default-height", Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind("is-maximized", self, "maximized", Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind("is-fullscreen", self, "fullscreened", Gio.SettingsBindFlags.DEFAULT)
|
||||
if Config.DEVEL:
|
||||
self.add_css_class("devel")
|
||||
|
||||
# Connections
|
||||
file_drop.connect("drop", self.on_file_drop)
|
||||
file_drop.connect("enter", self.on_drop_enter)
|
||||
file_drop.connect("leave", self.on_drop_leave)
|
||||
event_controller.connect("key-pressed", self.key_handler)
|
||||
self.refresh_button.connect("clicked", self.refresh_handler)
|
||||
|
||||
# Apply again
|
||||
self.start_loading()
|
||||
HostInfo.get_flatpaks(callback=self.end_loading)
|
||||
# Connections
|
||||
file_drop.connect("drop", self.on_file_drop)
|
||||
file_drop.connect("enter", self.on_drop_enter)
|
||||
file_drop.connect("leave", self.on_drop_leave)
|
||||
event_controller.connect("key-pressed", self.key_handler)
|
||||
self.refresh_button.connect("clicked", self.refresh_handler)
|
||||
|
||||
# Apply again
|
||||
self.start_loading()
|
||||
HostInfo.get_flatpaks(callback=self.end_loading)
|
||||
|
||||
@@ -240,89 +240,89 @@ template $PropertiesPage : Adw.NavigationPage {
|
||||
}
|
||||
}
|
||||
Adw.PreferencesGroup remote_info {
|
||||
margin-bottom: 12;
|
||||
title: _("Installation Information");
|
||||
Adw.ActionRow sdk_row {
|
||||
styles ["property"]
|
||||
title: "SDK";
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow origin_row {
|
||||
styles ["property"]
|
||||
title: _("Origin");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow collection_row {
|
||||
styles ["property"]
|
||||
title: _("Collection");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow installation_row {
|
||||
styles ["property"]
|
||||
title: _("Installation");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.PreferencesGroup commit_info {
|
||||
title: _("Commit Information");
|
||||
Adw.ActionRow commit_row {
|
||||
styles ["property"]
|
||||
title: "Commit";
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow parent_row {
|
||||
styles ["property"]
|
||||
title: _("Parent");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow subject_row {
|
||||
styles ["property"]
|
||||
title: _("Subject");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow date_row {
|
||||
styles ["property"]
|
||||
title: _("Date");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
margin-bottom: 12;
|
||||
title: _("Installation Information");
|
||||
Adw.ActionRow sdk_row {
|
||||
styles ["property"]
|
||||
title: "SDK";
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow origin_row {
|
||||
styles ["property"]
|
||||
title: _("Origin");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow collection_row {
|
||||
styles ["property"]
|
||||
title: _("Collection");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow installation_row {
|
||||
styles ["property"]
|
||||
title: _("Installation");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
Adw.PreferencesGroup commit_info {
|
||||
title: _("Commit Information");
|
||||
Adw.ActionRow commit_row {
|
||||
styles ["property"]
|
||||
title: "Commit";
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow parent_row {
|
||||
styles ["property"]
|
||||
title: _("Parent");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow subject_row {
|
||||
styles ["property"]
|
||||
title: _("Subject");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
Adw.ActionRow date_row {
|
||||
styles ["property"]
|
||||
title: _("Date");
|
||||
activatable: true;
|
||||
Image {
|
||||
icon-name: "copy-symbolic";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Popover more_menu {
|
||||
styles ["menu"]
|
||||
ListBox more_list {
|
||||
}
|
||||
styles ["menu"]
|
||||
ListBox more_list {
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user