Source code for consolemenu.multiselect_menu

import itertools

from consolemenu import ConsoleMenu
from consolemenu.items import SubmenuItem


[docs]class MultiSelectMenu(ConsoleMenu): """ Console menu that allows the selection of multiple menu items at a single prompt. Args: title: The menu title. subtitle: The menu subtitle. formatter: The menu formatter instance for styling the menu. prologue_text: The text to display in the prologue section of the menu. epilogue_text: The text to display in the epilogue section of the menu. show_exit_option (bool): Determines if the exit item should be displayed. exit_option_text (str): Text for the Exit menu item. Defaults to 'Exit'. clear_screen (bool): Set to False to disable clearing of screen between menus """ def __init__(self, title=None, subtitle=None, formatter=None, prologue_text=None, epilogue_text=None, ack_item_completion=True, show_exit_option=True, exit_option_text='Exit', clear_screen=True): super(MultiSelectMenu, self).__init__(title, subtitle, formatter=formatter, prologue_text=prologue_text, epilogue_text=epilogue_text, show_exit_option=show_exit_option, exit_option_text=exit_option_text, clear_screen=clear_screen) self.ack_item_completion = ack_item_completion
[docs] def append_item(self, item): """ Add an item to the end of the menu before the exit item. Note that Multi-Select Menus will not allow a SubmenuItem to be added, as multi-select menus are expected to be used only for executing multiple actions. Args: item (:obj:`MenuItem`): The item to be added Raises: TypeError: If the specified MenuIem is a SubmenuItem. """ if isinstance(item, SubmenuItem): raise TypeError("SubmenuItems cannot be added to a MultiSelectMenu") super(MultiSelectMenu, self).append_item(item)
[docs] def process_user_input(self): """ This overrides the method in ConsoleMenu to allow for comma-delimited and range inputs. Examples: All of the following inputs would have the same result: * 1,2,3,4 * 1-4 * 1-2,3-4 * 1 - 4 * 1, 2, 3, 4 Raises: ValueError: If the input cannot be correctly parsed. """ user_input = self.screen.input() try: indexes = self.__parse_range_list(user_input) # Subtract 1 from each number for its actual index number indexes[:] = [x - 1 for x in indexes if 0 < x < len(self.items) + 1] for index in indexes: self.current_option = index self.select() except Exception as e: return
@staticmethod def __parse_range(rng): parts = rng.split('-') if 1 > len(parts) > 2: raise ValueError("Bad range: '%s'" % (rng,)) parts = [int(i) for i in parts] start = parts[0] end = start if len(parts) == 1 else parts[1] if start > end: end, start = start, end return range(start, end + 1) def __parse_range_list(self, rngs): return sorted(set(itertools.chain(*[self.__parse_range(rng) for rng in rngs.split(',')])))