예제 #1
0
    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)
예제 #2
0
 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')
예제 #3
0
    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)
예제 #4
0
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)
예제 #5
0
    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
예제 #6
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()
예제 #7
0
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)
예제 #8
0
    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])
예제 #9
0
    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()
예제 #10
0
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()
예제 #11
0
    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()
예제 #12
0
    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)))
예제 #13
0
    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)
예제 #14
0
    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
예제 #15
0
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()
예제 #16
0
 def tearDown(self):
     ScreenManager.quit()
예제 #17
0
 def setUp(self):
     ScreenManager.init()
예제 #18
0
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)
예제 #19
0
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()