diff --git a/src/downgrade.blp b/src/downgrade.blp
new file mode 100644
index 0000000..7636b5c
--- /dev/null
+++ b/src/downgrade.blp
@@ -0,0 +1,83 @@
+using Gtk 4.0;
+using Adw 1;
+
+template DowngradeWindow : Adw.Window {
+ default-width: 500;
+ default-height: 750;
+ modal: true;
+
+ 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: _("Apply");
+ 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"]
+ }
+
+ ScrolledWindow scrolled_window {
+ vexpand: true;
+ Adw.Clamp{
+ Box outerbox {
+ orientation: vertical;
+
+ ListBox {
+ margin-top: 12;
+ margin-start: 12;
+ margin-end: 12;
+ hexpand: true;
+ valign: start;
+ selection-mode: none;
+ styles["boxed-list"]
+
+ Adw.SwitchRow mask_row {
+ title: _("Mask this Flatpak");
+ subtitle: _("Ensure that the flatpak will never update to a newer version");
+ active: true;
+ }
+ }
+
+ Label {
+ label: _("Select a Version");
+ margin-top: 12;
+ margin-start: 12;
+ halign: start;
+ styles["title-3"]
+ }
+
+ ListBox versions_listbox {
+ margin-top: 12;
+ margin-bottom: 12;
+ margin-start: 12;
+ margin-end: 12;
+ hexpand: true;
+ valign: start;
+ selection-mode: none;
+ styles["boxed-list"]
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/downgrade_window.py b/src/downgrade_window.py
new file mode 100644
index 0000000..c162275
--- /dev/null
+++ b/src/downgrade_window.py
@@ -0,0 +1,110 @@
+from gi.repository import Gtk, Adw, GLib, Gdk, Gio
+from .common import myUtils
+import subprocess
+import os
+import pathlib
+
+@Gtk.Template(resource_path="/io/github/flattool/Warehouse/downgrade.ui")
+class DowngradeWindow(Adw.Window):
+ __gtype_name__ = "DowngradeWindow"
+
+ new_env = dict( os.environ )
+ new_env['LC_ALL'] = 'C'
+
+ cancel_button = Gtk.Template.Child()
+ apply_button = Gtk.Template.Child()
+ versions_listbox = Gtk.Template.Child()
+ progress_bar = Gtk.Template.Child()
+ mask_row = Gtk.Template.Child()
+
+ def pulser(self):
+ if self.should_pulse:
+ self.progress_bar.pulse()
+ GLib.timeout_add(500, self.pulser)
+
+ def key_handler(self, _a, event, _c, _d):
+ if event == Gdk.KEY_Escape:
+ self.close()
+
+ def selectionHandler(self, button, index):
+ self.apply_button.set_sensitive(True)
+ if button.get_active():
+ self.commit_to_use = self.versions[index][0]
+
+ def getCommits(self):
+ output = subprocess.run(["flatpak-spawn", "--host", "flatpak", "remote-info", "--log", self.remote, self.app_ref, f"--{self.install_type}"], capture_output=True, text=True, env=self.new_env).stdout
+ lines = output.strip().split("\n")
+ columns = lines[0].split("\t")
+ data = [columns]
+ for line in lines[1:]:
+ row = line.split("\t")
+ data.append(row[0].strip())
+
+ commits = []
+ changes = []
+ dates = []
+ for i in range(len(data)):
+ line = data[i]
+
+ if "Commit:" in line:
+ commits.append(line.replace("Commit: ", ""))
+
+ if "Subject:" in line:
+ changes.append(line.replace("Subject: ", ""))
+
+ if "Date:" in line:
+ dates.append(line.replace("Date: ", ""))
+
+ for i in range(len(commits)):
+ self.versions.append([commits[i], changes[i], dates[i]])
+
+ def commitsResponse(self):
+ self.progress_bar.set_visible(False)
+ self.should_pulse = False
+ for i in range(len(self.versions)):
+ version = self.versions[i]
+ row = Adw.ActionRow(title=version[2], subtitle=version[1])
+ select = Gtk.CheckButton()
+ select.connect("toggled", self.selectionHandler, i)
+
+ if i > 0:
+ select.set_group(self.versions[i-1][3])
+
+ version.append(select)
+ row.set_activatable_widget(select)
+ row.add_prefix(select)
+ self.versions_listbox.append(row)
+
+ def generateList(self):
+ task = Gio.Task.new(None, None, lambda *_: self.commitsResponse())
+ task.run_in_thread(lambda *_: self.getCommits())
+
+ def __init__(self, parent_window, flatpak_row_item, **kwargs):
+ super().__init__(**kwargs)
+
+ # Create Variables
+ self.my_utils = myUtils(self)
+ self.app_name = flatpak_row_item[0]
+ self.app_id = flatpak_row_item[2]
+ self.remote = flatpak_row_item[6]
+ self.install_type = flatpak_row_item[7]
+ self.app_ref = flatpak_row_item[8]
+ self.versions = []
+ self.should_pulse = True
+ self.commit_to_use = ""
+ event_controller = Gtk.EventControllerKey()
+
+ # Connections
+ event_controller.connect("key-pressed", self.key_handler)
+ self.cancel_button.connect("clicked", lambda *_: self.close())
+
+ # Apply
+ self.pulser()
+ self.add_controller(event_controller)
+ self.set_title(_("Downgrade {}").format(self.app_name))
+ self.set_transient_for(parent_window)
+ # print(self.mask_row.get_active())
+
+ self.generateList()
+
+ self.present()
\ No newline at end of file
diff --git a/src/filter.blp b/src/filter.blp
index 9cef034..f2ebfb6 100644
--- a/src/filter.blp
+++ b/src/filter.blp
@@ -24,9 +24,7 @@ template FilterWindow : Adw.Window {
}
content:
Adw.ToastOverlay toast_overlay {
- Stack main_stack {
- //Box main_box {
- //orientation: vertical;
+ Stack main_stack {
Overlay main_overlay {
ScrolledWindow scrolled_window {
vexpand: true;
@@ -82,7 +80,6 @@ template FilterWindow : Adw.Window {
}
}
}
- //}
Adw.StatusPage no_data {
icon-name: "check-plain-symbolic";
title: _("No Leftover Data");
@@ -90,12 +87,5 @@ template FilterWindow : Adw.Window {
}
}
};
- // [bottom]
- // ActionBar action_bar {
- // [start]
- // ToggleButton select_all_button {
- // label: _("Select All");
- // }
- // }
}
}
\ No newline at end of file
diff --git a/src/meson.build b/src/meson.build
index ade318a..92b7e8a 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -9,7 +9,8 @@ blueprints = custom_target('blueprints',
'orphans.blp',
'filter.blp',
'popular_remotes.blp',
- 'remotes.blp'
+ 'remotes.blp',
+ 'downgrade.blp',
),
output: '.',
command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'],
@@ -53,7 +54,9 @@ warehouse_sources = [
'filter.blp',
'popular_remotes_window.py',
'style.css',
- 'remotes.blp'
+ 'remotes.blp',
+ 'downgrade_window.py',
+ 'downgrade.blp'
]
install_data(warehouse_sources, install_dir: moduledir)
diff --git a/src/warehouse.gresource.xml b/src/warehouse.gresource.xml
index 81742b3..e352131 100644
--- a/src/warehouse.gresource.xml
+++ b/src/warehouse.gresource.xml
@@ -6,6 +6,7 @@
filter.ui
popular_remotes.ui
remotes.ui
+ downgrade.ui
style.css
gtk/help-overlay.ui
diff --git a/src/window.py b/src/window.py
index 279074f..8b6722f 100644
--- a/src/window.py
+++ b/src/window.py
@@ -26,6 +26,7 @@ from .properties_window import show_properties_window
from .filter_window import FilterWindow
from .common import myUtils
from .remotes_window import RemotesWindow
+from .downgrade_window import DowngradeWindow
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/window.ui")
class WarehouseWindow(Adw.ApplicationWindow):
@@ -354,6 +355,10 @@ class WarehouseWindow(Adw.ApplicationWindow):
uninstall_item = Gio.MenuItem.new(_("Uninstall {}").format(app_name), f"win.uninstall{index}")
row_menu_model.append_item(uninstall_item)
+ self.create_action(("downgrade" + str(index)), lambda *_, row=self.host_flatpaks[index]: DowngradeWindow(self, row))
+ downgrade_item = Gio.MenuItem.new(_("Downgrade {}").format(app_name), f"win.downgrade{index}")
+ row_menu_model.append_item(downgrade_item)
+
# row_menu_model.remove(1)
row_menu.set_menu_model(row_menu_model)