r24655 by jghali - #16579: Tab order for PDF radio buttons does not respect Level in Outline order

scribus-commit scribus-commit at lists.scribus.net
Thu Jun 3 20:39:13 UTC 2021


Author: jghali
Date: Thu Jun  3 20:39:13 2021
New Revision: 24655

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=24655
Log:
#16579: Tab order for PDF radio buttons does not respect Level in Outline order

Modified:
    trunk/Scribus/scribus/pdflib_core.cpp
    trunk/Scribus/scribus/pdflib_core.h
    trunk/Scribus/scribus/pdfstructs.h

Modified: trunk/Scribus/scribus/pdflib_core.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24655&path=/trunk/Scribus/scribus/pdflib_core.cpp
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.cpp	(original)
+++ trunk/Scribus/scribus/pdflib_core.cpp	Thu Jun  3 20:39:13 2021
@@ -3388,6 +3388,7 @@
 	Content.clear();
 	pageData.AObjects.clear();
 	pageData.radioButtonList.clear();
+	pageData.radioButtonGroups.clear();
 	if (Options.Thumbnails)
 	{
 		ScImage img(thumb);
@@ -3422,7 +3423,7 @@
 void PDFLibCore::PDF_End_Page()
 {
 	if (!pageData.radioButtonList.isEmpty())
-		PDF_RadioButtons();
+		PDF_RadioButtonGroups();
 	uint PgNr =  ActPageP->pageNr();
 	double markOffs = 0.0;
 	if ((Options.cropMarks) || (Options.bleedMarks) || (Options.registrationMarks) || (Options.colorMarks) || (Options.docInfoMarks))
@@ -4686,6 +4687,20 @@
 				if (ite->annotation().Type() == Annotation::RadioButton)
 				{
 					pageData.radioButtonList.append(ite);
+					if (!pageData.radioButtonGroups.contains(ite->Parent))
+					{
+						PdfRadioButtonGroup radioButtonGroup;
+						radioButtonGroup.groupId = writer.newObject();
+						if (ite->Parent == nullptr)
+							radioButtonGroup.groupName = "Page" + Pdf::toPdf(ActPageP->pageNr() + 1);
+						else
+							radioButtonGroup.groupName = Pdf::toPdfDocEncoding(ite->Parent->itemName().replace(".", "_"));
+						pageData.radioButtonGroups.insert(ite->Parent, radioButtonGroup);
+					}
+					PdfRadioButtonGroup& radioButtonGroup = pageData.radioButtonGroups[ite->Parent];
+					PdfId parentObject = radioButtonGroup.groupId;
+					PdfId kid = PDF_RadioButton(ite, parentObject, radioButtonGroup.groupName);
+					radioButtonGroup.kids.append(kid);
 					break;
 				}
 				if (!PDF_Annotation(ite, PNr))
@@ -8792,39 +8807,40 @@
 }
 #endif
 
-void PDFLibCore::PDF_RadioButtons()
+void PDFLibCore::PDF_RadioButtonGroups()
 {
 	QHash<PageItem*, QList<PageItem*> > rbMap;
-	for (int a = 0; a < pageData.radioButtonList.count(); a++)
-	{
-		PageItem* pa = pageData.radioButtonList[a]->Parent;
-		if (rbMap.contains(pa))
-			rbMap[pa].append(pageData.radioButtonList[a]);
+	for (int i = 0; i < pageData.radioButtonList.count(); ++i)
+	{
+		PageItem* radioItem = pageData.radioButtonList[i];
+		PageItem* radioParent = radioItem->Parent;
+		if (rbMap.contains(radioParent))
+			rbMap[radioParent].append(radioItem);
 		else
 		{
 			QList<PageItem*> aList;
-			aList.append(pageData.radioButtonList[a]);
-			rbMap.insert(pa, aList);
-		}
-	}
-	QHash<PageItem*, QList<PageItem*> >::Iterator it;
-	for (it = rbMap.begin(); it != rbMap.end(); ++it)
-	{
-		QList<PageItem*> bList = it.value();
-		QList<PdfId> kidsList;
-		PdfId parentObject = writer.newObject();
+			aList.append(radioItem);
+			rbMap.insert(radioParent, aList);
+		}
+	}
+
+	// Do not iterate using rbMap, that would break tab order
+	for (int i = 0; i < pageData.radioButtonList.count(); ++i)
+	{
+		PageItem* radioItem = pageData.radioButtonList[i];
+		PageItem* itemKey = radioItem->Parent;
+		if (!rbMap.contains(itemKey))
+			continue;
+		QList<PageItem*> radioList = rbMap[itemKey];
+		const PdfRadioButtonGroup& pdfRadioButtonGroup = pageData.radioButtonGroups[itemKey];
+		PdfId parentObject = pdfRadioButtonGroup.groupId;
+		QByteArray anTitle = pdfRadioButtonGroup.groupName;
 		QByteArray onState;
-		QByteArray anTitle;
-		if (it.key() == 0)
-			anTitle = "Page" + Pdf::toPdf(ActPageP->pageNr() + 1);
-		else
-			anTitle = Pdf::toPdfDocEncoding(it.key()->itemName().replace(".", "_"));
-		for (int a = 0; a < bList.count(); a++)
-		{
-			PdfId kid = PDF_RadioButton(bList[a], parentObject, anTitle);
-			kidsList.append(kid);
-			if (bList[a]->annotation().IsChk())
-				onState = Pdf::toName(bList[a]->itemName().replace(".", "_"));
+		for (int j = 0; j < radioList.count(); ++j)
+		{
+			PageItem* radioKid = radioList[j];
+			if (radioKid->annotation().IsChk())
+				onState = Pdf::toName(radioKid->itemName().replace(".", "_"));
 		}
 		writer.startObj(parentObject);
 		pageData.AObjects.append(parentObject);
@@ -8838,14 +8854,16 @@
 		PutDoc("/V " + onState + "\n");
 		PutDoc("/DV " + onState + "\n");
 		PutDoc("/Kids\n[\n");
-		for (int a = 0; a < kidsList.count(); a++)
-		{
-			PutDoc(Pdf::toPdf(kidsList[a]) + " 0 R\n");
+		QList<PdfId> kidsList = pageData.radioButtonGroups[itemKey].kids;
+		for (int j = 0; j < kidsList.count(); ++j)
+		{
+			PutDoc(Pdf::toPdf(kidsList[j]) + " 0 R\n");
 		}
 		PutDoc("]\n");
 		PutDoc("/Rect [0 0 0 0]\n");
 		PutDoc(">>");
 		writer.endObj(parentObject);
+		rbMap.remove(itemKey);
 	}
 }
 

Modified: trunk/Scribus/scribus/pdflib_core.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24655&path=/trunk/Scribus/scribus/pdflib_core.h
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.h	(original)
+++ trunk/Scribus/scribus/pdflib_core.h	Thu Jun  3 20:39:13 2021
@@ -222,7 +222,7 @@
 #ifdef HAVE_OSG
 	bool    PDF_3DAnnotation(PageItem *ite, uint PNr);
 #endif
-	void	PDF_RadioButtons();
+	void    PDF_RadioButtonGroups();
 	uint    PDF_RadioButton(PageItem *ite, uint parent, const QString& parentName);
 	bool    PDF_Annotation(PageItem *ite, uint PNr);
 	void    PDF_Form(const QByteArray& im);

Modified: trunk/Scribus/scribus/pdfstructs.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24655&path=/trunk/Scribus/scribus/pdfstructs.h
==============================================================================
--- trunk/Scribus/scribus/pdfstructs.h	(original)
+++ trunk/Scribus/scribus/pdfstructs.h	Thu Jun  3 20:39:13 2021
@@ -9,11 +9,11 @@
 #ifndef Scribus_pdfstructs_h
 #define Scribus_pdfstructs_h
 
-#include<QByteArray>
-#include<QList>
-#include<QMap>
-#include<QRect>
-#include<QString>
+#include <QByteArray>
+#include <QList>
+#include <QMap>
+#include <QRect>
+#include <QString>
 
 class PageItem;
 
@@ -42,7 +42,6 @@
 }
 
 
-
 struct PdfDest
 {
 	QString Name;
@@ -66,6 +65,14 @@
 };
 
 
+struct PdfRadioButtonGroup
+{
+	PdfId groupId;
+	QByteArray groupName;
+	QList<PdfId> kids;
+};
+
+
 struct PdfPageData
 {
 	PdfId ObjNum;
@@ -76,6 +83,7 @@
 	QList<PdfId> AObjects;
 	QList<PdfId> FormObjects;
 	QList<PageItem*> radioButtonList;
+	QMap<PageItem*, PdfRadioButtonGroup> radioButtonGroups;
 };
 
 




More information about the scribus-commit mailing list