diff --git a/data/icons/arrow-turn-down-right-symbolic.svg b/data/icons/arrow-turn-down-right-symbolic.svg
new file mode 100644
index 0000000..09bd65f
--- /dev/null
+++ b/data/icons/arrow-turn-down-right-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/data/icons/minus-large-symbolic.svg b/data/icons/minus-large-symbolic.svg
new file mode 100644
index 0000000..09943ae
--- /dev/null
+++ b/data/icons/minus-large-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/install_page/install_page.blp b/src/install_page/install_page.blp
new file mode 100644
index 0000000..2165e85
--- /dev/null
+++ b/src/install_page/install_page.blp
@@ -0,0 +1,163 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $InstallPage : Adw.BreakpointBin {
+ width-request: 1;
+ height-request: 1;
+
+ Adw.Breakpoint bp1 {
+ condition ("max-width: 600")
+
+ setters {
+ split_view.collapsed: true;
+ split_view.show-content: false;
+ }
+ }
+
+ Adw.ToastOverlay toast_overlay {
+ Adw.NavigationSplitView split_view {
+ sidebar-width-fraction: 0.5;
+ max-sidebar-width: 999999999;
+ sidebar:
+ Adw.NavigationPage sidebar_navpage {
+ title: _("Search for Packages");
+
+ Gtk.Stack sb_stack {
+ Adw.ToolbarView no_remotes {
+ visible: false;
+ [top]
+ Adw.HeaderBar {
+ show-title: false;
+ }
+ Adw.StatusPage {
+ icon-name: "error-symbolic";
+ title: _("No Remotes Found");
+ description: _("Warehouse cannot see the current remotes or your system has no remotes added");
+ Button open_remotes_page_button {
+ label: _("Add Remotes");
+ halign: center;
+ styles ["pill"]
+ }
+ }
+ }
+
+ Adw.NavigationView sb_page_view {
+ Adw.NavigationPage {
+ title: _("Install Packages");
+
+ Adw.ToolbarView {
+ [top]
+ Adw.HeaderBar {
+ }
+ Adw.PreferencesPage {
+ Adw.PreferencesGroup remotes_group {
+ title: "Choose a Remote";
+ description: "Choose a remote to search for packages in";
+ }
+ }
+ }
+ }
+
+ Adw.NavigationPage results {
+ title: _("Search REMOTE");
+
+ Adw.ToolbarView sidebar_tbv {
+ [top]
+ Adw.HeaderBar header_bar {
+ show-back-button: false;
+ [start]
+ ToggleButton sidebar_button {
+ icon-name: "dock-left-symbolic";
+ tooltip-text: _("Show Sidebar");
+ }
+ [start]
+ Button back_button {
+ icon-name: "left-large-symbolic";
+ tooltip-text: _("Back");
+ }
+ }
+ [top]
+ Adw.Clamp {
+ maximum-size: 577;
+ Box {
+ margin-top: 3;
+ margin-bottom: 3;
+ margin-start: 6;
+ margin-end: 6;
+ styles ["linked"]
+ Gtk.SearchEntry search_entry {
+ search-delay: 700;
+ halign: fill;
+ hexpand: true;
+ placeholder-text: _("Search for Packages");
+ }
+ Button search_apply_button {
+ icon-name: "right-large-symbolic";
+ }
+ }
+ }
+ ScrolledWindow {
+ Adw.Clamp {
+ ListBox results_list {
+ styles["boxed-list"]
+ valign: start;
+ selection-mode: none;
+ margin-start: 12;
+ margin-end: 12;
+ margin-top: 12;
+ margin-bottom: 12;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ;
+ content:
+ Adw.NavigationPage results_page {
+ title: _("Pending Packages");
+ Adw.ToolbarView {
+ [top]
+ Adw.HeaderBar {
+ [start]
+ Button clear_button {
+ label: _("Remove All");
+ }
+ }
+ [bottom]
+ Box {
+ homogeneous: true;
+ styles ["toolbar"]
+ Button remove_all_button {
+ styles ["raised"]
+ Adw.ButtonContent {
+ can-shrink: true;
+ icon-name: "minus-large-symbolic";
+ label: _("Remove All");
+ }
+ }
+ Button open_button {
+ styles ["raised"]
+ Adw.ButtonContent {
+ can-shrink: true;
+ icon-name: "folder-open-symbolic";
+ label: _("Add File");
+ }
+ }
+ Button install_button {
+ styles ["raised", "suggested-action"]
+ Adw.ButtonContent {
+ can-shrink: true;
+ icon-name: "arrow-pointing-at-line-down-symbolic";
+ label: _("Install");
+ }
+ }
+ }
+ }
+ }
+ ;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/install_page/install_page.py b/src/install_page/install_page.py
new file mode 100644
index 0000000..cb18d3c
--- /dev/null
+++ b/src/install_page/install_page.py
@@ -0,0 +1,94 @@
+from gi.repository import Adw, Gtk, GLib, Gio
+from .host_info import HostInfo
+from .error_toast import ErrorToast
+from .app_row import AppRow
+from .snapshots_list_page import SnapshotsListPage
+import os, subprocess
+
+@Gtk.Template(resource_path="/io/github/flattool/Warehouse/install_page/install_page.ui")
+class InstallPage(Adw.BreakpointBin):
+ __gtype_name__ = "InstallPage"
+ gtc = Gtk.Template.Child
+
+ remotes_group = gtc()
+ sb_page_view = gtc()
+ results = gtc()
+ back_button = gtc()
+ search_entry = gtc()
+ search_apply_button = gtc()
+ results_list = 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
+
+ current_installation = ""
+ current_remote = None
+
+ def start_loading(self):
+ pass
+
+ def end_loading(self):
+ for installation in HostInfo.installations:
+ for remote in HostInfo.remotes[installation]:
+ 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.remote_selected, installation, remote)
+ self.remotes_group.add(row)
+
+ def remote_selected(self, row, installation, remote):
+ self.current_installation = installation
+ self.current_remote = remote
+ self.results.set_title(_("Search {}").format(remote.title))
+ self.sb_page_view.push(self.results)
+ self.search_entry.set_text("firefox")
+ self.search_entry.grab_focus()
+
+ def on_search(self, _):
+ text = self.search_entry.get_text().strip().lower().replace(" ", "")
+ if not text:
+ return
+
+ results = []
+ def thread(*args):
+ installation = ""
+ self.results_list.remove_all()
+ if self.current_installation == "user" or self.current_installation == "system":
+ installation = f"--{self.current_installation}"
+ else:
+ installation = f"--installation={self.current_installation}"
+
+ try:
+ output = subprocess.run(['flatpak-spawn', '--host', 'flatpak', 'search', '--columns=all', installation, text], text=True, check=True, capture_output=True).stdout.split("\n")
+ for line in output:
+ info = line.split("\t")
+ if len(info) != 6:
+ continue
+
+ name = GLib.markup_escape_text(info[0])
+ description = GLib.markup_escape_text(info[1])
+ app_id = GLib.markup_escape_text(info[2])
+ version = GLib.markup_escape_text(info[3])
+ branch = GLib.markup_escape_text(info[4])
+ remotes = GLib.markup_escape_text(info[5])
+ row = Adw.ActionRow(title=name, subtitle=app_id)
+
+ self.results_list.append(row)
+
+ except Exception as e:
+ print(e)
+ except subprocess.CalledProcessError as cpe:
+ print(cpe)
+
+ thread()
+
+ def __init__(self, main_window, **kwargs):
+ super().__init__(**kwargs)
+ self.instance = self
+ self.back_button.connect("clicked", lambda *_: self.sb_page_view.pop())
+ # self.search_entry.connect("search-changed", self.on_search)
+ self.search_entry.connect("activate", self.on_search)
+ self.search_apply_button.connect("clicked", self.on_search)
\ No newline at end of file
diff --git a/src/main_window/window.py b/src/main_window/window.py
index 74d8c72..40ede06 100644
--- a/src/main_window/window.py
+++ b/src/main_window/window.py
@@ -28,6 +28,7 @@ from .packages_page import PackagesPage
from .remotes_page import RemotesPage
from .user_data_page import UserDataPage
from .snapshot_page import SnapshotPage
+from .install_page import InstallPage
from .const import Config
from .error_toast import ErrorToast
@@ -100,7 +101,7 @@ class WarehouseWindow(Adw.ApplicationWindow):
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: None,
+ self.install_row: InstallPage(main_window=self),
}
for _, page in self.pages.items():
@@ -123,7 +124,7 @@ class WarehouseWindow(Adw.ApplicationWindow):
# file_drop.connect("drop", self.drop_callback)
self.refresh_button.connect("clicked", self.refresh_handler)
- self.activate_row(self.packages_row)
+ self.activate_row(self.install_row)
self.main_split.set_show_sidebar(True)
self.start_loading()
diff --git a/src/meson.build b/src/meson.build
index 8fbafc1..a5cfac8 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -20,6 +20,7 @@ blueprints = custom_target('blueprints',
'snapshot_page/snapshot_page.blp',
'snapshot_page/snapshots_list_page.blp',
'snapshot_page/snapshot_box.blp',
+ 'install_page/install_page.blp',
),
output: '.',
command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'],
@@ -78,6 +79,7 @@ warehouse_sources = [
'snapshot_page/snapshot_page.py',
'snapshot_page/snapshots_list_page.py',
'snapshot_page/snapshot_box.py',
+ 'install_page/install_page.py',
'../data/style.css',
]
diff --git a/src/warehouse.gresource.xml b/src/warehouse.gresource.xml
index 49cbf8f..9ad410f 100644
--- a/src/warehouse.gresource.xml
+++ b/src/warehouse.gresource.xml
@@ -18,6 +18,7 @@
snapshot_page/snapshot_page.ui
snapshot_page/snapshots_list_page.ui
snapshot_page/snapshot_box.ui
+ install_page/install_page.ui
@@ -65,5 +66,7 @@
../data/icons/font-x-generic-symbolic.svg
../data/icons/tag-outline-symbolic.svg
../data/icons/harddisk-symbolic.svg
+ ../data/icons/arrow-turn-down-right-symbolic.svg
+ ../data/icons/minus-large-symbolic.svg