[office/tellico] /: Check title field existence before exporting entry HTML
Robby Stephenson <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 69e223ad6fe7aa2b0f92a37f903ebd446ec8c8b8 by Robby Stephenson. Committed on 01/08/2026 at 00:48. Pushed by rstephenson into branch 'master'. Check title field existence before exporting entry HTML Fix crash for entries with no fields at all or a non-title field. Use "entry" in the exported file name if there is an empty title. BUG: 523140 FIXED-IN: 4.2.2 M +4 -0 ChangeLog M +48 -0 src/tests/htmlexportertest.cpp M +2 -0 src/tests/htmlexportertest.h M +8 -2 src/translators/htmlexporter.cpp https://invent.kde.org/office/tellico/-/commit/69e223ad6fe7aa2b0f92a37f903ebd446ec8c8b8 diff --git a/ChangeLog b/ChangeLog index f730554ef..d4b4df85c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2026-07-26 Robby Stephenson <[email protected]> + + * Fixed crashing bug when exporting HTML for entries with no title (Bug 523140). + 2026-07-05 Robby Stephenson <[email protected]> * Added drag-and-drop text importing for RIS. diff --git a/src/tests/htmlexportertest.cpp b/src/tests/htmlexportertest.cpp index 6f766a082..6748c0466 100644 --- a/src/tests/htmlexportertest.cpp +++ b/src/tests/htmlexportertest.cpp @@ -474,3 +474,51 @@ void HtmlExporterTest::testLinkedImage() { QVERIFY2(Tellico::GUI::Proxy::lastSorry().isEmpty(), "Last sorry message is not empty after writing output"); } + +// https://bugs.kde.org/show_bug.cgi?id=523140 +void HtmlExporterTest::testNoFields() { + // no fields at all + Tellico::Data::CollPtr coll(new Tellico::Data::Collection(false)); + Tellico::Data::EntryPtr e(new Tellico::Data::Entry(coll)); + coll->addEntries(e); + + QTemporaryDir tempDir; + QVERIFY(tempDir.isValid()); + tempDir.setAutoRemove(true); + + Tellico::Export::HTMLExporter exporter(coll, QUrl()); + exporter.setURL(QUrl::fromLocalFile(tempDir.path() + "/testHtml.html")); + exporter.setXSLTFile(QFINDTESTDATA("../../xslt/tellico2html.xsl")); + exporter.setParseDOM(true); // required since HtmlExporter only creates individual entry files if parsing DOM + exporter.setEntries(coll->entries()); + exporter.setExportEntryFiles(true); + exporter.setEntryXSLTFile(QStringLiteral("Fancy")); + + QVERIFY(exporter.exec()); +} + +// https://bugs.kde.org/show_bug.cgi?id=523140 +void HtmlExporterTest::testNoTitle() { + // no explicit title field + Tellico::Data::CollPtr coll(new Tellico::Data::Collection(false)); + Tellico::Data::FieldPtr f(new Tellico::Data::Field(QStringLiteral("name"), QStringLiteral("Name"))); + coll->addField(f); + + Tellico::Data::EntryPtr e(new Tellico::Data::Entry(coll)); + e->setField(f->name(), QStringLiteral("test")); + coll->addEntries(e); + + QTemporaryDir tempDir; + QVERIFY(tempDir.isValid()); + tempDir.setAutoRemove(true); + + Tellico::Export::HTMLExporter exporter(coll, QUrl()); + exporter.setURL(QUrl::fromLocalFile(tempDir.path() + "/testHtml.html")); + exporter.setXSLTFile(QFINDTESTDATA("../../xslt/tellico2html.xsl")); + exporter.setParseDOM(true); // required since HtmlExporter only creates individual entry files if parsing DOM + exporter.setEntries(coll->entries()); + exporter.setExportEntryFiles(true); + exporter.setEntryXSLTFile(QStringLiteral("Fancy")); + + QVERIFY(exporter.exec()); +} diff --git a/src/tests/htmlexportertest.h b/src/tests/htmlexportertest.h index 6f8cd9374..f5b09a8c9 100644 --- a/src/tests/htmlexportertest.h +++ b/src/tests/htmlexportertest.h @@ -44,6 +44,8 @@ private Q_SLOTS: void testEntryTemplates_data(); void testPrinting(); void testLinkedImage(); + void testNoFields(); + void testNoTitle(); }; #endif diff --git a/src/translators/htmlexporter.cpp b/src/translators/htmlexporter.cpp index daf9fe982..ac3237bda 100644 --- a/src/translators/htmlexporter.cpp +++ b/src/translators/htmlexporter.cpp @@ -141,6 +141,9 @@ void HTMLExporter::setParseDOM(bool parseDOM) { void HTMLExporter::setExportEntryFiles(bool exportEntryFiles) { m_exportEntryFiles = exportEntryFiles; + if(m_exportEntryFiles && !m_parseDOM) { + myWarning() << "HTMLExporter will not export entry files when DOM is not parsed"; + } } void HTMLExporter::setCustomHtml(const QString& html_) { @@ -821,12 +824,15 @@ bool HTMLExporter::writeEntryFiles() { exporter.setCollectionURL(url()); bool parseDOM = true; - const QString title = QStringLiteral("title"); + const QString title = collection()->titleField(); const QString html = QStringLiteral(".html"); - bool multipleTitles = collection()->fieldByName(title)->hasFlag(Data::Field::AllowMultiple); + const bool multipleTitles = !title.isEmpty() && collection()->fieldByName(title)->hasFlag(Data::Field::AllowMultiple); Data::EntryList entries = this->entries(); // not const since the pointer has to be copied foreach(Data::EntryPtr entryIt, entries) { QString file = entryIt->title(formatted); + if(file.isEmpty()) { + file = QStringLiteral("entry"); + } // but only use the first title if it has multiple if(multipleTitles) {