commit 34f59ebea3db165c1d77718f7fe8abbc80a800d2
parent 5511fe857367a89017c9e4113ea414f665c77626
Author: Eric Davis <edavis@insanum.com>
Date: Fri, 27 Jun 2014 12:21:34 -0700
implemented search functionality in the note list view
Diffstat:
M | config.py | | | 8 | +++++++- |
M | sncli.py | | | 306 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
2 files changed, 195 insertions(+), 119 deletions(-)
diff --git a/config.py b/config.py
@@ -36,11 +36,14 @@ def __init__(self):
'kb_tabstop4' : '4',
'kb_tabstop8' : '8',
'kb_search' : '/',
+ 'kb_clear_search' : 'a',
'clr_default_fg' : 'default',
'clr_default_bg' : 'default',
'clr_status_bar_fg' : 'dark gray',
'clr_status_bar_bg' : 'light gray',
+ 'clr_search_bar_fg' : 'white',
+ 'clr_search_bar_bg' : 'light red',
'clr_note_focus_fg' : 'white',
'clr_note_focus_bg' : 'light red',
'clr_note_title_day_fg' : 'light red',
@@ -116,7 +119,8 @@ def __init__(self):
'tabstop2' : [ cp.get(cfg_sec, 'kb_tabstop2'), 'View with tabstop=2' ],
'tabstop4' : [ cp.get(cfg_sec, 'kb_tabstop4'), 'View with tabstop=4' ],
'tabstop8' : [ cp.get(cfg_sec, 'kb_tabstop8'), 'View with tabstop=8' ],
- 'search' : [ cp.get(cfg_sec, 'kb_search'), 'Search notes' ]
+ 'search' : [ cp.get(cfg_sec, 'kb_search'), 'Search notes' ],
+ 'clear_search' : [ cp.get(cfg_sec, 'kb_clear_search'), 'Show all notes' ]
}
self.colors = \
@@ -125,6 +129,8 @@ def __init__(self):
'default_bg' : [ cp.get(cfg_sec, 'clr_default_bg'), 'Default bg' ],
'status_bar_fg' : [ cp.get(cfg_sec, 'clr_status_bar_fg'), 'Status bar fg' ],
'status_bar_bg' : [ cp.get(cfg_sec, 'clr_status_bar_bg'), 'Status bar bg' ],
+ 'search_bar_fg' : [ cp.get(cfg_sec, 'clr_search_bar_fg'), 'Search bar fg' ],
+ 'search_bar_bg' : [ cp.get(cfg_sec, 'clr_search_bar_bg'), 'Search bar bg' ],
'note_focus_fg' : [ cp.get(cfg_sec, 'clr_note_focus_fg'), 'Note title focus fg' ],
'note_focus_bg' : [ cp.get(cfg_sec, 'clr_note_focus_bg'), 'Note title focus bg' ],
'note_title_day_fg' : [ cp.get(cfg_sec, 'clr_note_title_day_fg'), 'Day old note title fg' ],
diff --git a/sncli.py b/sncli.py
@@ -10,7 +10,7 @@
class sncli:
- def __init__(self):
+ def __init__(self, do_sync):
self.config = Config()
if not os.path.exists(self.config.get_config('db_path')):
@@ -34,16 +34,16 @@ def __init__(self):
self.last_view = []
- # XXX
- #self.all_notes, match_regex, self.all_notes_cnt = self.ndb.filter_notes()
- #return
-
self.ndb.add_observer('synced:note', self.observer_notes_db_synced_note)
self.ndb.add_observer('change:note-status', self.observer_notes_db_change_note_status)
self.ndb.add_observer('progress:sync_full', self.observer_notes_db_sync_full)
- self.sync_full()
- self.all_notes, match_regex, self.all_notes_cnt = self.ndb.filter_notes()
+ if do_sync:
+ self.sync_full()
+
+ self.search_string = None
+ self.all_notes, match_regex, self.all_notes_cnt = \
+ self.ndb.filter_notes(self.search_string)
def sync_full(self):
try:
@@ -209,6 +209,12 @@ def list_get_note_titles():
'note_tags' : 'note_focus' }))
return lines
+ def filter_notes(search_string=None):
+ if self.search_string != search_string:
+ self.search_string = search_string
+ self.all_notes, match_regex, self.all_notes_cnt = \
+ self.ndb.filter_notes(self.search_string)
+
def list_get_note_content(index, tabstop):
lines = []
for l in self.all_notes[index].note['content'].split('\n'):
@@ -238,6 +244,8 @@ def handle_common_scroll_keybind(obj, size, key):
lb = obj.listbox
if key == self.config.get_keybind('down'):
+ if len(lb.body.positions()) <= 0:
+ return
last = len(lb.body.positions())
if lb.focus_position == (last - 1):
return
@@ -245,12 +253,16 @@ def handle_common_scroll_keybind(obj, size, key):
lb.render(size)
elif key == self.config.get_keybind('up'):
+ if len(lb.body.positions()) <= 0:
+ return
if lb.focus_position == 0:
return
lb.focus_position -= 1
lb.render(size)
elif key == self.config.get_keybind('page_down'):
+ if len(lb.body.positions()) <= 0:
+ return
last = len(lb.body.positions())
next_focus = lb.focus_position + size[1]
if next_focus >= last:
@@ -260,6 +272,8 @@ def handle_common_scroll_keybind(obj, size, key):
coming_from='above')
elif key == self.config.get_keybind('page_up'):
+ if len(lb.body.positions()) <= 0:
+ return
if 'bottom' in lb.ends_visible(size):
last = len(lb.body.positions())
next_focus = last - size[1] - size[1]
@@ -272,6 +286,8 @@ def handle_common_scroll_keybind(obj, size, key):
coming_from='below')
elif key == self.config.get_keybind('half_page_down'):
+ if len(lb.body.positions()) <= 0:
+ return
last = len(lb.body.positions())
next_focus = lb.focus_position + (size[1] / 2)
if next_focus >= last:
@@ -281,6 +297,8 @@ def handle_common_scroll_keybind(obj, size, key):
coming_from='above')
elif key == self.config.get_keybind('half_page_up'):
+ if len(lb.body.positions()) <= 0:
+ return
if 'bottom' in lb.ends_visible(size):
last = len(lb.body.positions())
next_focus = last - size[1] - (size[1] / 2)
@@ -293,11 +311,15 @@ def handle_common_scroll_keybind(obj, size, key):
coming_from='below')
elif key == self.config.get_keybind('bottom'):
+ if len(lb.body.positions()) <= 0:
+ return
lb.change_focus(size, (len(lb.body.positions()) - 1),
offset_inset=0,
coming_from='above')
elif key == self.config.get_keybind('top'):
+ if len(lb.body.positions()) <= 0:
+ return
lb.change_focus(size, 0,
offset_inset=0,
coming_from='below')
@@ -308,38 +330,71 @@ def handle_common_scroll_keybind(obj, size, key):
else:
obj.status_bar = obj.config.get_config('status_bar')
+ class SearchNotes(urwid.Edit):
+ def __init__(self, key, note_titles):
+ self.note_titles = note_titles
+ super(SearchNotes, self).__init__(key)
+
+ def keypress(self, size, key):
+ if key == 'esc':
+ self.note_titles.remove_search_bar()
+ elif key == 'enter':
+ self.note_titles.update_note_titles(self.get_edit_text())
+ else:
+ return super(SearchNotes, self).keypress(size, key)
+ return None
+
class NoteTitles(urwid.Frame):
def __init__(self):
self.config = get_config()
self.status_bar = self.config.get_config('status_bar')
- self.listbox = urwid.ListBox(urwid.SimpleFocusListWalker(list_get_note_titles()))
- self.listbox.keypress = self.note_title_listbox_keypress
- super(NoteTitles, self).__init__(body=self.listbox,
+ super(NoteTitles, self).__init__(body=None,
header=None,
footer=None,
focus_part='body')
+ self.update_note_titles(None)
+
+ def remove_status_bar(self):
+ self.contents['header'] = ( None, None )
+
+ def remove_search_bar(self):
+ self.contents['footer'] = ( None, None )
+
+ def update_note_titles(self, search_string):
+ filter_notes(search_string)
+ self.listbox = urwid.ListBox(urwid.SimpleFocusListWalker(list_get_note_titles()))
+ self.listbox.keypress = self.note_title_listbox_keypress
+ self.contents['body'] = ( self.listbox, None );
+ self.contents['footer'] = ( None, None );
self.update_status()
def update_status(self):
- if self.status_bar == 'yes':
- status_title = \
- urwid.AttrMap(urwid.Text(
- u'Simplenote',
- wrap='clip'),
- 'status_bar')
- status_index = \
- ('pack', urwid.AttrMap(urwid.Text(
- u' ' +
- str(self.listbox.focus_position + 1) +
- u'/' +
- str(len(self.listbox.body.positions()))),
- 'status_bar'))
- self.status = \
- urwid.AttrMap(urwid.Columns([ status_title, status_index ]),
- 'status_bar')
- self.contents['header'] = ( self.status, None )
- else:
- self.contents['header'] = ( None, None )
+ if self.status_bar != 'yes':
+ self.remove_status_bar()
+ return
+
+ cur = -1
+ total = 0
+ if len(self.listbox.body.positions()) > 0:
+ cur = self.listbox.focus_position
+ total = len(self.listbox.body.positions())
+
+ status_title = \
+ urwid.AttrMap(urwid.Text(
+ u'Simplenote',
+ wrap='clip'),
+ 'status_bar')
+ status_index = \
+ ('pack', urwid.AttrMap(urwid.Text(
+ u' ' +
+ str(cur + 1) +
+ u'/' +
+ str(total)),
+ 'status_bar'))
+ self.status = \
+ urwid.AttrMap(urwid.Columns([ status_title, status_index ]),
+ 'status_bar')
+ self.contents['header'] = ( self.status, None )
def note_title_listbox_keypress(self, size, key):
if key == self.config.get_keybind('quit'):
@@ -354,33 +409,23 @@ def note_title_listbox_keypress(self, size, key):
sncli_loop.widget = ViewLog()
elif key == self.config.get_keybind('view_note'):
- push_last_view(self)
- sncli_loop.widget = NoteContent(self.listbox.focus_position,
- int(get_config().get_config('tabstop')))
+ if len(self.listbox.body.positions()) > 0:
+ push_last_view(self)
+ sncli_loop.widget = NoteContent(self.listbox.focus_position,
+ int(get_config().get_config('tabstop')))
elif key == self.config.get_keybind('search'):
self.contents['footer'] = \
- ( urwid.AttrMap(SearchKey(key, self), 'status_bar'), None )
+ ( urwid.AttrMap(SearchNotes(key, self), 'search_bar'), None )
self.focus_position = 'footer'
+ elif key == self.config.get_keybind('clear_search'):
+ self.update_note_titles(None)
+
else:
handle_common_scroll_keybind(self, size, key)
self.update_status()
- class SearchKey(urwid.Edit):
- def __init__(self, key, notelist):
- self.notelist = notelist
- super(SearchKey, self).__init__(key)
-
- def keypress(self, size, key):
- if key == 'esc':
- self.notelist.contents['footer'] = ( None, None );
- elif key == 'enter':
- super(SearchKey, self).keypress(size, key)
- else:
- return super(SearchKey, self).keypress(size, key)
- return None
-
class NoteContent(urwid.Frame):
def __init__(self, nl_focus_index, tabstop):
self.config = get_config()
@@ -398,41 +443,48 @@ def __init__(self, nl_focus_index, tabstop):
self.update_status()
def update_status(self):
- if self.status_bar == 'yes':
- t = time.localtime(float(self.note['modifydate']))
- mod_time = time.strftime('%a, %d %b %Y %H:%M:%S', t)
- tags = '%s' % ','.join(self.note['tags'])
- status_title = \
- urwid.AttrMap(urwid.Text(
- u'Title: ' +
- utils.get_note_title(self.note),
- wrap='clip'),
- 'status_bar')
- status_index = \
- ('pack', urwid.AttrMap(urwid.Text(
- u' ' +
- str(self.listbox.focus_position + 1) +
- u'/' +
- str(len(self.listbox.body.positions()))),
- 'status_bar'))
- status_date = \
- urwid.AttrMap(urwid.Text(
- u'Date: ' +
- mod_time,
- wrap='clip'),
- 'status_bar')
- status_tags = \
- ('pack', urwid.AttrMap(urwid.Text(
- u'[' + tags + u']'),
- 'status_bar'))
- pile_top = urwid.Columns([ status_title, status_index ])
- pile_bottom = urwid.Columns([ status_date, status_tags ])
- self.status = \
- urwid.AttrMap(urwid.Pile([ pile_top, pile_bottom ]),
- 'status_bar')
- self.contents['header'] = ( self.status, None )
- else:
+ if self.status_bar != 'yes':
self.contents['header'] = ( None, None )
+ return
+
+ cur = -1
+ total = 0
+ if len(self.listbox.body.positions()) > 0:
+ cur = self.listbox.focus_position
+ total = len(self.listbox.body.positions())
+
+ t = time.localtime(float(self.note['modifydate']))
+ mod_time = time.strftime('%a, %d %b %Y %H:%M:%S', t)
+ tags = '%s' % ','.join(self.note['tags'])
+ status_title = \
+ urwid.AttrMap(urwid.Text(
+ u'Title: ' +
+ utils.get_note_title(self.note),
+ wrap='clip'),
+ 'status_bar')
+ status_index = \
+ ('pack', urwid.AttrMap(urwid.Text(
+ u' ' +
+ str(cur + 1) +
+ u'/' +
+ str(total)),
+ 'status_bar'))
+ status_date = \
+ urwid.AttrMap(urwid.Text(
+ u'Date: ' +
+ mod_time,
+ wrap='clip'),
+ 'status_bar')
+ status_tags = \
+ ('pack', urwid.AttrMap(urwid.Text(
+ u'[' + tags + u']'),
+ 'status_bar'))
+ pile_top = urwid.Columns([ status_title, status_index ])
+ pile_bottom = urwid.Columns([ status_date, status_tags ])
+ self.status = \
+ urwid.AttrMap(urwid.Pile([ pile_top, pile_bottom ]),
+ 'status_bar')
+ self.contents['header'] = ( self.status, None )
def note_content_listbox_keypress(self, size, key):
if key == self.config.get_keybind('quit'):
@@ -480,25 +532,32 @@ def __init__(self):
self.update_status()
def update_status(self):
- if self.status_bar == 'yes':
- status_title = \
- urwid.AttrMap(urwid.Text(
- u'Sync Log',
- wrap='clip'),
- 'status_bar')
- status_index = \
- ('pack', urwid.AttrMap(urwid.Text(
- u' ' +
- str(self.listbox.focus_position + 1) +
- u'/' +
- str(len(self.listbox.body.positions()))),
- 'status_bar'))
- self.status = \
- urwid.AttrMap(urwid.Columns([ status_title, status_index ]),
- 'status_bar')
- self.contents['header'] = ( self.status, None )
- else:
+ if self.status_bar != 'yes':
self.contents['header'] = ( None, None )
+ return
+
+ cur = -1
+ total = 0
+ if len(self.listbox.body.positions()) > 0:
+ cur = self.listbox.focus_position
+ total = len(self.listbox.body.positions())
+
+ status_title = \
+ urwid.AttrMap(urwid.Text(
+ u'Sync Log',
+ wrap='clip'),
+ 'status_bar')
+ status_index = \
+ ('pack', urwid.AttrMap(urwid.Text(
+ u' ' +
+ str(cur + 1) +
+ u'/' +
+ str(total)),
+ 'status_bar'))
+ self.status = \
+ urwid.AttrMap(urwid.Columns([ status_title, status_index ]),
+ 'status_bar')
+ self.contents['header'] = ( self.status, None )
def view_log_listbox_keypress(self, size, key):
if key == self.config.get_keybind('quit'):
@@ -536,6 +595,7 @@ def __init__(self):
# NoteTitles keybinds
keys = [ 'search',
+ 'clear_search',
'view_note' ]
lines.extend(self.create_kb_help_lines(u"Keybinds Note List", keys))
@@ -559,25 +619,32 @@ def __init__(self):
self.update_status()
def update_status(self):
- if self.status_bar == 'yes':
- status_title = \
- urwid.AttrMap(urwid.Text(
- u'Help',
- wrap='clip'),
- 'status_bar')
- status_index = \
- ('pack', urwid.AttrMap(urwid.Text(
- u' ' +
- str(self.listbox.focus_position + 1) +
- u'/' +
- str(len(self.listbox.body.positions()))),
- 'status_bar'))
- self.status = \
- urwid.AttrMap(urwid.Columns([ status_title, status_index ]),
- 'status_bar')
- self.contents['header'] = ( self.status, None )
- else:
+ if self.status_bar != 'yes':
self.contents['header'] = ( None, None )
+ return
+
+ cur = -1
+ total = 0
+ if len(self.listbox.body.positions()) > 0:
+ cur = self.listbox.focus_position
+ total = len(self.listbox.body.positions())
+
+ status_title = \
+ urwid.AttrMap(urwid.Text(
+ u'Help',
+ wrap='clip'),
+ 'status_bar')
+ status_index = \
+ ('pack', urwid.AttrMap(urwid.Text(
+ u' ' +
+ str(cur + 1) +
+ u'/' +
+ str(total)),
+ 'status_bar'))
+ self.status = \
+ urwid.AttrMap(urwid.Columns([ status_title, status_index ]),
+ 'status_bar')
+ self.contents['header'] = ( self.status, None )
def create_kb_help_lines(self, header, keys):
lines = [ urwid.AttrMap(urwid.Text(u''),
@@ -674,6 +741,9 @@ def help_listbox_keypress(self, size, key):
('status_bar',
self.config.get_color('status_bar_fg'),
self.config.get_color('status_bar_bg') ),
+ ('search_bar',
+ self.config.get_color('search_bar_fg'),
+ self.config.get_color('search_bar_bg') ),
('note_focus',
self.config.get_color('note_focus_fg'),
self.config.get_color('note_focus_bg') ),
@@ -737,7 +807,7 @@ def SIGINT_handler(signum, frame):
signal.signal(signal.SIGINT, SIGINT_handler)
def main():
- sncli().ba_bam_what()
+ sncli(True if len(sys.argv) > 1 else False).ba_bam_what()
if __name__ == '__main__':
main()