diff --git a/src/app_row_widget.py b/src/app_row_widget.py
new file mode 100644
index 0000000..9ee0c34
--- /dev/null
+++ b/src/app_row_widget.py
@@ -0,0 +1,51 @@
+import os
+import pathlib
+import subprocess
+import re
+
+from gi.repository import Adw, Gdk, Gio, GLib, Gtk
+from .properties_window import PropertiesWindow
+from .filter_window import FilterWindow
+from .common import myUtils
+
+class AppRow(Adw.ActionRow):
+
+ def __init__(self, parent_window, host_flatpaks, flatpak_index, **kwargs):
+ super().__init__(**kwargs)
+ self.my_utils = myUtils(parent_window)
+
+ current_flatpak = host_flatpaks[flatpak_index]
+
+ self.app_name = current_flatpak[0]
+ self.app_id = current_flatpak[2]
+ self.origin_remote = current_flatpak[6]
+ self.install_type = current_flatpak[7]
+ self.app_ref = current_flatpak[8]
+
+ self.set_title(self.app_name)
+ self.set_subtitle(self.app_id)
+ self.add_prefix(self.my_utils.findAppIcon(self.app_id))
+
+ properties_button = Gtk.Button(icon_name="info-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("View Properties"))
+ properties_button.add_css_class("flat")
+ properties_button.connect("clicked", lambda *_: PropertiesWindow(flatpak_index, host_flatpaks, parent_window))
+ self.add_suffix(properties_button)
+
+ select_flatpak_tickbox = Gtk.CheckButton() # visible=self.in_batch_mode
+ select_flatpak_tickbox.add_css_class("selection-mode")
+ # select_flatpak_tickbox.connect("toggled", self.rowSelectHandler, index)
+ self.add_suffix(select_flatpak_tickbox)
+
+ row_menu = Gtk.MenuButton(icon_name="view-more-symbolic", valign=Gtk.Align.CENTER) # visible=not self.in_batch_mode
+ row_menu.add_css_class("flat")
+ row_menu_model = Gio.Menu()
+ copy_menu_model = Gio.Menu()
+ advanced_menu_model = Gio.Menu()
+ self.add_suffix(row_menu)
+
+ parent_window.create_action(("copy-name" + str(flatpak_index)), lambda *_, name=self.app_name, toast=_("Copied name"): self.copyItem(name, toast))
+ copy_menu_model.append_item(Gio.MenuItem.new(_("Copy Name"), f"win.copy-name{flatpak_index}"))
+
+ row_menu_model.append_submenu(_("Copy"), copy_menu_model)
+
+ row_menu.set_menu_model(row_menu_model)
\ No newline at end of file
diff --git a/src/meson.build b/src/meson.build
index a173dd2..bef7d6e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -13,6 +13,7 @@ blueprints = custom_target('blueprints',
'downgrade.blp',
'search_install.blp',
'snapshots.blp',
+ 'properties.blp',
),
output: '.',
command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'],
@@ -63,6 +64,8 @@ warehouse_sources = [
'search_install_window.py',
'snapshots_window.py',
'snapshots.blp',
+ 'app_row_widget.py',
+ 'properties.blp',
]
install_data(warehouse_sources, install_dir: moduledir)
diff --git a/src/properties.blp b/src/properties.blp
new file mode 100644
index 0000000..4946094
--- /dev/null
+++ b/src/properties.blp
@@ -0,0 +1,103 @@
+using Gtk 4.0;
+using Adw 1;
+
+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 {
+ Box {
+ orientation: vertical;
+ Adw.Banner eol_app_banner {
+ }
+ Adw.Banner eol_runtime_banner {
+ }
+ Adw.Banner mask_banner {
+ }
+ 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 {
+
+ }
+ }
+ }
+ }
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/properties_window.py b/src/properties_window.py
index da0042f..c5306fb 100644
--- a/src/properties_window.py
+++ b/src/properties_window.py
@@ -2,191 +2,179 @@ from gi.repository import Gtk, Adw, GLib, Gdk, Gio
from .common import myUtils
import subprocess
import os
+import pathlib
-def show_properties_window(widget, index, window):
+@Gtk.Template(resource_path="/io/github/flattool/Warehouse/properties.ui")
+class PropertiesWindow(Adw.Window):
+ __gtype_name__ = "PropertiesWindow"
+
+ new_env = dict( os.environ )
+ new_env['LC_ALL'] = 'C'
+ host_home = str(pathlib.Path.home())
+ user_data_path = host_home + "/.var/app/"
- app_name = window.host_flatpaks[index][0]
- app_id = window.host_flatpaks[index][2]
- install_type = window.host_flatpaks[index][7]
- app_ref = window.host_flatpaks[index][8]
- data_folder = window.user_data_path + app_id
+ toast_overlay = Gtk.Template.Child()
+ upper = Gtk.Template.Child()
+ app_icon = Gtk.Template.Child()
+ data_row = Gtk.Template.Child()
+ open_data = Gtk.Template.Child()
+ trash_data = Gtk.Template.Child()
+ spinner = Gtk.Template.Child()
+ details = Gtk.Template.Child()
+ view_apps = Gtk.Template.Child()
+ runtime = Gtk.Template.Child()
+ runtime_properties = Gtk.Template.Child()
+ runtime_copy = Gtk.Template.Child()
+ lower = Gtk.Template.Child()
+ eol_app_banner = Gtk.Template.Child()
+ eol_runtime_banner = Gtk.Template.Child()
+ mask_banner = Gtk.Template.Child()
- properties_window = Adw.Window(title=_("{} Properties").format(window.host_flatpaks[index][0]))
- properties_window.set_default_size(350, 600)
- properties_window.set_size_request(260, 230)
- properties_window.set_modal(True)
- properties_window.set_resizable(True)
- outer_box = Gtk.Box(orientation="vertical")
- properties_window.set_transient_for(window)
- properties_scroll = Gtk.ScrolledWindow()
- properties_toast_overlay = Adw.ToastOverlay()
- properties_toast_overlay.set_child(outer_box)
- properties_box = Gtk.Box(orientation="vertical", vexpand=True)
- properties_clamp = Adw.Clamp()
- eol_app_banner = Adw.Banner(title=_("{} has reached its End of Life and will not receive any security updates").format(app_name))
- eol_runtime_banner = Adw.Banner(title=_("{}'s runtime has reached its End of Life and will not receive any security updates").format(app_name))
- mask_banner = Adw.Banner(title=_("{} is masked and will not be updated").format(window.host_flatpaks[index][0]))
- outer_box.append(eol_app_banner)
- outer_box.append(eol_runtime_banner)
- outer_box.append(mask_banner)
- outer_box.append(properties_scroll)
- properties_scroll.set_child(properties_clamp)
- properties_clamp.set_child(properties_box)
- properties_title_bar = Adw.ToolbarView()
- properties_header_bar = Gtk.HeaderBar()
- properties_title_bar.add_top_bar(properties_header_bar)
- properties_title_bar.set_content(properties_toast_overlay)
- user_data_list = Gtk.ListBox(selection_mode="none", margin_top=12, margin_bottom=0, margin_start=12, margin_end=12)
- user_data_row = Adw.ActionRow(title="No User Data")
- user_data_list.append(user_data_row)
- user_data_list.add_css_class("boxed-list")
+ def copyItem(self, to_copy, to_toast=None):
+ self.get_clipboard().set(to_copy)
+ if to_toast:
+ self.toast_overlay.add_toast(Adw.Toast.new(_("Copied {}").format(to_toast)))
- my_utils = myUtils(window)
+ def open_button_handler(self, widget):
+ try:
+ Gio.AppInfo.launch_default_for_uri(f"file://{self.user_data_path}", None)
+ except GLib.GError:
+ self.toast_overlay.add_toast(Adw.Toast.new(_("Could not open folder")))
- system_mask_list = my_utils.getHostMasks("system")
- user_mask_list = my_utils.getHostMasks("user")
+ def show_details(self, widget):
+ try:
+ Gio.AppInfo.launch_default_for_uri(f"appstream://{self.app_id}", None)
+ except GLib.GError:
+ self.toast_overlay.add_toast(Adw.Toast.new(_("Could not show details")))
- def viewAppsHandler(button):
- window.should_open_filter_window = False
- window.filter_button.set_active(True)
- window.applyFilter([[False], [False], "all", "all", [window.host_flatpaks[index][8]]])
- window.should_open_filter_window = True
- properties_window.close()
+ def getSizeCallback(self, *args):
+ self.open_data.set_visible(True)
+ self.open_data.connect("clicked", self.open_button_handler)
+ self.trash_data.set_visible(True)
+ self.data_row.set_title(_("User Data"))
+ self.data_row.set_subtitle(f"~{self.size}")
+ self.spinner.set_visible(False)
- def key_handler(_a, event, _c, _d):
- if event == Gdk.KEY_Escape:
- properties_window.close()
+ def getSizeThread(self, *args):
+ self.size = self.my_utils.getSizeWithFormat(self.user_data_path)
- event_controller = Gtk.EventControllerKey()
- event_controller.connect("key-pressed", key_handler)
- properties_window.add_controller(event_controller)
-
- def on_response(_a, response_id, _b):
- if response_id != "continue":
- return
- if my_utils.trashFolder(data_folder) == 0:
- properties_toast_overlay.add_toast(Adw.Toast.new(_("Trashed user data")))
- user_data_list.remove(user_data_row)
- user_data_list.append(Adw.ActionRow(title="No User Data"))
+ def generateUpper(self):
+ image = self.my_utils.findAppIcon(self.app_id)
+ self.runtime.set_subtitle(self.current_flatpak[13])
+ if image.get_paintable() == None:
+ self.app_icon.set_from_icon_name(image.get_icon_name())
else:
- properties_toast_overlay.add_toast(Adw.Toast.new(_("Could not trash user data")))
+ self.app_icon.set_from_paintable(image.get_paintable())
- def clean_button_handler(_widget):
- dialog = Adw.MessageDialog.new(window, _("Send {}'s User Data to the Trash?").format(app_name))
- dialog.set_body(_("Your files and data for this app will be sent to the trash."))
- dialog.set_close_response("cancel")
+ if os.path.exists(self.user_data_path):
+ task = Gio.Task.new(None, None, self.getSizeCallback)
+ task.run_in_thread(self.getSizeThread)
+ else:
+ self.data_row.set_title(_("No User Data"))
+ self.spinner.set_visible(False)
+
+ if "runtime" in self.current_flatpak[12]:
+ self.runtime.set_visible(False)
+ else:
+ self.view_apps.set_visible(False)
+
+ def generateLower(self):
+ column_headers = [
+ _('Name'), _('Description'), _('App ID'), _('Version'), _('Branch'),
+ _('Arch'), _('Origin'), _('Installation'), _('Ref'), _('Active Commit'),
+ _('Latest Commit'), _('Installed Size'), _('Options')
+ ]
+
+ for i in range(len(column_headers)):
+ if self.current_flatpak[i] == "":
+ continue
+
+ row = Adw.ActionRow(title=column_headers[i], activatable=True)
+ row.add_suffix(Gtk.Image.new_from_icon_name("edit-copy-symbolic"))
+ row.set_subtitle(GLib.markup_escape_text(self.current_flatpak[i]))
+ row.connect("activated", lambda *_a, row=row: self.copyItem(row.get_subtitle(), row.get_title()))
+ self.lower.add(row)
+
+ def viewAppsHandler(self, widget):
+ self.parent_window.should_open_filter_window = False
+ self.parent_window.filter_button.set_active(True)
+ self.parent_window.applyFilter([True, False, ["all"], ["all"], [self.app_ref]])
+ self.parent_window.should_open_filter_window = True
+ self.close()
+
+ def showPropertiesHandler(self):
+ runtime = self.current_flatpak[13]
+ for i in range(len(self.host_flatpaks)):
+ if runtime in self.host_flatpaks[i][8]:
+ PropertiesWindow(i, self.host_flatpaks, self.parent_window)
+
+ def trashDataHandler(self):
+ def onResponse(response, *args):
+ if response == "cancel":
+ return
+
+ if self.my_utils.trashFolder(self.user_data_path) == 0:
+ self.toast_overlay.add_toast(Adw.Toast.new(_("Trashed user data")))
+ self.data_row.set_title(_("No User Data"))
+ self.data_row.set_subtitle("")
+ self.open_data.set_visible(False)
+ self.trash_data.set_visible(False)
+ else:
+ self.toast_overlay.add_toast(Adw.Toast.new(_("Could not trash user data")))
+
+ dialog = Adw.MessageDialog.new(self, _("Send {}'s User Data to the Trash?").format(self.app_name))
dialog.add_response("cancel", _("Cancel"))
+ dialog.set_close_response("cancel")
dialog.add_response("continue", _("Trash Data"))
dialog.set_response_appearance("continue", Adw.ResponseAppearance.DESTRUCTIVE)
- dialog.set_transient_for(properties_window)
- dialog.connect("response", on_response, dialog.choose_finish)
- Gtk.Window.present(dialog)
-
- def open_button_handler(_widget):
- try:
- Gio.AppInfo.launch_default_for_uri(f"file://{path}", None)
- except GLib.GError:
- properties_toast_overlay.add_toast(Adw.Toast.new(_("Could not open folder")))
-
- def copy_button_handler(widget, title, to_copy):
- window.clipboard.set(to_copy)
- properties_toast_overlay.add_toast(Adw.Toast.new(_("Copied {}").format(title)))
+ dialog.connect("response", onResponse, dialog.choose_finish)
+ dialog.present()
- image = my_utils.findAppIcon(window.host_flatpaks[index][2])
- image.add_css_class("icon-dropshadow")
- image.set_margin_top(6)
- image.set_pixel_size(100)
- properties_box.append(image)
+ def __init__(self, flatpak_index, host_flatpaks, parent_window, **kwargs):
+ super().__init__(**kwargs)
+ self.my_utils = myUtils(self)
+ self.current_flatpak = host_flatpaks[flatpak_index]
+ self.parent_window = parent_window
+ self.host_flatpaks = host_flatpaks
+ self.flatpak_index = flatpak_index
- properties_list = Gtk.ListBox(selection_mode="none", margin_top=12, margin_bottom=12, margin_start=12, margin_end=12)
- properties_list.add_css_class("boxed-list")
+ self.app_name = self.current_flatpak[0]
+ self.app_id = self.current_flatpak[2]
+ self.origin_remote = self.current_flatpak[6]
+ self.install_type = self.current_flatpak[7]
+ self.app_ref = self.current_flatpak[8]
+ self.user_data_path += self.app_id
- path = str(window.user_data_path) + window.host_flatpaks[index][2]
+ self.details.connect("activated", self.show_details)
+ self.runtime_copy.connect("clicked", lambda *_: self.copyItem(self.runtime.get_subtitle(), self.runtime.get_title()))
+ self.runtime_properties.connect("clicked", lambda *_: self.close())
+ self.runtime_properties.connect("clicked", lambda *_: self.showPropertiesHandler())
+ self.view_apps.connect("activated", self.viewAppsHandler)
+ self.trash_data.connect("clicked", lambda *_: self.trashDataHandler())
+
+ if "eol" in self.current_flatpak[12]:
+ self.eol_app_banner.set_revealed(True)
+ self.eol_app_banner.set_title(_("{} has reached its End of Life and will not receive any security updates").format(self.app_name))
- def size_thread(path):
- size = f"{path}\n~{my_utils.getSizeWithFormat(path)}"
- user_data_row.set_subtitle(size)
+ if self.current_flatpak[13] in parent_window.eol_list:
+ self.eol_runtime_banner.set_revealed(True)
+ self.eol_runtime_banner.set_title(_("{}'s runtime has reached its End of Life and will not receive any security updates").format(self.app_name))
- def calc_size(path):
- task = Gio.Task.new(None, None, None)
- task.run_in_thread(lambda _task, _obj, _data, _cancellable: size_thread(path))
+ if self.app_id in self.my_utils.getHostMasks("system") or self.app_id in self.my_utils.getHostMasks("user"):
+ self.mask_banner.set_revealed(True)
+ self.mask_banner.set_title(_("{} is masked and will not be updated").format(self.app_name))
- def showPropertiesHandler(button, query):
- for i in range(len(window.host_flatpaks)):
- if query in window.host_flatpaks[i][8]:
- show_properties_window(button, i, window)
- properties_window.close()
+ def key_handler(_a, event, _c, _d):
+ if event == Gdk.KEY_Escape:
+ self.close()
+ event_controller = Gtk.EventControllerKey()
+ event_controller.connect("key-pressed", key_handler)
+ self.add_controller(event_controller)
- if os.path.exists(path):
- user_data_row.set_title("User Data")
- calc_size(path)
+ self.generateUpper()
+ self.generateLower()
- open_button = Gtk.Button(icon_name="document-open-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("Open User Data Folder"))
- open_button.add_css_class("flat")
- open_button.connect("clicked", open_button_handler)
- user_data_row.add_suffix(open_button)
-
- clean_button = Gtk.Button(icon_name="brush-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("Trash User Data"))
- clean_button.add_css_class("flat")
- clean_button.connect("clicked", clean_button_handler)
- user_data_row.add_suffix(clean_button)
-
- details_row = Adw.ActionRow(title=_("Show Details in Store"), activatable=True)
- details_row.add_suffix(Gtk.Image.new_from_icon_name("arrow2-top-right-symbolic"))
- details_row.connect("activated", lambda *_: Gio.AppInfo.launch_default_for_uri(f"appstream://{app_id}", None))
- user_data_list.append(details_row)
- properties_box.append(user_data_list)
-
- if "runtime" in window.host_flatpaks[index][12]:
- dependant_runtimes = my_utils.getDependantRuntimes()
- if app_ref in dependant_runtimes:
- view_apps = Adw.ActionRow(title=_("Show Apps Using this Runtime"), activatable=True)
- view_apps.add_suffix(Gtk.Image.new_from_icon_name("funnel-symbolic"))
- view_apps.connect("activated", viewAppsHandler)
- user_data_list.append(view_apps)
- # view_apps_button = Gtk.Button(icon_name="funnel-symbolic", tooltip_text=_("Show Apps Using this Runtime"))
- # view_apps_button.connect("clicked", viewAppsHandler)
- # properties_header_bar.pack_start(view_apps_button)
-
- column_headers = [_('Name'), _('Description'), _('App ID'), _('Version'), _('Branch'), _('Arch'), _('Origin'), _('Installation'), _('Ref'), _('Active Commit'), _('Latest Commit'), _('Installed Size'), _('Options'), _('Runtime')]
- for column in range(len(window.host_flatpaks[index])):
- visible = True
- if window.host_flatpaks[index][column] == "":
- visible = False
- row_item = Adw.ActionRow(title=column_headers[column], activatable=True)
- row_item.set_subtitle(GLib.markup_escape_text(window.host_flatpaks[index][column]))
- row_item.connect("activated", copy_button_handler, column_headers[column], window.host_flatpaks[index][column])
-
- if column == 13:
- runtime_properties_button = Gtk.Button(icon_name="info-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("View Properties"), margin_end=6)
- runtime_properties_button.add_css_class("flat")
- runtime_properties_button.connect("clicked", showPropertiesHandler, row_item.get_subtitle())
- row_item.add_suffix(runtime_properties_button)
-
- if row_item.get_subtitle() in window.eol_list:
- row_item.add_css_class("error")
- eol_runtime_banner.set_revealed(True)
-
- row_item.set_visible(visible)
- row_item.add_suffix(Gtk.Image.new_from_icon_name("edit-copy-symbolic"))
- properties_list.append(row_item)
-
- properties_box.append(properties_list)
-
- if "eol" in window.host_flatpaks[index][12]:
- eol_app_banner.set_revealed(True)
-
- def maskHandler():
- x = my_utils.maskFlatpak(app_id, install_type, True)
- if x == 0:
- mask_banner.set_revealed(False)
- window.flatpak_rows[index][7].set_visible(False) # Sets the mask label invisble
-
- # properties_window.set_default_size(8, 8)
- if app_id in system_mask_list or app_id in user_mask_list:
- mask_banner.set_revealed(True)
- mask_banner.set_button_label(_("Enable Updates"))
- mask_banner.connect("button-clicked", lambda *_: maskHandler())
-
- properties_window.set_content(properties_title_bar)
- properties_window.present()
+ self.set_title(_("{} Properties").format(self.app_name))
+ self.set_size_request(260, 230)
+ self.set_transient_for(parent_window)
+ self.present()
\ No newline at end of file
diff --git a/src/warehouse.gresource.xml b/src/warehouse.gresource.xml
index 059d012..0f1b0e9 100644
--- a/src/warehouse.gresource.xml
+++ b/src/warehouse.gresource.xml
@@ -9,6 +9,7 @@
downgrade.ui
search_install.ui
snapshots.ui
+ properties.ui
style.css
gtk/help-overlay.ui
diff --git a/src/window.py b/src/window.py
index 62aa1bf..e234f7b 100644
--- a/src/window.py
+++ b/src/window.py
@@ -22,13 +22,15 @@ import subprocess
import re
from gi.repository import Adw, Gdk, Gio, GLib, Gtk
-from .properties_window import show_properties_window
+from .properties_window import PropertiesWindow
from .filter_window import FilterWindow
from .common import myUtils
from .remotes_window import RemotesWindow
from .downgrade_window import DowngradeWindow
from .snapshots_window import SnapshotsWindow
+from .app_row_widget import AppRow
+
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/window.ui")
class WarehouseWindow(Adw.ApplicationWindow):
__gtype_name__ = "WarehouseWindow"
@@ -273,6 +275,7 @@ class WarehouseWindow(Adw.ApplicationWindow):
# EOL = End Of Life, meaning the app will not be updated
eol_app_label = Gtk.Label(label=_("App EOL"), hexpand=True, wrap=True, justify=Gtk.Justification.RIGHT, valign=Gtk.Align.CENTER, tooltip_text=_("{} has reached its End of Life and will not receive any security updates").format(app_name))
eol_app_label.add_css_class("error")
+ flatpak_row.add_suffix(eol_app_label)
if self.host_flatpaks[index][13] in self.eol_list:
# EOL = End Of Life, meaning the runtime will not be updated
@@ -287,7 +290,7 @@ class WarehouseWindow(Adw.ApplicationWindow):
properties_button = Gtk.Button(icon_name="info-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("View Properties"))
properties_button.add_css_class("flat")
- properties_button.connect("clicked", show_properties_window, index, self)
+ properties_button.connect("clicked", lambda *_, index=index: PropertiesWindow(index, self.host_flatpaks, self))
flatpak_row.add_suffix(properties_button)
select_flatpak_tickbox = Gtk.CheckButton(visible=self.in_batch_mode)
@@ -400,6 +403,10 @@ class WarehouseWindow(Adw.ApplicationWindow):
self.applyFilter(self.filter_list)
self.batchActionsEnable(False)
+ cool_row = AppRow(self, self.host_flatpaks, 7)
+ print(cool_row.app_id)
+ self.flatpaks_list_box.append(cool_row)
+
def openDataFolder(self, path):
try:
Gio.AppInfo.launch_default_for_uri(f"file://{path}", None)