diff options
author | Ignacy Kuchciński <ignacykuchcinski@gmail.com> | 2022-07-15 23:33:46 +0200 |
---|---|---|
committer | Ignacy Kuchciński <ignacykuchcinski@gmail.com> | 2022-09-11 00:03:53 +0200 |
commit | 62d9dea807f09e3887cf83120bf5a32ec25cd9ac (patch) | |
tree | 1906e31b867e99dc1fd999c2b7711d7e786fb476 | |
parent | 72f4d3f21826f6edbc6d0b39e90d8514dbddddc2 (diff) | |
download | nautilus-62d9dea807f09e3887cf83120bf5a32ec25cd9ac.tar.gz |
files-view: Add "New File" menu item
-rw-r--r-- | src/nautilus-files-view.c | 148 | ||||
-rw-r--r-- | src/resources/ui/nautilus-files-view-context-menus.ui | 5 |
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> |