mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-06-30 23:46:35 +00:00
Compare commits
5 Commits
ea0f3e462c
...
80abefd369
Author | SHA1 | Date | |
---|---|---|---|
|
80abefd369 | ||
|
adb8aeafe9 | ||
|
e73a8e88ec | ||
|
98296d71cc | ||
|
b1d7eaf666 |
|
@ -27,6 +27,7 @@ src/nautilus-directory.c
|
|||
src/nautilus-dnd.c
|
||||
src/nautilus-error-reporting.c
|
||||
src/nautilus-file.c
|
||||
src/nautilus-file-chooser.c
|
||||
src/nautilus-file-conflict-dialog.c
|
||||
src/nautilus-filename-validator.c
|
||||
src/nautilus-file-operations.c
|
||||
|
|
|
@ -1128,23 +1128,11 @@ nautilus_application_startup (GApplication *app)
|
|||
|
||||
g_application_set_resource_base_path (G_APPLICATION (self), "/org/gnome/nautilus");
|
||||
|
||||
/* Initialize GDK display (for wayland-x11-interop protocol) before GTK does
|
||||
* it during the chain-up. */
|
||||
g_autoptr (GError) error = NULL;
|
||||
GdkDisplay *display = init_external_window_display (&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_message ("Failed to initialize display server connection: %s",
|
||||
error->message);
|
||||
}
|
||||
|
||||
/* Chain up to the GtkApplication implementation early, so that gtk_init()
|
||||
* is called for us.
|
||||
*/
|
||||
G_APPLICATION_CLASS (nautilus_application_parent_class)->startup (G_APPLICATION (self));
|
||||
|
||||
g_assert (gdk_display_get_default () == display);
|
||||
|
||||
gtk_window_set_default_icon_name (APPLICATION_ID);
|
||||
|
||||
/* initialize preferences and create the global GSettings objects */
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "nautilus-file-chooser.h"
|
||||
|
||||
#include <config.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gtk/nautilusgtkplacessidebarprivate.h"
|
||||
|
@ -18,12 +19,18 @@
|
|||
#include "nautilus-directory.h"
|
||||
#include "nautilus-enum-types.h"
|
||||
#include "nautilus-file.h"
|
||||
#include "nautilus-filename-validator.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-shortcut-manager.h"
|
||||
#include "nautilus-toolbar.h"
|
||||
#include "nautilus-view-item-filter.h"
|
||||
#include "nautilus-window-slot.h"
|
||||
|
||||
#define SELECTOR_DEFAULT_WIDTH 890
|
||||
#define NAMER_DEFAULT_WIDTH 400
|
||||
#define SELECTOR_DEFAULT_HEIGHT 550
|
||||
#define NAMER_DEFAULT_HEIGHT 360
|
||||
|
||||
struct _NautilusFileChooser
|
||||
{
|
||||
AdwWindow parent_instance;
|
||||
|
@ -38,9 +45,19 @@ struct _NautilusFileChooser
|
|||
GtkDropDown *filters_dropdown;
|
||||
GtkWidget *choices_menu_button;
|
||||
GtkWidget *read_only_checkbox;
|
||||
GtkWidget *selector_cancel_button;
|
||||
GtkWidget *selector_accept_button;
|
||||
GtkWidget *namer_view;
|
||||
GtkWidget *name_group;
|
||||
GtkWidget *name_entry;
|
||||
GtkWidget *location_row;
|
||||
GtkWidget *namer_accept_button;
|
||||
|
||||
AdwAnimation *width_animation;
|
||||
AdwAnimation *height_animation;
|
||||
|
||||
NautilusDirectory *current_directory;
|
||||
NautilusFilenameValidator *validator;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (NautilusFileChooser, nautilus_file_chooser, ADW_TYPE_WINDOW)
|
||||
|
@ -173,22 +190,10 @@ selector_can_accept (NautilusFileChooser *self,
|
|||
|
||||
static void
|
||||
emit_accepted (NautilusFileChooser *self,
|
||||
GList *files)
|
||||
GList *file_locations)
|
||||
{
|
||||
g_autolist (GFile) file_locations = NULL;
|
||||
gboolean writable = !gtk_check_button_get_active (GTK_CHECK_BUTTON (self->read_only_checkbox));
|
||||
|
||||
if (files != NULL)
|
||||
{
|
||||
file_locations = g_list_copy_deep (files, (GCopyFunc) nautilus_file_get_activation_location, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *location = nautilus_window_slot_get_location (self->slot);
|
||||
|
||||
file_locations = g_list_prepend (NULL, g_object_ref (location));
|
||||
}
|
||||
|
||||
g_signal_emit (self, signals[SIGNAL_ACCEPTED], 0,
|
||||
file_locations,
|
||||
GTK_FILE_FILTER (gtk_drop_down_get_selected_item (self->filters_dropdown)),
|
||||
|
@ -202,27 +207,178 @@ update_current_directory (NautilusFileChooser *self,
|
|||
g_return_if_fail (G_IS_FILE (location));
|
||||
|
||||
g_autoptr (NautilusDirectory) directory = nautilus_directory_get (location);
|
||||
g_autofree char *parse_name = g_file_get_parse_name (location);
|
||||
|
||||
g_set_object (&self->current_directory, directory);
|
||||
|
||||
adw_action_row_set_subtitle (ADW_ACTION_ROW (self->location_row), parse_name);
|
||||
gtk_widget_add_css_class (self->location_row, "property");
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CURRENT_DIRECTORY]);
|
||||
}
|
||||
|
||||
static void
|
||||
animate_switch_to_stack_child (NautilusFileChooser *self,
|
||||
GtkWidget *page)
|
||||
{
|
||||
gboolean to_namer = (page == self->namer_view);
|
||||
|
||||
adw_timed_animation_set_value_from (ADW_TIMED_ANIMATION (self->width_animation),
|
||||
gtk_widget_get_width (GTK_WIDGET (self)));
|
||||
adw_timed_animation_set_value_from (ADW_TIMED_ANIMATION (self->height_animation),
|
||||
gtk_widget_get_height (GTK_WIDGET (self)));
|
||||
adw_timed_animation_set_value_to (ADW_TIMED_ANIMATION (self->width_animation),
|
||||
(to_namer ? NAMER_DEFAULT_WIDTH : SELECTOR_DEFAULT_WIDTH));
|
||||
adw_timed_animation_set_value_to (ADW_TIMED_ANIMATION (self->height_animation),
|
||||
(to_namer ? NAMER_DEFAULT_HEIGHT : SELECTOR_DEFAULT_HEIGHT));
|
||||
|
||||
adw_animation_play (self->width_animation);
|
||||
adw_animation_play (self->height_animation);
|
||||
|
||||
gtk_stack_set_visible_child (self->stack, page);
|
||||
}
|
||||
|
||||
static void
|
||||
on_selector_accept_button_clicked (NautilusFileChooser *self)
|
||||
{
|
||||
GList *selection = nautilus_window_slot_get_selection (self->slot);
|
||||
|
||||
if (mode_can_accept_files (self->mode, selection))
|
||||
if (self->mode == NAUTILUS_MODE_SAVE_FILE)
|
||||
{
|
||||
emit_accepted (self, selection);
|
||||
if (mode_can_accept_files (self->mode, selection))
|
||||
{
|
||||
g_autoptr (GFile) selected_location = NULL;
|
||||
NautilusFile *file = NAUTILUS_FILE (selection->data);
|
||||
|
||||
if (nautilus_file_opens_in_view (file))
|
||||
{
|
||||
selected_location = nautilus_file_get_location (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->name_entry),
|
||||
nautilus_file_get_edit_name (file));
|
||||
selected_location = nautilus_file_get_parent_location (file);
|
||||
}
|
||||
|
||||
update_current_directory (self, selected_location);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_current_directory (self, nautilus_window_slot_get_location (self->slot));
|
||||
}
|
||||
|
||||
animate_switch_to_stack_child (self, self->namer_view);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_accepted (self, NULL);
|
||||
if (mode_can_accept_files (self->mode, selection))
|
||||
{
|
||||
g_autolist (GFile) file_locations = g_list_copy_deep (selection, (GCopyFunc) nautilus_file_get_activation_location, NULL);
|
||||
|
||||
emit_accepted (self, file_locations);
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *location = nautilus_window_slot_get_location (self->slot);
|
||||
|
||||
emit_accepted (self, &(GList){ .data = location });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_override_confirm_response (AdwAlertDialog *dialog,
|
||||
GAsyncResult *result,
|
||||
NautilusFileChooser *self)
|
||||
{
|
||||
const char *response = adw_alert_dialog_choose_finish (dialog, result);
|
||||
|
||||
if (g_strcmp0 (response, "replace") == 0)
|
||||
{
|
||||
g_autofree char *name = nautilus_filename_validator_get_new_name (self->validator);
|
||||
g_autoptr (GFile) parent_location = nautilus_directory_get_location (self->current_directory);
|
||||
g_autoptr (GFile) file_location = g_file_get_child (parent_location, name);
|
||||
|
||||
emit_accepted (self, &(GList){ .data = file_location });
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ask_confirm_override (NautilusFileChooser *self)
|
||||
{
|
||||
AdwDialog *dialog = adw_alert_dialog_new (_("Replace When Saving?"), NULL);
|
||||
g_autofree char *filename = nautilus_filename_validator_get_new_name (self->validator);
|
||||
g_autoptr (NautilusFile) directory_as_file = nautilus_directory_get_corresponding_file (self->current_directory);
|
||||
const char *directory_name = nautilus_file_get_display_name (directory_as_file);
|
||||
|
||||
adw_alert_dialog_format_body (ADW_ALERT_DIALOG (dialog),
|
||||
_("“%s” already exists in “%s”. Saving will replace or override its contents."),
|
||||
filename, directory_name);
|
||||
|
||||
adw_alert_dialog_add_responses (ADW_ALERT_DIALOG (dialog),
|
||||
"cancel", _("_Cancel"),
|
||||
"replace", _("_Replace"),
|
||||
NULL);
|
||||
|
||||
adw_alert_dialog_set_response_appearance (ADW_ALERT_DIALOG (dialog),
|
||||
"replace",
|
||||
ADW_RESPONSE_DESTRUCTIVE);
|
||||
|
||||
adw_alert_dialog_set_default_response (ADW_ALERT_DIALOG (dialog), "cancel");
|
||||
adw_alert_dialog_set_close_response (ADW_ALERT_DIALOG (dialog), "cancel");
|
||||
|
||||
adw_alert_dialog_choose (ADW_ALERT_DIALOG (dialog), GTK_WIDGET (self),
|
||||
NULL, (GAsyncReadyCallback) on_override_confirm_response, self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_namer_accept_button_clicked (NautilusFileChooser *self)
|
||||
{
|
||||
if (nautilus_filename_validator_will_override (self->validator))
|
||||
{
|
||||
ask_confirm_override (self);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autofree char *name = nautilus_filename_validator_get_new_name (self->validator);
|
||||
g_autoptr (GFile) parent_location = nautilus_directory_get_location (self->current_directory);
|
||||
g_autoptr (GFile) file_location = g_file_get_child (parent_location, name);
|
||||
|
||||
emit_accepted (self, &(GList){ .data = file_location });
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_validator_has_feedback_changed (NautilusFileChooser *self)
|
||||
{
|
||||
gboolean has_feedback;
|
||||
|
||||
g_object_get (self->validator,
|
||||
"has-feedback", &has_feedback,
|
||||
NULL);
|
||||
if (has_feedback)
|
||||
{
|
||||
gtk_widget_add_css_class (self->namer_accept_button, "warning");
|
||||
gtk_widget_add_css_class (self->name_group, "warning");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_remove_css_class (self->namer_accept_button, "warning");
|
||||
gtk_widget_remove_css_class (self->name_group, "warning");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
action_pick_location (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
NautilusFileChooser *self = NAUTILUS_FILE_CHOOSER (widget);
|
||||
|
||||
animate_switch_to_stack_child (self, self->selector_view);
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor (NautilusFileChooser *self)
|
||||
{
|
||||
|
@ -243,10 +399,41 @@ on_slot_activate_files (NautilusFileChooser *self,
|
|||
{
|
||||
if (mode_can_accept_files (self->mode, files))
|
||||
{
|
||||
emit_accepted (self, files);
|
||||
if (self->mode == NAUTILUS_MODE_SAVE_FILE)
|
||||
{
|
||||
NautilusFile *file = NAUTILUS_FILE (files->data);
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->name_entry),
|
||||
nautilus_file_get_edit_name (file));
|
||||
|
||||
g_autoptr (GFile) location = nautilus_file_get_activation_location (file);
|
||||
g_autoptr (GFile) parent_location = g_file_get_parent (location);
|
||||
update_current_directory (self, parent_location);
|
||||
|
||||
animate_switch_to_stack_child (self, self->namer_view);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autolist (GFile) file_locations = g_list_copy_deep (files, (GCopyFunc) nautilus_file_get_activation_location, NULL);
|
||||
|
||||
emit_accepted (self, file_locations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_close_request (NautilusFileChooser *self)
|
||||
{
|
||||
if (self->mode == NAUTILUS_MODE_SAVE_FILE &&
|
||||
gtk_stack_get_visible_child (self->stack) == self->selector_view)
|
||||
{
|
||||
animate_switch_to_stack_child (self, self->namer_view);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_key_pressed_bubble (GtkEventControllerKey *controller,
|
||||
unsigned int keyval,
|
||||
|
@ -270,6 +457,8 @@ nautilus_file_chooser_dispose (GObject *object)
|
|||
{
|
||||
NautilusFileChooser *self = (NautilusFileChooser *) object;
|
||||
|
||||
g_clear_object (&self->width_animation);
|
||||
g_clear_object (&self->height_animation);
|
||||
g_clear_object (&self->current_directory);
|
||||
|
||||
if (self->slot != NULL)
|
||||
|
@ -344,6 +533,7 @@ nautilus_file_chooser_constructed (GObject *object)
|
|||
G_OBJECT_CLASS (nautilus_file_chooser_parent_class)->constructed (object);
|
||||
|
||||
NautilusFileChooser *self = (NautilusFileChooser *) object;
|
||||
gboolean start_with_namer = (self->mode == NAUTILUS_MODE_SAVE_FILE);
|
||||
|
||||
/* Setup slot.
|
||||
* We hold a reference to control its lifetime with relation to bindings. */
|
||||
|
@ -364,11 +554,22 @@ nautilus_file_chooser_constructed (GObject *object)
|
|||
|
||||
gtk_widget_set_visible (self->choices_menu_button,
|
||||
nautilus_mode_is_open (self->mode));
|
||||
|
||||
gtk_widget_set_visible (self->selector_cancel_button, start_with_namer);
|
||||
|
||||
gtk_stack_set_visible_child (self->stack, (start_with_namer ?
|
||||
self->namer_view :
|
||||
self->selector_view));
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (self),
|
||||
(start_with_namer ? NAMER_DEFAULT_WIDTH : SELECTOR_DEFAULT_WIDTH),
|
||||
(start_with_namer ? NAMER_DEFAULT_HEIGHT : SELECTOR_DEFAULT_HEIGHT));
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_file_chooser_init (NautilusFileChooser *self)
|
||||
{
|
||||
g_type_ensure (NAUTILUS_TYPE_FILENAME_VALIDATOR);
|
||||
g_type_ensure (NAUTILUS_TYPE_TOOLBAR);
|
||||
g_type_ensure (NAUTILUS_TYPE_GTK_PLACES_SIDEBAR);
|
||||
g_type_ensure (NAUTILUS_TYPE_SHORTCUT_MANAGER);
|
||||
|
@ -383,6 +584,18 @@ nautilus_file_chooser_init (NautilusFileChooser *self)
|
|||
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_BUBBLE);
|
||||
g_signal_connect (controller, "key-pressed",
|
||||
G_CALLBACK (on_key_pressed_bubble), self);
|
||||
|
||||
self->width_animation = adw_timed_animation_new (GTK_WIDGET (self),
|
||||
0.0, 0.0, 500,
|
||||
adw_property_animation_target_new (G_OBJECT (self),
|
||||
"default-width"));
|
||||
self->height_animation = adw_timed_animation_new (GTK_WIDGET (self),
|
||||
0.0, 0.0, 500,
|
||||
adw_property_animation_target_new (G_OBJECT (self),
|
||||
"default-height"));
|
||||
|
||||
|
||||
g_signal_connect_swapped (self, "close-request", G_CALLBACK (on_close_request), self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -406,10 +619,22 @@ nautilus_file_chooser_class_init (NautilusFileChooserClass *klass)
|
|||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, filters_dropdown);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, choices_menu_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, read_only_checkbox);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, selector_cancel_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, selector_accept_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, namer_view);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, name_group);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, name_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, location_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, namer_accept_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusFileChooser, validator);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, selector_can_accept);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_selector_accept_button_clicked);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_namer_accept_button_clicked);
|
||||
gtk_widget_class_bind_template_callback (widget_class, nautilus_filename_validator_validate);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_validator_has_feedback_changed);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "filechooser.pick-location", NULL, action_pick_location);
|
||||
|
||||
properties[PROP_CURRENT_DIRECTORY] =
|
||||
g_param_spec_object ("current-directory", NULL, NULL,
|
||||
|
@ -444,7 +669,14 @@ void
|
|||
nautilus_file_chooser_set_accept_label (NautilusFileChooser *self,
|
||||
const char *accept_label)
|
||||
{
|
||||
gtk_button_set_label (GTK_BUTTON (self->selector_accept_button), accept_label);
|
||||
if (self->mode == NAUTILUS_MODE_SAVE_FILE)
|
||||
{
|
||||
gtk_button_set_label (GTK_BUTTON (self->namer_accept_button), accept_label);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_button_set_label (GTK_BUTTON (self->selector_accept_button), accept_label);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -482,3 +714,13 @@ nautilus_file_chooser_set_starting_location (NautilusFileChooser *self,
|
|||
|
||||
nautilus_window_slot_open_location_full (self->slot, location_to_open, 0, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_file_chooser_set_suggested_name (NautilusFileChooser *self,
|
||||
const char *suggested_name)
|
||||
{
|
||||
if (suggested_name != NULL)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->name_entry), suggested_name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,5 +34,8 @@ nautilus_file_chooser_set_filters (NautilusFileChooser *self,
|
|||
void
|
||||
nautilus_file_chooser_set_starting_location (NautilusFileChooser *self,
|
||||
GFile *starting_location);
|
||||
void
|
||||
nautilus_file_chooser_set_suggested_name (NautilusFileChooser *self,
|
||||
const char *suggested_name);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -17,6 +17,7 @@ struct _NautilusFilenameValidator
|
|||
|
||||
NautilusDirectory *containing_directory;
|
||||
gboolean target_is_folder;
|
||||
gboolean allow_override;
|
||||
char *original_name;
|
||||
|
||||
const char *feedback_text;
|
||||
|
@ -43,6 +44,7 @@ enum
|
|||
PROP_NEW_NAME,
|
||||
PROP_CONTAINING_DIRECTORY,
|
||||
PROP_PASSED,
|
||||
PROP_ALLOW_OVERRIDE,
|
||||
PROP_TARGET_IS_FOLDER,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
@ -200,7 +202,8 @@ filename_validator_process_new_name (NautilusFilenameValidator *self)
|
|||
!nautilus_filename_validator_ignore_existing_file (self,
|
||||
existing_file);
|
||||
|
||||
gboolean passed = (self->valid_name && !self->duplicated_name);
|
||||
gboolean passed = (self->valid_name &&
|
||||
(self->allow_override || !self->duplicated_name));
|
||||
|
||||
if (self->passed != passed)
|
||||
{
|
||||
|
@ -249,7 +252,11 @@ void
|
|||
nautilus_filename_validator_validate (NautilusFilenameValidator *self)
|
||||
{
|
||||
g_return_if_fail (NAUTILUS_IS_FILENAME_VALIDATOR (self));
|
||||
g_return_if_fail (NAUTILUS_IS_DIRECTORY (self->containing_directory));
|
||||
|
||||
if (self->containing_directory == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nautilus_directory_call_when_ready (self->containing_directory,
|
||||
NAUTILUS_FILE_ATTRIBUTE_INFO,
|
||||
|
@ -378,6 +385,12 @@ nautilus_filename_validator_set_property (GObject *object,
|
|||
}
|
||||
break;
|
||||
|
||||
case PROP_ALLOW_OVERRIDE:
|
||||
{
|
||||
self->allow_override = g_value_get_boolean (value);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_TARGET_IS_FOLDER:
|
||||
{
|
||||
self->target_is_folder = g_value_get_boolean (value);
|
||||
|
@ -453,6 +466,10 @@ nautilus_filename_validator_class_init (NautilusFilenameValidatorClass *klass)
|
|||
g_param_spec_object ("containing-directory", NULL, NULL,
|
||||
NAUTILUS_TYPE_DIRECTORY,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||
properties[PROP_ALLOW_OVERRIDE] =
|
||||
g_param_spec_boolean ("allow-override", NULL, NULL,
|
||||
FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||
properties[PROP_TARGET_IS_FOLDER] =
|
||||
g_param_spec_boolean ("target-is-folder", NULL, NULL,
|
||||
FALSE,
|
||||
|
@ -460,3 +477,9 @@ nautilus_filename_validator_class_init (NautilusFilenameValidatorClass *klass)
|
|||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nautilus_filename_validator_will_override (NautilusFilenameValidator *self)
|
||||
{
|
||||
return (self->allow_override && self->passed && self->duplicated_name);
|
||||
}
|
||||
|
|
|
@ -24,3 +24,4 @@ void nautilus_filename_validator_set_original_name (NautilusFilenameVa
|
|||
const char *original_name);
|
||||
void nautilus_filename_validator_validate (NautilusFilenameValidator *self);
|
||||
void nautilus_filename_validator_try_accept (NautilusFilenameValidator *self);
|
||||
gboolean nautilus_filename_validator_will_override (NautilusFilenameValidator *self);
|
||||
|
|
|
@ -354,6 +354,7 @@ handle_file_chooser_methods (XdpImplFileChooser *object,
|
|||
nautilus_file_chooser_set_filters (window, G_LIST_MODEL (filters));
|
||||
nautilus_file_chooser_set_current_filter (window, current_filter_position);
|
||||
nautilus_file_chooser_set_starting_location (window, starting_location);
|
||||
nautilus_file_chooser_set_suggested_name (window, suggested_filename);
|
||||
gtk_window_set_title (GTK_WINDOW (window), arg_title);
|
||||
|
||||
g_signal_connect_swapped (window, "close-request",
|
||||
|
@ -364,24 +365,7 @@ handle_file_chooser_methods (XdpImplFileChooser *object,
|
|||
/* Show window */
|
||||
if (arg_parent_window != NULL)
|
||||
{
|
||||
data->external_parent = create_external_window_from_handle (arg_parent_window);
|
||||
if (data->external_parent == NULL)
|
||||
{
|
||||
g_warning ("Failed to associate portal window with parent window %s",
|
||||
arg_parent_window);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_realize (GTK_WIDGET (window));
|
||||
|
||||
GdkSurface *surface = gtk_native_get_surface (GTK_NATIVE (window));
|
||||
gboolean modal = TRUE;
|
||||
|
||||
(void) g_variant_lookup (arg_options, "modal", "b", &modal);
|
||||
|
||||
external_window_set_parent_of (data->external_parent, surface);
|
||||
gtk_window_set_modal (data->window, modal);
|
||||
}
|
||||
g_message ("No parenting. Testing purposes only.");
|
||||
}
|
||||
|
||||
gtk_window_present (data->window);
|
||||
|
|
|
@ -327,3 +327,7 @@ label.encrypted_zip {
|
|||
rubberband {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
#NautilusFileChooser preferencesgroup.move-up-12-px {
|
||||
margin-top: -12px;
|
||||
}
|
||||
|
|
|
@ -2,13 +2,11 @@
|
|||
<interface>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<template class="NautilusFileChooser" parent="AdwWindow">
|
||||
<property name="name">NautilusFileChooser</property>
|
||||
<property name="width-request">360</property>
|
||||
<property name="height-request">348</property>
|
||||
<property name="default-width">890</property>
|
||||
<property name="default-height">550</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="NautilusShortcutManager">
|
||||
<property name="child">
|
||||
|
@ -21,6 +19,9 @@
|
|||
<property name="max-sidebar-width">240</property>
|
||||
<property name="sidebar-width-unit">px</property>
|
||||
<property name="sidebar-width-fraction">0.2</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<property name="sidebar">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
|
@ -117,24 +118,41 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="center">
|
||||
<object class="GtkButton" id="selector_accept_button">
|
||||
<property name="use-underline">true</property>
|
||||
<binding name="sensitive">
|
||||
<closure type="gboolean" function="selector_can_accept">
|
||||
<lookup type="NautilusWindowSlot" name="selection">
|
||||
<lookup name="content">slot_container</lookup>
|
||||
</lookup>
|
||||
<lookup type="NautilusWindowSlot" name="location">
|
||||
<lookup name="content">slot_container</lookup>
|
||||
</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
<signal name="clicked" handler="on_selector_accept_button_clicked" swapped="yes"/>
|
||||
<style>
|
||||
<class name="pill"/>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
<child type="end">
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="selector_cancel_button">
|
||||
<property name="visible">false</property>
|
||||
<property name="label">_Cancel</property>
|
||||
<property name="use-underline">true</property>
|
||||
<property name="action-name">window.close</property>
|
||||
<style>
|
||||
<class name="pill"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="selector_accept_button">
|
||||
<property name="label">_Select</property>
|
||||
<property name="use-underline">true</property>
|
||||
<binding name="sensitive">
|
||||
<closure type="gboolean" function="selector_can_accept">
|
||||
<lookup type="NautilusWindowSlot" name="selection">
|
||||
<lookup name="content">slot_container</lookup>
|
||||
</lookup>
|
||||
<lookup type="NautilusWindowSlot" name="location">
|
||||
<lookup name="content">slot_container</lookup>
|
||||
</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
<signal name="clicked" handler="on_selector_accept_button_clicked" swapped="yes"/>
|
||||
<style>
|
||||
<class name="pill"/>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -145,6 +163,126 @@
|
|||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwToolbarView" id="namer_view">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar">
|
||||
<property name="show-end-title-buttons">false</property>
|
||||
<property name="show-start-title-buttons">false</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="AdwPreferencesPage">
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="name_group">
|
||||
<style>
|
||||
<class name="move-up-12-px"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="AdwEntryRow" id="name_entry">
|
||||
<property name="title" translatable="yes">File _Name</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="changed" handler="nautilus_filename_validator_validate" object="validator" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer">
|
||||
<property name="reveal-child" bind-source="validator" bind-property="has-feedback"/>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" bind-source="validator" bind-property="feedback-text"/>
|
||||
<property name="margin_top">6</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="caption"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="separate-rows">true</property>
|
||||
<style>
|
||||
<class name="move-up-12-px"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="AdwComboRow">
|
||||
<property name="title" translatable="yes">File _Type</property>
|
||||
<property name="use-underline">True</property>
|
||||
<!-- Share state with the dropdown. -->
|
||||
<property name="visible"
|
||||
bind-source="filters_dropdown" bind-property="visible"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="expression"
|
||||
bind-source="filters_dropdown" bind-property="expression"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="model"
|
||||
bind-source="filters_dropdown" bind-property="model"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="selected"
|
||||
bind-source="filters_dropdown" bind-property="selected"
|
||||
bind-flags="bidirectional|sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow" id="location_row">
|
||||
<property name="title" translatable="yes">Save _Location</property>
|
||||
<property name="subtitle" translatable="yes">Set location</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="activatable">True</property>
|
||||
<property name="action-name">filechooser.pick-location</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon-name">folder-open-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<child type="bottom">
|
||||
<object class="AdwClamp">
|
||||
<property name="child">
|
||||
<object class="GtkCenterBox">
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<style>
|
||||
<class name="toolbar"/>
|
||||
</style>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="label">_Cancel</property>
|
||||
<property name="use-underline">true</property>
|
||||
<property name="action-name">window.close</property>
|
||||
<style>
|
||||
<class name="pill"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkButton" id="namer_accept_button">
|
||||
<property name="use-underline">true</property>
|
||||
<property name="sensitive" bind-source="validator" bind-property="passed" bind-flags="sync-create"/>
|
||||
<signal name="clicked" handler="on_namer_accept_button_clicked" swapped="yes"/>
|
||||
<style>
|
||||
<class name="pill"/>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
|
@ -171,4 +309,10 @@
|
|||
</object>
|
||||
</child>
|
||||
</template>
|
||||
<object class="NautilusFilenameValidator" id="validator">
|
||||
<property name="allow-override">true</property>
|
||||
<property name="containing-directory" bind-source="NautilusFileChooser" bind-property="current-directory"/>
|
||||
<property name="new-name" bind-source="name_entry" bind-property="text"/>
|
||||
<signal name="notify::has-feedback" handler="on_validator_has_feedback_changed" swapped="yes"/>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
Loading…
Reference in New Issue
Block a user