Beispiel #1
0
    def _build_widget(self, **kwargs):
        total_items = []
        for _item in self.radio_items.keys():
            desc = AttrWrap(
                Text("  {}".format(
                    self.radio_items[_item][1])), 'input', 'input focus')
            total_items.append(
                AttrWrap(self.radio_items[_item][0], 'input', 'input focus'))
            total_items.append(AttrWrap(desc, 'input'))
            total_items.append(Divider('-'))

        self.input_lbox = ListBox(SimpleListWalker(total_items[:-1]))
        self.add_buttons()

        self.container_box_adapter = BoxAdapter(self.input_lbox,
                                                len(total_items))
        self.container_lbox = ListBox(
            [self.container_box_adapter,
             Divider(),
             self.btn_pile])

        return LineBox(
            BoxAdapter(self.container_lbox,
                       height=len(total_items) + 3),
            title=self.title)
Beispiel #2
0
    def __init__(self):
        self.screen = Screen()
        self.screen.set_input_timeouts(max_wait=0)
        self.steps = GridFlow([], 20, 2, 1, 'left')
        self.progress = SimpleFocusListWalker([])
        self.log = SimpleFocusListWalker([])

        self.widget = AttrMap(
            LineBox(Pile([
                ('fixed', 6, AttrMap(Filler(self.steps), 'default')),
                ('fixed', 1, Filler(Divider('\u2500'))),
                ('fixed', 3, ListBox(self.progress)),
                AttrMap(LineBox(ListBox(self.log), title='Message log'),
                        'default')
            ]),
                    title='Indico 1.2 -> 2.0 migration'), 'global_frame')

        self.screen.register_palette(
            [('green', 'light green', ''), ('white', 'white', ''),
             ('red', 'dark red', ''), ('yellow', 'yellow', ''),
             ('progress_empty', 'black',
              'light gray'), ('progress_progress', 'light cyan', 'light gray'),
             ('progress_done', 'black', 'light cyan'),
             ('box', 'white', 'dark gray'), ('step_done', 'light green', ''),
             ('step_working', 'dark gray',
              ''), ('global_frame', 'light cyan',
                    ''), ('fill', 'light cyan', 'dark cyan'),
             ('done', 'white', 'dark green'), ('eta', 'yellow', 'dark gray')] +
            generate_urwid_palette(PALETTE))
 def render(self, size, focus=False):
     self.body.sync()
     canvas = ListBox.render(self, size, focus)
     if self.body.event:
         self.body.sync()
         canvas = ListBox.render(self, size, focus)
         assert not self.body.event
     return canvas
Beispiel #4
0
 def render(self, size, focus=False):
     self.body.sync()
     canvas = ListBox.render(self, size, focus)
     if self.body.event:
         self.body.sync()
         canvas = ListBox.render(self, size, focus)
         assert not self.body.event
     return canvas
Beispiel #5
0
    def __init__(self,
                 choice_callback=None,
                 command_callback=None,
                 help_callback=None):

        self.palette = [
            ('brick', 'light red', 'black'),
            ('rubble', 'yellow', 'black'),
            ('wood', 'light green', 'black'),
            ('concrete', 'white', 'black'),
            ('stone', 'light cyan', 'black'),
            ('marble', 'light magenta', 'black'),
            ('jack', 'dark gray', 'white'),
            ('msg_info', 'white', 'black'),
            ('msg_err', 'light red', 'black'),
            ('msg_debug', 'light green', 'black'),
        ]

        self.choice_callback = choice_callback
        self.command_callback = command_callback
        self.help_callback = help_callback

        self.screen = None
        self.loop = None
        self.called_loop_stop = False
        self.reactor_stop_fired = False

        self.quit_flag = False
        self.edit_msg = "Make selection ('q' to quit): "
        self.roll_list = SimpleListWalker([])
        self.game_log_list = SimpleListWalker([])
        self.choices_list = SimpleListWalker([])

        self.state_text = SimpleListWalker([Text('Connecting...')])

        self.edit_widget = Edit(self.edit_msg)
        self.roll = ListBox(self.roll_list)
        self.game_log = ListBox(self.game_log_list)
        self.choices = ListBox(self.choices_list)
        self.state = ListBox(self.state_text)

        self.left_frame = Pile([
            LineBox(self.state),
            (13, LineBox(self.choices)),
        ])

        self.right_frame = Pile([LineBox(self.game_log), LineBox(self.roll)])

        self.state.set_focus(len(self.state_text) - 1)

        self.columns = Columns([('weight', 0.75, self.left_frame),
                                ('weight', 0.25, self.right_frame)])
        self.frame_widget = Frame(footer=self.edit_widget,
                                  body=self.columns,
                                  focus_part='footer')

        self.exc_info = None
Beispiel #6
0
class AddCharmDialog(Overlay):
    """ Adding charm dialog """

    def __init__(self, underlying, juju_state, destroy, command_runner=None):
        import cloudinstall.charms
        charm_modules = [import_module('cloudinstall.charms.' + mname)
                         for (_, mname, _) in
                         pkgutil.iter_modules(cloudinstall.charms.__path__)]
        charm_classes = [m.__charm_class__ for m in charm_modules
                         if m.__charm_class__.allow_multi_units]

        self.cr = command_runner
        self.underlying = underlying
        self.destroy = destroy

        self.boxes = []
        self.bgroup = []
        first_index = 0
        for i, charm_class in enumerate(charm_classes):
            charm = charm_class(juju_state=juju_state)
            if charm.name() and not first_index:
                first_index = i
            r = RadioButton(self.bgroup, charm.name())
            r.text_label = charm.name()
            self.boxes.append(r)

        self.count_editor = IntEdit("Number of units to add: ", 1)
        self.boxes.append(self.count_editor)
        wrapped_boxes = _wrap_focus(self.boxes)

        bs = [Button("Ok", self.yes), Button("Cancel", self.no)]
        wrapped_buttons = _wrap_focus(bs)
        self.buttons = Columns(wrapped_buttons)
        self.items = ListBox(wrapped_boxes)
        self.items.set_focus(first_index)
        ba = BoxAdapter(self.items, height=len(wrapped_boxes))
        self.lb = ListBox([ba, Text(""), self.buttons])
        self.w = LineBox(self.lb, title="Add unit")
        self.w = AttrMap(self.w, "dialog")
        Overlay.__init__(self, self.w, self.underlying,
                         'center', 45, 'middle', len(wrapped_boxes) + 4)

    def yes(self, button):
        selected = [r for r in self.boxes if
                    r is not self.count_editor
                    and r.get_state()][0]
        _charm_to_deploy = selected.label
        n = self.count_editor.value()
        log.info("Adding {n} units of {charm}".format(
            n=n, charm=_charm_to_deploy))
        self.cr.add_unit(_charm_to_deploy, count=int(n))
        self.destroy()

    def no(self, button):
        self.destroy()
Beispiel #7
0
 def __init__(self, walker, **kwargs):
     """
     :param walker: tree of widgets to be displayed.
         In case we are given a raw `TreeWalker`, it will be used though
         `TreeListWalker` which means no decoration.
     :type walker: TreeWalker or TreeListWalker
     """
     if not isinstance(walker, TreeListWalker):
         walker = TreeListWalker(walker)
     self._walker = walker
     self._outer_list = ListBox(walker)
     self.__super.__init__(self._outer_list)
Beispiel #8
0
 def __init__(self, tree, focus=None):
     """
     :param tree: tree of widgets to be displayed.
     :type tree: Tree
     :param focus: initially focussed position
     """
     self._tree = tree
     self._walker = TreeListWalker(tree)
     self._outer_list = ListBox(self._walker)
     if focus is not None:
         self._outer_list.set_focus(focus)
     self.__super.__init__(self._outer_list)
Beispiel #9
0
    def __init__(self, contents, offset=1):
        """
        Arguments:

        `contents` is a list with the elements contained in the
        `ScrollableListBox`.

        `offset` is the number of position that `scroll_up` and `scroll_down`
        shift the cursor.
        """
        self.offset = offset

        ListBox.__init__(self, SimpleListWalker(contents))
    def __init__(self, contents, offset=1):
        """
        Arguments:

        `contents` is a list with the elements contained in the
        `ScrollableListBox`.

        `offset` is the number of position that `scroll_up` and `scroll_down`
        shift the cursor.
        """
        self.offset = offset

        ListBox.__init__(self, SimpleListWalker(contents))
Beispiel #11
0
    def __init__(self,
                 height,
                 directory=".",
                 file="",
                 attr=(None, None),
                 show_hidden=False):
        """
        height -- height of the directory list and the file list
        directory, file -- default selection
        attr -- (inner selectable widgets, selected widgets)
        show_hidden -- If True, hidden files are shown by default.
        """

        self.directory = abspath(directory)
        self.file = ""
        self.attr = attr
        self.height = height
        self.show_hidden = show_hidden

        # Create dummy widgets for directory and file display:
        self.dir_widget = AttrWrap(
            BoxAdapter(ListBox([self._blank]), self.height), self.attr[0])
        self.file_widget = AttrWrap(
            BoxAdapter(ListBox([self._blank]), self.height), self.attr[0])

        columns = Columns([self.dir_widget, self.file_widget], 1)

        # Selection widget:
        self.select_widget = AttrWrap(Edit("", ""), self.attr[0], self.attr[1])

        # Buttons and checkbox:
        button_widgets = [
            AttrWrap(Button(button, self._action), attr[0], attr[1])
            for button in ["OK", "Cancel"]
        ]
        button_grid = GridFlow(button_widgets, 12, 2, 1, 'center')

        button_cols = Columns([
            CheckBox(self.SHOW_HIDDEN_TEXT, self.show_hidden, False,
                     self._toggle_hidden), button_grid
        ])

        self.outer_widget = Pile([
            columns, self._blank,
            Text(self.SELECTION_TEXT), self.select_widget, self._blank,
            button_cols
        ])

        self.update_widgets()

        WidgetWrap.__init__(self, self.outer_widget)
Beispiel #12
0
 def __init__(self, model, signal, iface):
     self.model = model
     self.signal = signal
     self.iface = iface
     self.iface_obj = self.model.get_interface(iface)
     self._build_widgets()
     super().__init__(ListBox(self._build_body()))
Beispiel #13
0
    def __init__(self, list_data=None):

        self.is_editing = False
        self.tasks = []
        self.name = None
        self.group = None
        self.id = None

        if list_data:
            # Parse the data.
            self.parse_data(list_data)
        else:
            # Must be a new list
            self.name = 'untitled'
            self.group = 'none'
            self.id = uuid.uuid4().hex

        # AttrSpecs
        self.attr_spec = AttrSpec('', '')
        self.focus_nav = AttrSpec('h12', '')
        self.focus_ins = AttrSpec('h160', '')

        # Build widget stack
        self.title = TitleBar(self.name)
        self.group_foot = GroupFoot(self.group)
        self.body = urwid.SimpleFocusListWalker(self.tasks)
        self.list_box = ListBox(self.body)
        self.list_frame = Frame(self.list_box,
                                header=self.title,
                                footer=self.group_foot)
        self.line_box = LineBox(self.list_frame)
        self.line_attr = AttrMap(self.line_box, self.attr_spec, self.focus_nav)
        super().__init__(self.line_attr)
Beispiel #14
0
    def __init__(self, model, signal, selected_disk):
        log.debug('AddPartitionView: selected_disk=[{}]'.format(selected_disk))
        self.model = model
        self.signal = signal
        self.selected_disk = selected_disk
        self.disk_obj = self.model.get_disk(selected_disk)

        self.partnum = IntegerEditor(caption="",
                                     default=self.disk_obj.lastpartnumber + 1)
        self.size_str = _humanize_size(self.disk_obj.freespace)
        self.size = StringEditor(caption="".format(self.size_str))
        self.mountpoint = MountEditor(caption="", edit_text="/")
        self.fstype = Selector(opts=self.model.supported_filesystems)
        body = [
            Columns([
                ("weight", 0.2,
                 Text("Adding partition to {}".format(self.disk_obj.devpath),
                      align="right")), ("weight", 0.3, Text(""))
            ]),
            Padding.line_break(""),
            self._container(),
            Padding.line_break(""),
            Padding.fixed_10(self._build_buttons())
        ]
        partition_box = Padding.center_50(ListBox(body))
        super().__init__(partition_box)
Beispiel #15
0
    def __init__(self, executor_widgets):
        self.log_widget = ScrollingLog()

        self.latest_stats = LatestStats()
        self.cumulative_stats = CumulativeStats()

        stats_pane = Pile([(WEIGHT, 0.333, self.latest_stats),
                           (WEIGHT, 0.667, self.cumulative_stats)])

        self.graphs = ThreeGraphs()
        self.logo = TaurusLogo()

        ordered_widgets = sorted(executor_widgets, key=lambda x: x.priority)
        right_widgets = ListBox(
            SimpleListWalker([Pile([x, Divider()]) for x in ordered_widgets]))
        widget_pile = Pile([
            (7, self.logo),
            right_widgets,
        ])

        log_block = Pile([(1, Filler(Divider('─'))), self.log_widget])

        right_pane = Pile([(WEIGHT, 0.667, widget_pile),
                           (WEIGHT, 0.333, log_block)])

        columns = [(WEIGHT, 0.25, self.graphs), (WEIGHT, 0.50, stats_pane),
                   (WEIGHT, 0.25, right_pane)]
        super(TaurusConsole, self).__init__(columns)
Beispiel #16
0
 def __init__(self, msg=None, height=10):
     if not msg:
         msg = "Processing."
     listbox = ListBox([Text(msg)])
     box_adapter = BoxAdapter(listbox, height=height)
     linebox = LineBox(box_adapter, title="Info")
     super().__init__(AttrWrap(linebox, 'dialog'))
Beispiel #17
0
    def __init__(self, tui, locator, device):
        super().__init__(tui)
        self.body.contents.append(
            (Text("Select file to load on \"{}\"".format(device)), ('pack',
                                                                    None)))
        self.body.contents.append((Divider(), ('pack', None)))
        self.device = device

        self.locator = locator
        self.device = device
        self.all_files = []

        def limit(regexp):
            self.regexp = regexp
            self.populate_list()

        def enter(edit_text):
            if len(self.walker) < 1:
                self.tui.pop_window()
                return
            button = self.walker[0]
            button.keypress(1, 'enter')

        editbox = CB_Edit("Limit (regexp): ", "", limit, enter)
        self.body.contents.append((editbox, ('pack', 1)))
        self.body.contents.append((Divider(), ('pack', 1)))

        self.walker = SimpleFocusListWalker([])
        listbox = ListBox(self.walker)
        self.body.contents.append((listbox, ('weight', 1)))
        self.body.focus_position = 2
        self.update()
        self.regexp = ".*"
 def __init__(self, model, signal, iface):
     self.model = model
     self.signal = signal
     self.ifname = iface
     self.iface = self.model.get_interface(self.ifname)
     self.is_gateway = False
     self.gateway_input = StringEditor(caption="")  # FIXME: ipaddr_editor
     self.address_input = StringEditor(caption="")  # FIXME: ipaddr_editor
     self.subnet_input = StringEditor(caption="")  # FIXME: ipaddr_editor
     self.error = Text("", align='center')
     self.nameserver_input = \
         StringEditor(caption="")  # FIXME: ipaddr_editor
     self.searchdomains_input = \
         StringEditor(caption="")  # FIXME: ipaddr_editor
     self.set_as_default_gw_button = Pile(
         self._build_set_as_default_gw_button())
     body = [
         Padding.center_79(self._build_iface_inputs()),
         Padding.line_break(""),
         Padding.center_79(self.set_as_default_gw_button),
         Padding.line_break(""),
         Padding.center_90(Color.info_error(self.error)),
         Padding.line_break(""),
         Padding.fixed_10(self._build_buttons())
     ]
     super().__init__(ListBox(body))
Beispiel #19
0
    def build_widgets(self):
        readme_files = glob(os.path.join(self.spell_dir, 'README.*'))
        if len(readme_files) == 0:
            self.readme_w = Text("No README found for bundle.")
        else:
            readme_file = readme_files[0]
            if len(readme_files) != 1:
                utils.warning("Unexpected: {} files matching README.*"
                              "- using {}".format(len(readme_files),
                                                  readme_file))
            with open(readme_file) as rf:
                rlines = [Text(l) for l in rf.readlines()]
                self.readme_w = BoxAdapter(ListBox(rlines),
                                           self.initial_height)

        ws = [
            Text("About {}:".format(self.spell_name)),
            Padding.right_50(
                Color.button_primary(PlainButton("Continue", self.do_continue),
                                     focus_map='button_primary focus')),
            Padding.center(HR()),
            Padding.center(self.readme_w, left=2),
            Padding.center(HR()),
            Padding.center(
                Text("Use arrow keys to scroll text "
                     "and TAB to select the button."))
        ]

        self.pile = Pile(ws)
        return Padding.center_90(Filler(self.pile, valign="top"))
Beispiel #20
0
    def __init__(self, tui, locator, device):
        super().__init__(tui)
        self.body.contents.append(
            (Text("Selected device \"{}\"".format(device)), ('pack', None)))
        fn = self.tui.controller.get_filename(locator)
        self.filename_txt = Text("Selected file \"{}\"".format(fn))
        self.body.contents.append((self.filename_txt, ('pack', None)))
        self.body.contents.append((Divider(), ('pack', None)))

        self.statuswidget = Pile([])
        self.body.contents.append((self.statuswidget, ('pack', None)))
        self.body.contents.append((Divider(), ('pack', None)))

        self.locator = locator
        self.device = device

        self.walker = SimpleFocusListWalker([])
        listbox = ListBox(self.walker)
        self.body.contents.append((listbox, ('weight', 1)))
        self.body.focus_position = 5
        self.add_hotkey('U', self.update, "update")
        self.add_hotkey('w', self.webcams, "webcams")
        self.add_hotkey('a', self.actions, "actions")
        self.status = defaultdict(str)
        self.update()
Beispiel #21
0
    def __init__(self, choice_callback=None,
                       command_callback=None,
                       help_callback=None):

        self.palette = [
                ('brick', 'light red', 'black'),
                ('rubble', 'yellow', 'black'),
                ('wood', 'light green', 'black'),
                ('concrete', 'white', 'black'),
                ('stone', 'light cyan', 'black'),
                ('marble', 'light magenta', 'black'),
                ('jack', 'dark gray', 'white'),
                ('msg_info', 'white', 'black'),
                ('msg_err', 'light red', 'black'),
                ('msg_debug', 'light green', 'black'),
                ]

        self.choice_callback = choice_callback
        self.command_callback = command_callback
        self.help_callback = help_callback

        self.screen = None
        self.loop = None
        self.called_loop_stop = False
        self.reactor_stop_fired = False

        self.quit_flag = False
        self.edit_msg = "Make selection ('q' to quit): "
        self.roll_list = SimpleListWalker([])
        self.game_log_list = SimpleListWalker([])
        self.choices_list = SimpleListWalker([])

        self.state_text = SimpleListWalker([Text('Connecting...')])

        self.edit_widget = Edit(self.edit_msg)
        self.roll = ListBox(self.roll_list)
        self.game_log = ListBox(self.game_log_list)
        self.choices = ListBox(self.choices_list)
        self.state = ListBox(self.state_text)

        self.left_frame = Pile([
                LineBox(self.state),
                (13, LineBox(self.choices)),
                ])

        self.right_frame = Pile([
                LineBox(self.game_log),
                LineBox(self.roll)
                ])

        self.state.set_focus(len(self.state_text)-1)

        self.columns = Columns([('weight', 0.75, self.left_frame),
                                ('weight', 0.25, self.right_frame)
                                ])
        self.frame_widget = Frame(footer=self.edit_widget,
                                  body=self.columns,
                                  focus_part='footer')

        self.exc_info = None
Beispiel #22
0
    def __init__(self, num_rows=20, w=(14, 14, 18, 16, 16, 16, 20)):
        """
            @method __init__
            Initializes the widget
        """
        self.m_process_list = ProcessList(w)
        self.prev_sort_item = None

        self.w_status = HeaderButton('Status', 'status', self.handle_click)
        self.w_pid = HeaderButton('PID', 'pid', self.handle_click)
        self.w_name = HeaderButton('Name', 'name', self.handle_click)
        self.w_cpu = HeaderButton('CPU %', 'cpu_perc', self.handle_click)
        self.w_mem = HeaderButton('MEM %', 'mem_perc', self.handle_click)
        self.w_up = HeaderButton('Uptime', 'uptime', self.handle_click)
        self.w_pname = HeaderButton('Process', 'pname', self.handle_click)

        self.w_cpu.activate()
        self.prev_sort_item = self.w_cpu

        self.header_buttons = h = [
            self.w_status, self.w_pid, self.w_name, self.w_cpu, self.w_mem,
            self.w_up, self.w_pname
        ]

        m_header = AttrMap(
            Columns([('fixed', w[i], h[i]) for i in range(0, len(h))]),
            'invert')
        m_lb = ListBox(
            SimpleListWalker(
                [m_header, BoxAdapter(self.m_process_list, num_rows)]))
        super(ProcessTable, self).__init__(m_lb, None)
        self.update()
Beispiel #23
0
    def create_interface(self):
        self.screen = Screen()
        self.screen.start()

        self.screen.register_palette([
            ("title", "white", "dark blue", "standout"),
            ("line", "light gray", "black"),
            ("help", "white", "dark blue")]
        )

        self.body = ListBox(SimpleListWalker([]))
        self.lines = self.body.body

        self.title = Text(MAIN_TITLE)
        self.header = AttrWrap(self.title, "title")

        self.help = AttrWrap(
            Text(HELP_STRINGS["main"]),
            "help"
        )

        self.input = Edit(caption="%s> " % self.ircchannel)
        self.footer = Pile([self.help, self.input])

        self.top = Frame(self.body, self.header, self.footer)
Beispiel #24
0
class ChangeStateDialog(Overlay):
    def __init__(self, underlying, juju_state, on_success, on_cancel):
        import cloudinstall.charms
        charm_modules = [import_module('cloudinstall.charms.' + mname)
                         for (_, mname, _) in
                         pkgutil.iter_modules(cloudinstall.charms.__path__)]
        charm_classes = sorted([m.__charm_class__ for m in charm_modules],
                               key=attrgetter('deploy_priority'))

        self.boxes = []
        first_index = 0
        for i, charm_class in enumerate(charm_classes):
            charm = charm_class(juju_state=juju_state)
            if charm.name() and not first_index:
                first_index = i
            r = CheckBox(charm.name())
            r.text_label = charm.name()
            self.boxes.append(r)
        wrapped_boxes = _wrap_focus(self.boxes)

        def ok(button):
            selected = filter(lambda r: r.get_state(), self.boxes)
            on_success([s.text_label for s in selected])

        def cancel(button):
            on_cancel()

        bs = [Button("Ok", ok), Button("Cancel", cancel)]
        wrapped_buttons = _wrap_focus(bs)
        self.buttons = Columns(wrapped_buttons)
        self.items = ListBox(wrapped_boxes)
        self.items.set_focus(first_index)
        ba = BoxAdapter(self.items, height=len(wrapped_boxes))
        self.lb = ListBox([ba, self.count_editor, self.buttons])
        root = LineBox(self.lb, title="Select new charm")
        root = AttrMap(root, "dialog")

        Overlay.__init__(self, root, underlying, 'center', 30, 'middle',
                         len(wrapped_boxes) + 4)

    def keypress(self, size, key):
        if key == 'tab':
            if self.lb.get_focus()[0] == self.buttons:
                self.keypress(size, 'page up')
            else:
                self.keypress(size, 'page down')
        return Overlay.keypress(self, size, key)
Beispiel #25
0
def show_copybook(body):
    listbox = ListBox([*body])
    main_widget.original_widget = Overlay(LineBox(listbox),
                                          box,
                                          align="center",
                                          width=62,
                                          height=31,
                                          valign="middle")

    #меняем фокус на последний зарисованный участок лабиринта
    listbox.change_focus((20, 20),
                         len(body) - 1,
                         offset_inset=0,
                         coming_from=None,
                         cursor_coords=None,
                         snap_rows=None)
    button_power.overlay = 1
Beispiel #26
0
    def _insert_charm_selections(self):
        first_index = 0
        bgroup = []
        for i, charm_class in enumerate(self.charms):
            charm = charm_class
            if charm.name() and not first_index:
                first_index = i
            r = RadioButton(bgroup, charm.name())
            r.text_label = charm.name()
            self.boxes.append(r)

        # Add input widget for specifying NumUnits
        self.count_editor = IntEdit("Number of units to add: ", 1)
        self.boxes.append(self.count_editor)
        wrapped_boxes = self._wrap_focus(self.boxes)
        items = ListBox(SimpleListWalker(wrapped_boxes))
        items.set_focus(first_index)
        return (len(self.boxes), BoxAdapter(items, len(self.boxes)))
Beispiel #27
0
 def __init__(self, model, signal):
     self.model = model
     self.signal = signal
     self.items = []
     self.error = Text("", align='center')
     self.body = [
         Padding.center_79(self._build_model_inputs()),
         Padding.line_break(""),
         Padding.center_79(self._build_additional_options()),
         Padding.line_break(""),
         Padding.center_79(Color.info_error(self.error)),
         Padding.line_break(""),
         Padding.fixed_10(self._build_buttons()),
     ]
     # FIXME determine which UX widget should have focus
     self.lb = ListBox(self.body)
     self.lb.set_focus(4)  # _build_buttons
     super().__init__(self.lb)
Beispiel #28
0
    def _insert_charm_selections(self):
        first_index = 0
        bgroup = []
        for i, charm_class in enumerate(self.charms):
            charm = charm_class
            if charm.name() and not first_index:
                first_index = i
            r = RadioButton(bgroup, charm.name())
            r.text_label = charm.name()
            self.boxes.append(r)

        # Add input widget for specifying NumUnits
        self.count_editor = IntEdit("Number of units to add: ", 1)
        self.boxes.append(self.count_editor)
        wrapped_boxes = self._wrap_focus(self.boxes)
        items = ListBox(SimpleListWalker(wrapped_boxes))
        items.set_focus(first_index)
        return (len(self.boxes), BoxAdapter(items, len(self.boxes)))
Beispiel #29
0
 def __init__(self, app, results, cb):
     self.app = app
     self.results = results
     self.cb = cb
     self.result_pile = [Padding.line_break("")]
     self.result_pile += [
         Padding.center_90(s) for s in self.build_results()
     ]
     super().__init__(ListBox(self.result_pile))
Beispiel #30
0
def start(config):
    """Start the application and handle user input. Blocks until the application exits."""
    def item_chosen(button, server):
        global choice
        choice = server
        response = Text(
            [u'Connecting to: ',
             server.connection_string(), u'\n'])
        done = Button(u'Ok')
        urwid.connect_signal(done, 'click', exit_program)
        main.original_widget = Filler(
            Pile([response,
                  AttrMap(done, None, focus_map='reversed')]))

    def exit_program(button):
        raise urwid.ExitMainLoop()

    def unhandled(key):
        vim_map = {'h': 'left', 'j': 'down', 'k': 'up', 'l': 'right'}
        if key in vim_map.keys():
            list_box.keypress((0, 1), vim_map[key])
        elif key in ['left', 'right']:
            pass
        elif key in ['esc', 'q']:
            raise ExitMainLoop()

    body = [urwid.Text(u'\nServers'), Divider(u'-')]

    for server in config.get_servers():
        button = Button(server.name)
        urwid.connect_signal(button, 'click', item_chosen, server)
        body.append(AttrMap(button, None, focus_map='reversed'))

    list_box = ListBox(urwid.SimpleFocusListWalker(body))

    main = Padding(list_box, left=2, right=2)

    overlay = Overlay(main,
                      SolidFill(u'\N{MEDIUM SHADE}'),
                      align='center',
                      width=('relative', 60),
                      valign='middle',
                      height=('relative', 60),
                      min_width=20,
                      min_height=9)

    header = AttrMap(Text(u' ssh-menu'), 'header')
    footer = AttrMap(Text(u'this is the footer'), 'footer')

    frame = Frame(overlay, header=header, footer=footer)

    urwid.MainLoop(urwid.AttrMap(frame, 'body'),
                   palette=palette,
                   unhandled_input=unhandled).run()

    return choice
Beispiel #31
0
 def __init__(self, model, signal):
     self.model = model
     self.signal = signal
     self.items = []
     self.body = [
         Padding.center_79(self._build_model_inputs()),
         Padding.line_break(""),
         Padding.fixed_10(self._build_buttons()),
     ]
     super().__init__(ListBox(self.body))
Beispiel #32
0
 def __init__(self, signal):
     self.signal = signal
     self.body = [
         Padding.center_79(Text("This view is not yet implemented.")),
         Padding.line_break(""),
         Padding.center_79(Color.info_minor(Text("A place holder widget"))),
         Padding.line_break(""),
         Padding.center_79(self._build_buttons())
     ]
     super().__init__(ListBox(self.body))
Beispiel #33
0
    def _build_widget(self, **kwargs):
        # Charm selections
        num_of_items, charm_sel = self._insert_charm_selections()

        # Control buttons
        buttons = self._insert_buttons()

        return LineBox(BoxAdapter(ListBox([charm_sel,
                                           Divider(), buttons]),
                                  height=num_of_items + 2),
                       title="Add unit")
Beispiel #34
0
    def __init__(self, parser):
        self.parser = parser
        self.find = {'ref': '', 'text': ''}
        self.isolate_filter = (None, None)
        self.line_collection = None
        self.jump_stack = []
        self.expansions = {}
        self.show_sip_level = 2
        self.show_ladder = False
        self.show_only_filtered = False
        self.show_verbose = True
        self.show_channel = True
        self.line_no_before_isolate = 0
        self.showing_help = False

        self.walker = LogLineWalker([('Select call on the left side', None)],
                                    self.jump, self.expand, self.isolate)
        self.header = AttrWrap(Text([('key', 'F6'), ' Log']), 'bar')
        self.listbox = ListBox(self.walker)
        self.frame = Frame(self.listbox, header=self.header)
Beispiel #35
0
    def _build_widget(self, **kwargs):

        total_items = []
        for _item in self.input_items.keys():
            total_items.append(
                AttrWrap(self.input_items[_item], 'input', 'input focus'))
        self.input_lbox = ListBox(SimpleListWalker(total_items))

        # Add buttons
        self.add_buttons()
        self.container_box_adapter = BoxAdapter(self.input_lbox,
                                                len(total_items))
        self.container_lbox = ListBox(
            [self.container_box_adapter,
             Divider(), self.btn_pile])

        return LineBox(BoxAdapter(self.container_lbox,
                                  height=len(total_items) + 1 +
                                  len(self.btn_pile.contents)),
                       title=self.title)
Beispiel #36
0
 def __init__(self, common, cb):
     self.common = common
     self.cb = cb
     _pile = [
         Padding.center_90(Text("Choose a solution to get started:")),
         Padding.center_90(Divider("\N{BOX DRAWINGS LIGHT HORIZONTAL}")),
         Padding.center_90(self.build_menuable_items()),
         Padding.line_break(""),
         Padding.center_20(self.buttons())
     ]
     super().__init__(ListBox(_pile))
Beispiel #37
0
 def __init__(self, walker, **kwargs):
     """
     :param walker: tree of widgets to be displayed.
         In case we are given a raw `TreeWalker`, it will be used though
         `TreeListWalker` which means no decoration.
     :type walker: TreeWalker or TreeListWalker
     """
     if not isinstance(walker, TreeListWalker):
         walker = TreeListWalker(walker)
     self._walker = walker
     self._outer_list = ListBox(walker)
     self.__super.__init__(self._outer_list)
 def keypress(self, size, key):
     key = self.body.keypress(size, key)
     if key == 'home':
         pos = self.body.get_home()
         if pos:
             self.change_focus(size, pos, coming_from='below')
     elif key == 'end':
         pos = self.body.get_end()
         if pos:
             self.change_focus(size, pos, coming_from='above')
     elif key:
         return ListBox.keypress(self, size, key)
Beispiel #39
0
 def __init__(self, tree, focus=None):
     """
     :param tree: tree of widgets to be displayed.
     :type tree: Tree
     :param focus: initially focussed position
     """
     self._tree = tree
     self._walker = TreeListWalker(tree)
     self._outer_list = ListBox(self._walker)
     if focus is not None:
         self._outer_list.set_focus(focus)
     self.__super.__init__(self._outer_list)
Beispiel #40
0
    def __init__(self, **kwargs):#{{{

        self.search_box = SearchBox()
        self.items_count = Text("", align='right')

        self.search_items = SimpleListWalker(self._null_list_item())
        connect_signal(self.search_items, "modified", self._update_items_count)
        self.search_list = ListBox(self.search_items)

        connect_signal(self.search_box, "edit-done", self.on_edit_done)
        connect_signal(self.search_box, "edit-cancel", lambda w: self.quit())
        connect_signal(self.search_box, "change", lambda sb, term: self.set_search_term(term))

        self._constr = self.get_item_constructor()

        self.multiple_selection = kwargs.pop('multiple_selection', False)
        self._selected_items = OrderedSet([])

        opts = {
            'height': kwargs.get('height', None),
            'width': kwargs.get('width', ('relative', 90)),
            'title': kwargs.get('title', self.title),
            'subtitle': kwargs.get('subtitle', self.subtitle),
            'compact_header': kwargs.get('compact_header', True),
        }
        kwargs.update(opts)

        self.pile = Pile([
            ('fixed', 15, AttrMap(self.search_list, 'dialog.search.item')),
            Columns([
                AttrMap(self.search_box, 'dialog.search.input'),
                ('fixed', 1, AttrMap(Divider(), 'dialog.search.input')),
                ('fixed', 4, AttrMap(self.items_count, 'dialog.search.input')),
                ]),
            ], focus_item=0)

        self.__super.__init__(self.pile, **kwargs)

        self.attr_style = "dialog.search"
        self.title_attr_style = "dialog.search.title"
        self.subtitle_attr_style = "dialog.search.subtitle"
Beispiel #41
0
class CursesGUI(object):

    def __init__(self, choice_callback=None,
                       command_callback=None,
                       help_callback=None):

        self.palette = [
                ('brick', 'light red', 'black'),
                ('rubble', 'yellow', 'black'),
                ('wood', 'light green', 'black'),
                ('concrete', 'white', 'black'),
                ('stone', 'light cyan', 'black'),
                ('marble', 'light magenta', 'black'),
                ('jack', 'dark gray', 'white'),
                ('msg_info', 'white', 'black'),
                ('msg_err', 'light red', 'black'),
                ('msg_debug', 'light green', 'black'),
                ]

        self.choice_callback = choice_callback
        self.command_callback = command_callback
        self.help_callback = help_callback

        self.screen = None
        self.loop = None
        self.called_loop_stop = False
        self.reactor_stop_fired = False

        self.quit_flag = False
        self.edit_msg = "Make selection ('q' to quit): "
        self.roll_list = SimpleListWalker([])
        self.game_log_list = SimpleListWalker([])
        self.choices_list = SimpleListWalker([])

        self.state_text = SimpleListWalker([Text('Connecting...')])

        self.edit_widget = Edit(self.edit_msg)
        self.roll = ListBox(self.roll_list)
        self.game_log = ListBox(self.game_log_list)
        self.choices = ListBox(self.choices_list)
        self.state = ListBox(self.state_text)

        self.left_frame = Pile([
                LineBox(self.state),
                (13, LineBox(self.choices)),
                ])

        self.right_frame = Pile([
                LineBox(self.game_log),
                LineBox(self.roll)
                ])

        self.state.set_focus(len(self.state_text)-1)

        self.columns = Columns([('weight', 0.75, self.left_frame),
                                ('weight', 0.25, self.right_frame)
                                ])
        self.frame_widget = Frame(footer=self.edit_widget,
                                  body=self.columns,
                                  focus_part='footer')

        self.exc_info = None


    def register_loggers(self):
        """Gets the global loggers and sets up log handlers.
        """
        self.game_logger_handler = RollLogHandler(self._roll_write)
        self.logger_handler = RollLogHandler(self._roll_write)

        self.game_logger = logging.getLogger('gtr.game')
        self.logger = logging.getLogger('gtr')

        self.logger.addHandler(self.logger_handler)
        self.game_logger.addHandler(self.game_logger_handler)

        #self.set_log_level(logging.INFO)


    def unregister_loggers(self):
        self.game_logger.removeHandler(self.game_logger_handler)
        self.logger.removeHandler(self.logger_handler)


    def fail_safely(f):
        """Wraps functions in this class to catch arbitrary exceptions,
        shut down the event loop and reset the terminal to a normal state.

        It then re-raises the exception.
        """
        @wraps(f)
        def wrapper(self, *args, **kwargs):
            retval = None
            try:
                retval = f(self, *args, **kwargs)
            except urwid.ExitMainLoop:
                from twisted.internet import reactor
                if not self.reactor_stop_fired and reactor.running:
                    # Make sure to call reactor.stop once
                    reactor.stop()
                    self.reactor_stop_fired = True

            except:
                #pdb.set_trace()
                from twisted.internet import reactor
                if not self.reactor_stop_fired and reactor.running:
                    # Make sure to call reactor.stop once
                    reactor.stop()
                    self.reactor_stop_fired = True

                if not self.called_loop_stop:
                    self.called_loop_stop = True
                    self.loop.stop()
                
                # Save exception info for printing later outside the GUI.
                self.exc_info = sys.exc_info()

                raise

            return retval

        return wrapper
                

    def set_log_level(self, level):
        """Set the log level as per the standard library logging module.

        Default is logging.INFO.
        """
        logging.getLogger('gtr.game').setLevel(level)
        logging.getLogger('gtr').setLevel(level)


    def run(self):
        loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input)
        loop.run()

    def run_twisted(self):
        from twisted.internet import reactor
        evloop = urwid.TwistedEventLoop(reactor, manage_reactor=False)
        self.screen = urwid.raw_display.Screen()
        self.screen.register_palette(self.palette)
        self.loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input,
                             screen = self.screen,
                             event_loop = evloop)
        self.loop.set_alarm_in(0.1, lambda loop, _: loop.draw_screen())

        self.loop.start()

        # The loggers get a Handler that writes to the screen. We want this to only
        # happen if the screen exists, so de-register them after the reactor stops.
        reactor.addSystemEventTrigger('after','startup', self.register_loggers)
        reactor.addSystemEventTrigger('before','shutdown', self.unregister_loggers)
        reactor.run()
        
        # We might have stopped the screen already, and the stop() method
        # doesn't check for stopping twice.
        if self.called_loop_stop:
            self.logger.warn('Internal error!')
        else:
            self.loop.stop()
            self.called_loop_stop = True

    @fail_safely
    def handle_input(self, key):
        if key == 'enter':
            text = self.edit_widget.edit_text
            if text in ['q', 'Q']:
                self.handle_quit_request()
            else:
                self.quit_flag = False

                try:
                    i = int(text)
                except ValueError:
                    i = None
                    self.handle_invalid_choice(text)

                if i is not None:
                    self.handle_choice(i)

            self.edit_widget.set_edit_text('')

    def _roll_write(self, line, attr=None):
        """Add a line to the roll with palette attributes 'attr'.

        If no attr is specified, None is used.

        Default attr is plain text
        """
        text = Text((attr, '* ' + line))
            
        self.roll_list.append(text)
        self.roll_list.set_focus(len(self.roll_list)-1)
        self._modified()

    @fail_safely
    def update_state(self, state):
        """Sets the game state window via one large string.
        """
        self.logger.debug('Drawing game state.')
        self.state_text[:] = [self.colorize(s) for s in state.split('\n')]
        self._modified()

    @fail_safely
    def update_game_log(self, log):
        """Sets the game log window via one large string.
        """
        self.logger.debug('Drawing game log.')
        self.game_log_list[:] = [self.colorize(s) for s in log.split('\n')]
        self.game_log_list.set_focus(len(self.game_log_list)-1)
        self._modified()

    @fail_safely
    def update_choices(self, choices):
        """Update choices list.
        """
        self.choices_list[:] = [self.colorize(str(c)) for c in choices]
        self._modified()

        length = len([c for c in choices if c[2] == '['])
        i = randint(1,length) if length else 0
        self.choices_list.append(self.colorize('\nPicking random choice: {0} in 1s'.format(i)))
        self._modified()
        #from twisted.internet import reactor
        #reactor.callLater(1, self.handle_choice, i)

    @fail_safely
    def update_prompt(self, prompt):
        """Set the prompt for the input field.
        """
        self.edit_widget.set_caption(prompt)
        self._modified()


    def _modified(self):
        if self.loop:
            self.loop.draw_screen()


    @fail_safely
    def quit(self):
        """Quit the program.
        """
        #import pdb; pdb.set_trace()
        #raise TypeError('Artificial TypeError')
        raise urwid.ExitMainLoop()

    def handle_invalid_choice(self, s):
        if len(s):
            text = 'Invalid choice: "' + s + '". Please enter an integer.'
            self.logger.warn(text)

    def handle_quit_request(self):
        if True or self.quit_flag:
            self.quit()
        else:
            self.quit_flag = True
            text = 'Are you sure you want to quit? Press Q again to confirm.'
            self.logger.warn(text)

    def handle_choice(self, i):
        if self.choice_callback:
            self.choice_callback(i)


    def colorize(self, s):
        """Applies color to roles found in a string.

        A string with attributes applied looks like

        Text([('attr1', 'some text'), 'some more text'])

        so we need to split into a list of tuples of text.
        """
        regex_color_dict = {
              r'\b([Ll]egionaries|[Ll]egionary|[Ll]eg|LEGIONARIES|LEGIONARY|LEG)\b' : 'brick',
              r'\b([Ll]aborers?|[Ll]ab|LABORERS?|LAB)\b' : 'rubble',
              r'\b([Cc]raftsmen|[Cc]raftsman|[Cc]ra|CRAFTSMEN|CRAFTSMAN|CRA)\b' : 'wood',
              r'\b([Aa]rchitects?|[Aa]rc|ARCHITECTS?|ARC)\b' : 'concrete',
              r'\b([Mm]erchants?|[Mm]er|MERCHANTS?|MER)\b' : 'stone',
              r'\b([Pp]atrons?|[Pp]at|PATRONS?|PAT)\b' : 'marble',
              r'\b([Jj]acks?|JACKS?)\b' : 'jack',

              r'\b([Bb]ricks?|[Bb]ri|BRICKS?|BRI)\b' : 'brick',
              r'\b([Rr]ubble|[Rr]ub|RUBBLE|RUB)\b' : 'rubble',
              r'\b([Ww]ood|[Ww]oo|WOOD|WOO)\b' : 'wood',
              r'\b([Cc]oncrete|[Cc]on|CONCRETE|CON)\b' : 'concrete',
              r'\b([Ss]tone|[Ss]to|STONE|STO)\b' : 'stone',
              r'\b([Mm]arble|[Mm]ar|MARBLE|MAR)\b' : 'marble',
        }

        def _colorize(s, regex, attr):
            """s is a tuple of ('attr', 'text'). This splits based on the regex
            and adds attr to any matches. Returns a list of tuples

            [('attr1', 'text1'), ('attr2', 'text2'), ('attr3','text3')]

            with some attributes being None if they aren't colored.
            """
            output = []
            a, t = s
            # Make a list of all tokens, split by matches
            tokens = re.split(regex, t)
            for tok in tokens:
                m = re.match(regex, tok)
                if m:
                    # matches get the new attributes
                    output.append( (attr,tok) )
                else:
                    # non-matches keep the old ones
                    output.append( (a, tok) )

            return output


        output = [ (None, s) ] 
        
        for k,v in regex_color_dict.items():
            new_output = []
            for token in output:
                new_output.extend(_colorize(token, k, v))

            output[:] = new_output

        return Text(output)
Beispiel #42
0
class TreeBox(WidgetWrap):
    """
    A widget that displays a given :class:`Tree`.
    This is essentially a :class:`ListBox` with the ability to move the focus
    based on directions in the Tree and to collapse/expand subtrees if
    possible.

    TreeBox interprets `left/right` as well as `page up/`page down` to move the
    focus to parent/first child and next/previous sibling respectively. All
    other keys are passed to the underlying ListBox.
    """

    def __init__(self, tree, focus=None):
        """
        :param tree: tree of widgets to be displayed.
        :type tree: Tree
        :param focus: initially focussed position
        """
        self._tree = tree
        self._walker = TreeListWalker(tree)
        self._outer_list = ListBox(self._walker)
        if focus is not None:
            self._outer_list.set_focus(focus)
        self.__super.__init__(self._outer_list)

    # Widget API
    def get_focus(self):
        return self._outer_list.get_focus()

    def set_focus(self, pos):
        return self._outer_list.set_focus(pos)

    def refresh(self):
        self._walker.clear_cache()
        signals.emit_signal(self._walker, "modified")

    def keypress(self, size, key):
        key = self._outer_list.keypress(size, key)
        if key in ["left", "right", "[", "]", "-", "+", "C", "E"]:
            if key == "left":
                self.focus_parent()
            elif key == "right":
                self.focus_first_child()
            elif key == "[":
                self.focus_prev_sibling()
            elif key == "]":
                self.focus_next_sibling()
            elif key == "-":
                self.collapse_focussed()
            elif key == "+":
                self.expand_focussed()
            elif key == "C":
                self.collapse_all()
            elif key == "E":
                self.expand_all()
            # This is a hack around ListBox misbehaving:
            # it seems impossible to set the focus without calling keypress as
            # otherwise the change becomes visible only after the next render()
            return self._outer_list.keypress(size, None)
        else:
            return self._outer_list.keypress(size, key)

    # Collapse operations
    def collapse_focussed(self):
        """
        Collapse currently focussed position; works only if the underlying
        tree allows it.
        """
        if implementsCollapseAPI(self._tree):
            w, focuspos = self.get_focus()
            self._tree.collapse(focuspos)
            self._walker.clear_cache()
            self.refresh()

    def expand_focussed(self):
        """
        Expand currently focussed position; works only if the underlying
        tree allows it.
        """
        if implementsCollapseAPI(self._tree):
            w, focuspos = self.get_focus()
            self._tree.expand(focuspos)
            self._walker.clear_cache()
            self.refresh()

    def collapse_all(self):
        """
        Collapse all positions; works only if the underlying tree allows it.
        """
        if implementsCollapseAPI(self._tree):
            self._tree.collapse_all()
            self.set_focus(self._tree.root)
            self._walker.clear_cache()
            self.refresh()

    def expand_all(self):
        """
        Expand all positions; works only if the underlying tree allows it.
        """
        if implementsCollapseAPI(self._tree):
            self._tree.expand_all()
            self._walker.clear_cache()
            self.refresh()

    # Tree based focus movement
    def focus_parent(self):
        """move focus to parent node of currently focussed one"""
        w, focuspos = self.get_focus()
        parent = self._tree.parent_position(focuspos)
        if parent is not None:
            self.set_focus(parent)

    def focus_first_child(self):
        """move focus to first child of currently focussed one"""
        w, focuspos = self.get_focus()
        child = self._tree.first_child_position(focuspos)
        if child is not None:
            self.set_focus(child)

    def focus_last_child(self):
        """move focus to last child of currently focussed one"""
        w, focuspos = self.get_focus()
        child = self._tree.last_child_position(focuspos)
        if child is not None:
            self.set_focus(child)

    def focus_next_sibling(self):
        """move focus to next sibling of currently focussed one"""
        w, focuspos = self.get_focus()
        sib = self._tree.next_sibling_position(focuspos)
        if sib is not None:
            self.set_focus(sib)

    def focus_prev_sibling(self):
        """move focus to previous sibling of currently focussed one"""
        w, focuspos = self.get_focus()
        sib = self._tree.prev_sibling_position(focuspos)
        if sib is not None:
            self.set_focus(sib)

    def focus_next(self):
        """move focus to next position (DFO)"""
        w, focuspos = self.get_focus()
        next = self._tree.next_position(focuspos)
        if next is not None:
            self.set_focus(next)

    def focus_prev(self):
        """move focus to previous position (DFO)"""
        w, focuspos = self.get_focus()
        prev = self._tree.prev_position(focuspos)
        if prev is not None:
            self.set_focus(prev)
Beispiel #43
0
class TreeBox(WidgetWrap):
    """
    A widget representing something in a nested tree display.
    This is essentially a ListBox with the ability to move the focus based on
    directions in the Tree.

    TreeBox interprets `left/right` as well as page `up/down` to move the focus
    to parent/first child and next/previous sibling respectively. All other
    keys are passed to the underlying ListBox.
    """
    _selectable = True

    def __init__(self, walker, **kwargs):
        """
        :param walker: tree of widgets to be displayed.
            In case we are given a raw `TreeWalker`, it will be used though
            `TreeListWalker` which means no decoration.
        :type walker: TreeWalker or TreeListWalker
        """
        if not isinstance(walker, TreeListWalker):
            walker = TreeListWalker(walker)
        self._walker = walker
        self._outer_list = ListBox(walker)
        self.__super.__init__(self._outer_list)

    # Widget API
    def get_focus(self):
        return self._outer_list.get_focus()

    def keypress(self, size, key):
        key = self._outer_list.keypress(size, key)
        if key in ['left', 'right', '[', ']', '-', '+', 'C', 'E']:
            if key == 'left':
                self.focus_parent()
            elif key == 'right':
                self.focus_first_child()
            elif key == '[':
                self.focus_prev_sibling()
            elif key == ']':
                self.focus_next_sibling()
            if isinstance(self._walker, CollapseMixin):
                if key == '-':
                    w, focuspos = self._walker.get_focus()
                    self._walker.collapse(focuspos)
                elif key == '+':
                    w, focuspos = self._walker.get_focus()
                    self._walker.expand(focuspos)
                elif key == 'C':
                    self._walker.collapse_all()
                elif key == 'E':
                    self._walker.expand_all()
            # This is a hack around ListBox misbehaving:
            # it seems impossible to set the focus without calling keypress as
            # otherwise the change becomes visible only after the next render()
            return self._outer_list.keypress(size, None)
        else:
            return self._outer_list.keypress(size, key)

    # Tree based focus movement
    def focus_parent(self):
        w, focuspos = self._walker.get_focus()
        parent = self._walker.parent_position(focuspos)
        if parent is not None:
            self._outer_list.set_focus(parent)

    def focus_first_child(self):
        w, focuspos = self._walker.get_focus()
        child = self._walker.first_child_position(focuspos)
        if child is not None:
            self._outer_list.set_focus(child)

    def focus_next_sibling(self):
        w, focuspos = self._walker.get_focus()
        sib = self._walker.next_sibling_position(focuspos)
        if sib is not None:
            self._outer_list.set_focus(sib)

    def focus_prev_sibling(self):
        w, focuspos = self._walker.get_focus()
        sib = self._walker.prev_sibling_position(focuspos)
        if sib is not None:
            self._outer_list.set_focus(sib)
 def __init__(self, charset, root, preload_fields, focus, options={}):
     ListBox.__init__(self, Walker(charset, root, preload_fields, focus, options))
Beispiel #45
0
class SearchDialog(Dialog):#{{{
    title = "SearchDialog"
    subtitle = "GenericWindow"
    _items = []

    def __init__(self, **kwargs):#{{{

        self.search_box = SearchBox()
        self.items_count = Text("", align='right')

        self.search_items = SimpleListWalker(self._null_list_item())
        connect_signal(self.search_items, "modified", self._update_items_count)
        self.search_list = ListBox(self.search_items)

        connect_signal(self.search_box, "edit-done", self.on_edit_done)
        connect_signal(self.search_box, "edit-cancel", lambda w: self.quit())
        connect_signal(self.search_box, "change", lambda sb, term: self.set_search_term(term))

        self._constr = self.get_item_constructor()

        self.multiple_selection = kwargs.pop('multiple_selection', False)
        self._selected_items = OrderedSet([])

        opts = {
            'height': kwargs.get('height', None),
            'width': kwargs.get('width', ('relative', 90)),
            'title': kwargs.get('title', self.title),
            'subtitle': kwargs.get('subtitle', self.subtitle),
            'compact_header': kwargs.get('compact_header', True),
        }
        kwargs.update(opts)

        self.pile = Pile([
            ('fixed', 15, AttrMap(self.search_list, 'dialog.search.item')),
            Columns([
                AttrMap(self.search_box, 'dialog.search.input'),
                ('fixed', 1, AttrMap(Divider(), 'dialog.search.input')),
                ('fixed', 4, AttrMap(self.items_count, 'dialog.search.input')),
                ]),
            ], focus_item=0)

        self.__super.__init__(self.pile, **kwargs)

        self.attr_style = "dialog.search"
        self.title_attr_style = "dialog.search.title"
        self.subtitle_attr_style = "dialog.search.subtitle"
#}}}
    def keypress(self, key):#{{{
        if key == 'insert' and self.multiple_selection:
            if self.pile.get_focus().original_widget is self.search_list:
                wid, pos = self.search_list.get_focus()
            else:
                pos = 0
            current_item = self.search_items[pos]
            article = self.get_data_for(pos)
            current_item.original_widget.selected = not current_item.original_widget.selected
            if current_item.original_widget.selected:
                current_item.attr_map = {None: 'dialog.search.item.selected'}
                current_item.focus_map = {None: 'dialog.search.item.focus.selected'}
                self._selected_items.add(article)
            else:
                current_item.attr_map = {None: 'dialog.search.item'}
                current_item.focus_map = {None: 'dialog.search.item.focus'}
                self._selected_items.discard(article)

            self.search_list.set_focus(pos+1)
            self._update_items_count()
#}}}
    def on_edit_done(self, widget, text):#{{{
        result = []
        if self.pile.get_focus().original_widget is self.search_list:
            wid, pos = self.search_list.get_focus()
        else:
            pos = 0
        if self.multiple_selection:
            result = list(self._selected_items)
        if len(result) < 1:
            if self.get_data_for(pos):
                result = [self.get_data_for(pos)]
        self.dialog_result = result
        self.quit()
#}}}
    def set_search_term(self, term):#{{{
        self._clear_search_items()
        query = self.get_query(term)
        if query is not None:
            self._items = tuple(query[:150])
            if len(self._items) > 0:
                l_items = map(self._constr, self._items)
                for i in l_items:
                    i.set_search_box(self.search_box)
                self.search_items.extend([AttrMap(i, 'dialog.search.item',\
                    'dialog.search.item.focus') for i in l_items])
                if self.multiple_selection:
                    for a in (self._selected_items & set(self._items)):
                        idx = self._items.index(a)
                        self.search_items[idx].attr_map = {None: 'dialog.search.item.selected'}
                        self.search_items[idx].focus_map = {None: 'dialog.search.item.focus.selected'}
                        self.search_items[idx].original_widget.selected = True
                return
        self.search_items.extend(self._null_list_item())
#}}}
    def _clear_search_items(self):#{{{
        self.search_items[:] = []
        self._update_items_count()
#}}}
    def _null_list_item(self):#{{{
        null = SearchListItem([Text("")])
        null.set_search_box(self.search_box)
        return [null]
#}}}
    def _update_items_count(self):#{{{
        if len(self.search_items) > 149:
            self.items_count.set_text("+150")
        else:
            self.items_count.set_text("")
        selected_count = len(self._selected_items)
        if selected_count > 0:
            self._title_widget.set_text(self.title + (" (+%d)" % selected_count))
        else:
            self._title_widget.set_text(self.title)

#}}}
    def get_data_for(self, index):#{{{
        try:
            return self._items[index]
        except IndexError as e: # index out of range
            return None
#}}}
    def get_query(self, term):#{{{
        raise NotImplementedError("This must be implemented by subclass")
#}}}
    def get_item_constructor(self):#{{{
        return None
Beispiel #46
0
 def __init__(self):
     self._contents = SimpleListWalker([])
     ListBox.__init__(self, self._contents)
     self.client = JujuClient()