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()
46 for key
, val
in kw
.items():
47 dlgargs
.append('--' + key
)
51 os
.execlp(dlgcmd
, *dlgargs
)
56 errout
= os
.fdopen(indesc
, 'r')
59 pid
, status
= os
.wait()
65 if (not os
.WIFEXITED(status
)):
70 status
= os
.WEXITSTATUS(status
)
83 dlgcmd
= os
.environ
.get('DIALOG', 'dialog')
84 if (call_dlg(dlgcmd
, '--print-maxsize')[0] != 0):
92 def width_fix(screen
, width
):
93 "Correct width to screen size"
95 if (width
+ width_extra
> screen
.width
):
96 width
= screen
.width
- width_extra
103 def height_fix(screen
, height
):
104 "Correct height to screen size"
106 if (height
+ height_extra
> screen
.height
):
107 height
= screen
.height
- height_extra
110 height
= screen
.height
115 "Initialize the screen"
118 return snack
.SnackScreen()
122 def screen_done(screen
):
128 def choice_window(screen
, title
, text
, options
, position
):
129 "Create options menu"
132 for option
in options
:
134 if (length
> maxopt
):
138 height
= len(options
)
141 width
= width_fix(screen
, width
+ width_extra
)
142 height
= height_fix(screen
, height
)
149 buttonbar
= snack
.ButtonBar(screen
, ('Done', 'Cancel'))
150 textbox
= snack
.TextboxReflowed(width
, text
)
151 listbox
= snack
.Listbox(height
, scroll
= large
, returnExit
= 1)
154 for option
in options
:
155 listbox
.append(option
, cnt
)
158 if (position
!= None):
159 listbox
.setCurrent(position
)
161 grid
= snack
.GridForm(screen
, title
, 1, 3)
162 grid
.add(textbox
, 0, 0)
163 grid
.add(listbox
, 0, 1, padding
= (0, 1, 0, 1))
164 grid
.add(buttonbar
, 0, 2, growx
= 1)
166 retval
= grid
.runOnce()
168 return (buttonbar
.buttonPressed(retval
), listbox
.current())
175 for option
in options
:
176 args
.append(str(cnt
+ 1))
182 if (position
!= None):
183 kw
['default-item'] = str(position
+ 1)
185 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
)
188 return ('cancel', None)
191 choice
= int(data
) - 1
193 return ('cancel', None)
196 return (None, choice
)
198 return ('done', choice
)
200 sys
.stdout
.write("\n *** %s *** \n%s\n\n" % (title
, text
))
202 maxcnt
= len(str(len(options
)))
204 for option
in options
:
205 sys
.stdout
.write("%*s. %s\n" % (maxcnt
, cnt
+ 1, option
))
208 sys
.stdout
.write("\n%*s. Done\n" % (maxcnt
, '0'))
209 sys
.stdout
.write("%*s. Quit\n\n" % (maxcnt
, 'q'))
212 if (position
!= None):
213 sys
.stdout
.write("Selection[%s]: " % str(position
+ 1))
216 sys
.stdout
.write("Selection[1]: ")
218 sys
.stdout
.write("Selection[0]: ")
219 inp
= sys
.stdin
.readline()
224 if (not inp
.strip()):
225 if (position
!= None):
226 return (None, position
)
233 if (inp
.strip() == 'q'):
234 return ('cancel', None)
237 choice
= int(inp
.strip())
244 if (choice
< 1) or (choice
> len(options
)):
247 return (None, choice
- 1)
249 def error_dialog(screen
, title
, msg
):
255 width
= width_fix(screen
, width
)
257 buttonbar
= snack
.ButtonBar(screen
, ['Ok'])
258 textbox
= snack
.TextboxReflowed(width
, msg
)
260 grid
= snack
.GridForm(screen
, title
, 1, 2)
261 grid
.add(textbox
, 0, 0, padding
= (0, 0, 0, 1))
262 grid
.add(buttonbar
, 0, 1, growx
= 1)
265 call_dlg(dlgcmd
, '--title', title
, '--msgbox', msg
, '6', str(width
+ width_extra
))
267 sys
.stdout
.write("\n%s: %s\n" % (title
, msg
))