From 1418d06569444dcce4813ae93d34406970bc102b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Simonis?= <simonisfrederic@gmail.com>
Date: Sun, 20 Nov 2022 14:06:19 +0100
Subject: [PATCH] Add deferred naming and bulkadder

---
 scribus/CMakeLists.txt                   |   1 +
 scribus/bulkadder.cpp                    | 108 +++++++++++++++++++++++
 scribus/bulkadder.h                      |  53 +++++++++++
 scribus/pageitem.cpp                     |  85 +++++++++++++-----
 scribus/pageitem.h                       |  11 +++
 scribus/pageitem_arc.cpp                 |   4 +
 scribus/pageitem_arc.h                   |   1 +
 scribus/pageitem_group.cpp               |   5 ++
 scribus/pageitem_group.h                 |   1 +
 scribus/pageitem_imageframe.cpp          |   7 +-
 scribus/pageitem_imageframe.h            |   1 +
 scribus/pageitem_latexframe.cpp          |   6 +-
 scribus/pageitem_latexframe.h            |   1 +
 scribus/pageitem_line.cpp                |   5 ++
 scribus/pageitem_line.h                  |   1 +
 scribus/pageitem_noteframe.cpp           |  14 ++-
 scribus/pageitem_noteframe.h             |   5 ++
 scribus/pageitem_osgframe.cpp            |   5 +-
 scribus/pageitem_osgframe.h              |   1 +
 scribus/pageitem_pathtext.cpp            |   6 +-
 scribus/pageitem_pathtext.h              |   1 +
 scribus/pageitem_polygon.cpp             |   5 ++
 scribus/pageitem_polygon.h               |   1 +
 scribus/pageitem_polyline.cpp            |   5 ++
 scribus/pageitem_polyline.h              |   1 +
 scribus/pageitem_regularpolygon.cpp      |   5 +-
 scribus/pageitem_regularpolygon.h        |   1 +
 scribus/pageitem_spiral.cpp              |   5 +-
 scribus/pageitem_spiral.h                |   1 +
 scribus/pageitem_symbol.cpp              |   5 ++
 scribus/pageitem_symbol.h                |   1 +
 scribus/pageitem_table.cpp               |   7 +-
 scribus/pageitem_table.h                 |   1 +
 scribus/pageitem_textframe.cpp           |   8 +-
 scribus/pageitem_textframe.h             |   1 +
 scribus/plugins/import/pdf/slaoutput.cpp |  44 ++++-----
 scribus/plugins/import/pdf/slaoutput.h   |   2 +
 scribus/scribusdoc.cpp                   |  66 ++++++++++----
 scribus/scribusdoc.h                     |  10 +++
 39 files changed, 417 insertions(+), 74 deletions(-)
 create mode 100644 scribus/bulkadder.cpp
 create mode 100644 scribus/bulkadder.h

diff --git a/scribus/CMakeLists.txt b/scribus/CMakeLists.txt
index 9e82181..fc29160 100644
--- a/scribus/CMakeLists.txt
+++ b/scribus/CMakeLists.txt
@@ -71,6 +71,7 @@ set(SCRIBUS_SOURCES
 	actionmanager.cpp
 	actionsearch.cpp
 	appmodehelper.cpp
+	bulkadder.cpp
 	canvas.cpp
 	canvasgesture_cellselect.cpp
 	canvasgesture_columnresize.cpp
diff --git a/scribus/bulkadder.cpp b/scribus/bulkadder.cpp
new file mode 100644
index 0000000..512ee2e
--- /dev/null
+++ b/scribus/bulkadder.cpp
@@ -0,0 +1,108 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+/***************************************************************************
+ *   Copyright (C) 2005 by Riku Leino                                      *
+ *   riku@scribus.info                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
+ ***************************************************************************/
+
+#include <set>
+#include <map>
+
+#include "bulkadder.h"
+
+namespace {
+void findName(PageItem *item, std::set<QString> &names,
+              std::map<PageItem::ItemType, int> &lastSuccess) {
+  auto type = item->itemType();
+  QString baseName = item->nameFromType(type);
+
+  int nameNum = lastSuccess[type];
+  QString tmp;
+  tmp.setNum(nameNum);
+  tmp.prepend(baseName);
+  while (names.count(tmp) != 0) {
+    ++nameNum;
+    tmp.setNum(nameNum);
+    tmp.prepend(baseName);
+  }
+  lastSuccess[type] = nameNum;
+  names.insert(tmp);
+  item->setSafeItemName(tmp);
+}
+
+std::set<QString> gatherNames(ScribusDoc *doc) {
+  std::set<QString> names;
+  std::vector<PageItem *> groups;
+  groups.reserve(32);
+
+  // Process root elements of the doc and remember groups
+  for (PageItem *item : *doc->Items) {
+    names.insert(item->itemName());
+    if (item->isGroup())
+      groups.push_back(item);
+  }
+
+  // Process groups
+  while (!groups.empty()) {
+    PageItem *item = groups.back();
+    groups.pop_back();
+    for (PageItem *item : item->groupItemList) {
+      names.insert(item->itemName());
+      if (item->isGroup())
+        groups.push_back(item);
+    }
+  }
+  return names;
+}
+} // namespace
+
+int BulkAdder::itemAdd(const PageItem::ItemType itemType,
+                       const PageItem::ItemFrameType frameType, double x,
+                       double y, double b, double h, double w,
+                       const QString &fill, const QString &outline,
+                       PageItem::ItemKind itemKind) {
+  int id = m_doc->itemAddDeferred(itemType, frameType, x, y, b, h, w, fill,
+                                  outline, itemKind);
+  m_pending.push_back(m_doc->Items->at(id));
+  return id;
+}
+
+
+PageItem* BulkAdder::groupObjectsSelection(Selection* customSelection)
+{
+  auto group = m_doc->groupObjectsSelectionDeferred(customSelection);
+  m_pending.push_back(group);
+  return group;
+}
+
+void BulkAdder::process() {
+  if (m_pending.empty()) {
+    return;
+  }
+
+  auto names = gatherNames(m_doc);
+  std::map<PageItem::ItemType, int> lastSuccess;
+  for (auto item : m_pending) {
+    findName(item, names, lastSuccess);
+  }
+  m_pending.clear();
+}
diff --git a/scribus/bulkadder.h b/scribus/bulkadder.h
new file mode 100644
index 0000000..2d630cd
--- /dev/null
+++ b/scribus/bulkadder.h
@@ -0,0 +1,53 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+/***************************************************************************
+ *   Copyright (C) 2005 by Riku Leino                                      *
+ *   riku@scribus.info                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
+ ***************************************************************************/
+
+#ifndef BULKADDER_H
+#define BULKADDER_H
+
+#include "pageitem.h"
+#include "scribusdoc.h"
+#include "scribusapi.h"
+
+class SCRIBUS_API BulkAdder {
+  public:
+    BulkAdder(ScribusDoc * document) : m_doc(document) {};
+
+    ~BulkAdder() {
+      process();
+    };
+
+    int itemAdd(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline, PageItem::ItemKind itemKind = PageItem::StandardItem);
+
+	  PageItem* groupObjectsSelection(Selection* customSelection = nullptr);
+
+    void process();
+
+  private:
+    ScribusDoc *  m_doc;
+    std::vector<PageItem*> m_pending;
+};
+
+#endif
diff --git a/scribus/pageitem.cpp b/scribus/pageitem.cpp
index b175029..501a54f 100644
--- a/scribus/pageitem.cpp
+++ b/scribus/pageitem.cpp
@@ -396,6 +396,9 @@ PageItem::PageItem(const PageItem & other)
 
 
 PageItem::PageItem(ScribusDoc *doc, ItemType newType, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
+ : PageItem(doc, newType, x, y, w, h, w2, fill, outline, NameTiming::Direct){};
+
+PageItem::PageItem(ScribusDoc *doc, ItemType newType, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
 	// Initialize superclass(es)
 	: QObject(doc), SingleObservable<PageItem>(doc->itemsChanged()), TextContext(this),
 	// Initialize member variables
@@ -455,70 +458,64 @@ PageItem::PageItem(ScribusDoc *doc, ItemType newType, double x, double y, double
 			// because c++'s typeinfos are still saying it's
 			// a plain pageitem
 			// This is fixed in the PageItem_LatexFrame constructor
-			m_itemName = tr("Image");
 			setUPixmap(Um::IImageFrame);
 			break;
 		case TextFrame:
-			m_itemName = tr("Text");
 			setUPixmap(Um::ITextFrame);
 			break;
 		case Line:
-			m_itemName = tr("Line");
 			setUPixmap(Um::ILine);
 			break;
 		case Polygon:
-			m_itemName = tr("Polygon");
 			setUPixmap(Um::IPolygon);
 			break;
 		case PolyLine:
-			m_itemName = tr("Polyline");
 			setUPixmap(Um::IPolyline);
 			break;
 		case PathText:
-			m_itemName = tr("PathText");
 			setUPixmap(Um::IPathText);
 			break;
 		case Symbol:
-			m_itemName = tr("Symbol");
 			setUPixmap(Um::IPolygon);
 			break;
 		case Group:
-			m_itemName = tr("Group");
 			setUPixmap(Um::IPolygon);
 			break;
 		case RegularPolygon:
-			m_itemName = tr("RegularPolygon");
 			setUPixmap(Um::IPolygon);
 			break;
 		case Arc:
-			m_itemName = tr("Arc");
 			setUPixmap(Um::IPolygon);
 			break;
 		case Spiral:
-			m_itemName = tr("Spiral");
 			setUPixmap(Um::IPolygon);
 			break;
 		case Table:
-			m_itemName = tr("Table");
 			//setUPixmap(Um::IPolygon); // TODO: Fix this.
 			break;
 		default:
-			m_itemName = "Item";
 			break;
 	}
 	m_Doc->TotalItems++;
+
+  if (nameTiming == NameTiming::Deferred) {
+    // It is the callers responsibilty to create a usable name
+    m_itemName = "pending";
+  } else {
+    m_itemName = nameFromType(m_itemType);
 	
-	QString oldName(m_itemName);
-	int nameNum = m_Doc->TotalItems;
-	m_itemName += tmp.setNum(m_Doc->TotalItems);
-	while (m_Doc->itemNameExists(m_itemName))
-	{
-		++nameNum;
-		m_itemName = oldName + tmp.setNum(nameNum);
-	}
+    QString oldName(m_itemName);
+    int nameNum = m_Doc->TotalItems;
+    m_itemName += tmp.setNum(m_Doc->TotalItems);
+    while (m_Doc->itemNameExists(m_itemName))
+    {
+      ++nameNum;
+      m_itemName = oldName + tmp.setNum(nameNum);
+    }
 	
-	uniqueNr = m_Doc->TotalItems;
-	setUName(m_itemName);
+    //uniqueNr = m_Doc->TotalItems;
+    setUName(m_itemName);
+  }
 	m_annotation.setBorderColor(outline);
 
 	ImageIntent = Intent_Relative_Colorimetric;
@@ -723,6 +720,39 @@ PageItem::~PageItem()
 //			unWeldChild();
 }
 
+QString PageItem::nameFromType(ItemType type) {
+  switch (type) {
+    case ImageFrame:
+    case OSGFrame:
+    case LatexFrame:
+      return tr("Image");
+    case TextFrame:
+      return tr("Text");
+    case Line:
+      return tr("Line");
+    case Polygon:
+      return tr("Polygon");
+    case PolyLine:
+      return tr("Polyline");
+    case PathText:
+      return tr("PathText");
+    case Symbol:
+      return tr("Symbol");
+    case Group:
+      return tr("Group");
+    case RegularPolygon:
+      return tr("RegularPolygon");
+    case Arc:
+      return tr("Arc");
+    case Spiral:
+      return tr("Spiral");
+    case Table:
+      return tr("Table");
+    default:
+      return "Item";
+  }
+}
+
 bool PageItem::isMasterItem() const
 {
 	if (Parent == nullptr)
@@ -2402,6 +2432,15 @@ void PageItem::DrawPolyL(QPainter *p, const QPolygon& pts)
 	p->drawPolygon(pts.constData() + firstVal, pts.size() - firstVal);
 }
 
+void PageItem::setSafeItemName(const QString& uniqueName)
+{
+	if (m_itemName == uniqueName || uniqueName.isEmpty())
+		return;
+
+  m_itemName = uniqueName;
+	setUName(m_itemName);
+}
+
 void PageItem::setItemName(const QString& newName)
 {
 	if (m_itemName == newName || newName.isEmpty())
diff --git a/scribus/pageitem.h b/scribus/pageitem.h
index 73125b5..74250fb 100644
--- a/scribus/pageitem.h
+++ b/scribus/pageitem.h
@@ -38,6 +38,7 @@ for which a new license (GPL+exception) is in place.
 #include <QVector>
 #include <QTemporaryFile>
 
+#include "deferredtask.h"
 #include "scribusapi.h"
 #include "annotation.h"
 #include "commonstrings.h"
@@ -219,6 +220,11 @@ public:	// Start enumerator definitions
 		Round		= 2,
 		Other		= 3
 	};
+
+  enum struct NameTiming : bool {
+    Direct,
+    Deferred
+  };
 		//End enumerator definitions
 
 	// This property may not hang around for too long, but should be useful
@@ -234,6 +240,7 @@ public:	// Start enumerator definitions
 public: // Start public functions
 
 	PageItem(ScribusDoc *doc, ItemType newType, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem(ScribusDoc *doc, ItemType newType, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	~PageItem() override;
 
 	/* these do essentially the same as a dynamic cast but might be more readable */
@@ -813,6 +820,8 @@ public: // Start public functions
 	 */
 	void setItemName(const QString& newName);
 
+	void setSafeItemName(const QString& uniqueName);
+
 	/**
 	* @brief Set the masterpage the object is on
 	* @param mpName name of the master page
@@ -1267,6 +1276,8 @@ public: // Start public functions
 	bool hasFill() { return ((fillColor() != CommonStrings::None) || (GrType != 0)); }
 	bool hasStroke() { return ((lineColor() != CommonStrings::None) || (GrTypeStroke != 0) || (!NamedLStyle.isEmpty()) || (!patternStrokeVal.isEmpty())); }
 
+  QString nameFromType(ItemType type);
+
 		// End public functions
 
 public:	// Start public variables
diff --git a/scribus/pageitem_arc.cpp b/scribus/pageitem_arc.cpp
index d840fb3..7401a4a 100644
--- a/scribus/pageitem_arc.cpp
+++ b/scribus/pageitem_arc.cpp
@@ -21,6 +21,7 @@ for which a new license (GPL+exception) is in place.
  *                                                                         *
  ***************************************************************************/
 
+#include <fcntl.h>
 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
 #define _USE_MATH_DEFINES
 #endif
@@ -47,6 +48,9 @@ for which a new license (GPL+exception) is in place.
 using namespace std;
 
 PageItem_Arc::PageItem_Arc(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
+	: PageItem_Arc(pa, x, y, w, h, w2, fill, outline, NameTiming::Direct){};
+
+PageItem_Arc::PageItem_Arc(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
 	: PageItem(pa, PageItem::Arc, x, y, w, h, w2, fill, outline)
 {
 	arcHeight = h;
diff --git a/scribus/pageitem_arc.h b/scribus/pageitem_arc.h
index 25cf024..74842aa 100644
--- a/scribus/pageitem_arc.h
+++ b/scribus/pageitem_arc.h
@@ -37,6 +37,7 @@ class SCRIBUS_API PageItem_Arc : public PageItem
 
 public:
 	PageItem_Arc(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_Arc(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_Arc(const PageItem & p) : PageItem(p) {}
 	~PageItem_Arc() {};
 
diff --git a/scribus/pageitem_group.cpp b/scribus/pageitem_group.cpp
index f6f0b95..7669448 100644
--- a/scribus/pageitem_group.cpp
+++ b/scribus/pageitem_group.cpp
@@ -52,6 +52,11 @@ PageItem_Group::PageItem_Group(ScribusDoc *pa, double x, double y, double w, dou
 {
 }
 
+PageItem_Group::PageItem_Group(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::Group, x, y, w, h, 0, CommonStrings::None, CommonStrings::None, nameTiming)
+{
+}
+
 PageItem_Group::~PageItem_Group()
 {
 //	while (!groupItemList.isEmpty())
diff --git a/scribus/pageitem_group.h b/scribus/pageitem_group.h
index fcead53..8edc224 100644
--- a/scribus/pageitem_group.h
+++ b/scribus/pageitem_group.h
@@ -37,6 +37,7 @@ class SCRIBUS_API PageItem_Group : public PageItem
 
 public:
 	PageItem_Group(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_Group(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_Group(const PageItem & p) : PageItem(p) {}
 	~PageItem_Group();
 
diff --git a/scribus/pageitem_imageframe.cpp b/scribus/pageitem_imageframe.cpp
index 0702b41..fb7ec85 100644
--- a/scribus/pageitem_imageframe.cpp
+++ b/scribus/pageitem_imageframe.cpp
@@ -55,8 +55,13 @@ for which a new license (GPL+exception) is in place.
 #include "util.h"
 
 
+PageItem_ImageFrame::PageItem_ImageFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::ImageFrame, x, y, w, h, w2, fill, outline, nameTiming)
+{
+}
+
 PageItem_ImageFrame::PageItem_ImageFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
-	: PageItem(pa, PageItem::ImageFrame, x, y, w, h, w2, fill, outline)
+	: PageItem(pa, PageItem::ImageFrame, x, y, w, h, w2, fill, outline, NameTiming::Direct)
 {
 }
 
diff --git a/scribus/pageitem_imageframe.h b/scribus/pageitem_imageframe.h
index a0b4d3b..355f708 100644
--- a/scribus/pageitem_imageframe.h
+++ b/scribus/pageitem_imageframe.h
@@ -37,6 +37,7 @@ class SCRIBUS_API PageItem_ImageFrame : public PageItem
 
 public:
 	PageItem_ImageFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_ImageFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_ImageFrame(const PageItem & p) : PageItem(p) {}
 	~PageItem_ImageFrame();
 
diff --git a/scribus/pageitem_latexframe.cpp b/scribus/pageitem_latexframe.cpp
index 6cba246..2f3681d 100644
--- a/scribus/pageitem_latexframe.cpp
+++ b/scribus/pageitem_latexframe.cpp
@@ -41,7 +41,11 @@ for which a new license (GPL+exception) is in place.
 #include "util.h"
 
 PageItem_LatexFrame::PageItem_LatexFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
-		: PageItem_ImageFrame(pa, x, y, w, h, w2, fill, outline)
+		: PageItem_LatexFrame(pa, x, y, w, h, w2, fill, outline, NameTiming::Direct)
+{}
+
+PageItem_LatexFrame::PageItem_LatexFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+		: PageItem_ImageFrame(pa, x, y, w, h, w2, fill, outline, nameTiming)
 {
 	setUPixmap(Um::ILatexFrame);
 	m_itemName = tr("Render") + QString::number(m_Doc->TotalItems);
diff --git a/scribus/pageitem_latexframe.h b/scribus/pageitem_latexframe.h
index 87a90eb..07e1ce4 100644
--- a/scribus/pageitem_latexframe.h
+++ b/scribus/pageitem_latexframe.h
@@ -46,6 +46,7 @@ class SCRIBUS_API PageItem_LatexFrame : public PageItem_ImageFrame
 
 	public:
 		PageItem_LatexFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+		PageItem_LatexFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 		~PageItem_LatexFrame();
 		
 		PageItem_LatexFrame * asLatexFrame() override { return this; }
diff --git a/scribus/pageitem_line.cpp b/scribus/pageitem_line.cpp
index da254c2..2665ef6 100644
--- a/scribus/pageitem_line.cpp
+++ b/scribus/pageitem_line.cpp
@@ -52,6 +52,11 @@ PageItem_Line::PageItem_Line(ScribusDoc *pa, double x, double y, double w, doubl
 {
 }
 
+PageItem_Line::PageItem_Line(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::Line, x, y, w, h, w2, fill, outline, nameTiming)
+{
+}
+
 void PageItem_Line::DrawObj_Item(ScPainter *p, const QRectF& /*e*/)
 {
 	if (m_Doc->RePos)
diff --git a/scribus/pageitem_line.h b/scribus/pageitem_line.h
index 60b9ade..1646224 100644
--- a/scribus/pageitem_line.h
+++ b/scribus/pageitem_line.h
@@ -37,6 +37,7 @@ class SCRIBUS_API PageItem_Line : public PageItem
 
 public:
 	PageItem_Line(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_Line(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_Line(const PageItem & p) : PageItem(p) {}
 	~PageItem_Line() {};
 	
diff --git a/scribus/pageitem_noteframe.cpp b/scribus/pageitem_noteframe.cpp
index 51b0f8e..f217d35 100644
--- a/scribus/pageitem_noteframe.cpp
+++ b/scribus/pageitem_noteframe.cpp
@@ -16,7 +16,10 @@
 #include "text/boxes.h"
 
 PageItem_NoteFrame::PageItem_NoteFrame(NotesStyle *nStyle, ScribusDoc *doc, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
-	: PageItem_TextFrame(doc, x, y, w, h, w2, fill, outline)
+  : PageItem_NoteFrame(nStyle, doc, x, y, w, h, w2, fill, outline, NameTiming::Direct) {}
+
+PageItem_NoteFrame::PageItem_NoteFrame(NotesStyle *nStyle, ScribusDoc *doc, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem_TextFrame(doc, x, y, w, h, w2, fill, outline, nameTiming)
 {
 	m_nstyle = nStyle;
 	itemText.clear();
@@ -44,12 +47,17 @@ PageItem_NoteFrame::PageItem_NoteFrame(NotesStyle *nStyle, ScribusDoc *doc, doub
 }
 
 PageItem_NoteFrame::PageItem_NoteFrame(ScribusDoc *doc, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
-	: PageItem_TextFrame(doc, x, y, w, h, w2, fill, outline)
+	: PageItem_NoteFrame(doc, x, y, w, h, w2, fill, outline, NameTiming::Direct) {}
+
+PageItem_NoteFrame::PageItem_NoteFrame(ScribusDoc *doc, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem_TextFrame(doc, x, y, w, h, w2, fill, outline, nameTiming)
 {
 	m_textFlowMode = TextFlowUsesFrameShape;
 }
 
-PageItem_NoteFrame::PageItem_NoteFrame(PageItem_TextFrame* inFrame, NotesStyle *nStyle) : PageItem_TextFrame(inFrame->doc(),inFrame->xPos(), inFrame->yPos(),inFrame->width(), inFrame->height(),inFrame->lineWidth(), inFrame->fillColor(), inFrame->lineColor())
+PageItem_NoteFrame::PageItem_NoteFrame(PageItem_TextFrame* inFrame, NotesStyle *nStyle) : PageItem_NoteFrame(inFrame, nStyle, NameTiming::Direct) {};
+
+PageItem_NoteFrame::PageItem_NoteFrame(PageItem_TextFrame* inFrame, NotesStyle *nStyle, NameTiming nameTiming) : PageItem_TextFrame(inFrame->doc(),inFrame->xPos(), inFrame->yPos(),inFrame->width(), inFrame->height(),inFrame->lineWidth(), inFrame->fillColor(), inFrame->lineColor(), nameTiming)
 {
 	m_nstyle = nStyle;
 	m_masterFrame = inFrame;
diff --git a/scribus/pageitem_noteframe.h b/scribus/pageitem_noteframe.h
index 5f62395..f1dbd33 100644
--- a/scribus/pageitem_noteframe.h
+++ b/scribus/pageitem_noteframe.h
@@ -14,6 +14,11 @@ private:
 	PageItem_NoteFrame(NotesStyle *nStyle, ScribusDoc *doc, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
 	PageItem_NoteFrame(ScribusDoc *doc, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
 	PageItem_NoteFrame(PageItem_TextFrame* inFrame, NotesStyle *nStyle);
+
+	PageItem_NoteFrame(NotesStyle *nStyle, ScribusDoc *doc, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
+	PageItem_NoteFrame(ScribusDoc *doc, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
+	PageItem_NoteFrame(PageItem_TextFrame* inFrame, NotesStyle *nStyle, NameTiming nameTiming);
+
 	~PageItem_NoteFrame() { }
 
 public:
diff --git a/scribus/pageitem_osgframe.cpp b/scribus/pageitem_osgframe.cpp
index 03f46f2..14845c0 100644
--- a/scribus/pageitem_osgframe.cpp
+++ b/scribus/pageitem_osgframe.cpp
@@ -42,7 +42,10 @@ for which a new license (GPL+exception) is in place.
 #include "util.h"
 
 PageItem_OSGFrame::PageItem_OSGFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
-		: PageItem_ImageFrame(pa, x, y, w, h, w2, fill, outline)
+		: PageItem_ImageFrame(pa, x, y, w, h, w2, fill, outline, NameTiming::Direct) {}
+
+PageItem_OSGFrame::PageItem_OSGFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+		: PageItem_ImageFrame(pa, x, y, w, h, w2, fill, outline, nameTiming)
 {
 	setUPixmap(Um::ILatexFrame);
 	m_itemName = tr("OSG") + QString::number(m_Doc->TotalItems);
diff --git a/scribus/pageitem_osgframe.h b/scribus/pageitem_osgframe.h
index f184bef..f08f972 100644
--- a/scribus/pageitem_osgframe.h
+++ b/scribus/pageitem_osgframe.h
@@ -74,6 +74,7 @@ class SCRIBUS_API PageItem_OSGFrame : public PageItem_ImageFrame
 			ShadedIllustration				= 14
 		};
 		PageItem_OSGFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+		PageItem_OSGFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 		~PageItem_OSGFrame();
 		
 		PageItem_OSGFrame * asOSGFrame() override { return this; }
diff --git a/scribus/pageitem_pathtext.cpp b/scribus/pageitem_pathtext.cpp
index 66a9f6f..dd758de 100644
--- a/scribus/pageitem_pathtext.cpp
+++ b/scribus/pageitem_pathtext.cpp
@@ -54,7 +54,11 @@ for which a new license (GPL+exception) is in place.
 using namespace std;
 
 PageItem_PathText::PageItem_PathText(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
-	: PageItem(pa, PageItem::PathText, x, y, w, h, w2, fill, outline)
+	: PageItem_PathText(pa, x, y, w, h, w2, fill, outline, NameTiming::Direct) {};
+
+
+PageItem_PathText::PageItem_PathText(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::PathText, x, y, w, h, w2, fill, outline, nameTiming)
 {
 	firstChar = 0;
 	m_maxChars = itemText.length();
diff --git a/scribus/pageitem_pathtext.h b/scribus/pageitem_pathtext.h
index 4d0d351..181e361 100644
--- a/scribus/pageitem_pathtext.h
+++ b/scribus/pageitem_pathtext.h
@@ -36,6 +36,7 @@ class SCRIBUS_API PageItem_PathText : public PageItem
 
 public:
 	PageItem_PathText(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_PathText(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_PathText(const PageItem & p) : PageItem(p) {}
 	~PageItem_PathText() {};
 	
diff --git a/scribus/pageitem_polygon.cpp b/scribus/pageitem_polygon.cpp
index 87c7023..aee8948 100644
--- a/scribus/pageitem_polygon.cpp
+++ b/scribus/pageitem_polygon.cpp
@@ -48,6 +48,11 @@ PageItem_Polygon::PageItem_Polygon(ScribusDoc *pa, double x, double y, double w,
 {
 }
 
+PageItem_Polygon::PageItem_Polygon(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::Polygon, x, y, w, h, w2, fill, outline, nameTiming)
+{
+}
+
 void PageItem_Polygon::DrawObj_Item(ScPainter *p, const QRectF& /*e*/)
 {
 	if (!m_Doc->RePos)
diff --git a/scribus/pageitem_polygon.h b/scribus/pageitem_polygon.h
index d501d92..d71ab7e 100644
--- a/scribus/pageitem_polygon.h
+++ b/scribus/pageitem_polygon.h
@@ -37,6 +37,7 @@ class SCRIBUS_API PageItem_Polygon : public PageItem
 
 public:
 	PageItem_Polygon(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_Polygon(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_Polygon(const PageItem & p) : PageItem(p) {}
 	~PageItem_Polygon() {};
 
diff --git a/scribus/pageitem_polyline.cpp b/scribus/pageitem_polyline.cpp
index 648c89d..67ffe43 100644
--- a/scribus/pageitem_polyline.cpp
+++ b/scribus/pageitem_polyline.cpp
@@ -51,6 +51,11 @@ PageItem_PolyLine::PageItem_PolyLine(ScribusDoc *pa, double x, double y, double
 {
 }
 
+PageItem_PolyLine::PageItem_PolyLine(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::PolyLine, x, y, w, h, w2, fill, outline, nameTiming)
+{
+}
+
 void PageItem_PolyLine::DrawObj_Item(ScPainter *p, const QRectF& /*e*/)
 {
 	if (m_Doc->RePos || PoLine.size() < 4)
diff --git a/scribus/pageitem_polyline.h b/scribus/pageitem_polyline.h
index 300f1fb..1213a28 100644
--- a/scribus/pageitem_polyline.h
+++ b/scribus/pageitem_polyline.h
@@ -36,6 +36,7 @@ class SCRIBUS_API PageItem_PolyLine : public PageItem
 
 public:
 	PageItem_PolyLine(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_PolyLine(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_PolyLine(const PageItem & p) : PageItem(p) {}
 	~PageItem_PolyLine() {};
 	
diff --git a/scribus/pageitem_regularpolygon.cpp b/scribus/pageitem_regularpolygon.cpp
index e66e26f..229d76b 100644
--- a/scribus/pageitem_regularpolygon.cpp
+++ b/scribus/pageitem_regularpolygon.cpp
@@ -48,7 +48,10 @@ for which a new license (GPL+exception) is in place.
 using namespace std;
 
 PageItem_RegularPolygon::PageItem_RegularPolygon(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
-	: PageItem(pa, PageItem::RegularPolygon, x, y, w, h, w2, fill, outline)
+	: PageItem_RegularPolygon(pa, x, y, w, h, w2, fill, outline, NameTiming::Direct) {}
+
+PageItem_RegularPolygon::PageItem_RegularPolygon(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::RegularPolygon, x, y, w, h, w2, fill, outline, nameTiming)
 {
 	polyCorners = m_Doc->itemToolPrefs().polyCorners;
 	polyFactor = m_Doc->itemToolPrefs().polyFactor;
diff --git a/scribus/pageitem_regularpolygon.h b/scribus/pageitem_regularpolygon.h
index 5f2a4a2..72f8b81 100644
--- a/scribus/pageitem_regularpolygon.h
+++ b/scribus/pageitem_regularpolygon.h
@@ -37,6 +37,7 @@ class SCRIBUS_API PageItem_RegularPolygon : public PageItem
 
 public:
 	PageItem_RegularPolygon(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_RegularPolygon(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_RegularPolygon(const PageItem & p) : PageItem(p) {}
 	~PageItem_RegularPolygon() {};
 
diff --git a/scribus/pageitem_spiral.cpp b/scribus/pageitem_spiral.cpp
index af13a41..2c4cd24 100644
--- a/scribus/pageitem_spiral.cpp
+++ b/scribus/pageitem_spiral.cpp
@@ -48,7 +48,10 @@ for which a new license (GPL+exception) is in place.
 using namespace std;
 
 PageItem_Spiral::PageItem_Spiral(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
-	: PageItem(pa, PageItem::Spiral, x, y, w, h, w2, fill, outline)
+	: PageItem_Spiral(pa, x, y, w, h, w2, fill, outline, NameTiming::Direct) {}
+
+PageItem_Spiral::PageItem_Spiral(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::Spiral, x, y, w, h, w2, fill, outline, nameTiming)
 {
 	spiralStartAngle = m_Doc->itemToolPrefs().spiralStartAngle;
 	spiralEndAngle = m_Doc->itemToolPrefs().spiralEndAngle;
diff --git a/scribus/pageitem_spiral.h b/scribus/pageitem_spiral.h
index da3b190..b3be70f 100644
--- a/scribus/pageitem_spiral.h
+++ b/scribus/pageitem_spiral.h
@@ -37,6 +37,7 @@ class SCRIBUS_API PageItem_Spiral : public PageItem
 
 public:
 	PageItem_Spiral(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_Spiral(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_Spiral(const PageItem & p) : PageItem(p) {}
 	~PageItem_Spiral() {};
 
diff --git a/scribus/pageitem_symbol.cpp b/scribus/pageitem_symbol.cpp
index ec51ed3..c80d223 100644
--- a/scribus/pageitem_symbol.cpp
+++ b/scribus/pageitem_symbol.cpp
@@ -52,6 +52,11 @@ PageItem_Symbol::PageItem_Symbol(ScribusDoc *pa, double x, double y, double w, d
 {
 }
 
+PageItem_Symbol::PageItem_Symbol(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::Symbol, x, y, w, h, 0, CommonStrings::None, CommonStrings::None, nameTiming)
+{
+}
+
 void PageItem_Symbol::DrawObj_Item(ScPainter *p, const QRectF& /*e*/)
 {
 	if (m_Doc->RePos)
diff --git a/scribus/pageitem_symbol.h b/scribus/pageitem_symbol.h
index a18042b..b783472 100644
--- a/scribus/pageitem_symbol.h
+++ b/scribus/pageitem_symbol.h
@@ -37,6 +37,7 @@ class SCRIBUS_API PageItem_Symbol : public PageItem
 
 public:
 	PageItem_Symbol(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+  PageItem_Symbol(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_Symbol(const PageItem & p) : PageItem(p) {}
 	~PageItem_Symbol() {};
 
diff --git a/scribus/pageitem_table.cpp b/scribus/pageitem_table.cpp
index 96dfd73..0957360 100644
--- a/scribus/pageitem_table.cpp
+++ b/scribus/pageitem_table.cpp
@@ -46,8 +46,11 @@ const double PageItem_Table::MinimumRowHeight = 3.0;
 // The minimum column width.
 const double PageItem_Table::MinimumColumnWidth = 3.0;
 
-PageItem_Table::PageItem_Table(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, int numRows, int numColumns) :
-	PageItem(pa, PageItem::Table, x, y, w, h, w2, fill, outline),
+PageItem_Table::PageItem_Table(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, int numRows, int numColumns)
+  : PageItem_Table(pa, x, y, w, h, w2, fill, outline, NameTiming::Direct, numRows, numColumns) {}
+
+PageItem_Table::PageItem_Table(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline,NameTiming nameTiming, int numRows, int numColumns ) :
+	PageItem(pa, PageItem::Table, x, y, w, h, w2, fill, outline, nameTiming),
 	m_rows(0), m_columns(0), m_tablePainter(new CollapsedTablePainter(this))
 {
 	initialize(numRows, numColumns);
diff --git a/scribus/pageitem_table.h b/scribus/pageitem_table.h
index f810247..d0d45fc 100644
--- a/scribus/pageitem_table.h
+++ b/scribus/pageitem_table.h
@@ -88,6 +88,7 @@ public:
 public:
 	/// Construct a new table item with @a numRows rows and @a numColumns columns.
 	PageItem_Table(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, int numRows = 1, int numColumns = 1);
+	PageItem_Table(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming,  int numRows = 1, int numColumns = 1 );
 
 	/// Destructor.
 	~PageItem_Table();
diff --git a/scribus/pageitem_textframe.cpp b/scribus/pageitem_textframe.cpp
index d0fb1c1..a7bd093 100644
--- a/scribus/pageitem_textframe.cpp
+++ b/scribus/pageitem_textframe.cpp
@@ -74,11 +74,17 @@ for which a new license (GPL+exception) is in place.
 using namespace std;
 
 PageItem_TextFrame::PageItem_TextFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline)
-	: PageItem(pa, PageItem::TextFrame, x, y, w, h, w2, fill, outline)
+	: PageItem(pa, PageItem::TextFrame, x, y, w, h, w2, fill, outline, NameTiming::Direct)
+{
+}
+
+PageItem_TextFrame::PageItem_TextFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming)
+	: PageItem(pa, PageItem::TextFrame, x, y, w, h, w2, fill, outline, NameTiming::Direct)
 {
 	init();
 }
 
+
 PageItem_TextFrame::PageItem_TextFrame(const PageItem & p) : PageItem(p)
 {
 	init();
diff --git a/scribus/pageitem_textframe.h b/scribus/pageitem_textframe.h
index 5c50745..8674b34 100644
--- a/scribus/pageitem_textframe.h
+++ b/scribus/pageitem_textframe.h
@@ -48,6 +48,7 @@ class SCRIBUS_API PageItem_TextFrame : public PageItem
 
 public:
 	PageItem_TextFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline);
+	PageItem_TextFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, const QString& fill, const QString& outline, NameTiming nameTiming);
 	PageItem_TextFrame(const PageItem & p);
 	~PageItem_TextFrame() {}
 
diff --git a/scribus/plugins/import/pdf/slaoutput.cpp b/scribus/plugins/import/pdf/slaoutput.cpp
index 960388b..633a5da 100644
--- a/scribus/plugins/import/pdf/slaoutput.cpp
+++ b/scribus/plugins/import/pdf/slaoutput.cpp
@@ -288,8 +288,8 @@ QString AnoOutputDev::getColor(GfxColorSpace *color_space, const GfxColor *color
 }
 
 SlaOutputDev::SlaOutputDev(ScribusDoc* doc, QList<PageItem*> *Elements, QStringList *importedColors, int flags)
+  : m_doc(doc), m_bulkadder(doc)
 {
-	m_doc = doc;
 	m_Elements = Elements;
 	pushGroup();
 	m_importedColors = importedColors;
@@ -400,7 +400,7 @@ bool SlaOutputDev::annotations_callback(Annot *annota, void *user_data)
 bool SlaOutputDev::handleTextAnnot(Annot* annota, double xCoor, double yCoor, double width, double height)
 {
 	AnnotText *anl = (AnnotText*)annota;
-	int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, CommonStrings::None, CommonStrings::None);
+	int z = m_bulkadder.itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, CommonStrings::None, CommonStrings::None);
 	PageItem *ite = m_doc->Items->at(z);
 	int flg = annota->getFlags();
 	if (!(flg & 16))
@@ -547,7 +547,7 @@ bool SlaOutputDev::handleLinkAnnot(Annot* annota, double xCoor, double yCoor, do
 	}
 	if (validLink)
 	{
-		int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, CommonStrings::None, CommonStrings::None);
+		int z = m_bulkadder.itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, CommonStrings::None, CommonStrings::None);
 		PageItem *ite = m_doc->Items->at(z);
 		int flg = annota->getFlags();
 		if (!(flg & 16))
@@ -713,7 +713,7 @@ bool SlaOutputDev::handleWidgetAnnot(Annot* annota, double xCoor, double yCoor,
 				delete annotOutDev;
 			}
 			const auto& graphicState = m_graphicStack.top();
-			int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, graphicState.fillColor, CommonStrings::None);
+			int z = m_bulkadder.itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, graphicState.fillColor, CommonStrings::None);
 			PageItem *ite = m_doc->Items->at(z);
 			int flg = annota->getFlags();
 			if (!(flg & 16))
@@ -1279,7 +1279,7 @@ void SlaOutputDev::endPage()
 			}
 			if (!m_tmpSel->isEmpty())
 			{
-				PageItem *ite = m_doc->groupObjectsSelection(m_tmpSel);
+				PageItem *ite = m_bulkadder.groupObjectsSelection(m_tmpSel);
 				ite->setItemName(it.key());
 				m_Elements->append(ite);
 				if (m_groupStack.count() != 0)
@@ -1313,7 +1313,7 @@ void SlaOutputDev::restoreState(GfxState *state)
 					m_tmpSel->addItem(gElements.Items.at(dre), true);
 					m_Elements->removeAll(gElements.Items.at(dre));
 				}
-				PageItem *ite = m_doc->groupObjectsSelection(m_tmpSel);
+				PageItem *ite = m_bulkadder.groupObjectsSelection(m_tmpSel);
 				if (ite)
 				{
 					QPainterPath clippath = m_graphicStack.top().clipPath;
@@ -1408,7 +1408,7 @@ void SlaOutputDev::endTransparencyGroup(GfxState *state)
 			m_tmpSel->addItem(gElements.Items.at(dre), true);
 			m_Elements->removeAll(gElements.Items.at(dre));
 		}
-		PageItem *ite = m_doc->groupObjectsSelection(m_tmpSel);
+		PageItem *ite = m_bulkadder.groupObjectsSelection(m_tmpSel);
 		ite->setFillTransparency(1.0 - state->getFillOpacity());
 		ite->setFillBlendmode(getBlendMode(state));
 		ScPattern pat(m_doc);
@@ -1438,7 +1438,7 @@ void SlaOutputDev::endTransparencyGroup(GfxState *state)
 		m_Elements->removeAll(gElements.Items.at(dre));
 	}
 	if ((gElements.Items.count() != 1) || (gElements.isolated))
-		ite = m_doc->groupObjectsSelection(m_tmpSel);
+		ite = m_bulkadder.groupObjectsSelection(m_tmpSel);
 	else
 		ite = gElements.Items.first();
 	if (ite->isGroup())
@@ -1588,9 +1588,9 @@ void SlaOutputDev::stroke(GfxState *state)
 
 	int z;
 	if (m_pathIsClosed)
-		z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, graphicState.strokeColor);
+		z = m_bulkadder.itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, graphicState.strokeColor);
 	else
-		z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, graphicState.strokeColor);
+		z = m_bulkadder.itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, graphicState.strokeColor);
 	PageItem* ite = m_doc->Items->at(z);
 	ite->PoLine = out.copy();
 	ite->ClipEdited = true;
@@ -1689,9 +1689,9 @@ void SlaOutputDev::createFillItem(GfxState *state, Qt::FillRule fillRule)
 		graphicState.fillColor = getColor(state->getFillColorSpace(), state->getFillColor(), &graphicState.fillShade);
 		int z;
 		if (m_pathIsClosed)
-			z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, graphicState.fillColor, CommonStrings::None);
+			z = m_bulkadder.itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, graphicState.fillColor, CommonStrings::None);
 		else
-			z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, graphicState.fillColor, CommonStrings::None);
+			z = m_bulkadder.itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, graphicState.fillColor, CommonStrings::None);
 		PageItem* ite = m_doc->Items->at(z);
 		ite->PoLine.fromQPainterPath(clippedPath, true);
 		ite->ClipEdited = true;
@@ -1813,7 +1813,7 @@ bool SlaOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, do
 	m_coords = output;
 
 	const auto& graphicState = m_graphicStack.top();
-	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), bb.width(), bb.height(), 0, graphicState.fillColor, CommonStrings::None);
+	int z = m_bulkadder.itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), bb.width(), bb.height(), 0, graphicState.fillColor, CommonStrings::None);
 	PageItem* ite = m_doc->Items->at(z);
 	if (checkClip())
 	{
@@ -1935,7 +1935,7 @@ bool SlaOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading,
 	m_coords = output;
 
 	const auto& graphicState = m_graphicStack.top();
-	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, graphicState.fillColor, CommonStrings::None);
+	int z = m_bulkadder.itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, graphicState.fillColor, CommonStrings::None);
 	PageItem* ite = m_doc->Items->at(z);
 	if (checkClip())
 	{
@@ -1998,7 +1998,7 @@ bool SlaOutputDev::gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangle
 	const double *ctm = state->getCTM();
 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
 	const auto& graphicState = m_graphicStack.top();
-	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, graphicState.fillColor, CommonStrings::None);
+	int z = m_bulkadder.itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, graphicState.fillColor, CommonStrings::None);
 	PageItem* ite = m_doc->Items->at(z);
 	ite->ClipEdited = true;
 	ite->FrameType = 3;
@@ -2079,7 +2079,7 @@ bool SlaOutputDev::patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *sha
 	const double *ctm = state->getCTM();
 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
 	const auto& graphicState = m_graphicStack.top();
-	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, graphicState.fillColor, CommonStrings::None);
+	int z = m_bulkadder.itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, graphicState.fillColor, CommonStrings::None);
 	PageItem* ite = m_doc->Items->at(z);
 	ite->ClipEdited = true;
 	ite->FrameType = 3;
@@ -2257,7 +2257,7 @@ bool SlaOutputDev::tilingPatternFill(GfxState *state, Gfx * /*gfx*/, Catalog *ca
 		m_doc->itemSelection_FlipV();
 		PageItem *ite;
 		if (m_doc->m_Selection->count() > 1)
-			ite = m_doc->groupObjectsSelection();
+			ite = m_bulkadder.groupObjectsSelection();
 		else
 			ite = m_doc->m_Selection->itemAt(0);
 		ite->setFillTransparency(1.0 - state->getFillOpacity());
@@ -2296,7 +2296,7 @@ bool SlaOutputDev::tilingPatternFill(GfxState *state, Gfx * /*gfx*/, Catalog *ca
 	m_coords = output;
 
 	const auto& graphicState = m_graphicStack.top();
-	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, graphicState.fillColor, CommonStrings::None);
+	int z = m_bulkadder.itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, graphicState.fillColor, CommonStrings::None);
 	ite = m_doc->Items->at(z);
 
 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
@@ -2683,7 +2683,7 @@ void SlaOutputDev::createImageFrame(QImage& image, GfxState *state, int numColor
 	without_rotation = m_ctm * without_rotation.rotate(angle);
 	QRectF trect_wr = without_rotation.mapRect(QRectF(0, 0, 1, 1));
 
-	int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Rectangle, xCoor + torigin.x(), yCoor + torigin.y(), trect_wr.width(), trect_wr.height(), 0, CommonStrings::None, CommonStrings::None);
+	int z = m_bulkadder.itemAdd(PageItem::ImageFrame, PageItem::Rectangle, xCoor + torigin.x(), yCoor + torigin.y(), trect_wr.width(), trect_wr.height(), 0, CommonStrings::None, CommonStrings::None);
 	PageItem* ite = m_doc->Items->at(z);
 	ite->ClipEdited = true;
 	ite->FrameType = 3;
@@ -3268,7 +3268,7 @@ void SlaOutputDev::drawChar(GfxState* state, double x, double y, double dx, doub
 			}
 			if ((textPath.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0)) && (textRenderingMode != 7))
 			{
-				int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CommonStrings::None, CommonStrings::None);
+				int z = m_bulkadder.itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CommonStrings::None, CommonStrings::None);
 				PageItem* ite = m_doc->Items->at(z);
 
 				// todo: merge this between vector and text implementations.
@@ -3332,7 +3332,7 @@ void SlaOutputDev::endType3Char(GfxState *state)
 		}
 		PageItem *ite;
 		if (m_doc->m_Selection->count() > 1)
-			ite = m_doc->groupObjectsSelection();
+			ite = m_bulkadder.groupObjectsSelection();
 		else
 			ite = m_doc->m_Selection->itemAt(0);
 		if (!f3e.colored)
@@ -3389,7 +3389,7 @@ void SlaOutputDev::endTextObject(GfxState *state)
 			}
 			PageItem *ite;
 			if (gElements.Items.count() != 1)
-				ite = m_doc->groupObjectsSelection(m_tmpSel);
+				ite = m_bulkadder.groupObjectsSelection(m_tmpSel);
 			else
 				ite = gElements.Items.first();
 			ite->setGroupClipping(false);
diff --git a/scribus/plugins/import/pdf/slaoutput.h b/scribus/plugins/import/pdf/slaoutput.h
index 4a64da8..b4d7010 100644
--- a/scribus/plugins/import/pdf/slaoutput.h
+++ b/scribus/plugins/import/pdf/slaoutput.h
@@ -29,6 +29,7 @@ for which a new license (GPL+exception) is in place.
 #include "scribusview.h"
 #include "selection.h"
 #include "vgradient.h"
+#include "bulkadder.h"
 
 #include <poppler/Object.h>
 #include <poppler/OutputDev.h>
@@ -285,6 +286,7 @@ protected:
 	void pushGroup(const QString& maskName = "", bool forSoftMask = false, bool alpha = false, bool inverted = false);
 
 	ScribusDoc* m_doc;
+  BulkAdder m_bulkadder;
 	Qt::PenCapStyle m_lineEnd { Qt::FlatCap };
 	Qt::PenJoinStyle m_lineJoin { Qt::MiterJoin };
 	QList<PageItem*>* m_Elements;
diff --git a/scribus/scribusdoc.cpp b/scribus/scribusdoc.cpp
index c182667..e9812ad 100644
--- a/scribus/scribusdoc.cpp
+++ b/scribus/scribusdoc.cpp
@@ -5156,6 +5156,16 @@ bool ScribusDoc::copyPageToMasterPage(int pageNumber, int leftPage, int maxLeftP
 }
 
 PageItem* ScribusDoc::createPageItem(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline)
+{
+  return implCreatePageItem(itemType, frameType, x, y, b, h, w, fill, outline, PageItem::NameTiming::Direct);
+}
+
+PageItem* ScribusDoc::createPageItemDeferred(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline)
+{
+  return implCreatePageItem(itemType, frameType, x, y, b, h, w, fill, outline, PageItem::NameTiming::Deferred);
+}
+
+PageItem* ScribusDoc::implCreatePageItem(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline, PageItem::NameTiming nameTiming)
 {
 	PageItem* newItem=nullptr;
 	switch (itemType)
@@ -5163,66 +5173,66 @@ PageItem* ScribusDoc::createPageItem(const PageItem::ItemType itemType, const Pa
 		//Q_ASSERTs here will warn on creation issues when a coder specifies the frameType incorrectly
 		//for items that do not have/need a frameType for creation.
 		case PageItem::ImageFrame:
-			newItem = new PageItem_ImageFrame(this, x, y, b, h, w, m_docPrefsData.itemToolPrefs.imageFillColor, m_docPrefsData.itemToolPrefs.imageStrokeColor);
+			newItem = new PageItem_ImageFrame(this, x, y, b, h, w, m_docPrefsData.itemToolPrefs.imageFillColor, m_docPrefsData.itemToolPrefs.imageStrokeColor, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Unspecified);
 			break;
 		case PageItem::TextFrame:
-			newItem = new PageItem_TextFrame(this, x, y, b, h, w, CommonStrings::None, outline);
+			newItem = new PageItem_TextFrame(this, x, y, b, h, w, CommonStrings::None, outline, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Unspecified);
 			break;
 		case PageItem::Line:
 			{
 				//CB 5521 Remove false minimum line width
 				double lineWidth = w; // == 0.0 ? 1.0 : w;
-				newItem = new PageItem_Line(this, x, y, b, h, lineWidth, CommonStrings::None, outline);
+				newItem = new PageItem_Line(this, x, y, b, h, lineWidth, CommonStrings::None, outline, nameTiming);
 //				Q_ASSERT(frameType==PageItem::Unspecified);
 			}
 			break;
 		case PageItem::Table:
-			newItem = new PageItem_Table(this, x, y, b, h, w, fill, outline);
+			newItem = new PageItem_Table(this, x, y, b, h, w, fill, outline, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Unspecified);
 			break;
 		case PageItem::Polygon:
-			newItem = new PageItem_Polygon(this, x, y, b, h, w, fill, outline);
+			newItem = new PageItem_Polygon(this, x, y, b, h, w, fill, outline, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Ellipse || frameType==PageItem::Unspecified);
 			break;
 		case PageItem::PolyLine:
-			newItem = new PageItem_PolyLine(this, x, y, b, h, w, fill, outline);
+			newItem = new PageItem_PolyLine(this, x, y, b, h, w, fill, outline, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Unspecified);
 			break;
 		case PageItem::PathText:
 			//Currently used only in fileloader
-			newItem = new PageItem_PathText(this, x, y, b, h, w, fill, outline);
+			newItem = new PageItem_PathText(this, x, y, b, h, w, fill, outline, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Unspecified);
 			break;
 		case PageItem::LatexFrame:
-			newItem = new PageItem_LatexFrame(this, x, y, b, h, w, m_docPrefsData.itemToolPrefs.imageFillColor, m_docPrefsData.itemToolPrefs.imageStrokeColor);
+			newItem = new PageItem_LatexFrame(this, x, y, b, h, w, m_docPrefsData.itemToolPrefs.imageFillColor, m_docPrefsData.itemToolPrefs.imageStrokeColor, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Unspecified);
 			break;
 #ifdef HAVE_OSG
 		case PageItem::OSGFrame:
-			newItem = new PageItem_OSGFrame(this, x, y, b, h, w, m_docPrefsData.itemToolPrefs.imageFillColor, m_docPrefsData.itemToolPrefs.imageStrokeColor);
+			newItem = new PageItem_OSGFrame(this, x, y, b, h, w, m_docPrefsData.itemToolPrefs.imageFillColor, m_docPrefsData.itemToolPrefs.imageStrokeColor, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Unspecified);
 			break;
 #endif
 		case PageItem::Symbol:
-			newItem = new PageItem_Symbol(this, x, y, b, h, w, CommonStrings::None, CommonStrings::None);
+			newItem = new PageItem_Symbol(this, x, y, b, h, w, CommonStrings::None, CommonStrings::None, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Unspecified);
 			break;
 		case PageItem::Group:
-			newItem = new PageItem_Group(this, x, y, b, h, w, CommonStrings::None, CommonStrings::None);
+			newItem = new PageItem_Group(this, x, y, b, h, w, CommonStrings::None, CommonStrings::None, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Unspecified);
 			break;
 		case PageItem::RegularPolygon:
-			newItem = new PageItem_RegularPolygon(this, x, y, b, h, w, fill, outline);
+			newItem = new PageItem_RegularPolygon(this, x, y, b, h, w, fill, outline, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Ellipse || frameType==PageItem::Unspecified);
 			break;
 		case PageItem::Arc:
-			newItem = new PageItem_Arc(this, x, y, b, h, w, fill, outline);
+			newItem = new PageItem_Arc(this, x, y, b, h, w, fill, outline, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Ellipse || frameType==PageItem::Unspecified);
 			break;
 		case PageItem::Spiral:
-			newItem = new PageItem_Spiral(this, x, y, b, h, w, fill, outline);
+			newItem = new PageItem_Spiral(this, x, y, b, h, w, fill, outline, nameTiming);
 //			Q_ASSERT(frameType==PageItem::Unspecified);
 			break;
 		default:
@@ -5238,6 +5248,16 @@ PageItem* ScribusDoc::createPageItem(const PageItem::ItemType itemType, const Pa
 }
 
 int ScribusDoc::itemAdd(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline, PageItem::ItemKind itemKind)
+{
+  return implItemAdd(itemType,frameType, x, y, b, h, w, fill, outline, itemKind, PageItem::NameTiming::Direct);
+}
+
+int ScribusDoc::itemAddDeferred(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline, PageItem::ItemKind itemKind)
+{
+  return implItemAdd(itemType,frameType, x, y, b, h, w, fill, outline, itemKind, PageItem::NameTiming::Deferred);
+}
+
+int ScribusDoc::implItemAdd(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline, PageItem::ItemKind itemKind, PageItem::NameTiming nameTiming)
 {
 	UndoTransaction activeTransaction;
 	if (UndoManager::undoEnabled()) // && !m_itemCreationTransaction)
@@ -5252,7 +5272,7 @@ int ScribusDoc::itemAdd(const PageItem::ItemType itemType, const PageItem::ItemF
 		itemAddDetails(PageItem::TextFrame, frameType, newItem);
 	}
 	else
-		newItem = createPageItem(itemType, frameType, x, y, b, h, w, fill, outline); 
+		newItem = implCreatePageItem(itemType, frameType, x, y, b, h, w, fill, outline, nameTiming); 
 	
 	Q_CHECK_PTR(newItem);
 	if (newItem == nullptr)
@@ -14797,6 +14817,16 @@ void ScribusDoc::scaleGroup(double scx, double scy, bool scaleText, Selection* c
 }
 
 PageItem* ScribusDoc::groupObjectsSelection(Selection* customSelection)
+{
+  return implGroupObjectsSelection(customSelection, PageItem::NameTiming::Direct);
+}
+
+PageItem* ScribusDoc::groupObjectsSelectionDeferred(Selection* customSelection)
+{
+  return implGroupObjectsSelection(customSelection, PageItem::NameTiming::Deferred);
+}
+
+PageItem* ScribusDoc::implGroupObjectsSelection(Selection* customSelection, PageItem::NameTiming nameTiming)
 {
 	Selection* itemSelection = (customSelection != nullptr) ? customSelection : m_Selection;
 	if (itemSelection->count() < 1)
@@ -14836,10 +14866,12 @@ PageItem* ScribusDoc::groupObjectsSelection(Selection* customSelection)
 	double gy = miny;
 	double gw = maxx - minx;
 	double gh = maxy - miny;
-	int z = itemAdd(PageItem::Group, PageItem::Rectangle, gx, gy, gw, gh, 0, CommonStrings::None, CommonStrings::None);
+	int z = implItemAdd(PageItem::Group, PageItem::Rectangle, gx, gy, gw, gh, 0, CommonStrings::None, CommonStrings::None, PageItem::StandardItem, nameTiming);
 	PageItem *groupItem = Items->takeAt(z);
 	Items->insert(lowestItem, groupItem);
-	groupItem->setItemName( tr("Group%1").arg(GroupCounter));
+  if (nameTiming == PageItem::NameTiming::Direct) {
+    groupItem->setItemName( tr("Group%1").arg(GroupCounter));
+  }
 	groupItem->AutoName = false;
 	groupItem->groupWidth = gw;
 	groupItem->groupHeight = gh;
diff --git a/scribus/scribusdoc.h b/scribus/scribusdoc.h
index 7300113..9894bb8 100644
--- a/scribus/scribusdoc.h
+++ b/scribus/scribusdoc.h
@@ -821,6 +821,9 @@ public:
 	 * @brief Just create but don't add to items list and don't create undo record
 	 */
 	PageItem* createPageItem(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline);
+
+	PageItem* createPageItemDeferred(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline);
+
 	
 	/**
 	 * @brief Add an Item to the document.
@@ -842,6 +845,8 @@ public:
 	*/
 	int itemAdd(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline, PageItem::ItemKind itemKind = PageItem::StandardItem);
 
+	int itemAddDeferred(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline, PageItem::ItemKind itemKind = PageItem::StandardItem);
+
 	/** Add an item to the page based on the x/y position. Item will be fitted to the closest guides/margins */
 	int itemAddArea(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double w, const QString& fill, const QString& outline, PageItem::ItemKind itemKind = PageItem::StandardItem);
 	
@@ -1094,6 +1099,7 @@ public:
 
 	QList<PageItem*>* groupOfItem(QList<PageItem*>* itemList, PageItem* item);
 	PageItem* groupObjectsSelection(Selection* customSelection = nullptr);
+	PageItem* groupObjectsSelectionDeferred(Selection* customSelection = nullptr);
 	PageItem* groupObjectsList(QList<PageItem*> &itemList);
 	void groupObjectsToItem(PageItem* groupItem, QList<PageItem*> &itemList);
 	PageItem * itemSelection_GroupObjects  (bool changeLock, bool lock, Selection* customSelection = nullptr, PageItem_Group* groupItem = nullptr);
@@ -1763,6 +1769,10 @@ private:
 
 	void multipleDuplicateByPage(const ItemMultipleDuplicateData& mdData, Selection& selection, QString& tooltip);
 
+	int implItemAdd(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline, PageItem::ItemKind itemKind, PageItem::NameTiming nameTiming);
+	PageItem* implCreatePageItem(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& outline, PageItem::NameTiming nameTiming);
+	PageItem* implGroupObjectsSelection(Selection* customSelection, PageItem::NameTiming nameTiming);
+
 public:
 	const QList<Mark*>& marksList() { return m_docMarksList; }
 	const QList<TextNote*>& notesList() { return m_docNotesList; }
-- 
2.38.1

