From eb1e069442d1a48b16976a9eb42093a50e8dbb35 Mon Sep 17 00:00:00 2001
From: ale rimoldi <ale@graphicslab.org>
Date: Sun, 6 Apr 2025 00:14:57 +0200
Subject: getPageItemByName should also look inside of groups


diff --git a/scribus/plugins/scriptplugin/cmdobj.cpp b/scribus/plugins/scriptplugin/cmdobj.cpp
index 296b0dbd2..5693c2faa 100644
--- a/scribus/plugins/scriptplugin/cmdobj.cpp
+++ b/scribus/plugins/scriptplugin/cmdobj.cpp
@@ -470,9 +470,6 @@ PyObject *scribus_createbezierline(PyObject* /* self */, PyObject* args)
 	return PyUnicode_FromString(it->itemName().toUtf8());
 }
 
-
-/* 03/31/2004 - xception handling
- */
 PyObject *scribus_createpathtext(PyObject* /* self */, PyObject* args)
 {
 	double x, y;
@@ -481,20 +478,14 @@ PyObject *scribus_createpathtext(PyObject* /* self */, PyObject* args)
 	PyESString polyB;
 	if (!PyArg_ParseTuple(args, "ddeses|es", &x, &y, "utf-8", textB.ptr(), "utf-8", polyB.ptr(), "utf-8", name.ptr()))
 		return nullptr;
+
 	if (!checkHaveDocument())
 		return nullptr;
-//	if (ItemExists(QString::fromUtf8(name.c_str())))
-//	{
-//		PyErr_SetString(NameExistsError, QObject::tr("An object with the requested name already exists.","python error"));
-//		return nullptr;
-//	}
-	//FIXME: Why use GetItem not GetUniqueItem? Maybe use GetUniqueItem and use the exceptions
-	// its sets for us?
-	PageItem *i = GetItem(QString::fromUtf8(textB.c_str()));
-	PageItem *ii = GetItem(QString::fromUtf8(polyB.c_str()));
+
+	PageItem *i = getPageItemByName(QString::fromUtf8(textB.c_str()));
+	PageItem *ii = getPageItemByName(QString::fromUtf8(polyB.c_str()));
 	if ((i == nullptr) || (ii == nullptr))
 	{
-		PyErr_SetString(NotFoundError, QObject::tr("Object not found.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
 	ScCore->primaryMainWindow()->doc->m_Selection->clear();
@@ -502,6 +493,7 @@ PyObject *scribus_createpathtext(PyObject* /* self */, PyObject* args)
 	ScCore->primaryMainWindow()->doc->m_Selection->addItem(ii);
 	ScCore->primaryMainWindow()->view->ToPathText();
 	ScCore->primaryMainWindow()->doc->moveItem(pageUnitXToDocX(x) - i->xPos(), pageUnitYToDocY(y) - i->yPos(), i);
+
 	if (name.length() > 0)
 	{
 		QString objName = QString::fromUtf8(name.c_str());
diff --git a/scribus/plugins/scriptplugin/cmdutil.cpp b/scribus/plugins/scriptplugin/cmdutil.cpp
index d3bd6da8f..56f3d89e6 100644
--- a/scribus/plugins/scriptplugin/cmdutil.cpp
+++ b/scribus/plugins/scriptplugin/cmdutil.cpp
@@ -58,25 +58,6 @@ double docUnitYToPageY(double pageUnitY)
 	return PointToValue(pageUnitY - ScCore->primaryMainWindow()->doc->currentPage()->yOffset());
 }
 
-PageItem *GetItem(const QString& name)
-{
-	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
-	if (!name.isEmpty())
-	{
-		for (int i = 0; i < currentDoc->Items->count(); ++i)
-		{
-			if (currentDoc->Items->at(i)->itemName() == name)
-				return currentDoc->Items->at(i);
-		}
-	}
-	else
-	{
-		if (currentDoc->m_Selection->count() != 0)
-			return currentDoc->m_Selection->itemAt(0);
-	}
-	return nullptr;
-}
-
 void ReplaceColor(const QString& col, const QString& rep)
 {
 	QMap<QString, QString> colorMap;
@@ -110,52 +91,56 @@ PageItem* GetUniqueItem(const QString& name)
 	return getPageItemByName(name);
 }
 
-PageItem* getPageItemByName(const QString& name)
+PageItem* getPageItemOrNullByName(const QString& name)
 {
-	if (name.length() == 0)
+	if (name.isEmpty())
 	{
-		PyErr_SetString(PyExc_ValueError, QString("Cannot accept empty name for pageitem").toLocal8Bit().constData());
 		return nullptr;
 	}
 
 	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
 	for (int i = 0; i < currentDoc->Items->count(); ++i)
 	{
-		if (name == currentDoc->Items->at(i)->itemName())
-			return currentDoc->Items->at(i);
+		PageItem* pageItem = currentDoc->Items->at(i);
+		if (name == pageItem->itemName())
+			return pageItem;
+		if (pageItem->isGroup())
+		{
+			for (const auto& groupItem: pageItem->asGroupFrame()->getAllChildren())
+			{
+				if (name == groupItem->itemName())
+					return groupItem;
+			}
+		}
 	}
 
-	PyErr_SetString(NoValidObjectError, QString("Object not found").toLocal8Bit().constData());
 	return nullptr;
 }
 
-
-/*!
- * Checks to see if a pageItem named 'name' exists and return true
- * if it does exist. Returns false if there is no such object, or
- * if the empty string ("") is passed.
- */
-bool ItemExists(const QString& name)
+PageItem* getPageItemByName(const QString& name)
 {
 	if (name.length() == 0)
-		return false;
+	{
+		PyErr_SetString(PyExc_ValueError, QString("Cannot accept empty name for pageitem").toLocal8Bit().constData());
+		return nullptr;
+	}
 
-	ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
-	for (int i = 0; i < currentDoc->Items->count(); ++i)
+	PageItem* pageItem = getPageItemOrNullByName(name);
+
+	if (pageItem == nullptr)
 	{
-		if (name == currentDoc->Items->at(i)->itemName())
-			return true;
+		PyErr_SetString(NoValidObjectError, QString("Object not found").toLocal8Bit().constData());
+		return nullptr;
 	}
-	return false;
+
+	return pageItem;
+}
+
+bool ItemExists(const QString& name)
+{
+	return getPageItemOrNullByName(name) != nullptr;
 }
 
-/*!
- * Checks to see if there is a document open.
- * If there is an open document, returns true.
- * If there is no open document, sets a Python
- * exception and returns false.
- * 2004-10-27 Craig Ringer
- */
 bool checkHaveDocument()
 {
 	if (ScCore->primaryMainWindow()->HaveDoc)
@@ -189,31 +174,6 @@ QStringList getSelectedItemsByName()
 	return ScCore->primaryMainWindow()->doc->m_Selection->getSelectedItemsByName();
 }
 
-bool setSelectedItemsByName(const QStringList& itemNames)
-{
-	ScribusDoc* currentDoc =  ScCore->primaryMainWindow()->doc;
-	ScribusView* currentView = ScCore->primaryMainWindow()->view;
-
-	currentView->deselectItems();
-
-	// For each named item
-	for (auto it = itemNames.begin() ; it != itemNames.end() ; it++)
-	{
-		// Search for the named item
-		PageItem* item = nullptr;
-		for (int j = 0; j < currentDoc->Items->count(); j++)
-		{
-			if (*it == currentDoc->Items->at(j)->itemName())
-				item = currentDoc->Items->at(j);
-		}
-		if (!item)
-			return false;
-		// And select it
-		currentView->selectItem(item);
-	}
-	return true;
-}
-
 TableBorder parseBorder(PyObject* borderLines, bool* ok)
 {
 	TableBorder border;
diff --git a/scribus/plugins/scriptplugin/cmdutil.h b/scribus/plugins/scriptplugin/cmdutil.h
index fc2f3f2cd..320631817 100644
--- a/scribus/plugins/scriptplugin/cmdutil.h
+++ b/scribus/plugins/scriptplugin/cmdutil.h
@@ -27,7 +27,6 @@ double pageUnitYToDocY(double pageUnitY);
 /// \brief Doc units -> page-relative units
 double docUnitYToPageY(double pageUnitY);
 
-PageItem *GetItem(const QString& name);
 void ReplaceColor(const QString& col, const QString& rep);
 
 /*!
@@ -43,6 +42,11 @@ void ReplaceColor(const QString& col, const QString& rep);
  */
 PageItem* GetUniqueItem(const QString& name);
 
+/*!
+ * @brief Returns named PageItem, or NULL if not found (no exception).
+ */
+PageItem* getPageItemOrNullByName(const QString& name);
+
 /*!
  * @brief Returns named PageItem, or exception and NULL if not found.
  *
@@ -51,7 +55,13 @@ PageItem* GetUniqueItem(const QString& name);
  */
 PageItem* getPageItemByName(const QString& name);
 
-// 2004-10-27 Craig Ringer see cmdutil.cpp for description
+/*!
+ * Checks to see if there is a document open.
+ * If there is an open document, returns true.
+ * If there is no open document, sets a Python
+ * exception and returns false.
+ * 2004-10-27 Craig Ringer
+ */
 bool checkHaveDocument();
 
 /*!
@@ -66,7 +76,11 @@ bool checkHaveDocument();
  */
 bool checkValidPageNumber(int page);
 
-// 2004-11-12 Craig Ringer see cmdutil.cpp for description
+/*!
+ * Checks to see if a pageItem named 'name' exists and return true
+ * if it does exist. Returns false if there is no such object, or
+ * if the empty string ("") is passed.
+ */
 bool ItemExists(const QString& name);
 
 /*!
@@ -74,14 +88,6 @@ bool ItemExists(const QString& name);
  */
 QStringList getSelectedItemsByName();
 
-/*!
- * @brief Replaces the current selection by selecting all the items named in the passed QStringList
- *
- * Returns false if one or more items can't be selected, true if all were selected.
- * Selection state is undefined on failure.
- */
-bool setSelectedItemsByName(const QStringList& itemNames);
-
 /*!
  * @brief Helper method to parse a border from a list of tuples.
  */
