undoable add-comp & clear-preset actions
This commit is contained in:
parent
f66ec40ba6
commit
c06ca5cdcb
|
@ -99,6 +99,23 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
return func(self)
|
||||
return errorWrapper
|
||||
|
||||
def presetWrapper(func):
|
||||
'''Wraps loadPreset to handle the self.openingPreset boolean'''
|
||||
class openingPreset:
|
||||
def __init__(self, comp):
|
||||
self.comp = comp
|
||||
|
||||
def __enter__(self):
|
||||
self.comp.openingPreset = True
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.comp.openingPreset = False
|
||||
|
||||
def presetWrapper(self, *args):
|
||||
with openingPreset(self):
|
||||
return func(self, *args)
|
||||
return presetWrapper
|
||||
|
||||
def __new__(cls, name, parents, attrs):
|
||||
if 'ui' not in attrs:
|
||||
# Use module name as ui filename by default
|
||||
|
@ -111,7 +128,7 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
'names', # Class methods
|
||||
'error', 'audio', 'properties', # Properties
|
||||
'preFrameRender', 'previewRender',
|
||||
'frameRender', 'command',
|
||||
'frameRender', 'command', 'loadPreset'
|
||||
)
|
||||
|
||||
# Auto-decorate methods
|
||||
|
@ -140,6 +157,9 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
if key == 'error':
|
||||
attrs[key] = cls.errorWrapper(attrs[key])
|
||||
|
||||
if key == 'loadPreset':
|
||||
attrs[key] = cls.presetWrapper(attrs[key])
|
||||
|
||||
# Turn version string into a number
|
||||
try:
|
||||
if 'version' not in attrs:
|
||||
|
@ -180,6 +200,7 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
self.compPos = compPos
|
||||
self.core = core
|
||||
self.currentPreset = None
|
||||
self.openingPreset = False
|
||||
|
||||
self._trackedWidgets = {}
|
||||
self._presetNames = {}
|
||||
|
@ -207,7 +228,10 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
preset = self.savePreset()
|
||||
except Exception as e:
|
||||
preset = '%s occurred while saving preset' % str(e)
|
||||
return '%s\n%s\n%s' % (
|
||||
|
||||
return 'Component(%s, %s, Core)\n' \
|
||||
'Name: %s v%s\n Preset: %s' % (
|
||||
self.moduleIndex, self.compPos,
|
||||
self.__class__.name, str(self.__class__.version), preset
|
||||
)
|
||||
|
||||
|
@ -308,6 +332,9 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
A component update triggered by the user changing a widget value
|
||||
Call super() at the END when subclassing this.
|
||||
'''
|
||||
if self.openingPreset or not hasattr(self.parent, 'undoStack'):
|
||||
return self._update()
|
||||
|
||||
oldWidgetVals = {
|
||||
attr: getattr(self, attr)
|
||||
for attr in self._trackedWidgets
|
||||
|
@ -328,7 +355,7 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
self.parent.undoStack.push(action)
|
||||
|
||||
def _update(self):
|
||||
'''An internal component update that is not undoable'''
|
||||
'''A component update that is not undoable'''
|
||||
|
||||
newWidgetVals = {
|
||||
attr: getWidgetValue(widget)
|
||||
|
@ -684,7 +711,7 @@ class ComponentUpdate(QtWidgets.QUndoCommand):
|
|||
self.id_ = -1
|
||||
if len(self.modifiedVals) == 1:
|
||||
attr, val = self.modifiedVals.popitem()
|
||||
self.id_ = sum([ord(letter) for letter in attr[:14]])
|
||||
self.id_ = sum([ord(letter) for letter in attr[-14:]])
|
||||
self.modifiedVals[attr] = val
|
||||
else:
|
||||
log.warning(
|
||||
|
|
|
@ -4,6 +4,23 @@
|
|||
from PyQt5.QtWidgets import QUndoCommand
|
||||
|
||||
|
||||
class AddComponent(QUndoCommand):
|
||||
def __init__(self, parent, compI, moduleI):
|
||||
super().__init__(
|
||||
"New %s component" %
|
||||
parent.core.modules[moduleI].Component.name
|
||||
)
|
||||
self.parent = parent
|
||||
self.moduleI = moduleI
|
||||
self.compI = compI
|
||||
|
||||
def redo(self):
|
||||
self.parent.core.insertComponent(self.compI, self.moduleI, self.parent)
|
||||
|
||||
def undo(self):
|
||||
self.parent._removeComponent(self.compI)
|
||||
|
||||
|
||||
class RemoveComponent(QUndoCommand):
|
||||
def __init__(self, parent, selectedRows):
|
||||
super().__init__('Remove component')
|
||||
|
@ -17,15 +34,7 @@ class RemoveComponent(QUndoCommand):
|
|||
]
|
||||
|
||||
def redo(self):
|
||||
stackedWidget = self.parent.window.stackedWidget
|
||||
componentList = self.parent.window.listWidget_componentList
|
||||
for index in self.selectedRows:
|
||||
stackedWidget.removeWidget(self.parent.pages[index])
|
||||
componentList.takeItem(index)
|
||||
self.parent.core.removeComponent(index)
|
||||
self.parent.pages.pop(index)
|
||||
self.parent.changeComponentWidget()
|
||||
self.parent.drawPreview()
|
||||
self.parent._removeComponent(self.selectedRows[0])
|
||||
|
||||
def undo(self):
|
||||
componentList = self.parent.window.listWidget_componentList
|
||||
|
@ -74,3 +83,21 @@ class MoveComponent(QUndoCommand):
|
|||
|
||||
def undo(self):
|
||||
self.do(self.newRow, self.row)
|
||||
|
||||
|
||||
class ClearPreset(QUndoCommand):
|
||||
def __init__(self, parent, compI):
|
||||
super().__init__("Clear preset")
|
||||
self.parent = parent
|
||||
self.compI = compI
|
||||
self.component = self.parent.core.selectedComponents[compI]
|
||||
self.store = self.component.savePreset()
|
||||
self.store['preset'] = self.component.currentPreset
|
||||
|
||||
def redo(self):
|
||||
self.parent.core.clearPreset(self.compI)
|
||||
self.parent.updateComponentTitle(self.compI, False)
|
||||
|
||||
def undo(self):
|
||||
self.parent.core.selectedComponents[self.compI].loadPreset(self.store)
|
||||
self.parent.updateComponentTitle(self.compI, self.store)
|
||||
|
|
|
@ -20,7 +20,9 @@ import gui.preview_thread as preview_thread
|
|||
from gui.preview_win import PreviewWindow
|
||||
from gui.presetmanager import PresetManager
|
||||
from gui.actions import *
|
||||
from toolkit import disableWhenEncoding, disableWhenOpeningProject, checkOutput
|
||||
from toolkit import (
|
||||
disableWhenEncoding, disableWhenOpeningProject, checkOutput, blockSignals
|
||||
)
|
||||
|
||||
|
||||
log = logging.getLogger('AVP.MainWindow')
|
||||
|
@ -165,7 +167,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
for i, comp in enumerate(self.core.modules):
|
||||
action = self.compMenu.addAction(comp.Component.name)
|
||||
action.triggered.connect(
|
||||
lambda _, item=i: self.core.insertComponent(0, item, self)
|
||||
lambda _, item=i: self.addComponent(0, item)
|
||||
)
|
||||
|
||||
self.window.pushButton_addComponent.setMenu(self.compMenu)
|
||||
|
@ -686,7 +688,13 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
msg="Current FFmpeg command:\n\n %s" % " ".join(lines)
|
||||
)
|
||||
|
||||
def addComponent(self, compPos, moduleIndex):
|
||||
'''Creates an undoable action that adds a new component.'''
|
||||
action = AddComponent(self, compPos, moduleIndex)
|
||||
self.undoStack.push(action)
|
||||
|
||||
def insertComponent(self, index):
|
||||
'''Triggered by Core to finish initializing a new component.'''
|
||||
componentList = self.window.listWidget_componentList
|
||||
stackedWidget = self.window.stackedWidget
|
||||
|
||||
|
@ -712,6 +720,16 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
action = RemoveComponent(self, selected)
|
||||
self.undoStack.push(action)
|
||||
|
||||
def _removeComponent(self, index):
|
||||
stackedWidget = self.window.stackedWidget
|
||||
componentList = self.window.listWidget_componentList
|
||||
stackedWidget.removeWidget(self.pages[index])
|
||||
componentList.takeItem(index)
|
||||
self.core.removeComponent(index)
|
||||
self.pages.pop(index)
|
||||
self.changeComponentWidget()
|
||||
self.drawPreview()
|
||||
|
||||
@disableWhenEncoding
|
||||
def moveComponent(self, change):
|
||||
'''Moves a component relatively from its current position'''
|
||||
|
@ -786,9 +804,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
self.window.lineEdit_audioFile,
|
||||
self.window.lineEdit_outputFile
|
||||
):
|
||||
field.blockSignals(True)
|
||||
field.setText('')
|
||||
field.blockSignals(False)
|
||||
with blockSignals(field):
|
||||
field.setText('')
|
||||
self.progressBarUpdated(0)
|
||||
self.progressBarSetText('')
|
||||
self.undoStack.clear()
|
||||
|
@ -938,8 +955,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
for i, comp in enumerate(self.core.modules):
|
||||
menuItem = self.submenu.addAction(comp.Component.name)
|
||||
menuItem.triggered.connect(
|
||||
lambda _, item=i: self.core.insertComponent(
|
||||
0 if insertCompAtTop else index, item, self
|
||||
lambda _, item=i: self.addComponent(
|
||||
0 if insertCompAtTop else index, item
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import os
|
|||
|
||||
from toolkit import badName
|
||||
from core import Core
|
||||
from gui.actions import *
|
||||
|
||||
|
||||
class PresetManager(QtWidgets.QDialog):
|
||||
|
@ -130,8 +131,8 @@ class PresetManager(QtWidgets.QDialog):
|
|||
def clearPreset(self, compI=None):
|
||||
'''Functions on mainwindow level from the context menu'''
|
||||
compI = self.parent.window.listWidget_componentList.currentRow()
|
||||
self.core.clearPreset(compI)
|
||||
self.parent.updateComponentTitle(compI, False)
|
||||
action = ClearPreset(self.parent, compI)
|
||||
self.parent.undoStack.push(action)
|
||||
|
||||
def openSavePresetDialog(self):
|
||||
'''Functions on mainwindow level from the context menu'''
|
||||
|
|
Reference in New Issue