void TilesetView::exportTileset() { Tileset *tileset = tilesetModel()->tileset(); const QLatin1String extension(".tsx"); QString suggestedFileName = QFileInfo(mMapDocument->fileName()).path(); suggestedFileName += QLatin1Char('/'); suggestedFileName += tileset->name(); if (!suggestedFileName.endsWith(extension)) suggestedFileName.append(extension); const QString fileName = QFileDialog::getSaveFileName(this, tr("Export Tileset"), suggestedFileName, tr("Tiled tileset files (*.tsx)")); if (fileName.isEmpty()) return; TmxMapWriter writer; if (writer.writeTileset(tileset, fileName)) { QUndoCommand *command = new SetTilesetFileName(tileset, fileName); mMapDocument->undoStack()->push(command); } }
void TilesetDock::deleteTilesetView(int index) { TilesetDocument *tilesetDocument = mTilesetDocuments.at(index); tilesetDocument->disconnect(this); Tileset *tileset = tilesetDocument->tileset().data(); TilesetView *view = tilesetViewAt(index); QString path = QLatin1String("TilesetDock/TilesetScale/") + tileset->name(); QSettings *settings = Preferences::instance()->settings(); if (view->scale() != 1.0) settings->setValue(path, view->scale()); else settings->remove(path); mTilesets.remove(index); mTilesetDocuments.removeAt(index); delete view; // view needs to go before the tab mTabBar->removeTab(index); // Make sure we don't reference this tileset anymore if (mCurrentTiles && mCurrentTiles->referencesTileset(tileset)) { TileLayer *cleaned = mCurrentTiles->clone(); cleaned->removeReferencesToTileset(tileset); setCurrentTiles(cleaned); } if (mCurrentTile && mCurrentTile->tileset() == tileset) setCurrentTile(nullptr); }
void TilesetDock::exportTileset() { Tileset *tileset = currentTileset(); if (!tileset) return; const QString tsxFilter = tr("Tiled tileset files (*.tsx)"); FormatHelper<TilesetFormat> helper(FileFormat::ReadWrite, tsxFilter); Preferences *prefs = Preferences::instance(); QString suggestedFileName = prefs->lastPath(Preferences::ExternalTileset); suggestedFileName += QLatin1Char('/'); suggestedFileName += tileset->name(); const QLatin1String extension(".tsx"); if (!suggestedFileName.endsWith(extension)) suggestedFileName.append(extension); QString selectedFilter = tsxFilter; const QString fileName = QFileDialog::getSaveFileName(this, tr("Export Tileset"), suggestedFileName, helper.filter(), &selectedFilter); if (fileName.isEmpty()) return; prefs->setLastPath(Preferences::ExternalTileset, QFileInfo(fileName).path()); TsxTilesetFormat tsxFormat; TilesetFormat *format = helper.formatByNameFilter(selectedFilter); if (!format) format = &tsxFormat; if (format->write(*tileset, fileName)) { QUndoCommand *command = new SetTilesetFileName(mMapDocument, tileset, fileName); mMapDocument->undoStack()->push(command); } else { QString error = format->errorString(); QMessageBox::critical(window(), tr("Export Tileset"), tr("Error saving tileset: %1").arg(error)); } }
void TilesetEditor::addDocument(Document *document) { TilesetDocument *tilesetDocument = qobject_cast<TilesetDocument*>(document); Q_ASSERT(tilesetDocument); TilesetView *view = new TilesetView(mWidgetStack); view->setTilesetDocument(tilesetDocument); Tileset *tileset = tilesetDocument->tileset().data(); QString path = QLatin1String("TilesetEditor/TilesetScale/") + tileset->name(); qreal scale = Preferences::instance()->settings()->value(path, 1).toReal(); view->zoomable()->setScale(scale); view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); TilesetModel *tilesetModel = new TilesetModel(tileset, view); view->setModel(tilesetModel); connect(tilesetDocument, &TilesetDocument::tileTerrainChanged, tilesetModel, &TilesetModel::tilesChanged); connect(tilesetDocument, &TilesetDocument::tileWangSetChanged, tilesetModel, &TilesetModel::tilesChanged); connect(tilesetDocument, &TilesetDocument::tileImageSourceChanged, tilesetModel, &TilesetModel::tileChanged); connect(tilesetDocument, &TilesetDocument::tileAnimationChanged, tilesetModel, &TilesetModel::tileChanged); connect(tilesetDocument, &TilesetDocument::tilesetChanged, this, &TilesetEditor::tilesetChanged); connect(view, &TilesetView::createNewTerrain, this, &TilesetEditor::addTerrainType); connect(view, &TilesetView::terrainImageSelected, this, &TilesetEditor::setTerrainImage); connect(view, &TilesetView::wangSetImageSelected, this, &TilesetEditor::setWangSetImage); connect(view, &TilesetView::wangColorImageSelected, this, &TilesetEditor::setWangColorImage); connect(view, &TilesetView::wangIdUsedChanged, mWangDock, &WangDock::onWangIdUsedChanged); connect(view, &TilesetView::currentWangIdChanged, mWangDock, &WangDock::onCurrentWangIdChanged); QItemSelectionModel *s = view->selectionModel(); connect(s, &QItemSelectionModel::selectionChanged, this, &TilesetEditor::selectionChanged); connect(s, &QItemSelectionModel::currentChanged, this, &TilesetEditor::currentChanged); connect(view, &TilesetView::pressed, this, &TilesetEditor::indexPressed); mViewForTileset.insert(tilesetDocument, view); mWidgetStack->addWidget(view); }
/** * Removes the tileset at the given index. Prompting the user when the tileset * is in use by the map. */ void TilesetDock::removeTileset(int index) { auto &sharedTileset = mTilesets.at(index); int mapTilesetIndex = mMapDocument->map()->tilesets().indexOf(sharedTileset); if (mapTilesetIndex == -1) return; Tileset *tileset = sharedTileset.data(); const bool inUse = mMapDocument->map()->isTilesetUsed(tileset); // If the tileset is in use, warn the user and confirm removal if (inUse) { QMessageBox warning(QMessageBox::Warning, tr("Remove Tileset"), tr("The tileset \"%1\" is still in use by the " "map!").arg(tileset->name()), QMessageBox::Yes | QMessageBox::No, this); warning.setDefaultButton(QMessageBox::Yes); warning.setInformativeText(tr("Remove this tileset and all references " "to the tiles in this tileset?")); if (warning.exec() != QMessageBox::Yes) return; } QUndoCommand *remove = new RemoveTileset(mMapDocument, mapTilesetIndex); QUndoStack *undoStack = mMapDocument->undoStack(); if (inUse) { // Remove references to tiles in this tileset from the current map auto referencesTileset = [tileset] (const Cell &cell) { return cell.tileset() == tileset; }; undoStack->beginMacro(remove->text()); removeTileReferences(mMapDocument, referencesTileset); } undoStack->push(remove); if (inUse) undoStack->endMacro(); }
QVariant MapToVariantConverter::toVariant(const Tileset &tileset, int firstGid) const { QVariantMap tilesetVariant; if (firstGid > 0) tilesetVariant[QLatin1String("firstgid")] = firstGid; else tilesetVariant[QLatin1String("version")] = 1.2; // external tileset const QString &fileName = tileset.fileName(); if (!fileName.isEmpty() && firstGid > 0) { QString source = mMapDir.relativeFilePath(fileName); tilesetVariant[QLatin1String("source")] = source; // Tileset is external, so no need to write any of the stuff below return tilesetVariant; } // Include a 'type' property if we are writing the tileset to its own file if (firstGid == 0) tilesetVariant[QLatin1String("type")] = QLatin1String("tileset"); tilesetVariant[QLatin1String("name")] = tileset.name(); tilesetVariant[QLatin1String("tilewidth")] = tileset.tileWidth(); tilesetVariant[QLatin1String("tileheight")] = tileset.tileHeight(); tilesetVariant[QLatin1String("spacing")] = tileset.tileSpacing(); tilesetVariant[QLatin1String("margin")] = tileset.margin(); tilesetVariant[QLatin1String("tilecount")] = tileset.tileCount(); tilesetVariant[QLatin1String("columns")] = tileset.columnCount(); const QColor bgColor = tileset.backgroundColor(); if (bgColor.isValid()) tilesetVariant[QLatin1String("backgroundcolor")] = colorToString(bgColor); addProperties(tilesetVariant, tileset.properties()); const QPoint offset = tileset.tileOffset(); if (!offset.isNull()) { QVariantMap tileOffset; tileOffset[QLatin1String("x")] = offset.x(); tileOffset[QLatin1String("y")] = offset.y(); tilesetVariant[QLatin1String("tileoffset")] = tileOffset; } if (tileset.orientation() != Tileset::Orthogonal || tileset.gridSize() != tileset.tileSize()) { QVariantMap grid; grid[QLatin1String("orientation")] = Tileset::orientationToString(tileset.orientation()); grid[QLatin1String("width")] = tileset.gridSize().width(); grid[QLatin1String("height")] = tileset.gridSize().height(); tilesetVariant[QLatin1String("grid")] = grid; } // Write the image element const QUrl &imageSource = tileset.imageSource(); if (!imageSource.isEmpty()) { const QString rel = toFileReference(imageSource, mMapDir); tilesetVariant[QLatin1String("image")] = rel; const QColor transColor = tileset.transparentColor(); if (transColor.isValid()) tilesetVariant[QLatin1String("transparentcolor")] = transColor.name(); tilesetVariant[QLatin1String("imagewidth")] = tileset.imageWidth(); tilesetVariant[QLatin1String("imageheight")] = tileset.imageHeight(); } // Write the properties, terrain, external image, object group and // animation for those tiles that have them. QVariantList tilesVariant; for (const Tile *tile : tileset.tiles()) { const Properties properties = tile->properties(); QVariantMap tileVariant; addProperties(tileVariant, properties); if (!tile->type().isEmpty()) tileVariant[QLatin1String("type")] = tile->type(); if (tile->terrain() != 0xFFFFFFFF) { QVariantList terrainIds; for (int j = 0; j < 4; ++j) terrainIds << QVariant(tile->cornerTerrainId(j)); tileVariant[QLatin1String("terrain")] = terrainIds; } if (tile->probability() != 1.0) tileVariant[QLatin1String("probability")] = tile->probability(); if (!tile->imageSource().isEmpty()) { const QString rel = toFileReference(tile->imageSource(), mMapDir); tileVariant[QLatin1String("image")] = rel; const QSize tileSize = tile->size(); if (!tileSize.isNull()) { tileVariant[QLatin1String("imagewidth")] = tileSize.width(); tileVariant[QLatin1String("imageheight")] = tileSize.height(); } } if (tile->objectGroup()) tileVariant[QLatin1String("objectgroup")] = toVariant(*tile->objectGroup()); if (tile->isAnimated()) { QVariantList frameVariants; for (const Frame &frame : tile->frames()) { QVariantMap frameVariant; frameVariant[QLatin1String("tileid")] = frame.tileId; frameVariant[QLatin1String("duration")] = frame.duration; frameVariants.append(frameVariant); } tileVariant[QLatin1String("animation")] = frameVariants; } if (!tileVariant.empty()) { tileVariant[QLatin1String("id")] = tile->id(); tilesVariant << tileVariant; } } if (!tilesVariant.empty()) tilesetVariant[QLatin1String("tiles")] = tilesVariant; // Write terrains if (tileset.terrainCount() > 0) { QVariantList terrainsVariant; for (int i = 0; i < tileset.terrainCount(); ++i) { Terrain *terrain = tileset.terrain(i); const Properties &properties = terrain->properties(); QVariantMap terrainVariant; terrainVariant[QLatin1String("name")] = terrain->name(); terrainVariant[QLatin1String("tile")] = terrain->imageTileId(); addProperties(terrainVariant, properties); terrainsVariant << terrainVariant; } tilesetVariant[QLatin1String("terrains")] = terrainsVariant; } return tilesetVariant; }