summaryrefslogtreecommitdiff
path: root/sw/source/core
diff options
context:
space:
mode:
authorVojtěch Doležal <dolezvo1@cvut.cz>2023-02-27 08:52:35 +0100
committerMiklos Vajna <vmiklos@collabora.com>2023-03-07 07:12:31 +0000
commit7b99871635cd48c2a8a1d0afbd7afc60a45cc2ff (patch)
treed2238324dac2096656a5b682bcedd288be5a5787 /sw/source/core
parentcc45d748e241ea96fd0c81154e3dd49f9fc58357 (diff)
tdf#153396 - Bibliography marks improvements
Adds option to separate function of "URL" into (listed) "URL" and "Target URL" to allow for more flexibility (in that case if target URL is empty, bibliography mark hyperlink leads to bibliography table row if possible) When writing tests also found and fixed bug where exporting new file with anchor link bibliography mark crashes LO. Change-Id: Ic1b5c8c9590c0338dcfc4fa3a981142bddae0113 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147868 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw/source/core')
-rw-r--r--sw/source/core/fields/authfld.cxx30
-rw-r--r--sw/source/core/fields/fldbas.cxx10
-rw-r--r--sw/source/core/text/EnhancedPDFExportHelper.cxx149
3 files changed, 155 insertions, 34 deletions
diff --git a/sw/source/core/fields/authfld.cxx b/sw/source/core/fields/authfld.cxx
index 44d1e39dd3ae..d1d50506d741 100644
--- a/sw/source/core/fields/authfld.cxx
+++ b/sw/source/core/fields/authfld.cxx
@@ -634,6 +634,12 @@ OUString SwAuthorityField::GetAuthority(const SwRootFrame* pLayout, const SwForm
return aText;
}
+bool SwAuthorityField::UseTargetURL() const
+{
+ const OUString& rValue = GetAuthEntry()->GetAuthorField(AUTH_FIELD_USE_TARGET_URL);
+ return rValue.toAsciiLowerCase() == "true";
+}
+
bool SwAuthorityField::HasURL() const
{
const OUString& rURL = GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL);
@@ -650,6 +656,22 @@ OUString SwAuthorityField::GetAbsoluteURL() const
INetURLObject::DecodeMechanism::WithCharset);
}
+bool SwAuthorityField::HasTargetURL() const
+{
+ const OUString& rURL = GetAuthEntry()->GetAuthorField(AUTH_FIELD_TARGET_URL);
+ return !rURL.isEmpty();
+}
+
+OUString SwAuthorityField::GetAbsoluteTargetURL() const
+{
+ const OUString& rURL = GetAuthEntry()->GetAuthorField(AUTH_FIELD_TARGET_URL);
+ SwDoc* pDoc = static_cast<SwAuthorityFieldType*>(GetTyp())->GetDoc();
+ SwDocShell* pDocShell = pDoc->GetDocShell();
+ OUString aBasePath = pDocShell->getDocumentBaseURL();
+ return INetURLObject::GetAbsURL(aBasePath, rURL, INetURLObject::EncodeMechanism::WasEncoded,
+ INetURLObject::DecodeMechanism::WithCharset);
+}
+
OUString SwAuthorityField::GetURI(bool bRelative) const
{
OUString sTmp = GetFieldText(AUTH_FIELD_URL);
@@ -751,7 +773,9 @@ const char* const aFieldNames[] =
"Custom4",
"Custom5",
"ISBN",
- "LocalURL"
+ "LocalURL",
+ "TargetURL",
+ "UseTargetURL"
};
void SwAuthEntry::dumpAsXml(xmlTextWriterPtr pWriter) const
@@ -808,8 +832,8 @@ bool SwAuthorityField::PutValue( const Any& rAny, sal_uInt16 /*nWhichId*/ )
if(!(rAny >>= aParam))
return false;
- OUStringBuffer sBuf(+AUTH_FIELD_LOCAL_URL);
- comphelper::string::padToLength(sBuf, AUTH_FIELD_LOCAL_URL, TOX_STYLE_DELIMITER);
+ OUStringBuffer sBuf(+(AUTH_FIELD_END - 1));
+ comphelper::string::padToLength(sBuf, (AUTH_FIELD_END - 1), TOX_STYLE_DELIMITER);
OUString sToSet(sBuf.makeStringAndClear());
for(const PropertyValue& rParam : std::as_const(aParam))
{
diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx
index 71afe0d7e425..80ae487f93fe 100644
--- a/sw/source/core/fields/fldbas.cxx
+++ b/sw/source/core/fields/fldbas.cxx
@@ -423,7 +423,8 @@ bool SwField::HasClickHdl() const
case SwFieldIds::GetRef:
case SwFieldIds::Macro:
case SwFieldIds::Input:
- case SwFieldIds::Dropdown :
+ case SwFieldIds::Dropdown:
+ case SwFieldIds::TableOfAuthorities:
bRet = true;
break;
@@ -431,13 +432,6 @@ bool SwField::HasClickHdl() const
bRet = static_cast<const SwSetExpField*>(this)->GetInputFlag();
break;
- case SwFieldIds::TableOfAuthorities:
- {
- const auto pAuthorityField = static_cast<const SwAuthorityField*>(this);
- bRet = pAuthorityField->HasURL();
- break;
- }
-
default: break;
}
return bRet;
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 053b67990eda..1dde77106624 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -803,6 +803,13 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType )
bLanguage = true;
break;
+ case vcl::PDFWriter::BibEntry :
+ bTextDecorationType =
+ bBaselineShift =
+ bLinkAttribute =
+ bLanguage = true;
+ break;
+
default:
break;
}
@@ -2246,6 +2253,50 @@ void SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks()
return;
}
+ // Create PDF destinations for bibliography table entries
+ std::vector<std::tuple<const SwTOXBase*, const OUString*, sal_Int32>> vDestinations;
+ // string is the row node text, sal_Int32 is number of the destination
+ // Note: This way of iterating doesn't seem to take into account TOXes
+ // that are in a frame, probably in some other cases too
+ {
+ mrSh.GotoPage(1);
+ while (mrSh.GotoNextTOXBase())
+ {
+ const SwTOXBase* pIteratedTOX = nullptr;
+ while ((pIteratedTOX = mrSh.GetCurTOX()) != nullptr
+ && pIteratedTOX->GetType() == TOX_AUTHORITIES)
+ {
+ if (const SwNode& rCurrentNode = mrSh.GetCursor()->GetPoint()->GetNode();
+ rCurrentNode.GetNodeType() == SwNodeType::Text)
+ {
+ if (mrSh.GetCursor()->GetPoint()->GetNode().FindSectionNode()->GetSection().GetType()
+ == SectionType::ToxContent) // this checks it's not a heading
+ {
+ // Destination Rectangle
+ const SwRect& rDestRect = mrSh.GetCharRect();
+
+ const SwPageFrame* pCurrPage =
+ static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
+
+ // Destination PageNum
+ const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
+
+ // Destination Export
+ if ( -1 != nDestPageNum )
+ {
+ tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
+ const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
+ const OUString* vNodeText = &static_cast<const SwTextNode*>(&rCurrentNode)->GetText();
+ vDestinations.emplace_back(pIteratedTOX, vNodeText, nDestId);
+ }
+ }
+ }
+ mrSh.MovePara(GoNextPara, fnParaStart);
+ }
+ }
+ }
+
+ // Generate links to matching entries in the bibliography tables
std::vector<SwFormatField*> aFields;
SwFieldType* pType = mrSh.GetFieldType(SwFieldIds::TableOfAuthorities, OUString());
if (!pType)
@@ -2264,38 +2315,90 @@ void SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks()
const auto& rAuthorityField
= *static_cast<const SwAuthorityField*>(pFormatField->GetField());
- if (!rAuthorityField.HasURL())
- {
- continue;
- }
- const OUString& rURL = rAuthorityField.GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL);
- const SwTextNode& rTextNode = pFormatField->GetTextField()->GetTextNode();
- if (!lcl_TryMoveToNonHiddenField(mrSh, rTextNode, *pFormatField))
+ if ((!rAuthorityField.UseTargetURL() && rAuthorityField.HasURL())
+ || (rAuthorityField.UseTargetURL() && rAuthorityField.HasTargetURL()))
{
- continue;
- }
+ // Since the conditions indicate usage of a URL link to it
+ const OUString& rURL = rAuthorityField.GetAuthEntry()->GetAuthorField(
+ rAuthorityField.UseTargetURL() ? AUTH_FIELD_TARGET_URL : AUTH_FIELD_URL);
- OUString const content(rAuthorityField.ExpandField(true, mrSh.GetLayout()));
+ const SwTextNode& rTextNode = pFormatField->GetTextField()->GetTextNode();
+ if (!lcl_TryMoveToNonHiddenField(mrSh, rTextNode, *pFormatField))
+ {
+ continue;
+ }
- // Select the field.
- mrSh.SwCursorShell::SetMark();
- mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars);
+ OUString const content(rAuthorityField.ExpandField(true, mrSh.GetLayout()));
- // Create the links.
- for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_())
- {
- for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
+ // Select the field.
+ mrSh.SwCursorShell::SetMark();
+ mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars);
+
+ // Create the links.
+ for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_())
{
- tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, rLinkRect.SVRect()));
- sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, content, rLinkPageNum);
- IdMapEntry aLinkEntry(rLinkRect, nLinkId);
- s_aLinkIdMap.push_back(aLinkEntry);
- pPDFExtOutDevData->SetLinkURL(nLinkId, rURL);
+ for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
+ {
+ tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, rLinkRect.SVRect()));
+ sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, content, rLinkPageNum);
+ IdMapEntry aLinkEntry(rLinkRect, nLinkId);
+ s_aLinkIdMap.push_back(aLinkEntry);
+ pPDFExtOutDevData->SetLinkURL(nLinkId, rURL);
+ }
}
+ mrSh.SwCursorShell::ClearMark();
}
+ else if (rAuthorityField.UseTargetURL())
+ {
+ // Since the bibliography mark doesn't have target URL, try linking to a bibliography table
+ sal_Int32 nDestId = -1;
+
+ std::unordered_map<const SwTOXBase*, OUString> vFormattedFieldStrings;
+ for (const auto& rDestinationTuple : vDestinations)
+ {
+ if (vFormattedFieldStrings.find(std::get<0>(rDestinationTuple))
+ == vFormattedFieldStrings.end())
+ vFormattedFieldStrings.emplace(std::get<0>(rDestinationTuple),
+ rAuthorityField.GetAuthority(mrSh.GetLayout(),
+ &std::get<0>(rDestinationTuple)->GetTOXForm()));
+
+ if (vFormattedFieldStrings.at(std::get<0>(rDestinationTuple)) == *std::get<1>(rDestinationTuple))
+ {
+ nDestId = std::get<2>(rDestinationTuple);
+ break;
+ }
+ }
+
+ if (nDestId == -1)
+ continue;
+
+ const SwTextNode& rTextNode = pFormatField->GetTextField()->GetTextNode();
+ if (!lcl_TryMoveToNonHiddenField(mrSh, rTextNode, *pFormatField))
+ {
+ continue;
+ }
+
+ OUString const content(rAuthorityField.ExpandField(true, mrSh.GetLayout()));
- mrSh.SwCursorShell::ClearMark();
+ // Select the field.
+ mrSh.SwCursorShell::SetMark();
+ mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars);
+
+ // Create the links.
+ for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_())
+ {
+ for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
+ {
+ tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, rLinkRect.SVRect()));
+ sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, content, rLinkPageNum);
+ IdMapEntry aLinkEntry(rLinkRect, nLinkId);
+ s_aLinkIdMap.push_back(aLinkEntry);
+ pPDFExtOutDevData->SetLinkDest(nLinkId, nDestId);
+ }
+ }
+ mrSh.SwCursorShell::ClearMark();
+ }
}
}