diff --git a/libflatpak_query.py b/libflatpak_query.py index c503443..2e2692d 100755 --- a/libflatpak_query.py +++ b/libflatpak_query.py @@ -672,6 +672,32 @@ def remove_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tuple return False, f"Failed to remove {app.id}: {e}" return True, f"Successfully removed {app.id}" +def update_flatpak(app: AppStreamPackage, repo_name=None, system=False) -> tuple[bool, str]: + """ + Remove a Flatpak package using transactions. + + Args: + app (AppStreamPackage): The package to install. + system (Optional[bool]): Whether to operate on user or system installation + + Returns: + Tuple[bool, str]: (success, message) + """ + if not repo_name: + repo_name = "flathub" + + # Get the appropriate installation based on user parameter + installation = get_installation(system) + + # Create a new transaction for removal + transaction = Flatpak.Transaction.new_for_installation(installation) + transaction.add_update(app.flatpak_bundle) + # Run the transaction + try: + transaction.run() + except GLib.Error as e: + return False, f"Failed to update {app.id}: {e}" + return True, f"Successfully updated {app.id}" def get_installation(system=False): if system is False: @@ -858,6 +884,8 @@ def main(): help='Install a Flatpak package') parser.add_argument('--remove', type=str, metavar='APP_ID', help='Remove a Flatpak package') + parser.add_argument('--update', type=str, metavar='APP_ID', + help='Update a Flatpak package') parser.add_argument('--system', action='store_true', help='Install as system instead of user') parser.add_argument('--refresh', action='store_true', help='Install as system instead of user') parser.add_argument('--refresh-local', action='store_true', help='Install as system instead of user') @@ -892,6 +920,10 @@ def main(): handle_remove(args, searcher) return + if args.update: + handle_update(args, searcher) + return + # Handle information operations if args.list_installed: handle_list_installed(args, searcher) @@ -967,7 +999,20 @@ def handle_remove(args, searcher): result_message = f"{message}" break except GLib.Error as e: - result_message = f"Installation of {args.install} failed: {str(e)}" + result_message = f"Removal of {args.remove} failed: {str(e)}" + pass + print(result_message) + +def handle_update(args, searcher): + packagelist = searcher.search_flatpak(args.update, args.repo) + result_message = "" + for package in packagelist: + try: + success, message = update_flatpak(package, args.repo, args.system) + result_message = f"{message}" + break + except GLib.Error as e: + result_message = f"Update of {args.update} failed: {str(e)}" pass print(result_message) diff --git a/main.py b/main.py index 15529c5..bc5ad2d 100755 --- a/main.py +++ b/main.py @@ -1162,12 +1162,49 @@ class MainWindow(Gtk.Window): dialog.destroy() def on_update_clicked(self, button, app): - """Handle the Update button click""" + """Handle the Remove button click with removal options""" details = app.get_details() - print(f"Updating application: {details['name']}") - # Implement update logic here - # Example: - # Flatpak.update(app_id=details['id']) + + # Create dialog + dialog = Gtk.Dialog( + title=f"Update {details['name']}?", + transient_for=self, + modal=True, + destroy_with_parent=True, + ) + # Add buttons using the new method + dialog.add_button("Cancel", Gtk.ResponseType.CANCEL) + dialog.add_button("Update", Gtk.ResponseType.OK) + + # Create content area + content_area = dialog.get_content_area() + content_area.set_spacing(12) + content_area.set_border_width(12) + + content_area.pack_start(Gtk.Label(label=f"Update: {details['id']}?"), False, False, 0) + + # Show dialog + dialog.show_all() + + # Run dialog + response = dialog.run() + if response == Gtk.ResponseType.OK: + # Perform Removal + def perform_update(): + # Show waiting dialog + GLib.idle_add(self.show_waiting_dialog, "Updating package...") + + success, message = libflatpak_query.update_flatpak(app, None, self.system_mode) + + # Update UI on main thread + GLib.idle_add(lambda: self.on_task_complete(dialog, success, message)) + + # Start spinner and begin installation + thread = threading.Thread(target=perform_update) + thread.daemon = True # Allow program to exit even if thread is still running + thread.start() + + dialog.destroy() def on_details_clicked(self, button, app): """Handle the Details button click"""