Commit Graph

1334 Commits

Author SHA1 Message Date
Anna Schumaker 47d5f0c0c6 entry: Create an entry for Filtering
This entry provides some helper functionality around a Gtk.SearchEntry
to make filtering lists easier.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 10:41:42 -04:00
Anna Schumaker 3cf730a5cc format: Add a function for formatting search strings
This takes the input string, casefolds it, and then adds some extra glob
operators to it so we can do a case insensitive substring search by
default.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 10:41:42 -04:00
Anna Schumaker 6ede296ba6 buttons: Create a PopoverButton
This is a MenuButton that already has a popover attached and a property
for setting the popover child directly.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 10:41:42 -04:00
Anna Schumaker a73063a04c emmental: Add our Window to the application
Bind the width and height properties to the settings so they are
restored on startup and bind the fullscreen property to mpris.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 10:41:42 -04:00
Anna Schumaker 5d1c11e64e window: Add a custom Window class
This window is set up with specific areas for our header, sidebar, now
playing info, and tracklist. It also implements a post_toast() function
so toast notifications can be displayed to the user.

Implements: #44 ("Create a new 3WayPane widget")
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 10:41:42 -04:00
Anna Schumaker 767f0c1584 mpris2: Add an Mpris2 DBus Connection
And implement the MediaPlayer2 interface on top of it.

Implements: #7 ("Add MPRIS2 Support")
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 10:41:42 -04:00
Anna Schumaker b1cd1706ed db/settings: Create a Settings table
This creates a new class to dynamically create GObject Properties, save
them to the database, and make it easy to bind application properties to
specific settings properties.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 10:41:42 -04:00
Anna Schumaker 788ca374a8 db: Create a Table base class
This is a Gtk.FilterListModel containing a store.SortedList to store
individual rows in sorted order. I also implemented some convenience
functions to make it easier to add, remove, look up, and filter rows.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 10:41:41 -04:00
Anna Schumaker 651f24672b db: Create a database row Filter
This filter takes a set of primary keys for rows that should be visible
during filtering. Passing None as a value means that all rows are shown.
It also has functions for adding or removing individual rows from the
filter.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 09:26:27 -04:00
Anna Schumaker 2eef68f76f db: Create a database Row base class
This will be shared between settings, playlists, and tracks so we have a
common interface for working with database rows.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 09:26:26 -04:00
Anna Schumaker 8c8135fc23 db: Create a full-featured Connection manager
This inherits from the base Connection manager and adds in reading our
sql script to set up the database. It will also eventually hold pointers
to table objects that we can access directly.

Finally, I add a db property to the Application instance. The db is
connected during the ::startup signal handler, and disconnected during
the ::shutdown signal handler.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 09:26:25 -04:00
Anna Schumaker deb4f3d252 db: Create a base Connection manager
This is a wrapper around the sqlite3.Connection objct that adds some
nice functionality to make working with SQL easier.

I defined the following magic methods:
  * __enter__() to manually begin a transaction
  * __exit__() to commit or rollback a manual transaction
  * __call__() to execute a SQL statement with either positional or
    keyword arguments.

Additionally:
  * I define a "CASEFOLD" function that can be used in queries
    to lowercase unicode text when searching.
  * I set foreign_keys = ON so foreign keys checking is always enabled
  * I provide an executemany() function for running running the same
    statement multiple times with different arguments.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 09:23:14 -04:00
Anna Schumaker 61fc252172 store: Add a SortedList store
This ListStore implementation uses a key function to keep the items
sorted at all times.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-03-07 11:19:30 -05:00
Anna Schumaker 482a199731 store: Add a Python-based ListStore
This is implemented as an alternative to the Gio.ListStore that uses a
Python list object to hold items.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-03-07 11:19:29 -05:00
Anna Schumaker 4be26c5fee gsetup: Load a Gio Resource with our application icons
We can put all our icons into a single resource bundle that gets loaded
and only exists for our app.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-03-07 11:19:29 -05:00
Anna Schumaker 5cd5d2640d gsetup: Load our application CSS file
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-03-07 11:19:27 -05:00
Anna Schumaker 4072ea97d4 emmental3.py: Start Emmental 3.0
I'm going to put all of the main source code into a single subdirectory
under emmental/ and separate out tests into a separate tests/ directory.

Additionally, I have switched over to pytest for running tests to give
me better output (with color!)

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-03-07 11:18:46 -05:00
Anna Schumaker 08ea7342dc Emmental 2.10 AUR Commit
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2022-02-25 13:34:26 -05:00
Anna Schumaker 18743f05c4 Emmental 2.10
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2022-02-25 13:32:32 -05:00
Anna Schumaker ab6eb556ad db: Fix track_adjusts_current() when the track has been removed
In this case, the call to get_track_index() returns None which can't be
used for the comparisons we're doing. Make sure we handle the None
result explicitely.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2022-02-22 10:08:34 -05:00
Anna Schumaker 1296857189 playlist: Don't leave the Subtitle column blank
Instead, fill in something generated from the disc number but make it
dimmed.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2022-01-10 11:36:42 -05:00
Anna Schumaker 73ba296d74 playlist: Use the new match / case statement in __init__.py:key_pressed()
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 17:33:26 -05:00
Anna Schumaker f9cec5e1b3 audio: Use the new match / case statement in scale.py:format_value()
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 17:24:09 -05:00
Anna Schumaker 0c7a4a4a4c db: Use the new match / case statement in user.py:do_factory()
This is cleaner than using a bunch of elif-s to pick the right playlist
type

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 17:23:57 -05:00
Anna Schumaker 289420e504 playlist: Add a Favorite toggle button
For adding / removing the currently playing track from the Favorites
playlist

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 15:50:11 -05:00
Anna Schumaker 15059db59a playlist: Create a TrackBox containing the JumpButton
And put it before the filter entry in the ui

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 15:50:11 -05:00
Anna Schumaker c4adea15bb playlist: Split out the ControlBox as a base class
And create a PlaylistBox inheriting from it containing the buttons.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 15:50:11 -05:00
Anna Schumaker 328dce0be2 scanner: Fix scanner.update_library() function
We were scheduling the CheckTask, but not following up with a
DirectoryTask to scan for new files. I use this function during the
Gtk.Application startup to automatically update the libraries.

Implements #31 (Automatically update the database during startup)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 15:50:11 -05:00
Anna Schumaker 295202443f scanner: Add a function for clearing the TaskQueue
And call this function when closing the player

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 15:50:08 -05:00
Anna Schumaker b245b2073e scanner: Rename tests
To remove a bunch of redundant names from the test functions

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 15:49:52 -05:00
Anna Schumaker 7b89f54e8b scanner: Remove the ImportTask
It is no longer needed now that we have updated from the tagdb

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 15:49:52 -05:00
Anna Schumaker b768d74928 sidebar: Don't change displayed playlist to None
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 15:49:52 -05:00
Anna Schumaker beca08b833 Implement the Gtk.Application instance in emmental.py
We don't use this during testing, so put it here instead of in a
submodule.

Implements #26 (Move the EmmentalApplication into emmental.py)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-28 15:49:50 -05:00
Anna Schumaker db2d122211 lib: Replace version.DEBUG with the __debug__ constant
Implements #27 (Check __debug__ constant instead of a .debug file)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-26 13:18:24 -05:00
Anna Schumaker 10c5fd4cef lib: set version.TESTING based on if the unittest module is loaded
This is cleaner than needing to set an environment variable before
running unit tests.

Implements #28 (Check if unittest is loaded to determine if we are testing)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-26 13:05:08 -05:00
Anna Schumaker 2daefa932c lib: Remove unused files
These are no longer needed now that tagdb has been removed

Implements #24 (Clean up lib/)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-26 10:18:09 -05:00
Anna Schumaker 915e3c8340 Remove unused tagdb module
Implements #23 (Remove tagdb/ code)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-26 10:08:33 -05:00
Anna Schumaker 04dc67a097 Emmental 2.9 AUR Commit
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-21 15:48:06 -05:00
Anna Schumaker 5aa9f36272 Emmental 2.9
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-21 15:43:57 -05:00
Anna Schumaker be7e8e6073 audio: Reset the pipeline whenever we reach EOS
This fixes a bug where a different track would be selected when hitting
"Play" after an autopause

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-10 12:00:20 -05:00
Anna Schumaker a85ac03517 db: Occasionally optimize the database
I do this whenever we commit during scanning, and during application
shutdown.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 22:09:40 -05:00
Anna Schumaker 853594fc26 db: Remove indexes
They aren't doing anything useful to help speed up sorting, so remove
for now and reevaluate later

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 22:05:42 -05:00
Anna Schumaker 798ef20a72 playlist: Give the playlist panel an add_selected_tracks() function
So we can have all the add track functionality in one place that also
allows for keyboard presses to work.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 19:25:16 -05:00
Anna Schumaker ba06eca07f audio: Switch to the Collection playlist if the current playlist has finished
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 17:51:02 -05:00
Anna Schumaker 4cdf4c528a audio: Implement our own about-to-finish handling
The playbin's about-to-finish signal triggers in a different thread,
which Gtk is very much not happy about, and often results in both the
about-to-finish and eos handlers getting called (and therefore multiple
tracks getting picked from the queue).

Fix this by checking how much time is left during the regular position
changed timeout function and triggering about-to-finish manually

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 17:51:02 -05:00
Anna Schumaker 8f26cf9fee db: Fix random next_track() on playlists with only one track
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 17:51:02 -05:00
Anna Schumaker bb0a9face7 ui: Update keyboard shortcuts
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 17:51:02 -05:00
Anna Schumaker 2e14b511a4 sidebar: add_to_playlist() fixes
- Commit after adding tracks
- If tracks were added to the Queued Tracks playlist, then set it as the
  current playlist in the Player

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 17:51:02 -05:00
Anna Schumaker 6c81981570 playlist: Clear selection after iterating
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 17:51:02 -05:00
Anna Schumaker c7b205e404 playlist: Remove selected tracks from the Queued Tracks playlist
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2021-12-09 17:44:09 -05:00