def write(self, map, fileName): # Open up a temporary file for saving the level. file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)): self.mError = self.tr("Could not open temporary file for writing.") return False # Create an output stream for serializing data. out = QDataStream(file) out.setByteOrder(QDataStream.LittleEndian) out.setFloatingPointPrecision(QDataStream.SinglePrecision) # Write out the signature and file header. out.writeInt8(96) # Signature. out.writeInt8(map.layerCount()) ok = False x, ok = Int2(map.property("background_index")) if (not ok): self.mError = self.tr("You must define a background_index property on the map!") return False out.writeInt8(x) # Write out each layer. for i in range(0, map.layerCount()): layer = map.layerAt(i).asTileLayer() if (not layer): self.mError = self.tr("Can't save non-tile layer!") return False if (not self.writeLayer(out, layer)): return False if not file.commit(): self.mError = file.errorString() return False return True
def savefile_open(filename, binary=False, encoding='utf-8'): """Context manager to easily use a QSaveFile.""" f = QSaveFile(filename) cancelled = False try: open_ok = f.open(QIODevice.WriteOnly) if not open_ok: raise QtOSError(f) if binary: new_f = PyQIODevice(f) else: new_f = io.TextIOWrapper(PyQIODevice(f), encoding=encoding) yield new_f new_f.flush() except: f.cancelWriting() cancelled = True raise finally: commit_ok = f.commit() if not commit_ok and not cancelled: raise QtOSError(f, msg="Commit failed!")
def write(self, tileset, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)): self.mError = self.tr("Could not open file for writing.") return False converter = MapToVariantConverter() variant = converter.toVariant(tileset, QFileInfo(fileName).dir()) writer = json try: result = writer.dumps(variant, indent=4) except: # This can only happen due to coding error self.mError = self.tr('Unknow error.') return False out = QTextStream(file) out << result out.flush() if (file.error() != QFile.NoError): self.mError = self.tr("Error while writing file:\n%1").arg(file.errorString()) return False if (not file.commit()): self.mError = file.errorString() return False return True
def saveStamp(self, stamp): # make sure we have a stamps directory prefs = preferences.Preferences.instance() stampsDirectory = prefs.stampsDirectory() stampsDir = QDir(stampsDirectory) if (not stampsDir.exists() and not stampsDir.mkpath(".")): qDebug("Failed to create stamps directory" + stampsDirectory) return filePath = stampsDir.filePath(stamp.fileName()) file = QSaveFile(filePath) if (not file.open(QIODevice.WriteOnly)): qDebug("Failed to open stamp file for writing" + filePath) return stampJson = stamp.toJson(QFileInfo(filePath).dir()) file.write(QJsonDocument(stampJson).toJson(QJsonDocument.Compact)) if (not file.commit()): qDebug() << "Failed to write stamp" << filePath
def onSave(self): fPath = saveFileSelect() if fPath: file = QSaveFile(fPath) if not file.open(QIODevice.WriteOnly): return messageBox('Cannot open file for writing') file.write(self.logZone.toPlainText().encode()) file.commit()
def writeMap(self, *args): l = len(args) if l==3: map, device, path = args self.d.writeMap(map, device, path) elif l==2: tp = type(args[1]) if tp==QIODevice: map, device, path = args, QString() self.d.writeMap(map, device, path) elif tp in [QString, str]: ## # Writes a TMX map to the given \a fileName. # # Returns False and sets errorString() when reading failed. # \overload ## map, fileName = args file = QSaveFile(fileName) if (not self.d.openFile(file)): return False self.writeMap(map, file, QFileInfo(fileName).absolutePath()) if (file.error() != QFile.NoError): self.d.mError = file.errorString() return False if (not file.commit()): self.d.mError = file.errorString() return False return True
def storeQGISui(self,force =False): try: # store current QGIS ui # layout qgisAppDataPath = QStandardPaths.standardLocations(QStandardPaths.AppDataLocation)[0] file = os.path.join(qgisAppDataPath, 'qgis_ui.bin') if not os.path.isfile(file) or force: if self.debug: self.info.log("storeQGISui:", self.helper.shortDisplayText(file)) f = QSaveFile(file) f.open(QIODevice.WriteOnly) f.write(self.iface.mainWindow().saveState()) f.commit() except Exception as e: self.info.err(e)
def savefile_open( filename: str, binary: bool = False, encoding: str = 'utf-8' ) -> Iterator[IO[AnyStr]]: """Context manager to easily use a QSaveFile.""" f = QSaveFile(filename) cancelled = False try: open_ok = f.open(QIODevice.WriteOnly) if not open_ok: raise QtOSError(f) dev = cast(BinaryIO, PyQIODevice(f)) if binary: new_f: IO[Any] = dev # FIXME:mypy Why doesn't AnyStr work? else: new_f = io.TextIOWrapper(dev, encoding=encoding) yield new_f new_f.flush() except: f.cancelWriting() cancelled = True raise finally: commit_ok = f.commit() if not commit_ok and not cancelled: raise QtOSError(f, msg="Commit failed!")
def savefile_open( filename: str, binary: bool = False, encoding: str = 'utf-8' ) -> typing.Iterator[typing.IO]: """Context manager to easily use a QSaveFile.""" f = QSaveFile(filename) cancelled = False try: open_ok = f.open(QIODevice.WriteOnly) if not open_ok: raise QtOSError(f) dev = typing.cast(typing.BinaryIO, PyQIODevice(f)) if binary: new_f = dev # type: typing.IO else: new_f = io.TextIOWrapper(dev, encoding=encoding) yield new_f new_f.flush() except: f.cancelWriting() cancelled = True raise finally: commit_ok = f.commit() if not commit_ok and not cancelled: raise QtOSError(f, msg="Commit failed!")
def saveLabels(self): if self._label_path != None: if self._label_path.endswith(".jpg.txt"): self._label_path = self._label_path[:-8] + ".txt" lf = QSaveFile(self._label_path) if not lf.open(QIODevice.WriteOnly | QIODevice.Text): raise IOError('Cannot open "{}" for writing'.format( self._label_path)) for item in self.items(): if item.type() == BBOX: rect = item.rect() c = item.number x = (rect.x() + rect.width() / 2) / self._img_w y = (rect.y() + rect.height() / 2) / self._img_h w = rect.width() / self._img_w h = rect.height() / self._img_h line = '{c:d} {x:.10f} {y:.10f} {w:.10f} {h:.10f}\n'.format( c=c, x=x, y=y, w=w, h=h) lf.write(line.encode()) if lf.commit(): print('Wrote "{}"'.format(self._label_path)) else: raise IOError('Cannot write "{}"'.format(self._label_path))
def saveLabels(self): if self._label_path != None: if len(self._boxes()) == 0: print('Removing empty "{}"'.format(self._label_path)) try: os.remove(self._label_path) except OSError as ex: if ex.errno != errno.ENOENT: raise else: lf = QSaveFile(self._label_path) if not lf.open(QIODevice.WriteOnly | QIODevice.Text): raise IOError('Cannot open "{}" for writing'.format( self._label_path)) for bbox in self._boxes(): rect = bbox.rect() c = bbox.number x = (rect.x() + rect.width() / 2) / self._img_w y = (rect.y() + rect.height() / 2) / self._img_h w = rect.width() / self._img_w h = rect.height() / self._img_h line = '{c:d} {x:.10f} {y:.10f} {w:.10f} {h:.10f}\n'.format( c=c, x=x, y=y, w=w, h=h) lf.write(line.encode()) if lf.commit(): print('Wrote "{}"'.format(self._label_path)) else: raise IOError('Cannot write "{}"'.format(self._label_path))
def write(self, map, fileName): collisionLayer = None for layer in map.layers(): if layer.name().lower() == "collision": tileLayer = layer.asTileLayer() if tileLayer: if (collisionLayer) : self.mError = self.tr("Multiple collision layers found!") return False collisionLayer = tileLayer if (not collisionLayer) : self.mError = self.tr("No collision layer found!") return False file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)) : self.mError = self.tr("Could not open file for writing.") return False width = collisionLayer.width() height = collisionLayer.height() stream = QDataStream(file) stream.setByteOrder(QDataStream.LittleEndian) stream.writeInt16(width&0xffff) stream.writeInt16(height&0xffff) for y in range(0, height): for x in range(0, width): tile = collisionLayer.cellAt(x, y).tile stream.writeInt8(int(tile and tile.id()> 0)&0xff) if not file.commit(): self.mError = file.errorString() return False return True
def saveFile(self): if self.filename is '': self.filename = QFileDialog.getSaveFileName(self.piirtoalusta)[0] if self.filename is not '': items = self.piirtoalusta.scene.items() if '.txt' not in self.filename: self.filename = "".join((self.filename, '.txt')) textfile = QSaveFile(self.filename) textfile.open(QIODevice.WriteOnly | QIODevice.Text) output = QByteArray() items = self.piirtoalusta.scene.items() save = Save(items) output.append(save.content) textfile.write(output) textfile.commit() return save.content
def write(self, map, fileName): # Open up a temporary file for saving the level. file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)): self.mError = self.tr("Could not open temporary file for writing.") return False # Create an output stream for serializing data. out = QDataStream(file) out.setByteOrder(QDataStream.LittleEndian) out.setFloatingPointPrecision(QDataStream.SinglePrecision) # Write out the signature and file header. out.writeInt8(96) # Signature. out.writeInt8(map.layerCount()) ok = False x, ok = Int2(map.property("background_index")) if (not ok): self.mError = self.tr( "You must define a background_index property on the map!") return False out.writeInt8(x) # Write out each layer. for i in range(0, map.layerCount()): layer = map.layerAt(i).asTileLayer() if (not layer): self.mError = self.tr("Can't save non-tile layer!") return False if (not self.writeLayer(out, layer)): return False if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)) : self.mError = self.tr("Could not open file for writing.") return False converter = MapToVariantConverter() variant = converter.toVariant(map, QFileInfo(fileName).dir()) writer = json try: result = writer.dumps(variant, indent=4) except: # This can only happen due to coding error self.mError = self.tr('Unknow error.') return False out = QTextStream(file) if self.mSubFormat == JsonMapFormat.SubFormat.JavaScript: # Trim and escape name nameWriter = json baseName = QFileInfo(fileName).baseName() baseNameResult = nameWriter.dumps(baseName) out << "(function(name,data){\n if(typeof onTileMapLoaded === 'undefined') {\n" out << " if(typeof TileMaps === 'undefined') TileMaps = {};\n" out << " TileMaps[name] = data;\n" out << " } else {\n" out << " onTileMapLoaded(name,data);\n" out << " }})(" + baseNameResult + ",\n" out << result if self.mSubFormat == JsonMapFormat.SubFormat.JavaScript: out << ");" out.flush() if (file.error() != QFile.NoError) : self.mError = self.tr("Error while writing file:\n%1").arg(file.errorString()) return False if (not file.commit()) : self.mError = file.errorString() return False return True
def savefile_open(filename, binary=False, encoding='utf-8'): """Context manager to easily use a QSaveFile.""" f = QSaveFile(filename) new_f = None try: ok = f.open(QIODevice.WriteOnly) if not ok: raise OSError(f.errorString()) if binary: new_f = PyQIODevice(f) else: new_f = io.TextIOWrapper(PyQIODevice(f), encoding=encoding) yield new_f except: f.cancelWriting() raise finally: if new_f is not None: new_f.flush() commit_ok = f.commit() if not commit_ok: raise OSError(f.errorString())
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)) : self.mError = self.tr("Could not open file for writing.") return False self.mMapDir = QDir(QFileInfo(fileName).path()) writer = LuaTableWriter(file) writer.writeStartDocument() self.writeMap(writer, map) writer.writeEndDocument() if (file.error() != QFile.NoError) : self.mError = file.errorString() return False if (not file.commit()) : self.mError = file.errorString() return False return True
def export(self, file, simplif=False): """le type d'export est obtenu par analyse de l'extension file est un QString: tuple (nom de fichier, filtre) la simplification est lue depuis l'attribut QMW.simple """ # choix pour pst,pag choix = {True: self.xmlsimplif, False: self.xml} f = file[0] ext = f[-3:] # 3 derniers caractères if ext == "tex": o = self.tab2latex(simplif=simplif) t = QByteArray(o.encode("utf-8")) elif ext in ["pst", "pag"]: o = etree.tostring(choix[simplif], pretty_print=True) t = QByteArray(o) out = QSaveFile(file[0]) out.open(QIODevice.WriteOnly) # cette constante de classe vaut 2 out.write(t) out.commit()
def write(self, map, fileName): # Check layer count and type if (map.layerCount() != 1 or not map.layerAt(0).isTileLayer()): self.mError = self.tr( "The map needs to have exactly one tile layer!") return False mapLayer = map.layerAt(0).asTileLayer() # Check layer size if (mapLayer.width() != 48 or mapLayer.height() != 48): self.mError = self.tr( "The layer must have a size of 48 x 48 tiles!") return False # Create QByteArray and compress it uncompressed = QByteArray(48 * 48, b'\x00') width = mapLayer.width() height = mapLayer.height() for y in range(0, height): for x in range(0, width): tile = mapLayer.cellAt(x, y).tile if tile: # 'QByteArray' object does not support item assignment uncompressed.replace(y * width + x, 1, bytes([tile.id() & 0xff])) compressed = compress(uncompressed, CompressionMethod.Gzip) # Write QByteArray file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)): self.mError = self.tr("Could not open file for writing.") return False file.write(compressed) if not file.commit(): self.mError = file.errorString() return False return True
def savefile_open(filename, binary=False, encoding='utf-8'): """Context manager to easily use a QSaveFile.""" f = QSaveFile(filename) new_f = None try: ok = f.open(QIODevice.WriteOnly) if not ok: # pylint: disable=used-before-assignment raise OSError(f.errorString()) if binary: new_f = PyQIODevice(f) else: new_f = io.TextIOWrapper(PyQIODevice(f), encoding=encoding) yield new_f except: f.cancelWriting() raise finally: if new_f is not None: new_f.flush() ok = f.commit() if not ok: raise OSError(f.errorString())
def write(self, map, fileName): # Check layer count and type if (map.layerCount() != 1 or not map.layerAt(0).isTileLayer()) : self.mError = self.tr("The map needs to have exactly one tile layer!") return False mapLayer = map.layerAt(0).asTileLayer() # Check layer size if (mapLayer.width() != 48 or mapLayer.height() != 48) : self.mError = self.tr("The layer must have a size of 48 x 48 tiles!") return False # Create QByteArray and compress it uncompressed = QByteArray(48 * 48, b'\x00') width = mapLayer.width() height = mapLayer.height() for y in range(0, height): for x in range(0, width): tile = mapLayer.cellAt(x, y).tile if tile: # 'QByteArray' object does not support item assignment uncompressed.replace(y * width + x, 1, bytes([tile.id()&0xff])) compressed = compress(uncompressed, CompressionMethod.Gzip) # Write QByteArray file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)) : self.mError = self.tr("Could not open file for writing.") return False file.write(compressed) if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QFile.WriteOnly | QFile.Text)): self.mError = self.tr("Could not open file for writing.") return False out = QTextStream(file) out.setCodec("UTF-8") mapWidth = map.width() mapHeight = map.height() # write [header] out << "[header]\n" out << "width=" << str(mapWidth) << "\n" out << "height=" << str(mapHeight) << "\n" out << "tilewidth=" << str(map.tileWidth()) << "\n" out << "tileheight=" << str(map.tileHeight()) << "\n" out << "orientation=" << str(orientationToString(map.orientation())) << "\n" # write all properties for this map for it in map.properties().__iter__(): out << it[0] << "=" << it[1] << "\n" out << "\n" mapDir = QFileInfo(fileName).absoluteDir() out << "[tilesets]\n" for tileset in map.tilesets(): imageSource = tileset.imageSource() source = mapDir.relativeFilePath(imageSource) out << "tileset=" << source \ << "," << str(tileset.tileWidth()) \ << "," << str(tileset.tileHeight()) \ << "," << str(tileset.tileOffset().x()) \ << "," << str(tileset.tileOffset().y()) \ << "\n" out << "\n" gidMapper = GidMapper(map.tilesets()) # write layers for layer in map.layers(): tileLayer = layer.asTileLayer() if tileLayer: out << "[layer]\n" out << "type=" << layer.name() << "\n" out << "data=\n" for y in range(0, mapHeight): for x in range(0, mapWidth): t = tileLayer.cellAt(x, y) id = 0 if (t.tile): id = gidMapper.cellToGid(t) out << id if (x < mapWidth - 1): out << "," if (y < mapHeight - 1): out << "," out << "\n" out << "\n" group = layer.asObjectGroup() if group: for o in group.objects(): if o.type() != '': out << "[" << group.name() << "]\n" # display object name as comment if o.name() != '': out << "# " << o.name() << "\n" out << "type=" << o.type() << "\n" x,y,w,h = 0 if (map.orientation() == Map.Orthogonal): x = o.x()/map.tileWidth() y = o.y()/map.tileHeight() w = o.width()/map.tileWidth() h = o.height()/map.tileHeight() else : x = o.x()/map.tileHeight() y = o.y()/map.tileHeight() w = o.width()/map.tileHeight() h = o.height()/map.tileHeight() out << "location=" << x << "," << y out << "," << w << "," << h << "\n" # write all properties for this object for it in o.properties().__iter__(): out << it[0] << "=" << it[1] << "\n" out << "\n" if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): # Get file paths for each layer layerPaths = self.outputFiles(map, fileName) # Traverse all tile layers currentLayer = 0 for layer in map.layers(): if layer.layerType() != Layer.TileLayerType: continue tileLayer = layer file = QSaveFile(layerPaths[currentLayer]) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)): self.mError = self.tr("Could not open file for writing.") return False # Write out tiles either by ID or their name, if given. -1 is "empty" for y in range(0, tileLayer.height()): for x in range(0, tileLayer.width()): if (x > 0): file.write(",") cell = tileLayer.cellAt(x, y) tile = cell.tile if (tile and tile.hasProperty("name")): file.write(tile.property("name").encode()) else: if tile: id = tile.id() else: id = -1 file.write(QByteArray.number(id)) file.write("\n") if (file.error() != QFile.NoError): self.mError = file.errorString() return False if (not file.commit()): self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QFile.WriteOnly | QFile.Text)): self.mError = self.tr("Could not open file for writing.") return False out = QTextStream(file) out.setCodec("UTF-8") mapWidth = map.width() mapHeight = map.height() # write [header] out << "[header]\n" out << "width=" << str(mapWidth) << "\n" out << "height=" << str(mapHeight) << "\n" out << "tilewidth=" << str(map.tileWidth()) << "\n" out << "tileheight=" << str(map.tileHeight()) << "\n" out << "orientation=" << str(orientationToString( map.orientation())) << "\n" # write all properties for this map for it in map.properties().__iter__(): out << it[0] << "=" << it[1] << "\n" out << "\n" mapDir = QFileInfo(fileName).absoluteDir() out << "[tilesets]\n" for tileset in map.tilesets(): imageSource = tileset.imageSource() source = mapDir.relativeFilePath(imageSource) out << "tileset=" << source \ << "," << str(tileset.tileWidth()) \ << "," << str(tileset.tileHeight()) \ << "," << str(tileset.tileOffset().x()) \ << "," << str(tileset.tileOffset().y()) \ << "\n" out << "\n" gidMapper = GidMapper(map.tilesets()) # write layers for layer in map.layers(): tileLayer = layer.asTileLayer() if tileLayer: out << "[layer]\n" out << "type=" << layer.name() << "\n" out << "data=\n" for y in range(0, mapHeight): for x in range(0, mapWidth): t = tileLayer.cellAt(x, y) id = 0 if (t.tile): id = gidMapper.cellToGid(t) out << id if (x < mapWidth - 1): out << "," if (y < mapHeight - 1): out << "," out << "\n" out << "\n" group = layer.asObjectGroup() if group: for o in group.objects(): if o.type() != '': out << "[" << group.name() << "]\n" # display object name as comment if o.name() != '': out << "# " << o.name() << "\n" out << "type=" << o.type() << "\n" x, y, w, h = 0 if (map.orientation() == Map.Orthogonal): x = o.x() / map.tileWidth() y = o.y() / map.tileHeight() w = o.width() / map.tileWidth() h = o.height() / map.tileHeight() else: x = o.x() / map.tileHeight() y = o.y() / map.tileHeight() w = o.width() / map.tileHeight() h = o.height() / map.tileHeight() out << "location=" << x << "," << y out << "," << w << "," << h << "\n" # write all properties for this object for it in o.properties().__iter__(): out << it[0] << "=" << it[1] << "\n" out << "\n" if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): # Get file paths for each layer layerPaths = self.outputFiles(map, fileName) # Traverse all tile layers currentLayer = 0 for layer in map.layers(): if layer.layerType() != Layer.TileLayerType: continue tileLayer = layer file = QSaveFile(layerPaths[currentLayer]) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)): self.mError = self.tr("Could not open file for writing.") return False # Write out tiles either by ID or their name, if given. -1 is "empty" for y in range(0, tileLayer.height()): for x in range(0, tileLayer.width()): if (x > 0): file.write(",") cell = tileLayer.cellAt(x, y) tile = cell.tile if (tile and tile.hasProperty("name")) : file.write(tile.property("name").encode()) else: if tile: id = tile.id() else: id = -1 file.write(QByteArray.number(id)) file.write("\n") if (file.error() != QFile.NoError) : self.mError = file.errorString() return False if (not file.commit()) : self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)): self.mError = self.tr("Could not open file for writing.") return False out = QTextStream(file) # Write the header header = map.property("header") for line in header.split("\\n"): out << line << '\n' width = map.width() height = map.height() asciiMap = QList() cachedTiles = QHash() propertyOrder = QList() propertyOrder.append("terrain") propertyOrder.append("object") propertyOrder.append("actor") propertyOrder.append("trap") propertyOrder.append("status") propertyOrder.append("spot") # Ability to handle overflow and strings for display outputLists = False asciiDisplay = ASCII_MIN overflowDisplay = 1 # Add the empty tile numEmptyTiles = 0 emptyTile = Properties() emptyTile["display"] = "?" cachedTiles["?"] = emptyTile # Process the map, collecting used display strings as we go for y in range(0, height): for x in range(0, width): currentTile = cachedTiles["?"] for layer in map.layers(): # If the layer name does not start with one of the tile properties, skip it layerKey = '' for currentProperty in propertyOrder: if (layer.name().lower().startswith( currentProperty.lower())): layerKey = currentProperty break if layerKey == '': continue tileLayer = layer.asTileLayer() objectLayer = layer.asObjectGroup() # Process the Tile Layer if (tileLayer): tile = tileLayer.cellAt(x, y).tile if (tile): currentTile["display"] = tile.property("display") currentTile[layerKey] = tile.property("value") # Process the Object Layer elif (objectLayer): for obj in objectLayer.objects(): if (math.floor(obj.y()) <= y and y <= math.floor(obj.y() + obj.height())): if (math.floor(obj.x()) <= x and x <= math.floor(obj.x() + obj.width())): # Check the Object Layer properties if either display or value was missing if (not obj.property("display").isEmpty()): currentTile["display"] = obj.property( "display") elif (not objectLayer.property( "display").isEmpty()): currentTile[ "display"] = objectLayer.property( "display") if (not obj.property("value").isEmpty()): currentTile[layerKey] = obj.property( "value") elif (not objectLayer.property( "value").isEmpty()): currentTile[ layerKey] = objectLayer.property( "value") # If the currentTile does not exist in the cache, add it if (not cachedTiles.contains(currentTile["display"])): cachedTiles[currentTile["display"]] = currentTile # Otherwise check that it EXACTLY matches the cached one # and if not... elif (currentTile != cachedTiles[currentTile["display"]]): # Search the cached tiles for a match foundInCache = False displayString = QString() for i in cachedTiles.items(): displayString = i[0] currentTile["display"] = displayString if (currentTile == i[1]): foundInCache = True break # If we haven't found a match then find a random display string # and cache it if (not foundInCache): while (True): # First try to use the ASCII characters if (asciiDisplay < ASCII_MAX): displayString = asciiDisplay asciiDisplay += 1 # Then fall back onto integers else: displayString = QString.number(overflowDisplay) overflowDisplay += 1 currentTile["display"] = displayString if (not cachedTiles.contains(displayString)): cachedTiles[displayString] = currentTile break elif (currentTile == cachedTiles[ currentTile["display"]]): break # Check the output type if len(currentTile["display"]) > 1: outputLists = True # Check if we are still the emptyTile if (currentTile == emptyTile): numEmptyTiles += 1 # Finally add the character to the asciiMap asciiMap.append(currentTile["display"]) # Write the definitions to the file out << "-- defineTile section\n" for i in cachedTiles.items(): displayString = i[0] # Only print the emptyTile definition if there were empty tiles if (displayString == "?" and numEmptyTiles == 0): continue # Need to escape " and \ characters displayString.replace('\\', "\\\\") displayString.replace('"', "\\\"") args = self.constructArgs(i[1], propertyOrder) if (not args.isEmpty()): args = QString(", %1").arg(args) out << "defineTile(\"%s\"%s)\n" % (displayString, args) # Check for an ObjectGroup named AddSpot out << "\n-- addSpot section\n" for layer in map.layers(): objectLayer = layer.asObjectGroup() if (objectLayer and objectLayer.name().lower().startsWith("addspot")): for obj in objectLayer.objects(): propertyOrder = QList() propertyOrder.append("type") propertyOrder.append("subtype") propertyOrder.append("additional") args = self.constructArgs(obj.properties(), propertyOrder) if (not args.isEmpty()): args = QString(", %1").arg(args) for y in range(math.floor(obj.y()), math.floor(obj.y() + obj.height())): for y in range(math.floor(obj.x()), math.floor(obj.x() + obj.width())): out << "addSpot({%s, %s}%s)\n" % (x, y, args) # Check for an ObjectGroup named AddZone out << "\n-- addZone section\n" for layer in map.layers(): objectLayer = layer.asObjectGroup() if (objectLayer and objectLayer.name().lower().startsWith("addzone")): for obj in objectLayer.objects(): propertyOrder = QList() propertyOrder.append("type") propertyOrder.append("subtype") propertyOrder.append("additional") args = self.constructArgs(obj.properties(), propertyOrder) if (not args.isEmpty()): args = QString(", %1").arg(args) top_left_x = math.floor(obj.x()) top_left_y = math.floor(obj.y()) bottom_right_x = math.floor(obj.x() + obj.width()) bottom_right_y = math.floor(obj.y() + obj.height()) out << "addZone({%s, %s, %s, %s}%s)" % ( top_left_x, top_left_y, bottom_right_x, bottom_right_y, args) # Write the map returnStart = QString() returnStop = QString() lineStart = QString() lineStop = QString() itemStart = QString() itemStop = QString() seperator = QString() if (outputLists): returnStart = "{" returnStop = "}" lineStart = "{" lineStop = "}," itemStart = "[[" itemStop = "]]" seperator = "," else: returnStart = "[[" returnStop = "]]" lineStart = "" lineStop = "" itemStart = "" itemStop = "" seperator = "" out << "\n-- ASCII map section\n" out << "return " << returnStart << '\n' for y in range(0, height): out << lineStart for x in range(0, width): out << itemStart << asciiMap[x + (y * width)] << itemStop << seperator if (y == height - 1): out << lineStop << returnStop else: out << lineStop << '\n' if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)) : self.mError = self.tr("Could not open file for writing.") return False out = QTextStream(file) # Write the header header = map.property("header") for line in header.split("\\n"): out << line << '\n' width = map.width() height = map.height() asciiMap = QList() cachedTiles = QHash() propertyOrder = QList() propertyOrder.append("terrain") propertyOrder.append("object") propertyOrder.append("actor") propertyOrder.append("trap") propertyOrder.append("status") propertyOrder.append("spot") # Ability to handle overflow and strings for display outputLists = False asciiDisplay = ASCII_MIN overflowDisplay = 1 # Add the empty tile numEmptyTiles = 0 emptyTile = Properties() emptyTile["display"] = "?" cachedTiles["?"] = emptyTile # Process the map, collecting used display strings as we go for y in range(0, height): for x in range(0, width): currentTile = cachedTiles["?"] for layer in map.layers(): # If the layer name does not start with one of the tile properties, skip it layerKey = '' for currentProperty in propertyOrder: if (layer.name().lower().startswith(currentProperty.lower())) : layerKey = currentProperty break if layerKey == '': continue tileLayer = layer.asTileLayer() objectLayer = layer.asObjectGroup() # Process the Tile Layer if (tileLayer) : tile = tileLayer.cellAt(x, y).tile if (tile) : currentTile["display"] = tile.property("display") currentTile[layerKey] = tile.property("value") # Process the Object Layer elif (objectLayer) : for obj in objectLayer.objects(): if (math.floor(obj.y()) <= y and y <= math.floor(obj.y() + obj.height())) : if (math.floor(obj.x()) <= x and x <= math.floor(obj.x() + obj.width())) : # Check the Object Layer properties if either display or value was missing if (not obj.property("display").isEmpty()) : currentTile["display"] = obj.property("display") elif (not objectLayer.property("display").isEmpty()) : currentTile["display"] = objectLayer.property("display") if (not obj.property("value").isEmpty()) : currentTile[layerKey] = obj.property("value") elif (not objectLayer.property("value").isEmpty()) : currentTile[layerKey] = objectLayer.property("value") # If the currentTile does not exist in the cache, add it if (not cachedTiles.contains(currentTile["display"])) : cachedTiles[currentTile["display"]] = currentTile # Otherwise check that it EXACTLY matches the cached one # and if not... elif (currentTile != cachedTiles[currentTile["display"]]) : # Search the cached tiles for a match foundInCache = False displayString = QString() for i in cachedTiles.items(): displayString = i[0] currentTile["display"] = displayString if (currentTile == i[1]) : foundInCache = True break # If we haven't found a match then find a random display string # and cache it if (not foundInCache) : while (True) : # First try to use the ASCII characters if (asciiDisplay < ASCII_MAX) : displayString = asciiDisplay asciiDisplay += 1 # Then fall back onto integers else : displayString = QString.number(overflowDisplay) overflowDisplay += 1 currentTile["display"] = displayString if (not cachedTiles.contains(displayString)) : cachedTiles[displayString] = currentTile break elif (currentTile == cachedTiles[currentTile["display"]]) : break # Check the output type if len(currentTile["display"]) > 1: outputLists = True # Check if we are still the emptyTile if (currentTile == emptyTile) : numEmptyTiles += 1 # Finally add the character to the asciiMap asciiMap.append(currentTile["display"]) # Write the definitions to the file out << "-- defineTile section\n" for i in cachedTiles.items(): displayString = i[0] # Only print the emptyTile definition if there were empty tiles if (displayString == "?" and numEmptyTiles == 0) : continue # Need to escape " and \ characters displayString.replace('\\', "\\\\") displayString.replace('"', "\\\"") args = self.constructArgs(i[1], propertyOrder) if (not args.isEmpty()) : args = QString(", %1").arg(args) out << "defineTile(\"%s\"%s)\n"%(displayString, args) # Check for an ObjectGroup named AddSpot out << "\n-- addSpot section\n" for layer in map.layers(): objectLayer = layer.asObjectGroup() if (objectLayer and objectLayer.name().lower().startsWith("addspot")): for obj in objectLayer.objects(): propertyOrder = QList() propertyOrder.append("type") propertyOrder.append("subtype") propertyOrder.append("additional") args = self.constructArgs(obj.properties(), propertyOrder) if (not args.isEmpty()) : args = QString(", %1").arg(args) for y in range(math.floor(obj.y()), math.floor(obj.y() + obj.height())): for y in range(math.floor(obj.x()), math.floor(obj.x() + obj.width())): out << "addSpot({%s, %s}%s)\n"%(x, y, args) # Check for an ObjectGroup named AddZone out << "\n-- addZone section\n" for layer in map.layers(): objectLayer = layer.asObjectGroup() if (objectLayer and objectLayer.name().lower().startsWith("addzone")): for obj in objectLayer.objects(): propertyOrder = QList() propertyOrder.append("type") propertyOrder.append("subtype") propertyOrder.append("additional") args = self.constructArgs(obj.properties(), propertyOrder) if (not args.isEmpty()) : args = QString(", %1").arg(args) top_left_x = math.floor(obj.x()) top_left_y = math.floor(obj.y()) bottom_right_x = math.floor(obj.x() + obj.width()) bottom_right_y = math.floor(obj.y() + obj.height()) out << "addZone({%s, %s, %s, %s}%s)"%(top_left_x, top_left_y, bottom_right_x, bottom_right_y, args) # Write the map returnStart = QString() returnStop = QString() lineStart = QString() lineStop = QString() itemStart = QString() itemStop = QString() seperator = QString() if (outputLists) : returnStart = "{" returnStop = "}" lineStart = "{" lineStop = "}," itemStart = "[[" itemStop = "]]" seperator = "," else : returnStart = "[[" returnStop = "]]" lineStart = "" lineStop = "" itemStart = "" itemStop = "" seperator = "" out << "\n-- ASCII map section\n" out << "return " << returnStart << '\n' for y in range(0, height): out << lineStart for x in range(0, width): out << itemStart << asciiMap[x + (y * width)] << itemStop << seperator if (y == height - 1): out << lineStop << returnStop else : out << lineStop << '\n' if not file.commit(): self.mError = file.errorString() return False return True