undoable removeComponent action

This commit is contained in:
tassaron 2017-08-14 18:41:45 -04:00
parent a327bec4e4
commit 733c005eea
7 changed files with 81 additions and 35 deletions

View File

@ -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

View File

@ -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)

View File

@ -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.

37
src/gui/actions.py Normal file
View File

@ -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()

View File

@ -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):

View File

@ -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))

View File

@ -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()