From 2a51e47a09a42a840b76fa7eea8bf013c61cfaa9 Mon Sep 17 00:00:00 2001 From: Nils Date: Mon, 1 Aug 2022 17:17:25 +0200 Subject: [PATCH] Add context menu to move CC Blocks to start or end of a track --- CHANGELOG | 4 ++- engine/api.py | 53 ++++++++++++++++++++++++++++++++++++++++ qtgui/graphs.py | 21 ++++++++++------ qtgui/musicstructures.py | 1 + 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 55ff374..b1855fc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,14 +6,16 @@ External contributors notice at the end of the line: (LastName, FirstName / nick ## 2022-10-15 2.2.0 -Add SOLO functionality alongside the existing audible/mute layer. Control via shortcuts, track editor, or track list widget +Add SOLO functionality alongside the existing audible/mute layer. Control via shortcuts, track editor, or track-list widget New function to create a new empty block from an existing one, that has reserved duration same as the original one. Add more time signatures to the quick-insert dialog: 8/4, three variants of 7/8, two variants of 5/4 and more. Also reorder and better labels. +Add context menu to move CC Blocks to start or end of a track Fix splitting of notes that were created by a previous split. Block Mode: Fix invisible block labels and graphics when dragging blocks (adopting to unannounced Qt regressions once again) Barlines more visible Undo for initial metrical instruction and key sig (track editor) Prevent block operations to jump to the cursor position in the GUI. Less jumpy. +Show first block name in track-list widget Various small fixes, like typos in variable names and wrong string quotes. Small things can crash as well. Lilypond: Add transposition of the whole score to properties and metadata dialog diff --git a/engine/api.py b/engine/api.py index 0c74710..b0ffa0e 100644 --- a/engine/api.py +++ b/engine/api.py @@ -2409,6 +2409,59 @@ def mergeWithNextGraphBlock(graphBlockId): callbacks._historyChanged() callbacks._updateGraphTrackCC(trId, cc) +def moveCCBlockToStartOfTrack(graphBlockId): + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + listOfBlockIds = ccTrack.asListOfBlockIds() + listOfBlockIds.pop(listOfBlockIds.index(graphBlockId)) #will succeed or raise ValueError. + listOfBlockIds.insert(0, graphBlockId) + rearrangeCCBlocks(trId, cc, listOfBlockIds) #does undo and callbacks + +def moveCCBlockToEndOfTrack(graphBlockId): + trId, cc, graphBlock = session.data.graphBlockById(graphBlockId) + ccTrack = session.data.trackById(trId).ccGraphTracks[cc] + listOfBlockIds = ccTrack.asListOfBlockIds() + listOfBlockIds.pop(listOfBlockIds.index(graphBlockId)) #will succeed or raise ValueError. + listOfBlockIds.append(graphBlockId) + rearrangeCCBlocks(trId, cc, listOfBlockIds) #does undo and callbacks + + +def moveBlockToEndOfTrack(blockId): + """Get a list of all blocks. Take the given one and place it at the end. + This is a high level function using rearrangeBlocks(), which does all the callbacks and + history""" + + track, block = session.data.blockById(blockId) + + currentBlockOrder = track.asListOfBlockIds() + + if len(currentBlockOrder) == 1: + return + + assert currentBlockOrder.count(blockId) == 1 + currentBlockOrder.remove(blockId) #modifies list in place + currentBlockOrder.append(blockId) + + rearrangeBlocks(id(track), currentBlockOrder) + +def moveBlockToStartOfTrack(blockId): + """Like moveBlockToEndOfTrack, but to the start""" + + track, block = session.data.blockById(blockId) + + currentBlockOrder = track.asListOfBlockIds() + + if len(currentBlockOrder) == 1: + return + + assert currentBlockOrder.count(blockId) == 1 + currentBlockOrder.remove(blockId) #modifies list in place + currentBlockOrder.insert(0, blockId) + + rearrangeBlocks(id(track), currentBlockOrder) + + + ##CC Blocks and User Points def addGraphItem(blockId, positionInTicksRelativeToBlock, newCCValue): diff --git a/qtgui/graphs.py b/qtgui/graphs.py index d3d9540..97062d5 100644 --- a/qtgui/graphs.py +++ b/qtgui/graphs.py @@ -21,6 +21,9 @@ along with this program. If not, see . import logging; logger = logging.getLogger(__name__); logger.info("import") from PyQt5 import QtCore, QtGui, QtSvg, QtWidgets +translate = QtCore.QCoreApplication.translate + + from .constantsAndConfigs import constantsAndConfigs from template.qtgui.helper import stringToColor, removeInstancesFromScene, callContextMenu, stretchLine, stretchRect import engine.api as api @@ -331,15 +334,19 @@ class CCGraphTransparentBlock(QtWidgets.QGraphicsRectItem): def contextMenuEvent(self, event): listOfLabelsAndFunctions = [ - ("split here", lambda: self.splitHere(event)), - ("duplicate", lambda: api.duplicateCCBlock(self.staticExportItem["id"])), - ("create content link", lambda: api.duplicateContentLinkCCBlock(self.staticExportItem["id"])), - ("unlink", lambda: api.unlinkCCBlock(self.staticExportItem["id"])), + (translate("ccblock", "split here"), lambda: self.splitHere(event)), + (translate("ccblock", "duplicate"), lambda: api.duplicateCCBlock(self.staticExportItem["id"])), + (translate("ccblock", "create content link"), lambda: api.duplicateContentLinkCCBlock(self.staticExportItem["id"])), + (translate("ccblock", "unlink"), lambda: api.unlinkCCBlock(self.staticExportItem["id"])), + ("separator", None), + (translate("ccblock", "move to start"), lambda: api.moveCCBlockToStartOfTrack(self.staticExportItem["id"])), + (translate("ccblock", "move to end"), lambda: api.moveCCBlockToEndOfTrack(self.staticExportItem["id"])), + ("separator", None), - ("join with next block", lambda: api.mergeWithNextGraphBlock(self.staticExportItem["id"])), - ("delete block", lambda: api.deleteCCBlock(self.staticExportItem["id"])), + (translate("ccblock", "join with next block"), lambda: api.mergeWithNextGraphBlock(self.staticExportItem["id"])), + (translate("ccblock", "delete block"), lambda: api.deleteCCBlock(self.staticExportItem["id"])), ("separator", None), - ("append block at the end", lambda ccNum = self.parentCCPath.getCCNumber(): api.appendGraphBlock(self.parentCCPath.parentDataTrackId, ccNum)), + (translate("ccblock", "append block at the end"), lambda ccNum = self.parentCCPath.getCCNumber(): api.appendGraphBlock(self.parentCCPath.parentDataTrackId, ccNum)), ] callContextMenu(listOfLabelsAndFunctions) diff --git a/qtgui/musicstructures.py b/qtgui/musicstructures.py index c3d647a..81553d8 100644 --- a/qtgui/musicstructures.py +++ b/qtgui/musicstructures.py @@ -178,6 +178,7 @@ class GuiBlockHandle(QtWidgets.QGraphicsRectItem): (translate("musicstructures", "duplicate to reserved empty"), lambda: api.duplicateToReservedSpaceBlock(self.staticExportItem["id"])), (translate("musicstructures", "create content link"), lambda: api.duplicateContentLinkBlock(self.staticExportItem["id"])), (translate("musicstructures", "unlink"), lambda: api.unlinkBlock(self.staticExportItem["id"])), + ("separator", None), (translate("musicstructures", "move to start"), lambda: api.moveBlockToStartOfTrack(self.staticExportItem["id"])), (translate("musicstructures", "move to end"), lambda: api.moveBlockToEndOfTrack(self.staticExportItem["id"])), ("separator", None),