This file is indexed.

/usr/share/wicd/curses/curses_misc.py is in wicd-curses 1.7.2.3-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
#!/usr/bin/env python
# -* coding: utf-8 -*-

""" curses_misc.py: Module for various widgets that are used throughout 
wicd-curses.
"""

#       Copyright (C) 2008-2009 Andrew Psaltis

#       This program 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 2 of the License, or
#       (at your option) any later version.
#       
#       This program 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 this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.

import urwid

from wicd.translations import _

# Uses code that is towards the bottom
def error(ui,parent,message):
    """Shows an error dialog (or something that resembles one)"""
    #     /\
    #    /!!\
    #   /____\
    dialog = TextDialog(message,6,40,('important',"ERROR"))
    return dialog.run(ui,parent)

class SelText(urwid.Text):
    """A selectable text widget. See urwid.Text."""

    def selectable(self):
        """Make widget selectable."""
        return True


    def keypress(self, size, key):
        """Don't handle any keys."""
        return key

# ListBox that can't be selected.
class NSelListBox(urwid.ListBox):
    def selectable(self):
        return False

# This class is annoying.  :/
class DynWrap(urwid.AttrWrap):
    """
    Makes an object have mutable selectivity.  Attributes will change like
    those in an AttrWrap

    w = widget to wrap
    sensitive = current selectable state
    attrs = tuple of (attr_sens,attr_not_sens)
    attrfoc = attributes when in focus, defaults to nothing
    """

    def __init__(self,w,sensitive=True,attrs=('editbx','editnfc'),focus_attr='editfc'):
        self._attrs=attrs
        self._sensitive = sensitive

        if sensitive:
            cur_attr = attrs[0]
        else:
            cur_attr = attrs[1]

        self.__super.__init__(w,cur_attr,focus_attr)

    def get_sensitive(self):
        return self._sensitive
    def set_sensitive(self,state):
        if state:
            self.set_attr(self._attrs[0])
        else:
            self.set_attr(self._attrs[1])
        self._sensitive = state
    property(get_sensitive,set_sensitive)

    def get_attrs(self):
        return self._attrs
    def set_attrs(self,attrs):
        self._attrs = attrs
    property(get_attrs,set_attrs)

    def selectable(self):
        return self._sensitive

# Just an Edit Dynwrapped to the most common specifications
class DynEdit(DynWrap):
    def __init__(self,caption='',edit_text='',sensitive=True,attrs=('editbx','editnfc'),focus_attr='editfc'):
        caption = ('editcp',caption + ': ')
        edit = urwid.Edit(caption,edit_text)
        self.__super.__init__(edit,sensitive,attrs,focus_attr)

# Just an IntEdit Dynwrapped to the most common specifications
class DynIntEdit(DynWrap):
    def __init__(self,caption='',edit_text='',sensitive=True,attrs=('editbx','editnfc'),focus_attr='editfc'):
        caption = ('editcp',caption + ':')
        edit = urwid.IntEdit(caption,edit_text)
        self.__super.__init__(edit,sensitive,attrs,focus_attr)

class DynRadioButton(DynWrap):
    def __init__(self,group,label,state='first True',on_state_change=None, user_data=None, sensitive=True, attrs=('body','editnfc'),focus_attr='body'):
        #caption = ('editcp',caption + ':')
        button = urwid.RadioButton(group,label,state,on_state_change,user_data)
        self.__super.__init__(button,sensitive,attrs,focus_attr)

class MaskingEditException(Exception):
    pass

# Password-style edit
class MaskingEdit(urwid.Edit):
    """
    mask_mode = one of:
        "always" : everything is a '*' all of the time
        "no_focus" : everything is a '*' only when not in focus
        "off" : everything is always unmasked
    mask_char = the single character that masks all other characters in the field
    """
    def __init__(self, caption = "", edit_text = "", multiline = False,
            align = 'left', wrap = 'space', allow_tab = False,
            edit_pos = None, layout=None, mask_mode="always",mask_char='*'):
        self.mask_mode = mask_mode
        if len(mask_char) > 1:
            raise MaskingEditException('Masks of more than one character are not supported!')
        self.mask_char = mask_char
        self.__super.__init__(caption,edit_text,multiline,align,wrap,allow_tab,edit_pos,layout)

    def get_caption(self):
        return self.caption
    def get_mask_mode(self):
        return self.mask_mode
    def set_mask_mode(self,mode):
        self.mask_mode = mode

    def get_masked_text(self):
        return self.mask_char*len(self.get_edit_text())

    def render(self,(maxcol,), focus=False):
        """ 
        Render edit widget and return canvas.  Include cursor when in
        focus.
        """
        # If we aren't masking anything ATM, then act like an Edit.
        # No problems.
        if self.mask_mode == "off" or (self.mask_mode == 'no_focus' and focus == True):
            canv = self.__super.render((maxcol,),focus)
            # The cache messes this thing up, because I am totally changing what
            # is displayed.
            self._invalidate()
            return canv

        # Else, we have a slight mess to deal with...
        self._shift_view_to_cursor = not not focus # force bool

        text, attr = self.get_text()
        text = text[:len(self.caption)]+self.get_masked_text()
        trans = self.get_line_translation( maxcol, (text,attr) )
        canv = urwid.canvas.apply_text_layout(text, attr, trans, maxcol)

        if focus:
            canv = urwid.CompositeCanvas(canv)
            canv.cursor = self.get_cursor_coords((maxcol,))

        return canv

# Tabbed interface, mostly for use in the Preferences Dialog
class TabColumns(urwid.WidgetWrap):
    """
    titles_dict = dictionary of tab_contents (a SelText) : tab_widget (box)
    attr = normal attributes
    attrsel = attribute when active
    """
    # FIXME Make the bottom_part optional
    def __init__(self,tab_str,tab_wid,title,bottom_part=None,attr=('body','focus'),
            attrsel='tab active', attrtitle='header'):
        #self.bottom_part = bottom_part
        #title_wid = urwid.Text((attrtitle,title),align='right')
        column_list = []
        for w in tab_str:
            text,trash = w.get_text()
            column_list.append(('fixed',len(text),w))
        column_list.append(urwid.Text((attrtitle,title),align='right'))

        self.tab_map = dict(zip(tab_str,tab_wid))
        self.active_tab = tab_str[0]
        self.columns = urwid.Columns(column_list,dividechars=1)
        #walker   = urwid.SimpleListWalker([self.columns,tab_wid[0]])
        #self.listbox = urwid.ListBox(walker)
        self.gen_pile(tab_wid[0],True)
        self.frame = urwid.Frame(self.pile)
        self.__super.__init__(self.frame)
        
    # Make the pile in the middle
    def gen_pile(self,lbox,firstrun=False):
        self.pile = urwid.Pile([
            ('fixed',1,urwid.Filler(self.columns,'top')),
            urwid.Filler(lbox,'top',height=('relative',99)),
            #('fixed',1,urwid.Filler(self.bottom_part,'bottom'))
            ])
        if not firstrun:
            self.frame.set_body(self.pile)
            self._w = self.frame
            self._invalidate()

    def selectable(self):
        return True

    def keypress(self,size,key):
        # If the key is page up or page down, move focus to the tabs and call
        # left or right on the tabs.
        if key == "page up" or key == "page down":
            self._w.get_body().set_focus(0)
            if key == "page up":
                newK = 'left'
            else:
                newK = 'right'
            self.keypress(size,newK)
            self._w.get_body().set_focus(1)
        else:
            key = self._w.keypress(size,key)
            wid = self.pile.get_focus().get_body()
            if wid == self.columns:
                self.active_tab.set_attr('body')
                self.columns.get_focus().set_attr('tab active')
                self.active_tab = self.columns.get_focus()
                self.gen_pile(self.tab_map[self.active_tab])
        
        return key

    def mouse_event(self,size,event,button,x,y,focus):
        wid = self.pile.get_focus().get_body()
        if wid == self.columns:
            self.active_tab.set_attr('body')

        self._w.mouse_event(size,event,button,x,y,focus)
        if wid == self.columns:
            self.active_tab.set_attr('body')
            self.columns.get_focus().set_attr('tab active')
            self.active_tab = self.columns.get_focus()
            self.gen_pile(self.tab_map[self.active_tab])


### Combo box code begins here
class ComboBoxException(Exception):
    pass

# A "combo box" of SelTexts
# I based this off of the code found here:
# http://excess.org/urwid/browser/contrib/trunk/rbreu_menus.py
# This is a hack/kludge.  It isn't without quirks, but it more or less works.
# We need to wait for changes in urwid's Canvas API before we can actually
# make a real ComboBox.
class ComboBox(urwid.WidgetWrap):
    """A ComboBox of text objects"""
    class ComboSpace(urwid.WidgetWrap):
        """The actual menu-like space that comes down from the ComboBox"""
        def __init__(self,list,body,ui,show_first,pos=(0,0),attr=('body','focus')):
            """
            body      : parent widget
            list      : stuff to include in the combobox
            ui        : the screen
            show_first: index of the element in the list to pick first
            pos       : a tuple of (row,col) where to put the list
            attr      : a tuple of (attr_no_focus,attr_focus)
            """
            
            #Calculate width and height of the menu widget:
            height = len(list)
            width = 0
            for entry in list:
                if len(entry) > width:
                    width = len(entry)
            content = [urwid.AttrWrap(SelText(w), attr[0], attr[1])
                       for w in list]
            self._listbox = urwid.ListBox(content)
            self._listbox.set_focus(show_first)

            overlay = urwid.Overlay(self._listbox, body, ('fixed left', pos[0]),
                                    width + 2, ('fixed top', pos[1]), height)
            self.__super.__init__(overlay)

        def show(self,ui,display):

            dim = ui.get_cols_rows()
            keys = True
            
            #Event loop:
            while True:
                if keys:
                    ui.draw_screen(dim, self.render(dim, True))
                    
                keys = ui.get_input()

                if "window resize" in keys:
                    dim = ui.get_cols_rows()
                if "esc" in keys:
                    return None
                if "enter" in keys:
                    (wid,pos) = self._listbox.get_focus()
                    (text,attr) = wid.get_text()
                    return text

                for k in keys:
                    #Send key to underlying widget:
                    self._w.keypress(dim, k)

        #def get_size(self):

    def __init__(self,label='',list=[],attrs=('body','editnfc'),focus_attr='focus',use_enter=True,focus=0,callback=None,user_args=None):
        """
        label     : bit of text that preceeds the combobox.  If it is "", then 
                    ignore it
        list      : stuff to include in the combobox
        body      : parent widget
        ui        : the screen
        row       : where this object is to be found onscreen
        focus     : index of the element in the list to pick first
        callback  : function that takes (combobox,sel_index,user_args=None)
        user_args : user_args in the callback
        """
        
        self.DOWN_ARROW = '    vvv'
        self.label = urwid.Text(label)
        self.attrs = attrs
        self.focus_attr = focus_attr
        self.list = list

        str,trash =  self.label.get_text()

        self.overlay = None
        self.cbox  = DynWrap(SelText(self.DOWN_ARROW),attrs=attrs,focus_attr=focus_attr)
        # Unicode will kill me sooner or later.
        if label != '':
            w = urwid.Columns([('fixed',len(str),self.label),self.cbox],dividechars=1)
        else:
            w = urwid.Columns([self.cbox])
        self.__super.__init__(w)

        # We need this to pick our keypresses
        self.use_enter = use_enter

        self.focus = focus

        self.callback = callback
        self.user_args = user_args

        # Widget references to simplify some things
        self.parent = None
        self.ui = None
        self.row = None
    def set_list(self,list):
        self.list = list

    def set_focus(self,index):
        self.focus = index
        # API changed between urwid 0.9.8.4 and 0.9.9
        try:
            self.cbox.set_w(SelText(self.list[index]+self.DOWN_ARROW))
        except AttributeError:
            self.cbox._w = SelText(self.list[index]+self.DOWN_ARROW)
        if self.overlay:
            self.overlay._listbox.set_focus(index)

    def rebuild_combobox(self):
        self.build_combobox(self.parent,self.ui,self.row)
    def build_combobox(self,parent,ui,row):
        str,trash =  self.label.get_text()

        self.cbox = DynWrap(SelText([self.list[self.focus]+self.DOWN_ARROW]),
                attrs=self.attrs,focus_attr=self.focus_attr)
        if str != '':
            w = urwid.Columns([('fixed',len(str),self.label),self.cbox],
                    dividechars=1)
            self.overlay = self.ComboSpace(self.list,parent,ui,self.focus,
                    pos=(len(str)+1,row))
        else:
            w = urwid.Columns([self.cbox])
            self.overlay = self.ComboSpace(self.list,parent,ui,self.focus,
                    pos=(0,row))

        self._w = w
        self._invalidate()
        self.parent = parent
        self.ui = ui
        self.row = row

    # If we press space or enter, be a combo box!
    def keypress(self,size,key):
        activate = key == ' '
        if self.use_enter:
            activate = activate or key == 'enter'
        if activate:
            # Die if the user didn't prepare the combobox overlay
            if self.overlay == None:
                raise ComboBoxException('ComboBox must be built before use!')
            retval = self.overlay.show(self.ui,self.parent)
            if retval != None:
                self.set_focus(self.list.index(retval))
                #self.cbox.set_w(SelText(retval+'    vvv'))
                if self.callback != None:
                    self.callback(self,self.overlay._listbox.get_focus()[1],
                            self.user_args)
        return self._w.keypress(size,key)

    def selectable(self):
        return self.cbox.selectable()

    def get_focus(self):
        if self.overlay:
            return self.overlay._listbox.get_focus()
        else:
            return None,self.focus

    def get_sensitive(self):
        return self.cbox.get_sensitive()
    def set_sensitive(self,state):
        self.cbox.set_sensitive(state)

# This is a h4x3d copy of some of the code in Ian Ward's dialog.py example.
class DialogExit(Exception):
    pass

class Dialog2(urwid.WidgetWrap):
    def __init__(self, text, height,width, body=None ):
       self.width = int(width)
       if width <= 0:
           self.width = ('relative', 80)
       self.height = int(height)
       if height <= 0:
           self.height = ('relative', 80)
 	   
       self.body = body
       if body is None:
           # fill space with nothing
           body = urwid.Filler(urwid.Divider(),'top')
    
       self.frame = urwid.Frame( body, focus_part='footer')
       if text is not None:
               self.frame.header = urwid.Pile( [urwid.Text(text,align='right'),
                       urwid.Divider()] )
       w = self.frame
       self.view = w

    # buttons: tuple of name,exitcode
    def add_buttons(self, buttons):
        l = []
        for name, exitcode in buttons:
            b = urwid.Button( name, self.button_press )
            b.exitcode = exitcode
            b = urwid.AttrWrap( b, 'body','focus' )
            l.append( b )
        self.buttons = urwid.GridFlow(l, 10, 3, 1, 'center')
        self.frame.footer = urwid.Pile( [ urwid.Divider(),
            self.buttons ], focus_item = 1)

    def button_press(self, button):
        raise DialogExit(button.exitcode)

    def run(self,ui,parent):
        ui.set_mouse_tracking()
        size = ui.get_cols_rows()
        overlay = urwid.Overlay(urwid.LineBox(self.view),
                                parent, 'center', self.width,
                                'middle', self.height)
        try:
            while True:
                canvas = overlay.render( size, focus=True )
                ui.draw_screen( size, canvas )
                keys = None
                while not keys:
                    keys = ui.get_input()
                for k in keys:
                    if urwid.VERSION < (1, 0, 0):
                        check_mouse_event = urwid.is_mouse_event
                    else:
                        check_mouse_event = urwid.util.is_mouse_event
                    if check_mouse_event(k):
                        event, button, col, row = k
                        overlay.mouse_event( size,
                                event, button, col, row,
                                focus=True)
                    else:
                        if k == 'window resize':
                            size = ui.get_cols_rows()
                        k = self.view.keypress( size, k )
                        if k == 'esc':
                            raise DialogExit(-1)
                        if k:
                            self.unhandled_key( size, k)
        except DialogExit, e:
            return self.on_exit( e.args[0] )
               
    def on_exit(self, exitcode):
        return exitcode, ""

    def unhandled_key(self, size, key):
        pass

# Simple dialog with text in it and "OK"
class TextDialog(Dialog2):
    def __init__(self, text, height, width, header=None,align='left'):
        l = [urwid.Text(text)]
        body = urwid.ListBox(l)
        body = urwid.AttrWrap(body, 'body')

        Dialog2.__init__(self, header, height+2, width+2, body)
        self.add_buttons([('OK',1)])


    def unhandled_key(self, size, k):
        if k in ('up','page up','down','page down'):
            self.frame.set_focus('body')
            self.view.keypress( size, k )
            self.frame.set_focus('footer')

class InputDialog(Dialog2):
    def __init__(self, text, height, width,ok_name=_('OK'),edit_text=''):
        self.edit = urwid.Edit(wrap='clip',edit_text=edit_text)
        body = urwid.ListBox([self.edit])
        body = urwid.AttrWrap(body, 'editbx','editfc')
       
        Dialog2.__init__(self, text, height, width, body)
       
        self.frame.set_focus('body')
        self.add_buttons([(ok_name,0),(_('Cancel'),-1)])
       
    def unhandled_key(self, size, k):
        if k in ('up','page up'):
            self.frame.set_focus('body')
        if k in ('down','page down'):
            self.frame.set_focus('footer')
        if k == 'enter':
            # pass enter to the "ok" button
            self.frame.set_focus('footer')
            self.view.keypress( size, k )
       
    def on_exit(self, exitcode):
        return exitcode, self.edit.get_edit_text()


class ClickCols(urwid.WidgetWrap):
    def __init__(self,items,callback=None,args=None):
        cols = urwid.Columns(items)
        self.__super.__init__(cols)
        self.callback = callback
        self.args = args
    def mouse_event(self,size,event,button,x,y,focus):
        if event == "mouse press":
            # The keypress dealie in wicd-curses.py expects a list of keystrokes
            self.callback([self.args])

# htop-style menu menu-bar on the bottom of the screen
class OptCols(urwid.WidgetWrap):
    # tuples = [(key,desc)], on_event gets passed a key
    # attrs = (attr_key,attr_desc)
    # handler = function passed the key of the "button" pressed
    # mentions of 'left' and right will be converted to <- and -> respectively
    def __init__(self,tuples,handler,attrs=('body','infobar'),debug=False):
        # Find the longest string.  Keys for this bar should be no greater than
        # 2 characters long (e.g., -> for left)
        #maxlen = 6
        #for i in tuples:
        #    newmax = len(i[0])+len(i[1])
        #    if newmax > maxlen:
        #        maxlen = newmax
        
        # Construct the texts
        textList = []
        i = 0
        # callbacks map the text contents to its assigned callback.
        self.callbacks = []
        for cmd in tuples:
            key = reduce(lambda s,(f,t):s.replace(f,t), [ \
                ('ctrl ', 'Ctrl+'), ('meta ', 'Alt+'), \
                ('left', '<-'), ('right', '->'), \
                ('page up', 'Page Up'), ('page down', 'Page Down'), \
                ('esc', 'ESC'), ('enter', 'Enter'), ('f10','F10')], cmd[0])
            
            if debug:
                callback = self.debugClick
                args = cmd[1]
            else:
                callback = handler
                args = cmd[0]
            #self.callbacks.append(cmd[2])
            col = ClickCols([
                ('fixed',len(key)+1,urwid.Text((attrs[0],key+':')) ),
                              urwid.AttrWrap(urwid.Text(cmd[1]),attrs[1])],
                              callback,args)
            textList.append(col)
            i+=1
        if debug:
            self.debug = urwid.Text("DEBUG_MODE")
            textList.append(('fixed',10,self.debug))
            
        cols = urwid.Columns(textList)
        self.__super.__init__(cols)
    def debugClick(self,args):
        self.debug.set_text(args)

    def mouse_event(self,size,event,button,x,y,focus):
        # Widgets are evenly long (as of current), so...
        return self._w.mouse_event(size,event,button,x,y,focus)