Add history deletion features - clear all in preferences and delete individual items
This commit is contained in:
parent
2797a320c1
commit
c9e53de55d
@ -78,3 +78,18 @@ class HistoryManager:
|
||||
entries = entries[:100]
|
||||
|
||||
self.save_history(entries)
|
||||
|
||||
def delete_entry(self, entry: HistoryEntry):
|
||||
"""Delete a specific entry from history."""
|
||||
entries = self.load_history()
|
||||
# Filter out the entry by comparing timestamps and URLs
|
||||
entries = [e for e in entries if not (
|
||||
e.timestamp == entry.timestamp and
|
||||
e.request.url == entry.request.url and
|
||||
e.request.method == entry.request.method
|
||||
)]
|
||||
self.save_history(entries)
|
||||
|
||||
def clear_history(self):
|
||||
"""Clear all history entries."""
|
||||
self.save_history([])
|
||||
|
||||
@ -68,8 +68,10 @@ class RosterApplication(Adw.Application):
|
||||
|
||||
def on_preferences_action(self, widget, _):
|
||||
"""Callback for the app.preferences action."""
|
||||
preferences = PreferencesDialog()
|
||||
preferences.set_transient_for(self.props.active_window)
|
||||
window = self.props.active_window
|
||||
preferences = PreferencesDialog(history_manager=window.history_manager)
|
||||
preferences.set_transient_for(window)
|
||||
preferences.connect('history-cleared', lambda d: window._load_history())
|
||||
preferences.present()
|
||||
|
||||
def on_shortcuts_action(self, widget, _):
|
||||
|
||||
@ -43,6 +43,30 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">History</property>
|
||||
<property name="description" translatable="yes">Manage request history</property>
|
||||
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Clear All History</property>
|
||||
<property name="subtitle" translatable="yes">Remove all saved request and response history</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="clear_history_button">
|
||||
<property name="label" translatable="yes">Clear</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="clicked" handler="on_clear_history_clicked" swapped="no"/>
|
||||
<style>
|
||||
<class name="destructive-action"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from gi.repository import Adw, Gtk, Gio
|
||||
from gi.repository import Adw, Gtk, Gio, GObject
|
||||
|
||||
|
||||
@Gtk.Template(resource_path='/cz/vesp/roster/preferences-dialog.ui')
|
||||
@ -26,10 +26,17 @@ class PreferencesDialog(Adw.PreferencesWindow):
|
||||
|
||||
tls_verification_row = Gtk.Template.Child()
|
||||
timeout_row = Gtk.Template.Child()
|
||||
clear_history_button = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
__gsignals__ = {
|
||||
'history-cleared': (GObject.SIGNAL_RUN_FIRST, None, ())
|
||||
}
|
||||
|
||||
def __init__(self, history_manager=None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.history_manager = history_manager
|
||||
|
||||
# Get settings
|
||||
self.settings = Gio.Settings.new('cz.vesp.roster')
|
||||
|
||||
@ -47,3 +54,30 @@ class PreferencesDialog(Adw.PreferencesWindow):
|
||||
'value',
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
)
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_clear_history_clicked(self, button):
|
||||
"""Clear all history after confirmation."""
|
||||
if not self.history_manager:
|
||||
return
|
||||
|
||||
# Create confirmation dialog
|
||||
dialog = Adw.AlertDialog.new(
|
||||
"Clear All History?",
|
||||
"This will permanently delete all saved request and response history. This action cannot be undone."
|
||||
)
|
||||
dialog.add_response("cancel", "Cancel")
|
||||
dialog.add_response("clear", "Clear History")
|
||||
dialog.set_response_appearance("clear", Adw.ResponseAppearance.DESTRUCTIVE)
|
||||
dialog.set_default_response("cancel")
|
||||
dialog.set_close_response("cancel")
|
||||
|
||||
def on_response(dialog, response):
|
||||
if response == "clear":
|
||||
# Clear the history
|
||||
self.history_manager.clear_history()
|
||||
# Notify the main window to refresh
|
||||
self.emit('history-cleared')
|
||||
|
||||
dialog.connect("response", on_response)
|
||||
dialog.present(self)
|
||||
|
||||
@ -62,6 +62,20 @@
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Delete Button -->
|
||||
<child>
|
||||
<object class="GtkButton" id="delete_button">
|
||||
<property name="icon-name">user-trash-symbolic</property>
|
||||
<property name="tooltip-text">Delete this history item</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="clicked" handler="on_delete_clicked" swapped="no"/>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Click gesture for toggling expansion (only on summary) -->
|
||||
<child>
|
||||
<object class="GtkGestureClick" id="click_gesture">
|
||||
|
||||
@ -33,6 +33,7 @@ class HistoryItem(Gtk.Box):
|
||||
url_label = Gtk.Template.Child()
|
||||
timestamp_label = Gtk.Template.Child()
|
||||
status_label = Gtk.Template.Child()
|
||||
delete_button = Gtk.Template.Child()
|
||||
request_headers_label = Gtk.Template.Child()
|
||||
request_body_scroll = Gtk.Template.Child()
|
||||
request_body_text = Gtk.Template.Child()
|
||||
@ -48,7 +49,8 @@ class HistoryItem(Gtk.Box):
|
||||
load_button = Gtk.Template.Child()
|
||||
|
||||
__gsignals__ = {
|
||||
'load-requested': (GObject.SIGNAL_RUN_FIRST, None, ())
|
||||
'load-requested': (GObject.SIGNAL_RUN_FIRST, None, ()),
|
||||
'delete-requested': (GObject.SIGNAL_RUN_FIRST, None, ())
|
||||
}
|
||||
|
||||
def __init__(self, entry):
|
||||
@ -140,6 +142,11 @@ class HistoryItem(Gtk.Box):
|
||||
"""Emit load signal when load button clicked."""
|
||||
self.emit('load-requested')
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_delete_clicked(self, button):
|
||||
"""Emit delete signal when delete button clicked."""
|
||||
self.emit('delete-requested')
|
||||
|
||||
@Gtk.Template.Callback()
|
||||
def on_request_expander_clicked(self, gesture, n_press, x, y):
|
||||
"""Toggle request body expansion."""
|
||||
|
||||
@ -437,6 +437,7 @@ class RosterWindow(Adw.ApplicationWindow):
|
||||
for entry in entries:
|
||||
item = HistoryItem(entry)
|
||||
item.connect('load-requested', self._on_history_load_requested, entry)
|
||||
item.connect('delete-requested', self._on_history_delete_requested, entry)
|
||||
self.history_listbox.append(item)
|
||||
|
||||
def _on_history_load_requested(self, widget, entry):
|
||||
@ -444,6 +445,13 @@ class RosterWindow(Adw.ApplicationWindow):
|
||||
# Smart loading: replaces empty tabs or creates new tab if modified
|
||||
self._load_request_from_entry(entry)
|
||||
|
||||
def _on_history_delete_requested(self, widget, entry):
|
||||
"""Handle delete request from history item."""
|
||||
# Delete the entry from history
|
||||
self.history_manager.delete_entry(entry)
|
||||
# Refresh the history panel
|
||||
self._load_history()
|
||||
|
||||
def _load_request_from_entry(self, entry):
|
||||
"""Load request from history entry - smart loading based on current tab state."""
|
||||
request = entry.request
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user