Make more robust

This commit is contained in:
Keith Edmunds 2021-03-27 13:55:57 +00:00
parent 44a8d30e35
commit 2bd96ad1a6
9 changed files with 711 additions and 268 deletions

View File

@ -33,34 +33,70 @@ class Music:
}
def get_current_artist(self):
try:
return self.current_track['meta'].artist
except AttributeError:
return ""
def get_current_duration(self):
try:
return self.current_track['meta'].duration
except AttributeError:
return 0
def get_current_fade_at(self):
try:
return self.current_track['meta'].fade_at
except AttributeError:
return 0
def get_current_playtime(self):
try:
return self.current_track['player'].get_time()
except AttributeError:
return 0
def get_current_silence_at(self):
try:
return self.current_track['meta'].silence_at
except AttributeError:
return 0
def get_current_title(self):
try:
return self.current_track['meta'].title
except AttributeError:
return ""
def get_last_artist(self):
return self.last_track['meta'].artist
def get_current_track_id(self):
try:
return self.current_track['meta'].id
except AttributeError:
return 0
def get_last_title(self):
return self.last_track['meta'].title
def get_previous_artist(self):
try:
return self.previous_track['meta'].artist
except AttributeError:
return ""
def get_previous_title(self):
try:
return self.previous_track['meta'].title
except AttributeError:
return ""
def get_next_artist(self):
try:
return self.next_track['meta'].artist
except AttributeError:
return ""
def get_next_title(self):
try:
return self.next_track['meta'].title
except AttributeError:
return ""
def play_next(self):
if self.previous_track['player']:
@ -83,7 +119,7 @@ class Music:
else:
return False
def resume_last(self):
def resume_previous(self):
pass
def set_next_track(self, id):
@ -104,6 +140,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.timer = QTimer()
self.connectSignalsSlots()
self.music = Music()
self.disable_play_next_controls()
record = Settings.get_int("mainwindow_x")
x = record.f_int or 1
@ -147,11 +184,10 @@ class Window(QMainWindow, Ui_MainWindow):
record.update({'f_int': self.y()})
def connectSignalsSlots(self):
self.fileButton.clicked.connect(self.selectFile)
self.databaseButton.clicked.connect(self.selectFromDatabase)
self.actionSearch_database.triggered.connect(self.selectFromDatabase)
self.actionPlay_selected.triggered.connect(self.play_next)
self.actionPlay_next.triggered.connect(self.play_next)
self.playlist.itemSelectionChanged.connect(self.set_next)
self.playlist.itemSelectionChanged.connect(self.set_next_track)
self.timer.timeout.connect(self.tick)
def selectFromDatabase(self):
@ -160,19 +196,22 @@ class Window(QMainWindow, Ui_MainWindow):
def play_next(self):
self.music.play_next()
self.current_track.setText(
f"{self.music.get_current_title()} - "
f"{self.music.get_current_artist()}"
)
self.previous_track.setText(
f"{self.music.get_previous_title()} - "
f"{self.music.get_previous_artist()}"
)
self.set_next_track()
# Set time clocks
now = datetime.now()
self.label_start_tod.setText(now.strftime("%H:%M:%S"))
fade_time = now + timedelta(
milliseconds=self.music.get_current_fade_at())
self.label_fade_tod.setText(fade_time.strftime("%H:%M:%S"))
silence_time = now + timedelta(
milliseconds=self.music.get_current_silence_at())
self.label_silent_tod.setText(silence_time.strftime("%H:%M:%S"))
end_time = now + timedelta(
milliseconds=self.music.get_current_duration())
self.label_end_tod.setText(end_time.strftime("%H:%M:%S"))
def play_selected(self):
if self.playlist.selectionModel().hasSelection():
@ -200,17 +239,42 @@ class Window(QMainWindow, Ui_MainWindow):
# track = Track(fname)
# self.add_to_playlist(track)
def set_next(self):
def set_next_track(self):
"""
Set the next track. In order of priority:
- the highlighted track so long as it's not the current track
- if the current track is highlighted, the next track if there
is one
- none, in which case disable play next controls
"""
track_id = None
if self.playlist.selectionModel().hasSelection():
row = self.playlist.currentRow()
track_id = int(self.playlist.item(row, 0).text())
DEBUG(f"set_next: track_id={track_id}")
if track_id == self.music.get_current_track_id():
# Current track highlighted: get next if it exists
try:
track_id = int(self.playlist.item(row + 1, 0).text())
except AttributeError:
# There is no next track
track_id = None
if track_id:
DEBUG(f"set_next_track: track_id={track_id}")
if self.music.set_next_track(track_id) != track_id:
ERROR("Can't set next track")
self.next_track.setText(
f"{self.music.get_next_title()} - "
f"{self.music.get_next_artist()}"
)
self.enable_play_next_controls()
else:
self.next_track.setText("")
self.disable_play_next_controls()
def tick(self):
now = datetime.now()
self.current_time.setText(now.strftime("%H:%M:%S"))
# self.current_time.setText(now.strftime("%H:%M:%S"))
if self.music.playing():
playtime = self.music.get_current_playtime()
self.label_elapsed_timer.setText(ms_to_mmss(playtime))
@ -245,6 +309,15 @@ class Window(QMainWindow, Ui_MainWindow):
item = QTableWidgetItem(track.path)
pl.setItem(row, 7, item)
def disable_play_next_controls(self):
self.actionPlay_selected.setEnabled(False)
self.actionPlay_next.setEnabled(False)
def enable_play_next_controls(self):
self.actionPlay_selected.setEnabled(True)
self.actionPlay_next.setEnabled(True)
class DbDialog(QDialog):
def __init__(self, parent=None):
@ -301,6 +374,8 @@ def ms_to_mmss(ms, decimals=0, negative=False):
minutes, remainder = divmod(ms, 60 * 1000)
seconds = remainder / 1000
if seconds == 60:
print(f"ms_to_mmss({ms}) gave 60 seconds")
return f"{sign}{minutes:.0f}:{seconds:02.{decimals}f}"

BIN
app/ui/icon-fade.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
app/ui/icon-play-next.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
app/ui/icon-play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
app/ui/icon-stop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
app/ui/icon_open_file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -14,178 +14,89 @@
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_5">
<property name="horizontalSpacing">
<number>10</number>
</property>
<item row="0" column="0">
<widget class="QGroupBox" name="start_box">
<property name="title">
<string>Elapsed</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_elapsed_timer">
<widget class="QLabel" name="previous_track_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>116</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Sans</family>
<pointsize>40</pointsize>
<weight>75</weight>
<bold>true</bold>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>2:46</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_start_tod">
<property name="font">
<font>
<family>DejaVu Sans</family>
<pointsize>16</pointsize>
</font>
<property name="styleSheet">
<string notr="true">background-color: #f8d7da;
border: 1px solid rgb(85, 87, 83);</string>
</property>
<property name="text">
<string>10:17:37</string>
<string>Last track:</string>
</property>
<property name="scaledContents">
<bool>false</bool>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="fade_box">
<property name="title">
<string>Fade at</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_fade_timer">
<widget class="QLabel" name="previous_track">
<property name="font">
<font>
<family>Sans</family>
<pointsize>40</pointsize>
<weight>75</weight>
<bold>true</bold>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>0:53</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_fade_tod">
<property name="font">
<font>
<family>DejaVu Sans</family>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>10:21:23</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="2">
<widget class="QGroupBox" name="silent_box">
<property name="styleSheet">
<string notr="true">background-color: rgb(252, 233, 79);</string>
</property>
<property name="title">
<string>Silent at</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_silent_timer">
<property name="font">
<font>
<family>Sans</family>
<pointsize>40</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
<string notr="true">background-color: #f8d7da;
border: 1px solid rgb(85, 87, 83);</string>
</property>
<property name="text">
<string>0:58</string>
<string>Before the goldrush - Neil Young [3:46]</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_silent_tod">
<property name="font">
<font>
<family>DejaVu Sans</family>
<pointsize>16</pointsize>
</font>
<widget class="QLabel" name="current_track_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>10:21:28</string>
<property name="maximumSize">
<size>
<width>116</width>
<height>16777215</height>
</size>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="3">
<widget class="QGroupBox" name="end_box">
<property name="title">
<string>End at</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_end_timer">
<property name="font">
<font>
<family>Sans</family>
<pointsize>40</pointsize>
<weight>75</weight>
<bold>true</bold>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>1:00</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_end_tod">
<property name="font">
<font>
<family>DejaVu Sans</family>
<pointsize>16</pointsize>
</font>
<property name="styleSheet">
<string notr="true">background-color: #d4edda;
border: 1px solid rgb(85, 87, 83);</string>
</property>
<property name="text">
<string>10:21:30</string>
<string>Current track:</string>
</property>
<property name="scaledContents">
<bool>false</bool>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<item row="1" column="1">
<widget class="QLabel" name="current_track">
<property name="font">
<font>
@ -194,7 +105,56 @@
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(138, 226, 52);
<string notr="true">background-color: #d4edda;
border: 1px solid rgb(85, 87, 83);</string>
</property>
<property name="text">
<string>During the goldrush - Neil Young [3:46]</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="next_track_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>116</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Sans</family>
<pointsize>20</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: #fff3cd;
border: 1px solid rgb(85, 87, 83);</string>
</property>
<property name="text">
<string>Next track:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="next_track">
<property name="font">
<font>
<family>Sans</family>
<pointsize>20</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: #fff3cd;
border: 1px solid rgb(85, 87, 83);</string>
</property>
<property name="text">
@ -202,7 +162,7 @@ border: 1px solid rgb(85, 87, 83);</string>
</property>
</widget>
</item>
<item>
<item row="3" column="0" colspan="2">
<widget class="QTableWidget" name="playlist">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
@ -225,6 +185,9 @@ border: 1px solid rgb(85, 87, 83);</string>
<property name="columnCount">
<number>8</number>
</property>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>0</number>
</attribute>
<column>
<property name="text">
<string>Index</string>
@ -267,41 +230,340 @@ border: 1px solid rgb(85, 87, 83);</string>
</column>
</widget>
</item>
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>5</number>
</property>
<item>
<widget class="QPushButton" name="fileButton">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Select file</string>
<string>Started at:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="databaseButton">
<property name="text">
<string>Database</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="current_time">
<widget class="QLabel" name="label_start_tod">
<property name="font">
<font>
<family>DejaVu Sans</family>
<pointsize>25</pointsize>
<weight>75</weight>
<bold>true</bold>
<family>FreeSans</family>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>10:20:30</string>
<string>10:17:37</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Silent at:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_silent_tod">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>10:21:28</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_elapsed">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Elapsed time</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_elapsed_timer">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>40</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>2:46</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_elapsed_2">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Fade</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_fade_timer">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>40</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>2:46</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_elapsed_3">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Silent</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_silent_timer">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>40</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>2:46</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_elapsed_4">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>End</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_end_timer">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>40</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>2:46</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
<zorder>playlist</zorder>
<zorder>current_time</zorder>
<zorder>fileButton</zorder>
<zorder>current_track</zorder>
<zorder>databaseButton</zorder>
<zorder>previous_track</zorder>
<zorder>next_track</zorder>
<zorder>horizontalSpacer</zorder>
<zorder>horizontalSpacer_2</zorder>
<zorder>horizontalSpacer_3</zorder>
<zorder>horizontalSpacer_4</zorder>
<zorder>frame_elapsed</zorder>
<zorder>frame</zorder>
<zorder>frame_elapsed_2</zorder>
<zorder>frame_elapsed_3</zorder>
<zorder>frame_elapsed_4</zorder>
<zorder>horizontalSpacer_5</zorder>
<zorder>current_track_2</zorder>
<zorder>next_track_2</zorder>
<zorder>previous_track_2</zorder>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
@ -323,16 +585,58 @@ border: 1px solid rgb(85, 87, 83);</string>
</property>
<addaction name="actionPlay_selected"/>
<addaction name="actionPlay_next"/>
<addaction name="actionSearch_database"/>
<addaction name="actionAdd_file"/>
<addaction name="separator"/>
<addaction name="actionF_ade"/>
<addaction name="actionS_top"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuPlaylist"/>
</widget>
<widget class="QStatusBar" name="statusbar">
<property name="enabled">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(211, 215, 207);</string>
</property>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionPlay_selected"/>
<addaction name="actionPlay_next"/>
<addaction name="actionF_ade"/>
<addaction name="separator"/>
<addaction name="actionAdd_file"/>
<addaction name="actionSearch_database"/>
<addaction name="separator"/>
<addaction name="actionS_top"/>
</widget>
<widget class="QToolBar" name="toolBar_2">
<property name="windowTitle">
<string>toolBar_2</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<action name="actionPlay_selected">
<property name="icon">
<iconset>
<normaloff>icon-play.png</normaloff>icon-play.png</iconset>
</property>
<property name="text">
<string>&amp;Play selected</string>
</property>
@ -341,8 +645,48 @@ border: 1px solid rgb(85, 87, 83);</string>
</property>
</action>
<action name="actionPlay_next">
<property name="icon">
<iconset>
<normaloff>icon-play-next.png</normaloff>icon-play-next.png</iconset>
</property>
<property name="text">
<string>Play &amp;next</string>
<string>Skip to &amp;next</string>
</property>
</action>
<action name="actionSearch_database">
<property name="icon">
<iconset>
<normaloff>icon_search_database.png</normaloff>icon_search_database.png</iconset>
</property>
<property name="text">
<string>Search &amp;database</string>
</property>
</action>
<action name="actionAdd_file">
<property name="icon">
<iconset>
<normaloff>icon_open_file.png</normaloff>icon_open_file.png</iconset>
</property>
<property name="text">
<string>Add &amp;file</string>
</property>
</action>
<action name="actionF_ade">
<property name="icon">
<iconset>
<normaloff>icon-fade.png</normaloff>icon-fade.png</iconset>
</property>
<property name="text">
<string>F&amp;ade</string>
</property>
</action>
<action name="actionS_top">
<property name="icon">
<iconset>
<normaloff>icon-stop.png</normaloff>icon-stop.png</iconset>
</property>
<property name="text">
<string>S&amp;top</string>
</property>
</action>
</widget>

View File

@ -1,46 +1,70 @@
First release
Play track
cause
menu command (play or skip to next)
autoplay
Cause
menu command (play next)
menu command (skip to next)
back to last track
track assignments (modify for "back to last track")
last = current
current = next
next = None
last = current
current = next
next = None
other
update last / current / next track display
update last / current / next track display
timers to new current
show track as played
update start time for remaining tracks
record track as played
show track as played
if playing, fade current over 1 second
Log tracks played
During playback
Update timers
Update timers
Update time colours
Status bar Total remaining playlist time
Stop
Fade
Playlist management
Save playlist
Load playlist
Automatically save playlist
Automatically load playlist
Add track to database and playlist
Reorder playlist
Remove track
Add track
Add track
Clear playlist
Track properties
Copy track
Paste track
Clear selection
Track volume analysis
Open track in Audacity
Wikipedia for song title
Song facts for song title
Click current does not change next
Display
✓ Remember window size
✓ Remember dialog size
✓ Remember playlist column sizes
Top: previous, current, next track
✓ Timer font less bold
Make elapsed time and end time correct when track ends
Select next track if not already selected on track end
✓ Top: previous, current, next track
Buttons
Play next
Skip to next
Fade
Stop
Fix icons in toolbar
Misc
Logging
Preferences
✓ Logging
✓ Preferences
Database check for new/missing
Database check mtimes as well
✓ Move clocks to bottom
Status bar
Timer colour warnings
Non-track playlist entries
Later releases
Autoplay next track
Track properties
Copy track
Paste track
Track volume analysis
Open track in Audacity
Wikipedia for song title
Song facts for song title
Named playlists
Song lookup as RompR
Visualise track volume
Script notes
Higher precision timer for some things (RTC)