def test_title(self): screen = get_screen() y = 10 screen.setmaxyx(y, 20) ta = TextArea() ta.minx = 10 lines = [chr(i) for i in range(97, 96 + y)] ta.show_text('\n'.join(lines)) self.assertEqual(screen.get_line(0), lines[0]) title = '' while len(title) < 10: title += get_random_lines(1, 20)[0].replace(' ', '') title = title[:10] ta.set_title(title) ta.draw() self.assertEqual(screen.get_line(0), title) title *= 3 ta.set_title(title) ta.draw() self.assertEqual(screen.get_line(0), '') screen.setmaxyx(y, 30) ScreenManager.resize() self.assertEqual(screen.get_line(0), title)
def test_search(self): screen = get_screen() y, x = screen.getmaxyx() lines = get_random_lines(300) lines1 = get_random_lines(3) prefix = lines[random.randint(y, 299)][:3] for i in range(3): lines.insert(random.randint(y, 299 + i), prefix + lines1[i][3:]) indices = [ind for ind, line in enumerate(lines) if prefix in line] sl = ScrollableList(lines) ScreenManager.draw_all() commands.add([ord(c) for c in prefix]) commands.add(ord('\n')) sl.handle_search() next_index = itertools.cycle(indices).next for i in range(10): index = next_index() self.assertEquals(sl.get_current_index(), index) self.assertTrue(lines[index] in map(screen.get_line, range(y))) sl.handle_keypress('n') sl.move_to_bottom() if prefix not in screen.get_line(-1): sl.handle_keypress('N') previous_index = itertools.cycle(reversed(indices)).next for i in range(10): index = previous_index() self.assertEquals(sl.get_current_index(), index) self.assertTrue(lines[index] in map(screen.get_line, range(y))) sl.handle_keypress('N')
def test_moving(self): lines = get_random_lines() sl = ScrollableList(lines) ScreenManager.draw_all() screen = get_screen() y, x = screen.getmaxyx() ind = sl.get_current_index self.assertEquals(ind(), 0) for i in range(y): self.assertEquals(screen.get_line(i), lines[i]) sl.move_up() self.assertEquals(ind(), 0) sl.move_to_bottom() self.assertEquals(ind(), len(lines) - 1) sl.move_down() self.assertEquals(ind(), len(lines) - 1) self.assertEquals(screen.get_line(0), lines[-y]) sl.move_to_top() self.assertEquals(ind(), 0) self.assertEquals(screen.get_line(-1), lines[y - 1]) for i in range(len(lines)): sl.move_down() self.assertEquals(ind(), len(lines) - 1) self.assertEquals(screen.get_line(0), lines[-y]) self.assertEquals(screen.get_line(-1), lines[-1]) self._move_down_and_up(sl)
def show_edits(date, edits, area_id): """Show all edits of an entry as a scrollable list.""" from writelightly.screen import ScreenManager from writelightly.utils import format_time, format_size from writelightly.scrollable_list import ScrollableList import curses formatted = ['%s, created' % format_time(edits[0][0], full=True)] formatted += ['%s, %s' % (format_time(ts, full=True), format_size(size)) for ts, size in edits[1:]] sl = ScrollableList(formatted, area_id=area_id) sl.draw() while 1: kn = curses.keyname(sl.window.getch()) if kn in Config.general_keys['quit']: raise WLQuit if kn in Config.general_keys['quit_mode']: break if kn == 'KEY_RESIZE': ScreenManager.resize() if sl.hidden: continue elif kn in Config.edits_keys['open']: index = sl.get_current_index() fn = save_tmp_version(date, edits, index) edit_file(fn) sl.draw() else: sl.handle_keypress(kn)
def resize(self, y=None, x=None): if not y: y = ScreenManager.get_coords(self.area_id)[0] if not x: x = ScreenManager.get_coords(self.area_id)[1] if self.search_mode: y -= 1 self.window.resize(y, x) self._calc_lines() new_ysize = self.window.getmaxyx()[0] - self.offset dif = new_ysize - self.ysize self.ysize = new_ysize bottom_lines = self.last - self.bottom down = dif if bottom_lines >= dif else bottom_lines if down < dif: top_lines = self.top up = dif - down if top_lines >= dif - down else top_lines self.top -= up self.bottom = self.top + self.ysize - 1 if self.bottom > self.last: self.bottom = self.last self.ibottom = self.lines[self.bottom][0] if self.current > self.ibottom: self.current = self.ibottom
def resize(): screen.setmaxyx(y, x) ScreenManager.resize() if not sl.hidden: self._move_down_and_up(sl) self._scroll_down_and_up(sl) if j % 2 == 0: sl.move_to_bottom()
def wrapper(func, with_screen=False): if with_screen: ScreenManager.init() error = None try: func() except WLQuit: pass except WLError as exc: error = exc finally: if with_screen: ScreenManager.quit() if error is not None: sys.stderr.write('%s\n' % error)
def test_scrolling(self): lines = get_random_lines() sl = ScrollableList(lines) ScreenManager.draw_all() screen = get_screen() y, x = screen.getmaxyx() ind = sl.get_current_index for i in range(len(lines) - y): sl.scroll_down() self.assertEquals(ind(), i + 1) self.assertEquals(screen.get_line(0), lines[i + 1]) self.assertEquals(screen.get_line(-1), lines[-1]) up = min(len(lines) - y, y) sl.scroll_screen_up() self.assertEquals(screen.get_line(-1), lines[-up-1])
def test_text(self): screen = get_screen() screen.setmaxyx(10, 20) ta = TextArea() ta.minx = 10 lines = [] # we need some lines longer than 10 while not 0 < len([l for l in lines if len(l) > 10]) < 5: lines = get_random_lines(5, 15) def check(): for index, line in enumerate(lines): self.assertEqual(screen.get_line(index), line) ta.show_text('\n'.join(lines)) check() screen.setmaxyx(10, 10) ScreenManager.resize() nl = [] for line in lines: nl += wrap(line, 10) lines = nl check() assert len(lines) < 10 screen.setmaxyx(len(lines), 10) ScreenManager.resize() check() screen.setmaxyx(len(lines) - 1, 10) ScreenManager.resize() old, lines = lines, [''] * (len(lines) - 1) check() lines = old screen.setmaxyx(len(lines), 10) ScreenManager.resize() check() screen.setmaxyx(10, 9) ScreenManager.resize() lines = [''] * len(lines) check()
def show_date_list(tag, dates, area_id=None, text_area=None): """Show the list of entries for a tag.""" labels = map(format_date, dates) sl = ScrollableList(labels, tag, area_id=area_id) sl.draw() date = dates[sl.get_current_index()] metadata = Metadata.get(date.year, date.month) if not text_area: text_area = TextArea() text_area.set_title() text_area.show_text(metadata.text(date.day)) while 1: try: kn = curses.keyname(sl.window.getch()) except KeyboardInterrupt: break if kn in Config.general_keys['quit']: raise WLQuit if kn in Config.general_keys['quit_mode']: break if kn == 'KEY_RESIZE': ScreenManager.resize() if sl.hidden: continue if kn in Config.tag_details_keys['edit']: date = dates[sl.get_current_index()] edit_date(date) sl.draw() metadata.load_day(date.day) text_area.show_text(metadata.text(date.day)) elif kn in Config.tag_details_keys['edits']: date = dates[sl.get_current_index()] edits = get_edits(date) if edits: show_edits(date, edits, text_area.area_id) ScreenManager.restore_area(text_area.area_id) text_area.show_text(metadata.text(date.day)) else: sl.handle_keypress(kn) date = dates[sl.get_current_index()] metadata = Metadata.get(date.year, date.month) text_area.show_text(metadata.text(date.day)) Metadata.write_all()
def test_resize(self): lines = get_random_lines() sl = ScrollableList(lines) ScreenManager.draw_all() screen = get_screen() y, x = maxyx = screen.getmaxyx() j = 0 def resize(): screen.setmaxyx(y, x) ScreenManager.resize() if not sl.hidden: self._move_down_and_up(sl) self._scroll_down_and_up(sl) if j % 2 == 0: sl.move_to_bottom() while y > 1: y -= random.randint(1, 20) if y < 1: y = 1 j += 1 resize() while y < maxyx[0]: y += random.randint(1, 20) if y > maxyx[0]: y = maxyx[0] j -= 1 resize() while x > 1: x -= random.randint(1, 20) if x < 1: x = 1 j += 1 resize() while x > maxyx[1]: x += random.randint(1, 20) if x > maxyx[1]: x = maxyx[1] j += 1 resize()
def test_current_month_cal(self): today = datetime.date.today() Calendar(today.year, today.month, today.day) ScreenManager.draw_all() # check the first line screen = get_screen() lines = screen.lines days = 'Mo Tu We Th Fr Sa Su' self.assertEquals(lines[0], list(days + ' ' * (screen.getmaxyx()[1] - len(days)))) # check the location of the first day first = datetime.date(today.year, today.month, 1) x = first.weekday() * 3 self.assertEquals(lines[1][x:x + 2], list(' 1')) # check the location of the last day last = lastday(today) x = datetime.date(today.year, today.month, last).weekday() * 3 weeks = int(math.ceil((last - (7 - first.weekday())) / 7.0)) + 1 self.assertEquals(lines[weeks][x:x + 2], list(str(last)))
def test_moving(self): today = datetime.date.today() day = 1 last = lastday(today) cal = Calendar(today.year, today.month, day) ScreenManager.draw_all() # moving from the first day to the last while day < last: cal.move_right() day += 1 self.assertEquals(cal.get_current_day(), day) # moving from the last day to the 7th while day > 7: cal.move_left() day -= 1 self.assertEquals(cal.get_current_day(), day) # moving up and down cal.move_down() self.assertEquals(cal.get_current_day(), 14) cal.move_up() self.assertEquals(cal.get_current_day(), 7)
def __init__(self, year, month, init_day=None, is_active=lambda date: False, *args, **kwargs): """Initialize calendar by year and month. init_day: day of the month that is initially selected is_active: function that takes a datetime.date instance and returns True if that date is "active" """ super(Calendar, self).__init__(*args, **kwargs) self.window = curses.newwin(*ScreenManager.get_coords(self.area_id)) self.window.keypad(1) self.year, self.month = year, month self.selected = () last = lastday(year, month) if not init_day: init_day = datetime.date.today().day if init_day > last: init_day = last self.init_day = init_day self.is_active = is_active first = datetime.date(self.year, self.month, 1) x, y = 0, 1 week = [None] * first.weekday() x += 3 * first.weekday() last = lastday(first) day = first.day data = [] while day <= last: date = datetime.date(self.year, self.month, day) week.append((x, y, is_active(date), day)) if len(week) == 7: data.append(week) week = [] y += 1 x = 0 else: x += 3 day += 1 if week: data.append(week + [None] * (7 - len(week))) self.data = data self.miny = len(self.data) + 1
def show_tags(area_id=None, text_area=None): """Show all tags sorted by entries number as a scrollable list.""" screen = ScreenManager.screen screen.addstr(0, 0, 'loading...') screen.refresh() tags = {} for year, month in get_all_months(conf['data_dir']): m = Metadata.get(year, month) for tag, days in m.tags.items(): for day in days: date = datetime.date(year, month, day) try: tags[tag].append(date) except KeyError: tags[tag] = [date] if not tags: raise WLError('No tags found') items = sorted(sorted(tags.items(), key=lambda i: i[0]), key=lambda i: len(i[1]), reverse=True) tl = ['%s (%d)' % (item[0], len(item[1])) for item in items] sl = ScrollableList(tl, area_id=area_id) if text_area: text_area.set_title('Last entry:') else: text_area = TextArea() text_area.set_title('Last entry:') ScreenManager.draw_all() def tag_info(index): tag, dates = items[index] d = dates[-1] text_area.show_text(Metadata.get(d.year, d.month).text(d.day)) tag_info(sl.get_current_index()) while 1: try: kn = curses.keyname(sl.window.getch()) except KeyboardInterrupt: break except ValueError: continue if kn in Config.general_keys['quit']: raise WLQuit if kn in Config.general_keys['quit_mode']: break if kn == 'KEY_RESIZE': ScreenManager.resize() if sl.hidden: continue elif kn in Config.tags_keys['details']: tag, dates = items[sl.get_current_index()] show_date_list(tag, dates, sl.area_id, text_area) ScreenManager.restore_area(sl.area_id) sl.reinit() text_area.set_title('Last entry:') tag_info(sl.get_current_index()) else: sl.handle_keypress(kn) tag_info(sl.get_current_index()) Metadata.write_all()
def tearDown(self): ScreenManager.quit()
def setUp(self): ScreenManager.init()
def edit_file(path): """Call up an external editor specified in config to edit a file.""" from writelightly.screen import ScreenManager ScreenManager.editor_called() return subprocess.call('%s %s' % (conf['editor'], path), shell=True)
def show_calendar(): """Show an interactive calendar. Show the calendar on the left side of the screen and some metadata about the selected date on the right. Any entry can be edited in external editor. """ today = datetime.date.today() year, month = today.year, today.month cal = Calendar(year, month, today.day, entry_exists) metadata = Metadata.get(year, month) text_area = TextArea() ScreenManager.draw_all() d = cal.get_current_date() text_area.show_text(metadata.text(d.day)) keys = Config.calendar_keys while 1: try: kn = curses.keyname(cal.window.getch()) except KeyboardInterrupt: break except ValueError: continue if kn in Config.general_keys['quit']: raise WLQuit if kn in Config.general_keys['quit_mode']: break if kn == 'KEY_RESIZE': ScreenManager.resize() if cal.hidden: continue if kn in keys['left']: moved = cal.move_left() if not moved: cal = cal.get_previous_calendar() cal.draw() metadata = Metadata.get(cal.year, cal.month) text_area.show_text(metadata.text(cal.get_current_day())) elif kn in keys['right']: moved = cal.move_right() if not moved: cal = cal.get_next_calendar() cal.draw() metadata = Metadata.get(cal.year, cal.month) text_area.show_text(metadata.text(cal.get_current_day())) elif kn in keys['down']: cal.move_down() text_area.show_text(metadata.text(cal.get_current_day())) elif kn in keys['up']: cal.move_up() text_area.show_text(metadata.text(cal.get_current_day())) elif kn in keys['edit']: date = cal.get_current_date() edit_date(date) metadata.load_day(date.day) cal.set_active(entry_exists(date)) text_area.show_text(metadata.text(date.day)) elif kn in keys['tags']: show_tags(cal.area_id, text_area) ScreenManager.restore_area(cal.area_id) cal.reinit() text_area.set_title() text_area.show_text(metadata.text(cal.get_current_day())) elif kn in keys['edits']: date = cal.get_current_date() edits = get_edits(date) if edits: show_edits(date, edits, text_area.area_id) ScreenManager.restore_area(text_area.area_id) text_area.show_text(metadata.text(date.day)) elif kn in keys['prev_month']: cal = cal.get_previous_calendar(cal.get_current_day()) cal.draw() metadata = Metadata.get(cal.year, cal.month) text_area.show_text(metadata.text(cal.get_current_day())) elif kn in keys['next_month']: cal = cal.get_next_calendar(cal.get_current_day()) cal.draw() metadata = Metadata.get(cal.year, cal.month) text_area.show_text(metadata.text(cal.get_current_day())) Metadata.write_all() clean_tmp()