diff --git a/io.github.flattool.Warehouse.json b/io.github.flattool.Warehouse.json
index ca2f685..047651d 100644
--- a/io.github.flattool.Warehouse.json
+++ b/io.github.flattool.Warehouse.json
@@ -44,6 +44,7 @@
"name" : "warehouse",
"builddir" : true,
"buildsystem" : "meson",
+ "config-opts": [ "-Dprofile=development" ],
"sources" : [
{
"type" : "dir",
diff --git a/meson.build b/meson.build
index ae25ec8..a36cacf 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
project('warehouse',
- version: '1.3.1.beta',
+ version: '1.3.1',
meson_version: '>= 0.62.0',
default_options: [ 'warning_level=2', 'werror=false', ],
)
@@ -7,8 +7,6 @@ project('warehouse',
i18n = import('i18n')
gnome = import('gnome')
-
-
subdir('data')
subdir('src')
subdir('po')
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..db3076f
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,9 @@
+option(
+ 'profile',
+ type: 'combo',
+ choices: [
+ 'default',
+ 'development'
+ ],
+ value: 'default'
+)
\ No newline at end of file
diff --git a/src/brush-symbolic.svg b/src/brush-symbolic.svg
deleted file mode 100644
index 45fdd8f..0000000
--- a/src/brush-symbolic.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/src/common.py b/src/common.py
index e96a0bd..4331959 100644
--- a/src/common.py
+++ b/src/common.py
@@ -143,14 +143,17 @@ class myUtils:
sorted_array = sorted(data, key=lambda item: item[0].lower())
return sorted_array
- def getDependantRuntimes(self):
+ def getDependentRuntimes(self):
paks = self.getHostFlatpaks()
- dependant_runtimes = []
+ dependent_runtimes = []
for i in range(len(paks)):
current = paks[i]
- if current[13] not in dependant_runtimes and current[13] != "":
- dependant_runtimes.append(current[13])
- return(dependant_runtimes)
+ try:
+ if current[13] not in dependent_runtimes and current[13] != "":
+ dependent_runtimes.append(current[13])
+ except:
+ print("Could not get dependent runtime")
+ return(dependent_runtimes)
def getHostMasks(self, user_or_system):
output = subprocess.run(["flatpak-spawn", "--host", "flatpak", "mask", f"--{user_or_system}"], capture_output=True, text=True, env=self.new_env).stdout
diff --git a/src/const.py.in b/src/const.py.in
new file mode 100644
index 0000000..1f7da55
--- /dev/null
+++ b/src/const.py.in
@@ -0,0 +1,8 @@
+#!@PYTHON@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+class Config:
+ DEVEL = '@DEVEL@' == 'Development'
+ PROFILE = '@DEVEL@'
+ APP_ID = '@APPID@'
+ VERSION = '@VERSION@'
\ No newline at end of file
diff --git a/src/downgrade.blp b/src/downgrade.blp
index fde194e..00211d3 100644
--- a/src/downgrade.blp
+++ b/src/downgrade.blp
@@ -1,54 +1,60 @@
using Gtk 4.0;
using Adw 1;
-template DowngradeWindow : Adw.Window {
- default-width: 500;
- default-height: 450;
- modal: true;
+template DowngradeWindow: Adw.Window {
+ default-width: 500;
+ default-height: 450;
+ modal: true;
- Adw.ToolbarView main_toolbar_view {
- [top]
- HeaderBar header_bar {
- show-title-buttons: false;
+ Adw.ToolbarView main_toolbar_view {
+ [top]
+ HeaderBar header_bar {
+ show-title-buttons: false;
- [start]
- Button cancel_button {
- label: _("Cancel");
- }
- [end]
- Button apply_button {
- sensitive: false;
- label: _("Downgrade");
- styles["suggested-action"]
- }
- }
- content:
- Adw.ToastOverlay toast_overlay {
- Stack main_stack {
- Overlay main_overlay {
- [overlay]
- ProgressBar progress_bar {
- pulse-step: 0.7;
- can-target: false;
- styles["osd"]
- }
+ [start]
+ Button cancel_button {
+ label: _("Cancel");
+ }
- Adw.PreferencesPage outerbox {
-
- Adw.PreferencesGroup {
- Adw.SwitchRow mask_row {
- title: _("Disable Updates");
- active: true;
- }
- }
+ [end]
+ Button apply_button {
+ sensitive: false;
+ label: _("Downgrade");
- 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.");
- }
- }
- }
- }
- };
+ styles [
+ "suggested-action"
+ ]
+ }
}
-}
\ No newline at end of file
+
+ content: Adw.ToastOverlay toast_overlay {
+ Stack main_stack {
+ Overlay main_overlay {
+ [overlay]
+ ProgressBar progress_bar {
+ pulse-step: 0.7;
+ can-target: false;
+
+ styles [
+ "osd"
+ ]
+ }
+
+ Adw.PreferencesPage outerbox {
+ Adw.PreferencesGroup {
+ 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.");
+ }
+ }
+ }
+ }
+ };
+ }
+}
diff --git a/src/filter.blp b/src/filter.blp
index c1ae00a..439f4d1 100644
--- a/src/filter.blp
+++ b/src/filter.blp
@@ -1,86 +1,98 @@
using Gtk 4.0;
using Adw 1;
-template FilterWindow : Adw.Window {
- default-width: 500;
- default-height: 450;
- title: _("Set Filters");
- modal: true;
+template FilterWindow: Adw.Window {
+ default-width: 500;
+ default-height: 450;
+ title: _("Set Filters");
+ modal: true;
- Adw.ToolbarView main_toolbar_view {
- [top]
- HeaderBar header_bar {
- show-title-buttons: false;
+ Adw.ToolbarView main_toolbar_view {
+ [top]
+ HeaderBar header_bar {
+ show-title-buttons: false;
- [start]
- Button cancel_button {
- label: _("Cancel");
- }
- [end]
- Button apply_button {
- label: _("Apply");
- styles["suggested-action"]
- }
- }
- content:
- Adw.ToastOverlay toast_overlay {
- Stack main_stack {
- Overlay main_overlay {
- ScrolledWindow scrolled_window {
- vexpand: true;
- Adw.Clamp{
- Box outerbox {
- orientation: vertical;
+ [start]
+ Button cancel_button {
+ label: _("Cancel");
+ }
- ListBox install_type_list {
- margin-top: 12;
- margin-bottom: 12;
- margin-start: 12;
- margin-end: 12;
- hexpand: true;
- valign: start;
- selection-mode: none;
- styles["boxed-list"]
-
- Adw.ActionRow apps_row {
- title: _("Show Apps");
+ [end]
+ Button apply_button {
+ label: _("Apply");
- Switch apps_switch {
- valign: center;
- }
-
- activatable-widget: apps_switch;
- }
- Adw.ActionRow runtimes_row {
- title: _("Show Runtimes");
-
- Switch runtimes_switch {
- valign: center;
- }
-
- activatable-widget: runtimes_switch;
- }
- Adw.ExpanderRow remotes_expander {
- enable-expansion: false;
- title: _("Filter Apps by Remotes");
- }
- Adw.ExpanderRow runtimes_expander {
- enable-expansion: false;
- title: _("Filter Apps by Runtime");
- }
- }
- // Button remove_filters_button {
- // visible: false;
- // margin-bottom: 18;
- // halign: center;
- // label: _("Clear Filters");
- // styles ["pill"]
- // }
- }
- }
- }
- }
- }
- };
+ styles [
+ "suggested-action"
+ ]
+ }
}
-}
\ No newline at end of file
+
+ content: Adw.ToastOverlay toast_overlay {
+ Stack main_stack {
+ Overlay main_overlay {
+ ScrolledWindow scrolled_window {
+ vexpand: true;
+
+ Adw.Clamp {
+ Box outerbox {
+ orientation: vertical;
+
+ ListBox install_type_list {
+ margin-top: 12;
+ margin-bottom: 12;
+ margin-start: 12;
+ margin-end: 12;
+ hexpand: true;
+ valign: start;
+ selection-mode: none;
+
+ styles [
+ "boxed-list"
+ ]
+
+ Adw.ActionRow apps_row {
+ title: _("Show Apps");
+
+ Switch apps_switch {
+ valign: center;
+ }
+
+ activatable-widget: apps_switch;
+ }
+
+ Adw.ActionRow runtimes_row {
+ title: _("Show Runtimes");
+
+ Switch runtimes_switch {
+ valign: center;
+ }
+
+ activatable-widget: runtimes_switch;
+ }
+
+ Adw.ExpanderRow remotes_expander {
+ enable-expansion: false;
+ title: _("Filter Apps by Remotes");
+ }
+
+ Adw.ExpanderRow runtimes_expander {
+ enable-expansion: false;
+ title: _("Filter Apps by Runtime");
+ }
+ }
+
+ // Button remove_filters_button {
+ // visible: false;
+ // margin-bottom: 18;
+ // halign: center;
+ // label: _("Clear Filters");
+ // styles ["pill"]
+ // }
+ }
+ }
+ }
+ }
+ }
+ };
+ }
+}
diff --git a/src/filter_window.py b/src/filter_window.py
index f82201a..74da607 100644
--- a/src/filter_window.py
+++ b/src/filter_window.py
@@ -88,39 +88,42 @@ class FilterWindow(Adw.Window):
self.remotes_expander_switch = Gtk.Switch(valign=Gtk.Align.CENTER)
self.runtimes_expander_switch = Gtk.Switch(valign=Gtk.Align.CENTER)
- dependant_runtimes = self.my_utils.getDependantRuntimes()
+ dependent_runtimes = self.my_utils.getDependentRuntimes()
if len(self.host_remotes) < 2: # Don't give the ability to filter by remotes if there is only 1
self.remotes_expander.set_visible(False)
- if len(dependant_runtimes) < 2: # Don't give the ability to filter by runtimes if there is only 1
+ if len(dependent_runtimes) < 2: # Don't give the ability to filter by runtimes if there is only 1
self.runtimes_expander.set_visible(False)
self.remote_checkboxes = []
for i in range(len(self.host_remotes)):
- name = self.host_remotes[i][0]
- title = self.host_remotes[i][1]
- install_type = self.host_remotes[i][7]
- url = self.host_remotes[i][2]
- remote_row = Adw.ActionRow(title=title, subtitle=url)
- if title == "-":
- remote_row.set_title(name)
- self.remotes_expander.add_row(remote_row)
- label = Gtk.Label(label=("{} wide").format(install_type))
- label.add_css_class("subtitle")
- remote_check = Gtk.CheckButton()
- remote_row.add_suffix(label)
- remote_row.add_suffix(remote_check)
- remote_row.set_activatable_widget(remote_check)
- remote_check.connect("toggled", self.remoteCheckHandler, install_type, name)
- self.remote_checkboxes.append(remote_check)
- remote_check.set_active(True)
+ try:
+ name = self.host_remotes[i][0]
+ title = self.host_remotes[i][1]
+ install_type = self.host_remotes[i][7]
+ url = self.host_remotes[i][2]
+ remote_row = Adw.ActionRow(title=title, subtitle=url)
+ if title == "-":
+ remote_row.set_title(name)
+ self.remotes_expander.add_row(remote_row)
+ label = Gtk.Label(label=("{} wide").format(install_type))
+ label.add_css_class("subtitle")
+ remote_check = Gtk.CheckButton()
+ remote_row.add_suffix(label)
+ remote_row.add_suffix(remote_check)
+ remote_row.set_activatable_widget(remote_check)
+ remote_check.connect("toggled", self.remoteCheckHandler, install_type, name)
+ self.remote_checkboxes.append(remote_check)
+ remote_check.set_active(True)
+ except:
+ print("Could not make remote row")
self.remotes_expander_switch.connect("state-set", self.remotesEnableHandler)
self.remotes_expander.add_suffix(self.remotes_expander_switch)
self.runtime_checkboxes = []
- for i in range(len(dependant_runtimes)):
- current = dependant_runtimes[i]
+ for i in range(len(dependent_runtimes)):
+ current = dependent_runtimes[i]
runtime_row = Adw.ActionRow(title=current)
runtime_check = Gtk.CheckButton()
runtime_check.connect("toggled", self.runtimeCheckHandler, current)
diff --git a/src/flatpak-symbolic.svg b/src/flatpak-symbolic.svg
new file mode 100644
index 0000000..0c0fa45
--- /dev/null
+++ b/src/flatpak-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/main.py b/src/main.py
index 68680f7..cae4fe6 100644
--- a/src/main.py
+++ b/src/main.py
@@ -30,10 +30,14 @@ from .window import WarehouseWindow
from .remotes_window import RemotesWindow
from .orphans_window import OrphansWindow
from .search_install_window import SearchInstallWindow
+from .const import Config
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",
@@ -54,6 +58,13 @@ class WarehouseApplication(Adw.Application):
self.create_action("open-menu", self.main_menu_shortcut, ["F10"])
self.create_action("open-search-install", self.open_search_install, ["i"])
+ 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 open_search_install(self, widget, _):
SearchInstallWindow(self.props.active_window).present()
@@ -117,11 +128,13 @@ class WarehouseApplication(Adw.Application):
application_name="Warehouse",
application_icon="io.github.flattool.Warehouse",
developer_name="Heliguy",
- version="1.3.1.beta",
+ version=self.version, # TODO: make this version number automatically loaded from meson
developers=["Heliguy https://github.com/heliguy4599", "kramo https://kramo.hu"],
artists=["Heliguy https://github.com/heliguy4599", "kramo https://kramo.hu", "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,
+ 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')
diff --git a/src/meson.build b/src/meson.build
index bef7d6e..cb76511 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -31,7 +31,15 @@ python = import('python')
conf = configuration_data()
conf.set('PYTHON', python.find_installation('python3').full_path())
-conf.set('VERSION', meson.project_version())
+conf.set('APPID', 'io.github.flattool.Warehouse') # TODO: dynamic version and appID
+if get_option('profile') == 'development'
+ vcs_tag = run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip()
+ conf.set('DEVEL', 'Development')
+ conf.set('VERSION', meson.project_version() + '.dev-' + vcs_tag)
+else
+ conf.set('DEVEL', 'Default')
+ conf.set('VERSION', meson.project_version())
+endif
conf.set('localedir', join_paths(get_option('prefix'), get_option('localedir')))
conf.set('pkgdatadir', pkgdatadir)
@@ -68,4 +76,13 @@ warehouse_sources = [
'properties.blp',
]
+configure_file(
+ input: 'const.py.in',
+ output: 'const.py',
+ configuration: conf,
+ install: true,
+ install_dir: moduledir,
+ install_mode: 'r-xr--r--',
+)
+
install_data(warehouse_sources, install_dir: moduledir)
diff --git a/src/orphans.blp b/src/orphans.blp
index 7bb7dab..483ba9d 100644
--- a/src/orphans.blp
+++ b/src/orphans.blp
@@ -1,103 +1,134 @@
using Gtk 4.0;
using Adw 1;
-template OrphansWindow : Adw.Window {
- default-width: 500;
- default-height: 450;
+template $OrphansWindow: Adw.Window {
+ default-width: 500;
+ default-height: 450;
- Adw.ToolbarView main_toolbar_view {
- [top]
- HeaderBar header_bar {
- [start]
- ToggleButton search_button {
- icon-name: "system-search-symbolic";
- tooltip-text: _("Search List");
- }
- [end]
- Button oepn_folder_button {
- icon-name: "document-open-symbolic";
- tooltip-text: _("Open Data Folder");
- }
- }
- [top]
- SearchBar search_bar {
- search-mode-enabled: bind-property search_button.active bidirectional;
- key-capture-widget: OrphansWindow;
- Adw.Clamp{
- maximum-size: 577;
- hexpand: true;
- SearchEntry search_entry {}
- }
- }
- content:
- Adw.ToastOverlay toast_overlay {
- Overlay main_overlay {
- Stack main_stack {
- Box main_box {
- orientation: vertical;
- ScrolledWindow scrolled_window {
- vexpand: true;
- Adw.Clamp{
- ListBox list_of_data {
- margin-top: 12;
- margin-bottom: 12;
- margin-start: 12;
- margin-end: 12;
- hexpand: true;
- valign: start;
- selection-mode: none;
- styles["boxed-list"]
- }
- }
- }
- }
- Box installing {
- orientation: vertical;
- spacing: 10;
- margin-top: 40;
- margin-bottom: 20;
- halign: center;
- valign: center;
- Spinner spinner {
- margin-bottom: 35;
- width-request: 30;
- height-request: 30;
- opacity: 0.5;
- spinning: true;
- }
- Label {
- label: _("Installing…");
- styles["title-1", "title"]
- }
- Label {
- label: _("This could take a while.");
- styles["description", "body"]
- }
- }
- Adw.StatusPage no_data {
- icon-name: "check-plain-symbolic";
- title: _("No Leftover Data");
- description: _("There is no leftover user data");
- }
- }
- }
- };
- [bottom]
- ActionBar action_bar {
- [start]
- ToggleButton select_all_button {
- label: _("Select All");
- }
- [end]
- Button trash_button {
- label: _("Trash");
- sensitive: false;
- }
- [end]
- Button install_button {
- label: _("Install");
- sensitive: false;
- }
- }
+ Adw.ToolbarView main_toolbar_view {
+ [top]
+ HeaderBar header_bar {
+ [start]
+ ToggleButton search_button {
+ icon-name: "system-search-symbolic";
+ tooltip-text: _("Search List");
+ }
+
+ [end]
+ Button oepn_folder_button {
+ icon-name: "document-open-symbolic";
+ tooltip-text: _("Open Data Folder");
+ }
}
-}
\ No newline at end of file
+
+ [top]
+ SearchBar search_bar {
+ search-mode-enabled: bind search_button.active bidirectional;
+ key-capture-widget: main_toolbar_view;
+
+ Adw.Clamp {
+ maximum-size: 577;
+ hexpand: true;
+
+ SearchEntry search_entry {}
+ }
+ }
+
+ content: Adw.ToastOverlay toast_overlay {
+ Overlay main_overlay {
+ Stack main_stack {
+ Box main_box {
+ orientation: vertical;
+
+ ScrolledWindow scrolled_window {
+ vexpand: true;
+
+ Adw.Clamp {
+ ListBox list_of_data {
+ margin-top: 12;
+ margin-bottom: 12;
+ margin-start: 12;
+ margin-end: 12;
+ hexpand: true;
+ valign: start;
+ selection-mode: none;
+
+ styles [
+ "boxed-list"
+ ]
+ }
+ }
+ }
+ }
+
+ Box installing {
+ orientation: vertical;
+ spacing: 10;
+ margin-top: 40;
+ margin-bottom: 20;
+ halign: center;
+ valign: center;
+
+ Spinner spinner {
+ margin-bottom: 35;
+ width-request: 30;
+ height-request: 30;
+ opacity: 0.5;
+ spinning: true;
+ }
+
+ Label {
+ label: _("Installing…");
+
+ styles [
+ "title-1",
+ "title"
+ ]
+ }
+
+ Label {
+ label: _("This could take a while.");
+
+ styles [
+ "description",
+ "body"
+ ]
+ }
+ }
+
+ Adw.StatusPage no_data {
+ icon-name: "check-plain-symbolic";
+ title: _("No Leftover Data");
+ description: _("There is no leftover user data");
+ }
+
+ Adw.StatusPage no_results {
+ icon-name: "system-search-symbolic";
+ title: _("No Results Found");
+ description: _("Try a different search term");
+ }
+ }
+ }
+ };
+
+ [bottom]
+ ActionBar action_bar {
+ [start]
+ ToggleButton select_all_button {
+ label: _("Select All");
+ }
+
+ [end]
+ Button trash_button {
+ label: _("Trash");
+ sensitive: false;
+ }
+
+ [end]
+ Button install_button {
+ label: _("Install");
+ sensitive: false;
+ }
+ }
+ }
+}
diff --git a/src/orphans_window.py b/src/orphans_window.py
index 59cc3f8..35b485c 100644
--- a/src/orphans_window.py
+++ b/src/orphans_window.py
@@ -16,6 +16,7 @@ class OrphansWindow(Adw.Window):
toast_overlay = Gtk.Template.Child()
main_stack = Gtk.Template.Child()
no_data = Gtk.Template.Child()
+ no_results = Gtk.Template.Child()
action_bar = Gtk.Template.Child()
search_bar = Gtk.Template.Child()
search_entry = Gtk.Template.Child()
@@ -30,6 +31,7 @@ class OrphansWindow(Adw.Window):
selected_remote = ""
selected_remote_install_type = ""
no_close_id = 0
+ is_result = False
def key_handler(self, _a, event, _c, _d):
if event == Gdk.KEY_Escape:
@@ -188,7 +190,10 @@ class OrphansWindow(Adw.Window):
# This is a list that only holds IDs of install flatpaks
id_list = []
for i in range(len(self.host_flatpaks)):
- id_list.append(self.host_flatpaks[i][2])
+ try:
+ id_list.append(self.host_flatpaks[i][2])
+ except:
+ print("Could not get data")
for i in range(len(dir_list)):
dir_name = dir_list[i]
@@ -229,8 +234,32 @@ class OrphansWindow(Adw.Window):
def filter_func(self, row):
if (self.search_entry.get_text().lower() in row.get_title().lower()):
+ self.is_result = True
return True
+ def on_invalidate(self, row):
+ if self.list_of_data.get_row_at_index(0) == None:
+ self.main_stack.set_visible_child(self.no_data)
+ self.action_bar.set_visible(False)
+ else:
+ self.main_stack.set_visible_child(self.main_box)
+ self.action_bar.set_visible(True)
+
+ self.is_result = False
+ self.list_of_data.invalidate_filter()
+ if self.is_result == False:
+ self.main_stack.set_visible_child(self.no_results)
+ self.action_bar.set_visible(False)
+
+ def on_change(self, prop, prop2):
+ if self.search_bar.get_search_mode() == False:
+ if self.list_of_data.get_row_at_index(0) == None:
+ self.main_stack.set_visible_child(self.no_data)
+ self.action_bar.set_visible(False)
+ else:
+ self.main_stack.set_visible_child(self.main_box)
+ self.action_bar.set_visible(True)
+
def __init__(self, main_window, **kwargs):
super().__init__(**kwargs)
self.my_utils = myUtils(self) # Access common utils and set the window to this window
@@ -258,6 +287,7 @@ class OrphansWindow(Adw.Window):
self.main_overlay.add_overlay(self.progress_bar)
self.list_of_data.set_filter_func(self.filter_func)
- self.search_entry.connect("search-changed", lambda *_: self.list_of_data.invalidate_filter())
+ self.search_entry.connect("search-changed", self.on_invalidate)
+ self.search_bar.connect("notify", self.on_change)
self.search_bar.connect_entry(self.search_entry)
self.oepn_folder_button.connect("clicked", self.open_button_handler)
\ No newline at end of file
diff --git a/src/popular_remotes.blp b/src/popular_remotes.blp
index 9c0ebb1..d0d11e9 100644
--- a/src/popular_remotes.blp
+++ b/src/popular_remotes.blp
@@ -1,49 +1,59 @@
using Gtk 4.0;
using Adw 1;
-template PopularRemotesWindow : Adw.Window {
- default-width: 450;
- default-height: 530;
- title: "";
+template PopularRemotesWindow: Adw.Window {
+ default-width: 450;
+ default-height: 530;
+ title: "";
- Adw.ToolbarView main_toolbar_view {
- [top]
- HeaderBar header_bar {
- }
- content:
- Adw.ToastOverlay toast_overlay {
- vexpand: true;
- Adw.StatusPage {
- valign: start;
- title: _("Add Remote");
- description: _("Choose from a list of popular remotes or add a new one.");
- Adw.Clamp {
- Box {
- orientation: vertical;
- ListBox list_of_remotes {
- hexpand: true;
- valign: start;
- selection-mode: none;
- styles["boxed-list"]
- }
- ListBox custom_list {
- hexpand: true;
- valign: start;
- selection-mode: none;
- styles["boxed-list"]
+ Adw.ToolbarView main_toolbar_view {
+ [top]
+ HeaderBar header_bar {}
- Adw.ActionRow add_from_file {
- title: _("Add a Repo File");
- activatable: true;
- }
- Adw.ActionRow custom_remote {
- title: _("Add a Custom Remote");
- activatable: true;
- }
- }
- }
- }
+ content: Adw.ToastOverlay toast_overlay {
+ vexpand: true;
+
+ Adw.StatusPage {
+ valign: start;
+ title: _("Add Remote");
+ description: _("Choose from a list of popular remotes or add a new one.");
+
+ Adw.Clamp {
+ Box {
+ orientation: vertical;
+
+ ListBox list_of_remotes {
+ hexpand: true;
+ valign: start;
+ selection-mode: none;
+
+ styles [
+ "boxed-list"
+ ]
}
- };
- }
-}
\ No newline at end of file
+
+ ListBox custom_list {
+ hexpand: true;
+ valign: start;
+ selection-mode: none;
+
+ styles [
+ "boxed-list"
+ ]
+
+ Adw.ActionRow add_from_file {
+ title: _("Add a Repo File");
+ activatable: true;
+ }
+
+ Adw.ActionRow custom_remote {
+ title: _("Add a Custom Remote");
+ activatable: true;
+ }
+ }
+ }
+ }
+ }
+ };
+ }
+}
diff --git a/src/properties.blp b/src/properties.blp
index 4946094..896907a 100644
--- a/src/properties.blp
+++ b/src/properties.blp
@@ -1,103 +1,129 @@
using Gtk 4.0;
using Adw 1;
-template PropertiesWindow : Adw.Window {
- default-width: 350;
- default-height: 600;
- modal: true;
+template PropertiesWindow: Adw.Window {
+ default-width: 350;
+ default-height: 600;
+ modal: true;
- Adw.ToolbarView main_toolbar_view {
- [top]
- HeaderBar header_bar {
- }
- content:
- Adw.ToastOverlay toast_overlay {
+ Adw.ToolbarView main_toolbar_view {
+ [top]
+ HeaderBar header_bar {}
+
+ content: Adw.ToastOverlay toast_overlay {
+ Box {
+ orientation: vertical;
+
+ Adw.Banner eol_app_banner {}
+
+ Adw.Banner eol_runtime_banner {}
+
+ Adw.Banner mask_banner {}
+
+ ScrolledWindow {
+ Adw.Clamp {
Box {
- orientation: vertical;
- Adw.Banner eol_app_banner {
+ orientation: vertical;
+ hexpand: false;
+ vexpand: true;
+ spacing: 12;
+ margin-top: 12;
+ margin-start: 12;
+ margin-end: 12;
+ margin-bottom: 12;
+
+ Image app_icon {
+ pixel-size: 100;
+
+ styles [
+ "icon-dropshadow"
+ ]
+ }
+
+ Adw.PreferencesGroup upper {
+ Adw.ActionRow data_row {
+ title: _("Loading User Data…");
+
+ [suffix]
+ Button open_data {
+ icon-name: "document-open-symbolic";
+ tooltip-text: _("Open User Data Folder");
+ valign: center;
+ visible: false;
+
+ styles [
+ "flat"
+ ]
+ }
+
+ [suffix]
+ Button trash_data {
+ icon-name: "user-trash-symbolic";
+ tooltip-text: _("Trash User Data");
+ valign: center;
+ visible: false;
+
+ styles [
+ "flat"
+ ]
+ }
+
+ [suffix]
+ Spinner spinner {
+ spinning: true;
+ }
}
- Adw.Banner eol_runtime_banner {
+
+ Adw.ActionRow view_apps {
+ title: _("Show Apps Using this Runtime");
+ activatable: true;
+
+ [suffix]
+ Image {
+ icon-name: "funnel-symbolic";
+ }
}
- Adw.Banner mask_banner {
+
+ Adw.ActionRow runtime {
+ title: _("Runtime");
+
+ [suffix]
+ Button runtime_properties {
+ icon-name: "info-symbolic";
+ valign: center;
+
+ styles [
+ "flat"
+ ]
+ }
+
+ [suffix]
+ Button runtime_copy {
+ icon-name: "edit-copy-symbolic";
+ valign: center;
+
+ styles [
+ "flat"
+ ]
+ }
}
- ScrolledWindow {
- Adw.Clamp {
- Box {
- orientation: vertical;
- hexpand: false;
- vexpand: true;
- spacing: 12;
- margin-top: 12;
- margin-start: 12;
- margin-end: 12;
- margin-bottom: 12;
- Image app_icon {
- pixel-size: 100;
- styles["icon-dropshadow"]
- }
- Adw.PreferencesGroup upper {
- Adw.ActionRow data_row {
- title: _("Loading User Data…");
- [suffix]
- Button open_data {
- icon-name: "document-open-symbolic";
- tooltip-text: _("Open User Data Folder");
- valign: center;
- visible: false;
- styles["flat"]
- }
- [suffix]
- Button trash_data {
- icon-name: "brush-symbolic";
- tooltip-text: _("Trash User Data");
- valign: center;
- visible: false;
- styles["flat"]
- }
- [suffix]
- Spinner spinner {
- spinning: true;
- }
- }
- Adw.ActionRow view_apps {
- title: _("Show Apps Using this Runtime");
- activatable: true;
- [suffix]
- Image {
- icon-name: "funnel-symbolic";
- }
- }
- Adw.ActionRow runtime {
- title: _("Runtime");
- [suffix]
- Button runtime_properties {
- icon-name: "info-symbolic";
- valign: center;
- styles["flat"]
- }
- [suffix]
- Button runtime_copy {
- icon-name: "edit-copy-symbolic";
- valign: center;
- styles["flat"]
- }
- }
- Adw.ActionRow details {
- title: _("Show Details in Store");
- activatable: true;
- [suffix]
- Image {
- icon-name: "arrow2-top-right-symbolic";
- }
- }
- }
- Adw.PreferencesGroup lower {
-
- }
- }
- }
+
+ Adw.ActionRow details {
+ title: _("Show Details in Store");
+ activatable: true;
+
+ [suffix]
+ Image {
+ icon-name: "arrow2-top-right-symbolic";
+ }
}
+ }
+
+ Adw.PreferencesGroup lower {}
}
- };
- }
-}
\ No newline at end of file
+ }
+ }
+ }
+ };
+ }
+}
diff --git a/src/remotes.blp b/src/remotes.blp
index b97837c..575c40c 100644
--- a/src/remotes.blp
+++ b/src/remotes.blp
@@ -1,53 +1,62 @@
using Gtk 4.0;
using Adw 1;
-template RemotesWindow : Adw.Window {
- default-width: 500;
- default-height: 450;
+template RemotesWindow: Adw.Window {
+ default-width: 500;
+ default-height: 450;
- Adw.ToolbarView main_toolbar_view {
- [top]
- HeaderBar header_bar {
- Button add_button {
- Adw.ButtonContent {
- label: _("Add Remote");
- icon-name: "plus-large-symbolic";
- }
- }
+ Adw.ToolbarView main_toolbar_view {
+ [top]
+ HeaderBar header_bar {
+ Button add_button {
+ Adw.ButtonContent {
+ label: _("Add Remote");
+ icon-name: "plus-large-symbolic";
}
- content:
- Adw.ToastOverlay toast_overlay {
- Stack stack {
- Overlay main_overlay {
- [overlay]
- ProgressBar progress_bar {
- visible: false;
- pulse-step: 0.7;
- can-target: false;
- styles ["osd"]
- }
- ScrolledWindow scroll {
- vexpand: true;
- Adw.Clamp{
- ListBox remotes_list {
- margin-top: 12;
- margin-bottom: 12;
- margin-start: 12;
- margin-end: 12;
- hexpand: true;
- valign: start;
- selection-mode: none;
- styles["boxed-list"]
- }
- }
- }
- }
- Adw.StatusPage no_remotes {
- icon-name: "error-symbolic";
- title: _("No Remotes");
- description: _("Warehouse cannot see the list of remotes or the system has no remotes added");
- }
- }
- };
+ }
}
-}
\ No newline at end of file
+
+ content: Adw.ToastOverlay toast_overlay {
+ Stack stack {
+ Overlay main_overlay {
+ [overlay]
+ ProgressBar progress_bar {
+ visible: false;
+ pulse-step: 0.7;
+ can-target: false;
+
+ styles [
+ "osd"
+ ]
+ }
+
+ ScrolledWindow scroll {
+ vexpand: true;
+
+ Adw.Clamp {
+ ListBox remotes_list {
+ margin-top: 12;
+ margin-bottom: 12;
+ margin-start: 12;
+ margin-end: 12;
+ hexpand: true;
+ valign: start;
+ selection-mode: none;
+
+ styles [
+ "boxed-list"
+ ]
+ }
+ }
+ }
+ }
+
+ Adw.StatusPage no_remotes {
+ icon-name: "error-symbolic";
+ title: _("No Remotes");
+ description: _("Warehouse cannot see the list of remotes or the system has no remotes added");
+ }
+ }
+ };
+ }
+}
diff --git a/src/remotes_window.py b/src/remotes_window.py
index c9adea3..7bb4317 100644
--- a/src/remotes_window.py
+++ b/src/remotes_window.py
@@ -78,25 +78,28 @@ class RemotesWindow(Adw.Window):
self.stack.set_visible_child(self.main_overlay)
for i in range(len(self.host_remotes)):
- name = self.host_remotes[i][0]
- title = self.host_remotes[i][1]
- install_type = self.host_remotes[i][7]
- url = self.host_remotes[i][2]
- remote_row = Adw.ActionRow(title=title, subtitle=name)
- if title == "-":
- remote_row.set_title(name)
- self.remotes_list.append(remote_row)
- label = Gtk.Label(label=("{} wide").format(install_type), valign=Gtk.Align.CENTER)
- label.add_css_class("subtitle")
- remote_row.add_suffix(label)
- copy_button = Gtk.Button(icon_name="edit-copy-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("Copy remote name"))
- copy_button.add_css_class("flat")
- copy_button.connect("clicked", rowCopyHandler, name)
- remove_button = Gtk.Button(icon_name="user-trash-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("Remove {}").format(name))
- remove_button.add_css_class("flat")
- remove_button.connect("clicked", self.remove_handler, i)
- remote_row.add_suffix(copy_button)
- remote_row.add_suffix(remove_button)
+ try:
+ name = self.host_remotes[i][0]
+ title = self.host_remotes[i][1]
+ install_type = self.host_remotes[i][7]
+ url = self.host_remotes[i][2]
+ remote_row = Adw.ActionRow(title=title, subtitle=name)
+ if title == "-":
+ remote_row.set_title(name)
+ self.remotes_list.append(remote_row)
+ label = Gtk.Label(label=("{} wide").format(install_type), valign=Gtk.Align.CENTER)
+ label.add_css_class("subtitle")
+ remote_row.add_suffix(label)
+ copy_button = Gtk.Button(icon_name="edit-copy-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("Copy remote name"))
+ copy_button.add_css_class("flat")
+ copy_button.connect("clicked", rowCopyHandler, name)
+ remove_button = Gtk.Button(icon_name="user-trash-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("Remove {}").format(name))
+ remove_button.add_css_class("flat")
+ remove_button.connect("clicked", self.remove_handler, i)
+ remote_row.add_suffix(copy_button)
+ remote_row.add_suffix(remove_button)
+ except:
+ print("Could not get remote")
def addRemoteCallback(self, _a, _b):
self.should_pulse = False
diff --git a/src/search_install.blp b/src/search_install.blp
index 1780cfc..23d2bbf 100644
--- a/src/search_install.blp
+++ b/src/search_install.blp
@@ -1,80 +1,125 @@
using Gtk 4.0;
using Adw 1;
-template SearchInstallWindow : Adw.Window {
- default-width: 500;
- default-height: 450;
- title: _("Install From Online");
- modal: true;
+template $SearchInstallWindow: Adw.Window {
+ default-width: 500;
+ default-height: 450;
+ title: _("Install From The Web…");
+ modal: true;
- Adw.ToolbarView main_toolbar_view {
- [top]
- HeaderBar header_bar {
- show-title-buttons: false;
- [start]
- Button cancel_button {
- label: _("Cancel");
- }
- [end]
- Button install_button {
- label: _("Install");
- styles["suggested-action"]
- }
- }
- [top]
- Adw.Clamp {
- Box {
- margin-top: 6;
- margin-start: 6;
- margin-end: 6;
- styles["linked"]
- [start]
- SearchEntry search_entry {
- hexpand: true;
- placeholder-text: _("Search for Flatpaks, press Enter to search.");
- }
- [start]
- MenuButton remotes_dropdown {
- label: _("All Remotes");
- }
- }
- }
- content:
- Adw.ToastOverlay toast_overlay {
- Stack main_stack {
- Overlay main_overlay {
- [overlay]
- ProgressBar progress_bar {
- pulse-step: 0.7;
- can-target: false;
- styles["osd"]
- }
- ScrolledWindow {
- Adw.Clamp {
- ListBox results_list_box {
- margin-top: 12;
- margin-bottom: 12;
- margin-start: 12;
- margin-end: 12;
- hexpand: true;
- valign: start;
- selection-mode: none;
- styles["boxed-list"]
- }
- }
- }
- }
- Adw.StatusPage no_results {
- icon-name: "error-symbolic";
- title: _("No matches found");
- description: _("Try a different search term");
- }
- Adw.StatusPage too_many {
- icon-name: "error-symbolic";
- title: _("Too many results");
- description: _("Try being more specific with your search");
- }
- }
- };
+ Adw.ToolbarView main_toolbar_view {
+ [top]
+ HeaderBar header_bar {
+ show-title-buttons: false;
+
+ [start]
+ Button cancel_button {
+ label: _("Cancel");
+ }
+
+ [end]
+ Button install_button {
+ label: _("Install");
+
+ styles [
+ "suggested-action"
+ ]
+ }
}
-}
\ No newline at end of file
+
+ [top]
+ Adw.Clamp {
+ Box {
+ margin-top: 6;
+ margin-start: 6;
+ margin-end: 6;
+
+ styles [
+ "linked"
+ ]
+
+ [start]
+ SearchEntry search_entry {
+ hexpand: true;
+ placeholder-text: _("Search for Flatpaks…");
+ }
+
+ [start]
+ MenuButton remotes_dropdown {
+ label: _("All Remotes");
+ }
+
+ [start]
+ Button search_button {
+ tooltip-text: _("Search");
+ icon-name: "system-search-symbolic";
+ }
+ }
+ }
+
+ content: Adw.ToastOverlay toast_overlay {
+ Stack main_stack {
+ Overlay main_overlay {
+ [overlay]
+ ProgressBar progress_bar {
+ pulse-step: 0.7;
+ can-target: false;
+
+ styles [
+ "osd"
+ ]
+ }
+
+ ScrolledWindow {
+ Adw.Clamp {
+ ListBox results_list_box {
+ margin-top: 12;
+ margin-bottom: 12;
+ margin-start: 12;
+ margin-end: 12;
+ hexpand: true;
+ valign: start;
+ selection-mode: none;
+
+ styles [
+ "boxed-list"
+ ]
+ }
+ }
+ }
+ }
+
+ Adw.StatusPage no_results {
+ icon-name: "system-search-symbolic";
+ title: _("No Results Found");
+ description: _("Try a different search term");
+ }
+
+ Adw.StatusPage blank_page {
+ title: _("Search for Flatpaks");
+ icon-name: "flatpak-symbolic";
+ description: _("Search for Flatpaks that you want to install");
+ }
+
+ Adw.StatusPage loading_page {
+ title: C_("Shown with a spinner while search operation is pending", "Searching…");
+
+ Spinner {
+ spinning: true;
+ height-request: 32;
+ width-request: 32;
+ margin-top: 0;
+ halign: center;
+ valign: center;
+ }
+ }
+
+ Adw.StatusPage too_many {
+ icon-name: "error-symbolic";
+ title: _("Too many results");
+ description: _("Try being more specific with your search");
+ }
+ }
+ };
+ }
+}
diff --git a/src/search_install_window.py b/src/search_install_window.py
index 15ea8d6..1f78659 100644
--- a/src/search_install_window.py
+++ b/src/search_install_window.py
@@ -5,7 +5,7 @@ import os
import pathlib
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/search_install.ui")
-class SearchInstallWindow (Adw.Window):
+class SearchInstallWindow (Adw.Window): # TODO: stop execution of thread when search is changed
__gtype_name__ = "SearchInstallWindow"
results_list_box = Gtk.Template.Child()
@@ -14,14 +14,18 @@ class SearchInstallWindow (Adw.Window):
no_results = Gtk.Template.Child()
too_many = Gtk.Template.Child()
cancel_button = Gtk.Template.Child()
- # search_bar = Gtk.Template.Child()
+ blank_page = Gtk.Template.Child()
+ loading_page = Gtk.Template.Child()
+ search_button = Gtk.Template.Child()
search_entry = Gtk.Template.Child()
remotes_dropdown = Gtk.Template.Child()
+ is_debug = GLib.environ_getenv(GLib.get_environ(), "G_MESSAGES_DEBUG") == "all"
+
def searchResponse(self, a, b):
self.results_list_box.remove_all()
print(self.search_results)
- if len(self.search_results) == 1 and len(self.search_results[0]) == 1:
+ if (self.is_debug and len(self.search_results) == 5) or (len(self.search_results) == 1 and len(self.search_results[0]) == 1): #This is unreliable with G_DEBUG
self.main_stack.set_visible_child(self.no_results)
return
if len(self.search_results) > 50:
@@ -29,15 +33,20 @@ class SearchInstallWindow (Adw.Window):
return
self.main_stack.set_visible_child(self.main_overlay)
for i in range(len(self.search_results)):
- row = Adw.ActionRow(title=GLib.markup_escape_text(self.search_results[i][0]), subtitle=self.search_results[i][2])
- check = Gtk.CheckButton()
- check.add_css_class("selection-mode")
- check.connect("toggled", self.on_check)
- label = Gtk.Label(label=self.search_results[i][3], justify=Gtk.Justification.RIGHT, wrap=True, hexpand=True)
- row.add_suffix(label)
- row.add_suffix(check)
- row.set_activatable_widget(check)
- self.results_list_box.append(row)
+ try:
+ print("creating row {}".format(str(i)))
+ row = Adw.ActionRow(title=GLib.markup_escape_text(self.search_results[i][0]), subtitle=self.search_results[i][2])
+ print("row {} is {}".format(str(i), self.search_results[i][0]))
+ check = Gtk.CheckButton()
+ check.add_css_class("selection-mode")
+ check.connect("toggled", self.on_check)
+ label = Gtk.Label(label=self.search_results[i][3], justify=Gtk.Justification.RIGHT, wrap=True, hexpand=True)
+ row.add_suffix(label)
+ row.add_suffix(check)
+ row.set_activatable_widget(check)
+ self.results_list_box.append(row)
+ except:
+ print("Could not create row")
def on_check(self, button):
print(button.get_active())
@@ -58,10 +67,11 @@ class SearchInstallWindow (Adw.Window):
self.search_results = data
def onSearch(self, widget):
- self.to_search = widget.get_text()
+ self.main_stack.set_visible_child(self.loading_page)
+ self.to_search = self.search_entry.get_text()
if len(self.to_search) < 1 or " " in self.to_search:
self.results_list_box.remove_all()
- self.main_stack.set_visible_child(self.no_results)
+ self.main_stack.set_visible_child(self.blank_page)
return
task = Gio.Task.new(None, None, self.searchResponse)
task.run_in_thread(lambda *_: self.searchThread())
@@ -72,10 +82,10 @@ class SearchInstallWindow (Adw.Window):
def remotesChooserCreator(self):
remotes_pop = Gtk.Popover()
remotes_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
- remotes_pop.set_size_request(400, 1)
- scroll = Gtk.ScrolledWindow()
- remotes_pop.set_child(scroll)
- scroll.set_child(remotes_box)
+ # remotes_pop.set_size_request(400, 1) # why?
+ remotes_pop.set_child(remotes_box) # don't use ScrolledWindows in popovers!
+
+ # why not just comment this code out and leave it unimplemented— it does nothing of use
for i in range(1, 3):
x = 0
height = remotes_pop.get_size(x)
@@ -109,6 +119,7 @@ class SearchInstallWindow (Adw.Window):
self.set_transient_for(parent_window)
# self.search_bar.connect_entry(self.search_entry)
self.search_entry.connect("activate", self.onSearch)
+ self.search_button.connect("clicked", self.onSearch)
self.search_entry.connect("changed", lambda *_: self.search_entry.grab_focus())
# self.search_entry.set_key_capture_widget(self.results_list_box)
self.search_entry.grab_focus()
@@ -118,6 +129,7 @@ class SearchInstallWindow (Adw.Window):
self.remotesChooserCreator()
self.remote_to_search = []
+ self.main_stack.set_visible_child(self.blank_page)
diff --git a/src/snapshots.blp b/src/snapshots.blp
index 6451c52..b02609c 100644
--- a/src/snapshots.blp
+++ b/src/snapshots.blp
@@ -1,64 +1,77 @@
using Gtk 4.0;
using Adw 1;
-template SnapshotsWindow : Adw.Window {
- default-width: 500;
- default-height: 455;
- modal: true;
+template SnapshotsWindow: Adw.Window {
+ default-width: 500;
+ default-height: 455;
+ modal: true;
- Adw.ToolbarView main_toolbar_view {
- [top]
- HeaderBar header_bar {
- [start]
- Button new_snapshot {
- Adw.ButtonContent {
- label: _("New Snapshot");
- icon-name: "plus-large-symbolic";
- }
- }
- [end]
- Button oepn_folder_button {
- icon-name: "document-open-symbolic";
- tooltip-text: _("Open Snapshots Folder");
- }
+ Adw.ToolbarView main_toolbar_view {
+ [top]
+ HeaderBar header_bar {
+ [start]
+ Button new_snapshot {
+ Adw.ButtonContent {
+ label: _("New Snapshot");
+ icon-name: "plus-large-symbolic";
}
- content:
- Adw.ToastOverlay toast_overlay {
- Overlay main_overlay {
- [overlay]
- ProgressBar progress_bar {
- pulse-step: 0.7;
- can-target: false;
- visible: false;
- styles["osd"]
- }
- Stack main_stack {
- ScrolledWindow outerbox {
- Adw.Clamp {
- ListBox snapshots_group {
- margin-top: 12;
- margin-bottom: 12;
- margin-start: 12;
- margin-end: 12;
- valign: start;
- selection-mode: none;
- styles["boxed-list"]
- }
- }
- }
- Adw.StatusPage no_snapshots {
- title: _("No Snapshots");
- description: _("Snapshots are backups of the app's user data. They can be reapplied at any time.");
- icon-name: "clock-alt-symbolic";
+ }
- Button new_snapshot_pill {
- label: _("New Snapshot");
- halign: center;
- styles["pill", "suggested-action"]
- }
- }
- }
- }
- };
+ [end]
+ Button oepn_folder_button {
+ icon-name: "document-open-symbolic";
+ tooltip-text: _("Open Snapshots Folder");
+ }
}
-}
\ No newline at end of file
+
+ content: Adw.ToastOverlay toast_overlay {
+ Overlay main_overlay {
+ [overlay]
+ ProgressBar progress_bar {
+ pulse-step: 0.7;
+ can-target: false;
+ visible: false;
+
+ styles [
+ "osd"
+ ]
+ }
+
+ Stack main_stack {
+ ScrolledWindow outerbox {
+ Adw.Clamp {
+ ListBox snapshots_group {
+ margin-top: 12;
+ margin-bottom: 12;
+ margin-start: 12;
+ margin-end: 12;
+ valign: start;
+ selection-mode: none;
+
+ styles [
+ "boxed-list"
+ ]
+ }
+ }
+ }
+
+ Adw.StatusPage no_snapshots {
+ title: _("No Snapshots");
+ description: _("Snapshots are backups of the app's user data. They can be reapplied at any time.");
+ icon-name: "clock-alt-symbolic";
+
+ Button new_snapshot_pill {
+ label: _("New Snapshot");
+ halign: center;
+
+ styles [
+ "pill",
+ "suggested-action"
+ ]
+ }
+ }
+ }
+ }
+ };
+ }
+}
diff --git a/src/user-trash-symbolic.svg b/src/user-trash-symbolic.svg
new file mode 100644
index 0000000..b6f8bd1
--- /dev/null
+++ b/src/user-trash-symbolic.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/src/warehouse.gresource.xml b/src/warehouse.gresource.xml
index 0f1b0e9..02c2dc7 100644
--- a/src/warehouse.gresource.xml
+++ b/src/warehouse.gresource.xml
@@ -17,13 +17,14 @@
selection-mode-symbolic.svg
error-symbolic.svg
- brush-symbolic.svg
+ user-trash-symbolic.svg
folder-visiting-symbolic.svg
info-symbolic.svg
check-plain-symbolic.svg
paper-filled-symbolic.svg
plus-large-symbolic.svg
funnel-symbolic.svg
+ flatpak-symbolic.svg
right-large-symbolic.svg
view-more-symbolic.svg
clock-alt-symbolic.svg
diff --git a/src/window.blp b/src/window.blp
index c358326..c2aa0cb 100644
--- a/src/window.blp
+++ b/src/window.blp
@@ -1,8 +1,7 @@
using Gtk 4.0;
using Adw 1;
-template WarehouseWindow : Adw.ApplicationWindow {
- styles["devel"]
+template $WarehouseWindow: Adw.ApplicationWindow {
Adw.ToolbarView main_toolbar_view {
[top]
HeaderBar header_bar {
@@ -11,7 +10,7 @@ template WarehouseWindow : Adw.ApplicationWindow {
icon-name: "view-refresh-symbolic";
tooltip-text: _("Refresh List");
}
-
+
[start]
ToggleButton search_button {
icon-name: "system-search-symbolic";
@@ -30,32 +29,37 @@ template WarehouseWindow : Adw.ApplicationWindow {
tooltip-text: _("Main Menu");
menu-model: primary_menu;
}
-
+
[end]
ToggleButton batch_mode_button {
icon-name: "selection-mode-symbolic";
tooltip-text: _("Toggle Selection Mode");
}
}
+
[top]
SearchBar search_bar {
- search-mode-enabled: bind-property search_button.active bidirectional;
- key-capture-widget: WarehouseWindow;
- Adw.Clamp{
+ search-mode-enabled: bind search_button.active bidirectional;
+ key-capture-widget: main_toolbar_view;
+
+ Adw.Clamp {
maximum-size: 577;
hexpand: true;
+
SearchEntry search_entry {}
}
}
- content:
- Adw.ToastOverlay toast_overlay {
+
+ content: Adw.ToastOverlay toast_overlay {
Overlay main_overlay {
Stack main_stack {
Box main_box {
orientation: vertical;
+
ScrolledWindow scrolled_window {
vexpand: true;
- Adw.Clamp{
+
+ Adw.Clamp {
ListBox flatpaks_list_box {
margin-top: 12;
margin-bottom: 12;
@@ -64,11 +68,15 @@ template WarehouseWindow : Adw.ApplicationWindow {
hexpand: true;
valign: start;
selection-mode: none;
- styles["boxed-list"]
+
+ styles [
+ "boxed-list"
+ ]
}
}
}
}
+
Box installing {
orientation: vertical;
spacing: 10;
@@ -76,22 +84,34 @@ template WarehouseWindow : Adw.ApplicationWindow {
margin-bottom: 20;
halign: center;
valign: center;
+
Spinner {
margin-bottom: 35;
- width-request: 30;
+ width-request: 30;
height-request: 30;
opacity: 0.5;
spinning: true;
}
+
Label {
label: _("Installing…");
- styles["title-1", "title"]
+
+ styles [
+ "title-1",
+ "title"
+ ]
}
+
Label {
label: _("This could take a while.");
- styles["description", "body"]
+
+ styles [
+ "description",
+ "body"
+ ]
}
}
+
Box uninstalling {
orientation: vertical;
spacing: 10;
@@ -99,53 +119,77 @@ template WarehouseWindow : Adw.ApplicationWindow {
margin-bottom: 20;
halign: center;
valign: center;
+
Spinner {
margin-bottom: 35;
- width-request: 30;
+ width-request: 30;
height-request: 30;
opacity: 0.5;
spinning: true;
}
+
Label {
label: _("Uninstalling…");
- styles["title-1", "title"]
+
+ styles [
+ "title-1",
+ "title"
+ ]
}
+
Label {
label: _("This could take a while.");
- styles["description", "body"]
+
+ styles [
+ "description",
+ "body"
+ ]
}
}
+
Adw.StatusPage no_flatpaks {
icon-name: "error-symbolic";
title: _("No Flatpaks Found");
description: _("There are either no Flatpaks that match the current filter, Warehouse cannot see the list of installed Flatpaks, or the system has no Flatpaks installed.");
}
+
+ Adw.StatusPage no_results {
+ icon-name: "system-search-symbolic";
+ title: _("No Results Found");
+ description: _("Try a different search term");
+ }
}
}
};
+
[bottom]
ActionBar batch_mode_bar {
revealed: false;
+
[start]
ToggleButton batch_select_all_button {
label: _("Select All");
}
+
[end]
Button batch_uninstall_button {
icon-name: "user-trash-symbolic";
tooltip-text: _("Uninstall Selected Apps");
}
+
[end]
Button batch_clean_button {
icon-name: "brush-symbolic";
tooltip-text: _("Send Selected Apps' Data to the Trash");
}
+
[end]
MenuButton batch_copy_button {
icon-name: "edit-copy-symbolic";
tooltip-text: _("Open Copy Menu");
menu-model: copy_menu;
}
+
[end]
Button batch_snapshot_button {
icon-name: "clock-alt-symbolic";
@@ -158,14 +202,13 @@ template WarehouseWindow : Adw.ApplicationWindow {
menu primary_menu {
section {
-
item {
- label: _("Install From File");
+ label: _("Install From File…");
action: "app.install-from-file";
}
item {
- label: _("Manage Leftover Data");
+ label: _("Manage Leftover Data…");
action: "app.manage-data-folders";
}
@@ -173,14 +216,13 @@ menu primary_menu {
label: _("_Preferences");
action: "app.preferences";
}*/
-
item {
- label: _("Manage Remotes");
+ label: _("Manage Remotes…");
action: "app.show-remotes-window";
}
item {
- label: _("Install from Search");
+ label: _("Install From The Web…");
action: "app.open-search-install";
}
@@ -202,7 +244,7 @@ menu copy_menu {
label: _("Copy Names");
action: "win.copy-names";
}
-
+
item {
label: _("Copy IDs");
action: "win.copy-ids";
@@ -222,4 +264,4 @@ menu row_menu {
//action: "win.open-app";
}
}
-}
\ No newline at end of file
+}
diff --git a/src/window.py b/src/window.py
index 534f15d..265b98f 100644
--- a/src/window.py
+++ b/src/window.py
@@ -28,6 +28,7 @@ from .common import myUtils
from .remotes_window import RemotesWindow
from .downgrade_window import DowngradeWindow
from .snapshots_window import SnapshotsWindow
+from .const import Config
from .app_row_widget import AppRow
@@ -42,6 +43,7 @@ class WarehouseWindow(Adw.ApplicationWindow):
toast_overlay = Gtk.Template.Child()
refresh_button = Gtk.Template.Child()
no_flatpaks = Gtk.Template.Child()
+ no_results = Gtk.Template.Child()
main_stack = Gtk.Template.Child()
batch_mode_button = Gtk.Template.Child()
batch_mode_bar = Gtk.Template.Child()
@@ -70,12 +72,15 @@ class WarehouseWindow(Adw.ApplicationWindow):
no_close = None
re_get_flatpaks = False
currently_uninstalling = False
+ is_result = False
+ is_empty = False
selected_rows = []
flatpak_rows = []
# ^ {Row visibility, Row selected, the row itself, properties, row menu, select, the flatpak row from `flatpak list`, mask label}
def filter_func(self, row):
if (self.search_entry.get_text().lower() in row.get_title().lower()) or (self.search_entry.get_text().lower() in row.get_subtitle().lower()):
+ self.is_result = True
return True
def removeRow(self, row):
@@ -255,6 +260,7 @@ class WarehouseWindow(Adw.ApplicationWindow):
self.batch_mode_button.set_sensitive(not is_empty)
self.search_button.set_sensitive(not is_empty)
self.filter_button.set_sensitive(not is_empty)
+ self.is_empty = is_empty
if is_empty:
self.batch_mode_button.set_active(False)
@@ -393,11 +399,17 @@ class WarehouseWindow(Adw.ApplicationWindow):
self.user_mask_list = self.my_utils.getHostMasks("user")
for index in range(len(self.host_flatpaks)):
- if "eol" in self.host_flatpaks[index][12]:
- self.eol_list.append(self.host_flatpaks[index][8])
+ try:
+ if "eol" in self.host_flatpaks[index][12]:
+ self.eol_list.append(self.host_flatpaks[index][8])
+ except:
+ print("Could not find EOL")
for index in range(len(self.host_flatpaks)):
- self.creat_row(index)
+ try:
+ self.creat_row(index)
+ except:
+ print("Could not create row")
self.windowSetEmpty(not self.flatpaks_list_box.get_row_at_index(0))
self.applyFilter(self.filter_list)
@@ -746,6 +758,28 @@ class WarehouseWindow(Adw.ApplicationWindow):
else:
self.toast_overlay.add_toast(Adw.Toast.new(_("File type not supported")))
+ def on_invalidate(self, row):
+ if self.is_empty:
+ self.batch_mode_button.set_active(False)
+ self.main_stack.set_visible_child(self.no_flatpaks)
+ else:
+ self.main_stack.set_visible_child(self.main_box)
+
+ self.is_result = False
+ self.flatpaks_list_box.invalidate_filter()
+ if self.is_result == False:
+ self.main_stack.set_visible_child(self.no_results)
+
+ def on_change(self, prop, prop2):
+ if self.search_bar.get_search_mode() == False:
+ if self.is_empty:
+ self.batch_mode_button.set_active(False)
+ self.main_stack.set_visible_child(self.no_flatpaks)
+ else:
+ self.main_stack.set_visible_child(self.main_box)
+
+
+
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.my_utils = myUtils(self)
@@ -767,8 +801,9 @@ class WarehouseWindow(Adw.ApplicationWindow):
self.flatpaks_list_box.set_filter_func(self.filter_func)
self.generate_list_of_flatpaks()
- self.search_entry.connect("search-changed", lambda *_: self.flatpaks_list_box.invalidate_filter())
+ self.search_entry.connect("search-changed", self.on_invalidate)
self.search_bar.connect_entry(self.search_entry)
+ self.search_bar.connect("notify", self.on_change)
self.refresh_button.connect("clicked", self.refresh_list_of_flatpaks, True)
self.batch_mode_button.connect("toggled", self.batch_mode_handler)
self.batch_clean_button.connect("clicked", self.batchCleanHandler)
@@ -791,6 +826,9 @@ class WarehouseWindow(Adw.ApplicationWindow):
file_drop.connect("drop", self.drop_callback)
self.scrolled_window.add_controller(file_drop)
+ if Config.DEVEL:
+ self.add_css_class("devel")
+