diff --git a/app/src/main.cpp b/app/src/main.cpp index 82ce29d82..bdd4f7d18 100644 --- a/app/src/main.cpp +++ b/app/src/main.cpp @@ -15,8 +15,6 @@ GNU General Public License for more details. */ -#include - #include "log.h" #include "pencil2d.h" #include "pencilerror.h" @@ -28,23 +26,12 @@ GNU General Public License for more details. */ int main(int argc, char* argv[]) { - // iss #940 - // Force dot separator on numbers because some localizations - // use comma as separator. - std::setlocale(LC_NUMERIC, "en_US.UTF-8"); - Q_INIT_RESOURCE(core_lib); PlatformHandler::initialise(); initCategoryLogging(); Pencil2D app(argc, argv); - #ifndef QT_DEBUG - if (app.isInstanceOpen()) { - return EXIT_SUCCESS; - } - #endif - switch (app.handleCommandLineOptions().code()) { case Status::OK: diff --git a/app/src/mainwindow2.cpp b/app/src/mainwindow2.cpp index 81b36880e..1966d8044 100644 --- a/app/src/mainwindow2.cpp +++ b/app/src/mainwindow2.cpp @@ -273,6 +273,7 @@ void MainWindow2::createMenus() connect(ui->actionImport_Replace_Palette, &QAction::triggered, this, &MainWindow2::openPalette); //--- Edit Menu --- + connect(mEditor, &Editor::updateBackup, this, &MainWindow2::undoActSetText); connect(ui->actionUndo, &QAction::triggered, mEditor, &Editor::undo); connect(ui->actionRedo, &QAction::triggered, mEditor, &Editor::redo); connect(ui->actionCut, &QAction::triggered, mEditor, &Editor::copyAndCut); @@ -425,9 +426,6 @@ void MainWindow2::createMenus() ui->menuFile->insertMenu(ui->actionSave, mRecentFileMenu); connect(mRecentFileMenu, &RecentFileMenu::loadRecentFile, this, &MainWindow2::openFile); - - connect(ui->menuEdit, &QMenu::aboutToShow, this, &MainWindow2::undoActSetText); - connect(ui->menuEdit, &QMenu::aboutToHide, this, &MainWindow2::undoActSetEnabled); } void MainWindow2::setOpacity(int opacity) @@ -557,18 +555,6 @@ void MainWindow2::closeEvent(QCloseEvent* event) m2ndCloseEvent = true; } -void MainWindow2::showEvent(QShowEvent*) -{ - static bool firstShowEvent = true; - if (!firstShowEvent) - { - return; - } - firstShowEvent = false; - if (tryRecoverUnsavedProject() || loadMostRecent() || tryLoadPreset()) { return; } - newObject(); -} - void MainWindow2::tabletEvent(QTabletEvent* event) { event->ignore(); @@ -605,6 +591,21 @@ bool MainWindow2::saveAsNewDocument() return saveObject(fileName); } +void MainWindow2::openStartupFile(const QString& filename) +{ + if (tryRecoverUnsavedProject()) + { + return; + } + + if (!filename.isEmpty() && openObject(filename)) + { + return; + } + + loadMostRecent() || tryLoadPreset(); +} + void MainWindow2::openFile(const QString& filename) { if (maybeSave()) @@ -656,6 +657,7 @@ bool MainWindow2::openObject(const QString& strFilePath) progress.setValue(progress.maximum()); updateSaveState(); + undoActSetText(); if (!QFileInfo(strFilePath).isWritable()) { @@ -1055,6 +1057,7 @@ void MainWindow2::newObject() closeDialogs(); setWindowTitle(PENCIL_WINDOW_TITLE); + undoActSetText(); } bool MainWindow2::newObjectFromPresets(int presetIndex) @@ -1079,6 +1082,7 @@ bool MainWindow2::newObjectFromPresets(int presetIndex) setWindowTitle(PENCIL_WINDOW_TITLE); updateSaveState(); + undoActSetText(); return true; } @@ -1331,12 +1335,6 @@ void MainWindow2::undoActSetText() } } -void MainWindow2::undoActSetEnabled() -{ - ui->actionUndo->setEnabled(true); - ui->actionRedo->setEnabled(true); -} - void MainWindow2::exportPalette() { QString filePath = FileDialog::getSaveFileName(this, FileType::PALETTE); @@ -1622,6 +1620,7 @@ void MainWindow2::startProjectRecovery(int result) Q_ASSERT(o); mEditor->setObject(o); updateSaveState(); + undoActSetText(); const QString title = tr("Recovery Succeeded!"); const QString text = tr("Please save your work immediately to prevent loss of data"); @@ -1631,6 +1630,7 @@ void MainWindow2::startProjectRecovery(int result) void MainWindow2::createToolbars() { mMainToolbar = addToolBar(tr("Main Toolbar")); + mMainToolbar->setObjectName("mMainToolbar"); mMainToolbar->addAction(ui->actionNew); mMainToolbar->addAction(ui->actionOpen); mMainToolbar->addAction(ui->actionSave); @@ -1643,6 +1643,7 @@ void MainWindow2::createToolbars() mMainToolbar->addAction(ui->actionPaste); mViewToolbar = addToolBar(tr("View Toolbar")); + mViewToolbar->setObjectName("mViewToolbar"); mViewToolbar->addAction(ui->actionZoom_In); mViewToolbar->addAction(ui->actionZoom_Out); mViewToolbar->addAction(ui->actionReset_View); @@ -1650,6 +1651,7 @@ void MainWindow2::createToolbars() mViewToolbar->addAction(ui->actionVertical_Flip); mOverlayToolbar = addToolBar(tr("Overlay Toolbar")); + mOverlayToolbar->setObjectName("mOverlayToolbar"); mOverlayToolbar->addAction(ui->actionGrid); mToolbars = { mMainToolbar, mViewToolbar, mOverlayToolbar }; diff --git a/app/src/mainwindow2.h b/app/src/mainwindow2.h index 201944144..92b799350 100644 --- a/app/src/mainwindow2.h +++ b/app/src/mainwindow2.h @@ -68,7 +68,6 @@ class MainWindow2 : public QMainWindow public slots: void undoActSetText(); - void undoActSetEnabled(); void updateSaveState(); void openPegAlignDialog(); void openRepositionDialog(); @@ -100,21 +99,19 @@ public slots: void setOpacity(int opacity); void preferences(); + void openStartupFile(const QString& filename); void openFile(const QString& filename); void displayMessageBox(const QString& title, const QString& body); void displayMessageBoxNoTitle(const QString& body); signals: - void updateRecentFilesList(bool b); - /** Emitted when window regains focus */ void windowActivated(); protected: void tabletEvent(QTabletEvent*) override; void closeEvent(QCloseEvent*) override; - void showEvent(QShowEvent*) override; bool event(QEvent*) override; private slots: diff --git a/app/src/pencil2d.cpp b/app/src/pencil2d.cpp index 2ce506725..adfbdc6e3 100644 --- a/app/src/pencil2d.cpp +++ b/app/src/pencil2d.cpp @@ -69,6 +69,12 @@ Status Pencil2D::handleCommandLineOptions() CommandLineParser parser; parser.process(arguments()); +#ifndef QT_DEBUG + if (isInstanceOpen()) { + return Status::SAFE; + } +#endif + QString inputPath = parser.inputPath(); QStringList outputPaths = parser.outputPaths(); @@ -102,7 +108,7 @@ bool Pencil2D::isInstanceOpen() mProcessLock.reset(new QLockFile(appDir.absoluteFilePath("pencil2d-process.lock"))); if (!mProcessLock->tryLock(10)) { - QMessageBox::StandardButton clickedButton = QMessageBox::warning(nullptr, QObject::tr("Warning"), QObject::tr("An instance of Pencil2D is already open. Running multiple instances of Pencil2D simultaneously is not recommended and could potentially result in data loss and other unexpected behavior."), QMessageBox::Close | QMessageBox::Open, QMessageBox::Close); + QMessageBox::StandardButton clickedButton = QMessageBox::warning(nullptr, tr("Warning"), tr("An instance of Pencil2D is already open. Running multiple instances of Pencil2D simultaneously is not recommended and could potentially result in data loss and other unexpected behavior."), QMessageBox::Close | QMessageBox::Open, QMessageBox::Close); if (clickedButton != QMessageBox::Open) { return true; @@ -130,6 +136,14 @@ void Pencil2D::installTranslators() QLocale locale = userLocale.isEmpty() ? QLocale::system() : QLocale(userLocale); QLocale::setDefault(locale); +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + // In versions prior to 5.14, Qt's DOM implementation erroneously used + // locale-dependent string conversion for double attributes (QTBUG-80068). + // To work around this, we override the numeric locale category to use the + // C locale. + std::setlocale(LC_NUMERIC, "C"); +#endif + std::unique_ptr qtTranslator(new QTranslator(this)); if (qtTranslator->load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { @@ -151,8 +165,5 @@ void Pencil2D::prepareGuiStartup(const QString& inputPath) connect(this, &Pencil2D::openFileRequested, mainWindow.get(), &MainWindow2::openFile); mainWindow->show(); - if (!inputPath.isEmpty()) - { - mainWindow->openFile(inputPath); - } + mainWindow->openStartupFile(inputPath); } diff --git a/core_lib/src/structure/filemanager.cpp b/core_lib/src/structure/filemanager.cpp index 2a8156a90..a24db42fd 100644 --- a/core_lib/src/structure/filemanager.cpp +++ b/core_lib/src/structure/filemanager.cpp @@ -177,8 +177,7 @@ bool FileManager::loadObject(Object* object, const QDomElement& root) } else if (element.tagName() == "editor" || element.tagName() == "projectdata") { - ObjectData* projectData = loadProjectData(element); - object->setData(projectData); + object->setData(loadProjectData(element)); } else if (element.tagName() == "version") { @@ -384,9 +383,9 @@ Status FileManager::writeToWorkingFolder(const Object* object) return Status(errorCode, dd); } -ObjectData* FileManager::loadProjectData(const QDomElement& docElem) +ObjectData FileManager::loadProjectData(const QDomElement& docElem) { - ObjectData* data = new ObjectData; + ObjectData data; if (docElem.isNull()) { return data; @@ -468,14 +467,12 @@ QDomElement FileManager::saveProjectData(const ObjectData* data, QDomDocument& x return rootTag; } -void FileManager::extractProjectData(const QDomElement& element, ObjectData* data) +void FileManager::extractProjectData(const QDomElement& element, ObjectData& data) { - Q_ASSERT(data); - QString strName = element.tagName(); if (strName == "currentFrame") { - data->setCurrentFrame(element.attribute("value").toInt()); + data.setCurrentFrame(element.attribute("value").toInt()); } else if (strName == "currentColor") { @@ -484,11 +481,11 @@ void FileManager::extractProjectData(const QDomElement& element, ObjectData* dat int b = element.attribute("b", "255").toInt(); int a = element.attribute("a", "255").toInt(); - data->setCurrentColor(QColor(r, g, b, a)); + data.setCurrentColor(QColor(r, g, b, a)); } else if (strName == "currentLayer") { - data->setCurrentLayer(element.attribute("value", "0").toInt()); + data.setCurrentLayer(element.attribute("value", "0").toInt()); } else if (strName == "currentView") { @@ -499,27 +496,27 @@ void FileManager::extractProjectData(const QDomElement& element, ObjectData* dat double dx = element.attribute("dx", "0").toDouble(); double dy = element.attribute("dy", "0").toDouble(); - data->setCurrentView(QTransform(m11, m12, m21, m22, dx, dy)); + data.setCurrentView(QTransform(m11, m12, m21, m22, dx, dy)); } else if (strName == "fps" || strName == "currentFps") { - data->setFrameRate(element.attribute("value", "12").toInt()); + data.setFrameRate(element.attribute("value", "12").toInt()); } else if (strName == "isLoop") { - data->setLooping(element.attribute("value", "false") == "true"); + data.setLooping(element.attribute("value", "false") == "true"); } else if (strName == "isRangedPlayback") { - data->setRangedPlayback((element.attribute("value", "false") == "true")); + data.setRangedPlayback((element.attribute("value", "false") == "true")); } else if (strName == "markInFrame") { - data->setMarkInFrameNumber(element.attribute("value", "0").toInt()); + data.setMarkInFrameNumber(element.attribute("value", "0").toInt()); } else if (strName == "markOutFrame") { - data->setMarkOutFrameNumber(element.attribute("value", "15").toInt()); + data.setMarkOutFrameNumber(element.attribute("value", "15").toInt()); } } diff --git a/core_lib/src/structure/filemanager.h b/core_lib/src/structure/filemanager.h index 75d5ec75e..9fc81a1ca 100644 --- a/core_lib/src/structure/filemanager.h +++ b/core_lib/src/structure/filemanager.h @@ -65,10 +65,10 @@ class FileManager : public QObject Status writeMainXml(const Object* obj, const QString& mainXmlPath, QStringList& filesWritten); Status writePalette(const Object* obj, const QString& dataFolder, QStringList& filesWritten); - ObjectData* loadProjectData(const QDomElement& element); + ObjectData loadProjectData(const QDomElement& element); QDomElement saveProjectData(const ObjectData*, QDomDocument& xmlDoc); - void extractProjectData(const QDomElement& element, ObjectData* data); + void extractProjectData(const QDomElement& element, ObjectData& data); void handleOpenProjectError(Status::ErrorCode, const DebugDetails&); QString backupPreviousFile(const QString& fileName); diff --git a/core_lib/src/structure/layer.cpp b/core_lib/src/structure/layer.cpp index 1ce4e92c3..b3163d54b 100644 --- a/core_lib/src/structure/layer.cpp +++ b/core_lib/src/structure/layer.cpp @@ -37,7 +37,7 @@ Layer::Layer(Object* object, LAYER_TYPE eType) mObject = object; meType = eType; - mName = QString(QObject::tr("Undefined Layer")); + mName = QString(tr("Undefined Layer")); mId = object->getUniqueLayerID(); } diff --git a/core_lib/src/structure/layerbitmap.cpp b/core_lib/src/structure/layerbitmap.cpp index a3fe09517..e81e24477 100644 --- a/core_lib/src/structure/layerbitmap.cpp +++ b/core_lib/src/structure/layerbitmap.cpp @@ -25,7 +25,7 @@ GNU General Public License for more details. LayerBitmap::LayerBitmap(Object* object) : Layer(object, Layer::BITMAP) { - setName(QObject::tr("Bitmap Layer")); + setName(tr("Bitmap Layer")); } LayerBitmap::~LayerBitmap() diff --git a/core_lib/src/structure/layercamera.cpp b/core_lib/src/structure/layercamera.cpp index 9d5900735..2d4712ed6 100644 --- a/core_lib/src/structure/layercamera.cpp +++ b/core_lib/src/structure/layercamera.cpp @@ -26,7 +26,7 @@ GNU General Public License for more details. LayerCamera::LayerCamera(Object* object) : Layer(object, Layer::CAMERA) { - setName(QObject::tr("Camera Layer")); + setName(tr("Camera Layer")); QSettings settings(PENCIL2D, PENCIL2D); mFieldW = settings.value("FieldW").toInt(); diff --git a/core_lib/src/structure/layersound.cpp b/core_lib/src/structure/layersound.cpp index 9165c866d..83b46bc50 100644 --- a/core_lib/src/structure/layersound.cpp +++ b/core_lib/src/structure/layersound.cpp @@ -26,7 +26,7 @@ GNU General Public License for more details. LayerSound::LayerSound(Object* object) : Layer(object, Layer::SOUND) { - setName(QObject::tr("Sound Layer")); + setName(tr("Sound Layer")); } LayerSound::~LayerSound() diff --git a/core_lib/src/structure/layervector.cpp b/core_lib/src/structure/layervector.cpp index babd1577c..57ea14443 100644 --- a/core_lib/src/structure/layervector.cpp +++ b/core_lib/src/structure/layervector.cpp @@ -24,7 +24,7 @@ GNU General Public License for more details. LayerVector::LayerVector(Object* object) : Layer(object, Layer::VECTOR) { - setName(QObject::tr("Vector Layer")); + setName(tr("Vector Layer")); } LayerVector::~LayerVector() diff --git a/core_lib/src/structure/object.cpp b/core_lib/src/structure/object.cpp index f29b878c1..3e84df91b 100644 --- a/core_lib/src/structure/object.cpp +++ b/core_lib/src/structure/object.cpp @@ -33,7 +33,6 @@ GNU General Public License for more details. #include "layercamera.h" #include "util.h" -#include "editor.h" #include "bitmapimage.h" #include "vectorimage.h" #include "fileformat.h" @@ -42,7 +41,6 @@ GNU General Public License for more details. Object::Object() { - setData(new ObjectData()); mActiveFramePool.reset(new ActiveFramePool); } @@ -853,10 +851,9 @@ int Object::getLayerCount() const return mLayers.size(); } -void Object::setData(const ObjectData* d) +void Object::setData(const ObjectData& d) { - Q_ASSERT(d != nullptr); - mData = *d; + mData = d; } int Object::totalKeyFrameCount() const diff --git a/core_lib/src/structure/object.h b/core_lib/src/structure/object.h index cf1aefcbf..9c7c8e1e6 100644 --- a/core_lib/src/structure/object.h +++ b/core_lib/src/structure/object.h @@ -141,7 +141,7 @@ class Object final ObjectData* data() { return &mData; } const ObjectData* data() const { return &mData; } - void setData(const ObjectData*); + void setData(const ObjectData&); int totalKeyFrameCount() const; void updateActiveFrames(int frame) const;