Saturday, April 12, 2008

nlaunch2

I've made a greatly-improved version of nlaunch, which uses sh -c and a different method of passing the exec string to it. Arguments may now be passed to the programs. It still uses the old commands.py, though:

nlaunch2

#!/usr/bin/python
# coding=utf8
import pygtk
pygtk.require('2.0')
import gtk
import os
import math
from commands import Commands
keep_atop = True

class ErrorDialog(object):
def destroy(self, widget, data=None):
self.dialog.destroy()
def __init__(self, message, parent = None):
self.dialog = gtk.Dialog(title = 'Error', parent = parent, flags = gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL)
self.button = gtk.Button('Okay')
self.dialog.action_area.pack_start(self.button, True, True, 1)
self.button.connect('clicked', self.destroy, None)
self.button.show()
self.label = gtk.Label(message)
self.dialog.vbox.pack_start(self.label)
self.label.show()
def run(self):
self.dialog.run()

class LaunchWindow(object):
controls = {
65293 : 'enter',
65307 : 'escape',
65289 : 'tab',
65056 : 'sh-tab'
}
def enter(self, widget, event, data = None):
#print event.keyval
if event.keyval in self.controls.keys():
cmd = self.controls[event.keyval]
if cmd == 'enter':
# Old method
#selected = self.cmdview.get_selection()
#if selected:
# (model, iter) = selected.get_selected()
# if model and iter:
# name, path = model.get_value(iter, 0), model.get_value(iter, 1)
# if os.fork():
# gtk.main_quit()
# #else:
# os.execv(path, (path,))
#self.input.grab_focus()
#self.input.select_region(-1, -1)
# better method
execstring = self.input.get_text()
if os.fork():
gtk.main_quit()
else:
os.execvp('sh', ('sh', '-c', execstring))
elif cmd == 'tab':
selected = self.cmdview.get_selection()
if selected:
(model, iter) = selected.get_selected()
if iter and model.iter_is_valid(iter):
iter = model.iter_next(iter)
if iter and model.iter_is_valid(iter):
self.cmdview.set_cursor_on_cell(model.get_path(iter))
self.cmdview.scroll_to_cell(model.get_path(iter))
else:
iter = model.get_iter_first()
self.cmdview.set_cursor_on_cell(model.get_path(iter))
self.cmdview.scroll_to_cell(model.get_path(iter))
# Stuff relating to replacing content in box
selected = self.cmdview.get_selection()
if selected:
(model, iter) = selected.get_selected()
if model and iter:
name, path = model.get_value(iter, 0), model.get_value(iter, 1)
self.blockchange = True
self.input.set_text(name)
self.blockchange = False
self.input.grab_focus()
self.input.select_region(-1, -1)
elif cmd == 'sh-tab':
selected = self.cmdview.get_selection()
if selected:
(model, iter) = selected.get_selected()
if iter and model.iter_is_valid(iter):
path = list(model.get_path(iter))
if path[0] > 0:
path[0] -= 1
self.cmdview.set_cursor_on_cell(tuple(path))
self.cmdview.scroll_to_cell(model.get_path(iter))
else:
iter = model.get_iter_first()
while model.iter_next(iter):
iter = model.iter_next(iter)
self.cmdview.set_cursor_on_cell(model.get_path(iter))
self.cmdview.scroll_to_cell(model.get_path(iter))
# Stuff relating to replacing content in box
selected = self.cmdview.get_selection()
if selected:
(model, iter) = selected.get_selected()
if model and iter:
name, path = model.get_value(iter, 0), model.get_value(iter, 1)
self.blockchange = True
self.input.set_text(name)
self.blockchange = False
self.input.grab_focus()
self.input.select_region(-1, -1)
elif cmd == 'escape':
gtk.main_quit()
return True
else:
return False
def changed(self, widget, data):
tmp = self.input.get_text()
if tmp != self.oldcmd:
if not self.blockchange:
self.cmds.clear()
if len(tmp):
cmdfound = self.commands.match_str(tmp)
cmdfound.sort(lambda x, y: cmp(x[0], y[0]))
for i in cmdfound:
self.cmds.append(i)
iter = self.cmds.get_iter_first()
if iter and self.cmds.iter_is_valid(iter):
self.cmdview.set_cursor_on_cell(self.cmds.get_path(iter))
self.oldcmd = tmp
def delete_event(self, widget, event, data=None):
return False
def destroy(self, widget, data=None):
gtk.main_quit()
def __init__(self):
self.blockchange = False
self.commands = Commands(os.environ['PATH'])
self.oldcmd = ''
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect('delete_event', self.delete_event)
self.window.connect('destroy', self.destroy)
self.window.set_border_width(4)
self.window.set_title('Launchy')
self.window.set_geometry_hints(None, 300, 400, 400, 900, 400, 800)
self.window.set_position(gtk.WIN_POS_CENTER_ALWAYS)
self.window.set_keep_above(keep_atop)

self.topbox = gtk.VBox(True, 1)
self.topbox.set_homogeneous(False)

self.input = gtk.Entry()
self.input.connect('key-press-event', self.enter, None)
self.input.connect('changed', self.changed, None)
self.input.show()
self.topbox.pack_start(self.input, False, False, 1)

self.cmds = gtk.ListStore(str, str)

self.cmdview = gtk.TreeView(self.cmds)
render = gtk.CellRendererText();
self.cmdview.append_column(gtk.TreeViewColumn('Cmd', render, text = 0));
self.cmdview.append_column(gtk.TreeViewColumn('Fullpath', render, text = 1));

self.cmdwin = gtk.ScrolledWindow()
self.cmdwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
self.cmdwin.add(self.cmdview)
self.cmdview.show()

self.topbox.pack_start(self.cmdwin, True, True, 1)
self.cmdwin.show()



self.window.add(self.topbox)
self.topbox.show()

self.window.show()
self.input.grab_focus()
def main(self):
gtk.main()


window = LaunchWindow()
window.main()

No comments: