#!/usr/bin/env python import pygtk pygtk.require('2.0') import gtk import string import pipes import os import sys class DnDIconButtonConfigData: def __init__(self): self.again_button_text="again." self.command_to_exec="%s" self.message_on_click="Drag and drop a file into the button." self.show_additional_flag=False self.command_to_exec_in_terminal="lxterminal -e %s" self.quate_command=False self.message_title_on_click="NOTE" self.dialog_title_on_click="note" self.button_toggle_text="Show optional button." self.entry_command_label= "Command to execute: " self.entry_terminal_label="Command to run terminal: " self.button_quote_text="quote" self.last_executed_command=None image=gtk.Image () image.set_from_stock(gtk.STOCK_EXECUTE,gtk.ICON_SIZE_DIALOG) self.button_exec_image=image self.button_exec_label="" class NoteArea: def __init__(self,title,message): label = gtk.Label() label.set_line_wrap(True) label.set_markup(message) frame=gtk.Frame() frame.add(label) frame.set_label(title) self.frame=frame self.label=label def get_frame(self): return self.frame def get_label(self): return self.label class DnDIconButtonArea: TARGET_TYPE_TEXT = 80 TARGET_TYPE_TEXT_URI_LIST = 12345 ACCEPTABLES = [ ( "text/plain", 0, TARGET_TYPE_TEXT ),('text/uri-list', 0, TARGET_TYPE_TEXT_URI_LIST) ] def __init__(self,dndIconButtonConfigData=None): if dndIconButtonConfigData: self.config=dndIconButtonConfigData else: self.config=DnDIconButtonConfigData() box = gtk.VBox(False,0) box.show() # button = gtk.Button(stock=gtk.STOCK_EXECUTE) button = gtk.Button() if self.config.button_exec_image: button.set_image(self.config.button_exec_image) if self.config.button_exec_label: button.set_label(self.config.button_exec_label) button.show() button.connect("drag_data_received", self.receiveDnD) button.connect('clicked', self.inform_and_preference) button.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, self.ACCEPTABLES, gtk.gdk.ACTION_COPY) box.add(button) self.additionalbox=gtk.VBox(False,0) button = gtk.Button(self.config.again_button_text) self.additionalbox.pack_start(button,expand=False, fill=False) button.connect('clicked', self.againbutton_clicked) self.additionalbox.show_all() if not self.config.show_additional_flag: self.additionalbox.hide() self.config.show_additional_flag=False box.pack_start(self.additionalbox,expand=False, fill=False) self.vbox=box def get_vbox(self): return self.vbox def toggle_additional_box(self,button): if self.config.show_additional_flag: self.additionalbox.hide() else: self.additionalbox.show() self.config.show_additional_flag=not self.config.show_additional_flag def inform_and_preference(self,button): self.inform_and_preference_by_dialog() def inform_and_preference_by_dialog(self): dialog = gtk.Dialog(self.config.dialog_title_on_click,None, gtk.DIALOG_MODAL, (gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT)) vbox=gtk.VBox() area=NoteArea(self.config.message_title_on_click,self.config.message_on_click) vbox.add(area.get_frame()) area.get_frame().show_all() hbox=gtk.HButtonBox() checkbutton_showoptional=gtk.CheckButton(self.config.button_toggle_text) checkbutton_showoptional.set_active(self.config.show_additional_flag) hbox.add(checkbutton_showoptional) hbox.show_all() vbox.add(hbox) hbox=gtk.HBox() label=gtk.Label() label.set_markup(self.config.entry_command_label) hbox.add(label) entry_command=gtk.Entry() entry_command.set_text(self.config.command_to_exec) hbox.add(entry_command) hbox.show_all() vbox.add(hbox) hbox=gtk.HBox() hbox.show() label=gtk.Label() label.set_markup(self.config.entry_terminal_label) hbox.add(label) entry_terminal=gtk.Entry() entry_terminal.set_text(self.config.command_to_exec_in_terminal) hbox.add(entry_terminal) checkbutton_quote=gtk.CheckButton(self.config.button_quote_text) checkbutton_quote.set_active(self.config.quate_command) hbox.add(checkbutton_quote) hbox.show_all() vbox.add(hbox) vbox.show() dialog.vbox.pack_start(vbox) r = dialog.run() self.config.command_to_exec=entry_command.get_text() self.config.command_to_exec_in_terminal=entry_terminal.get_text() self.config.show_additional_flag=checkbutton_showoptional.get_active() if self.config.show_additional_flag: self.additionalbox.show() else: self.additionalbox.hide() self.config.quate_command=checkbutton_quote.get_active() dialog.destroy() return (r,None) def receiveDnD(self, widget, context, x, y, selection, targetType,t): if targetType == self.TARGET_TYPE_TEXT: print ("Not yet implemented for text.") elif targetType == self.TARGET_TYPE_TEXT_URI_LIST: self.exec_in_terminal(selection.data) def uris2list(self,data_of_uris): r=[ri for ri in data_of_uris.splitlines() if ri != '\x00'] return r def urilist2fullapthlist(self,uris): r=[ri[7:] for ri in uris if ri.startswith("file://")] return r def exec_in_terminal(self,data_of_uris): urilist=self.uris2list(data_of_uris) quatedurils=[ pipes.quote(argi) for argi in urilist] if quatedurils == []: firsturi="" else: firsturi=quatedurils[0] alluris=" ".join(quatedurils) fullpaths=self.urilist2fullapthlist(urilist) quatedfullpaths=[ pipes.quote(argi) for argi in fullpaths] if quatedfullpaths == []: firstpath="" else: firstpath=quatedfullpaths[0] allpaths=" ".join(quatedfullpaths) if self.config.command_to_exec.find("%u")>=0: command=self.config.command_to_exec.replace("%u",firsturi) elif self.config.command_to_exec.find("%U")>=0: command=self.config.command_to_exec.replace("%U",alluris) elif self.config.command_to_exec.find("%f")>=0: command=self.config.command_to_exec.replace("%f",firstpath) elif self.config.command_to_exec.find("%F")>=0: command=self.config.command_to_exec.replace("%u",allpaths) elif self.config.command_to_exec.find("%s")>=0: command=self.config.command_to_exec.replace("%s",allpaths) else: command=self.config.command_to_exec+" "+allpaths if self.config.quate_command: command=pipes.quote(command) command=self.config.command_to_exec_in_terminal % command print command self.config.last_executed_command=command os.system(command) ############################ def exec_last_command(self): print self.config.last_executed_command if self.config.last_executed_command: os.system(self.config.last_executed_command) def againbutton_clicked(self,button): self.exec_last_command() class DnDIconButtonMain: def __init__(self,title,width,height,dndIconButtonConfigData): if width <0: width = -width if height <= 0: height=width self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_default_size(width,height) self.window.set_title(title) self.window.connect("destroy", lambda w: gtk.main_quit()) self.window.show() area = DnDIconButtonArea(dndIconButtonConfigData) self.window.add(area.get_vbox()) def main(): config=DnDIconButtonConfigData() window_width=100 window_height=0 window_title="" argv= sys.argv[:] while argv!= []: arg=argv.pop(0) if arg=="-e": config.command_to_exec=argv.pop(0) if config.command_to_exec.find("%s")<0: config.command_to_exec=config.command_to_exec+" %s" elif arg=="-t": arg=argv.pop(0) if arg=="lxde" or arg=="lxterminal" or arg=="l": config.command_to_exec_in_terminal="lxterminal -e %s" config.quate_command=False elif arg=="gnome" or arg=="gnome-terminal" or arg=="gterm" or arg=="g": config.command_to_exec_in_terminal="gnome-terminal -x %s" config.quate_command=False elif arg=="kde" or arg=="konsole": config.command_to_exec_in_terminal="konsole -e %s" config.quate_command=False elif arg=="xfce" or arg=="Terminal" or arg=="xf": config.command_to_exec_in_terminal="Terminal -x %s" config.quate_command=False elif arg=="kterm": config.command_to_exec_in_terminal="kterm -e %s" config.quate_command=False elif arg=="xterm" or arg=="x": config.command_to_exec_in_terminal="xterm -e %s" config.quate_command=False if config.command_to_exec_in_terminal.find("%s")<0: config.command_to_exec_in_terminal=config.command_to_exec_in_terminal+" %s" elif arg=="-terminal": config.command_to_exec_in_terminal=argv.pop(0) if config.command_to_exec_in_terminal.find("%s")<0: config.command_to_exec_in_terminal=config.command_to_exec_in_terminal+" %s" elif arg=="-quote-command": config.quate_command=True elif arg=="-message": config.message_on_click=argv.pop(0) elif arg=="-showoptional": config.show_additional_flag=True elif arg=="-message-title": config.message_title_on_click=argv.pop(0) elif arg=="-dialog-title": config.dialog_title_on_click=argv.pop(0) elif arg=="-againbutton-name": config.again_button_text=argv.pop(0) elif arg=="-againbutton-name": config.again_button_text=argv.pop(0) elif arg=="-commandentry-label": config.entry_command_label=argv.pop(0) elif arg=="-terminalentry-label": config.entry_terminal_label=argv.pop(0) elif arg=="-togglequote-label": config.button_quote_text=argv.pop(0) elif arg=="-toggleoptional-label": config.button_toggle_text=argv.pop(0) elif arg=="-execbutton-label": config.button_exec_label=argv.pop(0) elif arg=="-execbutton-image": arg=argv.pop(0) if arg == "None" or arg == "": config.button_exec_image=None else: image=gtk.Image () image.set_from_file(arg) config.button_exec_image=image elif arg=="-lastexecutedcommand": config.last_executed_command=argv.pop(0) elif arg=="-width": window_width=int(argv.pop(0)) elif arg=="-height": window_height=int(argv.pop(0)) elif arg=="-window-title": window_title=argv.pop(0) DnDIconButtonMain(window_title,window_width,window_height,config) gtk.main() if __name__ == "__main__": main()