explorertable.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. from PyQt5.QtCore import pyqtSignal
  2. from PyQt5.QtGui import QIcon, QBrush, QColor
  3. from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QTreeWidgetItemIterator
  4. from core import db
  5. from core.logging_ import Logger
  6. from core.repositories import TrackRepository
  7. from core.utils import norm_search
  8. logger = Logger.get()
  9. class ExplorerTable(QTreeWidget):
  10. trackSelected = pyqtSignal(object)
  11. trackDoubleClicked = pyqtSignal(object)
  12. def __init__(self, parent):
  13. super(QTreeWidget, self).__init__(parent)
  14. self.setColumnCount(3)
  15. self.setColumnWidth(0, 54)
  16. self.hideColumn(2)
  17. self.itemDoubleClicked.connect(self._itemDoubleClicked)
  18. self.artist_items, self.album_items, self.track_items = {}, {}, {}
  19. def populate(self):
  20. session = db.Session()
  21. track_repo = TrackRepository(session)
  22. self.clear()
  23. self.artist_items, self.album_items, self.track_items = {}, {}, {}
  24. tracks = track_repo.get_all()
  25. self.setUpdatesEnabled(False)
  26. self.update_tracks(tracks)
  27. self.setUpdatesEnabled(True)
  28. self.trackSelected.emit(None)
  29. def update_tracks(self, tracks):
  30. for track in tracks:
  31. if track.artist and track.artist not in self.artist_items:
  32. item = QTreeWidgetItem(self)
  33. item.setIcon(0, QIcon(":/img/rsc/artist.png"))
  34. item.setText(1, track.artist)
  35. self.artist_items[track.artist] = item
  36. for track in tracks:
  37. # list albums with artists
  38. if track.artist and track.album and (track.artist, track.album) not in self.album_items:
  39. item = QTreeWidgetItem(self.artist_items[track.artist])
  40. item.setIcon(0, QIcon(":/img/rsc/album.png"))
  41. item.setText(1, track.album)
  42. self.album_items[(track.artist, track.album)] = item
  43. for track in tracks:
  44. if track.id not in self.track_items:
  45. if track.artist and track.album:
  46. parent = self.album_items[(track.artist, track.album)]
  47. elif track.artist:
  48. parent = self.artist_items[track.artist]
  49. else:
  50. parent = self
  51. item = QTreeWidgetItem(parent)
  52. item.setIcon(0, QIcon(":/img/rsc/music.png"))
  53. item.setData(2, 0, track.id)
  54. self.track_items[track.id] = item
  55. if track.status != track.STATUS_UNAVAILABLE:
  56. title = track.title
  57. color = QColor(20, 20, 20)
  58. else:
  59. title = f"[Introuvable] {track.title}"
  60. color = QColor(200, 20, 20)
  61. self.track_items[track.id].setText(1, title)
  62. self.track_items[track.id].setForeground(0, QBrush(color))
  63. self.track_items[track.id].setForeground(1, QBrush(color))
  64. def selected_track(self):
  65. track_id = self.selectionModel().selection().indexes()[2].data(2)
  66. if not track_id:
  67. return None
  68. return TrackRepository().get_by_id(int(track_id))
  69. def selectionChanged(self, selected, _):
  70. try:
  71. track_id = selected.indexes()[2].data(2)
  72. except IndexError:
  73. return
  74. if track_id:
  75. track = TrackRepository().get_by_id(int(track_id))
  76. else:
  77. track = None
  78. self.trackSelected.emit(track)
  79. def _itemDoubleClicked(self, item, _):
  80. track_id = item.data(2, 0)
  81. if track_id:
  82. track = TrackRepository().get_by_id(int(track_id))
  83. self.trackDoubleClicked.emit(track)
  84. def filterBy(self, tag_id=None, searchText=""):
  85. track_ids = []
  86. if tag_id:
  87. track_repo = TrackRepository()
  88. track_ids = [t.id for t in track_repo.get_by_tag_id(tag_id)]
  89. searchText = norm_search(searchText)
  90. self.setUpdatesEnabled(False)
  91. iterator = QTreeWidgetItemIterator(self)
  92. while True:
  93. item = iterator.value()
  94. if item is not None:
  95. if not item.data(2, 0):
  96. # not a track
  97. item.setHidden(True)
  98. iterator += 1
  99. continue
  100. track_item = item
  101. parent_item = item.parent()
  102. grand_parent_item = parent_item.parent() if parent_item else None
  103. keys = [track_item.text(1)]
  104. if parent_item:
  105. keys.append(parent_item.text(1))
  106. if grand_parent_item:
  107. keys.append(grand_parent_item.text(1))
  108. s = norm_search(" ".join(keys))
  109. hide = (searchText and searchText not in s) \
  110. or (tag_id and item.data(2, 0) not in track_ids)
  111. track_item.setHidden(hide)
  112. iterator += 1
  113. else:
  114. break
  115. iterator = QTreeWidgetItemIterator(self)
  116. while True:
  117. item = iterator.value()
  118. if item is not None:
  119. if not item.data(2, 0) or item.isHidden():
  120. # not a track or hidden
  121. iterator += 1
  122. continue
  123. if item.parent():
  124. item.parent().setHidden(False)
  125. if item.parent() and item.parent().parent():
  126. item.parent().parent().setHidden(False)
  127. iterator += 1
  128. else:
  129. break
  130. if searchText:
  131. self.expandAll()
  132. else:
  133. self.collapseAll()
  134. self.setUpdatesEnabled(True)