aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsowgro <tpoke.ferrari@gmail.com>2025-07-22 02:22:52 -0400
committersowgro <tpoke.ferrari@gmail.com>2025-07-22 02:22:52 -0400
commit6ab8db2d2472abd545cb4873ae21ed11adc8d817 (patch)
treeddcee30958740ab0743e3c80ff53c5ded36e8805
downloadnautilus-newfile-6ab8db2d2472abd545cb4873ae21ed11adc8d817.tar.gz
nautilus-newfile-6ab8db2d2472abd545cb4873ae21ed11adc8d817.tar.bz2
nautilus-newfile-6ab8db2d2472abd545cb4873ae21ed11adc8d817.zip
Initial commit
-rw-r--r--README.md10
-rw-r--r--nautilus-newfile.py37
-rw-r--r--new-file-dialog.ui69
3 files changed, 116 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fc697a1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,10 @@
+# nautilus-newfile
+Adds a "New File..." option to the context menu of nautilus
+
+### Installation
+Copy both `nautilus-newfile.py` and `new-file-dialog.ui` to `~/.local/share/nautilus-python/extensions`
+
+### Limitations
+- No filename validation is run (needs implementation)
+- Modal is not attached to the nautilus window (limitation of the nautilus extensions api)
+- The newly created file is not automatically selected (limitation of the nautilus extensions api) \ No newline at end of file
diff --git a/nautilus-newfile.py b/nautilus-newfile.py
new file mode 100644
index 0000000..0af4831
--- /dev/null
+++ b/nautilus-newfile.py
@@ -0,0 +1,37 @@
+import os, gi
+gi.require_version('Adw', '1')
+gi.require_version("Gtk", "4.0")
+from gi.repository import Nautilus, GObject, Adw, Gtk, Gio
+from typing import List
+
+@Gtk.Template(filename=os.path.join(__file__, "../new-file-dialog.ui"))
+class NewFileDialog(Adw.Dialog):
+ fileinfo:Gio.FileInfo = None
+ __gtype_name__ = "NewFileDialog"
+ name_entry: Adw.EntryRow = Gtk.Template.Child()
+
+ def __init__(self, fileinfo):
+ super().__init__()
+ self.fileinfo = fileinfo
+
+ @Gtk.Template.Callback()
+ def on_create_clicked(self, _):
+ f: Gio.File = (self.fileinfo.get_location())
+ f.get_child(self.name_entry.get_text()).create(Gio.FileCreateFlags(0), None)
+ self.close()
+
+class NautilusNewfile(GObject.GObject, Nautilus.MenuProvider):
+ def show_dialog(self, _, fileinfo):
+
+ dialog = NewFileDialog(fileinfo)
+ dialog.present()
+
+ def get_background_items(self, fileinfo: Gio.FileInfo) -> List[Nautilus.MenuItem]:
+
+ menuitem = Nautilus.MenuItem(
+ name="ExampleMenuProvider::Foo2",
+ label="New File...",
+ )
+ menuitem.connect('activate', self.show_dialog, fileinfo)
+
+ return [menuitem,] \ No newline at end of file
diff --git a/new-file-dialog.ui b/new-file-dialog.ui
new file mode 100644
index 0000000..2553951
--- /dev/null
+++ b/new-file-dialog.ui
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- from: https://gitlab.gnome.org/GNOME/nautilus/-/blob/main/src/resources/ui/nautilus-new-folder-dialog.ui -->
+<interface>
+ <requires lib="gtk" version="4.0"/>
+ <template class="NewFileDialog" parent="AdwDialog">
+ <property name="title" translatable="yes">New File</property>
+ <property name="content-width">450</property>
+ <property name="child">
+ <object class="AdwToolbarView">
+ <child type="top">
+ <object class="AdwHeaderBar"/>
+ </child>
+ <property name="content">
+ <object class="AdwPreferencesPage">
+ <child>
+ <object class="AdwPreferencesGroup">
+ <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="sg_filename_validator_validate" swapped="no"/>-->
+ <signal name="entry-activated" handler="on_create_clicked" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRevealer">
+<!-- <property name="reveal-child" bind-source="validator" bind-property="has-feedback"/>-->
+ <property name="transition-type">crossfade</property>
+ <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="warning"/>
+ <class name="caption"/>
+ </style>
+ </object>
+ </property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="label" translatable="yes">_Create</property>
+ <property name="use-underline">True</property>
+ <property name="margin-top">6</property>
+ <property name="halign">center</property>
+<!-- <property name="sensitive" bind-source="validator" bind-property="passed" bind-flags="sync-create"/>-->
+ <signal name="clicked" handler="on_create_clicked" swapped="no"/>
+ <style>
+ <class name="pill"/>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </property>
+ </template>
+<!-- <object class="NautilusFilenameValidator" id="validator">-->
+<!-- <property name="new-name" bind-source="name_entry" bind-property="text"/>-->
+<!-- <property name="target-is-folder">true</property>-->
+<!-- <signal name="name-accepted" handler="on_name_accepted" swapped="yes"/>-->
+<!-- <signal name="notify::has-feedback" handler="on_feedback_changed" swapped="yes" object="NewFileDialog"/>-->
+<!-- </object>-->
+</interface>