mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-09-29 20:44:17 +00:00
network-address-bar: Recycle widgetry (step 2/2)
The new design for Network view uses an address entry bar which is similar to the one from Other Locations view. Instead of reinventing the wheel, let's salvage some code. In addition to formatting the code to nautilus style, this also makes a couple of visual changes to match the design requests. https://gitlab.gnome.org/GNOME/nautilus/-/issues/2785
This commit is contained in:
parent
2e59a031c1
commit
62c4a979ba
|
@ -42,6 +42,7 @@ src/nautilus-location-banner.c
|
|||
src/nautilus-location-entry.c
|
||||
src/nautilus-main.c
|
||||
src/nautilus-mime-actions.c
|
||||
src/nautilus-network-address-bar.c
|
||||
src/nautilus-new-folder-dialog.c
|
||||
src/nautilus-operations-ui-manager.c
|
||||
src/nautilus-pathbar.c
|
||||
|
@ -80,6 +81,7 @@ src/resources/ui/nautilus-files-view.ui
|
|||
src/resources/ui/nautilus-grid-cell.ui
|
||||
src/resources/ui/nautilus-history-controls.ui
|
||||
src/resources/ui/nautilus-name-cell.ui
|
||||
src/resources/ui/nautilus-network-address-bar.ui
|
||||
src/resources/ui/nautilus-operations-ui-manager-request-passphrase.ui
|
||||
src/resources/ui/nautilus-pathbar-context-menu.ui
|
||||
src/resources/ui/nautilus-preferences-window.ui
|
||||
|
|
|
@ -79,8 +79,6 @@ struct _NautilusGtkPlacesView
|
|||
char *search_query;
|
||||
|
||||
GtkWidget *actionbar;
|
||||
GtkWidget *address_entry;
|
||||
GtkWidget *connect_button;
|
||||
GtkWidget *listbox;
|
||||
GtkWidget *popup_menu;
|
||||
GtkWidget *recent_servers_listbox;
|
||||
|
@ -88,7 +86,6 @@ struct _NautilusGtkPlacesView
|
|||
GtkWidget *recent_servers_stack;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *server_adresses_popover;
|
||||
GtkWidget *available_protocols_grid;
|
||||
GtkWidget *network_placeholder;
|
||||
GtkWidget *network_placeholder_label;
|
||||
|
||||
|
@ -102,10 +99,6 @@ struct _NautilusGtkPlacesView
|
|||
|
||||
NautilusGtkPlacesViewRow *row_for_action;
|
||||
|
||||
guint should_open_location : 1;
|
||||
guint should_pulse_entry : 1;
|
||||
guint entry_pulse_timeout_id;
|
||||
guint connecting_to_server : 1;
|
||||
guint mounting_volume : 1;
|
||||
guint unmounting_mount : 1;
|
||||
guint fetching_networks : 1;
|
||||
|
@ -158,14 +151,6 @@ enum {
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
const char *unsupported_protocols [] =
|
||||
{
|
||||
"file", "afc", "obex", "http",
|
||||
"trash", "burn", "computer",
|
||||
"archive", "recent", "localtest",
|
||||
NULL
|
||||
};
|
||||
|
||||
static guint places_view_signals [LAST_SIGNAL] = { 0 };
|
||||
static GParamSpec *properties [LAST_PROP];
|
||||
|
||||
|
@ -180,15 +165,6 @@ emit_open_location (NautilusGtkPlacesView *view,
|
|||
g_signal_emit (view, places_view_signals[OPEN_LOCATION], 0, location, open_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_show_error_message (NautilusGtkPlacesView *view,
|
||||
char *primary_message,
|
||||
char *secondary_message)
|
||||
{
|
||||
g_signal_emit (view, places_view_signals[SHOW_ERROR_MESSAGE],
|
||||
0, primary_message, secondary_message);
|
||||
}
|
||||
|
||||
static void
|
||||
server_file_changed_cb (NautilusGtkPlacesView *view)
|
||||
{
|
||||
|
@ -401,9 +377,6 @@ nautilus_gtk_places_view_finalize (GObject *object)
|
|||
{
|
||||
NautilusGtkPlacesView *view = (NautilusGtkPlacesView *)object;
|
||||
|
||||
if (view->entry_pulse_timeout_id > 0)
|
||||
g_source_remove (view->entry_pulse_timeout_id);
|
||||
|
||||
g_clear_pointer (&view->search_query, g_free);
|
||||
g_clear_object (&view->server_list_file);
|
||||
g_clear_object (&view->server_list_monitor);
|
||||
|
@ -1180,102 +1153,6 @@ update_places (NautilusGtkPlacesView *view)
|
|||
update_loading (view);
|
||||
}
|
||||
|
||||
static void
|
||||
server_mount_ready_cb (GObject *source_file,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusGtkPlacesView *view = NAUTILUS_GTK_PLACES_VIEW (user_data);
|
||||
gboolean should_show;
|
||||
GError *error;
|
||||
GFile *location;
|
||||
|
||||
location = G_FILE (source_file);
|
||||
should_show = TRUE;
|
||||
error = NULL;
|
||||
|
||||
g_file_mount_enclosing_volume_finish (location, res, &error);
|
||||
if (error)
|
||||
{
|
||||
should_show = FALSE;
|
||||
|
||||
if (error->code == G_IO_ERROR_ALREADY_MOUNTED)
|
||||
{
|
||||
/*
|
||||
* Already mounted volume is not a critical error
|
||||
* and we can still continue with the operation.
|
||||
*/
|
||||
should_show = TRUE;
|
||||
}
|
||||
else if (error->domain != G_IO_ERROR ||
|
||||
(error->code != G_IO_ERROR_CANCELLED &&
|
||||
error->code != G_IO_ERROR_FAILED_HANDLED))
|
||||
{
|
||||
/* if it wasn't cancelled show a dialog */
|
||||
emit_show_error_message (view, _("Unable to access location"), error->message);
|
||||
}
|
||||
|
||||
/* The operation got cancelled by the user and or the error
|
||||
has been handled already. */
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
if (view->destroyed)
|
||||
{
|
||||
g_object_unref (view);
|
||||
return;
|
||||
}
|
||||
|
||||
view->should_pulse_entry = FALSE;
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (view->address_entry), 0);
|
||||
|
||||
/* Restore from Cancel to Connect */
|
||||
gtk_button_set_label (GTK_BUTTON (view->connect_button), _("Con_nect"));
|
||||
gtk_widget_set_sensitive (view->address_entry, TRUE);
|
||||
view->connecting_to_server = FALSE;
|
||||
|
||||
if (should_show)
|
||||
{
|
||||
server_list_add_server (view, location);
|
||||
|
||||
/*
|
||||
* Only clear the entry if it successfully connects to the server.
|
||||
* Otherwise, the user would lost the typed address even if it fails
|
||||
* to connect.
|
||||
*/
|
||||
gtk_editable_set_text (GTK_EDITABLE (view->address_entry), "");
|
||||
|
||||
if (view->should_open_location)
|
||||
{
|
||||
GMount *mount;
|
||||
GFile *root;
|
||||
|
||||
/*
|
||||
* If the mount is not found at this point, it is probably user-
|
||||
* invisible, which happens e.g for smb-browse, but the location
|
||||
* should be opened anyway...
|
||||
*/
|
||||
mount = g_file_find_enclosing_mount (location, view->cancellable, NULL);
|
||||
if (mount)
|
||||
{
|
||||
root = g_mount_get_default_location (mount);
|
||||
|
||||
emit_open_location (view, root, view->open_flags);
|
||||
|
||||
g_object_unref (root);
|
||||
g_object_unref (mount);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_open_location (view, location, view->open_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_places (view);
|
||||
g_object_unref (view);
|
||||
}
|
||||
|
||||
static void
|
||||
volume_mount_ready_cb (GObject *source_volume,
|
||||
GAsyncResult *res,
|
||||
|
@ -1385,32 +1262,6 @@ unmount_ready_cb (GObject *source_mount,
|
|||
g_object_unref (view);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pulse_entry_cb (gpointer user_data)
|
||||
{
|
||||
NautilusGtkPlacesView *view = NAUTILUS_GTK_PLACES_VIEW (user_data);
|
||||
|
||||
if (view->destroyed)
|
||||
{
|
||||
view->entry_pulse_timeout_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
else if (view->should_pulse_entry)
|
||||
{
|
||||
gtk_entry_progress_pulse (GTK_ENTRY (view->address_entry));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (view->address_entry), 0);
|
||||
view->entry_pulse_timeout_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unmount_mount (NautilusGtkPlacesView *view,
|
||||
GMount *mount)
|
||||
|
@ -1439,51 +1290,6 @@ unmount_mount (NautilusGtkPlacesView *view,
|
|||
g_object_unref (operation);
|
||||
}
|
||||
|
||||
static void
|
||||
mount_server (NautilusGtkPlacesView *view,
|
||||
GFile *location)
|
||||
{
|
||||
GMountOperation *operation;
|
||||
GtkWidget *toplevel;
|
||||
|
||||
g_cancellable_cancel (view->cancellable);
|
||||
g_clear_object (&view->cancellable);
|
||||
/* User cliked when the operation was ongoing, so wanted to cancel it */
|
||||
if (view->connecting_to_server)
|
||||
return;
|
||||
|
||||
view->cancellable = g_cancellable_new ();
|
||||
toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (view)));
|
||||
operation = gtk_mount_operation_new (GTK_WINDOW (toplevel));
|
||||
|
||||
view->should_pulse_entry = TRUE;
|
||||
gtk_entry_set_progress_pulse_step (GTK_ENTRY (view->address_entry), 0.1);
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (view->address_entry), 0.1);
|
||||
/* Allow to cancel the operation */
|
||||
gtk_button_set_label (GTK_BUTTON (view->connect_button), _("Cance_l"));
|
||||
gtk_widget_set_sensitive (view->address_entry, FALSE);
|
||||
view->connecting_to_server = TRUE;
|
||||
update_loading (view);
|
||||
|
||||
if (view->entry_pulse_timeout_id == 0)
|
||||
view->entry_pulse_timeout_id = g_timeout_add (100, (GSourceFunc) pulse_entry_cb, view);
|
||||
|
||||
g_mount_operation_set_password_save (operation, G_PASSWORD_SAVE_FOR_SESSION);
|
||||
|
||||
/* make sure we keep the view around for as long as we are running */
|
||||
g_object_ref (view);
|
||||
|
||||
g_file_mount_enclosing_volume (location,
|
||||
0,
|
||||
operation,
|
||||
view->cancellable,
|
||||
server_mount_ready_cb,
|
||||
view);
|
||||
|
||||
/* unref operation here - g_file_mount_enclosing_volume() does ref for itself */
|
||||
g_object_unref (operation);
|
||||
}
|
||||
|
||||
static void
|
||||
mount_volume (NautilusGtkPlacesView *view,
|
||||
GVolume *volume)
|
||||
|
@ -1612,77 +1418,6 @@ unmount_cb (GtkWidget *widget,
|
|||
unmount_mount (view, mount);
|
||||
}
|
||||
|
||||
static void
|
||||
attach_protocol_row_to_grid (GtkGrid *grid,
|
||||
const char *protocol_name,
|
||||
const char *protocol_prefix)
|
||||
{
|
||||
GtkWidget *name_label;
|
||||
GtkWidget *prefix_label;
|
||||
|
||||
name_label = gtk_label_new (protocol_name);
|
||||
gtk_widget_set_halign (name_label, GTK_ALIGN_START);
|
||||
gtk_grid_attach_next_to (grid, name_label, NULL, GTK_POS_BOTTOM, 1, 1);
|
||||
|
||||
prefix_label = gtk_label_new (protocol_prefix);
|
||||
gtk_widget_set_halign (prefix_label, GTK_ALIGN_START);
|
||||
gtk_grid_attach_next_to (grid, prefix_label, name_label, GTK_POS_RIGHT, 1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_available_protocols_grid (GtkGrid *grid)
|
||||
{
|
||||
const char * const *supported_protocols;
|
||||
gboolean has_any = FALSE;
|
||||
|
||||
supported_protocols = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
|
||||
|
||||
if (g_strv_contains (supported_protocols, "afp"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("AppleTalk"), "afp://");
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "ftp"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("File Transfer Protocol"),
|
||||
/* Translators: do not translate ftp:// and ftps:// */
|
||||
_("ftp:// or ftps://"));
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "nfs"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("Network File System"), "nfs://");
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "smb"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("Samba"), "smb://");
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "ssh"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("SSH File Transfer Protocol"),
|
||||
/* Translators: do not translate sftp:// and ssh:// */
|
||||
_("sftp:// or ssh://"));
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "dav"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("WebDAV"),
|
||||
/* Translators: do not translate dav:// and davs:// */
|
||||
_("dav:// or davs://"));
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (!has_any)
|
||||
gtk_widget_set_visible (GTK_WIDGET (grid), FALSE);
|
||||
}
|
||||
|
||||
static GMenuModel *
|
||||
get_menu_model (void)
|
||||
{
|
||||
|
@ -1920,71 +1655,6 @@ on_eject_button_clicked (GtkWidget *widget,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_connect_button_clicked (NautilusGtkPlacesView *view)
|
||||
{
|
||||
const char *uri;
|
||||
GFile *file;
|
||||
|
||||
file = NULL;
|
||||
|
||||
/*
|
||||
* Since the 'Connect' button is updated whenever the typed
|
||||
* address changes, it is sufficient to check if it's sensitive
|
||||
* or not, in order to determine if the given address is valid.
|
||||
*/
|
||||
if (!gtk_widget_get_sensitive (view->connect_button))
|
||||
return;
|
||||
|
||||
uri = gtk_editable_get_text (GTK_EDITABLE (view->address_entry));
|
||||
|
||||
if (uri != NULL && uri[0] != '\0')
|
||||
file = g_file_new_for_commandline_arg (uri);
|
||||
|
||||
if (file)
|
||||
{
|
||||
view->should_open_location = TRUE;
|
||||
|
||||
mount_server (view, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_show_error_message (view, _("Unable to get remote server location"), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_address_entry_text_changed (NautilusGtkPlacesView *view)
|
||||
{
|
||||
const char * const *supported_protocols;
|
||||
char *address, *scheme;
|
||||
gboolean supported;
|
||||
|
||||
supported = FALSE;
|
||||
supported_protocols = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
|
||||
address = g_strdup (gtk_editable_get_text (GTK_EDITABLE (view->address_entry)));
|
||||
scheme = g_uri_parse_scheme (address);
|
||||
|
||||
if (!supported_protocols)
|
||||
goto out;
|
||||
|
||||
if (!scheme)
|
||||
goto out;
|
||||
|
||||
supported = g_strv_contains (supported_protocols, scheme) &&
|
||||
!g_strv_contains (unsupported_protocols, scheme);
|
||||
|
||||
out:
|
||||
gtk_widget_set_sensitive (view->connect_button, supported);
|
||||
if (scheme && !supported)
|
||||
gtk_widget_add_css_class (view->address_entry, "error");
|
||||
else
|
||||
gtk_widget_remove_css_class (view->address_entry, "error");
|
||||
|
||||
g_free (address);
|
||||
g_free (scheme);
|
||||
}
|
||||
|
||||
static void
|
||||
on_address_entry_show_help_pressed (NautilusGtkPlacesView *view,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
|
@ -2254,16 +1924,6 @@ nautilus_gtk_places_view_constructed (GObject *object)
|
|||
object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_gtk_places_view_map (GtkWidget *widget)
|
||||
{
|
||||
NautilusGtkPlacesView *view = NAUTILUS_GTK_PLACES_VIEW (widget);
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (view->address_entry), "");
|
||||
|
||||
GTK_WIDGET_CLASS (nautilus_gtk_places_view_parent_class)->map (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_gtk_places_view_class_init (NautilusGtkPlacesViewClass *klass)
|
||||
{
|
||||
|
@ -2276,8 +1936,6 @@ nautilus_gtk_places_view_class_init (NautilusGtkPlacesViewClass *klass)
|
|||
object_class->get_property = nautilus_gtk_places_view_get_property;
|
||||
object_class->set_property = nautilus_gtk_places_view_set_property;
|
||||
|
||||
widget_class->map = nautilus_gtk_places_view_map;
|
||||
|
||||
/*
|
||||
* NautilusGtkPlacesView::open-location:
|
||||
* @view: the object which received the signal.
|
||||
|
@ -2351,21 +2009,15 @@ nautilus_gtk_places_view_class_init (NautilusGtkPlacesViewClass *klass)
|
|||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/nautilus/gtk/ui/nautilusgtkplacesview.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, actionbar);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, address_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, address_entry_completion);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, completion_store);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, connect_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, listbox);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, recent_servers_listbox);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, recent_servers_popover);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, recent_servers_stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, server_adresses_popover);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesView, available_protocols_grid);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_address_entry_text_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_address_entry_show_help_pressed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_connect_button_clicked);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_listbox_row_activated);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_recent_servers_listbox_row_activated);
|
||||
|
||||
|
@ -2458,8 +2110,6 @@ nautilus_gtk_places_view_init (NautilusGtkPlacesView *self)
|
|||
g_signal_connect (controller, "released",
|
||||
G_CALLBACK (on_middle_click_row_event), self);
|
||||
gtk_widget_add_controller (self->listbox, controller);
|
||||
|
||||
populate_available_protocols_grid (GTK_GRID (self->available_protocols_grid));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -165,6 +165,8 @@ libnautilus_sources = [
|
|||
'nautilus-filename-validator.h',
|
||||
'nautilus-rename-file-popover.c',
|
||||
'nautilus-rename-file-popover.h',
|
||||
'nautilus-network-address-bar.c',
|
||||
'nautilus-network-address-bar.h',
|
||||
'nautilus-network-directory.c',
|
||||
'nautilus-network-directory.h',
|
||||
'nautilus-new-folder-dialog.c',
|
||||
|
|
377
src/nautilus-network-address-bar.c
Normal file
377
src/nautilus-network-address-bar.c
Normal file
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
* Copyright (C) 2022 António Fernandes <antoniof@gnome.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "nautilus-network-address-bar.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
struct _NautilusNetworkAddressBar
|
||||
{
|
||||
GtkBox parent_instance;
|
||||
|
||||
GtkWidget *address_entry;
|
||||
GtkWidget *connect_button;
|
||||
GtkWidget *available_protocols_grid;
|
||||
|
||||
gboolean should_open_location;
|
||||
gboolean should_pulse_entry;
|
||||
gboolean connecting_to_server;
|
||||
guint entry_pulse_timeout_id;
|
||||
|
||||
GCancellable *cancellable;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NautilusNetworkAddressBar, nautilus_network_address_bar, GTK_TYPE_BOX)
|
||||
|
||||
const char *unsupported_protocols[] =
|
||||
{
|
||||
"afc", "archive", "burn", "computer", "file", "http", "localtest", "obex", "recent", "trash", NULL
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
show_error_message (NautilusNetworkAddressBar *self,
|
||||
const gchar *primary,
|
||||
const gchar *secondary)
|
||||
{
|
||||
GtkRoot *window = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
GtkWidget *dialog = adw_message_dialog_new (GTK_WINDOW (window), primary, secondary);
|
||||
adw_message_dialog_add_response (ADW_MESSAGE_DIALOG (dialog), "close", _("_Close"));
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
server_mount_ready_cb (GObject *source_file,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr (NautilusNetworkAddressBar) self = NAUTILUS_NETWORK_ADDRESS_BAR (user_data);
|
||||
gboolean should_show = TRUE;
|
||||
g_autoptr (GError) error = NULL;
|
||||
GFile *location = G_FILE (source_file);
|
||||
|
||||
g_file_mount_enclosing_volume_finish (location, res, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
should_show = FALSE;
|
||||
|
||||
if (error->code == G_IO_ERROR_ALREADY_MOUNTED)
|
||||
{
|
||||
/*
|
||||
* Already mounted volume is not a critical error
|
||||
* and we can still continue with the operation.
|
||||
*/
|
||||
should_show = TRUE;
|
||||
}
|
||||
else if (error->domain != G_IO_ERROR ||
|
||||
(error->code != G_IO_ERROR_CANCELLED &&
|
||||
error->code != G_IO_ERROR_FAILED_HANDLED))
|
||||
{
|
||||
/* if it wasn't cancelled show a dialog */
|
||||
show_error_message (self, _("Unable to access location"), error->message);
|
||||
}
|
||||
|
||||
/* The operation got cancelled by the user or dispose() and or the error
|
||||
* has been handled already. */
|
||||
}
|
||||
|
||||
self->should_pulse_entry = FALSE;
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (self->address_entry), 0);
|
||||
|
||||
/* Restore from Cancel to Connect */
|
||||
gtk_button_set_label (GTK_BUTTON (self->connect_button), _("Con_nect"));
|
||||
gtk_widget_set_sensitive (self->address_entry, TRUE);
|
||||
self->connecting_to_server = FALSE;
|
||||
|
||||
if (should_show)
|
||||
{
|
||||
#if 0
|
||||
server_list_add_server (self, location);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only clear the entry if it successfully connects to the server.
|
||||
* Otherwise, the user would lost the typed address even if it fails
|
||||
* to connect.
|
||||
*/
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->address_entry), "");
|
||||
|
||||
if (self->should_open_location)
|
||||
{
|
||||
g_autofree char *uri_to_open = NULL;
|
||||
g_autoptr (GMount) mount = g_file_find_enclosing_mount (location, self->cancellable, NULL);
|
||||
|
||||
/*
|
||||
* If the mount is not found at this point, it is probably user-
|
||||
* invisible, which happens e.g for smb-browse, but the location
|
||||
* should be opened anyway...
|
||||
*/
|
||||
if (mount != NULL)
|
||||
{
|
||||
g_autoptr (GFile) root = g_mount_get_default_location (mount);
|
||||
|
||||
uri_to_open = g_file_get_uri (root);
|
||||
}
|
||||
else
|
||||
{
|
||||
uri_to_open = g_file_get_uri (location);
|
||||
}
|
||||
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"win.open-location", "s", uri_to_open);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pulse_entry_cb (gpointer user_data)
|
||||
{
|
||||
NautilusNetworkAddressBar *self = NAUTILUS_NETWORK_ADDRESS_BAR (user_data);
|
||||
|
||||
if (self->should_pulse_entry)
|
||||
{
|
||||
gtk_entry_progress_pulse (GTK_ENTRY (self->address_entry));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (self->address_entry), 0);
|
||||
self->entry_pulse_timeout_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mount_server (NautilusNetworkAddressBar *self,
|
||||
GFile *location)
|
||||
{
|
||||
GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (self)));
|
||||
g_autoptr (GMountOperation) operation = gtk_mount_operation_new (GTK_WINDOW (toplevel));
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
/* User cliked when the operation was ongoing, so wanted to cancel it */
|
||||
if (self->connecting_to_server)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->cancellable = g_cancellable_new ();
|
||||
|
||||
self->should_pulse_entry = TRUE;
|
||||
gtk_entry_set_progress_pulse_step (GTK_ENTRY (self->address_entry), 0.1);
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (self->address_entry), 0.1);
|
||||
/* Allow to cancel the operation */
|
||||
gtk_button_set_label (GTK_BUTTON (self->connect_button), _("Cance_l"));
|
||||
gtk_widget_set_sensitive (self->address_entry, FALSE);
|
||||
self->connecting_to_server = TRUE;
|
||||
|
||||
if (self->entry_pulse_timeout_id == 0)
|
||||
{
|
||||
self->entry_pulse_timeout_id = g_timeout_add (100, (GSourceFunc) pulse_entry_cb, self);
|
||||
}
|
||||
|
||||
g_mount_operation_set_password_save (operation, G_PASSWORD_SAVE_FOR_SESSION);
|
||||
|
||||
/* make sure we keep the view around for as long as we are running */
|
||||
g_file_mount_enclosing_volume (location,
|
||||
0,
|
||||
operation,
|
||||
self->cancellable,
|
||||
server_mount_ready_cb,
|
||||
g_object_ref (self));
|
||||
}
|
||||
|
||||
static void
|
||||
on_connect_button_clicked (NautilusNetworkAddressBar *self)
|
||||
{
|
||||
/* Since the 'Connect' button is updated whenever the typed
|
||||
* address changes, it is sufficient to check if it's sensitive
|
||||
* or not, in order to determine if the given address is valid.
|
||||
*/
|
||||
if (!gtk_widget_get_sensitive (self->connect_button))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const char *uri = gtk_editable_get_text (GTK_EDITABLE (self->address_entry));
|
||||
|
||||
if (uri != NULL && uri[0] != '\0')
|
||||
{
|
||||
g_autoptr (GFile) file = g_file_new_for_commandline_arg (uri);
|
||||
|
||||
self->should_open_location = TRUE;
|
||||
|
||||
mount_server (self, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
show_error_message (self, _("Unable to get remote server location"), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_address_entry_text_changed (NautilusNetworkAddressBar *self)
|
||||
{
|
||||
const char * const *supported_protocols = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
|
||||
const char *address = gtk_editable_get_text (GTK_EDITABLE (self->address_entry));
|
||||
g_autofree char *scheme = g_uri_parse_scheme (address);
|
||||
gboolean supported = FALSE;
|
||||
|
||||
if (supported_protocols != NULL && scheme != NULL)
|
||||
{
|
||||
supported = g_strv_contains (supported_protocols, scheme) &&
|
||||
!g_strv_contains (unsupported_protocols, scheme);
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (self->connect_button, supported);
|
||||
if (scheme != NULL && !supported)
|
||||
{
|
||||
gtk_widget_add_css_class (self->address_entry, "error");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_remove_css_class (self->address_entry, "error");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_map (GtkWidget *widget)
|
||||
{
|
||||
NautilusNetworkAddressBar *self = NAUTILUS_NETWORK_ADDRESS_BAR (widget);
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->address_entry), "");
|
||||
|
||||
GTK_WIDGET_CLASS (nautilus_network_address_bar_parent_class)->map (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
attach_protocol_row_to_grid (GtkGrid *grid,
|
||||
const char *protocol_name,
|
||||
const char *protocol_prefix)
|
||||
{
|
||||
GtkWidget *name_label = gtk_label_new (protocol_name);
|
||||
GtkWidget *prefix_label = gtk_label_new (protocol_prefix);
|
||||
|
||||
gtk_widget_set_halign (name_label, GTK_ALIGN_START);
|
||||
gtk_grid_attach_next_to (grid, name_label, NULL, GTK_POS_BOTTOM, 1, 1);
|
||||
|
||||
gtk_widget_set_halign (prefix_label, GTK_ALIGN_START);
|
||||
gtk_grid_attach_next_to (grid, prefix_label, name_label, GTK_POS_RIGHT, 1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_available_protocols_grid (GtkGrid *grid)
|
||||
{
|
||||
const char * const *supported_protocols = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
|
||||
gboolean has_any = FALSE;
|
||||
|
||||
if (g_strv_contains (supported_protocols, "afp"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("AppleTalk"), "afp://");
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "ftp"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("File Transfer Protocol"),
|
||||
/* Translators: do not translate ftp:// and ftps:// */
|
||||
_("ftp:// or ftps://"));
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "nfs"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("Network File System"), "nfs://");
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "smb"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("Samba"), "smb://");
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "ssh"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("SSH File Transfer Protocol"),
|
||||
/* Translators: do not translate sftp:// and ssh:// */
|
||||
_("sftp:// or ssh://"));
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "dav"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("WebDAV"),
|
||||
/* Translators: do not translate dav:// and davs:// */
|
||||
_("dav:// or davs://"));
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (!has_any)
|
||||
{
|
||||
gtk_widget_set_visible (GTK_WIDGET (grid), FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_dispose (GObject *object)
|
||||
{
|
||||
NautilusNetworkAddressBar *self = NAUTILUS_NETWORK_ADDRESS_BAR (object);
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_handle_id (&self->entry_pulse_timeout_id, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_network_address_bar_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (nautilus_network_address_bar_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_init (NautilusNetworkAddressBar *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
populate_available_protocols_grid (GTK_GRID (self->available_protocols_grid));
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_class_init (NautilusNetworkAddressBarClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = nautilus_network_address_bar_finalize;
|
||||
object_class->dispose = nautilus_network_address_bar_dispose;
|
||||
|
||||
widget_class->map = nautilus_network_address_bar_map;
|
||||
|
||||
/* Bind class to template */
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/nautilus/ui/nautilus-network-address-bar.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusNetworkAddressBar, address_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusNetworkAddressBar, connect_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusNetworkAddressBar, available_protocols_grid);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_address_entry_text_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_connect_button_clicked);
|
||||
}
|
||||
|
||||
NautilusNetworkAddressBar *
|
||||
nautilus_network_address_bar_new (void)
|
||||
{
|
||||
return g_object_new (NAUTILUS_TYPE_NETWORK_ADDRESS_BAR, NULL);
|
||||
}
|
19
src/nautilus-network-address-bar.h
Normal file
19
src/nautilus-network-address-bar.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2022 António Fernandes <antoniof@gnome.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_NETWORK_ADDRESS_BAR (nautilus_network_address_bar_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (NautilusNetworkAddressBar, nautilus_network_address_bar, NAUTILUS, NETWORK_ADDRESS_BAR, GtkBox)
|
||||
|
||||
NautilusNetworkAddressBar * nautilus_network_address_bar_new (void);
|
||||
|
||||
G_END_DECLS
|
|
@ -55,6 +55,7 @@
|
|||
#include "nautilus-global-preferences.h"
|
||||
#include "nautilus-location-entry.h"
|
||||
#include "nautilus-metadata.h"
|
||||
#include "nautilus-network-address-bar.h"
|
||||
#include "nautilus-mime-actions.h"
|
||||
#include "nautilus-module.h"
|
||||
#include "nautilus-pathbar.h"
|
||||
|
@ -118,6 +119,8 @@ struct _NautilusWindow
|
|||
GtkWidget *toolbar;
|
||||
gboolean temporary_navigation_bar;
|
||||
|
||||
GtkWidget *network_address_bar;
|
||||
|
||||
/* focus widget before the location bar has been shown temporarily */
|
||||
GtkWidget *last_focus_widget;
|
||||
|
||||
|
@ -1152,6 +1155,9 @@ nautilus_window_sync_location_widgets (NautilusWindow *window)
|
|||
|
||||
path_bar = nautilus_toolbar_get_path_bar (NAUTILUS_TOOLBAR (window->toolbar));
|
||||
nautilus_path_bar_set_path (NAUTILUS_PATH_BAR (path_bar), location);
|
||||
|
||||
gtk_widget_set_visible (window->network_address_bar,
|
||||
g_file_has_uri_scheme (location, SCHEME_NETWORK_VIEW));
|
||||
}
|
||||
|
||||
enabled = (nautilus_window_slot_get_back_history (slot) != NULL &&
|
||||
|
@ -2280,6 +2286,7 @@ nautilus_window_init (NautilusWindow *window)
|
|||
GtkEventController *controller;
|
||||
GtkPadController *pad_controller;
|
||||
|
||||
g_type_ensure (NAUTILUS_TYPE_NETWORK_ADDRESS_BAR);
|
||||
g_type_ensure (NAUTILUS_TYPE_TOOLBAR);
|
||||
g_type_ensure (NAUTILUS_TYPE_GTK_PLACES_SIDEBAR);
|
||||
g_type_ensure (NAUTILUS_TYPE_PROGRESS_INDICATOR);
|
||||
|
@ -2421,6 +2428,7 @@ nautilus_window_class_init (NautilusWindowClass *class)
|
|||
gtk_widget_class_bind_template_child (wclass, NautilusWindow, toast_overlay);
|
||||
gtk_widget_class_bind_template_child (wclass, NautilusWindow, tab_view);
|
||||
gtk_widget_class_bind_template_child (wclass, NautilusWindow, tab_bar);
|
||||
gtk_widget_class_bind_template_child (wclass, NautilusWindow, network_address_bar);
|
||||
|
||||
gtk_widget_class_bind_template_callback (wclass, window_set_back_forward_accelerators);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<file>ui/nautilus-operations-ui-manager-request-passphrase.ui</file>
|
||||
<file>ui/nautilus-grid-cell.ui</file>
|
||||
<file>ui/nautilus-name-cell.ui</file>
|
||||
<file>ui/nautilus-network-address-bar.ui</file>
|
||||
<file alias="gtk/ui/nautilusgtksidebarrow.ui">../gtk/nautilusgtksidebarrow.ui</file>
|
||||
<file alias="icons/filmholes.png">../../icons/filmholes.png</file>
|
||||
<file>style.css</file>
|
||||
|
|
|
@ -1,33 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkListStore" id="completion_store">
|
||||
<columns>
|
||||
<column type="gchararray"/>
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkEntryCompletion" id="address_entry_completion">
|
||||
<property name="model">completion_store</property>
|
||||
<property name="text-column">1</property>
|
||||
<property name="inline-completion">1</property>
|
||||
<property name="popup-completion">0</property>
|
||||
</object>
|
||||
<object class="GtkPopover" id="server_adresses_popover">
|
||||
<property name="position">2</property>
|
||||
<property name="position">top</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="label" translatable="yes">Server Addresses</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
|
@ -36,9 +24,9 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="label" translatable="yes">Server addresses are made up of a protocol prefix and an address. Examples:</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="wrap">true</property>
|
||||
<property name="width-chars">40</property>
|
||||
<property name="max-width-chars">40</property>
|
||||
<property name="xalign">0</property>
|
||||
|
@ -46,9 +34,9 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="label">smb://gnome.org, ssh://192.168.0.1, ftp://[2001:db8::1]</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="wrap">true</property>
|
||||
<property name="width-chars">40</property>
|
||||
<property name="max-width-chars">40</property>
|
||||
<property name="xalign">0</property>
|
||||
|
@ -57,16 +45,16 @@
|
|||
<child>
|
||||
<object class="GtkGrid" id="available_protocols_grid">
|
||||
<property name="margin-top">12</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="label" translatable="yes">Available Protocols</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
|
@ -79,7 +67,7 @@
|
|||
<property name="label" translatable="yes">Prefix</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
|
@ -92,162 +80,40 @@
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="recent_servers_popover">
|
||||
<template class="NautilusNetworkAddressBar" parent="GtkBox">
|
||||
<property name="hexpand">true</property>
|
||||
<style>
|
||||
<class name="toolbar"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkStack" id="recent_servers_stack">
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">empty</property>
|
||||
<property name="child">
|
||||
<object class="AdwStatusPage">
|
||||
<property name="icon-name">network-server-symbolic</property>
|
||||
<property name="title" translatable="yes" comments="Translators: Server as any successfully connected network address">No Recent Servers</property>
|
||||
<style>
|
||||
<class name="compact"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">list</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">1</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Recent Servers</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="vexpand">1</property>
|
||||
<property name="has-frame">1</property>
|
||||
<property name="min-content-width">250</property>
|
||||
<property name="min-content-height">200</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkListBox" id="recent_servers_listbox">
|
||||
<property name="selection-mode">0</property>
|
||||
<signal name="row-activated" handler="on_recent_servers_listbox_row_activated" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<template class="NautilusGtkPlacesView" parent="GtkBox">
|
||||
<accessibility>
|
||||
<property name="label" translatable="yes">Other Locations</property>
|
||||
<property name="description" translatable="yes">List of common local and remote mountpoints.</property>
|
||||
</accessibility>
|
||||
<property name="orientation">1</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="vhomogeneous">0</property>
|
||||
<property name="transition-type">1</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">browse</property>
|
||||
<property name="child">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkListBox" id="listbox">
|
||||
<property name="selection-mode">0</property>
|
||||
<signal name="row-activated" handler="on_listbox_row_activated" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">empty-search</property>
|
||||
<property name="child">
|
||||
<object class="AdwStatusPage">
|
||||
<property name="icon-name">edit-find-symbolic</property>
|
||||
<property name="title" translatable="yes">No Results Found</property>
|
||||
<property name="description" translatable="yes">Try a different search.</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkEntry" id="address_entry">
|
||||
<property name="input-purpose">url</property>
|
||||
<property name="input-hints">no-spellcheck | no-emoji</property>
|
||||
<property name="width-chars">10</property>
|
||||
<property name="max-width-chars">34</property>
|
||||
<property name="placeholder-text" translatable="yes">Server address</property>
|
||||
<signal name="notify::text" handler="on_address_entry_text_changed" object="NautilusNetworkAddressBar" swapped="yes"/>
|
||||
<signal name="activate" handler="on_connect_button_clicked" object="NautilusNetworkAddressBar" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator"/>
|
||||
<object class="GtkButton" id="connect_button">
|
||||
<property name="label" translatable="yes">Con_nect</property>
|
||||
<property name="use-underline">true</property>
|
||||
<property name="can-shrink">true</property>
|
||||
<property name="sensitive">false</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="clicked" handler="on_connect_button_clicked" object="NautilusNetworkAddressBar" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="actionbar">
|
||||
<property name="hexpand">1</property>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">server_adresses_popover</property>
|
||||
<property name="icon-name">dialog-question-symbolic</property>
|
||||
<style>
|
||||
<class name="toolbar"/>
|
||||
<class name="flat"/>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkEntry" id="address_entry">
|
||||
<property name="width-chars">10</property>
|
||||
<property name="max-width-chars">34</property>
|
||||
<property name="placeholder-text" translatable="yes">Enter server address…</property>
|
||||
<property name="secondary-icon-name">dialog-question-symbolic</property>
|
||||
<property name="completion">address_entry_completion</property>
|
||||
<property name="input-purpose">url</property>
|
||||
<property name="input-hints">no-spellcheck | no-emoji</property>
|
||||
<signal name="notify::text" handler="on_address_entry_text_changed" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
<signal name="activate" handler="on_connect_button_clicked" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
<signal name="icon-press" handler="on_address_entry_show_help_pressed" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="server_list_button">
|
||||
<property name="direction">0</property>
|
||||
<property name="popover">recent_servers_popover</property>
|
||||
<property name="icon-name">pan-down-symbolic</property>
|
||||
<style>
|
||||
<class name="server-list-button"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="connect_button">
|
||||
<property name="label" translatable="yes">Con_nect</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="can-shrink">true</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="valign">3</property>
|
||||
<signal name="clicked" handler="on_connect_button_clicked" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
|
|
@ -207,6 +207,11 @@
|
|||
<property name="menu-model">tab_menu_model</property>
|
||||
</object>
|
||||
</property>
|
||||
<child type="bottom">
|
||||
<object class="NautilusNetworkAddressBar" id="network_address_bar">
|
||||
<property name="visible">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="bottom">
|
||||
<object class="GtkActionBar" id="action_bar">
|
||||
<property name="revealed">False</property>
|
||||
|
|
Loading…
Reference in a new issue