diff --git a/src/mcedit2/editorsession.py b/src/mcedit2/editorsession.py index 8567a64..de9e4bb 100644 --- a/src/mcedit2/editorsession.py +++ b/src/mcedit2/editorsession.py @@ -39,6 +39,14 @@ selection box, the editor tab containing its viewports, its command history, a s tool (why?), and the ChunkLoader that coordinates loading chunks into its viewports. """ +class PendingImport(object): + def __init__(self, schematic, pos): + self.pos = pos + self.schematic = schematic + + def __repr__(self): + return "%s(%r, %r)" % (self.__class__.__name__, self.schematic, self.pos) + class EditorSession(QtCore.QObject): def __init__(self, filename, versionInfo, readonly=False): QtCore.QObject.__init__(self) @@ -52,6 +60,9 @@ class EditorSession(QtCore.QObject): self.copiedSchematic = None """:type : WorldEditor""" + + self.pendingImports = [] + self.versionInfo = versionInfo # --- Open world editor --- @@ -250,13 +261,7 @@ class EditorSession(QtCore.QObject): if self.copiedSchematic is None: return - moveTool = self.tools["Move"] - - ray = self.editorTab.currentView().rayAtCenter() - point = ray.point + ray.vector * (self.copiedSchematic.getDimension().bounds.size.length() * 2) - point = Vector(*[int(i) for i in point]) - moveTool.pasteSchematic(self.copiedSchematic, point) - self.chooseTool("Move") + self.beginImport(self.copiedSchematic, self.currentSelection.origin) def pasteBlocks(self): NotImplementedYet() @@ -271,15 +276,32 @@ class EditorSession(QtCore.QObject): def importSchematic(self, filename): schematic = WorldEditor(filename, readonly=True) + self.beginImport(schematic) + + # --- Import --- + + def beginImport(self, schematic, pos=None): moveTool = self.tools["Move"] - ray = self.editorTab.currentView().rayAtCenter() - point, face = rayCastInBounds(ray, self.currentDimension) - if point is None: - point = ray.point - moveTool.pasteSchematic(schematic, point) + if pos is None: + ray = self.editorTab.currentView().rayAtCenter() + pos, face = rayCastInBounds(ray, self.currentDimension) + if pos is None: + pos = ray.point + + imp = PendingImport(schematic, pos) + + self.pendingImports.append(imp) + moveTool.currentImport = imp self.chooseTool("Move") + def addPendingImport(self, pendingImport): + self.pendingImports.append(pendingImport) + + def removePendingImport(self, pendingImport): + self.pendingImports.remove(pendingImport) + + # --- Undo support --- def undoIndexChanged(self, index): diff --git a/src/mcedit2/editortools/move.py b/src/mcedit2/editortools/move.py index 823f0b7..53e0b75 100644 --- a/src/mcedit2/editortools/move.py +++ b/src/mcedit2/editortools/move.py @@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function import logging from PySide import QtGui, QtCore +from mcedit2.editorsession import PendingImport from mcedit2.editortools import EditorTool from mcedit2.command import SimpleRevisionCommand @@ -24,25 +25,22 @@ from mceditlib.selection import BoundingBox log = logging.getLogger(__name__) class MoveSelectionCommand(SimpleRevisionCommand): - def __init__(self, moveTool, movingSchematic, movePosition=None, text=None, *args, **kwargs): + def __init__(self, moveTool, pendingImport, text=None, *args, **kwargs): if text is None: - text = moveTool.tr("Move Selected Things") - if movePosition is None: - movePosition = moveTool.editorSession.currentSelection.origin + text = moveTool.tr("Move Selected Object") super(MoveSelectionCommand, self).__init__(moveTool.editorSession, text, *args, **kwargs) + self.currentImport = pendingImport self.moveTool = moveTool - self.movingSchematic = movingSchematic - self.movePosition = movePosition def undo(self): super(MoveSelectionCommand, self).undo() - self.moveTool.movingSchematic = None - self.moveTool.movePosition = None + self.moveTool.currentImport = None + self.editorSession.removePendingImport(self.currentImport) self.moveTool.editorSession.chooseTool("Select") def redo(self): - self.moveTool.movingSchematic = self.movingSchematic - self.moveTool.movePosition = self.movePosition + self.moveTool.currentImport = self.currentImport + self.editorSession.addPendingImport(self.currentImport) self.moveTool.editorSession.chooseTool("Move") super(MoveSelectionCommand, self).redo() @@ -51,7 +49,7 @@ class MoveOffsetCommand(QtGui.QUndoCommand): def __init__(self, moveTool, oldPoint, newPoint): super(MoveOffsetCommand, self).__init__() - self.setText(moveTool.tr("Move Things")) + self.setText(moveTool.tr("Move Object")) self.newPoint = newPoint self.oldPoint = oldPoint self.moveTool = moveTool @@ -63,24 +61,24 @@ class MoveOffsetCommand(QtGui.QUndoCommand): self.moveTool.movePosition = self.newPoint class MoveFinishCommand(SimpleRevisionCommand): - def __init__(self, moveTool, movingSchematic, *args, **kwargs): - super(MoveFinishCommand, self).__init__(moveTool.editorSession, moveTool.tr("Finish Moving Things"), *args, **kwargs) - self.movingSchematic = movingSchematic + def __init__(self, moveTool, pendingImport, *args, **kwargs): + super(MoveFinishCommand, self).__init__(moveTool.editorSession, moveTool.tr("Finish Move"), *args, **kwargs) + self.currentImport = pendingImport self.moveTool = moveTool def undo(self): super(MoveFinishCommand, self).undo() - self.moveTool.movingSchematic = self.movingSchematic - self.moveTool.movePosition = self.movePosition + self.moveTool.pendingImport = self.currentImport self.editorSession.currentSelection = self.previousSelection self.editorSession.chooseTool("Move") def redo(self): super(MoveFinishCommand, self).redo() self.previousSelection = self.editorSession.currentSelection - self.movePosition = self.moveTool.movePosition - self.editorSession.currentSelection = BoundingBox(self.movePosition, self.previousSelection.size) - self.moveTool.movingSchematic = None + self.currentImport = self.moveTool.currentImport + self.editorSession.currentSelection = BoundingBox(self.pendingImport.pos, self.previousSelection.size) + self.moveTool.currentImport = None + self.editorSession.removePendingImport(self.currentImport) class CoordinateWidget(QtGui.QWidget): @@ -154,18 +152,15 @@ class MoveTool(EditorTool): self.pointInput = CoordinateWidget() self.pointInput.pointChanged.connect(self.pointInputChanged) confirmButton = QtGui.QPushButton("Confirm") # xxxx should be in worldview - confirmButton.clicked.connect(self.completeMove) + confirmButton.clicked.connect(self.confirmImport) self.toolWidget.setLayout(Column(self.pointInput, confirmButton, None)) - self.movePosition = None - - _movePosition = None @property def movePosition(self): - return self._movePosition + return None if self.currentImport is None else self.currentImport.pos @movePosition.setter def movePosition(self, value): @@ -179,35 +174,33 @@ class MoveTool(EditorTool): def doMoveOffsetCommand(self, oldPoint, newPoint): if newPoint != oldPoint: command = MoveOffsetCommand(self, oldPoint, newPoint) - self.editorSession.removeUndoBlock(self.moveUndoBlock) self.editorSession.pushCommand(command) - self.editorSession.setUndoBlock(self.moveUndoBlock) def pointInputChanged(self, value): - self._movePosition = value if value is not None: + self.currentImport.pos = value self.translateNode.visible = True self.translateNode.translateOffset = value else: self.translateNode.visible = False - _movingSchematic = None + _currentImport = None @property - def movingSchematic(self): - return self._movingSchematic + def currentImport(self): + return self._currentImport - @movingSchematic.setter - def movingSchematic(self, value): - oldVal = self._movingSchematic - self._movingSchematic = value + @currentImport.setter + def currentImport(self, value): + oldVal = self._currentImport + self._currentImport = value if oldVal is not value: self.updateOverlay() self.pointInput.setEnabled(value is not None) def updateOverlay(self): - if self.movingSchematic is None: + if self.currentImport is None: log.info("updateOverlay: Nothing to display") if self.movingWorldScene: self.sceneHolderNode.removeChild(self.movingWorldScene) @@ -215,12 +208,12 @@ class MoveTool(EditorTool): self.outlineNode.visible = False - log.info("Updating move schematic scene: %s", self.movingSchematic) + log.info("Updating move schematic scene: %s", self.currentImport) if self.movingWorldScene: self.loader.timer.stop() self.sceneHolderNode.removeChild(self.movingWorldScene) - if self.movingSchematic: - dim = self.movingSchematic.getDimension() + if self.currentImport: + dim = self.currentImport.schematic.getDimension() self.movingWorldScene = WorldScene(dim, self.editorSession.textureAtlas) # xxx assumes import is same blocktypes as world, find atlas for imported object self.outlineNode.selectionBox = dim.bounds @@ -234,7 +227,7 @@ class MoveTool(EditorTool): @property def schematicBox(self): - box = self.movingSchematic.getDimension().bounds + box = self.currentImport.schematic.getDimension().bounds return BoundingBox(self.movePosition, box.size) # --- Mouse events --- @@ -252,7 +245,7 @@ class MoveTool(EditorTool): def mouseMove(self, event): # Hilite face cursor is over - if self.movingSchematic is None or self.movePosition is None: + if self.currentImport is None: return point, face = boxFaceUnderCursor(self.schematicBox, event.ray) @@ -261,7 +254,7 @@ class MoveTool(EditorTool): self.faceHoverNode.visible = True self.faceHoverNode.face = face - self.faceHoverNode.selectionBox = self.movingSchematic.getDimension().bounds + self.faceHoverNode.selectionBox = self.currentImport.schematic.getDimension().bounds else: self.faceHoverNode.visible = False @@ -270,7 +263,7 @@ class MoveTool(EditorTool): def mouseDrag(self, event): # Move box using face or axis pointers - if self.movingSchematic is None: + if self.currentImport is None: return if self.dragStartFace is None: return @@ -286,7 +279,7 @@ class MoveTool(EditorTool): # begin drag - if self.movingSchematic is not None: + if self.currentImport is not None: point, face = boxFaceUnderCursor(self.schematicBox, event.ray) self.dragStartFace = face self.dragStartPoint = point @@ -296,55 +289,44 @@ class MoveTool(EditorTool): # Don't paste cut selection in yet. Wait for tool switch or "Confirm" button press. Begin new revision # for paste operation, paste stored world, store revision after paste (should be previously stored revision # +2), commit MoveCommand to undo history. - if self.movingSchematic is not None: + if self.currentImport is not None: self.doMoveOffsetCommand(self.dragStartMovePosition, self.movePosition) def toolActive(self): self.editorSession.selectionTool.hideSelectionWalls = True - if self.movingSchematic is None: + if self.currentImport is None: # Need to cut out selection # xxxx for huge selections, don't cut, just do everything at the end? if self.editorSession.currentSelection is None: return export = self.editorSession.currentDimension.exportSchematicIter(self.editorSession.currentSelection) - self.movingSchematic = showProgress("Lifting...", export) - - moveCommand = MoveSelectionCommand(self, self.movingSchematic) + schematic = showProgress("Copying...", export) + pos = self.editorSession.currentSelection.origin + pendingImport = PendingImport(schematic, pos) + moveCommand = MoveSelectionCommand(self, pendingImport) with moveCommand.begin(): fill = self.editorSession.currentDimension.fillBlocksIter(self.editorSession.currentSelection, "air") - showProgress("Lifting...", fill) + showProgress("Clearing...", fill) self.editorSession.pushCommand(moveCommand) - self.editorSession.setUndoBlock(self.moveUndoBlock) - def moveUndoBlock(self): - self.completeMove() - self.movingSchematic = None + self.outlineNode.visible = True def toolInactive(self): self.editorSession.selectionTool.hideSelectionWalls = False - if self.movingSchematic is not None: - self.completeMove() - self.movingSchematic = None self.outlineNode.visible = False self.faceHoverNode.visible = False - def completeMove(self): - if self.movingSchematic is None: + def confirmImport(self): + if self.currentImport is None: return - self.editorSession.removeUndoBlock(self.moveUndoBlock) - command = MoveFinishCommand(self, self.movingSchematic) + command = MoveFinishCommand(self, self.currentImport) with command.begin(): - task = self.editorSession.currentDimension.importSchematicIter(self.movingSchematic, self.movePosition) + task = self.editorSession.currentDimension.importSchematicIter(self.currentImport.schematic, self.currentImport.pos) showProgress(self.tr("Pasting..."), task) self.editorSession.pushCommand(command) - - def pasteSchematic(self, copiedSchematic, position): - command = MoveSelectionCommand(self, copiedSchematic, position, self.tr("Paste")) - self.editorSession.pushCommand(command) - self.editorSession.setUndoBlock(self.moveUndoBlock)