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(',')])))