From 72f4d3f21826f6edbc6d0b39e90d8514dbddddc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacy=20Kuchci=C5=84ski?= Date: Mon, 1 Aug 2022 02:51:26 +0200 Subject: [PATCH 1/3] new-file-dialog: Add basic dialog structure Related: https://gitlab.gnome.org/GNOME/nautilus/-/issues/2205 --- po/POTFILES.in | 2 + src/meson.build | 2 + src/nautilus-new-file-dialog-controller.c | 298 ++++++++++++++++++ src/nautilus-new-file-dialog-controller.h | 45 +++ src/resources/nautilus.gresource.xml | 1 + .../ui/nautilus-create-file-dialog.ui | 130 ++++++++ 6 files changed, 478 insertions(+) create mode 100644 src/nautilus-new-file-dialog-controller.c create mode 100644 src/nautilus-new-file-dialog-controller.h create mode 100644 src/resources/ui/nautilus-create-file-dialog.ui diff --git a/po/POTFILES.in b/po/POTFILES.in index 6bea74b376..61c9239401 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -39,6 +39,7 @@ src/nautilus-list-view.c src/nautilus-location-entry.c src/nautilus-main.c src/nautilus-mime-actions.c +src/nautilus-new-file-dialog-controller.c src/nautilus-new-folder-dialog-controller.c src/nautilus-operations-ui-manager.c src/nautilus-pathbar.c @@ -69,6 +70,7 @@ src/resources/ui/nautilus-app-chooser.ui src/resources/ui/nautilus-batch-rename-dialog.ui src/resources/ui/nautilus-column-chooser.ui src/resources/ui/nautilus-compress-dialog.ui +src/resources/ui/nautilus-create-file-dialog.ui src/resources/ui/nautilus-create-folder-dialog.ui src/resources/ui/nautilus-file-conflict-dialog.ui src/resources/ui/nautilus-file-properties-change-permissions.ui diff --git a/src/meson.build b/src/meson.build index e682b99bad..a866a2e9a9 100644 --- a/src/meson.build +++ b/src/meson.build @@ -178,6 +178,8 @@ libnautilus_sources = [ 'nautilus-rename-file-popover-controller.h', 'nautilus-templates-dialog.c', 'nautilus-templates-dialog.h', + 'nautilus-new-file-dialog-controller.c', + 'nautilus-new-file-dialog-controller.h', 'nautilus-new-folder-dialog-controller.c', 'nautilus-new-folder-dialog-controller.h', 'nautilus-compress-dialog-controller.c', diff --git a/src/nautilus-new-file-dialog-controller.c b/src/nautilus-new-file-dialog-controller.c new file mode 100644 index 0000000000..e66d541e99 --- /dev/null +++ b/src/nautilus-new-file-dialog-controller.c @@ -0,0 +1,298 @@ +/* nautilus-new-file-dialog-controller.c + * + * Copyright 2022 Ignacy Kuchciński + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "nautilus-new-file-dialog-controller.h" + +#include + +#include "nautilus-application.h" + +struct _NautilusNewFileDialogController +{ + NautilusFileNameWidgetController parent_instance; + + GtkDialog *new_file_dialog; + GtkLabel *extension_label; + + gchar *template_name; + gchar *extension; +}; + +G_DEFINE_TYPE (NautilusNewFileDialogController, nautilus_new_file_dialog_controller, NAUTILUS_TYPE_FILE_NAME_WIDGET_CONTROLLER) + +static gboolean +nautilus_new_file_dialog_controller_name_is_valid (NautilusFileNameWidgetController *self, + gchar *name, + gchar **error_message) +{ + gboolean is_valid; + + is_valid = TRUE; + if (strlen (name) == 0) + { + is_valid = FALSE; + } + else if (strstr (name, "/") != NULL) + { + is_valid = FALSE; + *error_message = _("File names cannot contain “/“."); + } + else if (strcmp (name, ".") == 0) + { + is_valid = FALSE; + *error_message = _("A file cannot be called “.“."); + } + else if (strcmp (name, "..") == 0) + { + is_valid = FALSE; + *error_message = _("A file cannot be called “..“."); + } + else if (nautilus_file_name_widget_controller_is_name_too_long (self, name)) + { + is_valid = FALSE; + *error_message = _("File name is too long."); + } + else if (g_str_has_prefix (name, ".")) + { + /* We must warn about the side effect */ + *error_message = _("Files with “.“ at the beginning of their name are hidden."); + } + + return is_valid; +} + +static gchar * +nautilus_new_file_dialog_controller_get_new_name (NautilusFileNameWidgetController *controller) +{ + NautilusNewFileDialogController *self; + g_autofree gchar *basename = NULL; + + self = NAUTILUS_NEW_FILE_DIALOG_CONTROLLER (controller); + + basename = NAUTILUS_FILE_NAME_WIDGET_CONTROLLER_CLASS (nautilus_new_file_dialog_controller_parent_class)->get_new_name (controller); + + if (g_str_has_suffix (basename, self->extension)) + { + return g_strdup (basename); + } + + return g_strconcat (basename, self->extension, NULL); +} + + +gchar * +nautilus_new_file_dialog_controller_get_template_name (NautilusNewFileDialogController *self) +{ + return self->template_name; +} + +static void +new_file_dialog_controller_on_response (GtkDialog *dialog, + int response, + NautilusNewFileDialogController *self) +{ + if (response != GTK_RESPONSE_OK) + { + g_signal_emit_by_name (self, "cancelled"); + } +} + +static void +text_action_row_on_activated (GtkCheckButton *check_button, + NautilusNewFileDialogController *self) +{ + self->template_name = NULL; + self->extension = ".txt"; + gtk_label_set_text (self->extension_label, ".txt"); +} + +static void +document_action_row_on_activated (GtkCheckButton *check_button, + NautilusNewFileDialogController *self) +{ + self->template_name = "document.odt"; + self->extension = ".odt"; + gtk_label_set_text (self->extension_label, ".odt"); +} + +static void +spreadsheet_action_row_on_activated (GtkCheckButton *check_button, + NautilusNewFileDialogController *self) +{ + self->template_name = "spreadsheet.ods"; + self->extension = ".ods"; + gtk_label_set_text (self->extension_label, ".ods"); +} + +static void +presentation_action_row_on_activated (GtkCheckButton *check_button, + NautilusNewFileDialogController *self) +{ + self->template_name = "presentation.odp"; + self->extension = ".odp"; + gtk_label_set_text (self->extension_label, ".odp"); +} + +NautilusNewFileDialogController * +nautilus_new_file_dialog_controller_new (GtkWindow *parent_window, + NautilusDirectory *destination_directory) +{ + NautilusNewFileDialogController *self; + g_autoptr (GtkBuilder) builder = NULL; + GtkDialog *new_file_dialog; + GtkLabel *extension_label; + GtkRevealer *error_revealer; + GtkLabel *error_label; + AdwEntryRow *name_entry; + GtkButton *activate_button; + GList *recommended_apps; + AdwActionRow *text_action_row; + AdwActionRow *document_action_row; + AdwActionRow *spreadsheet_action_row; + AdwActionRow *presentation_action_row; + gboolean not_sandboxed; + + builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/ui/nautilus-create-file-dialog.ui"); + new_file_dialog = GTK_DIALOG (gtk_builder_get_object (builder, "create_file_dialog")); + extension_label = GTK_LABEL (gtk_builder_get_object (builder, "extension_label")); + error_revealer = GTK_REVEALER (gtk_builder_get_object (builder, "error_revealer")); + error_label = GTK_LABEL (gtk_builder_get_object (builder, "error_label")); + name_entry = ADW_ENTRY_ROW (gtk_builder_get_object (builder, "name_entry")); + activate_button = GTK_BUTTON (gtk_builder_get_object (builder, "ok_button")); + text_action_row = ADW_ACTION_ROW (gtk_builder_get_object (builder, "text_action_row")); + document_action_row = ADW_ACTION_ROW (gtk_builder_get_object (builder, "document_action_row")); + spreadsheet_action_row = ADW_ACTION_ROW (gtk_builder_get_object (builder, "spreadsheet_action_row")); + presentation_action_row = ADW_ACTION_ROW (gtk_builder_get_object (builder, "presentation_action_row")); + + gtk_window_set_transient_for (GTK_WINDOW (new_file_dialog), parent_window); + + self = g_object_new (NAUTILUS_TYPE_NEW_FILE_DIALOG_CONTROLLER, + "error-revealer", error_revealer, + "error-label", error_label, + "name-entry", name_entry, + "activate-button", activate_button, + "containing-directory", destination_directory, NULL); + + self->new_file_dialog = new_file_dialog; + self->extension_label = extension_label; + + g_signal_connect_object (new_file_dialog, + "response", + G_CALLBACK (new_file_dialog_controller_on_response), + self, + 0); + + g_signal_connect_object (text_action_row, + "activated", + G_CALLBACK (text_action_row_on_activated), + self, + 0); + + g_signal_connect_object (document_action_row, + "activated", + G_CALLBACK (document_action_row_on_activated), + self, + 0); + + g_signal_connect_object (spreadsheet_action_row, + "activated", + G_CALLBACK (spreadsheet_action_row_on_activated), + self, + 0); + + g_signal_connect_object (presentation_action_row, + "activated", + G_CALLBACK (presentation_action_row_on_activated), + self, + 0); + + recommended_apps = g_app_info_get_recommended_for_type ("application/vnd.oasis.opendocument.presentation"); + not_sandboxed = !nautilus_application_is_sandboxed (); + + if (recommended_apps == NULL && not_sandboxed) + { + gtk_widget_set_visible (GTK_WIDGET (presentation_action_row), FALSE); + } + else + { + g_list_free_full (recommended_apps, g_object_unref); + } + + recommended_apps = g_app_info_get_recommended_for_type ("application/vnd.oasis.opendocument.spreadsheet"); + + if (recommended_apps == NULL && not_sandboxed) + { + gtk_widget_set_visible (GTK_WIDGET (spreadsheet_action_row), FALSE); + } + else + { + g_list_free_full (recommended_apps, g_object_unref); + } + + recommended_apps = g_app_info_get_recommended_for_type ("application/vnd.oasis.opendocument.text"); + + if (recommended_apps == NULL && not_sandboxed) + { + gtk_widget_set_visible (GTK_WIDGET (document_action_row), FALSE); + } + else + { + g_list_free_full (recommended_apps, g_object_unref); + } + + adw_action_row_activate (text_action_row); + + gtk_widget_show (GTK_WIDGET (new_file_dialog)); + + return self; +} + +static void +nautilus_new_file_dialog_controller_init (NautilusNewFileDialogController *self) +{ +} + +static void +nautilus_new_file_dialog_controller_finalize (GObject *gobject) +{ + NautilusNewFileDialogController *self; + + self = NAUTILUS_NEW_FILE_DIALOG_CONTROLLER (gobject); + + if (self->new_file_dialog != NULL) + { + gtk_window_destroy (GTK_WINDOW (self->new_file_dialog)); + self->new_file_dialog = NULL; + } + + G_OBJECT_CLASS (nautilus_new_file_dialog_controller_parent_class)->finalize (gobject); +} + +static void +nautilus_new_file_dialog_controller_class_init (NautilusNewFileDialogControllerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NautilusFileNameWidgetControllerClass *parent_class = NAUTILUS_FILE_NAME_WIDGET_CONTROLLER_CLASS (klass); + + object_class->finalize = nautilus_new_file_dialog_controller_finalize; + + parent_class->name_is_valid = nautilus_new_file_dialog_controller_name_is_valid; + parent_class->get_new_name = nautilus_new_file_dialog_controller_get_new_name; +} diff --git a/src/nautilus-new-file-dialog-controller.h b/src/nautilus-new-file-dialog-controller.h new file mode 100644 index 0000000000..f2153f1980 --- /dev/null +++ b/src/nautilus-new-file-dialog-controller.h @@ -0,0 +1,45 @@ +/* nautilus-new-file-dialog-controller.h + * + * Copyright 2022 Ignacy Kuchciński + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +#include "nautilus-file-name-widget-controller.h" +#include "nautilus-directory.h" + +G_BEGIN_DECLS + +#define NAUTILUS_TYPE_NEW_FILE_DIALOG_CONTROLLER (nautilus_new_file_dialog_controller_get_type ()) + +G_DECLARE_FINAL_TYPE (NautilusNewFileDialogController, nautilus_new_file_dialog_controller, NAUTILUS, NEW_FILE_DIALOG_CONTROLLER, NautilusFileNameWidgetController) + +NautilusNewFileDialogController * nautilus_new_file_dialog_controller_new (GtkWindow *parent_window, + NautilusDirectory *destination_directory); + +/** + * nautilus_new_file_dialog_controller_get_template_name: + * + * Returns: the filename of the chosen blank template, or NULL if the chosen + * file type is a text file + */ +gchar * nautilus_new_file_dialog_controller_get_template_name (NautilusNewFileDialogController *self); + +G_END_DECLS diff --git a/src/resources/nautilus.gresource.xml b/src/resources/nautilus.gresource.xml index 2866224ffb..56b5697da8 100644 --- a/src/resources/nautilus.gresource.xml +++ b/src/resources/nautilus.gresource.xml @@ -13,6 +13,7 @@ ui/nautilus-column-chooser.ui ui/nautilus-list-view-column-editor.ui ui/nautilus-templates-dialog.ui + ui/nautilus-create-file-dialog.ui ui/nautilus-create-folder-dialog.ui ui/nautilus-compress-dialog.ui ui/nautilus-rename-file-popover.ui diff --git a/src/resources/ui/nautilus-create-file-dialog.ui b/src/resources/ui/nautilus-create-file-dialog.ui new file mode 100644 index 0000000000..af3a19972b --- /dev/null +++ b/src/resources/ui/nautilus-create-file-dialog.ui @@ -0,0 +1,130 @@ + + + + New File + True + 1 + 500 + 450 + + + + + 18 + 18 + 18 + 18 + + + vertical + 12 + + + + + File Name + + + .txt + + + + + + + + + + + + + + + 0 + + + + + + + + + text-x-generic-symbolic + _Text File + true + + + True + + + text_check_button + + + + + x-office-document-symbolic + _Document + true + + + text_check_button + + + document_check_button + + + + + x-office-spreadsheet-symbolic + _Spreadsheet + true + + + text_check_button + + + spreadsheet_check_button + + + + + x-office-presentation-symbolic + _Presentation + true + + + text_check_button + + + presentation_check_button + + + + + + + + + + + + + _Cancel + true + + + + + C_reate + true + False + + + + ok_button + cancel_button + + + -- GitLab From 62d9dea807f09e3887cf83120bf5a32ec25cd9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacy=20Kuchci=C5=84ski?= Date: Fri, 15 Jul 2022 23:33:46 +0200 Subject: [PATCH 2/3] files-view: Add "New File" menu item --- src/nautilus-files-view.c | 148 +++++++++++++++++- .../ui/nautilus-files-view-context-menus.ui | 5 + 2 files changed, 152 insertions(+), 1 deletion(-) diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c index 4d4b2f4ac1..0b48c822e4 100644 --- a/src/nautilus-files-view.c +++ b/src/nautilus-files-view.c @@ -75,6 +75,8 @@ #include "nautilus-metadata.h" #include "nautilus-mime-actions.h" #include "nautilus-module.h" +#include "nautilus-templates-dialog.h" +#include "nautilus-new-file-dialog-controller.h" #include "nautilus-new-folder-dialog-controller.h" #include "nautilus-previewer.h" #include "nautilus-profile.h" @@ -165,6 +167,7 @@ typedef struct NautilusWindowSlot *slot; NautilusDirectory *model; + NautilusDirectory *templates_directory; NautilusFile *directory_as_file; GFile *location; guint dir_merge_id; @@ -172,6 +175,8 @@ typedef struct NautilusQuery *search_query; NautilusRenameFilePopoverController *rename_file_controller; + NautilusTemplatesDialog *templates_dialog; + NautilusNewFileDialogController *new_file_controller; NautilusNewFolderDialogController *new_folder_controller; NautilusCompressDialogController *compress_controller; @@ -234,6 +239,8 @@ typedef struct gboolean metadata_for_directory_as_file_pending; gboolean metadata_for_files_in_directory_pending; + gboolean has_templates; + GList *subdirectory_list; GMenu *selection_menu_model; @@ -2041,6 +2048,45 @@ new_folder_dialog_controller_on_cancelled (NautilusNewFolderDialogController *co g_clear_object (&priv->new_folder_controller); } +static void +templates_dialog_on_response (GtkDialog *dialog, + int response_id, + gpointer *user_data) +{ + NautilusFilesView *view; + NautilusFilesViewPrivate *priv; + + view = NAUTILUS_FILES_VIEW (user_data); + priv = nautilus_files_view_get_instance_private (view); + + gtk_window_destroy (GTK_WINDOW (dialog)); + priv->templates_dialog = NULL; +} + +static void +new_file_dialog_controller_on_name_accepted (NautilusFileNameWidgetController *controller, + NautilusFilesView *self) +{ + NautilusFilesViewPrivate *priv; + + priv = nautilus_files_view_get_instance_private (self); + + g_clear_object (&priv->new_file_controller); + + gtk_widget_grab_focus (GTK_WIDGET (self)); +} + +static void +new_file_dialog_controller_on_cancelled (NautilusNewFileDialogController *controller, + NautilusFilesView *self) +{ + NautilusFilesViewPrivate *priv; + + priv = nautilus_files_view_get_instance_private (self); + + g_clear_object (&priv->new_file_controller); +} + static void nautilus_files_view_new_folder_dialog_new (NautilusFilesView *view, gboolean with_selection) @@ -2420,6 +2466,83 @@ nautilus_files_view_new_file (NautilusFilesView *directory_view, g_free (container_uri); } +static void +templates_changed_cb (NautilusDirectory *directory, + NautilusFilesView *files_view, + gpointer callback_data) +{ + NautilusFilesViewPrivate *priv; + NautilusFilesView *view; + + view = NAUTILUS_FILES_VIEW (callback_data); + + g_assert (NAUTILUS_IS_FILES_VIEW (view)); + + priv = nautilus_files_view_get_instance_private (view); + + priv->has_templates = nautilus_directory_is_not_empty (directory); +} + +static void +action_new_file (GSimpleAction *action, + GVariant *state, + gpointer user_data) +{ + g_autoptr (NautilusDirectory) containing_directory = NULL; + NautilusFilesView *view; + NautilusFilesViewPrivate *priv; + g_autofree char *uri = NULL; + g_autofree char *templates_uri = NULL; + + g_assert (NAUTILUS_IS_FILES_VIEW (user_data)); + + view = NAUTILUS_FILES_VIEW (user_data); + priv = nautilus_files_view_get_instance_private (view); + uri = nautilus_files_view_get_backing_uri (view); + containing_directory = nautilus_directory_get_by_uri (uri); + + if (!priv->has_templates) /* if the XDG Templates directory is empty */ + { + if (priv->new_file_controller != NULL) + { + return; + } + + priv->new_file_controller = + nautilus_new_file_dialog_controller_new (nautilus_files_view_get_containing_window (view), + containing_directory); + + g_signal_connect_object (priv->new_file_controller, + "name-accepted", + G_CALLBACK (new_file_dialog_controller_on_name_accepted), + view, + 0); + g_signal_connect_object (priv->new_file_controller, + "cancelled", + G_CALLBACK (new_file_dialog_controller_on_cancelled), + view, + 0); + } + else + { + if (priv->templates_dialog != NULL) + { + return; + } + + + priv->templates_dialog = + nautilus_templates_dialog_new (nautilus_files_view_get_containing_window (view)); + gtk_window_present (GTK_WINDOW (priv->templates_dialog)); + + g_signal_connect_object (priv->templates_dialog, + "response", + G_CALLBACK (templates_dialog_on_response), + view, + 0); + } +} + static void action_new_folder (GSimpleAction *action, GVariant *state, @@ -3196,6 +3319,13 @@ nautilus_files_view_dispose (GObject *object) priv->subdirectory_list->data); } + if (priv->templates_directory != NULL) + { + nautilus_directory_file_monitor_remove (priv->templates_directory, view); + g_object_unref (priv->templates_directory); + priv->templates_directory = NULL; + } + remove_update_context_menus_timeout_callback (view); remove_update_status_idle_callback (view); @@ -3272,6 +3402,7 @@ nautilus_files_view_finalize (GObject *object) g_clear_object (&priv->toolbar_menu_sections->sort_section); g_clear_object (&priv->extensions_background_menu); g_clear_object (&priv->rename_file_controller); + g_clear_object (&priv->new_file_controller); g_clear_object (&priv->new_folder_controller); g_clear_object (&priv->compress_controller); /* We don't own the slot, so no unref */ @@ -6695,6 +6826,7 @@ const GActionEntry view_entries[] = { "show-hidden-files", NULL, NULL, "true", action_show_hidden_files }, /* Background menu */ { "new-folder", action_new_folder }, + { "new-file", action_new_file }, { "select-all", action_select_all }, { "paste", action_paste_files }, { "copy-current-location", action_copy_current_location }, @@ -7414,6 +7546,9 @@ real_update_actions_state (NautilusFilesView *view) action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "new-folder"); g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_create_files); + action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), + "new-file"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_create_files); action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "paste"); g_simple_action_set_enabled (G_SIMPLE_ACTION (action), @@ -9289,9 +9424,20 @@ nautilus_files_view_init (NautilusFilesView *view) { templates_uri = nautilus_get_templates_directory_uri (); templates_directory = nautilus_directory_get_by_uri (templates_uri); + priv->templates_directory = templates_directory; g_free (templates_uri); add_directory_to_templates_directory_list (view, templates_directory); - nautilus_directory_unref (templates_directory); + + /* Monitor templates directory */ + + nautilus_directory_file_monitor_add (templates_directory, view, + FALSE, NAUTILUS_FILE_ATTRIBUTE_INFO, + (NautilusDirectoryCallback) templates_changed_cb, view); + + g_signal_connect_object (templates_directory, "files-added", + G_CALLBACK (templates_changed_cb), view, 0); + g_signal_connect_object (templates_directory, "files-changed", + G_CALLBACK (templates_changed_cb), view, 0); } priv->sort_directories_first = diff --git a/src/resources/ui/nautilus-files-view-context-menus.ui b/src/resources/ui/nautilus-files-view-context-menus.ui index 1bcd861b0b..c51170e771 100644 --- a/src/resources/ui/nautilus-files-view-context-menus.ui +++ b/src/resources/ui/nautilus-files-view-context-menus.ui @@ -6,6 +6,11 @@ New _Folder… view.new-folder + + _New File + view.new-file + action-disabled + Open _With… view.open-current-directory-with-other-application -- GitLab From d89a0b0742f6215883b14ac78cc4e50032bccfb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacy=20Kuchci=C5=84ski?= Date: Mon, 1 Aug 2022 22:01:05 +0200 Subject: [PATCH 3/3] files-view: Allow creating new files --- data/meson.build | 1 + data/templates/document.odt | Bin 0 -> 8197 bytes data/templates/meson.build | 9 +++++++++ data/templates/presentation.odp | Bin 0 -> 13165 bytes data/templates/spreadsheet.ods | Bin 0 -> 6956 bytes src/nautilus-files-view.c | 27 +++++++++++++++++++++++++-- 6 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 data/templates/document.odt create mode 100644 data/templates/meson.build create mode 100644 data/templates/presentation.odp create mode 100644 data/templates/spreadsheet.ods diff --git a/data/meson.build b/data/meson.build index 2df5a226c3..953b814083 100644 --- a/data/meson.build +++ b/data/meson.build @@ -135,4 +135,5 @@ if appstream_util.found() endif subdir('ontology') +subdir('templates') subdir('tracker') diff --git a/data/templates/document.odt b/data/templates/document.odt new file mode 100644 index 0000000000000000000000000000000000000000..2a9ef52dea635c13fe1be2a50b958263d7032059 GIT binary patch literal 8197 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 NK43)9iJ-c^`!9P>18)ET literal 0 HcmV?d00001 diff --git a/data/templates/meson.build b/data/templates/meson.build new file mode 100644 index 0000000000..1b00e15ab1 --- /dev/null +++ b/data/templates/meson.build @@ -0,0 +1,9 @@ +templates_data = files( + 'document.odt', + 'spreadsheet.ods', + 'presentation.odp' +) + +install_data(templates_data, + install_dir: join_paths(datadir, 'nautilus', 'templates') +) \ No newline at end of file diff --git a/data/templates/presentation.odp b/data/templates/presentation.odp new file mode 100644 index 0000000000000000000000000000000000000000..6095afffb06def8fa0eed3cc7d639af5980fe9b9 GIT binary patch literal 13165 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 O=%4_A{^^Sv;C}%QZ6hK8 literal 0 HcmV?d00001 diff --git a/data/templates/spreadsheet.ods b/data/templates/spreadsheet.ods new file mode 100644 index 0000000000000000000000000000000000000000..16d4f2348424352a11bd5bc1b3c8e2f45413cce5 GIT binary patch literal 6956 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 literal 0 HcmV?d00001 diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c index 0b48c822e4..d65d4cf582 100644 --- a/src/nautilus-files-view.c +++ b/src/nautilus-files-view.c @@ -350,6 +350,11 @@ static void set_search_query_internal (NautilusFilesView *files_view, static gboolean nautilus_files_view_is_read_only (NautilusFilesView *view); +static void nautilus_files_view_new_file (NautilusFilesView *directory_view, + const char *parent_uri, + const char *target_filename, + NautilusFile *source); + G_DEFINE_TYPE_WITH_CODE (NautilusFilesView, nautilus_files_view, ADW_TYPE_BIN, @@ -2068,9 +2073,26 @@ new_file_dialog_controller_on_name_accepted (NautilusFileNameWidgetController *c NautilusFilesView *self) { NautilusFilesViewPrivate *priv; + gchar *template_name = NULL; + g_autofree gchar *template_path = NULL; + g_autoptr (GFile) template_location = NULL; + g_autofree gchar *name = NULL; + g_autoptr (NautilusFile) file = NULL; priv = nautilus_files_view_get_instance_private (self); + template_name = nautilus_new_file_dialog_controller_get_template_name (NAUTILUS_NEW_FILE_DIALOG_CONTROLLER (controller)); + name = nautilus_file_name_widget_controller_get_new_name (controller); + + if (template_name != NULL) + { + template_path = g_build_filename (NAUTILUS_DATADIR, "templates", template_name, NULL); + template_location = g_file_new_for_path (template_path); + file = nautilus_file_get (template_location); + } + + nautilus_files_view_new_file (self, NULL, name, file); + g_clear_object (&priv->new_file_controller); gtk_widget_grab_focus (GTK_WIDGET (self)); @@ -2428,6 +2450,7 @@ nautilus_files_view_new_file_with_initial_contents (NautilusFilesView *view, static void nautilus_files_view_new_file (NautilusFilesView *directory_view, const char *parent_uri, + const char *target_filename, NautilusFile *source) { NewFolderData *data; @@ -2445,7 +2468,7 @@ nautilus_files_view_new_file (NautilusFilesView *directory_view, { nautilus_files_view_new_file_with_initial_contents (directory_view, parent_uri != NULL ? parent_uri : container_uri, - NULL, + target_filename, NULL, 0); g_free (container_uri); @@ -2458,7 +2481,7 @@ nautilus_files_view_new_file (NautilusFilesView *directory_view, nautilus_file_operations_new_file_from_template (GTK_WIDGET (directory_view), parent_uri != NULL ? parent_uri : container_uri, - NULL, + target_filename, source_uri, new_folder_done, data); -- GitLab