def removeTiles(self): view = self.currentTilesetView() if (not view): return if (not view.selectionModel().hasSelection()): return indexes = view.selectionModel().selectedIndexes() model = view.tilesetModel() tileIds = RangeSet() tiles = QList() for index in indexes: tile = model.tileAt(index) if tile: tileIds.insert(tile.id()) tiles.append(tile) def matchesAnyTile(cell): tile = cell.tile if tile: return tiles.contains(tile) return False inUse = self.hasTileReferences(self.mMapDocument, matchesAnyTile) # If the tileset is in use, warn the user and confirm removal if (inUse): warning = QMessageBox( QMessageBox.Warning, self.tr("Remove Tiles"), self.tr("One or more of the tiles to be removed are " "still in use by the map!"), QMessageBox.Yes | QMessageBox.No, self) warning.setDefaultButton(QMessageBox.Yes) warning.setInformativeText( self.tr("Remove all references to these tiles?")) if (warning.exec() != QMessageBox.Yes): return undoStack = self.mMapDocument.undoStack() undoStack.beginMacro(self.tr("Remove Tiles")) removeTileReferences(self.mMapDocument, matchesAnyTile) # Iterate backwards over the ranges in order to keep the indexes valid firstRange = tileIds.begin() it = tileIds.end() if (it == firstRange): # no range return tileset = view.tilesetModel().tileset() while (it != firstRange): it -= 1 item = tileIds.item(it) length = item[1] - item[0] + 1 undoStack.push( RemoveTiles(self.mMapDocument, tileset, item[0], length)) undoStack.endMacro() # Clear the current tiles, will be referencing the removed tiles self.setCurrentTiles(None) self.setCurrentTile(None)
def raiseToTop(self): selectedItems = self.mMapScene.selectedObjectItems() objectGroup = RaiseLowerHelper.sameObjectGroup(selectedItems) if (not objectGroup): return if (objectGroup.drawOrder() != ObjectGroup.DrawOrder.IndexOrder): return ranges = RangeSet() for item in selectedItems: ranges.insert(int(item.zValue())) # Iterate backwards over the ranges in order to keep the indexes valid size = len(ranges) if size <= 0: # no range return commands = QList() to = objectGroup.objectCount() for i in range(size - 1, -1, -1): it = ranges.item(i) first = it[0] last = it[1] count = last - first + 1 if (last + 1 == to): to -= count continue _from = first commands.append( ChangeMapObjectsOrder(self.mMapDocument, objectGroup, _from, to, count)) to -= count self.push( commands, QCoreApplication.translate("Undo Commands", "Raise Object To Top"))
def delete_(self): if (not self.mMapDocument or not self.mTile): return if (self.mTile.tileset().isExternal()): return selectionModel = self.mUi.frameList.selectionModel() indexes = selectionModel.selectedIndexes() if len(indexes) == 0: return undoStack = self.mMapDocument.undoStack() undoStack.beginMacro(self.tr("Delete Frames")) ranges = RangeSet() for index in indexes: ranges.insert(index.row()) # Iterate backwards over the ranges in order to keep the indexes valid firstRange = ranges.begin() it = ranges.end() while (it != firstRange): it -= 1 item = ranges.item(it) length = item[1] - item[0] + 1 self.mFrameListModel.removeRows(item[0], length, QModelIndex()) undoStack.endMacro()
class RaiseLowerHelper(): def __init__(self, mapScene): self.mSelectionRanges = RangeSet() self.mMapDocument = mapScene.mapDocument() self.mMapScene = mapScene # Context self.mObjectGroup = None self.mRelatedObjects = QList() def raise_(self): if (not self.initContext()): return # Iterate backwards over the ranges in order to keep the indexes valid size = len(self.mSelectionRanges) if size <= 0: # no range return firstRange = self.mSelectionRanges.begin() it = self.mSelectionRanges.end() if (it == firstRange): # no range return # For each range of objects, only the first will move commands = QList() lastIndex = len(self.mRelatedObjects) - 1 for i in range(size - 1, -1, -1): it = self.mSelectionRanges.item(i) value = it[1] # The last range may be already at the top of the related items if value == lastIndex: continue movingItem = self.mRelatedObjects.at(value) targetItem = self.mRelatedObjects.at(value + 1) _from = int(movingItem.zValue()) to = int(targetItem.zValue() + 1) commands.append( ChangeMapObjectsOrder(self.mMapDocument, self.mObjectGroup, _from, to, 1)) self.push(commands, QCoreApplication.translate("Undo Commands", "Raise Object")) def lower(self): if (not self.initContext()): return # For each range of objects, only the first will move commands = QList() for it in self.mSelectionRanges: value = it[0] # The first range may be already at the bottom of the related items if (value == 0): continue movingItem = self.mRelatedObjects.at(value) targetItem = self.mRelatedObjects.at(value - 1) _from = int(movingItem.zValue()) to = int(targetItem.zValue()) commands.append( ChangeMapObjectsOrder(self.mMapDocument, self.mObjectGroup, _from, to, 1)) self.push(commands, QCoreApplication.translate("Undo Commands", "Lower Object")) def raiseToTop(self): selectedItems = self.mMapScene.selectedObjectItems() objectGroup = RaiseLowerHelper.sameObjectGroup(selectedItems) if (not objectGroup): return if (objectGroup.drawOrder() != ObjectGroup.DrawOrder.IndexOrder): return ranges = RangeSet() for item in selectedItems: ranges.insert(int(item.zValue())) # Iterate backwards over the ranges in order to keep the indexes valid size = len(ranges) if size <= 0: # no range return commands = QList() to = objectGroup.objectCount() for i in range(size - 1, -1, -1): it = ranges.item(i) first = it[0] last = it[1] count = last - first + 1 if (last + 1 == to): to -= count continue _from = first commands.append( ChangeMapObjectsOrder(self.mMapDocument, objectGroup, _from, to, count)) to -= count self.push( commands, QCoreApplication.translate("Undo Commands", "Raise Object To Top")) def lowerToBottom(self): selectedItems = self.mMapScene.selectedObjectItems() objectGroup = RaiseLowerHelper.sameObjectGroup(selectedItems) if (not objectGroup): return if (objectGroup.drawOrder() != ObjectGroup.DrawOrder.IndexOrder): return ranges = RangeSet() for item in selectedItems: ranges.insert(int(item.zValue())) commands = QList() to = 0 for it in ranges: first = it[0] _from = first count = it[1] - first + 1 if (_from == to): to += count continue commands.append( ChangeMapObjectsOrder(self.mMapDocument, objectGroup, _from, to, count)) to += count self.push( commands, QCoreApplication.translate("Undo Commands", "Lower Object To Bottom")) def sameObjectGroup(items): if (items.isEmpty()): return None # All selected objects need to be in the same group group = items.begin().mapObject().objectGroup() for item in items: if (item.mapObject().objectGroup() != group): return None return group ## # Initializes the context in which objects are being raised or lowered. Only # used for single-step raising and lowering, since the context is not relevant # when raising to the top or lowering to the bottom. # # Returns whether the operation can be performed. ## def initContext(self): self.mObjectGroup = None self.mRelatedObjects.clear() self.mSelectionRanges.clear() selectedItems = self.mMapScene.selectedObjectItems() if (selectedItems.isEmpty()): return False # All selected objects need to be in the same group self.mObjectGroup = selectedItems.begin().mapObject().objectGroup() if (self.mObjectGroup.drawOrder() != ObjectGroup.DrawOrder.IndexOrder): return False shape = QPainterPath() for item in selectedItems: if (item.mapObject().objectGroup() != self.mObjectGroup): return False shape |= item.mapToScene(item.shape()) # The list of related items are all items from the same object group # that share space with the selected items. items = self.mMapScene.items(shape, Qt.IntersectsItemShape, Qt.AscendingOrder) for item in items: if type(item) == MapObjectItem: if (item.mapObject().objectGroup() == self.mObjectGroup): self.mRelatedObjects.append(item) for item in selectedItems: index = self.mRelatedObjects.indexOf(item) self.mSelectionRanges.insert(index) return True def push(self, commands, text): if (commands.isEmpty()): return undoStack = self.mMapDocument.undoStack() undoStack.beginMacro(text) for command in commands: undoStack.push(command) undoStack.endMacro()