summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgnacy Kuchciński <ignacykuchcinski@gmail.com>2022-07-15 23:33:46 +0200
committerIgnacy Kuchciński <ignacykuchcinski@gmail.com>2022-09-11 00:03:53 +0200
commit62d9dea807f09e3887cf83120bf5a32ec25cd9ac (patch)
tree1906e31b867e99dc1fd999c2b7711d7e786fb476
parent72f4d3f21826f6edbc6d0b39e90d8514dbddddc2 (diff)
downloadnautilus-62d9dea807f09e3887cf83120bf5a32ec25cd9ac.tar.gz
files-view: Add "New File" menu item
-rw-r--r--src/nautilus-files-view.c148
-rw-r--r--src/resources/ui/nautilus-files-view-context-menus.ui5
2 files changed, 152 insertions, 1 deletions
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index 4d4b2f4ac..0b48c822e 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;
@@ -2042,6 +2049,45 @@ new_folder_dialog_controller_on_cancelled (NautilusNewFolderDialogController *co
}
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)
{
@@ -2421,6 +2467,83 @@ nautilus_files_view_new_file (NautilusFilesView *directory_view,
}
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,
gpointer user_data)
@@ -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 },
@@ -7415,6 +7547,9 @@ real_update_actions_state (NautilusFilesView *view)
"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),
!is_read_only && !selection_contains_recent &&
@@ -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 1bcd861b0..c51170e77 100644
--- a/src/resources/ui/nautilus-files-view-context-menus.ui
+++ b/src/resources/ui/nautilus-files-view-context-menus.ui
@@ -7,6 +7,11 @@
<attribute name="action">view.new-folder</attribute>
</item>
<item>
+ <attribute name="label" translatable="yes">_New File</attribute>
+ <attribute name="action">view.new-file</attribute>
+ <attribute name="hidden-when">action-disabled</attribute>
+ </item>
+ <item>
<attribute name="label" translatable="yes">Open _With…</attribute>
<attribute name="action">view.open-current-directory-with-other-application</attribute>
</item>