From 317bc432e27d220efdcb01cfc6c2bd2ed1eea6a1 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Sat, 29 Jan 2022 20:13:54 +0200 Subject: [PATCH] Fix reparsing background image items. --- src/app/valentina/mainwindow.cpp | 104 +++++++++++++++++++++---------- src/app/valentina/mainwindow.h | 6 +- 2 files changed, 76 insertions(+), 34 deletions(-) diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 2f5a5b020..f3e3c8881 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -2398,41 +2398,53 @@ void MainWindow::NewBackgroundImageItem(const VBackgroundPatternImage &image) m_backgroundImages.insert(image.Id(), item); } m_deletedBackgroundImageItems.remove(image.Id()); + m_deletedBackgroundImages.remove(image.Id()); } else { - VBackgroundImageItem *item = nullptr; - if (image.Type() == PatternImage::Raster) - { - item = new VBackgroundPixmapItem(image, doc); - } - else if (image.Type() == PatternImage::Vector || image.Type() == PatternImage::Unknown) - { - item = new VBackgroundSVGItem(image, doc); - } - + VBackgroundImageItem *item = InitBackgroundImageItem(image); if (item != nullptr) { - connect(item, &VBackgroundImageItem::UpdateControls, m_backgroudcontrols, - &VBackgroundImageControls::UpdateControls); - connect(item, &VBackgroundImageItem::ActivateControls, m_backgroudcontrols, - &VBackgroundImageControls::ActivateControls); - connect(item, &VBackgroundImageItem::DeleteImage, this, &MainWindow::RemoveBackgroundImage); - connect(this, &MainWindow::EnableBackgroundImageSelection, item, &VBackgroundImageItem::EnableSelection); - connect(item, &VBackgroundImageItem::ShowImageInExplorer, this, &MainWindow::ShowBackgroundImageInExplorer); - connect(item, &VBackgroundImageItem::SaveImage, this, &MainWindow::SaveBackgroundImage); - connect(m_backgroudcontrols, &VBackgroundImageControls::ActiveImageChanged, backgroundImagesWidget, - &VWidgetBackgroundImages::ImageSelected); - connect(backgroundImagesWidget, &VWidgetBackgroundImages::SelectImage, m_backgroudcontrols, - &VBackgroundImageControls::ActivateControls); - sceneDraw->addItem(item); m_backgroundImages.insert(image.Id(), item); + sceneDraw->addItem(item); } } VMainGraphicsView::NewSceneRect(sceneDraw, ui->view); } +//--------------------------------------------------------------------------------------------------------------------- +auto MainWindow::InitBackgroundImageItem(const VBackgroundPatternImage &image) -> VBackgroundImageItem * +{ + VBackgroundImageItem *item = nullptr; + if (image.Type() == PatternImage::Raster) + { + item = new VBackgroundPixmapItem(image, doc); + } + else if (image.Type() == PatternImage::Vector || image.Type() == PatternImage::Unknown) + { + item = new VBackgroundSVGItem(image, doc); + } + + if (item != nullptr) + { + connect(item, &VBackgroundImageItem::UpdateControls, m_backgroudcontrols, + &VBackgroundImageControls::UpdateControls); + connect(item, &VBackgroundImageItem::ActivateControls, m_backgroudcontrols, + &VBackgroundImageControls::ActivateControls); + connect(item, &VBackgroundImageItem::DeleteImage, this, &MainWindow::RemoveBackgroundImage); + connect(this, &MainWindow::EnableBackgroundImageSelection, item, &VBackgroundImageItem::EnableSelection); + connect(item, &VBackgroundImageItem::ShowImageInExplorer, this, &MainWindow::ShowBackgroundImageInExplorer); + connect(item, &VBackgroundImageItem::SaveImage, this, &MainWindow::SaveBackgroundImage); + connect(m_backgroudcontrols, &VBackgroundImageControls::ActiveImageChanged, backgroundImagesWidget, + &VWidgetBackgroundImages::ImageSelected); + connect(backgroundImagesWidget, &VWidgetBackgroundImages::SelectImage, m_backgroudcontrols, + &VBackgroundImageControls::ActivateControls); + } + + return item; +} + //--------------------------------------------------------------------------------------------------------------------- #if defined(Q_OS_MAC) void MainWindow::OpenAt(QAction *where) @@ -3821,6 +3833,7 @@ void MainWindow::FullParseFile() SetEnabledGUI(true); doc->Parse(Document::FullParse); + ParseBackgroundImages(); if (VAbstractValApplication::VApp()->getOpeningPattern()) { @@ -4358,6 +4371,7 @@ void MainWindow::DeleteBackgroundImageItem(const QUuid &id) } m_backgroundImages.remove(id); m_deletedBackgroundImageItems.insert(id, item); + m_deletedBackgroundImages.insert(id, item->Image()); if (backgroundImagesWidget != nullptr) { @@ -4425,6 +4439,39 @@ void MainWindow::SaveBackgroundImage(const QUuid &id) } } +//--------------------------------------------------------------------------------------------------------------------- +void MainWindow::ParseBackgroundImages() +{ + // No memory leak. Scene should take care of these items + m_backgroudcontrols = nullptr; // force creating new controls + m_backgroundImages.clear(); // clear dangling pointers + + QVector allImages = doc->GetBackgroundImages(); + for (const auto &image : allImages) + { + NewBackgroundImageItem(image); + } + backgroundImagesWidget->UpdateImages(); + + // Undostack rely on m_deletedBackgroundImageItems to prevent crashes + QMap deletedBackgroundImageItems; + QMap::const_iterator i; + for (i = m_deletedBackgroundImageItems.constBegin(); i != m_deletedBackgroundImageItems.constEnd(); ++i) + { + if (m_deletedBackgroundImages.contains(i.key())) + { + VBackgroundPatternImage image = m_deletedBackgroundImages.value(i.key()); + VBackgroundImageItem *item = InitBackgroundImageItem(image); + if (item != nullptr) + { + deletedBackgroundImageItems.insert(image.Id(), item); + } + } + } + + m_deletedBackgroundImageItems = deletedBackgroundImageItems; +} + //--------------------------------------------------------------------------------------------------------------------- void MainWindow::InitDimensionControls() { @@ -5838,16 +5885,7 @@ bool MainWindow::LoadPattern(QString fileName, const QString& customMeasureFile) /* Collect garbage only after successfully parse. This way wrongly accused items have one more time to restore * a reference. */ QTimer::singleShot(100, Qt::CoarseTimer, this, [this](){doc->GarbageCollector(true);}); - - QTimer::singleShot(500, Qt::CoarseTimer, this, [this]() - { - QVector allImages = doc->GetBackgroundImages(); - for (const auto &image : allImages) - { - NewBackgroundImageItem(image); - } - backgroundImagesWidget->UpdateImages(); - }); + QTimer::singleShot(500, Qt::CoarseTimer, this, &MainWindow::ParseBackgroundImages); } patternReadOnly = doc->IsReadOnly(); diff --git a/src/app/valentina/mainwindow.h b/src/app/valentina/mainwindow.h index d4d8bd533..d07391790 100644 --- a/src/app/valentina/mainwindow.h +++ b/src/app/valentina/mainwindow.h @@ -241,6 +241,8 @@ private slots: void ShowBackgroundImageInExplorer(const QUuid &id); void SaveBackgroundImage(const QUuid &id); + void ParseBackgroundImages(); + private: Q_DISABLE_COPY(MainWindow) /** @brief ui keeps information about user interface */ @@ -323,7 +325,8 @@ private: QMap m_backgroundImages{}; QMap m_deletedBackgroundImageItems{}; - VBackgroundImageControls *m_backgroudcontrols{nullptr}; + VBackgroundImageControls* m_backgroudcontrols{nullptr}; + QMap m_deletedBackgroundImages{}; bool m_groupsActive{false}; bool m_toolOptionsActive{false}; @@ -446,6 +449,7 @@ private: void ExportDraw(const QString &fileName); void NewBackgroundImageItem(const VBackgroundPatternImage &image); + auto InitBackgroundImageItem(const VBackgroundPatternImage &image) -> VBackgroundImageItem *; }; #endif // MAINWINDOW_H