undoable removeComponent action
This commit is contained in:
parent
a327bec4e4
commit
733c005eea
|
@ -19,6 +19,7 @@ class Command(QtCore.QObject):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
QtCore.QObject.__init__(self)
|
QtCore.QObject.__init__(self)
|
||||||
self.core = Core()
|
self.core = Core()
|
||||||
|
Core.mode = 'commandline'
|
||||||
self.dataDir = self.core.dataDir
|
self.dataDir = self.core.dataDir
|
||||||
self.canceled = False
|
self.canceled = False
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,8 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
||||||
'''Intercepts the command() method to check for global args'''
|
'''Intercepts the command() method to check for global args'''
|
||||||
def commandWrapper(self, arg):
|
def commandWrapper(self, arg):
|
||||||
if arg.startswith('preset='):
|
if arg.startswith('preset='):
|
||||||
from presetmanager import getPresetDir
|
|
||||||
_, preset = arg.split('=', 1)
|
_, preset = arg.split('=', 1)
|
||||||
path = os.path.join(getPresetDir(self), preset)
|
path = os.path.join(self.core.getPresetDir(self), preset)
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
print('Couldn\'t locate preset "%s"' % preset)
|
print('Couldn\'t locate preset "%s"' % preset)
|
||||||
quit(1)
|
quit(1)
|
||||||
|
|
36
src/core.py
36
src/core.py
|
@ -64,31 +64,39 @@ class Core:
|
||||||
for i, component in enumerate(self.selectedComponents):
|
for i, component in enumerate(self.selectedComponents):
|
||||||
component.compPos = i
|
component.compPos = i
|
||||||
|
|
||||||
def insertComponent(self, compPos, moduleIndex, loader):
|
def insertComponent(self, compPos, component, loader):
|
||||||
'''
|
'''
|
||||||
Creates a new component using these args:
|
Creates a new component using these args:
|
||||||
(compPos, moduleIndex in self.modules, MWindow/Command/Core obj)
|
(compPos, component obj or moduleIndex, MWindow/Command/Core obj)
|
||||||
'''
|
'''
|
||||||
if compPos < 0 or compPos > len(self.selectedComponents):
|
if compPos < 0 or compPos > len(self.selectedComponents):
|
||||||
compPos = len(self.selectedComponents)
|
compPos = len(self.selectedComponents)
|
||||||
if len(self.selectedComponents) > 50:
|
if len(self.selectedComponents) > 50:
|
||||||
return None
|
return None
|
||||||
log.debug('Inserting Component from module #%s' % moduleIndex)
|
if type(component) is int:
|
||||||
component = self.modules[moduleIndex].Component(
|
# create component using module index in self.modules
|
||||||
moduleIndex, compPos, self
|
moduleIndex = int(component)
|
||||||
|
log.debug('Creating new component from module #%s' % moduleIndex)
|
||||||
|
component = self.modules[moduleIndex].Component(
|
||||||
|
moduleIndex, compPos, self
|
||||||
|
)
|
||||||
|
# init component's widget for loading/saving presets
|
||||||
|
component.widget(loader)
|
||||||
|
else:
|
||||||
|
moduleIndex = -1
|
||||||
|
log.debug(
|
||||||
|
'Inserting previously-created %s component' % component.name)
|
||||||
|
|
||||||
|
component._error.connect(
|
||||||
|
loader.videoThreadError
|
||||||
)
|
)
|
||||||
self.selectedComponents.insert(
|
self.selectedComponents.insert(
|
||||||
compPos,
|
compPos,
|
||||||
component
|
component
|
||||||
)
|
)
|
||||||
self.componentListChanged()
|
self.componentListChanged()
|
||||||
self.selectedComponents[compPos]._error.connect(
|
if moduleIndex > -1:
|
||||||
loader.videoThreadError
|
self.updateComponent(compPos)
|
||||||
)
|
|
||||||
|
|
||||||
# init component's widget for loading/saving presets
|
|
||||||
self.selectedComponents[compPos].widget(loader)
|
|
||||||
self.updateComponent(compPos)
|
|
||||||
|
|
||||||
if hasattr(loader, 'insertComponent'):
|
if hasattr(loader, 'insertComponent'):
|
||||||
loader.insertComponent(compPos)
|
loader.insertComponent(compPos)
|
||||||
|
@ -156,6 +164,10 @@ class Core:
|
||||||
break
|
break
|
||||||
return saveValueStore
|
return saveValueStore
|
||||||
|
|
||||||
|
def getPresetDir(self, comp):
|
||||||
|
'''Get the preset subdir for a particular version of a component'''
|
||||||
|
return os.path.join(Core.presetDir, str(comp), str(comp.version))
|
||||||
|
|
||||||
def openProject(self, loader, filepath):
|
def openProject(self, loader, filepath):
|
||||||
''' loader is the object calling this method which must have
|
''' loader is the object calling this method which must have
|
||||||
its own showMessage(**kwargs) method for displaying errors.
|
its own showMessage(**kwargs) method for displaying errors.
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
'''
|
||||||
|
QCommand classes for every undoable user action performed in the MainWindow
|
||||||
|
'''
|
||||||
|
from PyQt5.QtWidgets import QUndoCommand
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveComponent(QUndoCommand):
|
||||||
|
def __init__(self, parent, selectedRows):
|
||||||
|
super().__init__('Remove component')
|
||||||
|
self.parent = parent
|
||||||
|
componentList = self.parent.window.listWidget_componentList
|
||||||
|
self.selectedRows = [
|
||||||
|
componentList.row(selected) for selected in selectedRows
|
||||||
|
]
|
||||||
|
self.components = [
|
||||||
|
parent.core.selectedComponents[i] for i in self.selectedRows
|
||||||
|
]
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
def undo(self):
|
||||||
|
componentList = self.parent.window.listWidget_componentList
|
||||||
|
for index, comp in zip(self.selectedRows, self.components):
|
||||||
|
self.parent.core.insertComponent(
|
||||||
|
index, comp, self.parent
|
||||||
|
)
|
||||||
|
self.parent.drawPreview()
|
||||||
|
|
|
@ -16,9 +16,10 @@ import time
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from core import Core
|
from core import Core
|
||||||
import preview_thread
|
import gui.preview_thread as preview_thread
|
||||||
from preview_win import PreviewWindow
|
from gui.preview_win import PreviewWindow
|
||||||
from presetmanager import PresetManager
|
from gui.presetmanager import PresetManager
|
||||||
|
from gui.actions import *
|
||||||
from toolkit import disableWhenEncoding, disableWhenOpeningProject, checkOutput
|
from toolkit import disableWhenEncoding, disableWhenOpeningProject, checkOutput
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,9 +44,12 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
QtWidgets.QMainWindow.__init__(self)
|
QtWidgets.QMainWindow.__init__(self)
|
||||||
self.window = window
|
self.window = window
|
||||||
self.core = Core()
|
self.core = Core()
|
||||||
|
Core.mode = 'GUI'
|
||||||
log.debug(
|
log.debug(
|
||||||
'Main thread id: {}'.format(int(QtCore.QThread.currentThreadId())))
|
'Main thread id: {}'.format(int(QtCore.QThread.currentThreadId())))
|
||||||
|
|
||||||
|
self.undoStack = QtWidgets.QUndoStack(self)
|
||||||
|
|
||||||
# widgets of component settings
|
# widgets of component settings
|
||||||
self.pages = []
|
self.pages = []
|
||||||
self.lastAutosave = time.time()
|
self.lastAutosave = time.time()
|
||||||
|
@ -62,7 +66,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
self.presetManager = PresetManager(
|
self.presetManager = PresetManager(
|
||||||
uic.loadUi(
|
uic.loadUi(
|
||||||
os.path.join(Core.wd, 'presetmanager.ui')), self)
|
os.path.join(Core.wd, 'gui', 'presetmanager.ui')), self)
|
||||||
|
|
||||||
# Create the preview window and its thread, queues, and timers
|
# Create the preview window and its thread, queues, and timers
|
||||||
log.debug('Creating preview window')
|
log.debug('Creating preview window')
|
||||||
|
@ -298,6 +302,9 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
QtWidgets.QShortcut("Ctrl+A", self.window, self.openSaveProjectDialog)
|
QtWidgets.QShortcut("Ctrl+A", self.window, self.openSaveProjectDialog)
|
||||||
QtWidgets.QShortcut("Ctrl+O", self.window, self.openOpenProjectDialog)
|
QtWidgets.QShortcut("Ctrl+O", self.window, self.openOpenProjectDialog)
|
||||||
QtWidgets.QShortcut("Ctrl+N", self.window, self.createNewProject)
|
QtWidgets.QShortcut("Ctrl+N", self.window, self.createNewProject)
|
||||||
|
QtWidgets.QShortcut("Ctrl+Z", self.window, self.undoStack.undo)
|
||||||
|
QtWidgets.QShortcut("Ctrl+Y", self.window, self.undoStack.redo)
|
||||||
|
QtWidgets.QShortcut("Ctrl+Shift+Z", self.window, self.undoStack.redo)
|
||||||
|
|
||||||
# Hotkeys for component list
|
# Hotkeys for component list
|
||||||
for inskey in ("Ctrl+T", QtCore.Qt.Key_Insert):
|
for inskey in ("Ctrl+T", QtCore.Qt.Key_Insert):
|
||||||
|
@ -685,15 +692,10 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
def removeComponent(self):
|
def removeComponent(self):
|
||||||
componentList = self.window.listWidget_componentList
|
componentList = self.window.listWidget_componentList
|
||||||
|
selected = componentList.selectedItems()
|
||||||
for selected in componentList.selectedItems():
|
if selected:
|
||||||
index = componentList.row(selected)
|
action = RemoveComponent(self, selected)
|
||||||
self.window.stackedWidget.removeWidget(self.pages[index])
|
self.undoStack.push(action)
|
||||||
componentList.takeItem(index)
|
|
||||||
self.core.removeComponent(index)
|
|
||||||
self.pages.pop(index)
|
|
||||||
self.changeComponentWidget()
|
|
||||||
self.drawPreview()
|
|
||||||
|
|
||||||
@disableWhenEncoding
|
@disableWhenEncoding
|
||||||
def moveComponent(self, change):
|
def moveComponent(self, change):
|
||||||
|
|
|
@ -302,7 +302,7 @@ class PresetManager(QtWidgets.QDialog):
|
||||||
self.findPresets()
|
self.findPresets()
|
||||||
self.drawPresetList()
|
self.drawPresetList()
|
||||||
for i, comp in enumerate(self.core.selectedComponents):
|
for i, comp in enumerate(self.core.selectedComponents):
|
||||||
if getPresetDir(comp) == path \
|
if self.core.getPresetDir(comp) == path \
|
||||||
and comp.currentPreset == oldName:
|
and comp.currentPreset == oldName:
|
||||||
self.core.openPreset(newPath, i, newName)
|
self.core.openPreset(newPath, i, newName)
|
||||||
self.parent.updateComponentTitle(i, False)
|
self.parent.updateComponentTitle(i, False)
|
||||||
|
@ -351,8 +351,3 @@ class PresetManager(QtWidgets.QDialog):
|
||||||
|
|
||||||
def clearPresetListSelection(self):
|
def clearPresetListSelection(self):
|
||||||
self.window.listWidget_presets.setCurrentRow(-1)
|
self.window.listWidget_presets.setCurrentRow(-1)
|
||||||
|
|
||||||
|
|
||||||
def getPresetDir(comp):
|
|
||||||
'''Get the preset subdir for a particular version of a component'''
|
|
||||||
return os.path.join(Core.presetDir, str(comp), str(comp.version))
|
|
||||||
|
|
|
@ -35,11 +35,11 @@ def main():
|
||||||
log.debug("Finished creating command object")
|
log.debug("Finished creating command object")
|
||||||
|
|
||||||
elif mode == 'GUI':
|
elif mode == 'GUI':
|
||||||
from mainwindow import MainWindow
|
from gui.mainwindow import MainWindow
|
||||||
import atexit
|
import atexit
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
window = uic.loadUi(os.path.join(wd, "mainwindow.ui"))
|
window = uic.loadUi(os.path.join(wd, "gui", "mainwindow.ui"))
|
||||||
# window.adjustSize()
|
# window.adjustSize()
|
||||||
desc = QtWidgets.QDesktopWidget()
|
desc = QtWidgets.QDesktopWidget()
|
||||||
dpi = desc.physicalDpiX()
|
dpi = desc.physicalDpiX()
|
||||||
|
|
Reference in New Issue