Permalink
Browse files

Use gtk dialog to add/edit panel launchers, so we can have the

full power of a file picker, copy/paste, and icon previews
  • Loading branch information...
mtwebster committed Aug 11, 2012
1 parent 8c0a193 commit daa013de8ca8e4d22c04b569319dc4a47fa58392
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkDialog" id="add-panel-launcher-dialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Add panel launcher...</property>
+ <property name="resizable">False</property>
+ <property name="window_position">center</property>
+ <property name="icon_name">list-add</property>
+ <property name="type_hint">dialog</property>
+ <signal name="close" handler="onDeleteWindow" swapped="no"/>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="add_button">
+ <property name="label" translatable="yes">Add</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="onAdd" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel_button">
+ <property name="label" translatable="yes">Cancel</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <signal name="clicked" handler="onDeleteWindow" swapped="no"/>
+ </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="GtkLayout" id="layout1">
+ <property name="width_request">549</property>
+ <property name="height_request">110</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="width_request">430</property>
+ <property name="height_request">85</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Name </property>
+ </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="application_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Application </property>
+ </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="GtkLabel" id="icon_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Icon</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="app_name">
+ <property name="width_request">300</property>
+ <property name="height_request">35</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <signal name="changed" handler="onNameChanged" swapped="no"/>
+ </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>
+ <placeholder/>
+ </child>
+ <child>
+ <object class="GtkEntry" id="app_path">
+ <property name="width_request">300</property>
+ <property name="height_request">35</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <signal name="changed" handler="onAppChanged" swapped="no"/>
+ </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>
+ <child>
+ <object class="GtkEntry" id="icon_path">
+ <property name="width_request">300</property>
+ <property name="height_request">35</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <signal name="changed" handler="onIconChanged" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFileChooserButton" id="app_picker">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="preview_widget_active">False</property>
+ <property name="use_preview_label">False</property>
+ <signal name="file-set" handler="onAppPicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFileChooserButton" id="icon_picker">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="preview_widget_active">False</property>
+ <property name="use_preview_label">False</property>
+ <signal name="file-set" handler="onIconPicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="icon">
+ <property name="width_request">100</property>
+ <property name="height_request">80</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-execute</property>
+ <property name="icon-size">6</property>
+ </object>
+ <packing>
+ <property name="x">441</property>
+ <property name="y">11</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="0">add_button</action-widget>
+ <action-widget response="0">cancel_button</action-widget>
+ </action-widgets>
+ </object>
+</interface>
@@ -0,0 +1,154 @@
+#! /usr/bin/python -OOt
+
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Gio
+from os.path import expanduser
+from time import sleep as wait
+import os
+import os.path
+import inspect
+import sys
+import gettext
+
+gettext.install("cinnamon", "/usr/share/cinnamon/locale")
+Settings = Gio.Settings.new("org.cinnamon")
+
+_ = gettext.gettext
+
+class Namespace: pass
+
+iface = Namespace()
+
+oldDesktopName = ""
+newDesktopName = ""
+appName = ""
+appPath = ""
+iconPath = ""
+
+editMode = len(sys.argv) > 1
+if editMode:
+ oldDesktopName = sys.argv[1]
+ appName = sys.argv[2]
+ appPath = sys.argv[3]
+ iconPath = sys.argv[4]
+
+def updatePreviewIcon(name):
+ global iface
+ if os.path.exists(name):
+ iface.preview_icon.set_from_file(name)
+ else:
+ iface.preview_icon.set_from_icon_name(name, 6)
+
+def editOrAddLaunchers():
+ makeLauncher()
+ global Settings, desktopName
+ desktopFiles = Settings.get_strv('panel-launchers')
+ if not editMode:
+ desktopFiles.append(newDesktopName)
+ else:
+ i = desktopFiles.index(oldDesktopName)
+ if i >= 0:
+ del desktopFiles[i]
+ desktopFiles.insert(i, newDesktopName)
+ Settings.set_strv('panel-launchers', desktopFiles)
+ Gtk.main_quit(None)
+
+def makeLauncher():
+ global appName, appPath, iconPath, custom_launchers_path, newDesktopName
+ description = _("Custom Launcher")
+ i = 1
+ dir = Gio.file_new_for_path(custom_launchers_path)
+ if not dir.query_exists(None):
+ dir.make_directory_with_parents(None)
+
+ file = Gio.file_parse_name(custom_launchers_path + '/cinnamon-custom-launcher-' + str(i) + '.desktop')
+ while file.query_exists(None):
+ i = i + 1
+ file = Gio.file_parse_name(custom_launchers_path + '/cinnamon-custom-launcher-' + str(i) + '.desktop')
+ file = open(custom_launchers_path+ '/cinnamon-custom-launcher-' + str(i) + '.desktop', "w")
+
+ desktopEntry = "[Desktop Entry]\nName=" + appName + "\nExec=" + appPath + "\nType=Application\n"
+ desktopEntry = desktopEntry + "Description=" + description + "\n"
+ if iconPath == "":
+ iconPath = "application-x-executable"
+ desktopEntry += "Icon=" + iconPath + "\n"
+ print desktopEntry
+ file.write(desktopEntry)
+ file.close()
+ newDesktopName = 'cinnamon-custom-launcher-' + str(i) + '.desktop'
+
+class Handler:
+ def onDeleteWindow(self, *args):
+ Gtk.main_quit(*args)
+
+ def onAdd(self, button):
+ global appPath, appName
+ if appPath == "" or appName == "":
+ return
+ else:
+ editOrAddLaunchers()
+
+ def onIconPicked(self, *args):
+ global iconPath, iface
+ iconPath = iface.icon_picker.get_uri()[7:]
+ iface.icon_path.set_text(iconPath)
+ updatePreviewIcon(iconPath)
+
+ def onAppPicked(self, *args):
+ global appPath, iface
+ appPath = iface.app_picker.get_uri()[7:]
+ iface.file_path.set_text(appPath)
+
+ def onNameChanged(self, *args):
+ global appName, iface
+ appName = iface.app_name.get_text().strip()
+
+ def onAppChanged(self, *args):
+ global appPath, iface
+ appPath = iface.file_path.get_text().strip()
+
+ def onIconChanged(self, *args):
+ global iconPath, iface
+ iconPath = iface.icon_path.get_text().strip()
+ updatePreviewIcon(iconPath)
+
+builder = Gtk.Builder()
+
+userhome = expanduser("~")
+custom_launchers_path = userhome + "/.cinnamon/panel-launchers"
+
+applet_dir = os.path.dirname(inspect.getfile(inspect.currentframe()))
+builder.add_from_file(applet_dir + "/add-panel-launcher.glade")
+
+window = builder.get_object("add-panel-launcher-dialog")
+builder.connect_signals(Handler())
+
+iface.add_button = builder.get_object("add_button")
+iface.cancel_button = builder.get_object("cancel_button")
+iface.preview_icon = builder.get_object("icon")
+iface.app_name = builder.get_object("app_name")
+iface.file_path = builder.get_object("app_path")
+iface.icon_path = builder.get_object("icon_path")
+iface.app_picker = builder.get_object("app_picker")
+iface.icon_picker = builder.get_object("icon_picker")
+
+
+# set static translations (labels, etc..)
+builder.get_object("name_label").set_markup(_("Name"))
+builder.get_object("application_label").set_markup(_("Application"))
+builder.get_object("icon_label").set_markup(_("Icon"))
+builder.get_object("cancel_button").set_label(_("Cancel"))
+builder.get_object("add-panel-launcher-dialog").set_title(_("Add panel launcher..."))
+
+if editMode:
+ iface.app_name.set_text(appName)
+ iface.file_path.set_text(appPath)
+ iface.icon_path.set_text(iconPath)
+ iface.add_button.set_label(_("Update"))
+ updatePreviewIcon(iconPath)
+else:
+ iface.add_button.set_label(_("Add"))
+
+window.show_all()
+Gtk.main()
Oops, something went wrong.

0 comments on commit daa013d

Please sign in to comment.