diff options
author | Vivien Kraus <vivien@planete-kraus.eu> | 2023-03-12 12:20:30 +0100 |
---|---|---|
committer | Vivien Kraus <vivien@planete-kraus.eu> | 2023-03-12 19:11:24 +0100 |
commit | 258d8d016f4b1dca38cf2d03b7faa0cb09f5496f (patch) | |
tree | 309df7810985170136b4b8d465ea8ebf3c6a1c4a | |
parent | cf0a29d1d72d104d99386293ac4763619f8e0fc2 (diff) |
Add a widget to display a cache entry.
-rw-r--r-- | include/disfluid.h | 4 | ||||
-rw-r--r-- | po/POTFILES.in | 2 | ||||
-rw-r--r-- | src/adwaita/Makefile.am | 1 | ||||
-rw-r--r-- | src/adwaita/disfluid-adwaita.h | 15 | ||||
-rw-r--r-- | src/adwaita/disfluid-cache-entry.c | 249 | ||||
-rw-r--r-- | src/adwaita/disfluid-g-cache-entry.c | 9 | ||||
-rw-r--r-- | src/adwaita/disfluid-window.c | 19 | ||||
-rw-r--r-- | src/libdisfluid/disfluid-cache-entry.h | 14 |
8 files changed, 293 insertions, 20 deletions
diff --git a/include/disfluid.h b/include/disfluid.h index 3eff069..c4ddcc8 100644 --- a/include/disfluid.h +++ b/include/disfluid.h @@ -143,8 +143,8 @@ extern "C" *disfluid_cache_entry_from_fd (int fd); LIBDISFLUID_API LIBDISFLUID_DEALLOC_AS_CACHE_ENTRY - extern struct disfluid_cache_entry * - disfluid_cache_entry_dup (const struct disfluid_cache_entry *entry); + extern struct disfluid_cache_entry + *disfluid_cache_entry_dup (const struct disfluid_cache_entry *entry); LIBDISFLUID_API extern void disfluid_cache_entry_set_request_date (struct disfluid_cache_entry *entry, diff --git a/po/POTFILES.in b/po/POTFILES.in index 371f070..4397e1f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,8 +1,8 @@ desktop/eu.planete_kraus.Disfluid.Devel.desktop.in desktop/eu.planete_kraus.Disfluid.desktop.in src/adwaita/disfluid-about.c +src/adwaita/disfluid-cache-entry.c src/adwaita/disfluid-menus.c -src/adwaita/disfluid-window.c src/libdisfluid/disfluid-authors.h src/libdisfluid/disfluid-tests.h src/libdisfluid/disfluid-version.h diff --git a/src/adwaita/Makefile.am b/src/adwaita/Makefile.am index c496d47..41f0bb0 100644 --- a/src/adwaita/Makefile.am +++ b/src/adwaita/Makefile.am @@ -5,6 +5,7 @@ noinst_LTLIBRARIES += %D%/libdisfluid-adwaita.la %D%/disfluid-about.c \ %D%/disfluid-application.c \ %D%/disfluid-g-cache-entry.c \ + %D%/disfluid-cache-entry.c \ %D%/disfluid-menus.c \ %D%/disfluid-window.c diff --git a/src/adwaita/disfluid-adwaita.h b/src/adwaita/disfluid-adwaita.h index b5f6e83..e589c75 100644 --- a/src/adwaita/disfluid-adwaita.h +++ b/src/adwaita/disfluid-adwaita.h @@ -5,12 +5,13 @@ # include <glib-object.h> # include <gtk/gtk.h> # include <adwaita.h> +# include <disfluid.h> /* *INDENT-OFF* */ G_BEGIN_DECLS /* *INDENT-ON* */ -#define DISFLUID_TYPE_CACHE_ENTRY \ +# define DISFLUID_TYPE_CACHE_ENTRY \ disfluid_cache_entry_get_type () # define DISFLUID_ADW_TYPE_APPLICATION \ @@ -19,6 +20,9 @@ G_BEGIN_DECLS # define DISFLUID_ADW_TYPE_WINDOW \ disfluid_adw_window_get_type () +# define DISFLUID_ADW_TYPE_CACHE_ENTRY \ + disfluid_adw_cache_entry_get_type () + /* *INDENT-OFF* */ G_DECLARE_FINAL_TYPE (DisfluidAdwApplication, disfluid_adw_application, @@ -28,6 +32,10 @@ G_DECLARE_FINAL_TYPE (DisfluidAdwWindow, disfluid_adw_window, DISFLUID_ADW, WINDOW, AdwApplicationWindow) +G_DECLARE_FINAL_TYPE (DisfluidAdwCacheEntry, + disfluid_adw_cache_entry, + DISFLUID_ADW, CACHE_ENTRY, + AdwPreferencesGroup) G_END_DECLS /* *INDENT-ON* */ @@ -45,4 +53,9 @@ GMenuItem *disfluid_adw_menu_item_about (void); GMenu *disfluid_adw_main_menu (void); +void disfluid_adw_cache_entry_set_cache_entry (DisfluidAdwCacheEntry * + cache_entry, + struct disfluid_cache_entry + *value); + #endif /* not H_DISFLUID_ADWAITA_INCLUDED */ diff --git a/src/adwaita/disfluid-cache-entry.c b/src/adwaita/disfluid-cache-entry.c new file mode 100644 index 0000000..e0245c4 --- /dev/null +++ b/src/adwaita/disfluid-cache-entry.c @@ -0,0 +1,249 @@ +#include <config.h> + +#include "attribute.h" +#include <disfluid-adwaita.h> + +#define STREQ(a, b) (strcmp ((a), (b)) == 0) +#define STRNEQ(a, b) (! (STREQ (a, b))) + +#include <locale.h> +#include <stdio.h> +#include <unistd.h> +#include <assert.h> +#include "gettext.h" +#include "relocatable.h" + +#define _(String) dgettext (PACKAGE, (String)) +#define N_(String) (String) + +#include <disfluid.h> +#include <glib-object.h> +#include <adwaita.h> +#include <gtk/gtk.h> + +struct _DisfluidAdwCacheEntry +{ + AdwPreferencesGroup parent_instance; + struct disfluid_cache_entry *cache_entry; + GtkLabel *row_request_date; + GtkLabel *row_response_date; + GtkLabel *row_invalidation_status; +}; + +struct _DisfluidAdwCacheEntryClass +{ + AdwPreferencesGroupClass parent_instance; +}; + +/* *INDENT-OFF* */ +G_DEFINE_TYPE (DisfluidAdwCacheEntry, + disfluid_adw_cache_entry, + ADW_TYPE_PREFERENCES_GROUP) +/* *INDENT-ON* */ + +typedef enum +{ + PROP_CACHE_ENTRY = 1, + + /* ... */ + N_PROPERTIES +} DisfluidAdwCacheEntryProperty; + +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; + +static void +disfluid_adw_cache_entry_set_property (GObject * object, + guint property_id, + const GValue * value, + GParamSpec * pspec) +{ + DisfluidAdwCacheEntry *self = DISFLUID_ADW_CACHE_ENTRY (object); + switch ((DisfluidAdwCacheEntryProperty) property_id) + { + case PROP_CACHE_ENTRY: + assert (G_VALUE_TYPE (value) == DISFLUID_TYPE_CACHE_ENTRY); + disfluid_adw_cache_entry_set_cache_entry (self, + g_value_get_boxed (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +disfluid_adw_cache_entry_get_property (GObject * object, + guint property_id, + GValue * value, GParamSpec * pspec) +{ + DisfluidAdwCacheEntry *self = DISFLUID_ADW_CACHE_ENTRY (object); + switch ((DisfluidAdwCacheEntryProperty) property_id) + { + case PROP_CACHE_ENTRY: + if (self->cache_entry != NULL) + { + g_value_set_boxed (value, + disfluid_cache_entry_dup (self->cache_entry)); + } + else + { + g_value_set_boxed (value, NULL); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +disfluid_adw_cache_entry_finalize (GObject * obj) +{ + DisfluidAdwCacheEntry *self = DISFLUID_ADW_CACHE_ENTRY (obj); + disfluid_cache_entry_free (self->cache_entry); + G_OBJECT_CLASS (disfluid_adw_cache_entry_parent_class)->finalize (obj); +} + +static void +disfluid_adw_cache_entry_class_init (DisfluidAdwCacheEntryClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->set_property = disfluid_adw_cache_entry_set_property; + object_class->get_property = disfluid_adw_cache_entry_get_property; + object_class->finalize = disfluid_adw_cache_entry_finalize; + obj_properties[PROP_CACHE_ENTRY] = + g_param_spec_boxed ("cache-entry", + _("Cache entry"), _("Value of the cache entry \ +that is to be displayed by this widget"), DISFLUID_TYPE_CACHE_ENTRY, G_PARAM_READWRITE); + g_object_class_install_properties (object_class, N_PROPERTIES, + obj_properties); +} + +static void +disfluid_adw_cache_entry_init (DisfluidAdwCacheEntry * self) +{ + /* Perform default initialization of self. */ + self->cache_entry = NULL; + self->row_request_date = GTK_LABEL (gtk_label_new (_("Unset"))); + self->row_response_date = GTK_LABEL (gtk_label_new (_("Unset"))); + self->row_invalidation_status = GTK_LABEL (gtk_label_new (_("Unset"))); + GtkLabel *my_labels[3] = { self->row_request_date, self->row_response_date, + self->row_invalidation_status + }; + for (size_t i = 0; i < sizeof (my_labels) / sizeof (my_labels[0]); i++) + { + gtk_label_set_wrap (my_labels[i], true); + const int margin = 8; + gtk_widget_set_margin_top (GTK_WIDGET (my_labels[i]), margin); + gtk_widget_set_margin_bottom (GTK_WIDGET (my_labels[i]), margin); + gtk_widget_set_margin_start (GTK_WIDGET (my_labels[i]), margin); + gtk_widget_set_margin_end (GTK_WIDGET (my_labels[i]), margin); + } + GtkListBoxRow *row_request_date = + GTK_LIST_BOX_ROW (g_object_new (ADW_TYPE_PREFERENCES_ROW, + "title", _("Request date"), + "child", self->row_request_date, + "selectable", false, + NULL)); + GtkListBoxRow *row_response_date = + GTK_LIST_BOX_ROW (g_object_new (ADW_TYPE_PREFERENCES_ROW, + "title", _("Response date"), + "child", self->row_response_date, + "selectable", false, + NULL)); + GtkListBoxRow *row_invalidation_status = + GTK_LIST_BOX_ROW (g_object_new (ADW_TYPE_PREFERENCES_ROW, + "title", _("Invalidation status"), + "child", self->row_invalidation_status, + "selectable", false, + NULL)); + adw_preferences_group_set_title (ADW_PREFERENCES_GROUP (self), + _("Unknown cache entry")); + adw_preferences_group_set_description (ADW_PREFERENCES_GROUP (self), + _("Unknown URI")); + adw_preferences_group_add (ADW_PREFERENCES_GROUP (self), + GTK_WIDGET (row_request_date)); + adw_preferences_group_add (ADW_PREFERENCES_GROUP (self), + GTK_WIDGET (row_response_date)); + adw_preferences_group_add (ADW_PREFERENCES_GROUP (self), + GTK_WIDGET (row_invalidation_status)); +} + +void +disfluid_adw_cache_entry_set_cache_entry (DisfluidAdwCacheEntry * self, + struct disfluid_cache_entry *value) +{ + disfluid_cache_entry_free (self->cache_entry); + if (value != NULL) + { + self->cache_entry = disfluid_cache_entry_dup (value); + struct timespec request_ts, response_ts; + disfluid_cache_entry_get_request_date (self->cache_entry, &request_ts); + disfluid_cache_entry_get_response_date (self->cache_entry, + &response_ts); + GDateTime *request_date_gross = + g_date_time_new_from_unix_local (request_ts.tv_sec); + const double request_frac = request_ts.tv_nsec * 1e-9; + GDateTime *request_date = g_date_time_add_seconds (request_date_gross, + request_frac); + g_date_time_unref (request_date_gross); + GDateTime *response_date_gross = + g_date_time_new_from_unix_local (response_ts.tv_sec); + const double response_frac = response_ts.tv_nsec * 1e-9; + GDateTime *response_date = g_date_time_add_seconds (response_date_gross, + response_frac); + g_date_time_unref (response_date_gross); + gchar *request_format = g_date_time_format (request_date, "%c"); + gchar *response_format = g_date_time_format (response_date, "%c"); + g_date_time_unref (request_date); + g_date_time_unref (response_date); + char *request_title; + char *response_title; + char *invalidation_status_title; + /* TRANSLATORS: The argument is a date and time. */ + if (asprintf (&request_title, _("Requested %s"), request_format) < 0) + { + abort (); + } + /* TRANSLATORS: The argument is a date and time. */ + if (asprintf (&response_title, _("Responded %s"), response_format) < 0) + { + abort (); + } + if (disfluid_cache_entry_invalidated (self->cache_entry)) + { + if (asprintf + (&invalidation_status_title, + _("This response has been invalidated.")) < 0) + { + abort (); + } + } + else + { + if (asprintf + (&invalidation_status_title, + _("This response is still valid.")) < 0) + { + abort (); + } + } + g_free (request_format); + g_free (response_format); + gtk_label_set_label (self->row_request_date, request_title); + gtk_label_set_label (self->row_response_date, response_title); + gtk_label_set_label (self->row_invalidation_status, + invalidation_status_title); + g_free (request_title); + g_free (response_title); + g_free (invalidation_status_title); + } + else + { + self->cache_entry = NULL; + gtk_label_set_label (self->row_request_date, _("No content")); + gtk_label_set_label (self->row_response_date, _("No content")); + gtk_label_set_label (self->row_invalidation_status, _("No content")); + } +} diff --git a/src/adwaita/disfluid-g-cache-entry.c b/src/adwaita/disfluid-g-cache-entry.c index d7820cc..8fe7141 100644 --- a/src/adwaita/disfluid-g-cache-entry.c +++ b/src/adwaita/disfluid-g-cache-entry.c @@ -18,7 +18,8 @@ #include <glib-object.h> -G_DEFINE_BOXED_TYPE (disfluid_cache_entry, - disfluid_cache_entry, - disfluid_cache_entry_dup, - disfluid_cache_entry_free) +typedef struct disfluid_cache_entry DisfluidCacheEntry; + +G_DEFINE_BOXED_TYPE (DisfluidCacheEntry, + disfluid_cache_entry, + disfluid_cache_entry_dup, disfluid_cache_entry_free) diff --git a/src/adwaita/disfluid-window.c b/src/adwaita/disfluid-window.c index c3d1053..d1943f5 100644 --- a/src/adwaita/disfluid-window.c +++ b/src/adwaita/disfluid-window.c @@ -53,11 +53,20 @@ disfluid_adw_window_init (DisfluidAdwWindow * self) G_MENU_MODEL (main_menu)); g_object_unref (main_menu); adw_header_bar_pack_end (ADW_HEADER_BAR (header_bar), menu_button); - GtkWidget *main_page = adw_status_page_new (); - adw_status_page_set_icon_name (ADW_STATUS_PAGE (main_page), "face-smile"); - adw_status_page_set_title (ADW_STATUS_PAGE (main_page), _("Hello, world!")); - adw_status_page_set_description (ADW_STATUS_PAGE (main_page), _("\ -There is nothing here yet, please come back later.")); + struct disfluid_cache_entry *cache_entry = disfluid_cache_entry_alloc (); + if (cache_entry == NULL) + { + abort (); + } + GtkWidget *unique_content = + g_object_new (DISFLUID_ADW_TYPE_CACHE_ENTRY, NULL); + disfluid_adw_cache_entry_set_cache_entry (DISFLUID_ADW_CACHE_ENTRY + (unique_content), cache_entry); + disfluid_cache_entry_free (cache_entry); + GtkWidget *main_page = g_object_new (ADW_TYPE_PREFERENCES_PAGE, + NULL); + adw_preferences_page_add (ADW_PREFERENCES_PAGE (main_page), + ADW_PREFERENCES_GROUP (unique_content)); GtkWidget *content = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_append (GTK_BOX (content), header_bar); gtk_box_append (GTK_BOX (content), main_page); diff --git a/src/libdisfluid/disfluid-cache-entry.h b/src/libdisfluid/disfluid-cache-entry.h index 2371515..3f9123c 100644 --- a/src/libdisfluid/disfluid-cache-entry.h +++ b/src/libdisfluid/disfluid-cache-entry.h @@ -11,8 +11,8 @@ MAYBE_UNUSED static struct disfluid_cache_entry MAYBE_UNUSED static struct disfluid_cache_entry *cache_entry_from_fd (int fd); -MAYBE_UNUSED static struct disfluid_cache_entry * -cache_entry_dup (const struct disfluid_cache_entry *entry); +MAYBE_UNUSED static struct disfluid_cache_entry + *cache_entry_dup (const struct disfluid_cache_entry *entry); MAYBE_UNUSED static int cache_entry_save_other_file_name (const struct disfluid_cache_entry *entry, @@ -115,14 +115,14 @@ static struct disfluid_cache_entry * cache_entry_dup (const struct disfluid_cache_entry *entry) { struct disfluid_cache_entry *ret = cache_entry_alloc (); - if (ret != NULL) + if (ret != NULL && entry->fd >= 0) { ret->fd = dup (entry->fd); if (ret->fd < 0) - { - cache_entry_free (ret); - ret = NULL; - } + { + cache_entry_free (ret); + ret = NULL; + } } if (ret != NULL) { |