1
0
mirror of https://github.com/wting/autojump synced 2024-10-27 20:34:07 +00:00
wting_autojump/jumpapplet

307 lines
9.8 KiB
Plaintext
Raw Permalink Normal View History

2011-01-06 12:00:08 +00:00
#!/usr/bin/env python2
2009-03-27 10:46:21 +00:00
2009-05-14 19:43:04 +00:00
#Copyright Joel Schaerer and Pierre Gueth 2008, 2009
2009-05-13 09:32:19 +00:00
#This file is part of autojump
#autojump is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#autojump is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with autojump. If not, see <http://www.gnu.org/licenses/>.
2009-03-27 10:46:21 +00:00
import subprocess
import cPickle
import os.path
import os
import sys
import pygtk
pygtk.require('2.0')
import gtk
from autojump import open_dic,get_dic_file
2009-03-27 10:46:21 +00:00
defaults={}
2009-03-27 10:46:21 +00:00
actions={}
#directory finding helpers, conforming to the XDG Base Directory Specification
def data_dir():
xdg_data_dir = os.environ.get('XDG_DATA_HOME') or os.path.join(os.environ['HOME'], '.local', 'share')
return os.path.join(xdg_data_dir, 'autojump')
def config_dir():
xdg_config_dir = os.environ.get('XDG_CONFIG_HOME') or os.path.join(os.environ['HOME'], '.config')
return os.path.join(xdg_config_dir, 'autojump')
#decorator truff
2009-03-27 10:46:21 +00:00
def action(validator,name=None):
if name is None:
def wrapper(action):
actions[action.__name__]=(action,validator)
else:
def wrapper(action):
actions[name]=(action,validator)
return wrapper
#validator helper
2009-03-27 11:25:14 +00:00
def has_child_dir(dirname,recursion=0):
2009-03-27 10:46:21 +00:00
def wrapper(path):
2009-03-27 11:25:14 +00:00
k=recursion
ii=""
while k>=0:
if os.path.isdir(os.path.join(path,ii,dirname)): return True
k-=1
ii=os.path.join("..",ii)
return False
2009-03-27 10:46:21 +00:00
return wrapper
def has_child_file(filename):
def wrapper(path):
return os.path.isfile(os.path.join(path,filename))
return wrapper
def load_paths(maxpath=10):
path_dict=open_dic(get_dic_file())
path_dict=path_dict.items()
path_dict.sort(key=lambda x: x[1],reverse=True)
return [path for path,score in path_dict[:maxpath]]
2009-03-27 10:46:21 +00:00
def load_settings_file():
filename = os.path.join(config_dir(), 'jumpapplet_py')
#migration from old location
old_filename = os.path.join(os.environ['HOME'], '.jumpapplet_py')
if not os.path.exists(filename) and os.path.exists(old_filename):
os.rename(old_filename, filename)
print "loading settings"
global defaults
dic_file = filename
try:
aj_file=open(dic_file,'r')
defaults=cPickle.load(aj_file)
aj_file.close()
except IOError:
print "no config file"
pass
if not "terminal" in defaults: defaults["terminal"]="gnome-terminal"
if not "navigator" in defaults: defaults["navigator"]="nautilus"
2009-04-16 21:17:40 +00:00
if not "maxpath" in defaults: defaults["maxpath"]=15
if not "invert" in defaults: defaults["invert"]=False
if not "collapse" in defaults: defaults["collapse"]=True
create_actions()
def save_settings_file(filename=None):
directory = config_dir()
if not filename:
filename = os.path.join(directory, 'jumpapplet_py')
if not os.path.exists(directory):
os.makedirs(directory)
print "saving settings"
dic_file= filename
aj_file=open(dic_file,'w')
cPickle.dump(defaults,aj_file)
aj_file.close()
2009-03-27 10:46:21 +00:00
def get_actions(path):
return [(name,action) for name,(action,validator) in actions.items() if validator(path)]
def popup(sender,button,activation):
2009-04-16 21:17:40 +00:00
paths=load_paths(maxpath=defaults["maxpath"])
2009-03-27 10:46:21 +00:00
if defaults["collapse"]:
def collapse_home(path):
return path.replace(os.path.expanduser('~'),"~")
else:
def collapse_home(path):
return path
2009-05-14 19:43:04 +00:00
2009-03-27 10:46:21 +00:00
menu=gtk.Menu()
2009-04-16 21:17:40 +00:00
if defaults["invert"]:
2009-05-14 19:43:04 +00:00
item=gtk.ImageMenuItem(stock_id=gtk.STOCK_QUIT)
2009-04-16 21:17:40 +00:00
item.connect("activate",quit)
menu.append(item)
2009-05-14 19:43:04 +00:00
item=gtk.ImageMenuItem(stock_id=gtk.STOCK_PREFERENCES)
2009-04-16 21:17:40 +00:00
item.connect("activate",settings)
2009-03-27 10:46:21 +00:00
menu.append(item)
2009-04-16 21:17:40 +00:00
menu.append(gtk.SeparatorMenuItem())
for path in reversed(paths):
actions=get_actions(path)
if not actions: continue
item=gtk.MenuItem(collapse_home(path),use_underline=False)
2009-04-16 21:17:40 +00:00
submenu=gtk.Menu()
item.set_submenu(submenu)
for name,action in actions:
subitem=gtk.MenuItem(name)
subitem.connect("activate",action,path)
submenu.append(subitem)
menu.append(item)
else:
for path in paths:
actions=get_actions(path)
if not actions: continue
item=gtk.MenuItem(collapse_home(path),use_underline=False)
2009-04-16 21:17:40 +00:00
submenu=gtk.Menu()
item.set_submenu(submenu)
for name,action in actions:
subitem=gtk.MenuItem(name)
subitem.connect("activate",action,path)
submenu.append(subitem)
menu.append(item)
menu.append(gtk.SeparatorMenuItem())
2009-05-14 19:43:04 +00:00
item=gtk.ImageMenuItem(stock_id=gtk.STOCK_PREFERENCES)
2009-04-16 21:17:40 +00:00
item.connect("activate",settings)
menu.append(item)
2009-05-14 19:43:04 +00:00
item=gtk.ImageMenuItem(stock_id=gtk.STOCK_QUIT)
2009-04-16 21:17:40 +00:00
item.connect("activate",quit)
menu.append(item)
2009-03-27 10:46:21 +00:00
menu.show_all()
menu.popup(None,None,gtk.status_icon_position_menu,button,activation,sender)
def settings(sender):
2009-05-14 19:43:04 +00:00
window=gtk.Dialog("jump applet preferences",None,gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_SAVE,gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL))
window.set_border_width(3)
window.set_resizable(False)
2009-05-14 19:43:04 +00:00
if os.path.isfile("icon.png"): window.set_icon_from_file("icon.png")
elif os.path.isfile("/usr/share/autojump/icon.png"): window.set_icon_from_file("/usr/share/autojump/icon.png")
2009-05-14 19:43:04 +00:00
vbox=gtk.Table(5,2)
vbox.set_row_spacings(3)
2009-05-14 19:43:04 +00:00
window.get_child().add(vbox)
def add_string_setting(name,label,nsettings):
label=gtk.Label(label+' ')
label.set_alignment(1.,.5)
entry=gtk.Entry()
if name in defaults: entry.set_text(defaults[name])
2009-04-16 21:17:40 +00:00
vbox.attach(label,0,1,nsettings,nsettings+1)
vbox.attach(entry,1,2,nsettings,nsettings+1)
return (name,entry)
def add_integer_setting(name,label,nsettings):
label=gtk.Label(label+' ')
label.set_alignment(1.,.5)
2009-04-16 21:17:40 +00:00
entry=gtk.SpinButton()
entry.set_range(5,35)
entry.set_numeric(True)
entry.set_increments(1,5)
entry.set_snap_to_ticks(True)
if name in defaults: entry.set_value(defaults[name])
vbox.attach(label,0,1,nsettings,nsettings+1)
vbox.attach(entry,1,2,nsettings,nsettings+1)
return (name,entry)
def add_bool_setting(name,label,nsettings):
entry=gtk.CheckButton(label=label,use_underline=False)
2009-04-16 21:17:40 +00:00
if name in defaults: entry.set_active(defaults[name])
vbox.attach(entry,0,2,nsettings,nsettings+1)
return (name,entry)
entries=[]
2009-05-14 19:43:04 +00:00
entries.append(add_string_setting("terminal","Terminal program",0))
entries.append(add_string_setting("navigator","Navigator program",1))
entries.append(add_integer_setting("maxpath","Number of directories",2))
entries.append(add_bool_setting("invert","List directories in reverse order",3))
entries.append(add_bool_setting("collapse","Collapse home directory to ~",4))
2009-05-14 19:43:04 +00:00
window.connect("response",save_settings,entries,window)
window.show_all();
2009-05-14 19:43:04 +00:00
def save_settings(sender,response,entries,window):
window.hide_all()
2009-05-14 19:43:04 +00:00
if response!=gtk.RESPONSE_OK: return
global defaults
for name,entry in entries:
2009-04-16 21:17:40 +00:00
try:
defaults[name]=int(entry.get_text())
except (ValueError,AttributeError):
try:
defaults[name]=entry.get_active()
except AttributeError:
defaults[name]=entry.get_text()
save_settings_file()
create_actions()
2009-03-27 10:46:21 +00:00
def init():
2009-04-16 21:17:40 +00:00
load_settings_file()
2009-03-27 11:04:59 +00:00
if os.path.isfile("icon.png"): icon=gtk.status_icon_new_from_file("icon.png")
elif os.path.isfile("/usr/share/autojump/icon.png"): icon=gtk.status_icon_new_from_file("/usr/share/autojump/icon.png")
2009-03-27 16:13:56 +00:00
else: icon=gtk.status_icon_new_from_icon_name("help")
2009-03-27 10:46:21 +00:00
icon.set_visible(True)
icon.connect("popup-menu",popup)
def quit(sender):
gtk.main_quit()
######################################################
#insert other actions here using the action decorator#
######################################################
def create_actions():
global actions
actions={}
@action(has_child_dir(".git",recursion=3))
def gitk(sender,path):
if not os.fork():
os.chdir(path)
subprocess.Popen(['gitk']).wait()
sys.exit()
@action(has_child_file("CMakeCache.txt"),"configure")
def cmake(sender,path):
if not os.fork():
os.chdir(path)
subprocess.Popen(['cmake-gui','.']).wait()
sys.exit()
@action(os.path.isdir)
def terminal(sender,path):
print "launch terminal '%s'" % defaults["terminal"]
if not os.fork():
try:
2009-04-17 13:31:26 +00:00
if defaults["terminal"]=="konsole":
subprocess.Popen([defaults["terminal"],"--workdir=%s"%path]).wait()
else:
os.chdir(path)
subprocess.Popen([defaults["terminal"]]).wait()
except OSError:
pass
sys.exit()
@action(os.path.isdir)
def navigator(sender,path):
print "launch navigator '%s'" % defaults["navigator"]
if not os.fork():
try:
subprocess.Popen([defaults["navigator"],path]).wait()
except OSError:
pass
sys.exit()
2009-03-27 10:46:21 +00:00
if __name__=='__main__':
init()
gtk.main()