From a9ad61774aff14af05810d6802ddb3389b1552af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 24 Mar 2020 22:34:03 +0100 Subject: [PATCH] Refactoring of Session and Preferences * Session is now based on QSettings with a JSON backend, instead of manually saving and loading to JSON. * Preferences just forwards to QSettings backend instead of storing the settings internally as well. --- src/tiled/documentmanager.cpp | 4 +- src/tiled/mainwindow.cpp | 28 +- src/tiled/preferences.cpp | 611 ++++++++++++++++------------------ src/tiled/preferences.h | 237 +------------ src/tiled/projectdock.cpp | 2 +- src/tiled/session.cpp | 183 +++++----- src/tiled/session.h | 132 +++----- src/tiled/utils.cpp | 22 ++ src/tiled/utils.h | 5 + 9 files changed, 466 insertions(+), 758 deletions(-) diff --git a/src/tiled/documentmanager.cpp b/src/tiled/documentmanager.cpp index 261e51a860..fd7f328ab4 100644 --- a/src/tiled/documentmanager.cpp +++ b/src/tiled/documentmanager.cpp @@ -1225,8 +1225,8 @@ void DocumentManager::updateSession() const auto doc = currentDocument(); auto prefs = Preferences::instance(); - prefs->session().setOpenFiles(fileList); - prefs->session().setActiveFile(doc ? doc->fileName() : QString()); + prefs->session().openFiles = fileList; + prefs->session().activeFile = doc ? doc->fileName() : QString(); prefs->saveSession(); } diff --git a/src/tiled/mainwindow.cpp b/src/tiled/mainwindow.cpp index 7e4dfce7a9..0bc0d953f4 100644 --- a/src/tiled/mainwindow.cpp +++ b/src/tiled/mainwindow.cpp @@ -896,17 +896,15 @@ void MainWindow::initializeSession() if (!prefs->restoreSessionOnStartup()) return; - Session session = Session::load(prefs->lastSession()); + const auto &session { prefs->session() }; // Restore associated project if applicable Project project; - if (!session.project().isEmpty() && project.load(session.project())) { + if (!session.project.isEmpty() && project.load(session.project)) { mProjectDock->setProject(std::move(project)); updateWindowTitle(); } - prefs->switchSession(std::move(session)); - restoreSession(); } @@ -1228,8 +1226,8 @@ void MainWindow::openProjectFile(const QString &fileName) if (!closeAllFiles()) return; - Session session = Session::load(Session::defaultFileNameForProject(fileName)); - session.setProject(fileName); + Session session { Session::defaultFileNameForProject(fileName) }; + session.project = fileName; mProjectDock->setProject(std::move(project)); prefs->addRecentProject(fileName); @@ -1291,10 +1289,12 @@ void MainWindow::saveProjectAs() } prefs->addRecentProject(fileName); - prefs->session().setProject(fileName); + prefs->session().project = fileName; const auto sessionFileName = Session::defaultFileNameForProject(fileName); - prefs->saveSessionNow(sessionFileName); + prefs->session().setFileName(sessionFileName); + + prefs->saveSessionNow(); prefs->setLastSession(sessionFileName); updateWindowTitle(); @@ -1314,7 +1314,7 @@ void MainWindow::closeProject() return; mProjectDock->setProject(Project{}); - prefs->switchSession(Session::load(Session::defaultFileName())); + prefs->switchSession(Session { Session::defaultFileName() }); restoreSession(); updateWindowTitle(); @@ -1326,14 +1326,14 @@ void MainWindow::restoreSession() const auto &session = Preferences::instance()->session(); // Copy values because the session will get changed while restoring it - const auto openFiles = session.openFiles(); - const auto activeFile = session.activeFile(); + const auto openFiles = session.openFiles; + const auto activeFile = session.activeFile; for (const QString &file : openFiles) openFile(file); mDocumentManager->switchToDocument(activeFile); - mProjectDock->setExpandedPaths(session.expandedProjectPaths()); + mProjectDock->setExpandedPaths(session.expandedProjectPaths); } void MainWindow::cut() @@ -1707,7 +1707,7 @@ void MainWindow::openRecentFile() void MainWindow::reopenClosedFile() { - const auto recentFiles = Preferences::instance()->session().recentFiles(); + const auto recentFiles = Preferences::instance()->session().recentFiles; for (const QString &file : recentFiles) { if (mDocumentManager->findDocument(file) == -1) { openFile(file); @@ -1728,7 +1728,7 @@ void MainWindow::openRecentProject() */ void MainWindow::updateRecentFilesMenu() { - const QStringList files = Preferences::instance()->session().recentFiles(); + const QStringList files = Preferences::instance()->session().recentFiles; const int numRecentFiles = qMin(files.size(), Preferences::MaxRecentFiles); for (int i = 0; i < numRecentFiles; ++i) { diff --git a/src/tiled/preferences.cpp b/src/tiled/preferences.cpp index ba8cafd5b5..f976c2d2d7 100644 --- a/src/tiled/preferences.cpp +++ b/src/tiled/preferences.cpp @@ -52,7 +52,8 @@ void Preferences::deleteInstance() } Preferences::Preferences() - : mSettings(new QSettings(this)) + : mSettings { new QSettings(this) } + , mSession { restoreSessionOnStartup() ? lastSession() : Session::defaultFileName() } { // Make sure the data directory exists const QDir dataDir { dataLocation() }; @@ -62,68 +63,12 @@ Preferences::Preferences() connect(&mWatcher, &FileSystemWatcher::fileChanged, this, &Preferences::objectTypesFileChangedOnDisk); - // Retrieve storage settings - mSettings->beginGroup(QLatin1String("Storage")); - mLayerDataFormat = static_cast - (intValue("LayerDataFormat", Map::CSV)); - mMapRenderOrder = static_cast - (intValue("MapRenderOrder", Map::RightDown)); - mDtdEnabled = boolValue("DtdEnabled"); - mSafeSavingEnabled = boolValue("SafeSavingEnabled", true); - mExportOnSave = boolValue("ExportOnSave", false); - mReloadTilesetsOnChange = boolValue("ReloadTilesets", true); - mStampsDirectory = stringValue("StampsDirectory"); - mTemplatesDirectory = stringValue("TemplatesDirectory"); - mObjectTypesFile = stringValue("ObjectTypesFile"); - mSettings->endGroup(); - - mSettings->beginGroup(QLatin1String("Export")); - setExportOption(EmbedTilesets, boolValue("EmbedTilesets", false)); - setExportOption(DetachTemplateInstances, boolValue("DetachTemplateInstances", false)); - setExportOption(ResolveObjectTypesAndProperties, boolValue("ResolveObjectTypesAndProperties", false)); - setExportOption(ExportMinimized, boolValue("Minimized", false)); - mSettings->endGroup(); - - SaveFile::setSafeSavingEnabled(mSafeSavingEnabled); - - // Retrieve interface settings - mSettings->beginGroup(QLatin1String("Interface")); - mShowGrid = boolValue("ShowGrid", true); - mShowTileObjectOutlines = boolValue("ShowTileObjectOutlines"); - mShowTileAnimations = boolValue("ShowTileAnimations", true); - mShowTileCollisionShapes = boolValue("ShowTileCollisionShapes"); - mShowObjectReferences = boolValue("ShowObjectReferences", true); - mSnapToGrid = boolValue("SnapToGrid"); - mSnapToFineGrid = boolValue("SnapToFineGrid"); - mSnapToPixels = boolValue("SnapToPixels"); - mGridColor = colorValue("GridColor", Qt::black); - mGridFine = intValue("GridFine", 4); - mObjectLineWidth = realValue("ObjectLineWidth", 2); - mHighlightCurrentLayer = boolValue("HighlightCurrentLayer"); - mHighlightHoveredObject = boolValue("HighlightHoveredObject", true); - mShowTilesetGrid = boolValue("ShowTilesetGrid", true); - mLanguage = stringValue("Language"); - mUseOpenGL = boolValue("OpenGL"); - mWheelZoomsByDefault = boolValue("WheelZoomsByDefault"); - mObjectLabelVisibility = static_cast - (intValue("ObjectLabelVisibility", AllObjectLabels)); - mLabelForHoveredObject = boolValue("LabelForHoveredObject", false); -#if defined(Q_OS_MAC) - mApplicationStyle = static_cast - (intValue("ApplicationStyle", SystemDefaultStyle)); -#else - mApplicationStyle = static_cast - (intValue("ApplicationStyle", TiledStyle)); -#endif + SaveFile::setSafeSavingEnabled(safeSavingEnabled()); // Backwards compatibility check since 'FusionStyle' was removed from the // preferences dialog. - if (mApplicationStyle == FusionStyle) - mApplicationStyle = TiledStyle; - - mBaseColor = colorValue("BaseColor", Qt::lightGray); - mSelectionColor = colorValue("SelectionColor", QColor(48, 140, 198)); - mSettings->endGroup(); + if (applicationStyle() == FusionStyle) + setApplicationStyle(TiledStyle); // Retrieve defined object types ObjectTypesSerializer objectTypesSerializer; @@ -159,9 +104,9 @@ Preferences::Preferences() Session session(Session::defaultFileName()); mSettings->beginGroup(QLatin1String("recentFiles")); - session.setRecentFiles(mSettings->value(QLatin1String("fileNames")).toStringList()); - session.setOpenFiles(mSettings->value(QLatin1String("lastOpenFiles")).toStringList()); - session.setActiveFile(mSettings->value(QLatin1String("lastActive")).toString()); + session.recentFiles = mSettings->value(QLatin1String("fileNames")).toStringList(); + session.openFiles = mSettings->value(QLatin1String("lastOpenFiles")).toStringList(); + session.activeFile = mSettings->value(QLatin1String("lastActive")).toString(); mSettings->endGroup(); const QVariantMap mapStates = mSettings->value(QLatin1String("MapEditor/MapStates")).toMap(); @@ -186,13 +131,9 @@ Preferences::Preferences() } } - mSettings->beginGroup(QLatin1String("Automapping")); - mAutoMapDrawing = boolValue("WhileDrawing"); - mSettings->endGroup(); - TilesetManager *tilesetManager = TilesetManager::instance(); - tilesetManager->setReloadTilesetsOnChange(mReloadTilesetsOnChange); - tilesetManager->setAnimateTiles(mShowTileAnimations); + tilesetManager->setReloadTilesetsOnChange(reloadTilesetsOnChange()); + tilesetManager->setAnimateTiles(showTileAnimations()); // Read the lists of enabled and disabled plugins const QStringList disabledPlugins = mSettings->value(QLatin1String("Plugins/Disabled")).toStringList(); @@ -205,287 +146,301 @@ Preferences::Preferences() pluginManager->setPluginState(fileName, PluginEnabled); // Keeping track of some usage information - mSettings->beginGroup(QLatin1String("Install")); - if (mSettings->contains(QLatin1String("PatreonDialogTime"))) { - mSettings->setValue(QLatin1String("DonationDialogTime"), mSettings->value(QLatin1String("PatreonDialogTime"))); - mSettings->remove(QLatin1String("PatreonDialogTime")); - } - mFirstRun = mSettings->value(QLatin1String("FirstRun")).toDate(); - mDonationDialogTime = mSettings->value(QLatin1String("DonationDialogTime")).toDate(); - mRunCount = intValue("RunCount", 0) + 1; - mIsPatron = boolValue("IsPatron"); - mCheckForUpdates = boolValue("CheckForUpdates", true); - mDisplayNews = boolValue("DisplayNews", true); - if (!mFirstRun.isValid()) { - mFirstRun = QDate::currentDate(); - mSettings->setValue(QLatin1String("FirstRun"), mFirstRun.toString(Qt::ISODate)); + if (mSettings->contains(QLatin1String("Install/PatreonDialogTime"))) { + mSettings->setValue(QLatin1String("Install/DonationDialogTime"), mSettings->value(QLatin1String("Install/PatreonDialogTime"))); + mSettings->remove(QLatin1String("Install/PatreonDialogTime")); } - if (!mSettings->contains(QLatin1String("DonationDialogTime"))) { - mDonationDialogTime = mFirstRun.addMonths(1); + + if (!firstRun().isValid()) + mSettings->setValue(QLatin1String("Install/FirstRun"), QDate::currentDate().toString(Qt::ISODate)); + + if (!mSettings->contains(QLatin1String("Install/DonationDialogTime"))) { + QDate donationDialogTime = firstRun().addMonths(1); const QDate today(QDate::currentDate()); - if (mDonationDialogTime.daysTo(today) >= 0) - mDonationDialogTime = today.addDays(2); - mSettings->setValue(QLatin1String("DonationDialogTime"), mDonationDialogTime.toString(Qt::ISODate)); + if (donationDialogTime.daysTo(today) >= 0) + donationDialogTime = today.addDays(2); + mSettings->setValue(QLatin1String("Install/DonationDialogTime"), donationDialogTime.toString(Qt::ISODate)); } - mSettings->setValue(QLatin1String("RunCount"), mRunCount); - mSettings->endGroup(); - - // Retrieve startup settings - mSettings->beginGroup(QLatin1String("Startup")); - mRestoreSessionOnStartup = boolValue("RestorePreviousSession", true); - mSettings->endGroup(); + mSettings->setValue(QLatin1String("Install/RunCount"), runCount() + 1); } Preferences::~Preferences() { } -void Preferences::setObjectLabelVisibility(ObjectLabelVisiblity visibility) +bool Preferences::showGrid() const { - if (mObjectLabelVisibility == visibility) - return; + return boolValue("Interface/ShowGrid", true); +} + +bool Preferences::showTileObjectOutlines() const +{ + return boolValue("Interface/ShowTileObjectOutlines"); +} + +bool Preferences::showTileAnimations() const +{ + return boolValue("Interface/ShowTileAnimations", true); +} + +bool Preferences::showTileCollisionShapes() const +{ + return boolValue("Interface/ShowTileCollisionShapes"); +} + +bool Preferences::showObjectReferences() const +{ + return boolValue("Interface/ShowObjectReferences", true); +} + +bool Preferences::snapToGrid() const +{ + return boolValue("Interface/SnapToGrid"); +} + +bool Preferences::snapToFineGrid() const +{ + return boolValue("Interface/SnapToFineGrid"); +} + +bool Preferences::snapToPixels() const +{ + return boolValue("Interface/SnapToPixels"); +} + +QColor Preferences::gridColor() const +{ + return colorValue("Interface/GridColor", Qt::black); +} + +int Preferences::gridFine() const +{ + return intValue("Interface/GridFine", 4); +} + +qreal Preferences::objectLineWidth() const +{ + return realValue("Interface/ObjectLineWidth", 2); +} + +bool Preferences::highlightCurrentLayer() const +{ + return boolValue("Interface/HighlightCurrentLayer"); +} + +bool Preferences::highlightHoveredObject() const +{ + return boolValue("Interface/HighlightHoveredObject", true); +} + +bool Preferences::showTilesetGrid() const +{ + return boolValue("Interface/ShowTilesetGrid", true); +} - mObjectLabelVisibility = visibility; +Preferences::ObjectLabelVisiblity Preferences::objectLabelVisibility() const +{ + return static_cast(intValue("Interface/ObjectLabelVisibility", AllObjectLabels)); +} + +void Preferences::setObjectLabelVisibility(ObjectLabelVisiblity visibility) +{ mSettings->setValue(QLatin1String("Interface/ObjectLabelVisibility"), visibility); emit objectLabelVisibilityChanged(visibility); } -void Preferences::setLabelForHoveredObject(bool enabled) +bool Preferences::labelForHoveredObject() const { - if (mLabelForHoveredObject == enabled) - return; + return boolValue("Interface/LabelForHoveredObject", false); +} - mLabelForHoveredObject = enabled; +void Preferences::setLabelForHoveredObject(bool enabled) +{ mSettings->setValue(QLatin1String("Interface/LabelForHoveredObject"), enabled); emit labelForHoveredObjectChanged(enabled); } -void Preferences::setApplicationStyle(ApplicationStyle style) +Preferences::ApplicationStyle Preferences::applicationStyle() const { - if (mApplicationStyle == style) - return; +#if defined(Q_OS_MAC) + return static_cast(intValue("Interface/ApplicationStyle", SystemDefaultStyle)); +#else + return static_cast(intValue("Interface/ApplicationStyle", TiledStyle)); +#endif +} - mApplicationStyle = style; +void Preferences::setApplicationStyle(ApplicationStyle style) +{ mSettings->setValue(QLatin1String("Interface/ApplicationStyle"), style); emit applicationStyleChanged(style); } -void Preferences::setBaseColor(const QColor &color) +QColor Preferences::baseColor() const { - if (mBaseColor == color) - return; + return colorValue("Interface/BaseColor", Qt::lightGray); +} - mBaseColor = color; +void Preferences::setBaseColor(const QColor &color) +{ mSettings->setValue(QLatin1String("Interface/BaseColor"), color.name()); emit baseColorChanged(color); } -void Preferences::setSelectionColor(const QColor &color) +QColor Preferences::selectionColor() const { - if (mSelectionColor == color) - return; + return colorValue("Interface/SelectionColor", QColor(48, 140, 198)); +} - mSelectionColor = color; +void Preferences::setSelectionColor(const QColor &color) +{ mSettings->setValue(QLatin1String("Interface/SelectionColor"), color.name()); emit selectionColorChanged(color); } -void Preferences::setShowGrid(bool showGrid) +Map::LayerDataFormat Preferences::layerDataFormat() const { - if (mShowGrid == showGrid) - return; + return static_cast(intValue("Storage/LayerDataFormat", Map::CSV)); +} - mShowGrid = showGrid; - mSettings->setValue(QLatin1String("Interface/ShowGrid"), mShowGrid); - emit showGridChanged(mShowGrid); +void Preferences::setShowGrid(bool showGrid) +{ + mSettings->setValue(QLatin1String("Interface/ShowGrid"), showGrid); + emit showGridChanged(showGrid); } void Preferences::setShowTileObjectOutlines(bool enabled) { - if (mShowTileObjectOutlines == enabled) - return; - - mShowTileObjectOutlines = enabled; - mSettings->setValue(QLatin1String("Interface/ShowTileObjectOutlines"), - mShowTileObjectOutlines); - emit showTileObjectOutlinesChanged(mShowTileObjectOutlines); + mSettings->setValue(QLatin1String("Interface/ShowTileObjectOutlines"), enabled); + emit showTileObjectOutlinesChanged(enabled); } void Preferences::setShowTileAnimations(bool enabled) { - if (mShowTileAnimations == enabled) - return; - - mShowTileAnimations = enabled; - mSettings->setValue(QLatin1String("Interface/ShowTileAnimations"), - mShowTileAnimations); - - TilesetManager *tilesetManager = TilesetManager::instance(); - tilesetManager->setAnimateTiles(mShowTileAnimations); - - emit showTileAnimationsChanged(mShowTileAnimations); + mSettings->setValue(QLatin1String("Interface/ShowTileAnimations"), enabled); + TilesetManager::instance()->setAnimateTiles(enabled); + emit showTileAnimationsChanged(enabled); } void Preferences::setShowTileCollisionShapes(bool enabled) { - if (mShowTileCollisionShapes == enabled) - return; - - mShowTileCollisionShapes = enabled; - mSettings->setValue(QLatin1String("Interface/ShowTileCollisionShapes"), - mShowTileCollisionShapes); - + mSettings->setValue(QLatin1String("Interface/ShowTileCollisionShapes"), enabled); emit showTileCollisionShapesChanged(enabled); } void Preferences::setShowObjectReferences(bool enabled) { - if (mShowObjectReferences == enabled) - return; - - mShowObjectReferences = enabled; - mSettings->setValue(QLatin1String("Interface/ShowObjectReferences"), - mShowObjectReferences); - + mSettings->setValue(QLatin1String("Interface/ShowObjectReferences"), enabled); emit showObjectReferencesChanged(enabled); } void Preferences::setSnapToGrid(bool snapToGrid) { - if (mSnapToGrid == snapToGrid) - return; - - mSnapToGrid = snapToGrid; - mSettings->setValue(QLatin1String("Interface/SnapToGrid"), mSnapToGrid); - emit snapToGridChanged(mSnapToGrid); + mSettings->setValue(QLatin1String("Interface/SnapToGrid"), snapToGrid); + emit snapToGridChanged(snapToGrid); } void Preferences::setSnapToFineGrid(bool snapToFineGrid) { - if (mSnapToFineGrid == snapToFineGrid) - return; - - mSnapToFineGrid = snapToFineGrid; - mSettings->setValue(QLatin1String("Interface/SnapToFineGrid"), mSnapToFineGrid); - emit snapToFineGridChanged(mSnapToFineGrid); + mSettings->setValue(QLatin1String("Interface/SnapToFineGrid"), snapToFineGrid); + emit snapToFineGridChanged(snapToFineGrid); } void Preferences::setSnapToPixels(bool snapToPixels) { - if (mSnapToPixels == snapToPixels) - return; - - mSnapToPixels = snapToPixels; - mSettings->setValue(QLatin1String("Interface/SnapToPixels"), mSnapToPixels); - emit snapToPixelsChanged(mSnapToPixels); + mSettings->setValue(QLatin1String("Interface/SnapToPixels"), snapToPixels); + emit snapToPixelsChanged(snapToPixels); } void Preferences::setGridColor(QColor gridColor) { - if (mGridColor == gridColor) - return; - - mGridColor = gridColor; - mSettings->setValue(QLatin1String("Interface/GridColor"), mGridColor.name()); - emit gridColorChanged(mGridColor); + mSettings->setValue(QLatin1String("Interface/GridColor"), gridColor.name()); + emit gridColorChanged(gridColor); } void Preferences::setGridFine(int gridFine) { - if (mGridFine == gridFine) - return; - mGridFine = gridFine; - mSettings->setValue(QLatin1String("Interface/GridFine"), mGridFine); - emit gridFineChanged(mGridFine); + mSettings->setValue(QLatin1String("Interface/GridFine"), gridFine); + emit gridFineChanged(gridFine); } void Preferences::setObjectLineWidth(qreal lineWidth) { - if (mObjectLineWidth == lineWidth) - return; - mObjectLineWidth = lineWidth; - mSettings->setValue(QLatin1String("Interface/ObjectLineWidth"), mObjectLineWidth); - emit objectLineWidthChanged(mObjectLineWidth); + mSettings->setValue(QLatin1String("Interface/ObjectLineWidth"), lineWidth); + emit objectLineWidthChanged(lineWidth); } void Preferences::setHighlightCurrentLayer(bool highlight) { - if (mHighlightCurrentLayer == highlight) - return; - - mHighlightCurrentLayer = highlight; - mSettings->setValue(QLatin1String("Interface/HighlightCurrentLayer"), - mHighlightCurrentLayer); - emit highlightCurrentLayerChanged(mHighlightCurrentLayer); + mSettings->setValue(QLatin1String("Interface/HighlightCurrentLayer"), highlight); + emit highlightCurrentLayerChanged(highlight); } void Preferences::setHighlightHoveredObject(bool highlight) { - if (mHighlightHoveredObject == highlight) - return; - - mHighlightHoveredObject = highlight; - mSettings->setValue(QLatin1String("Interface/HighlightHoveredObject"), - mHighlightHoveredObject); - emit highlightHoveredObjectChanged(mHighlightHoveredObject); + mSettings->setValue(QLatin1String("Interface/HighlightHoveredObject"), highlight); + emit highlightHoveredObjectChanged(highlight); } void Preferences::setShowTilesetGrid(bool showTilesetGrid) { - if (mShowTilesetGrid == showTilesetGrid) - return; - - mShowTilesetGrid = showTilesetGrid; - mSettings->setValue(QLatin1String("Interface/ShowTilesetGrid"), - mShowTilesetGrid); - emit showTilesetGridChanged(mShowTilesetGrid); + mSettings->setValue(QLatin1String("Interface/ShowTilesetGrid"), showTilesetGrid); + emit showTilesetGridChanged(showTilesetGrid); } -void Preferences::setLayerDataFormat(Map::LayerDataFormat - layerDataFormat) +void Preferences::setLayerDataFormat(Map::LayerDataFormat layerDataFormat) { - if (mLayerDataFormat == layerDataFormat) - return; + mSettings->setValue(QLatin1String("Storage/LayerDataFormat"), layerDataFormat); +} - mLayerDataFormat = layerDataFormat; - mSettings->setValue(QLatin1String("Storage/LayerDataFormat"), - mLayerDataFormat); +Map::RenderOrder Preferences::mapRenderOrder() const +{ + return static_cast(intValue("Storage/MapRenderOrder", Map::RightDown)); } void Preferences::setMapRenderOrder(Map::RenderOrder mapRenderOrder) { - if (mMapRenderOrder == mapRenderOrder) - return; + mSettings->setValue(QLatin1String("Storage/MapRenderOrder"), mapRenderOrder); +} - mMapRenderOrder = mapRenderOrder; - mSettings->setValue(QLatin1String("Storage/MapRenderOrder"), - mMapRenderOrder); +bool Preferences::safeSavingEnabled() const +{ + return boolValue("SafeSavingEnabled", true); } void Preferences::setSafeSavingEnabled(bool enabled) { - mSafeSavingEnabled = enabled; mSettings->setValue(QLatin1String("Storage/SafeSavingEnabled"), enabled); SaveFile::setSafeSavingEnabled(enabled); } +bool Preferences::exportOnSave() const +{ + return boolValue("Storage/ExportOnSave", false); +} + void Preferences::setExportOnSave(bool enabled) { - mExportOnSave = enabled; mSettings->setValue(QLatin1String("Storage/ExportOnSave"), enabled); } -void Preferences::setExportOption(Preferences::ExportOption option, bool value) +Preferences::ExportOptions Preferences::exportOptions() const { -#if QT_VERSION >= 0x050700 - mExportOptions.setFlag(option, value); -#else - if (value) - mExportOptions |= option; - else - mExportOptions &= ~option; -#endif + ExportOptions options; + + if (boolValue("Export/EmbedTilesets", false)) + options |= EmbedTilesets; + if (boolValue("Export/DetachTemplateInstances", false)) + options |= DetachTemplateInstances; + if (boolValue("Export/ResolveObjectTypesAndProperties", false)) + options |= ResolveObjectTypesAndProperties; + if (boolValue("Export/Minimized", false)) + options |= ExportMinimized; + + return options; +} +void Preferences::setExportOption(Preferences::ExportOption option, bool value) +{ switch (option) { case EmbedTilesets: mSettings->setValue(QLatin1String("Export/EmbedTilesets"), value); @@ -502,41 +457,53 @@ void Preferences::setExportOption(Preferences::ExportOption option, bool value) } } -void Preferences::setLanguage(const QString &language) +bool Preferences::exportOption(Preferences::ExportOption option) const { - if (mLanguage == language) - return; + switch (option) { + case EmbedTilesets: + return boolValue("Export/EmbedTilesets", false); + case DetachTemplateInstances: + return boolValue("Export/DetachTemplateInstances", false); + case ResolveObjectTypesAndProperties: + return boolValue("Export/ResolveObjectTypesAndProperties", false); + case ExportMinimized: + return boolValue("Export/Minimized", false); + } + return false; +} - mLanguage = language; - mSettings->setValue(QLatin1String("Interface/Language"), - mLanguage); +QString Preferences::language() const +{ + return stringValue("Interface/Language"); +} +void Preferences::setLanguage(const QString &language) +{ + mSettings->setValue(QLatin1String("Interface/Language"), language); LanguageManager::instance()->installTranslators(); emit languageChanged(); } -void Preferences::setReloadTilesetsOnChanged(bool value) +bool Preferences::reloadTilesetsOnChange() const { - if (mReloadTilesetsOnChange == value) - return; + return boolValue("Storage/ReloadTilesets", true); +} - mReloadTilesetsOnChange = value; - mSettings->setValue(QLatin1String("Storage/ReloadTilesets"), - mReloadTilesetsOnChange); +void Preferences::setReloadTilesetsOnChanged(bool reloadOnChanged) +{ + mSettings->setValue(QLatin1String("Storage/ReloadTilesets"), reloadOnChanged); + TilesetManager::instance()->setReloadTilesetsOnChange(reloadOnChanged); +} - TilesetManager *tilesetManager = TilesetManager::instance(); - tilesetManager->setReloadTilesetsOnChange(mReloadTilesetsOnChange); +bool Preferences::useOpenGL() const +{ + return boolValue("Interface/OpenGL"); } void Preferences::setUseOpenGL(bool useOpenGL) { - if (mUseOpenGL == useOpenGL) - return; - - mUseOpenGL = useOpenGL; - mSettings->setValue(QLatin1String("Interface/OpenGL"), mUseOpenGL); - - emit useOpenGLChanged(mUseOpenGL); + mSettings->setValue(QLatin1String("Interface/OpenGL"), useOpenGL); + emit useOpenGLChanged(useOpenGL); } void Preferences::setObjectTypes(const ObjectTypes &objectTypes) @@ -615,52 +582,70 @@ void Preferences::setLastPath(FileType fileType, const QString &path) mSettings->setValue(lastPathKey(fileType), path); } +bool Preferences::automappingDrawing() const +{ + return boolValue("Automapping/WhileDrawing"); +} + void Preferences::setAutomappingDrawing(bool enabled) { - mAutoMapDrawing = enabled; mSettings->setValue(QLatin1String("Automapping/WhileDrawing"), enabled); } -void Preferences::setPatron(bool isPatron) +QDate Preferences::firstRun() const { - if (mIsPatron == isPatron) - return; + return mSettings->value(QLatin1String("Install/FirstRun")).toDate(); +} - mIsPatron = isPatron; - mSettings->setValue(QLatin1String("Install/IsPatron"), isPatron); +int Preferences::runCount() const +{ + return intValue("Install/RunCount", 0); +} + +bool Preferences::isPatron() const +{ + return boolValue("Install/IsPatron"); +} +void Preferences::setPatron(bool isPatron) +{ + mSettings->setValue(QLatin1String("Install/IsPatron"), isPatron); emit isPatronChanged(); } bool Preferences::shouldShowDonationDialog() const { - if (mIsPatron) + if (isPatron()) return false; - if (mRunCount < 7) + if (runCount() < 7) return false; - if (!mDonationDialogTime.isValid()) + + const QDate dialogTime = donationDialogTime(); + if (!dialogTime.isValid()) return false; - return mDonationDialogTime.daysTo(QDate::currentDate()) >= 0; + return dialogTime.daysTo(QDate::currentDate()) >= 0; +} + +QDate Preferences::donationDialogTime() const +{ + return mSettings->value(QLatin1String("Install/DonationDialogTime")).toDate(); } void Preferences::setDonationDialogReminder(const QDate &date) { if (date.isValid()) setPatron(false); - mDonationDialogTime = date; - mSettings->setValue(QLatin1String("Install/DonationDialogTime"), mDonationDialogTime.toString(Qt::ISODate)); + mSettings->setValue(QLatin1String("Install/DonationDialogTime"), date.toString(Qt::ISODate)); } QString Preferences::fileDialogStartLocation() const { - const QString activeFile = mSession.activeFile(); - if (!activeFile.isEmpty()) - return QFileInfo(activeFile).path(); + if (!mSession.activeFile.isEmpty()) + return QFileInfo(mSession.activeFile).path(); - const QStringList files = mSession.recentFiles(); - if (!files.isEmpty()) - return QFileInfo(files.first()).path(); + if (!mSession.recentFiles.isEmpty()) + return QFileInfo(mSession.recentFiles.first()).path(); return QStandardPaths::writableLocation(QStandardPaths::HomeLocation); } @@ -702,6 +687,11 @@ void Preferences::setLastSession(const QString &fileName) mSettings->setValue(QLatin1String("Project/LastSession"), fileName); } +bool Preferences::restoreSessionOnStartup() const +{ + return boolValue("Startup/RestorePreviousSession", true); +} + void Preferences::switchSession(Session session) { mSession = std::move(session); @@ -716,16 +706,10 @@ void Preferences::saveSession() mSaveSessionTimer.start(); } -void Preferences::saveSessionNow(const QString &fileName) +void Preferences::saveSessionNow() { emit aboutToSaveSession(); - mSaveSessionTimer.stop(); - - // Set the file name regardless of whether the save succeeded - if (!fileName.isEmpty()) - mSession.setFileName(fileName); - mSession.save(); } @@ -745,7 +729,7 @@ void Preferences::addToRecentFileList(const QString &fileName, QStringList& file void Preferences::clearRecentFiles() { - mSession.setRecentFiles(QStringList()); + mSession.recentFiles.clear(); emit recentFilesChanged(); } @@ -755,34 +739,35 @@ void Preferences::clearRecentProjects() emit recentProjectsChanged(); } -void Preferences::setCheckForUpdates(bool on) +bool Preferences::checkForUpdates() const { - if (mCheckForUpdates == on) - return; + return boolValue("Install/CheckForUpdates", true); +} - mCheckForUpdates = on; +void Preferences::setCheckForUpdates(bool on) +{ mSettings->setValue(QLatin1String("Install/CheckForUpdates"), on); - emit checkForUpdatesChanged(on); } -void Preferences::setDisplayNews(bool on) +bool Preferences::displayNews() const { - if (mDisplayNews == on) - return; + return boolValue("Install/DisplayNews", true); +} - mDisplayNews = on; +void Preferences::setDisplayNews(bool on) +{ mSettings->setValue(QLatin1String("Install/DisplayNews"), on); - emit displayNewsChanged(on); } -void Preferences::setRestoreSessionOnStartup(bool enabled) +bool Preferences::wheelZoomsByDefault() const { - if (mRestoreSessionOnStartup == enabled) - return; + return boolValue("Interface/WheelZoomsByDefault"); +} - mRestoreSessionOnStartup = enabled; +void Preferences::setRestoreSessionOnStartup(bool enabled) +{ mSettings->setValue(QLatin1String("Startup/RestorePreviousSession"), enabled); } @@ -818,10 +803,6 @@ void Preferences::setPluginEnabled(const QString &fileName, bool enabled) void Preferences::setWheelZoomsByDefault(bool mode) { - if (mWheelZoomsByDefault == mode) - return; - - mWheelZoomsByDefault = mode; mSettings->setValue(QLatin1String("Interface/WheelZoomsByDefault"), mode); } @@ -862,64 +843,54 @@ QString Preferences::dataLocation() QString Preferences::stampsDirectory() const { - if (mStampsDirectory.isEmpty()) + QString directory = stringValue("Storage/StampsDirectory"); + if (directory.isEmpty()) return dataLocation() + QLatin1String("/stamps"); - return mStampsDirectory; + return directory; } void Preferences::setStampsDirectory(const QString &stampsDirectory) { - if (mStampsDirectory == stampsDirectory) - return; - - mStampsDirectory = stampsDirectory; mSettings->setValue(QLatin1String("Storage/StampsDirectory"), stampsDirectory); - emit stampsDirectoryChanged(stampsDirectory); } QString Preferences::templatesDirectory() const { - if (mTemplatesDirectory.isEmpty()) + QString directory = stringValue("Storage/TemplatesDirectory"); + if (directory.isEmpty()) return dataLocation() + QLatin1String("/templates"); - return mTemplatesDirectory; + return directory; } void Preferences::setTemplatesDirectory(const QString &templatesDirectory) { - if (mTemplatesDirectory == templatesDirectory) - return; - - mTemplatesDirectory = templatesDirectory; mSettings->setValue(QLatin1String("Storage/TemplatesDirectory"), templatesDirectory); - emit templatesDirectoryChanged(templatesDirectory); } QString Preferences::objectTypesFile() const { - if (mObjectTypesFile.isEmpty()) + QString file = stringValue("Storage/ObjectTypesFile"); + if (file.isEmpty()) return dataLocation() + QLatin1String("/objecttypes.xml"); - return mObjectTypesFile; + return file; } void Preferences::setObjectTypesFile(const QString &fileName) { - if (mObjectTypesFile == fileName) + QString previousObjectTypesFile = objectTypesFile(); + if (previousObjectTypesFile == fileName) return; - if (!mObjectTypesFile.isEmpty()) - mWatcher.removePath(mObjectTypesFile); + if (!previousObjectTypesFile.isEmpty()) + mWatcher.removePath(previousObjectTypesFile); - mObjectTypesFile = fileName; mSettings->setValue(QLatin1String("Storage/ObjectTypesFile"), fileName); - - mWatcher.addPath(mObjectTypesFile); - - emit stampsDirectoryChanged(fileName); + mWatcher.addPath(fileName); } void Preferences::setObjectTypesFileLastSaved(const QDateTime &time) diff --git a/src/tiled/preferences.h b/src/tiled/preferences.h index 03292da131..49be4c01aa 100644 --- a/src/tiled/preferences.h +++ b/src/tiled/preferences.h @@ -46,6 +46,11 @@ class Preferences : public QObject static Preferences *instance(); static void deleteInstance(); +private: + Preferences(); + ~Preferences() override; + +public: bool showGrid() const; bool showTileObjectOutlines() const; bool showTileAnimations() const; @@ -117,7 +122,7 @@ class Preferences : public QObject void setLanguage(const QString &language); bool reloadTilesetsOnChange() const; - void setReloadTilesetsOnChanged(bool value); + void setReloadTilesetsOnChanged(bool reloadOnChanged); bool useOpenGL() const; void setUseOpenGL(bool useOpenGL); @@ -156,6 +161,7 @@ class Preferences : public QObject void setPatron(bool isPatron); bool shouldShowDonationDialog() const; + QDate donationDialogTime() const; void setDonationDialogReminder(const QDate &date); enum { MaxRecentFiles = 12 }; @@ -171,7 +177,7 @@ class Preferences : public QObject bool restoreSessionOnStartup() const; void switchSession(Session session); void saveSession(); - void saveSessionNow(const QString &fileName = QString()); + void saveSessionNow(); bool checkForUpdates() const; void setCheckForUpdates(bool on); @@ -254,9 +260,6 @@ public slots: void aboutToSaveSession(); private: - Preferences(); - ~Preferences() override; - bool boolValue(const char *key, bool def = false) const; QColor colorValue(const char *key, const QColor &def = QColor()) const; QString stringValue(const char *key, const QString &def = QString()) const; @@ -273,241 +276,17 @@ public slots: Session mSession; QTimer mSaveSessionTimer; - bool mShowGrid; - bool mShowTileObjectOutlines; - bool mShowTileAnimations; - bool mShowTileCollisionShapes; - bool mShowObjectReferences; - bool mSnapToGrid; - bool mSnapToFineGrid; - bool mSnapToPixels; - QColor mGridColor; - int mGridFine; - qreal mObjectLineWidth; - bool mHighlightCurrentLayer; - bool mHighlightHoveredObject; - bool mShowTilesetGrid; - bool mRestoreSessionOnStartup; - ObjectLabelVisiblity mObjectLabelVisibility; - bool mLabelForHoveredObject; - ApplicationStyle mApplicationStyle; - QColor mBaseColor; - QColor mSelectionColor; - - Map::LayerDataFormat mLayerDataFormat; - Map::RenderOrder mMapRenderOrder; - bool mDtdEnabled; - bool mSafeSavingEnabled; - bool mExportOnSave; - ExportOptions mExportOptions; - QString mLanguage; - bool mReloadTilesetsOnChange; - bool mUseOpenGL; - - bool mAutoMapDrawing; - - QString mStampsDirectory; - QString mTemplatesDirectory; - QString mObjectTypesFile; QDateTime mObjectTypesFileLastSaved; - QDate mFirstRun; - QDate mDonationDialogTime; - int mRunCount; - bool mIsPatron; - bool mCheckForUpdates; - bool mDisplayNews; - bool mWheelZoomsByDefault; - static Preferences *mInstance; }; -inline bool Preferences::showGrid() const -{ - return mShowGrid; -} - -inline bool Preferences::showTileObjectOutlines() const -{ - return mShowTileObjectOutlines; -} - -inline bool Preferences::showTileAnimations() const -{ - return mShowTileAnimations; -} - -inline bool Preferences::showTileCollisionShapes() const -{ - return mShowTileCollisionShapes; -} - -inline bool Preferences::showObjectReferences() const -{ - return mShowObjectReferences; -} - -inline bool Preferences::snapToGrid() const -{ - return mSnapToGrid; -} - -inline bool Preferences::snapToFineGrid() const -{ - return mSnapToFineGrid; -} - -inline bool Preferences::snapToPixels() const -{ - return mSnapToPixels; -} - -inline QColor Preferences::gridColor() const -{ - return mGridColor; -} - -inline int Preferences::gridFine() const -{ - return mGridFine; -} - -inline qreal Preferences::objectLineWidth() const -{ - return mObjectLineWidth; -} - -inline bool Preferences::highlightCurrentLayer() const -{ - return mHighlightCurrentLayer; -} - -inline bool Preferences::highlightHoveredObject() const -{ - return mHighlightHoveredObject; -} - -inline bool Preferences::showTilesetGrid() const -{ - return mShowTilesetGrid; -} - -inline Preferences::ObjectLabelVisiblity Preferences::objectLabelVisibility() const -{ - return mObjectLabelVisibility; -} - -inline bool Preferences::labelForHoveredObject() const -{ - return mLabelForHoveredObject; -} - -inline Preferences::ApplicationStyle Preferences::applicationStyle() const -{ - return mApplicationStyle; -} - -inline QColor Preferences::baseColor() const -{ - return mBaseColor; -} - -inline QColor Preferences::selectionColor() const -{ - return mSelectionColor; -} - -inline Map::LayerDataFormat Preferences::layerDataFormat() const -{ - return mLayerDataFormat; -} - -inline Map::RenderOrder Preferences::mapRenderOrder() const -{ - return mMapRenderOrder; -} - -inline bool Preferences::safeSavingEnabled() const -{ - return mSafeSavingEnabled; -} - -inline bool Preferences::exportOnSave() const -{ - return mExportOnSave; -} - -inline Preferences::ExportOptions Preferences::exportOptions() const -{ - return mExportOptions; -} - -inline bool Preferences::exportOption(ExportOption option) const -{ - return mExportOptions.testFlag(option); -} - -inline QString Preferences::language() const -{ - return mLanguage; -} - -inline bool Preferences::reloadTilesetsOnChange() const -{ - return mReloadTilesetsOnChange; -} - -inline bool Preferences::useOpenGL() const -{ - return mUseOpenGL; -} - -inline bool Preferences::automappingDrawing() const -{ - return mAutoMapDrawing; -} - -inline QDate Preferences::firstRun() const -{ - return mFirstRun; -} - -inline int Preferences::runCount() const -{ - return mRunCount; -} - -inline bool Preferences::isPatron() const -{ - return mIsPatron; -} - -inline bool Preferences::checkForUpdates() const -{ - return mCheckForUpdates; -} - -inline bool Preferences::displayNews() const -{ - return mDisplayNews; -} - inline Session &Preferences::session() { return mSession; } -inline bool Preferences::restoreSessionOnStartup() const -{ - return mRestoreSessionOnStartup; -} - -inline bool Preferences::wheelZoomsByDefault() const -{ - return mWheelZoomsByDefault; -} - inline QSettings *Preferences::settings() const { return mSettings; diff --git a/src/tiled/projectdock.cpp b/src/tiled/projectdock.cpp index bf36bb160b..b1d65e695b 100644 --- a/src/tiled/projectdock.cpp +++ b/src/tiled/projectdock.cpp @@ -92,7 +92,7 @@ ProjectDock::ProjectDock(QWidget *parent) auto prefs = Preferences::instance(); connect(prefs, &Preferences::aboutToSaveSession, - this, [this, prefs] { prefs->session().setExpandedProjectPaths(mProjectView->expandedPaths()); }); + this, [this, prefs] { prefs->session().expandedProjectPaths = mProjectView->expandedPaths(); }); } void ProjectDock::addFolderToProject() diff --git a/src/tiled/session.cpp b/src/tiled/session.cpp index 2d149b39c2..16ceaf9599 100644 --- a/src/tiled/session.cpp +++ b/src/tiled/session.cpp @@ -21,127 +21,86 @@ #include "session.h" #include "preferences.h" -#include "savefile.h" +#include "utils.h" -#include -#include #include -#include -#include -#include namespace Tiled { -class JsonHelper -{ -public: - JsonHelper(const QString &fileName) - : mDir(QFileInfo(fileName).dir()) - {} - - QString relativeFileName(const QString &fileName) const - { - if (fileName.startsWith(mDir.path())) - return mDir.relativeFilePath(fileName); - return fileName; - } - - QJsonArray relativeFileNames(const QStringList &fileNames) const - { - QJsonArray result; - for (const QString &fileName : fileNames) - result.append(relativeFileName(fileName)); - return result; - } - - QString resolveFileName(const QString &value) const - { - return QDir::cleanPath(mDir.filePath(value)); - } - - QString resolveFileName(const QJsonValue &value) const - { - return resolveFileName(value.toString()); - } - - QStringList resolveFileNames(const QJsonArray &array) const - { - QStringList result; - for (const QJsonValue &value : array) - result.append(resolveFileName(value)); - return result; - } - -private: - QDir mDir; -}; +FileHelper::FileHelper(const QString &fileName) + : mDir { QFileInfo(fileName).dir() } +{} +void FileHelper::setFileName(const QString &fileName) +{ + mDir = QFileInfo(fileName).dir(); +} -Session::Session(const QString &fileName) - : mFileName(fileName) +QStringList FileHelper::relative(const QStringList &fileNames) const { + QStringList result; + for (const QString &fileName : fileNames) + result.append(relative(fileName)); + return result; } -bool Session::save() const +QStringList FileHelper::resolve(const QStringList &fileNames) const { - SaveFile file(mFileName); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - return false; + QStringList result; + for (const QString &fileName : fileNames) + result.append(resolve(fileName)); + return result; +} - QJsonObject jsonSession; - JsonHelper helper(mFileName); - jsonSession.insert(QLatin1String("project"), helper.relativeFileName(mProject)); - jsonSession.insert(QLatin1String("recentFiles"), helper.relativeFileNames(mRecentFiles)); - jsonSession.insert(QLatin1String("openFiles"), helper.relativeFileNames(mOpenFiles)); - jsonSession.insert(QLatin1String("expandedProjectPaths"), helper.relativeFileNames(mExpandedProjectPaths)); - jsonSession.insert(QLatin1String("activeFile"), helper.relativeFileName(mActiveFile)); +Session::Session(const QString &fileName) + : FileHelper { fileName } + , settings { Utils::jsonSettings(fileName) } + , project { resolve(get("project")) } + , recentFiles { resolve(get("recentFiles")) } + , openFiles { resolve(get("openFiles")) } + , expandedProjectPaths { resolve(get("expandedProjectPaths")) } + , activeFile { resolve(get("activeFile")) } +{ + const auto states = get("fileStates"); + for (auto it = states.constBegin(); it != states.constEnd(); ++it) + fileStates.insert(resolve(it.key()), it.value()); +} - QJsonObject fileStates; - for (auto it = mFileStates.constBegin(); it != mFileStates.constEnd(); ++it) { - fileStates.insert(helper.relativeFileName(it.key()), - QJsonValue::fromVariant(it.value())); - } +bool Session::save() +{ + set("project", relative(project)); + set("recentFiles", relative(recentFiles)); + set("openFiles", relative(openFiles)); + set("expandedProjectPaths", relative(expandedProjectPaths)); + set("activeFile", relative(activeFile)); + + QVariantMap states; + for (auto it = fileStates.constBegin(); it != fileStates.constEnd(); ++it) + fileStates.insert(relative(it.key()), it.value()); + set("fileStates", states); + + settings->sync(); + return settings->status() == QSettings::NoError; +} - jsonSession.insert(QLatin1String("fileStates"), fileStates); +/** + * This function "moves" the current session to a new location. It happens for + * example when saving a project for the first time or saving it under a + * different file name. + */ +void Session::setFileName(const QString &fileName) +{ + auto newSettings = Utils::jsonSettings(fileName); - file.device()->write(QJsonDocument(jsonSession).toJson()); - if (!file.commit()) - return false; + // Copy over all settings + const auto keys = settings->allKeys(); + for (const auto &key : keys) + newSettings->setValue(key, settings->value(key)); - return true; -} + settings = std::move(newSettings); -Session Session::load(const QString &fileName) -{ - Session session(fileName); - - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return session; - - QJsonParseError error; - QByteArray json = file.readAll(); - QJsonDocument document(QJsonDocument::fromJson(json, &error)); - if (error.error != QJsonParseError::NoError) - return session; - - QJsonObject jsonSession = document.object(); - JsonHelper helper(fileName); - - session.mProject = helper.resolveFileName(jsonSession.value(QLatin1String("project"))); - session.mRecentFiles = helper.resolveFileNames(jsonSession.value(QLatin1String("recentFiles")).toArray()); - session.mOpenFiles = helper.resolveFileNames(jsonSession.value(QLatin1String("openFiles")).toArray()); - session.mExpandedProjectPaths = helper.resolveFileNames(jsonSession.value(QLatin1String("expandedProjectPaths")).toArray()); - session.mActiveFile = helper.resolveFileName(jsonSession.value(QLatin1String("activeFile"))); - - QJsonObject fileStates = jsonSession.value(QLatin1String("fileStates")).toObject(); - for (auto it = fileStates.constBegin(); it != fileStates.constEnd(); ++it) { - session.mFileStates.insert(helper.resolveFileName(it.key()), - it.value().toVariant()); - } - - return session; + FileHelper::setFileName(fileName); } void Session::addRecentFile(const QString &fileName) @@ -152,10 +111,20 @@ void Session::addRecentFile(const QString &fileName) if (absoluteFilePath.isEmpty()) return; - mRecentFiles.removeAll(absoluteFilePath); - mRecentFiles.prepend(absoluteFilePath); - while (mRecentFiles.size() > Preferences::MaxRecentFiles) - mRecentFiles.removeLast(); + recentFiles.removeAll(absoluteFilePath); + recentFiles.prepend(absoluteFilePath); + while (recentFiles.size() > Preferences::MaxRecentFiles) + recentFiles.removeLast(); +} + +QVariantMap Session::fileState(const QString &fileName) const +{ + return fileStates.value(fileName).toMap(); +} + +void Session::setFileState(const QString &fileName, const QVariantMap &fileState) +{ + fileStates.insert(fileName, fileState); } QString Session::defaultFileName() diff --git a/src/tiled/session.h b/src/tiled/session.h index ae0454c69a..45ead10e58 100644 --- a/src/tiled/session.h +++ b/src/tiled/session.h @@ -20,124 +20,86 @@ #pragma once +#include +#include #include #include +#include + namespace Tiled { -class Session +class FileHelper { public: - explicit Session(const QString &fileName = QString()); + FileHelper(const QString &fileName); - QString fileName() const; void setFileName(const QString &fileName); - bool save() const; - static Session load(const QString &fileName); - - QString project() const; - void setProject(const QString &fileName); - - QStringList recentFiles() const; - void setRecentFiles(const QStringList &recentFiles); - void addRecentFile(const QString &fileName); - - QStringList openFiles() const; - void setOpenFiles(const QStringList &openFiles); + QString relative(const QString &fileName) const; + QStringList relative(const QStringList &fileNames) const; - QStringList expandedProjectPaths() const; - void setExpandedProjectPaths(const QStringList &paths); + QString resolve(const QString &fileName) const; + QStringList resolve(const QStringList &fileNames) const; - const QString &activeFile() const; - void setActiveFile(const QString &fileName); - - QVariantMap fileState(const QString &fileName) const; - void setFileState(const QString &fileName, const QVariantMap &fileState); - - static QString defaultFileName(); - static QString defaultFileNameForProject(const QString &projectFile); - -private: - QString mFileName; - - QString mProject; - QStringList mRecentFiles; - QStringList mOpenFiles; - QStringList mExpandedProjectPaths; - QString mActiveFile; - QVariantMap mFileStates; +protected: + QDir mDir; }; - -inline QString Session::fileName() const +inline QString FileHelper::relative(const QString &fileName) const { - return mFileName; + if (fileName.startsWith(mDir.path())) + return mDir.relativeFilePath(fileName); + return fileName; } -inline void Session::setFileName(const QString &fileName) +inline QString FileHelper::resolve(const QString &fileName) const { - mFileName = fileName; + if (fileName.isEmpty()) + return QString(); + return QDir::cleanPath(mDir.filePath(fileName)); } -inline QString Session::project() const -{ - return mProject; -} -inline void Session::setProject(const QString &fileName) +class Session : protected FileHelper { - mProject = fileName; -} + std::unique_ptr settings; -inline QStringList Session::recentFiles() const -{ - return mRecentFiles; -} +public: + explicit Session(const QString &fileName = QString()); -inline QStringList Session::openFiles() const -{ - return mOpenFiles; -} + bool save(); -inline void Session::setRecentFiles(const QStringList &recentFiles) -{ - mRecentFiles = recentFiles; -} + QString fileName() const; + void setFileName(const QString &fileName); -inline void Session::setOpenFiles(const QStringList &openFiles) -{ - mOpenFiles = openFiles; -} + void addRecentFile(const QString &fileName); -inline QStringList Session::expandedProjectPaths() const -{ - return mExpandedProjectPaths; -} + QVariantMap fileState(const QString &fileName) const; + void setFileState(const QString &fileName, const QVariantMap &fileState); -inline void Session::setExpandedProjectPaths(const QStringList &paths) -{ - mExpandedProjectPaths = paths; -} + template + T get(const char *key, const QVariant &defaultValue = QVariant()) const + { return settings->value(QLatin1String(key), defaultValue).value(); } -inline const QString &Session::activeFile() const -{ - return mActiveFile; -} + template + void set(const char *key, const T &value) const { settings->setValue(QLatin1String(key), value); } -inline void Session::setActiveFile(const QString &fileName) -{ - mActiveFile = fileName; -} + static QString defaultFileName(); + static QString defaultFileNameForProject(const QString &projectFile); + + QString project; + QStringList recentFiles; + QStringList openFiles; + QStringList expandedProjectPaths; + QString activeFile; + QVariantMap fileStates; +}; -inline QVariantMap Session::fileState(const QString &fileName) const -{ - return mFileStates.value(fileName).toMap(); -} -inline void Session::setFileState(const QString &fileName, const QVariantMap &fileState) +inline QString Session::fileName() const { - mFileStates.insert(fileName, fileState); + return settings->fileName(); } } // namespace Tiled diff --git a/src/tiled/utils.cpp b/src/tiled/utils.cpp index 8abf7fc88b..eb21b1660e 100644 --- a/src/tiled/utils.cpp +++ b/src/tiled/utils.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -303,5 +304,26 @@ void addFileManagerActions(QMenu &menu, const QString &fileName) }); } +static bool readJsonFile(QIODevice &device, QSettings::SettingsMap &map) +{ + QJsonParseError error; + map = QJsonDocument::fromJson(device.readAll(), &error).toVariant().toMap(); + return error.error == QJsonParseError::NoError; +} + +static bool writeJsonFile(QIODevice &device, const QSettings::SettingsMap &map) +{ + const auto json = QJsonDocument::fromVariant(map).toJson(); + return device.write(json) == json.size(); +} + +std::unique_ptr jsonSettings(const QString &fileName) +{ + static const auto format = QSettings::registerFormat(QStringLiteral("json"), + readJsonFile, + writeJsonFile); + return std::make_unique(fileName, format); +} + } // namespace Utils } // namespace Tiled diff --git a/src/tiled/utils.h b/src/tiled/utils.h index 9cd78dbad9..db4a4a0767 100644 --- a/src/tiled/utils.h +++ b/src/tiled/utils.h @@ -21,8 +21,11 @@ #pragma once #include +#include #include +#include + class QAction; class QKeyEvent; class QMenu; @@ -83,5 +86,7 @@ bool isResetZoomShortcut(QKeyEvent *event); void addFileManagerActions(QMenu &menu, const QString &fileName); +std::unique_ptr jsonSettings(const QString &fileName); + } // namespace Utils } // namespace Tiled