Use slugs instead of names; Backup commands; Filter on search & settings pages

This commit is contained in:
Valentijn 2018-09-24 14:55:19 +02:00
parent fc47df518b
commit 5620e79432
6 changed files with 51 additions and 74 deletions

View file

@ -36,10 +36,6 @@ hotkeys:
song_view:
start_filtering: /
end_filtering: esc
move_to_beginning: home
move_to_end: end
move_up: up
move_down: down
hide_context_menu: m
general_page:

View file

@ -9,7 +9,7 @@ from .clipboard import copy
from .hotkeys import hotkey_manager
from .notifications import notification_area
from .playbar import PlayBar
from .songlist import SongListBox, filter_out
from .songlist import SongListBox
from .pages import *
@ -174,6 +174,11 @@ class AppWidget(urwid.Frame):
"""
Switch to a different tab.
"""
try:
self.current_page.songlist.end_filtering()
except AttributeError as e:
pass
page = [page for page in self.pages if page.slug == slug][0]
self.current_page = page
self.contents['body'] = (page, None)
@ -214,9 +219,6 @@ class AppWidget(urwid.Frame):
Handle keypress.
Can switch tabs, control playback, flags, notifications and app state.
"""
if filter_out(key):
return super(AppWidget, self).keypress(size, key)
hotkey_manager.keypress("global", self, super(AppWidget, self), size, key)
return None
@ -250,6 +252,7 @@ class AppWidget(urwid.Frame):
def show_settings(self):
""" Show settings page. """
self.set_page('settings')
@staticmethod

View file

@ -5,6 +5,8 @@ Requires "gi" package and "Gtk" & "Keybinder" modules.
# pylint: disable=broad-except
from clay.core import settings_manager, logger
from string import ascii_letters, digits
def report_error(exc):
"Print an error message to the debug screen"
logger.error("{0}: {1}".format(exc.__class__.__name__, exc))
@ -17,6 +19,7 @@ class _HotkeyManager(object):
def __init__(self):
self._hotkeys = self._parse_hotkeys()
self.config = None
self.filtering = False
def _parse_hotkeys(self):
"""
@ -42,6 +45,33 @@ class _HotkeyManager(object):
return hotkeys
def keypress(self, name, caller, super_, size, key):
"""
Processes a key and sends the appropiated command back.
Returns:
the letter pressed if Clay is filtering, the command or, in case a modifier key is pressed,
the command associated with the letter after the modifier key.
"""
split_keys = key.split()
if split_keys[0] == 'meta' or split_keys[0] == 'ctrl':
self.filtering = False
return self._lookup_key(name, caller, super_, size, ''.join(split_keys[1:]))
if not self.filtering:
return self._lookup_key(name, caller, super_, size, key)
if key == 'backspace' or key == 'tab' or key in ascii_letters + digits + ' _-.,?()[]\'':
if name == 'song_view':
ret = caller.perform_filtering(key)
else:
ret = super_.keypress(size, key)
else:
ret = self._lookup_key(name, caller, super_, size, key)
return ret
def _lookup_key(self, name, caller, super_, size, key):
"""
Process the pressed key by looking it up in the configuration file

View file

@ -40,6 +40,7 @@ class SearchBox(urwid.Columns):
"""
Send a message to urwid to search the filled in search query
"""
urwid.emit_signal(self, 'search-requested', self.query.edit_text)
@ -71,7 +72,7 @@ class SearchPage(urwid.Pile, AbstractPage):
def __init__(self, app):
self.app = app
self.songlist = SongListBox(app)
self._focus_position = 0
self.search_box = SearchBox()
urwid.connect_signal(self.search_box, 'search-requested', self.perform_search)
@ -102,9 +103,11 @@ class SearchPage(urwid.Pile, AbstractPage):
self.app.redraw()
def activate(self):
pass
hotkey_manager.filtering = True
def keypress(self, size, key):
hotkey_manager.filtering = (self.focus == self.search_box)
if key == 'tab':
if self.focus == self.search_box:
self.focus_position = 2

View file

@ -197,4 +197,4 @@ class SettingsPage(urwid.Columns, AbstractPage):
self.app.log_in()
def activate(self):
pass
hotkey_manager.filtering = True

View file

@ -25,13 +25,6 @@ from .clipboard import copy
player = get_player() # pylint: disable=invalid-name
FILTERING = False
def filter_out(key):
"""
Checks whether the keypress should be sent to the filter instead
"""
return FILTERING and (key == 'backspace' or key in (ascii_letters + digits + ' _-.,?!()[]\''))
class SongListItem(urwid.Pile):
"""
Widget that represents single song item.
@ -183,9 +176,6 @@ class SongListItem(urwid.Pile):
"""
Handle keypress.
"""
if filter_out(key):
return super(SongListItem, self).keypress(size, key)
return hotkey_manager.keypress("song_item", self, super(SongListItem, self), size, key)
def mouse_event(self, size, event, button, col, row, focus):
@ -440,7 +430,7 @@ class SongListBox(urwid.Frame):
self.list_box = urwid.ListBox(self.walker)
self.filter_prefix = '> '
self.filter_query = ''
self.filter_box = urwid.Text(self.filter_prefix)
self.filter_box = urwid.Text('')
self.filter_info = urwid.Text('')
self.filter_panel = urwid.Columns([
self.filter_box,
@ -469,16 +459,14 @@ class SongListBox(urwid.Frame):
"""
Starts filtering the song view
"""
global FILTERING
if not FILTERING:
if not hotkey_manager.filtering:
self.content.contents = [
(self.list_box, ('weight', 1)),
(self.filter_panel, ('pack', None))
]
self.app.append_cancel_action(self.end_filtering)
self.filter_query = ''
FILTERING = True
hotkey_manager.filtering = True
self.tracks_walker[:] = self.walker
self.filter_box.set_text(self.filter_prefix)
@ -501,7 +489,7 @@ class SongListBox(urwid.Frame):
self.walker[:] = matches
self.walker.set_focus(0)
if self.app.current_page.name == 'Library':
if self.app.current_page.slug == 'library':
self.update_indexes()
def get_filtered_items(self):
@ -520,14 +508,12 @@ class SongListBox(urwid.Frame):
"""
Exit filtering mode.
"""
global FILTERING
if not FILTERING:
if self.filter_box.text == '':
return
self.content.contents = [
(self.list_box, ('weight', 1))
]
FILTERING = False
hotkey_manager.filtering = False
self.filter_box.set_text('')
self.filter_info.set_text('')
self.walker[:] = self.tracks_walker
@ -596,12 +582,12 @@ class SongListBox(urwid.Frame):
# There are some pages like search library where overwriting the queue
# doesn't make much sense. We can also assume that someone searching
# for a specific song also wants to append.
elif (page.append or FILTERING) and page.name != 'Queue':
elif (page.append or hotkey_manager.filtering) and page.slug != 'queue':
self.item_append_requested(songitem)
else:
player.load_queue(self.tracks, songitem.index)
if FILTERING:
if hotkey_manager.filtering and page.slug != 'search':
self.walker[:] = self.get_filtered_items()
@staticmethod
@ -736,49 +722,8 @@ class SongListBox(urwid.Frame):
songlistitem.set_index(i)
def keypress(self, size, key):
if filter_out(key):
self.perform_filtering(key)
return hotkey_manager.keypress("song_view", self, super(SongListBox, self), size, key)
def move_to_beginning(self):
"""Move to the focus to beginning of the songlist"""
self.list_box.set_focus(0, 'below')
return False
def move_to_end(self):
"""Move to the focus to end of the songlist"""
self.list_box.set_focus(-1, 'above')
return False
def move_up(self):
"""Move the focus an item up in the playlist"""
_, index = self.walker.get_focus()
if index is None:
return False
if index <= 0:
self.list_box.set_focus(len(self.walker) - 1, 'below')
else:
self.list_box.set_focus(index - 1, 'above')
return False
def move_down(self):
"""Move the focus an item down in the playlist """
_, index = self.walker.get_focus()
if index is None:
return False
if index >= len(self.walker) - 1:
self.list_box.set_focus(0, 'above')
else:
self.list_box.set_focus(index + 1, 'below')
return False
def mouse_event(self, size, event, button, col, row, focus):
"""
Handle mouse event.