def _init_win(self, window): '''Require at least 70 columns and 6 lines to fit current needs for display of partitions and slices. Builds two inner ScrollWindows for displaying/editing the data. ''' if self.area.columns < 70: raise ValueError, "Insufficient space - area.columns < 70" if self.area.lines < 6: raise ValueError, "Insufficient space - area.lines < 6" self.win_width = (self.area.columns - DiskWindow.DEAD_ZONE + DiskWindow.SCROLL_PAD) / 2 super(DiskWindow, self)._init_win(window) win_area = WindowArea(self.area.lines - 1, self.win_width, 2, 0) win_area.scrollable_lines = self.area.lines - 2 self.left_win = ScrollWindow(win_area, window=self, add_obj=False) self.left_win.color = None self.left_win.highlight_color = None win_area.x_loc = self.win_width + DiskWindow.DEAD_ZONE win_area.scrollable_lines = 2 * PartitionInfo.MAX_LOGICAL_PARTITIONS self.right_win = ScrollWindow(win_area, window=self, add_obj=False) self.right_win.color = None self.right_win.highlight_color = None
def test_no_ut_refresh(self): '''Ensure deep_refresh is updating nested window screen location ''' scroll_win = ScrollWindow(WindowArea(60, 70, 0, 0, scrollable_columns=75), color_theme=ColorTheme(force_bw=True)) scroll_win.window = MockInnerWin() scroll_win.area.lower_right_y = 20 scroll_win.area.lower_right_x = 20 myscroll = ScrollWindow(WindowArea(10, 10, 0, 0, scrollable_columns=15), color_theme=ColorTheme(force_bw=True)) myscroll.window = MockInnerWin() myscroll.area.lower_right_y = 16 myscroll.area.lower_right_x = 18 scroll_win.objects.append(myscroll) scroll_win.area.y_loc = 3 scroll_win.area.x_loc = 5 abs_y = 12 abs_x = 15 scroll_win.latest_yx = (abs_y, abs_x) scroll_win.no_ut_refresh() self.assertEquals(myscroll.latest_yx[0], scroll_win.area.y_loc + abs_y) self.assertEquals(myscroll.latest_yx[1], scroll_win.area.x_loc + abs_x)
def test_horiz_scrollbar_created(self): '''Ensure horizontal scrollbar is created or not appropriately''' scroll_win = ScrollWindow(WindowArea(70, 70, 0, 0, scrollable_columns=75), color_theme=ColorTheme(force_bw=True)) self.assertTrue(scroll_win.get_use_horiz_scroll_bar()) scroll_win = ScrollWindow(WindowArea(70, 70, 0, 0, scrollable_columns=69), color_theme=ColorTheme(force_bw=True)) self.assertFalse(scroll_win.get_use_horiz_scroll_bar())
def test_vert_scrollbar_created(self): '''Ensure vertical scrollbar is created or not appropriately''' scroll_win = ScrollWindow(WindowArea(70, 70, 0, 0, scrollable_lines=75), color_theme=ColorTheme(force_bw=True)) self.assertTrue(scroll_win.get_use_vert_scroll_bar()) scroll_win = ScrollWindow(WindowArea(70, 70, 0, 0, scrollable_lines=70), color_theme=ColorTheme(force_bw=True)) self.assertFalse(scroll_win.get_use_vert_scroll_bar())
def test_active_object(self): '''Test that arrow key changes active object''' lines = 4 extra_lines = 9 scroll_win = ScrollWindow(WindowArea(lines, 70, 0, 0, scrollable_lines=lines + extra_lines), color_theme=ColorTheme(force_bw=True)) scroll_win.active_object = 0 myobj0 = MockEditField() myobj0.area = MockInnerWin() myobj0.area.y_loc = 1 myobj0.active = True myobj1 = MockEditField() myobj1.area = MockInnerWin() myobj1.area.y_loc = 3 myobj1.active = False scroll_win.objects.append(myobj0) scroll_win.objects.append(myobj1) key = scroll_win.on_arrow_key(curses.KEY_DOWN) self.assertEquals(key, None) self.assertEquals(scroll_win.active_object, 1)
def test_scroll_right_left_arrow(self): '''Test to scroll right and left with arrow key ''' cols = 3 extra_cols = 5 scroll_win = ScrollWindow(WindowArea(10, cols, 0, 0, scrollable_columns=cols+extra_cols), color_theme=ColorTheme(force_bw=True)) scroll_win.active_object = None self.assertTrue(scroll_win.at_left()) key = scroll_win.on_arrow_key(curses.KEY_RIGHT) self.assertEqual(key, None) self.assertFalse(scroll_win.at_left()) key = scroll_win.on_arrow_key(curses.KEY_LEFT) self.assertEqual(key, None) self.assertTrue(scroll_win.at_left()) key = scroll_win.on_arrow_key(curses.KEY_LEFT) self.assertEqual(key, curses.KEY_LEFT) self.assertTrue(scroll_win.at_left()) scroll_win.scroll(columns=extra_cols-2) self.assertFalse(scroll_win.at_left()) self.assertFalse(scroll_win.at_right()) scroll_win.on_arrow_key(curses.KEY_RIGHT) self.assertTrue(scroll_win.at_right()) scroll_win.scroll(columns=-(extra_cols-2)) self.assertFalse(scroll_win.at_left()) self.assertFalse(scroll_win.at_right()) scroll_win.on_arrow_key(curses.KEY_LEFT) self.assertTrue(scroll_win.at_left())
def test_scroll_down_up_arrow(self): '''Test to scroll down and up with arrow key ''' lines = 4 extra_lines = 9 scroll_win = ScrollWindow(WindowArea(lines, 70, 0, 0, scrollable_lines=lines + extra_lines), color_theme=ColorTheme(force_bw=True)) scroll_win.active_object = None self.assertTrue(scroll_win.at_top()) key = scroll_win.on_arrow_key(curses.KEY_DOWN) self.assertEqual(key, None) self.assertFalse(scroll_win.at_top()) key = scroll_win.on_arrow_key(curses.KEY_UP) self.assertEqual(key, None) self.assertTrue(scroll_win.at_top()) key = scroll_win.on_arrow_key(curses.KEY_UP) self.assertEqual(key, curses.KEY_UP) self.assertTrue(scroll_win.at_top()) scroll_win.scroll(extra_lines-2) self.assertFalse(scroll_win.at_bottom()) scroll_win.on_arrow_key(curses.KEY_DOWN) self.assertTrue(scroll_win.at_bottom()) scroll_win.scroll(-(extra_lines-2)) self.assertFalse(scroll_win.at_top()) scroll_win.on_arrow_key(curses.KEY_UP) self.assertTrue(scroll_win.at_top())
def display_help(self): '''Display the single file help screen''' # customize header help_header = "%s: %s" logging.debug("self.screen is =%s", self.screen) if self.screen in self.help_dict: help_header = help_header % (_("Help"), self.help_dict[self.screen][1]) help_text = self.get_help_text(self.help_dict[self.screen][0]) else: help_header = help_header % (_("Help"), _("Not Available")) help_text = _("Help for this screen is not available") self.main_win.set_header_text(help_header) help_text = convert_paragraph(help_text, self.win_size_x - 5) logging.debug("help_text #lines=%d, text is \n%s", len(help_text), help_text) area = WindowArea(x_loc=0, y_loc=1, scrollable_lines=(len(help_text) + 1)) area.lines = self.win_size_y - 1 area.columns = self.win_size_x self.scroll_region = ScrollWindow(area, window=self.center_win) self.scroll_region.add_paragraph(help_text, start_x=(area.x_loc + 3)) self.center_win.activate_object(self.scroll_region)
def test_scroll_no_args(self): '''Test that scroll called with no args throws ValueError''' scroll_win = ScrollWindow(WindowArea(70, 70, 0, 0, scrollable_lines=75), color_theme=ColorTheme(force_bw=True)) self.assertTrue(scroll_win.get_use_vert_scroll_bar()) self.assertEquals(scroll_win.current_line[0], 0) self.assertRaises(ValueError, scroll_win.scroll)
def _show(self): '''Create a scrollable region and fill it with the install log''' self.center_win.border_size = (0, 0) self.scroll_area = WindowArea(self.win_size_y, self.win_size_x, 0, 0, len(self.get_log_data())) log = ScrollWindow(self.scroll_area, window=self.center_win) log.add_paragraph(self.get_log_data(), 0, 2) self.center_win.activate_object(log)
def test_scroll_to_bottom(self): '''Test to scroll multiple lines to bottom of scrollarea''' lines = 70 extra_lines = 5 scroll_win = ScrollWindow(WindowArea(lines, 70, 0, 0, scrollable_lines=lines + extra_lines), color_theme=ColorTheme(force_bw=True)) scroll_win.scroll(scroll_to_line=5) self.assertTrue(scroll_win.at_bottom())
def test_scroll_to_right(self): '''Test to scroll multiple columns to right of scrollarea''' cols = 70 extra_cols = 5 scroll_win = ScrollWindow(WindowArea(70, cols, 0, 0, scrollable_columns=cols+extra_cols), color_theme=ColorTheme(force_bw=True)) scroll_win.scroll(scroll_to_column=5) self.assertTrue(scroll_win.at_right())
def test_scroll_one_col(self): '''Test to scroll one column ''' scroll_win = ScrollWindow(WindowArea(70, 70, 0, 0, scrollable_columns=75), color_theme=ColorTheme(force_bw=True)) self.assertTrue(scroll_win.get_use_horiz_scroll_bar()) self.assertEquals(scroll_win.current_line[1], 0) scroll_win.scroll(columns=1) self.assertEquals(scroll_win.current_line[1], 1)
def test_scroll_past_left(self): '''Test to scroll past left, should end up at left ''' cols = 70 extra_cols = 5 scroll_win = ScrollWindow(WindowArea(70, cols, 0, 0, scrollable_columns=cols+extra_cols), color_theme=ColorTheme(force_bw=True)) self.assertTrue(scroll_win.at_left()) scroll_win.scroll(columns=-3) self.assertTrue(scroll_win.at_left())
def test_scroll_past_top(self): '''Test to scroll past top, should end up at top ''' lines = 70 extra_lines = 5 scroll_win = ScrollWindow(WindowArea(lines, 70, 0, 0, scrollable_lines=lines + extra_lines), color_theme=ColorTheme(force_bw=True)) self.assertTrue(scroll_win.at_top()) scroll_win.scroll(lines=-3) self.assertTrue(scroll_win.at_top())
def test_act_obj_indexerr_not_edge(self): '''Test arrow key, active object, IndexError, not at edge''' lines = 4 extra_lines = 9 scroll_win = ScrollWindow(WindowArea(lines, 70, 0, 0, scrollable_lines=lines + extra_lines), color_theme=ColorTheme(force_bw=True)) scroll_win.active_object = 0 scroll_win.objects.append(object()) key = scroll_win.on_arrow_key(curses.KEY_DOWN) self.assertEquals(scroll_win.current_line[0], 1) self.assertEquals(key, None)
def _show(self): '''Create a list of NICs to choose from. If more than 15 NICs are found, create a scrolling region to put them in ''' self.nic = self.install_profile.nic if self.nic.type != NetworkInfo.MANUAL: raise SkipException if len(self.ether_nics) == 1: self.set_nic_in_profile(self.ether_nics[0]) raise SkipException try: selected_nic_name = self.nic.nic_name except AttributeError: selected_nic_name = "" y_loc = 1 y_loc += self.center_win.add_paragraph(NICSelect.PARAGRAPH, y_loc) selected_nic = 0 y_loc += 1 max_nics = min(NICSelect.MAX_NICS, self.center_win.area.lines - y_loc) if len(self.ether_nics) > max_nics: columns = self.win_size_x - NICSelect.LIST_OFFSET win_area = WindowArea(lines=max_nics, columns=columns, y_loc=y_loc, x_loc=NICSelect.LIST_OFFSET, scrollable_lines=len(self.ether_nics)) window = ScrollWindow(win_area, window=self.center_win) y_loc = 0 else: window = self.center_win for nic in self.ether_nics: self.list_area.y_loc = y_loc self.list_area.columns = len(nic) + 1 list_item = ListItem(self.list_area, window=window, text=nic, data_obj=nic) if nic == selected_nic_name: selected_nic = list_item y_loc += 1 self.main_win.do_update() self.center_win.activate_object(selected_nic)
def display_help_topics(self): '''Display the help topics screen.''' self.main_win.set_header_text(HelpScreen.HELP_HEADER) y_loc = 1 y_loc += self.center_win.add_paragraph(HelpScreen.INTRO, y_loc, 1, max_x=(self.win_size_x - 1)) y_loc += 1 area = WindowArea(scrollable_lines=(len(self.help_info) + 1), y_loc=y_loc, x_loc=0) logging.debug("lines=%s", len(self.help_dict)) area.lines = self.win_size_y - (y_loc + 1) area.columns = self.win_size_x self.scroll_region = ScrollWindow(area, window=self.center_win) # add the entries to the screen logging.debug("range=%s", len(self.help_info)) for idx, info in enumerate(self.help_info): # create ListItem for each help topic topic_format = info[1] help_topic = self.get_help_topic(info[0]) help_topic = topic_format % help_topic hilite = min(self.win_size_x, textwidth(help_topic) + 1) list_item = ListItem(WindowArea(1, hilite, idx, 0), window=self.scroll_region, text=help_topic) help_screens = info[0] logging.debug("help_screens=%s", list(help_screens)) logging.debug("self.screen_last=%s", self.screen_last) if self.screen_last in help_screens: logging.debug("Set cur_help_idx = %s", idx) self.cur_help_idx = idx logging.debug("beg_y=%d, beg_x=%d", *list_item.window.getbegyx()) self.center_win.activate_object(self.scroll_region) self.scroll_region.activate_object(self.cur_help_idx)
def _show(self): '''Prepare a text summary from the install_profile and display it to the user in a ScrollWindow ''' y_loc = 1 y_loc += self.center_win.add_paragraph(SummaryScreen.PARAGRAPH, y_loc) y_loc += 1 summary_text = self.build_summary() # Wrap the summary text, accounting for the INDENT (used below in # the call to add_paragraph) max_chars = self.win_size_x - SummaryScreen.INDENT - 1 summary_text = convert_paragraph(summary_text, max_chars) area = WindowArea(x_loc=0, y_loc=y_loc, scrollable_lines=(len(summary_text)+1)) area.lines = self.win_size_y - y_loc area.columns = self.win_size_x scroll_region = ScrollWindow(area, window=self.center_win) scroll_region.add_paragraph(summary_text, start_x=SummaryScreen.INDENT) self.center_win.activate_object(scroll_region)
def reset(self): '''Create the InnerWindows representing the header, footer/border, error line, and main central_area ''' window_size = self.initscr.getmaxyx() win_size_y = window_size[0] win_size_x = window_size[1] footer_area = WindowArea(1, win_size_x, win_size_y - 1, 0) self.footer = InnerWindow(footer_area, color_theme=self.theme, color=self.theme.border) top = self.initscr.derwin(1, win_size_x, 0, 0) left = self.initscr.derwin(win_size_y - 2, 1, 1, 0) right = self.initscr.derwin(win_size_y - 2, 1, 1, win_size_x - 1) self.footer.more_windows = [top, left, right] self.footer.set_color(self.theme.border) header_area = WindowArea(1, win_size_x - 2, 1, 1) self.header = InnerWindow(header_area, color_theme=self.theme, color=self.theme.header) central_win_area = WindowArea(win_size_y - 4, win_size_x - 2, 2, 1) self.central_area = InnerWindow(central_win_area, border_size=(0, 2), color_theme=self.theme) self._active_win = self.central_area popup_win_area = WindowArea(central_win_area.lines - 10, central_win_area.columns - 20, 5, 10, central_win_area.lines - 10) self.popup_win = ScrollWindow(popup_win_area, window=self.central_area, color=self.theme.error_msg, highlight_color=self.theme.error_msg) error_area = WindowArea(1, win_size_x - 2, win_size_y - 2, 1) self.error_line = ErrorWindow(error_area, color_theme=self.theme) self.reset_actions()
def _show(self): '''Create a list of disks to choose from and create the window for displaying the partition/slice information from the selected disk ''' if self.install_profile.install_to_pool: raise SkipException self.wait_for_disks() self.num_targets = 0 if not self.disks: self.center_win.add_paragraph(DiskScreen.NO_DISKS, 1, 1, max_x=(self.win_size_x - 1)) return if isinstance(self.disks[0], BaseException): if len(self.disks) == 1: raise tgt.TgtError(("Unexpected error (%s) during target " "discovery. See log for details.") % self.disks[0]) else: self.disks = self.disks[1:] logging.warn("Failure in target discovery, but one or more" " disks found. Continuing.") boot_disk = self.disks[0] for disk in self.disks: if (disk.size.size_as("gb") > self.minimum_size): self.num_targets += 1 if disk.boot: boot_disk = disk self.disks.remove(boot_disk) self.disks.insert(0, boot_disk) if self.num_targets == 0: self.center_win.add_paragraph(DiskScreen.NO_TARGETS, 1, 1, max_x=(self.win_size_x - 1)) return self.main_win.reset_actions() self.main_win.show_actions() y_loc = 1 self.center_win.add_text(DiskScreen.PARAGRAPH, y_loc, 1) y_loc += 1 self.center_win.add_text(self.size_line, y_loc, 1) y_loc += 2 self.center_win.add_text(self.disk_header_text, y_loc, 1) y_loc += 1 self.center_win.window.hline(y_loc, self.center_win.border_size[1] + 1, curses.ACS_HLINE, textwidth(self.disk_header_text)) y_loc += 1 disk_win_area = WindowArea(4, textwidth(self.disk_header_text) + 2, y_loc, 0) disk_win_area.scrollable_lines = len(self.disks) + 1 self.disk_win = ScrollWindow(disk_win_area, window=self.center_win) disk_item_area = WindowArea(1, disk_win_area.columns - 2, 0, 1) disk_index = 0 len_use = DiskScreen.DISK_HEADERS[0][0] - 1 len_type = DiskScreen.DISK_HEADERS[1][0] - 1 len_size = DiskScreen.DISK_HEADERS[2][0] - 1 len_boot = DiskScreen.DISK_HEADERS[3][0] - 1 len_dev = DiskScreen.DISK_HEADERS[4][0] - 1 len_mftr = DiskScreen.DISK_HEADERS[5][0] - 1 for disk in self.disks: disk_text_fields = [] type_field = disk.type[:len_type] type_field = ljust_columns(type_field, len_type) disk_text_fields.append(type_field) disk_size = disk.size.size_as("gb") size_field = "%*.1f" % (len_size, disk_size) disk_text_fields.append(size_field) if disk.boot: bootable_field = "+".center(len_boot) else: bootable_field = " " * (len_boot) disk_text_fields.append(bootable_field) device_field = disk.name[:len_dev] device_field = ljust_columns(device_field, len_dev) disk_text_fields.append(device_field) if disk.vendor is not None: mftr_field = disk.vendor[:len_mftr] mftr_field = ljust_columns(mftr_field, len_mftr) else: mftr_field = " " * len_mftr disk_text_fields.append(mftr_field) selectable = True if disk_size < self.minimum_size: note_field = self.too_small_text selectable = False elif DiskInfo.GPT in disk.label: note_field = DiskScreen.GPT_LABELED elif disk_size > SliceInfo.MAX_VTOC.size_as("gb"): note_field = self.too_big_warn else: note_field = "" # Use first selectable disk if no disk was used yet if disk.used is None and not self.one_disk_used and selectable: disk.used = True self.one_disk_used = True disk_text_fields.append(note_field) disk_text = " ".join(disk_text_fields) disk_item_area.y_loc = disk_index disk_list_item = MultiListItem(disk_item_area, window=self.disk_win, text=disk_text, add_obj=selectable, used=disk.used) disk_list_item.on_make_active = on_activate disk_list_item.on_make_active_kwargs["disk_info"] = disk disk_list_item.on_make_active_kwargs["disk_select"] = self disk_list_item.on_select = on_select disk_list_item.on_select_kwargs["disk_info"] = disk disk_list_item.on_select_kwargs["disk_select"] = self disk_index += 1 self.disk_win.no_ut_refresh() y_loc += 7 disk_detail_area = WindowArea(6, 70, y_loc, 1) self.disk_detail = DiskWindow(disk_detail_area, self.disks[0], window=self.center_win) self.main_win.do_update() self.center_win.activate_object(self.disk_win) self.disk_win.activate_object(self.selected_disk) # Set the flag so that the disk is not copied by on_change_screen, # unless on_select gets called as a result of the user changing # the selected disks. self.do_copy = False
def _show(self): '''Create a list of pools to choose from, ask user to select BE name and if we should overwrite pool's boot configuration ''' if not self.install_profile.install_to_pool: raise SkipException if len(self.existing_pools) == 0: self.existing_pools.extend(get_zpool_list()) self.num_targets = 0 if len(self.existing_pools) == 0: self.center_win.add_paragraph(ZpoolScreen.NO_POOLS, 1, 1, max_x=(self.win_size_x - 1)) return for pool in self.existing_pools: free_gb = get_zpool_free_size(pool) / 1024 / 1024 / 1024 if (get_zpool_free_size(pool) / 1024 / 1024 / 1024 > self.minimum_size): self.num_targets += 1 else: logging.info("Skipping pool %s: need %d GB, free %d GB" % (pool, self.minimum_size, free_gb)) if self.num_targets == 0: self.center_win.add_paragraph(ZpoolScreen.NO_TARGETS, 1, 1, max_x=(self.win_size_x - 1)) return self.main_win.reset_actions() self.main_win.show_actions() y_loc = 1 self.center_win.add_text(ZpoolScreen.PARAGRAPH, y_loc, 1) y_loc += 1 self.center_win.add_text(self.size_line, y_loc, 1) y_loc += 2 self.center_win.add_text(self.pool_header_text, y_loc, 1) y_loc += 1 self.center_win.window.hline(y_loc, self.center_win.border_size[1] + 1, curses.ACS_HLINE, textwidth(self.pool_header_text)) y_loc += 1 pool_win_area = WindowArea(4, textwidth(self.pool_header_text) + 2, y_loc, 0) pool_win_area.scrollable_lines = len(self.existing_pools) + 1 self.pool_win = ScrollWindow(pool_win_area, window=self.center_win) pool_item_area = WindowArea(1, pool_win_area.columns - 2, 0, 1) pool_index = 0 len_name = ZpoolScreen.POOL_HEADERS[0][0] - 1 len_size = ZpoolScreen.POOL_HEADERS[2][0] - 1 for pool in self.existing_pools: pool_text_fields = [] name_field = pool[:len_name] name_field = ljust_columns(name_field, len_name) pool_text_fields.append(name_field) pool_size = get_zpool_free_size(pool) / 1024 / 1024 / 1024 size_field = "%*.1f" % (len_size, pool_size) pool_text_fields.append(size_field) selectable = True if pool_size < self.minimum_size: note_field = self.too_small_text selectable = False else: note_field = "" pool_text_fields.append(note_field) pool_text = " ".join(pool_text_fields) pool_item_area.y_loc = pool_index pool_list_item = ListItem(pool_item_area, window=self.pool_win, text=pool_text, add_obj=selectable) pool_list_item.on_make_active = on_activate pool_list_item.on_make_active_kwargs["pool_select"] = self pool_index += 1 self.pool_win.no_ut_refresh() y_loc += 7 self.list_area.y_loc = y_loc y_loc += 2 self.error_area.y_loc = y_loc self.be_name_err = ErrorWindow(self.error_area, window=self.center_win) self.be_name_list = ListItem(self.list_area, window=self.center_win, text=ZpoolScreen.BE_LABEL) self.be_name_edit = EditField(self.edit_area, window=self.be_name_list, validate=be_name_valid, error_win=self.be_name_err, text=self.install_profile.be_name) y_loc += 2 boot_configuration_width = textwidth( ZpoolScreen.OVERWRITE_BOOT_CONFIGURATION_LABEL) + 5 cols = int((self.win_size_x - boot_configuration_width) / 2) boot_configuration_area = WindowArea(1, boot_configuration_width, y_loc, cols) self.boot_configuration_item = MultiListItem( boot_configuration_area, window=self.center_win, text=ZpoolScreen.OVERWRITE_BOOT_CONFIGURATION_LABEL, used=self.install_profile.overwrite_boot_configuration) self.boot_configuration_item.on_select = on_select_obc self.boot_configuration_item.on_select_kwargs["pool_select"] = self self.main_win.do_update() self.center_win.activate_object(self.pool_win) self.pool_win.activate_object(self.selected_pool) # Set the flag so that the pool is not copied by on_change_screen, # unless on_activate gets called as a result of the user changing # the selected pool. self.do_copy = False
def _show(self): '''Create the list of time zones''' logging.debug("self.screen %s", self.screen) if self.install_profile.system is None: self.install_profile.system = SystemInfo() self.sys_info = self.install_profile.system self.cur_country = self.sys_info.tz_country self.cur_continent = self.sys_info.tz_region if self.cur_continent == SystemInfo.UTC and self.screen != "regions": raise SkipException self.center_win.border_size = TimeZone.BORDER_WIDTH if self.screen == TimeZone.LOCATIONS: self.cur_timezone_parent = self.cur_continent elif self.screen == TimeZone.TIMEZONE: self.cur_timezone_parent = self.cur_country logging.debug("cur_continent %s, cur_country %s", self.cur_continent, self.cur_country) y_loc = 1 y_loc += self.center_win.add_paragraph(self.intro, y_loc) y_loc += 1 menu_item_max_width = self.win_size_x - TimeZone.SCROLL_SIZE self.center_win.add_text(self.title, y_loc, TimeZone.SCROLL_SIZE) y_loc += 1 self.center_win.window.hline(y_loc, 3, curses.ACS_HLINE, 40) y_loc += 1 tz_list = self.get_timezones(self.cur_continent, self.cur_country) area = WindowArea(x_loc=0, y_loc=y_loc, scrollable_lines=len(tz_list) + 1) area.lines = self.win_size_y - (y_loc + 1) area.columns = self.win_size_x logging.debug("area.lines=%d, area.columns=%d", area.lines, area.columns) self.scroll_region = ScrollWindow(area, window=self.center_win) utc = 0 if self.screen == TimeZone.REGIONS: utc_area = WindowArea(1, len(TimeZone.UTC_TEXT) + 1, 0, TimeZone.SCROLL_SIZE) utc_item = ListItem(utc_area, window=self.scroll_region, text=TimeZone.UTC_TEXT, data_obj=SystemInfo.UTC) utc = 1 # add the entries to the screen for idx, timezone in enumerate(tz_list): logging.log(LOG_LEVEL_INPUT, "tz idx = %i name= %s", idx, tz_list[idx]) hilite = min(menu_item_max_width, len(timezone) + 1) win_area = WindowArea(1, hilite, idx + utc, TimeZone.SCROLL_SIZE) list_item = ListItem(win_area, window=self.scroll_region, text=timezone, data_obj=timezone) y_loc += 1 self.main_win.do_update() self.center_win.activate_object(self.scroll_region) logging.debug("self.cur_timezone_idx=%s", self.cur_timezone_idx) self.scroll_region.activate_object_force(self.cur_timezone_idx, force_to_top=True)