#! /usr/bin/env python3 # -*- coding: utf-8 -*- """ Copyright 2022, Nils Hilbricht, Germany ( https://www.hilbricht.net ) This file is part of the Laborejo Software Suite ( https://www.laborejo.org ), Laborejo2 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ import logging; logger = logging.getLogger(__name__); logger.info("import") #Third Party from PyQt5 import QtCore, QtGui, QtWidgets #Template Modules #Our Modules import engine.api as api class TrackListWidget(QtWidgets.QListWidget): """The TrackListWidget holds all tracks as text-only variants with cursor access. It will show one track at a time, the current one. It is meant as alternative access for hard-to-reach items, such as zero-duration-items. The cursor decides which track is currently handled as items. But track content changes can come it for any track at any time. In opposite to the ScoreScene we do not deal with deleted and hidden tracks. We recreate the items on track change. """ def __init__(self, mainWindow, parentSplitter): super().__init__(parentSplitter) self.mainWindow = mainWindow self._lastCurrentTrack = None self.tracks = {} # engineTrackId : engineExportData self.itemPressed.connect(self._react_itemPressed) api.callbacks.tracksChanged.append(self.syncTracks) api.callbacks.updateTrack.append(self.updateTrack) api.callbacks.setCursor.append(self.setCursor) def setCursor(self, cursorExportObject): if not self._lastCurrentTrack == cursorExportObject["trackId"]: self._lastCurrentTrack == cursorExportObject["trackId"] self.showTrack(cursorExportObject["trackId"]) self.blockSignals(True) self.setCurrentRow(cursorExportObject["position"]) self.blockSignals(False) def _react_itemPressed(self, item): """This is gui->api cursor setting It only happens when the mouse etc. actually pressed an item. This list cannot be activated by cursor keys etc. directly. """ api.toPosition(self.currentRow()) #currentRow is calculated after we already are on the item. def syncTracks(self, listOfStaticTrackRepresentations): """Handles the number of tracks and track meta-data changes, but not track contents, which is handled by self.updateTrack through a different callback""" for trackExportObject in listOfStaticTrackRepresentations: if not trackExportObject["id"] in self.tracks: self.tracks[trackExportObject["id"]] = None def updateTrack(self, trackId, staticRepresentationList): """Callback: The content of a single track has changed""" if not trackId in self.tracks: #hidden track. But this can still happen through the data editor return self.tracks[trackId] = staticRepresentationList if trackId == self._lastCurrentTrack: self.showTrack(trackId) def showTrack(self, trackId): """Cursor moved to a different track. This is essentially destroy-and-recreate in Qt """ self.clear() staticRepresentationList = self.tracks[trackId] count = 0 for staticItem in staticRepresentationList: self.addItem(staticItem["UIstring"]) self.addItem("|") #Appending