View Issue Details

IDProjectCategoryView StatusLast Update
0017417InfrastructureGeneralpublic2025-02-13 17:01
Reportertropion Assigned To 
PrioritynormalSeveritytweakReproducibilityalways
Status newResolutionopen 
Summary0017417: ItemIDs in .sla files change every time a document is loaded and saved again
DescriptionThe ItemIDs in .sla files change every time a document is loaded and saved again.
This makes any kind of versioning system for .sla files pointless, because the actual changes are hidden by the huge number of changed ItemIDs.

Currently the ItemIDs in the .sla files are a hash of the pointer to the PageItem.
I suggest changing that to a hash of the PageItems name.

Why are the ItemIDs restricted to 31bit (& 7FFFFFFF)?
TagsNo tags attached.

Activities

tropion

2025-02-13 17:01

reporter  

stable_ItemIDs.diff (9,388 bytes)   
diff --git a/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp b/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
index 9a029ec25..bbb1cbbc5 100644
--- a/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
+++ b/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
@@ -687,7 +687,7 @@ void Scribus150Format::writeBookmarks(ScXmlStreamWriter & docu)
 		docu.writeAttribute("Text", itbm->Text);
 		docu.writeAttribute("Aktion", itbm->Aktion);
 		docu.writeAttribute("ItemNr", itbm->ItemNr);
-		docu.writeAttribute("Element", qHash(itbm->PageObject) & 0x7FFFFFFF);
+		docu.writeAttribute("Element", qHash(itbm->PageObject->itemName()) & 0x7FFFFFFF);
 		docu.writeAttribute("First", itbm->First);
 		docu.writeAttribute("Last", itbm->Last);
 		docu.writeAttribute("Prev", itbm->Prev);
@@ -1466,7 +1466,7 @@ void Scribus150Format::writeMarks(ScXmlStreamWriter & docu)
 		{
 			const PageItem* item = mrk->getItemPtr();
 			assert(item != nullptr);
-			docu.writeAttribute("ItemID", qHash(item) & 0x7FFFFFFF);
+			docu.writeAttribute("ItemID", qHash(item->itemName()) & 0x7FFFFFFF);
 			//docu.writeAttribute("itemName", item->itemName());
 		}
 		else if (mrk->isType(MARKVariableTextType) && mrk->hasString())
@@ -1595,18 +1595,18 @@ void Scribus150Format::writeNotesFrames(ScXmlStreamWriter & docu, const QList<Pa
 			docu.writeEmptyElement("ENDNOTEFRAME");
 			docu.writeAttribute("NSname", noteStyle->name());
 			docu.writeAttribute("range", (int) noteStyle->range());
-			docu.writeAttribute("myID", qHash(noteFrame) & 0x7FFFFFFF);
+			docu.writeAttribute("myID", qHash(noteFrame->itemName()) & 0x7FFFFFFF);
 			
 			rangeItem rI = m_Doc->m_docEndNotesFramesMap.value(noteFrame);
 			if (noteStyle->range() == NSRstory)
-				docu.writeAttribute("ItemID", qHash(rI.firstStoryFrame) & 0x7FFFFFFF);
+				docu.writeAttribute("ItemID", qHash(rI.firstStoryFrame->itemName()) & 0x7FFFFFFF);
 		}
 		else //footnotes frame
 		{
 			docu.writeEmptyElement("FOOTNOTEFRAME");
 			docu.writeAttribute("NSname", noteStyle->name());
-			docu.writeAttribute("myID", qHash(noteFrame) & 0x7FFFFFFF);
-			docu.writeAttribute("MasterID", qHash(noteFrame->masterFrame()) & 0x7FFFFFFF);
+			docu.writeAttribute("myID", qHash(noteFrame->itemName()) & 0x7FFFFFFF);
+			docu.writeAttribute("MasterID", qHash(noteFrame->masterFrame()->itemName()) & 0x7FFFFFFF);
 		}
 	}
 	docu.writeEndElement();
@@ -2180,7 +2180,7 @@ void Scribus150Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, co
 		if (item->isTextFrame() || item->isPathText() || item->isImageFrame())
 		{
 			if (item->nextInChain() != nullptr)
-				docu.writeAttribute("NEXTITEM", qHash(item->nextInChain()) & 0x7FFFFFFF);
+				docu.writeAttribute("NEXTITEM", qHash(item->nextInChain()->itemName()) & 0x7FFFFFFF);
 			else
 				docu.writeAttribute("NEXTITEM", -1);
 
@@ -2194,7 +2194,7 @@ void Scribus150Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, co
 			}
 
 			if (item->prevInChain() != nullptr && prevTopParentCheck)
-				docu.writeAttribute("BACKITEM", qHash(item->prevInChain()) & 0x7FFFFFFF);
+				docu.writeAttribute("BACKITEM", qHash(item->prevInChain()->itemName()) & 0x7FFFFFFF);
 			else
 			{
 				docu.writeAttribute("BACKITEM", -1);
@@ -2220,7 +2220,7 @@ void Scribus150Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, co
 				if (pIt->isAutoNoteFrame())
 					continue;
 				docu.writeEmptyElement("WeldEntry");
-				docu.writeAttribute("Target", qHash(wInf.weldItem) & 0x7FFFFFFF);
+				docu.writeAttribute("Target", qHash(wInf.weldItem->itemName()) & 0x7FFFFFFF);
 				docu.writeAttribute("WX", wInf.weldPoint.x());
 				docu.writeAttribute("WY", wInf.weldPoint.y());
 			}
@@ -2649,7 +2649,7 @@ void Scribus150Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, co
 void Scribus150Format::SetItemProps(ScXmlStreamWriter& docu, PageItem* item, const QString& baseDir)
 {
 	docu.writeAttribute("OwnPage", item->OwnPage);
-	docu.writeAttribute("ItemID", qHash(item) & 0x7FFFFFFF);
+	docu.writeAttribute("ItemID", qHash(item->itemName()) & 0x7FFFFFFF);
 	docu.writeAttribute("PTYPE", item->realItemType());
 	docu.writeAttribute("WIDTH", item->width());
 	docu.writeAttribute("HEIGHT", item->height());
@@ -2706,7 +2706,7 @@ void Scribus150Format::SetItemProps(ScXmlStreamWriter& docu, PageItem* item, con
 		if (isWelded)
 		{
 			docu.writeAttribute("isWeldItem", 1);
-			docu.writeAttribute("WeldSource", qHash(item) & 0x7FFFFFFF);
+			docu.writeAttribute("WeldSource", qHash(item->itemName()) & 0x7FFFFFFF);
 		}
 	}
 	if (item->isRegularPolygon())
diff --git a/scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp b/scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp
index 3368812b6..2d997be39 100644
--- a/scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp
+++ b/scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp
@@ -688,7 +688,7 @@ void Scribus170Format::writeBookmarks(ScXmlStreamWriter & docu)
 		docu.writeAttribute("Text", itbm->Text);
 		docu.writeAttribute("Aktion", itbm->Aktion);
 		docu.writeAttribute("ItemNr", itbm->ItemNr);
-		docu.writeAttribute("Element", qHash(itbm->PageObject) & 0x7FFFFFFF);
+		docu.writeAttribute("Element", qHash(itbm->PageObject->itemName()) & 0x7FFFFFFF);
 		docu.writeAttribute("First", itbm->First);
 		docu.writeAttribute("Last", itbm->Last);
 		docu.writeAttribute("Prev", itbm->Prev);
@@ -1515,7 +1515,7 @@ void Scribus170Format::writeMarks(ScXmlStreamWriter & docu)
 		{
 			const PageItem* item = mrk->getItemPtr();
 			assert(item != nullptr);
-			docu.writeAttribute("ItemID", qHash(item) & 0x7FFFFFFF);
+			docu.writeAttribute("ItemID", qHash(item->itemName()) & 0x7FFFFFFF);
 			//docu.writeAttribute("itemName", item->itemName());
 		}
 		else if ((mrk->isType(MARKVariableTextType) || mrk->isType(MARKIndexType)) && mrk->hasString())
@@ -1644,18 +1644,18 @@ void Scribus170Format::writeNotesFrames(ScXmlStreamWriter & docu, const QList<Pa
 			docu.writeEmptyElement("ENDNOTEFRAME");
 			docu.writeAttribute("NSname", noteStyle->name());
 			docu.writeAttribute("range", (int) noteStyle->range());
-			docu.writeAttribute("myID", qHash(noteFrame) & 0x7FFFFFFF);
+			docu.writeAttribute("myID", qHash(noteFrame->itemName()) & 0x7FFFFFFF);
 			
 			rangeItem rI = m_Doc->m_docEndNotesFramesMap.value(noteFrame);
 			if (noteStyle->range() == NSRstory)
-				docu.writeAttribute("ItemID", qHash(rI.firstStoryFrame) & 0x7FFFFFFF);
+				docu.writeAttribute("ItemID", qHash(rI.firstStoryFrame->itemName()) & 0x7FFFFFFF);
 		}
 		else //footnotes frame
 		{
 			docu.writeEmptyElement("FOOTNOTEFRAME");
 			docu.writeAttribute("NSname", noteStyle->name());
-			docu.writeAttribute("myID", qHash(noteFrame) & 0x7FFFFFFF);
-			docu.writeAttribute("MasterID", qHash(noteFrame->masterFrame()) & 0x7FFFFFFF);
+			docu.writeAttribute("myID", qHash(noteFrame->itemName()) & 0x7FFFFFFF);
+			docu.writeAttribute("MasterID", qHash(noteFrame->masterFrame()->itemName()) & 0x7FFFFFFF);
 		}
 	}
 	docu.writeEndElement();
@@ -2229,7 +2229,7 @@ void Scribus170Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, co
 		if (item->isTextFrame() || item->isPathText() || item->isImageFrame())
 		{
 			if (item->nextInChain() != nullptr)
-				docu.writeAttribute("NEXTITEM", qHash(item->nextInChain()) & 0x7FFFFFFF);
+				docu.writeAttribute("NEXTITEM", qHash(item->nextInChain()->itemName()) & 0x7FFFFFFF);
 			else
 				docu.writeAttribute("NEXTITEM", -1);
 
@@ -2243,7 +2243,7 @@ void Scribus170Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, co
 			}
 
 			if (item->prevInChain() != nullptr && prevTopParentCheck)
-				docu.writeAttribute("BACKITEM", qHash(item->prevInChain()) & 0x7FFFFFFF);
+				docu.writeAttribute("BACKITEM", qHash(item->prevInChain()->itemName()) & 0x7FFFFFFF);
 			else
 			{
 				docu.writeAttribute("BACKITEM", -1);
@@ -2269,7 +2269,7 @@ void Scribus170Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, co
 				if (pIt->isAutoNoteFrame())
 					continue;
 				docu.writeEmptyElement("WeldEntry");
-				docu.writeAttribute("Target", qHash(wInf.weldItem) & 0x7FFFFFFF);
+				docu.writeAttribute("Target", qHash(wInf.weldItem->itemName()) & 0x7FFFFFFF);
 				docu.writeAttribute("WX", wInf.weldPoint.x());
 				docu.writeAttribute("WY", wInf.weldPoint.y());
 			}
@@ -2698,7 +2698,7 @@ void Scribus170Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, co
 void Scribus170Format::SetItemProps(ScXmlStreamWriter& docu, PageItem* item, const QString& baseDir)
 {
 	docu.writeAttribute("OwnPage", item->OwnPage);
-	docu.writeAttribute("ItemID", qHash(item) & 0x7FFFFFFF);
+	docu.writeAttribute("ItemID", qHash(item->itemName()) & 0x7FFFFFFF);
 	docu.writeAttribute("PTYPE", item->realItemType());
 	docu.writeAttribute("WIDTH", item->width());
 	docu.writeAttribute("HEIGHT", item->height());
@@ -2755,7 +2755,7 @@ void Scribus170Format::SetItemProps(ScXmlStreamWriter& docu, PageItem* item, con
 		if (isWelded)
 		{
 			docu.writeAttribute("isWeldItem", 1);
-			docu.writeAttribute("WeldSource", qHash(item) & 0x7FFFFFFF);
+			docu.writeAttribute("WeldSource", qHash(item->itemName()) & 0x7FFFFFFF);
 		}
 	}
 	if (item->isRegularPolygon())
stable_ItemIDs.diff (9,388 bytes)   

Issue History

Date Modified Username Field Change
2025-02-13 17:01 tropion New Issue
2025-02-13 17:01 tropion File Added: stable_ItemIDs.diff