[nyx/master] Common method for line wrapping

commit 475874849090f7a47bea0e4b7987a7d40a454a14 Author: Damian Johnson <atagar@torproject.org> Date: Tue Feb 9 20:29:30 2016 -0800 Common method for line wrapping Our log panel, torrc panel, and descriptor popup all draw lines with wrapping. Rather then reinvent the wheel three spots adding a helper to our panel. Only change (I hope) is that log panels now don't split with a hyphen. --- nyx/log_panel.py | 30 +++++------------------------- nyx/popups.py | 20 ++------------------ nyx/torrc_panel.py | 37 ++++--------------------------------- nyx/util/panel.py | 31 ++++++++++++++++++++++++++++++- nyxrc.sample | 5 +---- 5 files changed, 42 insertions(+), 81 deletions(-) diff --git a/nyx/log_panel.py b/nyx/log_panel.py index e1c79af..4fdb8ad 100644 --- a/nyx/log_panel.py +++ b/nyx/log_panel.py @@ -15,8 +15,8 @@ import nyx.arguments import nyx.popups import nyx.util.log -from stem.util import conf, log, str_tools from nyx.util import join, panel, tor_controller, ui_tools +from stem.util import conf, log def conf_handler(key, value): @@ -368,38 +368,18 @@ class LogPanel(panel.Panel, threading.Thread): Presents a log entry with line wrapping. """ - def draw_line(x, y, width, msg, *attr): - msg, remaining_lines = msg.split('\n', 1) if ('\n' in msg) else (msg, '') - msg, cropped = str_tools.crop(msg, width - x - 1, min_crop = 4, ending = str_tools.Ending.HYPHEN, get_remainder = True) - x = self.addstr(y, x, msg, *attr) - return x, (cropped + '\n' + remaining_lines).strip() - - def draw_msg(min_x, x, y, width, msg, *attr): - orig_y = y - - while msg: - x, msg = draw_line(x, y, width, msg, *attr) - - if (y - orig_y + 1) >= CONFIG['features.log.maxLineWrap']: - break # filled up the maximum number of lines we're allowing for - - if msg: - msg = ' ' + msg # indent the next line - x, y = min_x, y + 1 - - return x, y - - min_x, msg = x, entry.display_message + min_x, msg = x + 2, entry.display_message boldness = curses.A_BOLD if 'ERR' in entry.type else curses.A_NORMAL # emphasize ERR messages color = CONFIG['attr.log_color'].get(entry.type, 'white') - x, y = draw_msg(min_x, x, y, width, msg, boldness, color) + for line in msg.splitlines(): + x, y = self.addstr_wrap(y, x, line, width, min_x, boldness, color) if entry.duplicates and not show_duplicates: duplicate_count = len(entry.duplicates) - 1 plural = 's' if duplicate_count > 1 else '' duplicate_msg = ' [%i duplicate%s hidden]' % (duplicate_count, plural) - x, y = draw_msg(min_x, x, y, width, duplicate_msg, curses.A_BOLD, 'green') + x, y = self.addstr_wrap(y, x, duplicate_msg, width, min_x, curses.A_BOLD, 'green') return y + 1 diff --git a/nyx/popups.py b/nyx/popups.py index 017b672..c25b321 100644 --- a/nyx/popups.py +++ b/nyx/popups.py @@ -11,8 +11,6 @@ import nyx.controller from nyx import __version__, __release_date__ from nyx.util import tor_controller, panel, ui_tools -from stem.util import str_tools - NO_STATS_MSG = "Usage stats aren't available yet, press any key..." HEADERS = ['Consensus:', 'Microdescriptor:', 'Server Descriptor:'] @@ -529,20 +527,6 @@ def _preferred_size(text, max_width, show_line_numbers): def _draw(popup, title, lines, entry_color, scroll, show_line_numbers): - def draw_msg(popup, min_x, x, y, width, msg, *attr): - while msg: - draw_msg, msg = str_tools.crop(msg, width - x, None, ending = None, get_remainder = True) - - if not draw_msg: - draw_msg, msg = str_tools.crop(msg, width - x), '' # first word is longer than the line - - x = popup.addstr(y, x, draw_msg, *attr) - - if msg: - x, y = min_x, y + 1 - - return x, y - popup.win.erase() line_number_width = int(math.log10(len(lines))) + 1 @@ -574,8 +558,8 @@ def _draw(popup, title, lines, entry_color, scroll, show_line_numbers): if show_line_numbers: popup.addstr(y, 2, str(i + 1).rjust(line_number_width), curses.A_BOLD, LINE_NUMBER_COLOR) - x, y = draw_msg(popup, offset, offset, y, width, keyword, color, curses.A_BOLD) - x, y = draw_msg(popup, offset, x + 1, y, width, value, color) + x, y = popup.addstr_wrap(y, width, keyword, width, offset, color, curses.A_BOLD) + x, y = popup.addstr_wrap(y, x + 1, value, width, offset, color) y += 1 diff --git a/nyx/torrc_panel.py b/nyx/torrc_panel.py index 89d42f3..1958b4e 100644 --- a/nyx/torrc_panel.py +++ b/nyx/torrc_panel.py @@ -9,17 +9,6 @@ from nyx.util import expand_path, msg, panel, tor_controller, ui_tools from stem import ControllerError from stem.control import State -from stem.util import conf, str_tools - - -def conf_handler(key, value): - if key == 'features.torrc.maxLineWrap': - return max(1, value) - - -CONFIG = conf.config_dict('nyx', { - 'features.torrc.maxLineWrap': 8, -}, conf_handler) class TorrcPanel(panel.Panel): @@ -145,25 +134,6 @@ class TorrcPanel(panel.Panel): scroll_offset = 3 self.add_scroll_bar(self._scroll, self._scroll + height - 1, self._last_content_height, 1) - def draw_msg(min_x, x, y, width, msg, *attr): - orig_y = y - - while msg: - draw_msg, msg = str_tools.crop(msg, width - x, None, ending = None, get_remainder = True) - - if not draw_msg: - draw_msg, msg = str_tools.crop(msg, width - x), '' # first word is longer than the line - - x = self.addstr(y, x, draw_msg, *attr) - - if (y - orig_y + 1) >= CONFIG['features.torrc.maxLineWrap']: - break # filled up the maximum number of lines we're allowing for - - if msg: - x, y = min_x, y + 1 - - return x, y - y = 1 - self._scroll is_multiline = False # true if we're in the middle of a multiline torrc entry @@ -178,6 +148,7 @@ class TorrcPanel(panel.Panel): if '#' in line: line, comment = line.split('#', 1) + comment = '#' + comment # splits the option and argument, preserving any whitespace around them @@ -208,9 +179,9 @@ class TorrcPanel(panel.Panel): x = line_number_offset + scroll_offset min_x = line_number_offset + scroll_offset - x, y = draw_msg(min_x, x, y, width, option, curses.A_BOLD, 'green') - x, y = draw_msg(min_x, x, y, width, argument, curses.A_BOLD, 'cyan') - x, y = draw_msg(min_x, x, y, width, comment, 'white') + x, y = self.addstr_wrap(y, x, option, width, min_x, curses.A_BOLD, 'green') + x, y = self.addstr_wrap(y, x, argument, width, min_x, curses.A_BOLD, 'cyan') + x, y = self.addstr_wrap(y, x, comment, width, min_x, 'white') y += 1 diff --git a/nyx/util/panel.py b/nyx/util/panel.py index efade79..136fe85 100644 --- a/nyx/util/panel.py +++ b/nyx/util/panel.py @@ -11,7 +11,7 @@ from threading import RLock from nyx.util import text_input, ui_tools -from stem.util import log +from stem.util import conf, log, str_tools # global ui lock governing all panel instances (curses isn't thread save and # concurrency bugs produce especially sinister glitches) @@ -33,6 +33,16 @@ SPECIAL_KEYS = { } +def conf_handler(key, value): + if key == 'features.torrc.maxLineWrap': + return max(1, value) + + +CONFIG = conf.config_dict('nyx', { + 'features.maxLineWrap': 8, +}, conf_handler) + + # tags used by addfstr - this maps to functor/argument combinations since the # actual values (in the case of color attributes) might not yet be initialized @@ -534,6 +544,25 @@ class Panel(object): return x + def addstr_wrap(self, y, x, msg, width, min_x = 0, *attr): + orig_y = y + + while msg: + draw_msg, msg = str_tools.crop(msg, width - x, None, ending = None, get_remainder = True) + + if not draw_msg: + draw_msg, msg = str_tools.crop(msg, width - x), '' # first word is longer than the line + + x = self.addstr(y, x, draw_msg, *attr) + + if (y - orig_y + 1) >= CONFIG['features.maxLineWrap']: + break # maximum number we'll wrap + + if msg: + x, y = min_x, y + 1 + + return x, y + def getstr(self, y, x, initial_text = '', text_format = None, max_width = None, validator = None): """ Provides a text field where the user can input a string, blocking until diff --git a/nyxrc.sample b/nyxrc.sample index dfb9873..160ce68 100644 --- a/nyxrc.sample +++ b/nyxrc.sample @@ -59,8 +59,6 @@ features.confirmQuit true # showDuplicateEntries # shows all log entries if true, otherwise collapses similar entries with an # indicator for how much is being hidden -# maxLinesPerEntry -# max number of lines to display for a single log entry # prepopulate # attempts to read past events from the log file if true # prepopulateReadLimit @@ -73,14 +71,13 @@ features.confirmQuit true # preconfigured regular expression pattern, up to five will be loaded features.log.showDuplicateEntries false -features.log.maxLineWrap 6 features.log.prepopulate true features.log.prepopulateReadLimit 5000 features.log.maxRefreshRate 300 #features.log.regex My First Regex Pattern #features.log.regex ^My Second Regex Pattern$ -features.torrc.maxLineWrap 8 +features.maxLineWrap 8 # Paremters for the config panel # ---------------------------
participants (1)
-
atagar@torproject.org