diff options
Diffstat (limited to 'pym/dcdialog.py')
-rw-r--r-- | pym/dcdialog.py | 412 |
1 files changed, 0 insertions, 412 deletions
diff --git a/pym/dcdialog.py b/pym/dcdialog.py deleted file mode 100644 index 1687392..0000000 --- a/pym/dcdialog.py +++ /dev/null @@ -1,412 +0,0 @@ -# -# Changes and extensions by Carlos Castillo... -# -cvs_id_string="$Id: dcdialog.py,v 1.2 2005/02/26 06:35:20 jstubbs Exp $"[5:-2] - -# -# Module: dialog.py -# Copyright (c) 2000 Robb Shecter <robb@acm.org> -# All rights reserved. -# This source is covered by the GNU GPL. -# -# This module is a Python wrapper around the Linux "dialog" utility -# by Savio Lam and Stuart Herbert. My goals were to make dialog as -# easy to use from Python as possible. The demo code at the end of -# the module is a good example of how to use it. To run the demo, -# execute: -# -# python dialog.py -# -# This module has one class in it, "Dialog". An application typically -# creates an instance of it, and possibly sets the background title option. -# Then, methods can be called on it for interacting with the user. -# -# I wrote this because I want to use my 486-33 laptop as my main -# development computer (!), and I wanted a way to nicely interact with the -# user in console mode. There are apparently other modules out there -# with similar functionality, but they require the Python curses library. -# Writing this module from scratch was easier than figuring out how to -# recompile Python with curses enabled. :) -# -# One interesting feature is that the menu and selection windows allow -# *any* objects to be displayed and selected, not just strings. -# -# TO DO: -# Add code so that the input buffer is flushed before a dialog box is -# shown. This would make the UI more predictable for users. This -# feature could be turned on and off through an instance method. -# Drop using temporary files when interacting with 'dialog' -# (it's possible -- I've already tried :-). -# Try detecting the terminal window size in order to make reasonable -# height and width defaults. Hmmm - should also then check for -# terminal resizing... -# Put into a package name to make more reusable - reduce the possibility -# of name collisions. -# -# NOTES: -# there is a bug in (at least) Linux-Mandrake 7.0 Russian Edition -# running on AMD K6-2 3D that causes core dump when 'dialog' -# is running with --gauge option; -# in this case you'll have to recompile 'dialog' program. -# -# Modifications: -# Jul 2000, Sultanbek Tezadov (http://sultan.da.ru) -# Added: -# - 'gauge' widget *) -# - 'title' option to some widgets -# - 'checked' option to checklist dialog; clicking "Cancel" is now -# recognizable -# - 'selected' option to radiolist dialog; clicking "Cancel" is now -# recognizable -# - some other cosmetic changes and improvements -# - -import os -from tempfile import mktemp -from string import split -from time import sleep - -# -# Path of the dialog executable -# -DIALOG="/usr/bin/dialog" - - -class Dialog: - def __init__(self): - self.__bgTitle = '' # Default is no background title - - - def setBackgroundTitle(self, text): - self.__bgTitle = '--backtitle "%s"' % text - - - def __perform(self, cmd): - """Do the actual work of invoking dialog and getting the output.""" - fName = mktemp() - rv = os.system('%s %s %s 2> %s' % (DIALOG, self.__bgTitle, cmd, fName)) - f = open(fName) - output = f.readlines() - f.close() - os.unlink(fName) - return (rv, output) - - - def __perform_no_options(self, cmd): - """Call dialog w/out passing any more options. Needed by --clear.""" - return os.system(DIALOG + ' ' + cmd) - - - def __handleTitle(self, title): - if len(title) == 0: - return '' - else: - return '--title "%s" ' % title - - - def yesno(self, text, height=10, width=30, title=''): - """ - Put a Yes/No question to the user. - Uses the dialog --yesno option. - Returns a 1 or a 0. - """ - (code, output) = self.__perform(self.__handleTitle(title) +\ - '--yesno "%s" %d %d' % (text, height, width)) - return code == 0 - - - def msgbox(self, text, height=10, width=30, title=''): - """ - Pop up a message to the user which has to be clicked - away with "ok". - """ - self.__perform(self.__handleTitle(title) +\ - '--msgbox "%s" %d %d' % (text, height, width)) - - - def infobox(self, text, height=10, width=30): - """Make a message to the user, and return immediately.""" - self.__perform('--infobox "%s" %d %d' % (text, height, width)) - - - def inputbox(self, text, height=10, width=30, init='', title=''): - """ - Request a line of input from the user. - Returns the user's input or None if cancel was chosen. - """ - (c, o) = self.__perform(self.__handleTitle(title) +\ - '--inputbox "%s" %d %d "%s"' % (text, height, width, init)) - try: - return o[0] - except IndexError: - if c == 0: # empty string entered - return '' - else: # canceled - return None - - - def textbox(self, filename, height=20, width=60, title=None): - """Display a file in a scrolling text box.""" - if title is None: - title = filename - self.__perform(self.__handleTitle(title) +\ - ' --textbox "%s" %d %d' % (filename, height, width)) - - - def menu(self, text, height=15, width=54, list=[]): - """ - Display a menu of options to the user. This method simplifies the - --menu option of dialog, which allows for complex arguments. This - method receives a simple list of objects, and each one is assigned - a choice number. - The selected object is returned, or None if the dialog was canceled. - """ - menuheight = height - 8 - pairs = map(lambda i, item: (i + 1, item), range(len(list)), list) - choices = reduce(lambda res, pair: res + '%d "%s" ' % pair, pairs, '') - (code, output) = self.__perform('--menu "%s" %d %d %d %s' %\ - (text, height, width, menuheight, choices)) - try: - return list[int(output[0]) - 1] - except IndexError: - return None - - def menu_ext(self, text, height=15, width=54, list=[], list2=[]): - """ - Extended the method above for (string, string) pairs, for GLIS UI - """ - menuheight = height - 8 - pairs = [] - for i in range(len(list)): - pairs.append((list2[i],list[i])) - #pairs = map(lambda i, item: (i + 1, item), range(len(list)), list) - choices = reduce(lambda res, pair: res + '%s "%s" ' % pair, pairs, '') - (code, output) = self.__perform('--menu "%s" %d %d %d %s' %\ - (text, height, width, menuheight, choices)) - try: - return output[0] - except IndexError: - return None - - - def checklist(self, text, height=15, width=54, list=[], checked=None): - """ - Returns a list of the selected objects. - Returns an empty list if nothing was selected. - Returns None if the window was canceled. - checked -- a list of boolean (0/1) values; len(checked) must equal - len(list). - """ - if checked is None: - checked = [0]*len(list) - menuheight = height - 8 - triples = map( - lambda i, item, onoff, fs=('off', 'on'): (i + 1, item, fs[onoff]), - range(len(list)), list, checked) - choices = reduce(lambda res, triple: res + '%d "%s" %s ' % triple, - triples, '') - (c, o) = self.__perform('--checklist "%s" %d %d %d %s' %\ - (text, height, width, menuheight, choices)) - try: - output = o[0] - indexList = map(lambda x: int(x[1:-1]), split(output)) - objectList = filter(lambda item, list=list, indexList=indexList: - list.index(item) + 1 in indexList, - list) - return objectList - except IndexError: - if c == 0: # Nothing was selected - return [] - return None # Was canceled - - def checklist_ext(self, text, height=15, width=54, list=[], list2=[], checked=None): - """ - Returns a list of the selected objects. - Returns an empty list if nothing was selected. - Returns None if the window was canceled. - checked -- a list of boolean (0/1) values; len(checked) must equal - len(list). - """ - if checked is None: - checked = [0]*len(list) - menuheight = height - 8 - triples = [] - #equally 3 lines, much more readable - fs = ('off','on') - for i in range(len(list)): - triples.append((list2[i],list[i],fs[checked[i]])) - -## triples = map( -## lambda i, item, onoff, fs=('off', 'on'): (i + 1, item, fs[onoff]), -## range(len(list)), list, checked) - choices = reduce(lambda res, triple: res + '%s "%s" %s ' % triple, - triples, '') - (c, o) = self.__perform('--checklist "%s" %d %d %d %s' %\ - (text, height, width, menuheight, choices)) - try: - output = o[0] - return split(output) -## indexList = map(lambda x: int(x[1:-1]), split(output)) -## objectList = filter(lambda item, list=list, indexList=indexList: -## list.index(item) + 1 in indexList, -## list) -## return objectList - except IndexError: - if c == 0: # Nothing was selected - return [] - return None # Was canceled - - - def radiolist(self, text, height=15, width=54, list=[], selected=0): - """ - Return the selected object. - Returns empty string if no choice was selected. - Returns None if window was canceled. - selected -- the selected item (must be between 1 and len(list) - or 0, meaning no selection). - """ - menuheight = height - 8 - triples = map(lambda i, item: (i + 1, item, 'off'), - range(len(list)), list) - if selected: - i, item, tmp = triples[selected - 1] - triples[selected - 1] = (i, item, 'on') - choices = reduce(lambda res, triple: res + '%d "%s" %s ' % triple, - triples, '') - (c, o) = self.__perform('--radiolist "%s" %d %d %d %s' %\ - (text, height, width, menuheight, choices)) - try: - return list[int(o[0]) - 1] - except IndexError: - if c == 0: - return '' - return None - - - - def clear(self): - """ - Clear the screen. Equivalent to the dialog --clear option. - """ - self.__perform_no_options('--clear') - - - def scrollbox(self, text, height=20, width=60, title=''): - """ - This is a bonus method. The dialog package only has a function to - display a file in a scrolling text field. This method allows any - string to be displayed by first saving it in a temp file, and calling - --textbox. - """ - fName = mktemp() - f = open(fName, 'w') - f.write(text) - f.close() - self.__perform(self.__handleTitle(title) +\ - '--textbox "%s" %d %d' % (fName, height, width)) - os.unlink(fName) - - - def gauge_start(self, perc=0, text='', height=8, width=54, title=''): - """ - Display gauge output window. - Gauge normal usage (assuming that there is an instace of 'Dialog' - class named 'd'): - d.gauge_start() - # do something - d.gauge_iterate(10) # passed throgh 10% - # ... - d.gauge_iterate(100, 'any text here') # work is done - d.stop_gauge() # clean-up actions - """ - cmd = self.__handleTitle(title) +\ - '--gauge "%s" %d %d %d' % (text, height, width, perc) - cmd = '%s %s %s 2> /dev/null' % (DIALOG, self.__bgTitle, cmd) - self.pipe = os.popen(cmd, 'w') - #/gauge_start() - - - def gauge_iterate(self, perc, text=''): - """ - Update percentage point value. - - See gauge_start() function above for the usage. - """ - if text: - text = 'XXX\n%d\n%s\nXXX\n' % (perc, text) - else: - text = '%d\n' % perc - self.pipe.write(text) - self.pipe.flush() - #/gauge_iterate() - - - def gauge_stop(self): - """ - Finish previously started gauge. - - See gauge_start() function above for the usage. - """ - self.pipe.close() - #/gauge_stop() - - - -# -# DEMO APPLICATION -# -if __name__ == '__main__': - """ - This demo tests all the features of the class. - """ - d = Dialog() - d.setBackgroundTitle('dialog.py demo') - - d.infobox( - "One moment... Just wasting some time here to test the infobox...") - sleep(3) - - if d.yesno("Do you like this demo?"): - d.msgbox("Excellent! Here's the source code:") - else: - d.msgbox("Send your complaints to /dev/null") - - d.textbox("dialog.py") - - name = d.inputbox("What's your name?", init="Snow White") - fday = d.menu("What's your favorite day of the week?", - list=["Monday", "Tuesday", "Wednesday", "Thursday", - "Friday (The best day of all)", "Saturday", "Sunday"]) - food = d.checklist("What sandwich toppings do you like?", - list=["Catsup", "Mustard", "Pesto", "Mayonaise", "Horse radish", - "Sun-dried tomatoes"], checked=[0,0,0,1,1,1]) - sand = d.radiolist("What's your favorite kind of sandwich?", - list=["Hamburger", "Hotdog", "Burrito", "Doener", "Falafel", - "Bagel", "Big Mac", "Whopper", "Quarter Pounder", - "Peanut Butter and Jelly", "Grilled cheese"], selected=4) - - # Prepare the message for the final window - bigMessage = "Here are some vital statistics about you:\n\nName: " + name +\ - "\nFavorite day of the week: " + fday +\ - "\nFavorite sandwich toppings:\n" - for topping in food: - bigMessage = bigMessage + " " + topping + "\n" - bigMessage = bigMessage + "Favorite sandwich: " + str(sand) - - d.scrollbox(bigMessage) - - #<># Gauge Demo - d.gauge_start(0, 'percentage: 0', title='Gauge Demo') - for i in range(1, 101): - if i < 50: - msg = 'percentage: %d' % i - elif i == 50: - msg = 'Over 50%' - else: - msg = '' - d.gauge_iterate(i, msg) - sleep(0.1) - d.gauge_stop() - #<># - - d.clear() |