[gnome-terminal] window: Add option to decode timestamps in context menu
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-terminal] window: Add option to decode timestamps in context menu
- Date: Tue, 17 Nov 2020 20:45:59 +0000 (UTC)
commit 59886f9e7d2b2447c1c52cd23d866d9a531581ae
Author: Christian Persch <chpe src gnome org>
Date: Tue Nov 17 21:45:10 2020 +0100
window: Add option to decode timestamps in context menu
Based on a patch by Egmont Koblinger <egmont gmail com>.
https://bugzilla.gnome.org/show_bug.cgi?id=757540
src/org.gnome.Terminal.gschema.xml | 5 ++++
src/terminal-libgsystem.h | 10 +++++++
src/terminal-schemas.h | 1 +
src/terminal-screen.c | 21 ++++++++++----
src/terminal-screen.h | 1 +
src/terminal-util.c | 59 +++++++++++++++++++++++++++++++-------
src/terminal-util.h | 1 +
src/terminal-window.c | 30 +++++++++++++++----
8 files changed, 105 insertions(+), 23 deletions(-)
---
diff --git a/src/org.gnome.Terminal.gschema.xml b/src/org.gnome.Terminal.gschema.xml
index be00aa2d..1a629341 100644
--- a/src/org.gnome.Terminal.gschema.xml
+++ b/src/org.gnome.Terminal.gschema.xml
@@ -669,6 +669,11 @@
<summary>Whether to ask for confirmation before closing a terminal</summary>
</key>
+ <key name="context-info" type="as">
+ <default>['numbers']</default>
+ <summary>Additional info section items to appear in the context menu</summary>
+ </key>
+
<key name="default-show-menubar" type="b">
<default>true</default>
<summary>Whether to show the menubar in new windows</summary>
diff --git a/src/terminal-libgsystem.h b/src/terminal-libgsystem.h
index 906a127d..4c84dc30 100644
--- a/src/terminal-libgsystem.h
+++ b/src/terminal-libgsystem.h
@@ -51,6 +51,7 @@ G_BEGIN_DECLS
GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free)
+GS_DEFINE_CLEANUP_FUNCTION0(GDateTime*, gs_local_date_time_unref, g_date_time_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free)
GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, gs_local_key_file_unref, g_key_file_unref)
@@ -164,6 +165,15 @@ static inline void gs_local_gstring_free (void *v) \
*/
#define gs_free_checksum __attribute__ ((cleanup(gs_local_checksum_free)))
+/**
+ * gs_unref_date_time:
+ *
+ * Call g_date_time_free() on a variable location when it goes out
+ * of scope. Note that unlike g_date_time_free(), the variable may
+ * be %NULL.
+ */
+#define gs_unref_date_time __attribute__ ((cleanup(gs_local_date_time_unref)))
+
/**
* gs_unref_bytes:
*
diff --git a/src/terminal-schemas.h b/src/terminal-schemas.h
index cffc4ed8..08b6e85f 100644
--- a/src/terminal-schemas.h
+++ b/src/terminal-schemas.h
@@ -77,6 +77,7 @@ G_BEGIN_DECLS
#define TERMINAL_PROFILE_WORD_CHAR_EXCEPTIONS_KEY "word-char-exceptions"
#define TERMINAL_SETTING_CONFIRM_CLOSE_KEY "confirm-close"
+#define TERMINAL_SETTING_CONTEXT_INFO_KEY "context-info"
#define TERMINAL_SETTING_DEFAULT_SHOW_MENUBAR_KEY "default-show-menubar"
#define TERMINAL_SETTING_ENABLE_MENU_BAR_ACCEL_KEY "menu-accelerator-enabled"
#define TERMINAL_SETTING_ENABLE_MNEMONICS_KEY "mnemonics-enabled"
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 844b563c..f44de43a 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -163,7 +163,8 @@ static char* terminal_screen_check_hyperlink (TerminalScreen *scree
GdkEvent *event);
static void terminal_screen_check_extra (TerminalScreen *screen,
GdkEvent *event,
- char **number_info);
+ char **number_info,
+ char **timestamp_info);
static char* terminal_screen_check_match (TerminalScreen *screen,
GdkEvent *event,
int *flavor);
@@ -1683,6 +1684,7 @@ terminal_screen_popup_info_unref (TerminalScreenPopupInfo *info)
g_free (info->hyperlink);
g_free (info->url);
g_free (info->number_info);
+ g_free (info->timestamp_info);
g_slice_free (TerminalScreenPopupInfo, info);
}
@@ -1708,7 +1710,8 @@ terminal_screen_do_popup (TerminalScreen *screen,
char *hyperlink,
char *url,
int url_flavor,
- char *number_info)
+ char *number_info,
+ char *timestamp_info)
{
TerminalScreenPopupInfo *info;
@@ -1720,6 +1723,7 @@ terminal_screen_do_popup (TerminalScreen *screen,
info->url = url; /* adopted */
info->url_flavor = url_flavor;
info->number_info = number_info; /* adopted */
+ info->timestamp_info = timestamp_info; /* adopted */
g_signal_emit (screen, signals[SHOW_POPUP_MENU], 0, info);
terminal_screen_popup_info_unref (info);
@@ -1736,13 +1740,14 @@ terminal_screen_button_press (GtkWidget *widget,
gs_free char *url = NULL;
int url_flavor = 0;
gs_free char *number_info = NULL;
+ gs_free char *timestamp_info = NULL;
guint state;
state = event->state & gtk_accelerator_get_default_mod_mask ();
hyperlink = terminal_screen_check_hyperlink (screen, (GdkEvent*)event);
url = terminal_screen_check_match (screen, (GdkEvent*)event, &url_flavor);
- terminal_screen_check_extra (screen, (GdkEvent*)event, &number_info);
+ terminal_screen_check_extra (screen, (GdkEvent*)event, &number_info, ×tamp_info);
if (hyperlink != NULL &&
(event->button == 1 || event->button == 2) &&
@@ -1783,19 +1788,21 @@ terminal_screen_button_press (GtkWidget *widget,
if (button_press_event && button_press_event (widget, event))
return TRUE;
- terminal_screen_do_popup (screen, event, hyperlink, url, url_flavor, number_info);
+ terminal_screen_do_popup (screen, event, hyperlink, url, url_flavor, number_info, timestamp_info);
hyperlink = NULL; /* adopted to the popup info */
url = NULL; /* ditto */
number_info = NULL; /* ditto */
+ timestamp_info = NULL; /* ditto */
return TRUE;
}
else if (!(event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)))
{
/* do popup on shift+right-click */
- terminal_screen_do_popup (screen, event, hyperlink, url, url_flavor, number_info);
+ terminal_screen_do_popup (screen, event, hyperlink, url, url_flavor, number_info, timestamp_info);
hyperlink = NULL; /* adopted to the popup info */
url = NULL; /* ditto */
number_info = NULL; /* ditto */
+ timestamp_info = NULL; /* ditto */
return TRUE;
}
}
@@ -2163,7 +2170,8 @@ terminal_screen_check_match (TerminalScreen *screen,
static void
terminal_screen_check_extra (TerminalScreen *screen,
GdkEvent *event,
- char **number_info)
+ char **number_info,
+ char **timestamp_info)
{
guint i;
char **matches;
@@ -2191,6 +2199,7 @@ terminal_screen_check_extra (TerminalScreen *screen,
if (!flavor_number_found)
{
*number_info = terminal_util_number_info (matches[i]);
+ *timestamp_info = terminal_util_timestamp_info (matches[i]);
flavor_number_found = TRUE;
}
g_free (matches[i]);
diff --git a/src/terminal-screen.h b/src/terminal-screen.h
index 8ea33786..df59b1a5 100644
--- a/src/terminal-screen.h
+++ b/src/terminal-screen.h
@@ -150,6 +150,7 @@ struct _TerminalScreenPopupInfo {
TerminalURLFlavor url_flavor;
char *hyperlink;
char *number_info;
+ char *timestamp_info;
guint button;
guint state;
guint32 timestamp;
diff --git a/src/terminal-util.c b/src/terminal-util.c
index 3155e3f4..d4b6f80a 100644
--- a/src/terminal-util.c
+++ b/src/terminal-util.c
@@ -1030,22 +1030,21 @@ terminal_util_number_info (const char *str)
gs_free char *hextmp = NULL;
gs_free char *hexstr = NULL;
gs_free char *magnitudestr = NULL;
- unsigned long long num;
gboolean exact = TRUE;
gboolean hex = FALSE;
const char *thousep;
- errno = 0;
/* Deliberately not handle octal */
- if (str[1] == 'x' || str[1] == 'X') {
- num = strtoull(str + 2, NULL, 16);
+ if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
+ str += 2;
hex = TRUE;
- } else {
- num = strtoull(str, NULL, 10);
}
- if (errno) {
+
+ errno = 0;
+ char* end;
+ gint64 num = g_ascii_strtoull(str, &end, hex ? 16 : 10);
+ if (errno || str == end || num == -1)
return NULL;
- }
/* No use in dec-hex conversion for so small numbers */
if (num < 10) {
@@ -1057,18 +1056,18 @@ terminal_util_number_info (const char *str)
if (thousep[0] != '\0') {
/* If thousep is nonempty, use printf's magic which can handle
more complex separating logics, e.g. 2+2+2+3 for some locales */
- decstr = g_strdup_printf("%'llu", num);
+ decstr = g_strdup_printf("%'" G_GINT64_FORMAT, num);
} else {
/* If, however, thousep is empty, override it with a space so that we
do always group the digits (that's the whole point of this feature;
the choice of space guarantees not conflicting with the decimal separator) */
- gs_free char *tmp = g_strdup_printf("%llu", num);
+ gs_free char *tmp = g_strdup_printf("%" G_GINT64_FORMAT, num);
thousep = " ";
decstr = add_separators(tmp, thousep, 3);
}
/* Group the hex digits by 4 using the same nonempty separator */
- hextmp = g_strdup_printf("%llx", num);
+ hextmp = g_strdup_printf("%" G_GINT64_MODIFIER "x", (guint64)(num));
hexstr = add_separators(hextmp, thousep, 4);
/* Find out the human-readable magnitude, e.g. 15.99 Mi */
@@ -1093,6 +1092,44 @@ terminal_util_number_info (const char *str)
return g_strdup_printf(hex ? "0x%2$s = %1$s%3$s" : "%s = 0x%s%s", decstr, hexstr, magnitudestr);
}
+/**
+ * terminal_util_timestamp_info:
+ * @str: a dec or hex number as string
+ *
+ * Returns: (transfer full): Formatted localtime if @str is decimal and looks like a timestamp, or %NULL
+ */
+char *
+terminal_util_timestamp_info (const char *str)
+{
+ /* Bail out on hex numbers */
+ if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
+ return NULL;
+ }
+
+ /* Deliberately not handle octal */
+ errno = 0;
+ char* end;
+ gint64 num = g_ascii_strtoull (str, &end, 10);
+ if (errno || end == str || num == -1)
+ return NULL;
+
+ /* Java uses Unix time in milliseconds. */
+ if (num >= 1000000000000 && num <= 1999999999999)
+ num /= 1000;
+
+ /* Fun: use inclusive interval so you can right-click on these numbers
+ * and check the human-readable time in gnome-terminal.
+ * (They're Sep 9 2001 and May 18 2033 by the way.) */
+ if (num < 1000000000 || num > 1999999999)
+ return NULL;
+
+ gs_unref_date_time GDateTime* date = g_date_time_new_from_unix_utc (num);
+ if (date == NULL)
+ return NULL;
+
+ return g_date_time_format(date, "%c");
+}
+
/**
* terminal_util_uri_fixup:
* @uri: The URI to verify and maybe fixup
diff --git a/src/terminal-util.h b/src/terminal-util.h
index 0f3e6bfa..07c9470a 100644
--- a/src/terminal-util.h
+++ b/src/terminal-util.h
@@ -93,6 +93,7 @@ void terminal_g_settings_set_rgba_palette (GSettings *settings,
void terminal_util_bind_mnemonic_label_sensitivity (GtkWidget *widget);
char *terminal_util_number_info (const char *str);
+char *terminal_util_timestamp_info (const char *str);
char *terminal_util_uri_fixup (const char *uri,
GError **error);
diff --git a/src/terminal-window.c b/src/terminal-window.c
index 7a8953c5..0bed828e 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -1727,14 +1727,32 @@ screen_show_popup_menu_cb (TerminalScreen *screen,
}
/* Info section */
- if (info->number_info != NULL) {
- gs_unref_object GMenu *section3 = g_menu_new ();
- /* Non-existent action will make this item insensitive */
- gs_unref_object GMenuItem *item3 = g_menu_item_new (info->number_info, "win.notexist");
- g_menu_append_item (section3, item3);
- g_menu_append_section (menu, NULL, G_MENU_MODEL (section3));
+ gs_strfreev char** citems = g_settings_get_strv (terminal_app_get_global_settings (terminal_app_get ()),
+ TERMINAL_SETTING_CONTEXT_INFO_KEY);
+
+ gs_unref_object GMenu *section3 = g_menu_new ();
+
+ for (int i = 0; citems[i] != NULL; ++i) {
+ const char *citem = citems[i];
+
+ if (g_str_equal (citem, "numbers") &&
+ info->number_info != NULL) {
+ /* Non-existent action will make this item insensitive */
+ gs_unref_object GMenuItem *item3 = g_menu_item_new (info->number_info, "win.notexist");
+ g_menu_append_item (section3, item3);
+ }
+
+ if (g_str_equal (citem, "timestamps") &&
+ info->timestamp_info != NULL) {
+ /* Non-existent action will make this item insensitive */
+ gs_unref_object GMenuItem *item3 = g_menu_item_new (info->timestamp_info, "win.notexist");
+ g_menu_append_item (section3, item3);
+ }
}
+ if (g_menu_model_get_n_items(G_MENU_MODEL (section3)) > 0)
+ g_menu_append_section (menu, NULL, G_MENU_MODEL (section3));
+
/* Clipboard section */
gs_unref_object GMenu *section4 = g_menu_new ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]