Compare commits

..

8 Commits

Author SHA1 Message Date
Keith Edmunds
2fbf829eed Show track info when importing track
Fixes #79
2021-09-23 17:50:39 +01:00
Keith Edmunds
32fb44439d Change force play next keyboard shortcut
Now control-alt-return to prevent muscle memory typing control-return

Fixes #76
2021-09-23 08:08:36 +01:00
Keith Edmunds
8b641cd728 Fix last track going blank
Fixes: #68
2021-09-11 16:53:00 +01:00
Keith Edmunds
d5d4361ec5 Further fixes to moving tracks between playlists
Fixes: #38
2021-09-10 11:48:30 +01:00
Keith Edmunds
c69aefef92 Save playlist after moving tracks to another list
Fixes: #38
2021-09-10 09:25:06 +01:00
Keith Edmunds
baf0c180bd Add .desktop file 2021-09-03 14:16:44 +01:00
Keith Edmunds
b46830f010 Tab text colours implemented
Fixes #61
2021-08-24 16:41:50 +01:00
Keith Edmunds
0a4730e5a7 Start implementing coloured text on tabs 2021-08-24 15:13:03 +01:00
8 changed files with 107 additions and 22 deletions

View File

@ -6,12 +6,15 @@ class Config(object):
AUDIO_SEGMENT_CHUNK_SIZE = 10
COLOUR_CURRENT_HEADER = "#d4edda"
COLOUR_CURRENT_PLAYLIST = "#28a745"
COLOUR_CURRENT_TAB = "#248f24"
COLOUR_ODD_PLAYLIST = "#f2f2f2"
COLOUR_ENDING_TIMER = "#dc3545"
COLOUR_EVEN_PLAYLIST = "#d9d9d9"
COLOUR_LONG_START = "#dc3545"
COLOUR_NORMAL_TAB = "#000000"
COLOUR_NEXT_HEADER = "#fff3cd"
COLOUR_NEXT_PLAYLIST = "#ffc107"
COLOUR_NEXT_TAB = "#b38600"
COLOUR_NOTES_PLAYLIST = "#b8daff"
COLOUR_PREVIOUS_HEADER = "#f8d7da"
COLOUR_UNREADABLE = "#dc3545"

View File

@ -338,6 +338,7 @@ class PlaylistTracks(Base):
f"PlaylistTracks.playlist_id == {from_playlist_id}, "
f"PlaylistTracks.row == {row}"
)
return
record.playlist_id = to_playlist_id
record.row = new_row
session.commit()

View File

@ -11,7 +11,7 @@ from datetime import datetime, timedelta
from log import DEBUG, EXCEPTION
from PyQt5.QtCore import Qt, QTimer, QUrl
from PyQt5.QtGui import QFontMetrics, QPainter
from PyQt5.QtGui import QColor, QFontMetrics, QPainter
from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView
from PyQt5.QtWidgets import (
QApplication,
@ -265,7 +265,8 @@ class Window(QMainWindow, Ui_MainWindow):
self.playing = False
# Clean up metadata
self.previous_track = self.current_track
if self.current_track:
self.previous_track = self.current_track
if self.current_track_playlist_tab:
self.current_track_playlist_tab.play_stopped()
self.current_track_playlist_tab.clear_current()
@ -480,6 +481,8 @@ class Window(QMainWindow, Ui_MainWindow):
# Play next track
self.current_track = self.next_track
self.current_track_playlist_tab = self.next_track_playlist_tab
self.set_tab_colour(self.current_track_playlist_tab,
QColor(Config.COLOUR_CURRENT_TAB))
self.next_track = None
self.next_track_playlist_tab = None
DEBUG(
@ -501,6 +504,12 @@ class Window(QMainWindow, Ui_MainWindow):
else:
self.next_track = self.next_track_playlist_tab = None
if self.next_track_playlist_tab and (
self.current_track_playlist_tab !=
self.next_track_playlist_tab):
self.set_tab_colour(self.next_track_playlist_tab,
QColor(Config.COLOUR_NEXT_TAB))
# Tell database to record it as played
self.current_track.update_lastplayed()
Playdates.add_playdate(session, self.current_track)
@ -554,12 +563,32 @@ class Window(QMainWindow, Ui_MainWindow):
if not next_track_id:
next_track_id = (
self.visible_playlist_tab().set_selected_as_next())
if next_track_id:
if self.next_track_playlist_tab != self.visible_playlist_tab():
if self.next_track_playlist_tab:
self.next_track_playlist_tab.clear_next()
self.next_track_playlist_tab = self.visible_playlist_tab()
self.next_track = Tracks.get_track(session, next_track_id)
if not next_track_id:
return
# The next track has been selected on the currently-visible
# playlist. However, there may already be a 'next track'
# selected on another playlist that the user is overriding,
# in which case we need to reset that playlist.
if self.next_track_playlist_tab != self.visible_playlist_tab():
# We need to reset the ex-next-track playlist
if self.next_track_playlist_tab:
self.next_track_playlist_tab.clear_next()
# Reset tab colour if it NOT the current playing tab
if (self.next_track_playlist_tab !=
self.current_track_playlist_tab):
self.set_tab_colour(self.next_track_playlist_tab,
QColor(Config.COLOUR_NORMAL_TAB))
self.next_track_playlist_tab = self.visible_playlist_tab()
# self.next_track_playlist_tab is now set to correct
# playlist
if (self.next_track_playlist_tab !=
self.current_track_playlist_tab):
self.set_tab_colour(self.next_track_playlist_tab,
QColor(Config.COLOUR_NEXT_TAB))
self.next_track = Tracks.get_track(session, next_track_id)
self.update_headers()
def select_unplayed(self):
@ -567,6 +596,14 @@ class Window(QMainWindow, Ui_MainWindow):
self.visible_playlist_tab().select_unplayed_tracks()
def set_tab_colour(self, widget, colour):
"""
Find the tab containing the widget and set the text colour
"""
idx = self.tabPlaylist.indexOf(widget)
self.tabPlaylist.tabBar().setTabTextColor(idx, colour)
def song_info_search(self):
"""
Open browser tabs for Wikipedia, searching for
@ -601,6 +638,13 @@ class Window(QMainWindow, Ui_MainWindow):
DEBUG(f"musicmuster.stop_playing({fade=})", True)
if self.current_track_playlist_tab == self.next_track_playlist_tab:
self.set_tab_colour(self.current_track_playlist_tab,
QColor(Config.COLOUR_NEXT_TAB))
else:
self.set_tab_colour(self.current_track_playlist_tab,
QColor(Config.COLOUR_NORMAL_TAB))
if not self.music.playing():
DEBUG("musicmuster.stop_playing(): not playing", True)
self.end_of_track_actions()
@ -632,7 +676,7 @@ class Window(QMainWindow, Ui_MainWindow):
if not self.playing():
return
self.music.set_position(self.get_current_silence_at() - 1000)
self.music.set_position(self.current_track.silence_at - 1000)
def test_skip_to_fade(self):
"Skip current track to 1 second before fade"
@ -640,7 +684,7 @@ class Window(QMainWindow, Ui_MainWindow):
if not self.music.playing():
return
self.music.set_position(self.get_current_fade_at() - 1000)
self.music.set_position(self.current_track.fade_at - 1000)
def tick(self):
"""

View File

@ -382,6 +382,9 @@ class PlaylistTab(QTableWidget):
for row in sorted(rows, reverse=True):
self.removeRow(row)
with Session() as session:
self._save_playlist(session)
self._repaint()
def play_started(self):
@ -420,6 +423,9 @@ class PlaylistTab(QTableWidget):
# on its specified row, only that it will be above
# larger-numbered row items, and below lower-numbered ones.
# That means we need to re-save ourself once loaded to ensure
# database is correct.
# First, save our id for the future
self.id = playlist_db.id
self.name = playlist_db.name
@ -446,6 +452,7 @@ class PlaylistTab(QTableWidget):
scroll_to = self.item(0, self.COL_INDEX)
self.scrollToItem(scroll_to, QAbstractItemView.PositionAtTop)
self._save_playlist(session)
self._repaint()
def repaint(self):
@ -965,13 +972,17 @@ class PlaylistTab(QTableWidget):
return None
track_id = self._get_row_id(row)
if track_id:
if self._track_path_is_readable(track_id):
self._meta_set_next(row)
self.master_process.set_next_track(track_id)
else:
self._meta_set_unreadable(row)
track_id = None
if not track_id:
return None
if self._track_path_is_readable(track_id):
self._meta_set_next(row)
self.master_process.set_next_track(track_id)
else:
self._meta_set_unreadable(row)
track_id = None
self._repaint()
return track_id
def _repaint(self, clear_selection=True):
@ -1195,9 +1206,6 @@ class PlaylistTab(QTableWidget):
If multiple rows are selected, display sum of durations in status bar.
"""
# Clear label
self.master_process.lblSumPlaytime.setText("")
rows = set([item.row() for item in self.selectedItems()])
notes = self._meta_get_notes()
ms = 0
@ -1210,6 +1218,8 @@ class PlaylistTab(QTableWidget):
if ms > 0:
self.master_process.lblSumPlaytime.setText(
f"Selected duration: {helpers.ms_to_mmss(ms)}")
else:
self.master_process.lblSumPlaytime.setText("")
def _set_column_widths(self):
# Column widths from settings

View File

@ -72,6 +72,9 @@ def create_track_from_file(session, path, verbose=False):
t = get_music_info(path)
track.title = t['title']
track.artist = t['artist']
if verbose:
INFO(f" Title: \"{track.title}\"")
INFO(f" Artist: \"{track.artist}\"")
track.duration = int(round(
t['duration'], Config.MILLISECOND_SIGFIGS) * 1000)

View File

@ -836,7 +836,7 @@ border: 1px solid rgb(85, 87, 83);</string>
<string>Skip to &amp;next</string>
</property>
<property name="shortcut">
<string>Ctrl+Return</string>
<string>Ctrl+Alt+Return</string>
</property>
</action>
<action name="actionSearch_database">

View File

@ -514,7 +514,7 @@ class Ui_MainWindow(object):
self.actionPlay_next.setText(_translate("MainWindow", "&Play next"))
self.actionPlay_next.setShortcut(_translate("MainWindow", "Return"))
self.actionSkip_next.setText(_translate("MainWindow", "Skip to &next"))
self.actionSkip_next.setShortcut(_translate("MainWindow", "Ctrl+Return"))
self.actionSkip_next.setShortcut(_translate("MainWindow", "Ctrl+Alt+Return"))
self.actionSearch_database.setText(_translate("MainWindow", "Search &database"))
self.actionSearch_database.setShortcut(_translate("MainWindow", "Ctrl+D"))
self.actionAdd_file.setText(_translate("MainWindow", "Add &file"))

24
musicmuster.desktop Normal file
View File

@ -0,0 +1,24 @@
[Desktop Entry]
Type=Application
# The version of the desktop entry specification to which this file complies
Version=1.0
# The name of the application
Name=MusicMuster
# A comment which can/will be used as a tooltip
Comment=Music play for internet radio
# The path to the folder in which the executable is run
Path=/usr/local/bin
# The executable of the application, possibly with arguments.
Exec=musicmuster
# Describes whether this application needs to be run in a terminal or not
Terminal=false
# Describes the categories in which this entry should be shown
Categories=AudioVideo;Audio;