[Libreoffice-commits] core.git: sw/inc sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Mar 12 18:33:03 UTC 2021


 sw/inc/authfld.hxx                 |    2 +
 sw/qa/core/tox/tox.cxx             |   46 +++++++++++++++++++++++++++++++++++++
 sw/source/core/fields/authfld.cxx  |    9 +++++--
 sw/source/core/fields/fldbas.cxx   |    9 +++++++
 sw/source/uibase/docvw/edtwin.cxx  |    2 -
 sw/source/uibase/docvw/edtwin2.cxx |    7 +++++
 sw/source/uibase/inc/wrtsh.hxx     |    2 -
 sw/source/uibase/shells/basesh.cxx |    2 -
 sw/source/uibase/wrtsh/wrtsh2.cxx  |   21 ++++++++++++++++
 9 files changed, 94 insertions(+), 6 deletions(-)

New commits:
commit 64ffabbdb2725e93de997171708bb31c33c93a55
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Mar 12 17:51:07 2021 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Mar 12 19:32:19 2021 +0100

    sw bibliography, refer to a page: make the biblio field clickable
    
    - add support for this in SwWrtShell::ClickToField()
    
    - restrict this to ctrl-click by default (similar to hyperlinks)
    
    - ignore empty URLs
    
    - extend the tooltip to hint the URL
    
    - change pointer to hint that the field is clickable
    
    - downgrade the assert to SAL_WARN in
      SwAuthorityFieldType::RemoveField(), that currently fires every time a
      biblio field is de-selected
    
    Change-Id: I3b4a12d8a7661f7d8d41804f104505c7594debd6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112400
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/authfld.hxx b/sw/inc/authfld.hxx
index cdfcf7f9f55a..c9c7fd880b7b 100644
--- a/sw/inc/authfld.hxx
+++ b/sw/inc/authfld.hxx
@@ -185,6 +185,8 @@ public:
     /// Returns the line matching the source's default row in the ToX.
     OUString GetAuthority(const SwTextAttr* pTextAttr, const SwRootFrame* pLayout) const;
 
+    bool HasURL() const;
+
     void dumpAsXml(xmlTextWriterPtr pWriter) const override;
 };
 
diff --git a/sw/qa/core/tox/tox.cxx b/sw/qa/core/tox/tox.cxx
index 127cb4b06e7f..0862b6403638 100644
--- a/sw/qa/core/tox/tox.cxx
+++ b/sw/qa/core/tox/tox.cxx
@@ -16,6 +16,9 @@
 
 #include <comphelper/propertyvalue.hxx>
 
+#include <IDocumentFieldsAccess.hxx>
+#include <fmtfld.hxx>
+
 namespace
 {
 /// Covers sw/source/core/tox/ fixes.
@@ -108,6 +111,49 @@ CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryURL)
     CPPUNIT_ASSERT_EQUAL(OUString("http://www.example.com/test.pdf"), aActual);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableEntryClick)
+{
+    // Given an empty document:
+    SwDoc* pDoc = createSwDoc();
+
+    // When inserting a biblio entry field with an URL:
+    uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xField(
+        xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY);
+    uno::Sequence<beans::PropertyValue> aFields = {
+        comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW),
+        comphelper::makePropertyValue("Identifier", OUString("AT")),
+        comphelper::makePropertyValue("Author", OUString("Author")),
+        comphelper::makePropertyValue("Title", OUString("Title")),
+        comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf#page=1")),
+    };
+    xField->setPropertyValue("Fields", uno::makeAny(aFields));
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xTextDocument->getText();
+    uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+    uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY);
+    xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false);
+
+    // Then make sure that the field is clickable, since the page part will not be part of the
+    // bibliography table:
+    const SwFieldTypes* pTypes = pDoc->getIDocumentFieldsAccess().GetFieldTypes();
+    auto it = std::find_if(pTypes->begin(), pTypes->end(),
+                           [](const std::unique_ptr<SwFieldType>& pType) {
+                               return pType->Which() == SwFieldIds::TableOfAuthorities;
+                           });
+    CPPUNIT_ASSERT(it != pTypes->end());
+    const SwFieldType* pType = it->get();
+    std::vector<SwFormatField*> aFormatFields;
+    pType->GatherFields(aFormatFields);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aFormatFields.size());
+    SwField* pField = aFormatFields[0]->GetField();
+    // Without the accompanying fix in place, this test would have failed, as the field was not
+    // clickable.
+    CPPUNIT_ASSERT(pField->IsClickable());
+    // This is needed, so the mouse has the correct RefHand pointer style.
+    CPPUNIT_ASSERT(pField->HasClickHdl());
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testAuthorityTableURLDeduplication)
 {
     // Given a document with 3 bibliography references (of type WWW) in it:
diff --git a/sw/source/core/fields/authfld.cxx b/sw/source/core/fields/authfld.cxx
index ad60d02db173..8812d70d2db6 100644
--- a/sw/source/core/fields/authfld.cxx
+++ b/sw/source/core/fields/authfld.cxx
@@ -99,8 +99,7 @@ void SwAuthorityFieldType::RemoveField(const SwAuthEntry* pEntry)
             return;
         }
     }
-    assert(false);
-    OSL_FAIL("Field unknown" );
+    SAL_WARN("sw.core", "SwAuthorityFieldType::RemoveField: pEntry is not my field");
 }
 
 SwAuthEntry* SwAuthorityFieldType::AddField(const OUString& rFieldContents)
@@ -605,6 +604,12 @@ OUString SwAuthorityField::GetAuthority(const SwTextAttr* pTextAttr,
     return aText;
 }
 
+bool SwAuthorityField::HasURL() const
+{
+    const OUString& rURL = GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL);
+    return !rURL.isEmpty();
+}
+
 void SwAuthorityField::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
     xmlTextWriterStartElement(pWriter, BAD_CAST("SwAuthorityField"));
diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx
index 26588ea50199..b942dd47726c 100644
--- a/sw/source/core/fields/fldbas.cxx
+++ b/sw/source/core/fields/fldbas.cxx
@@ -405,6 +405,14 @@ bool SwField::HasClickHdl() const
     case SwFieldIds::SetExp:
         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;
@@ -814,6 +822,7 @@ bool SwField::IsClickable() const
     case SwFieldIds::Input:
     case SwFieldIds::SetExp:
     case SwFieldIds::Dropdown:
+    case SwFieldIds::TableOfAuthorities:
         return true;
     default: break;
     }
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 1f95f9bdea31..93560ec91f3b 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -4809,7 +4809,7 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
                                 }
                                 else
                                 {
-                                    rSh.ClickToField( *aContentAtPos.aFnd.pField );
+                                    rSh.ClickToField(*aContentAtPos.aFnd.pField, bExecHyperlinks);
                                     // a bit of a mystery what this is good for?
                                     // in this case we assume it's valid since we
                                     // just selected a field
diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx
index 645878cd855f..c3af8bd54149 100644
--- a/sw/source/uibase/docvw/edtwin2.cxx
+++ b/sw/source/uibase/docvw/edtwin2.cxx
@@ -347,6 +347,13 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt)
                                 = static_cast<const SwAuthorityField*>(pField);
                             sText = pAuthorityField->GetAuthority(aContentAtPos.pFndTextAttr,
                                                                   rSh.GetLayout());
+                            if (pAuthorityField->HasURL())
+                            {
+                                const OUString& rURL
+                                    = pAuthorityField->GetAuthEntry()->GetAuthorField(
+                                        AUTH_FIELD_URL);
+                                sText += "\n" + SfxHelp::GetURLHelpText(rURL);
+                            }
                             break;
                         }
 
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index cd50a2f3f7a9..67b626dc70bc 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -437,7 +437,7 @@ typedef bool (SwWrtShell::*FNSimpleMove)();
 
     // a click at the given field. the cursor is on it.
     // execute the predefined actions.
-    void ClickToField( const SwField& rField );
+    void ClickToField( const SwField& rField, bool bExecHyperlinks );
     void ClickToINetAttr( const SwFormatINetFormat& rItem, LoadUrlFlags nFilter = LoadUrlFlags::NONE );
     bool ClickToINetGrf( const Point& rDocPt, LoadUrlFlags nFilter );
     inline bool IsInClickToEdit() const ;
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
index 4ec9dccd3113..c91fab016851 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -773,7 +773,7 @@ void SwBaseShell::Execute(SfxRequest &rReq)
                 bool bRet = rSh.MoveFieldType( pFieldType, nSlot == FN_GOTO_NEXT_MARK );
                 SwField* pCurField = bRet ? rSh.GetCurField() : nullptr;
                 if (pCurField)
-                    rSh.ClickToField(*pCurField);
+                    rSh.ClickToField(*pCurField, /*bExecHyperlinks=*/false);
                 rReq.SetReturnValue(SfxBoolItem( nSlot, bRet));
             }
         }
diff --git a/sw/source/uibase/wrtsh/wrtsh2.cxx b/sw/source/uibase/wrtsh/wrtsh2.cxx
index c179383bd28a..cbda31185fed 100644
--- a/sw/source/uibase/wrtsh/wrtsh2.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh2.cxx
@@ -46,6 +46,7 @@
 #include <cmdid.h>
 #include <swabstdlg.hxx>
 #include <SwRewriter.hxx>
+#include <authfld.hxx>
 
 #include <com/sun/star/document/XDocumentProperties.hpp>
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
@@ -334,7 +335,7 @@ void SwWrtShell::UpdateTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
 // handler for click on the field given as parameter.
 // the cursor is positioned on the field.
 
-void SwWrtShell::ClickToField( const SwField& rField )
+void SwWrtShell::ClickToField(const SwField& rField, bool bExecHyperlinks)
 {
     // cross reference field must not be selected because it moves the cursor
     if (SwFieldIds::GetRef != rField.GetTyp()->Which())
@@ -396,6 +397,24 @@ void SwWrtShell::ClickToField( const SwField& rField )
         }
         break;
 
+    case SwFieldIds::TableOfAuthorities:
+        {
+            if (!bExecHyperlinks)
+            {
+                break;
+            }
+
+            auto pField = static_cast<const SwAuthorityField*>(&rField);
+            if (!pField->HasURL())
+            {
+                break;
+            }
+
+            const OUString& rURL = pField->GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL);
+            ::LoadURL(*this, rURL, LoadUrlFlags::NewView, /*rTargetFrameName=*/OUString());
+        }
+        break;
+
     case SwFieldIds::GetRef:
         StartAllAction();
         SwCursorShell::GotoRefMark( static_cast<const SwGetRefField&>(rField).GetSetRefName(),


More information about the Libreoffice-commits mailing list