From 0772c714e31e983e9658154db3bfc33f3e72c0fe Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 22 Jun 2022 22:27:18 -0400 Subject: [PATCH] Move selection-only preview to refresh function When the drawing items are mutated during a modification event cycle, there is the possibility that the drawing item hierarchy is not consistent and will crash. Also fixes lack of updates on selectionModified. Fixes https://gitlab.com/inkscape/inkscape/-/issues/3638 Fixes https://gitlab.com/inkscape/inkscape/-/issues/3582 --- src/ui/dialog/export-batch.cpp | 20 ++++++++++---------- src/ui/dialog/export-single.cpp | 15 ++++++++------- src/ui/widget/export-preview.cpp | 12 +++++++++++- src/ui/widget/export-preview.h | 7 ++++++- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/ui/dialog/export-batch.cpp b/src/ui/dialog/export-batch.cpp index eef2fda72c..8ba8d2c0b7 100644 --- a/src/ui/dialog/export-batch.cpp +++ b/src/ui/dialog/export-batch.cpp @@ -67,7 +67,7 @@ public: SPPage *getPage() { return _page; } bool isActive() { return _selector.get_active(); } void refresh(bool hide, guint32 bg_color); - void refreshHide(const std::vector *list) { _preview.refreshHide(list); } + void refreshHide(const std::vector &list) { _preview.refreshHide(list); } void setDocument(SPDocument *doc) { _preview.setDocument(doc); } private: @@ -408,16 +408,16 @@ void BatchExport::refreshPreview() for (auto &[key, val] : current_items) { if (preview) { - if (!hide) { - val->refreshHide(nullptr); - } else if (auto item = val->getItem()) { - std::vector selected = {item}; - val->refreshHide(&selected); - } else if (val->getPage()) { - auto sels = _desktop->getSelection()->items(); - std::vector selected(sels.begin(), sels.end()); - val->refreshHide(&selected); + std::vector selected; + if (hide) { + if (auto item = val->getItem()) { + selected = std::vector({item}); + } else if (val->getPage()) { + auto sels = _desktop->getSelection()->items(); + selected = std::vector(sels.begin(), sels.end()); + } } + val->refreshHide(selected); } val->refresh(!preview, _bgnd_color_picker->get_current_color()); } diff --git a/src/ui/dialog/export-single.cpp b/src/ui/dialog/export-single.cpp index 8a1ef9ea3d..63819caa0d 100644 --- a/src/ui/dialog/export-single.cpp +++ b/src/ui/dialog/export-single.cpp @@ -138,10 +138,8 @@ void SingleExport::selectionModified(Inkscape::Selection *selection, guint flags if (!(flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { return; } - if (!_document) { - refreshArea(); - loadExportHints(); - } + refreshArea(); + // Do not load export hits for modifications } void SingleExport::selectionChanged(Inkscape::Selection *selection) @@ -951,8 +949,11 @@ void SingleExport::refreshPreview() return; } - std::vector selected(_desktop->getSelection()->items().begin(), _desktop->getSelection()->items().end()); - bool hide = si_hide_all->get_active(); + std::vector selected; + if (si_hide_all->get_active()) { + // This is because selection items is not a std::vector yet. FIXME. + selected = std::vector(_desktop->getSelection()->items().begin(), _desktop->getSelection()->items().end()); + } Unit const *unit = units->getUnit(); float x0 = unit->convert(spin_buttons[SPIN_X0]->get_value(), "px"); @@ -961,7 +962,7 @@ void SingleExport::refreshPreview() float y1 = unit->convert(spin_buttons[SPIN_Y1]->get_value(), "px"); preview->setDbox(x0, x1, y0, y1); preview->set_background_color(_bgnd_color_picker->get_current_color()); - preview->refreshHide(hide ? &selected : nullptr); + preview->refreshHide(selected); preview->queueRefresh(); } diff --git a/src/ui/widget/export-preview.cpp b/src/ui/widget/export-preview.cpp index 6f01bcc1e7..bdf60ba275 100644 --- a/src/ui/widget/export-preview.cpp +++ b/src/ui/widget/export-preview.cpp @@ -92,7 +92,13 @@ void ExportPreview::setDocument(SPDocument *document) } } -void ExportPreview::refreshHide(const std::vector *list) +void ExportPreview::refreshHide(const std::vector &list) +{ + _hidden_excluded = std::vector(list.begin(), list.end()); + _hidden_requested = true; +} + +void ExportPreview::performHide(const std::vector *list) { if (_document) { if (isLastHide) { @@ -192,6 +198,10 @@ void ExportPreview::renderPreview() return; } + if (_hidden_requested) { + this->performHide(&_hidden_excluded); + _hidden_requested = false; + } if (_document) { GdkPixbuf *pb = nullptr; if (_item) { diff --git a/src/ui/widget/export-preview.h b/src/ui/widget/export-preview.h index 54d58c045c..2aa651b549 100644 --- a/src/ui/widget/export-preview.h +++ b/src/ui/widget/export-preview.h @@ -16,6 +16,8 @@ #include "document.h" class SPObject; +class SPItem; + namespace Glib { class Timer; } @@ -47,9 +49,11 @@ private: gdouble minDelay = 0.1; guint32 _bg_color = 0; + std::vector _hidden_excluded; + bool _hidden_requested = false; public: void setDocument(SPDocument *document); - void refreshHide(const std::vector *list); + void refreshHide(const std::vector &list = {}); void hide_other_items_recursively(SPObject *o, const std::vector &list); void setItem(SPItem *item); void setDbox(double x0, double x1, double y0, double y1); @@ -67,6 +71,7 @@ private: void refreshPreview(); void renderPreview(); bool refreshCB(); + void performHide(const std::vector *list); }; } // namespace Dialog } // namespace UI -- GitLab