Compare commits
3 Commits
c195e68216
...
70d7f5fa70
Author | SHA1 | Date |
---|---|---|
Anna Schumaker | 70d7f5fa70 | |
Anna Schumaker | 2504f4b91d | |
Anna Schumaker | 7358183fef |
|
@ -1,6 +1,7 @@
|
|||
# Copyright 2022 (c) Anna Schumaker.
|
||||
"""A card for displaying the list of playlists."""
|
||||
from gi.repository import GObject
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk
|
||||
from . import artist
|
||||
from . import decade
|
||||
|
@ -66,27 +67,37 @@ class Card(Gtk.Box):
|
|||
if self.get_sensitive() is False:
|
||||
if False not in {tbl.loaded for tbl in sql.playlist_tables()}:
|
||||
self.set_sensitive(True)
|
||||
self.select_playlist(sql.active_playlist)
|
||||
self.select_playlist(sql.active_playlist, 150)
|
||||
if len(sql.libraries) == 0:
|
||||
self._libraries.extra_widget.emit("clicked")
|
||||
|
||||
def select_playlist(self, playlist: db.playlist.Playlist) -> None:
|
||||
"""Set the current active playlist."""
|
||||
def __select_playlist(self, playlist: db.playlist.Playlist) -> bool:
|
||||
if playlist is not None:
|
||||
match playlist.table:
|
||||
case self.sql.playlists:
|
||||
section = self._playlists
|
||||
case self.sql.artists | self.sql.albums | self.sql.media:
|
||||
section = self._artists
|
||||
case self.sql.genres:
|
||||
section = self._genres
|
||||
case self.sql.decades | self.sql.years:
|
||||
section = self._decades
|
||||
case self.sql.libraries:
|
||||
section = self._libraries
|
||||
|
||||
section.active = True
|
||||
section = self.table_section(playlist.table)
|
||||
if not section.active:
|
||||
section.active = True
|
||||
return GLib.SOURCE_CONTINUE
|
||||
section.select_playlist(playlist)
|
||||
return GLib.SOURCE_REMOVE
|
||||
|
||||
def select_playlist(self, playlist: db.playlist.Playlist,
|
||||
timeout: int = 0) -> None:
|
||||
"""Set the current active playlist."""
|
||||
GLib.timeout_add(timeout, self.__select_playlist, playlist)
|
||||
|
||||
def table_section(self, table: db.playlist.Table) -> section.Section:
|
||||
"""Get the Section associated with a specific Playlist Table."""
|
||||
match table:
|
||||
case self.sql.playlists:
|
||||
return self._playlists
|
||||
case self.sql.artists | self.sql.albums | self.sql.media:
|
||||
return self._artists
|
||||
case self.sql.genres:
|
||||
return self._genres
|
||||
case self.sql.decades | self.sql.years:
|
||||
return self._decades
|
||||
case self.sql.libraries:
|
||||
return self._libraries
|
||||
|
||||
@property
|
||||
def accelerators(self) -> list[ActionEntry]:
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
"""A sidebar Header attached to a hidden ListView for selecting playlists."""
|
||||
import typing
|
||||
from gi.repository import GObject
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk
|
||||
from .. import db
|
||||
from .. import factory
|
||||
|
@ -86,9 +85,7 @@ class Section(header.Header):
|
|||
def select_playlist(self, playlist: db.playlist.Playlist) -> None:
|
||||
"""Select the requested playlist."""
|
||||
if (index := self.playlist_index(playlist)) is not None:
|
||||
self._selection.select_item(index, True)
|
||||
self._listview.activate_action("list.scroll-to-item",
|
||||
GLib.Variant.new_uint32(index))
|
||||
self._listview.scroll_to(index, Gtk.ListScrollFlags.SELECT)
|
||||
|
||||
@GObject.Signal(arg_types=(db.playlist.Playlist,))
|
||||
def playlist_activated(self, playlist: db.playlist.Playlist):
|
||||
|
|
|
@ -81,13 +81,9 @@ class TrackView(Gtk.ScrolledWindow):
|
|||
|
||||
def scroll_to_track(self, track: db.tracks.Track) -> None:
|
||||
"""Scroll to the requested Track."""
|
||||
# This is a workaround until the ColumnView has better scrolling
|
||||
# support, which seems to be targeted for Gtk 4.10.
|
||||
adjustment = self._scrollwin.get_vadjustment()
|
||||
for (i, t) in enumerate(self._selection):
|
||||
if t == track:
|
||||
pos = max(i - 3, 0) * adjustment.get_upper()
|
||||
adjustment.set_value(pos / self._selection.get_n_items())
|
||||
for i in range(self._selection.props.n_items):
|
||||
if self._selection[i] == track:
|
||||
self._columnview.scroll_to(i, None, Gtk.ListScrollFlags.NONE)
|
||||
|
||||
@GObject.Property(type=Gio.ListModel)
|
||||
def columns(self) -> Gio.ListModel:
|
||||
|
|
|
@ -4,7 +4,6 @@ import emmental.db
|
|||
import emmental.sidebar.section
|
||||
import tests.util
|
||||
import unittest.mock
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
|
@ -105,18 +104,12 @@ class TestSection(tests.util.TestCase):
|
|||
def test_select_playlist(self):
|
||||
"""Test selecting a specific playlist."""
|
||||
self.section.do_get_subtitle = unittest.mock.Mock(return_value="")
|
||||
|
||||
playlist_selected = unittest.mock.Mock()
|
||||
self.section.connect("playlist-selected", playlist_selected)
|
||||
playlist = self.table.create("Test Playlist")
|
||||
playlist_selected.assert_not_called()
|
||||
|
||||
with unittest.mock.patch.object(self.section._listview,
|
||||
"activate_action") as mock_action:
|
||||
"scroll_to") as mock_scroll_to:
|
||||
self.section.select_playlist(playlist)
|
||||
playlist_selected.assert_called_with(self.section, playlist)
|
||||
mock_action.assert_called_with("list.scroll-to-item",
|
||||
GLib.Variant.new_uint32(0))
|
||||
mock_scroll_to.assert_called_with(0, Gtk.ListScrollFlags.SELECT)
|
||||
|
||||
def test_playlist_selected(self):
|
||||
"""Test selecting a playlist in the list."""
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import emmental.sidebar
|
||||
import tests.util
|
||||
import unittest.mock
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
|
@ -73,10 +74,13 @@ class TestSidebar(tests.util.TestCase):
|
|||
self.assertFalse(self.sidebar.get_sensitive())
|
||||
self.sidebar.select_playlist.assert_not_called()
|
||||
self.sidebar._libraries.extra_widget.emit.assert_not_called()
|
||||
self.sql.emit("table-loaded", table)
|
||||
|
||||
self.assertTrue(self.sidebar.get_sensitive())
|
||||
self.sidebar.select_playlist.assert_called()
|
||||
table.load(now=True)
|
||||
self.assertEqual(self.sidebar.get_sensitive(),
|
||||
table == tables[-1])
|
||||
|
||||
playlist = self.sql.playlists.collection
|
||||
self.sidebar.select_playlist.assert_called_with(playlist, 150)
|
||||
self.sidebar._libraries.extra_widget.emit.assert_called_with("clicked")
|
||||
|
||||
self.sidebar.select_playlist.reset_mock()
|
||||
|
@ -147,45 +151,48 @@ class TestSidebar(tests.util.TestCase):
|
|||
|
||||
def test_select_playlist(self):
|
||||
"""Test setting the active playlist."""
|
||||
self.assertEqual(self.sidebar._Card__select_playlist(None),
|
||||
GLib.SOURCE_REMOVE)
|
||||
|
||||
playlist = self.sql.playlists.create("Test Playlist")
|
||||
self.sidebar.select_playlist(playlist)
|
||||
self.assertTrue(self.sidebar._playlists.active)
|
||||
self.assertEqual(self.sidebar.selected_playlist, playlist)
|
||||
with unittest.mock.patch.object(self.sidebar._playlists,
|
||||
"select_playlist") as mock_select:
|
||||
self.assertEqual(self.sidebar._Card__select_playlist(playlist),
|
||||
GLib.SOURCE_CONTINUE)
|
||||
self.assertTrue(self.sidebar._playlists.active)
|
||||
mock_select.assert_not_called()
|
||||
|
||||
artist = self.sql.artists.create("Test Artist")
|
||||
album = self.sql.albums.create("Test Album", "Test Artist", "2023")
|
||||
medium = self.sql.media.create(album, "Test Medium", number=1)
|
||||
self.assertEqual(self.sidebar._Card__select_playlist(playlist),
|
||||
GLib.SOURCE_REMOVE)
|
||||
mock_select.assert_called_with(playlist)
|
||||
|
||||
self.sidebar._artists.select_playlist = unittest.mock.Mock()
|
||||
for plist in [artist, album, medium]:
|
||||
self.sidebar._artists.select_playlist.reset_mock()
|
||||
self.sidebar._artists.active = False
|
||||
with unittest.mock.patch.object(GLib, "timeout_add") as mock_to:
|
||||
self.sidebar.select_playlist(playlist)
|
||||
mock_to.assert_called_with(0, self.sidebar._Card__select_playlist,
|
||||
playlist)
|
||||
self.sidebar.select_playlist(playlist, 42)
|
||||
mock_to.assert_called_with(42, self.sidebar._Card__select_playlist,
|
||||
playlist)
|
||||
|
||||
self.sidebar.select_playlist(plist)
|
||||
self.assertTrue(self.sidebar._artists.active)
|
||||
self.sidebar._artists.select_playlist.assert_called_with(plist)
|
||||
|
||||
genre = self.sql.genres.create("Test Genre")
|
||||
self.sidebar.select_playlist(genre)
|
||||
self.assertTrue(self.sidebar._genres.active)
|
||||
self.assertEqual(self.sidebar.selected_playlist, genre)
|
||||
|
||||
decade = self.sql.decades.create(1990)
|
||||
year = self.sql.years.create(1990)
|
||||
|
||||
self.sidebar._decades.select_playlist = unittest.mock.Mock()
|
||||
for plist in [decade, year]:
|
||||
self.sidebar._decades.select_playlist.reset_mock()
|
||||
self.sidebar._decades.active = False
|
||||
|
||||
self.sidebar.select_playlist(plist)
|
||||
self.assertTrue(self.sidebar._decades.active)
|
||||
self.sidebar._decades.select_playlist.assert_called_with(plist)
|
||||
|
||||
library = self.sql.libraries.create("/a/b/c")
|
||||
self.sidebar.select_playlist(library)
|
||||
self.assertTrue(self.sidebar._libraries.active)
|
||||
self.assertEqual(self.sidebar.selected_playlist, library)
|
||||
def test_table_section(self):
|
||||
"""Test converting a Playlist database table into a Section."""
|
||||
self.assertEqual(self.sidebar.table_section(self.sql.playlists),
|
||||
self.sidebar._playlists)
|
||||
self.assertEqual(self.sidebar.table_section(self.sql.artists),
|
||||
self.sidebar._artists)
|
||||
self.assertEqual(self.sidebar.table_section(self.sql.albums),
|
||||
self.sidebar._artists)
|
||||
self.assertEqual(self.sidebar.table_section(self.sql.media),
|
||||
self.sidebar._artists)
|
||||
self.assertEqual(self.sidebar.table_section(self.sql.genres),
|
||||
self.sidebar._genres)
|
||||
self.assertEqual(self.sidebar.table_section(self.sql.decades),
|
||||
self.sidebar._decades)
|
||||
self.assertEqual(self.sidebar.table_section(self.sql.years),
|
||||
self.sidebar._decades)
|
||||
self.assertEqual(self.sidebar.table_section(self.sql.libraries),
|
||||
self.sidebar._libraries)
|
||||
self.assertIsNone(self.sidebar.table_section(None))
|
||||
|
||||
def test_accelerators(self):
|
||||
"""Check that the accelerators list is set up properly."""
|
||||
|
|
Loading…
Reference in New Issue