2 # Copyright (c) 2009 Martin Decky
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
9 # - Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # - Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # - The name of the author may not be used to endorse or promote products
15 # derived from this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 Text User Interface wrapper
35 def call_dlg(dlgcmd
, *args
, **kw
):
36 "Wrapper for calling 'dialog' program"
38 indesc
, outdesc
= os
.pipe()
45 for key
, val
in kw
.items():
46 dlgargs
.append('--' + key
)
50 os
.execlp(dlgcmd
, *dlgargs
)
55 errout
= os
.fdopen(indesc
, 'r')
58 pid
, status
= os
.wait()
64 if (not os
.WIFEXITED(status
)):
69 status
= os
.WEXITSTATUS(status
)
82 dlgcmd
= os
.environ
.get('DIALOG', 'dialog')
83 if (call_dlg(dlgcmd
, '--print-maxsize')[0] != 0):
91 def width_fix(screen
, width
):
92 "Correct width to screen size"
94 if (width
+ width_extra
> screen
.width
):
95 width
= screen
.width
- width_extra
102 def height_fix(screen
, height
):
103 "Correct height to screen size"
105 if (height
+ height_extra
> screen
.height
):
106 height
= screen
.height
- height_extra
109 height
= screen
.height
114 "Initialize the screen"
117 return snack
.SnackScreen()
121 def screen_done(screen
):
127 def choice_window(screen
, title
, text
, options
, position
):
128 "Create options menu"
131 for option
in options
:
133 if (length
> maxopt
):
137 height
= len(options
)
140 width
= width_fix(screen
, width
+ width_extra
)
141 height
= height_fix(screen
, height
)
148 buttonbar
= snack
.ButtonBar(screen
, ('Done', 'Cancel'))
149 textbox
= snack
.TextboxReflowed(width
, text
)
150 listbox
= snack
.Listbox(height
, scroll
= large
, returnExit
= 1)
153 for option
in options
:
154 listbox
.append(option
, cnt
)
157 if (position
!= None):
158 listbox
.setCurrent(position
)
160 grid
= snack
.GridForm(screen
, title
, 1, 3)
161 grid
.add(textbox
, 0, 0)
162 grid
.add(listbox
, 0, 1, padding
= (0, 1, 0, 1))
163 grid
.add(buttonbar
, 0, 2, growx
= 1)
165 retval
= grid
.runOnce()
167 return (buttonbar
.buttonPressed(retval
), listbox
.current())
174 for option
in options
:
175 args
.append(str(cnt
+ 1))
181 if (position
!= None):
182 kw
['default-item'] = str(position
+ 1)
184 status
, data
= call_dlg(dlgcmd
, '--title', title
, '--extra-button', '--extra-label', 'Done', '--menu', text
, str(height
+ height_extra
), str(width
+ width_extra
), str(cnt
), *args
, **kw
)
187 return ('cancel', None)
190 choice
= int(data
) - 1
192 return ('cancel', None)
195 return (None, choice
)
197 return ('done', choice
)
199 sys
.stdout
.write("\n *** %s *** \n%s\n\n" % (title
, text
))
201 maxcnt
= len(str(len(options
)))
203 for option
in options
:
204 sys
.stdout
.write("%*s. %s\n" % (maxcnt
, cnt
+ 1, option
))
207 sys
.stdout
.write("\n%*s. Done\n" % (maxcnt
, '0'))
208 sys
.stdout
.write("%*s. Quit\n\n" % (maxcnt
, 'q'))
211 if (position
!= None):
212 sys
.stdout
.write("Selection[%s]: " % str(position
+ 1))
215 sys
.stdout
.write("Selection[1]: ")
217 sys
.stdout
.write("Selection[0]: ")
218 inp
= sys
.stdin
.readline()
223 if (not inp
.strip()):
224 if (position
!= None):
225 return (None, position
)
232 if (inp
.strip() == 'q'):
233 return ('cancel', None)
236 choice
= int(inp
.strip())
243 if (choice
< 1) or (choice
> len(options
)):
246 return (None, choice
- 1)
248 def error_dialog(screen
, title
, msg
):
254 width
= width_fix(screen
, width
)
256 buttonbar
= snack
.ButtonBar(screen
, ['Ok'])
257 textbox
= snack
.TextboxReflowed(width
, msg
)
259 grid
= snack
.GridForm(screen
, title
, 1, 2)
260 grid
.add(textbox
, 0, 0, padding
= (0, 0, 0, 1))
261 grid
.add(buttonbar
, 0, 1, growx
= 1)
264 call_dlg(dlgcmd
, '--title', title
, '--msgbox', msg
, '6', str(width
+ width_extra
))
266 sys
.stdout
.write("\n%s: %s\n" % (title
, msg
))