Bladeren bron

Merge branch 'master' of https://git.xorion.net/olinox14/mew

Conflicts:
	ui/qt/rsc_rc.py
Olivier Massot 4 jaren geleden
bovenliggende
commit
f57e0c0cdf
12 gewijzigde bestanden met toevoegingen van 1369 en 767 verwijderingen
  1. 4 0
      core/repositories.py
  2. 36 0
      ui/qt/dlg_tag_editor.py
  3. 166 0
      ui/qt/dlg_tag_editor.ui
  4. 90 0
      ui/qt/dlg_tag_editor_ui.py
  5. 1 0
      ui/qt/gen.cmd
  6. 284 75
      ui/qt/main.ui
  7. 154 42
      ui/qt/main_ui.py
  8. BIN
      ui/qt/rsc/next_track.png
  9. BIN
      ui/qt/rsc/previous_track.jpg
  10. 464 641
      ui/qt/rsc_rc.py
  11. 109 0
      ui/qt/widgets/tags_table.py
  12. 61 9
      ui/window.py

+ 4 - 0
core/repositories.py

@@ -65,6 +65,10 @@ class TagRepository(Repository):
             all()
 
 
+class TrackTagRepository(Repository):
+    MODEL_CLS = TrackTag
+
+
 class TrackRepository(Repository):
     MODEL_CLS = Track
 

+ 36 - 0
ui/qt/dlg_tag_editor.py

@@ -0,0 +1,36 @@
+from PyQt5 import QtWidgets
+from PyQt5.QtWidgets import QMessageBox
+
+from ui.qt.dlg_tag_editor_ui import Ui_DlgTagEditor
+
+
+class DlgTagEditor(QtWidgets.QDialog):
+    def __init__(self, track=None, parent=None):
+        super().__init__(parent)
+        self.createWidgets(track)
+
+    def createWidgets(self, track=None):
+        self.ui = Ui_DlgTagEditor()
+        self.ui.setupUi(self)
+        self.ui.tagsTable.populate(track)
+
+        self.ui.btnOk.clicked.connect(self.ok)
+        self.ui.btnCancel.clicked.connect(self.cancel)
+
+    @classmethod
+    def select(cls, parent, track=None):
+        dlg = cls(parent, track)
+        r = dlg.exec_()
+        if r:
+            return dlg.selected_tags()
+        else:
+            return None
+
+    def ok(self):
+        self.done(1)
+
+    def cancel(self):
+        self.done(0)
+
+    def selected_tags(self):
+        return []

+ 166 - 0
ui/qt/dlg_tag_editor.ui

@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DlgTagEditor</class>
+ <widget class="QDialog" name="DlgTagEditor">
+  <property name="windowModality">
+   <enum>Qt::ApplicationModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>392</width>
+    <height>270</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>392</width>
+    <height>270</height>
+   </size>
+  </property>
+  <property name="font">
+   <font>
+    <family>Verdana</family>
+    <pointsize>8</pointsize>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>Mes étiquettes</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="font">
+        <font>
+         <family>Verdana</family>
+         <pointsize>11</pointsize>
+         <weight>75</weight>
+         <bold>true</bold>
+        </font>
+       </property>
+       <property name="text">
+        <string>Mes étiquettes</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="TagsTable" name="tagsTable">
+       <property name="horizontalScrollBarPolicy">
+        <enum>Qt::ScrollBarAlwaysOff</enum>
+       </property>
+       <property name="editTriggers">
+        <set>QAbstractItemView::DoubleClicked</set>
+       </property>
+       <property name="selectionMode">
+        <enum>QAbstractItemView::SingleSelection</enum>
+       </property>
+       <property name="selectionBehavior">
+        <enum>QAbstractItemView::SelectRows</enum>
+       </property>
+       <property name="gridStyle">
+        <enum>Qt::NoPen</enum>
+       </property>
+       <attribute name="horizontalHeaderVisible">
+        <bool>false</bool>
+       </attribute>
+       <attribute name="horizontalHeaderDefaultSectionSize">
+        <number>45</number>
+       </attribute>
+       <attribute name="horizontalHeaderStretchLastSection">
+        <bool>true</bool>
+       </attribute>
+       <attribute name="verticalHeaderVisible">
+        <bool>false</bool>
+       </attribute>
+       <column>
+        <property name="text">
+         <string>id</string>
+        </property>
+       </column>
+       <column>
+        <property name="text">
+         <string>checked</string>
+        </property>
+        <property name="textAlignment">
+         <set>AlignCenter</set>
+        </property>
+       </column>
+       <column>
+        <property name="text">
+         <string>label</string>
+        </property>
+       </column>
+      </widget>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_2">
+       <item>
+        <widget class="QPushButton" name="btnCancel">
+         <property name="minimumSize">
+          <size>
+           <width>120</width>
+           <height>32</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>120</width>
+           <height>32</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>Annuler</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QPushButton" name="btnOk">
+         <property name="minimumSize">
+          <size>
+           <width>140</width>
+           <height>32</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>140</width>
+           <height>32</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>Enregistrer</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>TagsTable</class>
+   <extends>QTableWidget</extends>
+   <header location="global">.widgets.tags_table.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>

+ 90 - 0
ui/qt/dlg_tag_editor_ui.py

@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'dlg_tag_editor.ui'
+#
+# Created by: PyQt5 UI code generator 5.15.2
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again.  Do not edit this file unless you know what you are doing.
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_DlgTagEditor(object):
+    def setupUi(self, DlgTagEditor):
+        DlgTagEditor.setObjectName("DlgTagEditor")
+        DlgTagEditor.setWindowModality(QtCore.Qt.ApplicationModal)
+        DlgTagEditor.resize(392, 270)
+        DlgTagEditor.setMinimumSize(QtCore.QSize(392, 270))
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(8)
+        DlgTagEditor.setFont(font)
+        self.horizontalLayout = QtWidgets.QHBoxLayout(DlgTagEditor)
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        self.verticalLayout = QtWidgets.QVBoxLayout()
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.label = QtWidgets.QLabel(DlgTagEditor)
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(11)
+        font.setBold(True)
+        font.setWeight(75)
+        self.label.setFont(font)
+        self.label.setObjectName("label")
+        self.verticalLayout.addWidget(self.label)
+        self.tagsTable = TagsTable(DlgTagEditor)
+        self.tagsTable.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+        self.tagsTable.setEditTriggers(QtWidgets.QAbstractItemView.DoubleClicked)
+        self.tagsTable.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
+        self.tagsTable.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
+        self.tagsTable.setGridStyle(QtCore.Qt.NoPen)
+        self.tagsTable.setObjectName("tagsTable")
+        self.tagsTable.setColumnCount(3)
+        self.tagsTable.setRowCount(0)
+        item = QtWidgets.QTableWidgetItem()
+        self.tagsTable.setHorizontalHeaderItem(0, item)
+        item = QtWidgets.QTableWidgetItem()
+        item.setTextAlignment(QtCore.Qt.AlignCenter)
+        self.tagsTable.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.tagsTable.setHorizontalHeaderItem(2, item)
+        self.tagsTable.horizontalHeader().setVisible(False)
+        self.tagsTable.horizontalHeader().setDefaultSectionSize(45)
+        self.tagsTable.horizontalHeader().setStretchLastSection(True)
+        self.tagsTable.verticalHeader().setVisible(False)
+        self.verticalLayout.addWidget(self.tagsTable)
+        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+        self.btnCancel = QtWidgets.QPushButton(DlgTagEditor)
+        self.btnCancel.setMinimumSize(QtCore.QSize(120, 32))
+        self.btnCancel.setMaximumSize(QtCore.QSize(120, 32))
+        self.btnCancel.setObjectName("btnCancel")
+        self.horizontalLayout_2.addWidget(self.btnCancel)
+        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+        self.horizontalLayout_2.addItem(spacerItem)
+        self.btnOk = QtWidgets.QPushButton(DlgTagEditor)
+        self.btnOk.setMinimumSize(QtCore.QSize(140, 32))
+        self.btnOk.setMaximumSize(QtCore.QSize(140, 32))
+        self.btnOk.setObjectName("btnOk")
+        self.horizontalLayout_2.addWidget(self.btnOk)
+        self.verticalLayout.addLayout(self.horizontalLayout_2)
+        self.horizontalLayout.addLayout(self.verticalLayout)
+
+        self.retranslateUi(DlgTagEditor)
+        QtCore.QMetaObject.connectSlotsByName(DlgTagEditor)
+
+    def retranslateUi(self, DlgTagEditor):
+        _translate = QtCore.QCoreApplication.translate
+        DlgTagEditor.setWindowTitle(_translate("DlgTagEditor", "Mes étiquettes"))
+        self.label.setText(_translate("DlgTagEditor", "Mes étiquettes"))
+        item = self.tagsTable.horizontalHeaderItem(0)
+        item.setText(_translate("DlgTagEditor", "id"))
+        item = self.tagsTable.horizontalHeaderItem(1)
+        item.setText(_translate("DlgTagEditor", "checked"))
+        item = self.tagsTable.horizontalHeaderItem(2)
+        item.setText(_translate("DlgTagEditor", "label"))
+        self.btnCancel.setText(_translate("DlgTagEditor", "Annuler"))
+        self.btnOk.setText(_translate("DlgTagEditor", "Enregistrer"))
+from .widgets.tags_table import TagsTable

+ 1 - 0
ui/qt/gen.cmd

@@ -2,5 +2,6 @@ pyrcc5 rsc.qrc -o rsc_rc.py
 pyuic5 main.ui -o main_ui.py --from-imports
 pyuic5 dlg_select_playlist.ui -o dlg_select_playlist_ui.py --from-imports
 pyuic5 dlg_playlist.ui -o dlg_playlist_ui.py --from-imports
+pyuic5 dlg_tag_editor.ui -o dlg_tag_editor_ui.py --from-imports
 pyuic5 widgets/frame_notes.ui -o widgets/frame_notes_ui.py --import-from=..
 pyuic5 widgets/vlcframe.ui -o widgets/vlcframe_ui.py --import-from=..

+ 284 - 75
ui/qt/main.ui

@@ -134,6 +134,8 @@
                  <widget class="QLabel" name="sessionLblTitle">
                   <property name="font">
                    <font>
+                    <family>Verdana</family>
+                    <pointsize>8</pointsize>
                     <weight>75</weight>
                     <bold>true</bold>
                    </font>
@@ -445,7 +447,7 @@
                </layout>
               </item>
               <item>
-               <layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,0,0,0,0,0,0,0">
+               <layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,0,0,0">
                 <property name="leftMargin">
                  <number>10</number>
                 </property>
@@ -724,20 +726,128 @@
                        </layout>
                       </item>
                       <item>
-                       <spacer name="verticalSpacer_3">
-                        <property name="orientation">
-                         <enum>Qt::Vertical</enum>
-                        </property>
-                        <property name="sizeType">
-                         <enum>QSizePolicy::Fixed</enum>
+                       <layout class="QHBoxLayout" name="horizontalLayout_19">
+                        <item>
+                         <widget class="QLabel" name="label_12">
+                          <property name="font">
+                           <font>
+                            <family>Verdana</family>
+                            <pointsize>8</pointsize>
+                            <underline>true</underline>
+                           </font>
+                          </property>
+                          <property name="text">
+                           <string>Etiquettes</string>
+                          </property>
+                         </widget>
+                        </item>
+                        <item>
+                         <widget class="QLineEdit" name="lineSearchTags">
+                          <property name="minimumSize">
+                           <size>
+                            <width>0</width>
+                            <height>25</height>
+                           </size>
+                          </property>
+                          <property name="maximumSize">
+                           <size>
+                            <width>100</width>
+                            <height>16777215</height>
+                           </size>
+                          </property>
+                          <property name="placeholderText">
+                           <string>Rechercher...</string>
+                          </property>
+                          <property name="clearButtonEnabled">
+                           <bool>true</bool>
+                          </property>
+                         </widget>
+                        </item>
+                        <item>
+                         <widget class="QToolButton" name="btnEditTags">
+                          <property name="minimumSize">
+                           <size>
+                            <width>28</width>
+                            <height>28</height>
+                           </size>
+                          </property>
+                          <property name="maximumSize">
+                           <size>
+                            <width>28</width>
+                            <height>28</height>
+                           </size>
+                          </property>
+                          <property name="text">
+                           <string>...</string>
+                          </property>
+                          <property name="icon">
+                           <iconset resource="rsc.qrc">
+                            <normaloff>:/img/rsc/edit.png</normaloff>:/img/rsc/edit.png</iconset>
+                          </property>
+                         </widget>
+                        </item>
+                       </layout>
+                      </item>
+                      <item>
+                       <widget class="TagsTable" name="explorerTrackTagsTable">
+                        <property name="minimumSize">
+                         <size>
+                          <width>0</width>
+                          <height>160</height>
+                         </size>
                         </property>
-                        <property name="sizeHint" stdset="0">
+                        <property name="maximumSize">
                          <size>
-                          <width>20</width>
-                          <height>20</height>
+                          <width>16777215</width>
+                          <height>160</height>
                          </size>
                         </property>
-                       </spacer>
+                        <property name="horizontalScrollBarPolicy">
+                         <enum>Qt::ScrollBarAlwaysOff</enum>
+                        </property>
+                        <property name="editTriggers">
+                         <set>QAbstractItemView::NoEditTriggers</set>
+                        </property>
+                        <property name="alternatingRowColors">
+                         <bool>true</bool>
+                        </property>
+                        <property name="selectionMode">
+                         <enum>QAbstractItemView::NoSelection</enum>
+                        </property>
+                        <property name="gridStyle">
+                         <enum>Qt::NoPen</enum>
+                        </property>
+                        <property name="cornerButtonEnabled">
+                         <bool>false</bool>
+                        </property>
+                        <attribute name="horizontalHeaderVisible">
+                         <bool>false</bool>
+                        </attribute>
+                        <attribute name="horizontalHeaderStretchLastSection">
+                         <bool>true</bool>
+                        </attribute>
+                        <attribute name="verticalHeaderVisible">
+                         <bool>false</bool>
+                        </attribute>
+                        <column>
+                         <property name="text">
+                          <string>id</string>
+                         </property>
+                        </column>
+                        <column>
+                         <property name="text">
+                          <string>check</string>
+                         </property>
+                         <property name="textAlignment">
+                          <set>AlignCenter</set>
+                         </property>
+                        </column>
+                        <column>
+                         <property name="text">
+                          <string>label</string>
+                         </property>
+                        </column>
+                       </widget>
                       </item>
                       <item>
                        <widget class="QLabel" name="label_10">
@@ -764,7 +874,13 @@
                         <property name="minimumSize">
                          <size>
                           <width>218</width>
-                          <height>120</height>
+                          <height>160</height>
+                         </size>
+                        </property>
+                        <property name="maximumSize">
+                         <size>
+                          <width>16777215</width>
+                          <height>160</height>
                          </size>
                         </property>
                         <property name="cursor" stdset="0">
@@ -790,51 +906,6 @@
                   </widget>
                  </widget>
                 </item>
-                <item>
-                 <spacer name="verticalSpacer_5">
-                  <property name="orientation">
-                   <enum>Qt::Vertical</enum>
-                  </property>
-                  <property name="sizeType">
-                   <enum>QSizePolicy::Fixed</enum>
-                  </property>
-                  <property name="sizeHint" stdset="0">
-                   <size>
-                    <width>20</width>
-                    <height>10</height>
-                   </size>
-                  </property>
-                 </spacer>
-                </item>
-                <item>
-                 <widget class="Line" name="line_2">
-                  <property name="minimumSize">
-                   <size>
-                    <width>220</width>
-                    <height>0</height>
-                   </size>
-                  </property>
-                  <property name="orientation">
-                   <enum>Qt::Horizontal</enum>
-                  </property>
-                 </widget>
-                </item>
-                <item>
-                 <spacer name="verticalSpacer_4">
-                  <property name="orientation">
-                   <enum>Qt::Vertical</enum>
-                  </property>
-                  <property name="sizeType">
-                   <enum>QSizePolicy::Fixed</enum>
-                  </property>
-                  <property name="sizeHint" stdset="0">
-                   <size>
-                    <width>20</width>
-                    <height>30</height>
-                   </size>
-                  </property>
-                 </spacer>
-                </item>
                 <item>
                  <widget class="QPushButton" name="explorerTrackPlay">
                   <property name="enabled">
@@ -901,22 +972,6 @@
                   </property>
                  </widget>
                 </item>
-                <item>
-                 <spacer name="verticalSpacer_2">
-                  <property name="orientation">
-                   <enum>Qt::Vertical</enum>
-                  </property>
-                  <property name="sizeType">
-                   <enum>QSizePolicy::Fixed</enum>
-                  </property>
-                  <property name="sizeHint" stdset="0">
-                   <size>
-                    <width>20</width>
-                    <height>30</height>
-                   </size>
-                  </property>
-                 </spacer>
-                </item>
                </layout>
               </item>
               <item>
@@ -1067,6 +1122,9 @@
            <layout class="QHBoxLayout" name="horizontalLayout_5">
             <item>
              <layout class="QVBoxLayout" name="verticalLayout_6">
+              <property name="spacing">
+               <number>10</number>
+              </property>
               <property name="leftMargin">
                <number>20</number>
               </property>
@@ -1081,17 +1139,32 @@
               </property>
               <item>
                <widget class="QLabel" name="label_5">
+                <property name="font">
+                 <font>
+                  <family>Verdana</family>
+                  <pointsize>8</pointsize>
+                  <weight>75</weight>
+                  <bold>true</bold>
+                  <underline>true</underline>
+                 </font>
+                </property>
                 <property name="text">
                  <string>Mes dossiers de musique</string>
                 </property>
                </widget>
               </item>
               <item>
-               <widget class="QTableWidget" name="musicFoldersTable">
+               <widget class="QTableWidget" name="settingsMusicFoldersTable">
+                <property name="minimumSize">
+                 <size>
+                  <width>0</width>
+                  <height>192</height>
+                 </size>
+                </property>
                 <property name="maximumSize">
                  <size>
                   <width>16777215</width>
-                  <height>400</height>
+                  <height>192</height>
                  </size>
                 </property>
                 <property name="editTriggers">
@@ -1205,6 +1278,137 @@
                 </property>
                </widget>
               </item>
+              <item>
+               <widget class="QLabel" name="label_13">
+                <property name="font">
+                 <font>
+                  <family>Verdana</family>
+                  <pointsize>8</pointsize>
+                  <weight>75</weight>
+                  <bold>true</bold>
+                  <underline>true</underline>
+                 </font>
+                </property>
+                <property name="text">
+                 <string>Mes étiquettes</string>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="TagsTable" name="settingsTagsTableWidget">
+                <property name="minimumSize">
+                 <size>
+                  <width>0</width>
+                  <height>192</height>
+                 </size>
+                </property>
+                <property name="maximumSize">
+                 <size>
+                  <width>16777215</width>
+                  <height>192</height>
+                 </size>
+                </property>
+                <property name="horizontalScrollBarPolicy">
+                 <enum>Qt::ScrollBarAsNeeded</enum>
+                </property>
+                <property name="selectionMode">
+                 <enum>QAbstractItemView::SingleSelection</enum>
+                </property>
+                <property name="selectionBehavior">
+                 <enum>QAbstractItemView::SelectRows</enum>
+                </property>
+                <property name="showGrid">
+                 <bool>false</bool>
+                </property>
+                <property name="gridStyle">
+                 <enum>Qt::NoPen</enum>
+                </property>
+                <property name="cornerButtonEnabled">
+                 <bool>false</bool>
+                </property>
+                <attribute name="horizontalHeaderVisible">
+                 <bool>false</bool>
+                </attribute>
+                <attribute name="horizontalHeaderStretchLastSection">
+                 <bool>true</bool>
+                </attribute>
+                <attribute name="verticalHeaderVisible">
+                 <bool>false</bool>
+                </attribute>
+                <column>
+                 <property name="text">
+                  <string>id</string>
+                 </property>
+                </column>
+                <column>
+                 <property name="text">
+                  <string>checked</string>
+                 </property>
+                 <property name="textAlignment">
+                  <set>AlignCenter</set>
+                 </property>
+                </column>
+                <column>
+                 <property name="text">
+                  <string>label</string>
+                 </property>
+                </column>
+               </widget>
+              </item>
+              <item>
+               <layout class="QHBoxLayout" name="horizontalLayout_20">
+                <property name="sizeConstraint">
+                 <enum>QLayout::SetMinimumSize</enum>
+                </property>
+                <item>
+                 <widget class="QPushButton" name="tableTagsRemoveButton">
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>32</height>
+                   </size>
+                  </property>
+                  <property name="text">
+                   <string>Supprimer</string>
+                  </property>
+                  <property name="icon">
+                   <iconset resource="rsc.qrc">
+                    <normaloff>:/img/rsc/delete.png</normaloff>:/img/rsc/delete.png</iconset>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <spacer name="horizontalSpacer_3">
+                  <property name="orientation">
+                   <enum>Qt::Horizontal</enum>
+                  </property>
+                  <property name="sizeHint" stdset="0">
+                   <size>
+                    <width>40</width>
+                    <height>20</height>
+                   </size>
+                  </property>
+                 </spacer>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="tagsTableAddButton">
+                  <property name="minimumSize">
+                   <size>
+                    <width>128</width>
+                    <height>32</height>
+                   </size>
+                  </property>
+                  <property name="text">
+                   <string>Ajouter</string>
+                  </property>
+                  <property name="icon">
+                   <iconset resource="rsc.qrc">
+                    <normaloff>:/img/rsc/plus.png</normaloff>:/img/rsc/plus.png</iconset>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </item>
               <item>
                <spacer name="verticalSpacer">
                 <property name="orientation">
@@ -1277,6 +1481,11 @@
    <header location="global">.widgets.frame_notes.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>TagsTable</class>
+   <extends>QTableWidget</extends>
+   <header location="global">.widgets.tags_table.h</header>
+  </customwidget>
  </customwidgets>
  <resources>
   <include location="rsc.qrc"/>

+ 154 - 42
ui/qt/main_ui.py

@@ -71,6 +71,8 @@ class Ui_mainWindow(object):
         self.horizontalLayout_15.addWidget(self.sessionBtnChange)
         self.sessionLblTitle = QtWidgets.QLabel(self.page_1)
         font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(8)
         font.setBold(True)
         font.setWeight(75)
         self.sessionLblTitle.setFont(font)
@@ -302,8 +304,52 @@ class Ui_mainWindow(object):
         self.explorerLblTrackNumber.setObjectName("explorerLblTrackNumber")
         self.horizontalLayout_11.addWidget(self.explorerLblTrackNumber)
         self.verticalLayout_9.addLayout(self.horizontalLayout_11)
-        spacerItem1 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
-        self.verticalLayout_9.addItem(spacerItem1)
+        self.horizontalLayout_19 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_19.setObjectName("horizontalLayout_19")
+        self.label_12 = QtWidgets.QLabel(self.page_6)
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(8)
+        font.setUnderline(True)
+        self.label_12.setFont(font)
+        self.label_12.setObjectName("label_12")
+        self.horizontalLayout_19.addWidget(self.label_12)
+        self.lineSearchTags = QtWidgets.QLineEdit(self.page_6)
+        self.lineSearchTags.setMinimumSize(QtCore.QSize(0, 25))
+        self.lineSearchTags.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.lineSearchTags.setClearButtonEnabled(True)
+        self.lineSearchTags.setObjectName("lineSearchTags")
+        self.horizontalLayout_19.addWidget(self.lineSearchTags)
+        self.btnEditTags = QtWidgets.QToolButton(self.page_6)
+        self.btnEditTags.setMinimumSize(QtCore.QSize(28, 28))
+        self.btnEditTags.setMaximumSize(QtCore.QSize(28, 28))
+        self.btnEditTags.setIcon(icon5)
+        self.btnEditTags.setObjectName("btnEditTags")
+        self.horizontalLayout_19.addWidget(self.btnEditTags)
+        self.verticalLayout_9.addLayout(self.horizontalLayout_19)
+        self.explorerTrackTagsTable = TagsTable(self.page_6)
+        self.explorerTrackTagsTable.setMinimumSize(QtCore.QSize(0, 160))
+        self.explorerTrackTagsTable.setMaximumSize(QtCore.QSize(16777215, 160))
+        self.explorerTrackTagsTable.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+        self.explorerTrackTagsTable.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
+        self.explorerTrackTagsTable.setAlternatingRowColors(True)
+        self.explorerTrackTagsTable.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
+        self.explorerTrackTagsTable.setGridStyle(QtCore.Qt.NoPen)
+        self.explorerTrackTagsTable.setCornerButtonEnabled(False)
+        self.explorerTrackTagsTable.setObjectName("explorerTrackTagsTable")
+        self.explorerTrackTagsTable.setColumnCount(3)
+        self.explorerTrackTagsTable.setRowCount(0)
+        item = QtWidgets.QTableWidgetItem()
+        self.explorerTrackTagsTable.setHorizontalHeaderItem(0, item)
+        item = QtWidgets.QTableWidgetItem()
+        item.setTextAlignment(QtCore.Qt.AlignCenter)
+        self.explorerTrackTagsTable.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.explorerTrackTagsTable.setHorizontalHeaderItem(2, item)
+        self.explorerTrackTagsTable.horizontalHeader().setVisible(False)
+        self.explorerTrackTagsTable.horizontalHeader().setStretchLastSection(True)
+        self.explorerTrackTagsTable.verticalHeader().setVisible(False)
+        self.verticalLayout_9.addWidget(self.explorerTrackTagsTable)
         self.label_10 = QtWidgets.QLabel(self.page_6)
         self.label_10.setMaximumSize(QtCore.QSize(361, 14))
         font = QtGui.QFont()
@@ -314,7 +360,8 @@ class Ui_mainWindow(object):
         self.label_10.setObjectName("label_10")
         self.verticalLayout_9.addWidget(self.label_10)
         self.explorerTrackNotepad = QtWidgets.QTextEdit(self.page_6)
-        self.explorerTrackNotepad.setMinimumSize(QtCore.QSize(218, 120))
+        self.explorerTrackNotepad.setMinimumSize(QtCore.QSize(218, 160))
+        self.explorerTrackNotepad.setMaximumSize(QtCore.QSize(16777215, 160))
         self.explorerTrackNotepad.viewport().setProperty("cursor", QtGui.QCursor(QtCore.Qt.IBeamCursor))
         self.explorerTrackNotepad.setAutoFormatting(QtWidgets.QTextEdit.AutoAll)
         self.explorerTrackNotepad.setUndoRedoEnabled(True)
@@ -324,16 +371,6 @@ class Ui_mainWindow(object):
         self.horizontalLayout_16.addLayout(self.verticalLayout_9)
         self.explorerTrackMetaStack.addWidget(self.page_6)
         self.verticalLayout_5.addWidget(self.explorerTrackMetaStack)
-        spacerItem2 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
-        self.verticalLayout_5.addItem(spacerItem2)
-        self.line_2 = QtWidgets.QFrame(self.page_3)
-        self.line_2.setMinimumSize(QtCore.QSize(220, 0))
-        self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
-        self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
-        self.line_2.setObjectName("line_2")
-        self.verticalLayout_5.addWidget(self.line_2)
-        spacerItem3 = QtWidgets.QSpacerItem(20, 30, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
-        self.verticalLayout_5.addItem(spacerItem3)
         self.explorerTrackPlay = QtWidgets.QPushButton(self.page_3)
         self.explorerTrackPlay.setEnabled(False)
         self.explorerTrackPlay.setMinimumSize(QtCore.QSize(220, 0))
@@ -359,8 +396,6 @@ class Ui_mainWindow(object):
         self.explorerRemoveFromPlaylist.setIcon(icon8)
         self.explorerRemoveFromPlaylist.setObjectName("explorerRemoveFromPlaylist")
         self.verticalLayout_5.addWidget(self.explorerRemoveFromPlaylist)
-        spacerItem4 = QtWidgets.QSpacerItem(20, 30, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
-        self.verticalLayout_5.addItem(spacerItem4)
         self.horizontalLayout_6.addLayout(self.verticalLayout_5)
         self.verticalLayout_12 = QtWidgets.QVBoxLayout()
         self.verticalLayout_12.setObjectName("verticalLayout_12")
@@ -433,33 +468,42 @@ class Ui_mainWindow(object):
         self.horizontalLayout_5.setObjectName("horizontalLayout_5")
         self.verticalLayout_6 = QtWidgets.QVBoxLayout()
         self.verticalLayout_6.setContentsMargins(20, 20, 20, 20)
+        self.verticalLayout_6.setSpacing(10)
         self.verticalLayout_6.setObjectName("verticalLayout_6")
         self.label_5 = QtWidgets.QLabel(self.page_5)
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(8)
+        font.setBold(True)
+        font.setUnderline(True)
+        font.setWeight(75)
+        self.label_5.setFont(font)
         self.label_5.setObjectName("label_5")
         self.verticalLayout_6.addWidget(self.label_5)
-        self.musicFoldersTable = QtWidgets.QTableWidget(self.page_5)
-        self.musicFoldersTable.setMaximumSize(QtCore.QSize(16777215, 400))
-        self.musicFoldersTable.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
-        self.musicFoldersTable.setProperty("showDropIndicator", False)
-        self.musicFoldersTable.setDragDropOverwriteMode(False)
-        self.musicFoldersTable.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
-        self.musicFoldersTable.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
-        self.musicFoldersTable.setShowGrid(False)
-        self.musicFoldersTable.setCornerButtonEnabled(False)
-        self.musicFoldersTable.setObjectName("musicFoldersTable")
-        self.musicFoldersTable.setColumnCount(3)
-        self.musicFoldersTable.setRowCount(0)
+        self.settingsMusicFoldersTable = QtWidgets.QTableWidget(self.page_5)
+        self.settingsMusicFoldersTable.setMinimumSize(QtCore.QSize(0, 192))
+        self.settingsMusicFoldersTable.setMaximumSize(QtCore.QSize(16777215, 192))
+        self.settingsMusicFoldersTable.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
+        self.settingsMusicFoldersTable.setProperty("showDropIndicator", False)
+        self.settingsMusicFoldersTable.setDragDropOverwriteMode(False)
+        self.settingsMusicFoldersTable.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
+        self.settingsMusicFoldersTable.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
+        self.settingsMusicFoldersTable.setShowGrid(False)
+        self.settingsMusicFoldersTable.setCornerButtonEnabled(False)
+        self.settingsMusicFoldersTable.setObjectName("settingsMusicFoldersTable")
+        self.settingsMusicFoldersTable.setColumnCount(3)
+        self.settingsMusicFoldersTable.setRowCount(0)
         item = QtWidgets.QTableWidgetItem()
-        self.musicFoldersTable.setHorizontalHeaderItem(0, item)
+        self.settingsMusicFoldersTable.setHorizontalHeaderItem(0, item)
         item = QtWidgets.QTableWidgetItem()
-        self.musicFoldersTable.setHorizontalHeaderItem(1, item)
+        self.settingsMusicFoldersTable.setHorizontalHeaderItem(1, item)
         item = QtWidgets.QTableWidgetItem()
-        self.musicFoldersTable.setHorizontalHeaderItem(2, item)
-        self.musicFoldersTable.horizontalHeader().setCascadingSectionResizes(True)
-        self.musicFoldersTable.horizontalHeader().setDefaultSectionSize(70)
-        self.musicFoldersTable.horizontalHeader().setStretchLastSection(True)
-        self.musicFoldersTable.verticalHeader().setVisible(False)
-        self.verticalLayout_6.addWidget(self.musicFoldersTable)
+        self.settingsMusicFoldersTable.setHorizontalHeaderItem(2, item)
+        self.settingsMusicFoldersTable.horizontalHeader().setCascadingSectionResizes(True)
+        self.settingsMusicFoldersTable.horizontalHeader().setDefaultSectionSize(70)
+        self.settingsMusicFoldersTable.horizontalHeader().setStretchLastSection(True)
+        self.settingsMusicFoldersTable.verticalHeader().setVisible(False)
+        self.verticalLayout_6.addWidget(self.settingsMusicFoldersTable)
         self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
         self.horizontalLayout_7.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
         self.horizontalLayout_7.setObjectName("horizontalLayout_7")
@@ -470,8 +514,8 @@ class Ui_mainWindow(object):
         self.musicFoldersRemoveButton.setIcon(icon9)
         self.musicFoldersRemoveButton.setObjectName("musicFoldersRemoveButton")
         self.horizontalLayout_7.addWidget(self.musicFoldersRemoveButton)
-        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
-        self.horizontalLayout_7.addItem(spacerItem5)
+        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+        self.horizontalLayout_7.addItem(spacerItem1)
         self.musicFoldersAddButton = QtWidgets.QPushButton(self.page_5)
         self.musicFoldersAddButton.setMinimumSize(QtCore.QSize(128, 32))
         icon10 = QtGui.QIcon()
@@ -485,8 +529,57 @@ class Ui_mainWindow(object):
         self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
         self.line.setObjectName("line")
         self.verticalLayout_6.addWidget(self.line)
-        spacerItem6 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
-        self.verticalLayout_6.addItem(spacerItem6)
+        self.label_13 = QtWidgets.QLabel(self.page_5)
+        font = QtGui.QFont()
+        font.setFamily("Verdana")
+        font.setPointSize(8)
+        font.setBold(True)
+        font.setUnderline(True)
+        font.setWeight(75)
+        self.label_13.setFont(font)
+        self.label_13.setObjectName("label_13")
+        self.verticalLayout_6.addWidget(self.label_13)
+        self.settingsTagsTableWidget = TagsTable(self.page_5)
+        self.settingsTagsTableWidget.setMinimumSize(QtCore.QSize(0, 192))
+        self.settingsTagsTableWidget.setMaximumSize(QtCore.QSize(16777215, 192))
+        self.settingsTagsTableWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
+        self.settingsTagsTableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
+        self.settingsTagsTableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
+        self.settingsTagsTableWidget.setShowGrid(False)
+        self.settingsTagsTableWidget.setGridStyle(QtCore.Qt.NoPen)
+        self.settingsTagsTableWidget.setCornerButtonEnabled(False)
+        self.settingsTagsTableWidget.setObjectName("settingsTagsTableWidget")
+        self.settingsTagsTableWidget.setColumnCount(3)
+        self.settingsTagsTableWidget.setRowCount(0)
+        item = QtWidgets.QTableWidgetItem()
+        self.settingsTagsTableWidget.setHorizontalHeaderItem(0, item)
+        item = QtWidgets.QTableWidgetItem()
+        item.setTextAlignment(QtCore.Qt.AlignCenter)
+        self.settingsTagsTableWidget.setHorizontalHeaderItem(1, item)
+        item = QtWidgets.QTableWidgetItem()
+        self.settingsTagsTableWidget.setHorizontalHeaderItem(2, item)
+        self.settingsTagsTableWidget.horizontalHeader().setVisible(False)
+        self.settingsTagsTableWidget.horizontalHeader().setStretchLastSection(True)
+        self.settingsTagsTableWidget.verticalHeader().setVisible(False)
+        self.verticalLayout_6.addWidget(self.settingsTagsTableWidget)
+        self.horizontalLayout_20 = QtWidgets.QHBoxLayout()
+        self.horizontalLayout_20.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
+        self.horizontalLayout_20.setObjectName("horizontalLayout_20")
+        self.tableTagsRemoveButton = QtWidgets.QPushButton(self.page_5)
+        self.tableTagsRemoveButton.setMinimumSize(QtCore.QSize(0, 32))
+        self.tableTagsRemoveButton.setIcon(icon9)
+        self.tableTagsRemoveButton.setObjectName("tableTagsRemoveButton")
+        self.horizontalLayout_20.addWidget(self.tableTagsRemoveButton)
+        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+        self.horizontalLayout_20.addItem(spacerItem2)
+        self.tagsTableAddButton = QtWidgets.QPushButton(self.page_5)
+        self.tagsTableAddButton.setMinimumSize(QtCore.QSize(128, 32))
+        self.tagsTableAddButton.setIcon(icon10)
+        self.tagsTableAddButton.setObjectName("tagsTableAddButton")
+        self.horizontalLayout_20.addWidget(self.tagsTableAddButton)
+        self.verticalLayout_6.addLayout(self.horizontalLayout_20)
+        spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+        self.verticalLayout_6.addItem(spacerItem3)
         self.horizontalLayout_5.addLayout(self.verticalLayout_6)
         self.stack.addWidget(self.page_5)
         self.verticalLayout_7.addWidget(self.stack)
@@ -536,6 +629,15 @@ class Ui_mainWindow(object):
         self.label_6.setText(_translate("mainWindow", "Artiste"))
         self.label_7.setText(_translate("mainWindow", "Album"))
         self.label_8.setText(_translate("mainWindow", "N°"))
+        self.label_12.setText(_translate("mainWindow", "Etiquettes"))
+        self.lineSearchTags.setPlaceholderText(_translate("mainWindow", "Rechercher..."))
+        self.btnEditTags.setText(_translate("mainWindow", "..."))
+        item = self.explorerTrackTagsTable.horizontalHeaderItem(0)
+        item.setText(_translate("mainWindow", "id"))
+        item = self.explorerTrackTagsTable.horizontalHeaderItem(1)
+        item.setText(_translate("mainWindow", "check"))
+        item = self.explorerTrackTagsTable.horizontalHeaderItem(2)
+        item.setText(_translate("mainWindow", "label"))
         self.label_10.setText(_translate("mainWindow", "Notes"))
         self.explorerTrackNotepad.setPlaceholderText(_translate("mainWindow", "Mes notes sur ce morceau..."))
         self.explorerTrackPlay.setText(_translate("mainWindow", "  Lire le morceau sélectionné"))
@@ -552,16 +654,26 @@ class Ui_mainWindow(object):
         item.setText(_translate("mainWindow", "Label"))
         self.label.setText(_translate("mainWindow", "Page 4"))
         self.label_5.setText(_translate("mainWindow", "Mes dossiers de musique"))
-        item = self.musicFoldersTable.horizontalHeaderItem(0)
+        item = self.settingsMusicFoldersTable.horizontalHeaderItem(0)
         item.setText(_translate("mainWindow", "id"))
-        item = self.musicFoldersTable.horizontalHeaderItem(1)
+        item = self.settingsMusicFoldersTable.horizontalHeaderItem(1)
         item.setText(_translate("mainWindow", "Statut"))
-        item = self.musicFoldersTable.horizontalHeaderItem(2)
+        item = self.settingsMusicFoldersTable.horizontalHeaderItem(2)
         item.setText(_translate("mainWindow", "Emplacement"))
         self.musicFoldersRemoveButton.setText(_translate("mainWindow", "Supprimer"))
         self.musicFoldersAddButton.setText(_translate("mainWindow", "Ajouter"))
+        self.label_13.setText(_translate("mainWindow", "Mes étiquettes"))
+        item = self.settingsTagsTableWidget.horizontalHeaderItem(0)
+        item.setText(_translate("mainWindow", "id"))
+        item = self.settingsTagsTableWidget.horizontalHeaderItem(1)
+        item.setText(_translate("mainWindow", "checked"))
+        item = self.settingsTagsTableWidget.horizontalHeaderItem(2)
+        item.setText(_translate("mainWindow", "label"))
+        self.tableTagsRemoveButton.setText(_translate("mainWindow", "Supprimer"))
+        self.tagsTableAddButton.setText(_translate("mainWindow", "Ajouter"))
 from .widgets.explorertable import ExplorerTable
 from .widgets.frame_notes import FrameNotes
 from .widgets.playlist_table import PlaylistTable
+from .widgets.tags_table import TagsTable
 from .widgets.vlcframe import VlcFrame
 from . import rsc_rc

BIN
ui/qt/rsc/next_track.png


BIN
ui/qt/rsc/previous_track.jpg


File diff suppressed because it is too large
+ 464 - 641
ui/qt/rsc_rc.py


+ 109 - 0
ui/qt/widgets/tags_table.py

@@ -0,0 +1,109 @@
+from PyQt5.QtCore import pyqtSignal
+from PyQt5.QtWidgets import QTableWidget, QTableWidgetItem, QCheckBox, QTableWidgetSelectionRange, QMessageBox
+
+from core.models import Tag
+from core.repositories import TagRepository
+
+
+class TagsTable(QTableWidget):
+    contentChanged = pyqtSignal()
+    selectionChanged = pyqtSignal()
+
+    def __init__(self, parent=None):
+        super().__init__(parent)
+
+        self.cellChanged.connect(self.tagChanged)
+
+    def populate(self, track=None, selectable=True):
+        self.setColumnHidden(0, True)
+        self.setColumnWidth(1, 45)
+
+        self.cellChanged.disconnect(self.tagChanged)
+        while self.rowCount():
+            self.removeRow(0)
+        super().clear()
+
+        tag_repo = TagRepository()
+        tags = tag_repo.get_all()
+
+        checked = []
+        if track is not None:
+            checked = [t.id for t in tag_repo.get_by_track_id(track.id)]
+
+        if not selectable:
+            self.setColumnHidden(1, True)
+
+        i = 0
+        for tag in tags:
+            self.insertRow(i)
+
+            item = QTableWidgetItem()
+            item.setData(0, tag.id)
+            self.setItem(i, 0, item)
+
+            if selectable:
+                checkBox = QCheckBox()
+                if tag.id in checked:
+                    checkBox.setChecked(True)
+                checkBox.stateChanged.connect(self.selectionChanged.emit)
+                self.setCellWidget(i, 1, checkBox)
+
+            self.setItem(i, 2, QTableWidgetItem(tag.label))
+            i += 1
+
+        self.cellChanged.connect(self.tagChanged)
+
+    def add(self):
+        tag_repo = TagRepository()
+        tag = Tag()
+        tag.label = "Mon étiquette"
+        tag_repo.create(tag, True)
+        self.populate()
+        self.selectTag(tag.id)
+        self.contentChanged.emit()
+
+    def selectTag(self, tag_id):
+        for i in range(self.rowCount()):
+            item = self.item(i, 0)
+            if item.data(0) == tag_id:
+                self.setCurrentItem(item)
+                self.setRangeSelected(QTableWidgetSelectionRange(i, 0, i, 2), True)
+                break
+
+    def removeSelected(self):
+        row = self.currentRow()
+        tag_id = self.item(row, 0).data(0)
+        tag_repo = TagRepository()
+        tag = tag_repo.get_by_id(tag_id)
+        tag_repo.delete(tag, True)
+        self.populate()
+        self.contentChanged.emit()
+
+    def tagChanged(self, row, column):
+        tag_id = self.item(row, 0).data(0)
+
+        if column == 1:
+            # tag has been checked / unchecked
+            print("checked")
+
+        elif column == 2:
+            # tag label has been updated
+            new_label = self.item(row, 2).text()
+            self.tagLabelUpdated(tag_id, new_label)
+
+    def tagLabelUpdated(self, tag_id, new_label):
+        tag_repo = TagRepository()
+        tag = tag_repo.get_by_id(tag_id)
+        tag.label = new_label
+        tag_repo.commit()
+        self.contentChanged.emit()
+
+    def selectedTags(self):
+        selected = []
+        for i in range(self.rowCount()):
+            checked = self.cellWidget(i, 1).isChecked()
+            if checked:
+                tag_id = self.item(i, 0).data(0)
+                selected.append(tag_id)
+        return selected
+

+ 61 - 9
ui/window.py

@@ -8,13 +8,15 @@
 from path import Path
 
 from PyQt5.QtGui import QIcon
-from PyQt5.QtWidgets import QMainWindow, QListWidgetItem, QTableWidgetItem, QFileDialog
+from PyQt5.QtWidgets import QMainWindow, QListWidgetItem, QTableWidgetItem, QFileDialog, QMessageBox
 
 from core.logging_ import Logger
-from core.models import MusicFolder
-from core.repositories import MusicFolderRepository, TrackRepository, SessionTrackRepository, SessionRepository
+from core.models import MusicFolder, TrackTag
+from core.repositories import MusicFolderRepository, TrackRepository, SessionTrackRepository, SessionRepository, \
+    TrackTagRepository
 from ui.qt.dlg_playlist import DlgPlaylist
 from ui.qt.dlg_select_playlist import DlgSelectPlaylist
+from ui.qt.dlg_tag_editor import DlgTagEditor
 from ui.qt.main_ui import Ui_mainWindow
 from ui.qt.widgets.explorertable import ExplorerTable
 from ui.qt.widgets.playlist_table import PlaylistTable
@@ -75,6 +77,9 @@ class MainWindow(QMainWindow):
         self.ui.explorerLineSearch.textChanged.connect(lambda s: (s or self.explorerSearchChanged())) # when search bar is cleared
         self.ui.explorerBtnSearch.clicked.connect(self.explorerSearchChanged)
 
+        # self.ui.btnEditTags.clicked.connect(self.showTagsEditor)
+        self.ui.explorerTrackTagsTable.selectionChanged.connect(self.updateTrackTags)
+
         self.ui.explorerTrackMetaStack.setCurrentIndex(0)
         self.ui.explorerTrackNotepad.textChanged.connect(self.explorerTrackNotesChanged)
         self.ui.explorerTrackPlay.clicked.connect(self.explorerPlaySelected)
@@ -88,11 +93,17 @@ class MainWindow(QMainWindow):
         self.ui.explorerPlaylist.trackDoubleClicked.connect(self.play_playlist)
 
         # Page 5 - settings
-        self.ui.musicFoldersTable.setColumnHidden(0, 1)
+        self.ui.settingsMusicFoldersTable.setColumnHidden(0, 1)
         self.ui.musicFoldersAddButton.clicked.connect(self.add_music_folder)
         self.ui.musicFoldersRemoveButton.clicked.connect(self.remove_music_folder)
         self.populate_music_folders_table()
 
+        self.ui.tagsTableAddButton.clicked.connect(self.addTag)
+        self.ui.tableTagsRemoveButton.clicked.connect(self.removeTag)
+        self.ui.settingsTagsTableWidget.populate(selectable=False)
+
+        self.ui.settingsTagsTableWidget.contentChanged.connect(self.ui.explorerTrackTagsTable.populate)
+
         # vlc frame
         self.ui.vlcFrame.trackStarted.connect(self.vlcTrackStarted)
         self.ui.vlcFrame.playlistEnded.connect(self.vlcPlaylistEnded)
@@ -147,6 +158,8 @@ class MainWindow(QMainWindow):
         self.ui.explorerTrackNotepad.setHtml(track.note)
         self.ui.explorerTrackNotepad.textChanged.connect(self.explorerTrackNotesChanged)
 
+        self.ui.explorerTrackTagsTable.populate(track)
+
         self.ui.explorerTrackMetaStack.setCurrentIndex(1)
         self.ui.explorerTrackPlay.setEnabled(True)
 
@@ -158,22 +171,34 @@ class MainWindow(QMainWindow):
         else:
             raise RuntimeError("Unknown sender")
 
+        self.ui.explorerTable.viewport().repaint()
+        self.ui.explorerPlaylist.viewport().repaint()
+        self.ui.sessionPlaylist.viewport().repaint()
+
     def populate_music_folders_table(self):
         music_folders = MusicFolderRepository().get_all()
-        self.ui.musicFoldersTable.setRowCount(0)
-        self.ui.musicFoldersTable.setRowCount(len(music_folders))
+        self.ui.settingsMusicFoldersTable.setRowCount(0)
+        self.ui.settingsMusicFoldersTable.setRowCount(len(music_folders))
         music_folder_statuses = [
             ('Inconnu', 'status_unknown.png'),
             ('Valide', 'status_found.png'),
             ('Inaccessible', 'status_unavailable.png')
         ]
         for i, music_folder in enumerate(music_folders):
-            self.ui.musicFoldersTable.setItem(i, 0, QTableWidgetItem(music_folder.id))
+            self.ui.settingsMusicFoldersTable.setItem(i, 0, QTableWidgetItem(music_folder.id))
 
             status_lbl, status_pic = music_folder_statuses[music_folder.status]
-            self.ui.musicFoldersTable.setItem(i, 1, QTableWidgetItem(QIcon(status_pic), status_lbl))
+            self.ui.settingsMusicFoldersTable.setItem(i, 1, QTableWidgetItem(QIcon(status_pic), status_lbl))
 
-            self.ui.musicFoldersTable.setItem(i, 2, QTableWidgetItem(music_folder.path))
+            self.ui.settingsMusicFoldersTable.setItem(i, 2, QTableWidgetItem(music_folder.path))
+
+    def addTag(self):
+        self.ui.settingsTagsTableWidget.add()
+
+    def removeTag(self):
+        if QMessageBox.question(self, "Confirmer", "Êtes-vous sûr(e) de vouloir supprimer cette étiquette?") != QMessageBox.Yes:
+            return
+        self.ui.settingsTagsTableWidget.removeSelected()
 
     def explorerPlaySelected(self):
         track = self.ui.explorerTable.selected_track()
@@ -287,6 +312,33 @@ class MainWindow(QMainWindow):
         self.ui.explorerPlaylist.set_is_playing(None)
         self.ui.sessionPlaylist.set_is_playing(None)
 
+    # def showTagsEditor(self):
+    #     track = self.selected_track or None
+    #     tags = DlgTagEditor.select(track, self)
+    #     if tags:
+    #         print(tags)
+
+    def updateTrackTags(self):
+        track_id = self.selected_track.id
+
+        new_tags = self.ui.explorerTrackTagsTable.selectedTags()
+
+        track_tag_repo = TrackTagRepository()
+
+        current_track_tags = [tt.tag_id for tt in track_tag_repo.get_by("track_id", track_id)]
+
+        added = [t for t in new_tags if t not in current_track_tags]
+        removed = [t for t in current_track_tags if t not in new_tags]
+
+        for tag_id in added:
+            tt = TrackTag(track_id=track_id, tag_id=tag_id)
+            track_tag_repo.create(tt)
+
+        for tag_id in removed:
+            track_tag_repo.query().where(TrackTag.track_id == track_id).where(TrackTag.tag_id == tag_id).delete()
+
+        track_tag_repo.commit()
+
     def sessionNotesChanged(self):
         if not self.selected_playlist:
             return

Some files were not shown because too many files changed in this diff