Selaa lähdekoodia

add settings, playlist management ok

olinox 4 vuotta sitten
vanhempi
commit
a54b0f5f80
11 muutettua tiedostoa jossa 1318 lisäystä ja 1545 poistoa
  1. 8 3
      core/constants.py
  2. 16 9
      core/repositories.py
  3. 13 1
      main.py
  4. 1 4
      notes
  5. 38 3
      ui/qt/main.ui
  6. 17 4
      ui/qt/main_ui.py
  7. 965 1483
      ui/qt/rsc_rc.py
  8. 141 0
      ui/qt/widgets/DragDropTableWidget.py
  9. 53 13
      ui/qt/widgets/playlist_table.py
  10. 1 0
      ui/qt/widgets/vlcframe.py
  11. 65 25
      ui/window.py

+ 8 - 3
core/constants.py

@@ -11,11 +11,16 @@ SUPPORTED_EXTENSIONS = ('mp3', 'wma', 'flac')
 # VLC
 VLC_PATH = APP_ROOT / 'core' / 'vlc-core'
 
-# Db
-DB_PATH = APP_ROOT / 'data' / 'default' / 'db.sqlite'
-
 DATA_DIR = APP_ROOT / 'data'
 
+SETTING_DIST_PATH = DATA_DIR / 'settings.yaml.dist'
+
+PROFILE_DIR = APP_ROOT / 'data' / 'default'
+
+DB_PATH = PROFILE_DIR / 'db.sqlite'
+SETTING_PATH = PROFILE_DIR / 'settings.yaml'
+
+
 LOGGER_NAME = "mew"
 LOG_DIR = DATA_DIR
 LOGGER_LEVEL = 0

+ 16 - 9
core/repositories.py

@@ -1,3 +1,5 @@
+from sqlalchemy import func
+
 from core import db
 from core.models import MusicFolder, Track, Tag, TrackTag, SessionTrack, Session, SessionFolder
 
@@ -35,7 +37,7 @@ class Repository:
             self.session.commit()
 
     def delete(self, model, commit=False):
-        model.delete()
+        self.session.delete(model)
         if commit:
             self.commit()
 
@@ -84,13 +86,6 @@ class TrackRepository(Repository):
             .filter(TrackTag.tag_id.in_(tag_ids)).\
             all()
 
-    def get_by_session_id(self, session_id):
-        return self.session.query(Track)\
-            .join(SessionTrack, Track.id == SessionTrack.track_id)\
-            .filter(SessionTrack.session_id == session_id)\
-            .order_by(SessionTrack.order)\
-            .all()
-
     def get_artists(self):
         return self.session.query(Track).group_by(Track.artist).all()
 
@@ -104,14 +99,26 @@ class TrackRepository(Repository):
             .group_by(Track.album)\
             .all()
 
-    def add_to_playlist(self, track_id, session_id, order):
+    def add_to_playlist(self, track_id, session_id):
         track_session = SessionTrack()
         track_session.track_id = track_id
         track_session.session_id = session_id
+        row = self.session.query(func.max(SessionTrack.order)).filter(SessionTrack.session_id == session_id)
+        order = (row.scalar() or 0) + 1
         track_session.order = order
         self.create(track_session)
         self.commit()
 
+
+class SessionTrackRepository(Repository):
+    MODEL_CLS = SessionTrack
+
+    def get_by_session_id(self, session_id):
+        return self.session.query(SessionTrack)\
+            .filter(SessionTrack.session_id == session_id)\
+            .order_by(SessionTrack.order)\
+            .all()
+
 class SessionFolderRepository(Repository):
     MODEL_CLS = SessionFolder
 

+ 13 - 1
main.py

@@ -7,10 +7,12 @@
 
 import sys
 
+import yaml
 from PyQt5.Qt import QApplication
 from PyQt5.QtWidgets import QMessageBox
 
 from core import db
+from core.constants import SETTING_PATH, SETTING_DIST_PATH
 from core.indexer import Indexer
 from core.logging_ import Logger
 from ui.window import MainWindow
@@ -35,6 +37,12 @@ def err_handler(typ, value, trace):
     sys_err(typ, value, trace)
 sys.excepthook = err_handler
 
+# create settings file
+if not SETTING_PATH.exists():
+    SETTING_DIST_PATH.copy(SETTING_PATH)
+
+settings = yaml.load(SETTING_PATH.text())
+
 # Create db if not existing
 try:
     db.create()
@@ -46,7 +54,7 @@ logger.info("-- Start --")
 app = QApplication(sys.argv)
 indexer = Indexer()
 indexer.start()
-main_window = MainWindow()
+main_window = MainWindow(settings)
 main_window.show()
 try:
     r = app.exec_()
@@ -54,4 +62,8 @@ finally:
     indexer.stop()
     db.close()
 
+    settings = main_window.currentSettings()
+    with open(SETTING_PATH, 'w') as f:
+        yaml.dump(settings, f)
+
 logger.info("-- Closed --")

+ 1 - 4
notes

@@ -20,13 +20,10 @@ Priorité 1:
 * indexer: clarifier ce qu'il se passe lorsqu'un morceau apparait plusieurs fois dans les répertoires indexés, et
   que le morceau indéxé est suppr. Est-ce que ses versions jumelles sont bien indéxées à sa place?
 * mettre à jour l'explorer au fur et à mesure de l'indexation
-* permettre l'ajoute à des playlists
 * permettre l'ajout de tags
 * faire une modale pour l'édition des metadonnées
-* afficher l'activité de l'indextation dans la barre de statut
-* Permettre la lecture d'un morceau
+* afficher l'activité de l'indexation dans la barre de statut
 * Enregistrer les notes pour un morceau et s'assurer qu'elles ne soient pas perdues
-* Permettre d'enregistrer des playlists, de les ordonner, et de les attacher à une date
 * memoriser les données d'une session à l'autre: playlist en cours, volume, ...
 
 Priorité 2:

+ 38 - 3
ui/qt/main.ui

@@ -318,7 +318,7 @@
                  <widget class="QStackedWidget" name="explorerTrackMetaStack">
                   <property name="minimumSize">
                    <size>
-                    <width>0</width>
+                    <width>220</width>
                     <height>50</height>
                    </size>
                   </property>
@@ -329,6 +329,12 @@
                    <layout class="QVBoxLayout" name="verticalLayout_11">
                     <item>
                      <widget class="QLabel" name="label_2">
+                      <property name="minimumSize">
+                       <size>
+                        <width>220</width>
+                        <height>0</height>
+                       </size>
+                      </property>
                       <property name="text">
                        <string>Sélectionnez une piste</string>
                       </property>
@@ -359,7 +365,7 @@
                     <item>
                      <layout class="QVBoxLayout" name="verticalLayout_9">
                       <property name="spacing">
-                       <number>0</number>
+                       <number>4</number>
                       </property>
                       <property name="sizeConstraint">
                        <enum>QLayout::SetMinimumSize</enum>
@@ -705,6 +711,30 @@
                     <height>0</height>
                    </size>
                   </property>
+                  <property name="editTriggers">
+                   <set>QAbstractItemView::NoEditTriggers</set>
+                  </property>
+                  <property name="dragEnabled">
+                   <bool>true</bool>
+                  </property>
+                  <property name="dragDropOverwriteMode">
+                   <bool>false</bool>
+                  </property>
+                  <property name="dragDropMode">
+                   <enum>QAbstractItemView::InternalMove</enum>
+                  </property>
+                  <property name="defaultDropAction">
+                   <enum>Qt::MoveAction</enum>
+                  </property>
+                  <property name="alternatingRowColors">
+                   <bool>true</bool>
+                  </property>
+                  <property name="selectionMode">
+                   <enum>QAbstractItemView::SingleSelection</enum>
+                  </property>
+                  <property name="selectionBehavior">
+                   <enum>QAbstractItemView::SelectRows</enum>
+                  </property>
                   <attribute name="horizontalHeaderVisible">
                    <bool>false</bool>
                   </attribute>
@@ -712,13 +742,18 @@
                    <bool>true</bool>
                   </attribute>
                   <attribute name="verticalHeaderVisible">
-                   <bool>false</bool>
+                   <bool>true</bool>
                   </attribute>
                   <column>
                    <property name="text">
                     <string>id</string>
                    </property>
                   </column>
+                  <column>
+                   <property name="text">
+                    <string>track_id</string>
+                   </property>
+                  </column>
                   <column>
                    <property name="text">
                     <string>Label</string>

+ 17 - 4
ui/qt/main_ui.py

@@ -154,13 +154,14 @@ class Ui_mainWindow(object):
         self.verticalLayout_5.setContentsMargins(10, 10, 10, 10)
         self.verticalLayout_5.setObjectName("verticalLayout_5")
         self.explorerTrackMetaStack = QtWidgets.QStackedWidget(self.page_3)
-        self.explorerTrackMetaStack.setMinimumSize(QtCore.QSize(0, 50))
+        self.explorerTrackMetaStack.setMinimumSize(QtCore.QSize(220, 50))
         self.explorerTrackMetaStack.setObjectName("explorerTrackMetaStack")
         self.page = QtWidgets.QWidget()
         self.page.setObjectName("page")
         self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.page)
         self.verticalLayout_11.setObjectName("verticalLayout_11")
         self.label_2 = QtWidgets.QLabel(self.page)
+        self.label_2.setMinimumSize(QtCore.QSize(220, 0))
         self.label_2.setAlignment(QtCore.Qt.AlignCenter)
         self.label_2.setObjectName("label_2")
         self.verticalLayout_11.addWidget(self.label_2)
@@ -315,16 +316,26 @@ class Ui_mainWindow(object):
         self.explorerPlaylist = PlaylistTable(self.page_3)
         self.explorerPlaylist.setEnabled(False)
         self.explorerPlaylist.setMinimumSize(QtCore.QSize(240, 0))
+        self.explorerPlaylist.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
+        self.explorerPlaylist.setDragEnabled(True)
+        self.explorerPlaylist.setDragDropOverwriteMode(False)
+        self.explorerPlaylist.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
+        self.explorerPlaylist.setDefaultDropAction(QtCore.Qt.MoveAction)
+        self.explorerPlaylist.setAlternatingRowColors(True)
+        self.explorerPlaylist.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
+        self.explorerPlaylist.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
         self.explorerPlaylist.setObjectName("explorerPlaylist")
-        self.explorerPlaylist.setColumnCount(2)
+        self.explorerPlaylist.setColumnCount(3)
         self.explorerPlaylist.setRowCount(0)
         item = QtWidgets.QTableWidgetItem()
         self.explorerPlaylist.setHorizontalHeaderItem(0, item)
         item = QtWidgets.QTableWidgetItem()
         self.explorerPlaylist.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.explorerPlaylist.setHorizontalHeaderItem(2, item)
         self.explorerPlaylist.horizontalHeader().setVisible(False)
         self.explorerPlaylist.horizontalHeader().setStretchLastSection(True)
-        self.explorerPlaylist.verticalHeader().setVisible(False)
+        self.explorerPlaylist.verticalHeader().setVisible(True)
         self.verticalLayout_12.addWidget(self.explorerPlaylist)
         self.horizontalLayout_6.addLayout(self.verticalLayout_12)
         self.horizontalLayout_6.setStretch(0, 1)
@@ -425,7 +436,7 @@ class Ui_mainWindow(object):
         self.retranslateUi(mainWindow)
         self.menu.setCurrentRow(-1)
         self.stack.setCurrentIndex(2)
-        self.explorerTrackMetaStack.setCurrentIndex(1)
+        self.explorerTrackMetaStack.setCurrentIndex(0)
         QtCore.QMetaObject.connectSlotsByName(mainWindow)
 
     def retranslateUi(self, mainWindow):
@@ -458,6 +469,8 @@ class Ui_mainWindow(object):
         item = self.explorerPlaylist.horizontalHeaderItem(0)
         item.setText(_translate("mainWindow", "id"))
         item = self.explorerPlaylist.horizontalHeaderItem(1)
+        item.setText(_translate("mainWindow", "track_id"))
+        item = self.explorerPlaylist.horizontalHeaderItem(2)
         item.setText(_translate("mainWindow", "Label"))
         self.label.setText(_translate("mainWindow", "Page 4"))
         self.label_5.setText(_translate("mainWindow", "Mes dossiers de musique"))

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 965 - 1483
ui/qt/rsc_rc.py


+ 141 - 0
ui/qt/widgets/DragDropTableWidget.py

@@ -0,0 +1,141 @@
+from PyQt5.QtCore import Qt, QModelIndex
+from PyQt5.QtWidgets import QTableWidget, QAbstractItemView, QTableWidgetItem, QTableView
+
+
+class DragDropTableWidget(QTableWidget):
+    def __init__(self, *args, **kwargs):
+        QTableWidget.__init__(self, *args, **kwargs)
+
+        self.setDragEnabled(True)
+        self.setAcceptDrops(True)
+        self.viewport().setAcceptDrops(True)
+        self.setDragDropOverwriteMode(False)
+        self.setDropIndicatorShown(True)
+
+        self.setSelectionMode(QAbstractItemView.SingleSelection)
+        self.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.setDragDropMode(QAbstractItemView.InternalMove)
+
+    def dropEvent(self, event):
+        if event.source() == self and (event.dropAction() == Qt.MoveAction or self.dragDropMode() == QAbstractItemView.InternalMove):
+            success, row, col, topIndex = self.dropOn(event)
+            if success:
+                selRows = self.getSelectedRowsFast()
+
+                top = selRows[0]
+                # print 'top is %d'%top
+                dropRow = row
+                if dropRow == -1:
+                    dropRow = self.rowCount()
+                # print 'dropRow is %d'%dropRow
+                offset = dropRow - top
+                # print 'offset is %d'%offset
+
+                for i, row in enumerate(selRows):
+                    r = row + offset
+                    if r > self.rowCount() or r < 0:
+                        r = 0
+                    self.insertRow(r)
+                    # print 'inserting row at %d'%r
+
+                selRows = self.getSelectedRowsFast()
+                # print 'selected rows: %s'%selRows
+
+                top = selRows[0]
+                # print 'top is %d'%top
+                offset = dropRow - top
+                # print 'offset is %d'%offset
+                for i, row in enumerate(selRows):
+                    r = row + offset
+                    if r > self.rowCount() or r < 0:
+                        r = 0
+
+                    for j in range(self.columnCount()):
+                        # print 'source is (%d, %d)'%(row, j)
+                        # print 'item text: %s'%self.item(row,j).text()
+                        source = QTableWidgetItem(self.item(row, j))
+                        # print 'dest is (%d, %d)'%(r,j)
+                        self.setItem(r, j, source)
+
+                # Why does this NOT need to be here?
+                # for row in reversed(selRows):
+                    # self.removeRow(row)
+
+                event.accept()
+
+        else:
+            QTableView.dropEvent(event)
+
+    def getSelectedRowsFast(self):
+        selRows = []
+        for item in self.selectedItems():
+            if item.row() not in selRows:
+                selRows.append(item.row())
+        return selRows
+
+    def droppingOnItself(self, event, index):
+        dropAction = event.dropAction()
+
+        if self.dragDropMode() == QAbstractItemView.InternalMove:
+            dropAction = Qt.MoveAction
+
+        if event.source() == self and event.possibleActions() & Qt.MoveAction and dropAction == Qt.MoveAction:
+            selectedIndexes = self.selectedIndexes()
+            child = index
+            while child.isValid() and child != self.rootIndex():
+                if child in selectedIndexes:
+                    return True
+                child = child.parent()
+
+        return False
+
+    def dropOn(self, event):
+        if event.isAccepted():
+            return False, None, None, None
+
+        index = QModelIndex()
+        row = -1
+        col = -1
+
+        if self.viewport().rect().contains(event.pos()):
+            index = self.indexAt(event.pos())
+            if not index.isValid() or not self.visualRect(index).contains(event.pos()):
+                index = self.rootIndex()
+
+        if self.model().supportedDropActions() & event.dropAction():
+            if index != self.rootIndex():
+                dropIndicatorPosition = self.position(event.pos(), self.visualRect(index), index)
+
+                if dropIndicatorPosition == QAbstractItemView.AboveItem:
+                    row = index.row()
+                    col = index.column()
+                    # index = index.parent()
+                elif dropIndicatorPosition == QAbstractItemView.BelowItem:
+                    row = index.row() + 1
+                    col = index.column()
+                    # index = index.parent()
+                else:
+                    row = index.row()
+                    col = index.column()
+
+            if not self.droppingOnItself(event, index):
+                # print 'row is %d'%row
+                # print 'col is %d'%col
+                return True, row, col, index
+
+        return False, None, None, None
+
+    def position(self, pos, rect, index):
+        r = QAbstractItemView.OnViewport
+        margin = 2
+        if pos.y() - rect.top() < margin:
+            r = QAbstractItemView.AboveItem
+        elif rect.bottom() - pos.y() < margin:
+            r = QAbstractItemView.BelowItem
+        elif rect.contains(pos, True):
+            r = QAbstractItemView.OnItem
+
+        if r == QAbstractItemView.OnItem and not (self.model().flags(index) & Qt.ItemIsDropEnabled):
+            r = QAbstractItemView.AboveItem if pos.y() < rect.center().y() else QAbstractItemView.BelowItem
+
+        return r

+ 53 - 13
ui/qt/widgets/playlist_table.py

@@ -1,35 +1,57 @@
-from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem
+from PyQt5.QtCore import pyqtSignal
+from PyQt5.QtWidgets import QTableWidgetItem
 
-from core.repositories import TrackRepository
+from core.repositories import TrackRepository, SessionTrackRepository
+from ui.qt.widgets.DragDropTableWidget import DragDropTableWidget
 
 
-class PlaylistTable(QTableWidget):
+class PlaylistTable(DragDropTableWidget):
+    trackSelected = pyqtSignal(object)
+    trackDoubleClicked = pyqtSignal(object)
+
     def __init__(self, parent):
-        super(QTableWidget, self).__init__(parent)
+        super().__init__(parent)
         self.playlist = None
         self.count = -1
+        self.cellPressed.connect(self._cellPressed)
+        self.cellDoubleClicked.connect(self._cellDoubleClicked)
+
+    def populate(self, playlist=None):
+        if playlist:
+            self.playlist = playlist
+        if not self.playlist:
+            return
 
-    def populate(self, playlist):
-        self.playlist = playlist
+        session_track_repo = SessionTrackRepository()
         track_repo = TrackRepository()
 
         self.clear()
         self.hideColumn(0)
+        self.hideColumn(1)
 
-        tracks = track_repo.get_by_session_id(playlist.id)
+        session_tracks = session_track_repo.get_by_session_id(self.playlist.id)
 
-        if not tracks:
-            self.insertRow(0)
-            self.setItem(0, 1, QTableWidgetItem("(la liste est vide, ajoutez y vos morceaux)"))
+        if not session_tracks:
+            # self.insertRow(0)
+            # self.setItem(0, 2, QTableWidgetItem("(la liste est vide, ajoutez y vos morceaux)"))
             return
 
         i = 0
-        for track in tracks:
+        for session_track in session_tracks:
+            track = track_repo.get_by_id(session_track.track_id)
+
             self.insertRow(i)
+
             item = QTableWidgetItem()
-            item.setData(0, track.id)
+            item.setData(0, session_track.id)
             self.setItem(i, 0, item)
-            self.setItem(i, 1, QTableWidgetItem(track.title))
+
+            item = QTableWidgetItem()
+            item.setData(0, track.id)
+            self.setItem(i, 1, item)
+
+            self.setItem(i, 2, QTableWidgetItem(track.title))
+
             i += 1
         self.count = i
 
@@ -37,3 +59,21 @@ class PlaylistTable(QTableWidget):
         while self.rowCount():
             self.removeRow(0)
         super().clear()
+
+    def _cellPressed(self, row, _):
+        track_id = int(self.item(row, 1).data(0))
+        if track_id:
+            track = TrackRepository().get_by_id(track_id)
+            self.trackSelected.emit(track)
+
+    def _cellDoubleClicked(self, row, _):
+        track_id = int(self.item(row, 1).data(0))
+        if track_id:
+            track = TrackRepository().get_by_id(int(track_id))
+            self.trackDoubleClicked.emit(track)
+
+    def selected_session_track(self):
+        session_track_id = self.item(self.currentRow(), 0).data(0)
+        if not session_track_id:
+            return None
+        return SessionTrackRepository().get_by_id(int(session_track_id))

+ 1 - 0
ui/qt/widgets/vlcframe.py

@@ -126,6 +126,7 @@ class VlcFrame(QtWidgets.QFrame):
 
         self._mediaplayer.audio_set_volume(volume)
         self.volume = volume
+        self.ui.volumeSlider.setValue(volume)
 
     def set_position(self, position=None):
         """Set the movie position according to the position slider.

+ 65 - 25
ui/window.py

@@ -5,32 +5,28 @@
     @author:[author], [year]
 """
 
-from PyQt5.QtSql import QSqlDatabase
 from path import Path
 
 from PyQt5.QtGui import QIcon
 from PyQt5.QtWidgets import QMainWindow, QListWidgetItem, QTableWidgetItem, QFileDialog
 
-from core import constants
 from core.logging_ import Logger
 from core.models import MusicFolder
-from core.repositories import MusicFolderRepository, TrackRepository
+from core.repositories import MusicFolderRepository, TrackRepository, SessionTrackRepository, SessionRepository
 from ui.qt.dlg_playlist import DlgPlaylist
 from ui.qt.dlg_select_playlist import DlgSelectPlaylist
 from ui.qt.main_ui import Ui_mainWindow
+from ui.qt.widgets.explorertable import ExplorerTable
+from ui.qt.widgets.playlist_table import PlaylistTable
 
 logger = Logger.get()
 
 
 class MainWindow(QMainWindow):
-    def __init__(self):
+    def __init__(self, settings=None):
         super().__init__()
 
-        # db
-        # self.qdb = QSqlDatabase.addDatabase("QSQLITE")
-        # self.qdb.setDatabaseName(constants.DB_PATH)
-        # self.qdb.open()
-
+        self.settings = settings or {}
         self.createWidgets()
 
     def createWidgets(self):
@@ -59,7 +55,7 @@ class MainWindow(QMainWindow):
 
         # Page 3 - explorer
         self.ui.explorerTable.populate()
-        self.ui.explorerTable.trackSelected.connect(self.explorer_tree_selection_changed)
+        self.ui.explorerTable.trackSelected.connect(self.explorer_selection_changed)
         self.ui.explorerTable.trackDoubleClicked.connect(self.play_track)
         self.ui.btnExplorerRefresh.clicked.connect(self.refresh_explorer_tree)
         self.ui.explorerTrackMetaStack.setCurrentIndex(0)
@@ -68,6 +64,10 @@ class MainWindow(QMainWindow):
         self.ui.btnSelectPlaylist.clicked.connect(self.selectPlaylist)
 
         self.ui.explorerAddToPlaylist.clicked.connect(self.add_to_playlist)
+        self.ui.explorerRemoveFromPlaylist.clicked.connect(self.remove_from_playlist)
+
+        self.ui.explorerPlaylist.trackSelected.connect(self.explorer_selection_changed)
+        self.ui.explorerPlaylist.trackDoubleClicked.connect(self.play_track)
 
         # self.ui.explorerCreatePlaylist.clicked.connect(self.createOrEditPlaylist)
 
@@ -77,6 +77,16 @@ class MainWindow(QMainWindow):
         self.ui.musicFoldersRemoveButton.clicked.connect(self.remove_music_folder)
         self.populate_music_folders_table()
 
+        # Apply settings
+        if self.settings:
+            self.ui.vlcFrame.set_volume(int(self.settings['volume']))
+
+            playlist_id = int(self.settings['playlist'])
+            if playlist_id > 0:
+                playlist_repo = SessionRepository()
+                playlist = playlist_repo.get_by_id(playlist_id)
+                self.loadPlaylist(playlist)
+
     def menu_item_selected(self, e):
         self.ui.stack.setCurrentIndex(e.index)
 
@@ -89,21 +99,35 @@ class MainWindow(QMainWindow):
     def refresh_explorer_tree(self):
         self.ui.explorerTable.populate()
 
-    def explorer_tree_selection_changed(self, track):
-        if track:
-            self.ui.explorerLblTrackTitle.setText(track.title)
-            self.ui.explorerLblTrackArtist.setText(track.artist)
-            self.ui.explorerLblTrackAlbum.setText(track.album)
-            self.ui.explorerLblTrackNumber.setText(
-                str(track.track_num if track.track_num is not None else "")
-            )
-            self.ui.explorerTrackMetaStack.setCurrentIndex(1)
-            self.ui.explorerTrackPlay.setEnabled(True)
+    def explorer_selection_changed(self, track):
+        sender = self.sender()
+
+        self.ui.explorerTrackMetaStack.setCurrentIndex(0)
+        self.ui.explorerTrackPlay.setEnabled(False)
+        self.ui.explorerAddToPlaylist.setEnabled(False)
+        self.ui.explorerRemoveFromPlaylist.setEnabled(False)
+
+        if not track:
+            return
+
+        # track infos
+        self.ui.explorerLblTrackTitle.setText(track.title)
+        self.ui.explorerLblTrackArtist.setText(track.artist)
+        self.ui.explorerLblTrackAlbum.setText(track.album)
+        self.ui.explorerLblTrackNumber.setText(
+            str(track.track_num if track.track_num is not None else "")
+        )
+        self.ui.explorerTrackMetaStack.setCurrentIndex(1)
+        self.ui.explorerTrackPlay.setEnabled(True)
+
+        if type(sender) is ExplorerTable:
             self.ui.explorerAddToPlaylist.setEnabled(True)
+
+        elif type(sender) is PlaylistTable:
+            self.ui.explorerRemoveFromPlaylist.setEnabled(True)
+
         else:
-            self.ui.explorerTrackMetaStack.setCurrentIndex(0)
-            self.ui.explorerTrackPlay.setEnabled(False)
-            self.ui.explorerAddToPlaylist.setEnabled(False)
+            raise RuntimeError("Unknown sender")
 
     def populate_music_folders_table(self):
         music_folders = MusicFolderRepository().get_all()
@@ -183,14 +207,30 @@ class MainWindow(QMainWindow):
         track_repo = TrackRepository()
         track_repo.add_to_playlist(
             track.id,
-            playlist.id,
-            order
+            playlist.id
         )
         self.ui.explorerPlaylist.populate(playlist)
 
+    def remove_from_playlist(self):
+        session_track = self.ui.explorerPlaylist.selected_session_track()
+        if session_track is None:
+            return
+        session_track_repo = SessionTrackRepository()
+        session_track_repo.delete(session_track, True)
+        self.ui.explorerPlaylist.populate()
+
     def run(self):
         pass
 
+    def currentSettings(self):
+        volume = self.ui.vlcFrame.volume
+        playlist_id = self.ui.explorerPlaylist.playlist.id
+
+        return {
+            "playlist": playlist_id,
+            "volume": volume
+        }
+
     def __del__(self):
         if self.qdb.isOpen():
             self.qdb.close()

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä