[alacarte] ItemEditor: Add a directory editor as well



commit 536c2c42ebfb58ef020027afe45a3b6bf81dd9f1
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Jan 11 01:19:56 2013 -0500

    ItemEditor: Add a directory editor as well

 Alacarte/ItemEditor.py   |  139 ++++++++++++++++++++++++------------
 Alacarte/MainWindow.py   |   16 +---
 data/Makefile.am         |    2 +-
 data/directory-editor.ui |  178 ++++++++++++++++++++++++++++++++++++++++++++++
 po/POTFILES.in           |    1 +
 5 files changed, 277 insertions(+), 59 deletions(-)
---
diff --git a/Alacarte/ItemEditor.py b/Alacarte/ItemEditor.py
index 4bf7355..3685c56 100644
--- a/Alacarte/ItemEditor.py
+++ b/Alacarte/ItemEditor.py
@@ -91,34 +91,9 @@ class IconPicker(object):
             self.image.props.file = chooser.get_filename()
         chooser.destroy()
 
-class LauncherEditor(object):
-    def __init__(self, item_path):
-        self.builder = Gtk.Builder()
-        self.builder.add_from_file(os.path.join(config.pkgdatadir, 'launcher-editor.ui'))
-
-        self.dialog = self.builder.get_object('launcher-editor')
-        self.dialog.connect('response', self.on_response)
-
-        self.icon_picker = IconPicker(self.dialog,
-                                      self.builder.get_object('icon-button'),
-                                      self.builder.get_object('icon-image'))
-
-        self.builder.get_object('exec-browse').connect('clicked', self.pick_exec)
-
-        self.builder.get_object('name-entry').connect('changed', self.resync_validity)
-        self.builder.get_object('exec-entry').connect('changed', self.resync_validity)
-
-        self.item_path = item_path
-        self.load()
-        self.resync_validity()
-
-    def resync_validity(self, *args):
-        name_text = self.builder.get_object('name-entry').get_text()
-        exec_text = self.builder.get_object('exec-entry').get_text()
-
-        valid = (name_text and exec_text)
-
-        self.builder.get_object('ok').set_sensitive(valid)
+class ItemEditor(object):
+    def get_keyfile_edits(self):
+        raise NotImplementedError()
 
     def set_text(self, ctl, name):
         try:
@@ -149,34 +124,64 @@ class LauncherEditor(object):
         try:
             self.keyfile.load_from_file(self.item_path, util.KEY_FILE_FLAGS)
         except GError:
-            return
-
-        self.set_text('name-entry', "Name")
-        self.set_text('exec-entry', "Exec")
-        self.set_text('comment-entry', "Comment")
-        self.set_check('terminal-check', "Terminal")
-        self.set_icon('icon-image', "Icon")
-
-    def run(self):
-        self.dialog.present()
+            pass
 
     def save(self):
-        params = dict(Name=self.builder.get_object('name-entry').get_text(),
-                      Exec=self.builder.get_object('exec-entry').get_text(),
-                      Comment=self.builder.get_object('comment-entry').get_text(),
-                      Terminal=self.builder.get_object('terminal-check').get_active(),
-                      Icon=get_icon_string(self.builder.get_object('icon-image')))
-        util.fillKeyFile(self.keyfile, params)
-
+        util.fillKeyFile(self.keyfile, self.get_keyfile_edits())
         contents, length = self.keyfile.to_data()
         with open(self.item_path, 'w') as f:
             f.write(contents)
 
+    def run(self):
+        self.dialog.present()
+
     def on_response(self, dialog, response):
         if response == Gtk.ResponseType.OK:
             self.save()
         self.dialog.destroy()
 
+class LauncherEditor(ItemEditor):
+    def __init__(self, item_path):
+        self.builder = Gtk.Builder()
+        self.builder.add_from_file(os.path.join(config.pkgdatadir, 'launcher-editor.ui'))
+
+        self.dialog = self.builder.get_object('launcher-editor')
+        self.dialog.connect('response', self.on_response)
+
+        self.icon_picker = IconPicker(self.dialog,
+                                      self.builder.get_object('icon-button'),
+                                      self.builder.get_object('icon-image'))
+
+        self.builder.get_object('exec-browse').connect('clicked', self.pick_exec)
+
+        self.builder.get_object('name-entry').connect('changed', self.resync_validity)
+        self.builder.get_object('exec-entry').connect('changed', self.resync_validity)
+
+        self.item_path = item_path
+        self.load()
+        self.resync_validity()
+
+    def resync_validity(self, *args):
+        name_text = self.builder.get_object('name-entry').get_text()
+        exec_text = self.builder.get_object('exec-entry').get_text()
+        valid = (name_text is not None and exec_text is not None)
+        self.builder.get_object('ok').set_sensitive(valid)
+
+    def load(self):
+        super(LauncherEditor, self).load()
+        self.set_text('name-entry', "Name")
+        self.set_text('exec-entry', "Exec")
+        self.set_text('comment-entry', "Comment")
+        self.set_check('terminal-check', "Terminal")
+        self.set_icon('icon-image', "Icon")
+
+    def get_keyfile_edits(self):
+        return dict(Name=self.builder.get_object('name-entry').get_text(),
+                    Exec=self.builder.get_object('exec-entry').get_text(),
+                    Comment=self.builder.get_object('comment-entry').get_text(),
+                    Terminal=self.builder.get_object('terminal-check').get_active(),
+                    Icon=get_icon_string(self.builder.get_object('icon-image')))
+
     def pick_exec(self, button):
         chooser = Gtk.FileChooserDialog(title=_("Choose a command"),
                                         parent=self.dialog,
@@ -187,11 +192,53 @@ class LauncherEditor(object):
             self.builder.get_object('exec-entry').set_text(chooser.get_filename())
         chooser.destroy()
 
+class DirectoryEditor(ItemEditor):
+    def __init__(self, item_path):
+        self.builder = Gtk.Builder()
+        self.builder.add_from_file(os.path.join(config.pkgdatadir, 'directory-editor.ui'))
+
+        self.dialog = self.builder.get_object('directory-editor')
+        self.dialog.connect('response', self.on_response)
+
+        self.icon_picker = IconPicker(self.dialog,
+                                      self.builder.get_object('icon-button'),
+                                      self.builder.get_object('icon-image'))
+
+        self.builder.get_object('name-entry').connect('changed', self.resync_validity)
+
+        self.item_path = item_path
+        self.load()
+        self.resync_validity()
+
+    def resync_validity(self, *args):
+        name_text = self.builder.get_object('name-entry').get_text()
+        valid = (name_text is not None)
+        self.builder.get_object('ok').set_sensitive(valid)
+
+    def load(self):
+        super(DirectoryEditor, self).load()
+        self.set_text('name-entry', "Name")
+        self.set_text('comment-entry', "Comment")
+        self.set_icon('icon-image', "Icon")
+
+    def get_keyfile_edits(self):
+        return dict(Name=self.builder.get_object('name-entry').get_text(),
+                    Comment=self.builder.get_object('comment-entry').get_text(),
+                    Icon=get_icon_string(self.builder.get_object('icon-image')))
+
+def test_editor(path):
+    if path.endswith('.directory'):
+        return DirectoryEditor(path)
+    elif path.endswith('.desktop'):
+        return LauncherEditor(path)
+    else:
+        raise ValueError("Invalid filename, %r" % (path,))
+
 def test():
     import sys
 
     Gtk.Window.set_default_icon_name('alacarte')
-    editor = LauncherEditor(sys.argv[1])
+    editor = test_editor(sys.argv[1])
     editor.dialog.connect('destroy', Gtk.main_quit)
     editor.run()
     Gtk.main()
diff --git a/Alacarte/MainWindow.py b/Alacarte/MainWindow.py
index c3dc42b..29dd1e5 100644
--- a/Alacarte/MainWindow.py
+++ b/Alacarte/MainWindow.py
@@ -30,7 +30,7 @@ gettext.textdomain(config.GETTEXT_PACKAGE)
 
 _ = gettext.gettext
 from Alacarte.MenuEditor import MenuEditor
-from Alacarte.ItemEditor import LauncherEditor
+from Alacarte.ItemEditor import LauncherEditor, DirectoryEditor
 from Alacarte import util
 
 class MainWindow(object):
@@ -233,15 +233,6 @@ class MainWindow(object):
 
             self.item_store.append((show, icon, name, item))
 
-    #this is a little timeout callback to insert new items after
-    #gnome-desktop-item-edit has finished running
-    def waitForNewMenuProcess(self, process, parent_id, file_path):
-        if process.poll() is not None:
-            if os.path.isfile(file_path):
-                self.editor.insertExternalMenu(os.path.split(file_path)[1], parent_id)
-            return False
-        return True
-
     def on_new_menu_button_clicked(self, button):
         menu_tree = self.tree.get_object('menu_tree')
         menus, iter = menu_tree.get_selection().get_selected()
@@ -252,8 +243,9 @@ class MainWindow(object):
         else:
             parent = menus[iter][2]
         file_path = os.path.join(util.getUserDirectoryPath(), util.getUniqueFileId('alacarte-made', '.directory'))
-        process = subprocess.Popen(['gnome-desktop-item-edit', file_path], env=os.environ)
-        GObject.timeout_add(100, self.waitForNewMenuProcess, process, parent.get_menu_id(), file_path)
+
+        editor = DirectoryEditor(file_path)
+        editor.run()
 
     def on_new_item_button_clicked(self, button):
         menu_tree = self.tree.get_object('menu_tree')
diff --git a/data/Makefile.am b/data/Makefile.am
index e2f7340..82fcc96 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -6,7 +6,7 @@ desktopdir = $(datadir)/applications
 ndesktop_in_files = alacarte.desktop.in
 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
 
-pkgdata_DATA = alacarte.ui launcher-editor.ui
+pkgdata_DATA = alacarte.ui launcher-editor.ui directory-editor.ui
 
 CLEANFILES = $(desktop_DATA)
 
diff --git a/data/directory-editor.ui b/data/directory-editor.ui
new file mode 100644
index 0000000..8203855
--- /dev/null
+++ b/data/directory-editor.ui
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkDialog" id="directory-editor">
+    <property name="can_focus">False</property>
+    <property name="border_width">4</property>
+    <property name="title" translatable="yes">Directory Properties</property>
+    <property name="modal">True</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-box">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">4</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="cancel">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="ok">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="hbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">10</property>
+            <child>
+              <object class="GtkAlignment" id="alignment1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">1</property>
+                <property name="yalign">0</property>
+                <property name="yscale">0</property>
+                <child>
+                  <object class="GtkButton" id="icon-button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <child>
+                      <object class="GtkImage" id="icon-image">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="pixel_size">64</property>
+                        <property name="icon_name">folder</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="grid1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="row_spacing">6</property>
+                <property name="column_spacing">10</property>
+                <child>
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Name:</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Comment:</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="name-entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="has_focus">True</property>
+                    <property name="invisible_char">â</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="comment-entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">â</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">cancel</action-widget>
+      <action-widget response="-5">ok</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 033686a..6a3e835 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -5,3 +5,4 @@ Alacarte/ItemEditor.py
 data/alacarte.desktop.in.in
 [type: gettext/glade]data/alacarte.ui
 [type: gettext/glade]data/launcher-editor.ui
+[type: gettext/glade]data/directory-editor.ui



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]