Add directory history

Not fully polished yet (see FIXME), but it's a start.
This commit is contained in:
Přemysl Eric Janouch 2021-12-19 09:59:27 +01:00
parent 39cd52905b
commit 2c46ca262b
Signed by: p
GPG Key ID: A0420B94F92B9493
1 changed files with 78 additions and 14 deletions

View File

@ -105,7 +105,9 @@ struct {
gchar **supported_globs; gchar **supported_globs;
gboolean filtering; gboolean filtering;
gchar *directory; gchar *directory; ///< Full path to the currently browsed directory
GList *directory_back; ///< History paths going backwards
GList *directory_forward; ///< History paths going forwards
GPtrArray *files; GPtrArray *files;
gint files_index; gint files_index;
@ -203,12 +205,52 @@ update_files_index(void)
g_free(basename); g_free(basename);
} }
static void
load_directory_without_reload(const gchar *dirname)
{
gchar *dirname_duplicated = g_strdup(dirname);
if (g.directory_back &&
!strcmp(dirname, g.directory_back->data)) {
// We're going back in history.
if (g.directory) {
g.directory_forward =
g_list_prepend(g.directory_forward, g.directory);
g.directory = NULL;
}
GList *link = g.directory_back;
g.directory_back = g_list_remove_link(g.directory_back, link);
g_list_free_full(link, g_free);
} else if (g.directory_forward &&
!strcmp(dirname, g.directory_forward->data)) {
// We're going forward in history.
if (g.directory) {
g.directory_back =
g_list_prepend(g.directory_back, g.directory);
g.directory = NULL;
}
GList *link = g.directory_forward;
g.directory_forward = g_list_remove_link(g.directory_forward, link);
g_list_free_full(link, g_free);
} else if (g.directory && strcmp(dirname, g.directory)) {
// We're on a new subpath.
g_list_free_full(g.directory_forward, g_free);
g.directory_forward = NULL;
g.directory_back = g_list_prepend(g.directory_back, g.directory);
g.directory = NULL;
}
g_free(g.directory);
g.directory = dirname_duplicated;
}
static void static void
load_directory(const gchar *dirname) load_directory(const gchar *dirname)
{ {
if (dirname) { if (dirname) {
g_free(g.directory); load_directory_without_reload(dirname);
g.directory = g_strdup(dirname);
GtkAdjustment *vadjustment = gtk_scrolled_window_get_vadjustment( GtkAdjustment *vadjustment = gtk_scrolled_window_get_vadjustment(
GTK_SCROLLED_WINDOW(g.browser_scroller)); GTK_SCROLLED_WINDOW(g.browser_scroller));
@ -285,6 +327,9 @@ open(const gchar *path)
g_free(uri); g_free(uri);
} }
g_list_free_full(g.directory_forward, g_free);
g.directory_forward = NULL;
g_free(g.path); g_free(g.path);
g.path = g_strdup(path); g.path = g_strdup(path);
@ -520,6 +565,22 @@ on_key_press(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
return TRUE; return TRUE;
} }
break; break;
case GDK_MOD1_MASK:
switch (event->keyval) {
case GDK_KEY_Left:
if (gtk_stack_get_visible_child(GTK_STACK(g.stack)) == g.view_box)
switch_to_browser();
else if (g.directory_back)
load_directory(g.directory_back->data);
return TRUE;
case GDK_KEY_Right:
if (g.directory_forward)
load_directory(g.directory_forward->data);
else
switch_to_view(g.path);
return TRUE;
}
break;
case 0: case 0:
switch (event->keyval) { switch (event->keyval) {
case GDK_KEY_Escape: case GDK_KEY_Escape:
@ -570,18 +631,11 @@ on_key_press_view(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event,
on_next(); on_next();
return TRUE; return TRUE;
case GDK_KEY_Tab:
case GDK_KEY_Return: case GDK_KEY_Return:
switch_to_browser(); switch_to_browser();
return TRUE; return TRUE;
} }
break; break;
case GDK_MOD1_MASK:
switch (event->keyval) {
case GDK_KEY_Left:
switch_to_browser();
return TRUE;
}
} }
return FALSE; return FALSE;
} }
@ -607,12 +661,22 @@ on_button_press_view(G_GNUC_UNUSED GtkWidget *widget, GdkEventButton *event)
} }
static gboolean static gboolean
on_button_press_browser(G_GNUC_UNUSED GtkWidget *widget, GdkEventButton *event) on_button_press_browser_paned(
G_GNUC_UNUSED GtkWidget *widget, GdkEventButton *event)
{ {
if ((event->state & gtk_accelerator_get_default_mod_mask())) if ((event->state & gtk_accelerator_get_default_mod_mask()))
return FALSE; return FALSE;
switch (event->button) { switch (event->button) {
case 8: // back
if (g.directory_back)
load_directory(g.directory_back->data);
return TRUE;
case 9: // forward case 9: // forward
// FIXME: It may be inappropriate to go to the picture,
// which may be left over from a different directory.
if (g.directory_forward)
load_directory(g.directory_forward->data);
else
switch_to_view(g.path); switch_to_view(g.path);
return TRUE; return TRUE;
default: default:
@ -954,8 +1018,6 @@ main(int argc, char *argv[])
gtk_widget_set_hexpand(g.browser, TRUE); gtk_widget_set_hexpand(g.browser, TRUE);
g_signal_connect(g.browser, "item-activated", g_signal_connect(g.browser, "item-activated",
G_CALLBACK(on_item_activated), NULL); G_CALLBACK(on_item_activated), NULL);
g_signal_connect(g.browser, "button-press-event",
G_CALLBACK(on_button_press_browser), NULL);
gtk_container_add(GTK_CONTAINER(g.browser_scroller), g.browser); gtk_container_add(GTK_CONTAINER(g.browser_scroller), g.browser);
// Christ, no, do not scroll all the way to the top on focus. // Christ, no, do not scroll all the way to the top on focus.
@ -1013,6 +1075,8 @@ main(int argc, char *argv[])
g.browser_paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); g.browser_paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
gtk_paned_add1(GTK_PANED(g.browser_paned), g.browser_sidebar); gtk_paned_add1(GTK_PANED(g.browser_paned), g.browser_sidebar);
gtk_paned_add2(GTK_PANED(g.browser_paned), g.browser_scroller); gtk_paned_add2(GTK_PANED(g.browser_paned), g.browser_scroller);
g_signal_connect(g.browser_paned, "button-press-event",
G_CALLBACK(on_button_press_browser_paned), NULL);
// TODO(p): Can we not do it here separately? // TODO(p): Can we not do it here separately?
gtk_widget_show_all(g.browser_paned); gtk_widget_show_all(g.browser_paned);