[Libreoffice-commits] core.git: extensions/source extensions/uiconfig

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Jul 16 12:45:58 UTC 2021


 extensions/source/bibliography/general.cxx          |  143 ++++++++++++++++++--
 extensions/source/bibliography/general.hxx          |    8 +
 extensions/uiconfig/sbibliography/ui/generalpage.ui |   81 +++++++++--
 3 files changed, 214 insertions(+), 18 deletions(-)

New commits:
commit 1e2420e7add9ca78e5f4de095dac2cef5c0f5940
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jul 16 12:27:44 2021 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Jul 16 14:45:23 2021 +0200

    extensions: bibliography database window: add UI to set a page number on a URL
    
    Again, to be consistent with the Define Bibliography Entry dialog which
    already had this.
    
    Change-Id: If43506a3c2cb105551df7ec8198a749315458409
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119021
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/extensions/source/bibliography/general.cxx b/extensions/source/bibliography/general.cxx
index 07fda81fc69f..329ed9391bf9 100644
--- a/extensions/source/bibliography/general.cxx
+++ b/extensions/source/bibliography/general.cxx
@@ -26,6 +26,7 @@
 #include <com/sun/star/awt/XWindow.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
 
 #include <toolkit/helper/vclunohelper.hxx>
 #include <cppuhelper/implbase.hxx>
@@ -51,6 +52,65 @@ using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::form;
 using namespace ::com::sun::star::sdb;
 
+namespace
+{
+/// Tries to split rText into rURL and nPageNumber.
+bool SplitUrlAndPage(const OUString& rText, OUString& rUrl, int& nPageNumber)
+{
+    uno::Reference<uri::XUriReferenceFactory> xUriReferenceFactory
+        = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext());
+    uno::Reference<uri::XUriReference> xUriRef;
+    try
+    {
+        xUriRef = xUriReferenceFactory->parse(rText);
+    }
+    catch (const uno::Exception& rException)
+    {
+        SAL_WARN("extensions.biblio",
+                 "SplitUrlAndPage: failed to parse url: " << rException.Message);
+        return false;
+    }
+
+    OUString aPagePrefix("page=");
+    if (!xUriRef->getFragment().startsWith(aPagePrefix))
+    {
+        return false;
+    }
+
+    nPageNumber = xUriRef->getFragment().copy(aPagePrefix.getLength()).toInt32();
+    xUriRef->clearFragment();
+    rUrl = xUriRef->getUriReference();
+    return true;
+}
+
+/// Merges rUrl and rPageSB to a URL string.
+OUString MergeUrlAndPage(const OUString& rUrl, weld::SpinButton& rPageSB)
+{
+    if (!rPageSB.get_sensitive())
+    {
+        return rUrl;
+    }
+
+    uno::Reference<uri::XUriReferenceFactory> xUriReferenceFactory
+        = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext());
+    uno::Reference<uri::XUriReference> xUriRef;
+    try
+    {
+        xUriRef = xUriReferenceFactory->parse(rUrl);
+    }
+    catch (const uno::Exception& rException)
+    {
+        SAL_WARN("extensions.biblio",
+                 "MergeUrlAndPage: failed to parse url: " << rException.Message);
+        return rUrl;
+    }
+
+    OUString aFragment("page=" + OUString::number(rPageSB.get_value()));
+    xUriRef->setFragment(aFragment);
+    return xUriRef->getUriReference();
+}
+}
+
 static OUString lcl_GetColumnName( const Mapping* pMapping, sal_uInt16 nIndexPos )
 {
     BibConfig* pBibConfig = BibModul::GetConfig();
@@ -125,6 +185,8 @@ BibGeneralPage::BibGeneralPage(vcl::Window* pParent, BibDataManager* pMan)
     , xURLFT(m_xBuilder->weld_label("url"))
     , xURLED(m_xBuilder->weld_entry("urlcontrol"))
     , m_xBrowseButton(m_xBuilder->weld_button("browse"))
+    , m_xPageCB(m_xBuilder->weld_check_button("pagecb"))
+    , m_xPageSB(m_xBuilder->weld_spin_button("pagesb"))
     , xCustom1FT(m_xBuilder->weld_label("custom1"))
     , xCustom1ED(m_xBuilder->weld_entry("custom1control"))
     , xCustom2FT(m_xBuilder->weld_label("custom2"))
@@ -402,12 +464,11 @@ public:
         WriteBack();
     }
 
+    virtual void WriteBack() = 0;
+
 protected:
     css::uno::Reference<css::beans::XPropertySet> m_xPropSet;
     bool m_bSelfChanging;
-
-private:
-    virtual void WriteBack() = 0;
 };
 
 namespace
@@ -415,9 +476,11 @@ namespace
     class EntryChangeListener : public ChangeListener
     {
     public:
-        explicit EntryChangeListener(weld::Entry& rEntry, css::uno::Reference<css::beans::XPropertySet>& rPropSet)
+        explicit EntryChangeListener(weld::Entry& rEntry, css::uno::Reference<css::beans::XPropertySet>& rPropSet,
+                                     BibGeneralPage& rPage)
             : ChangeListener(rPropSet)
             , m_rEntry(rEntry)
+            , m_rPage(rPage)
         {
             rEntry.connect_focus_out(LINK(this, EntryChangeListener, LoseFocusHdl));
             setValue(rPropSet->getPropertyValue("Text"));
@@ -443,24 +506,66 @@ namespace
 
     private:
         weld::Entry& m_rEntry;
+        BibGeneralPage& m_rPage;
 
         DECL_LINK(LoseFocusHdl, weld::Widget&, void);
 
+        /// Updates the UI widget(s) based on rValue.
         void setValue(const css::uno::Any& rValue)
         {
             OUString sNewName;
             rValue >>= sNewName;
-            m_rEntry.set_text(sNewName);
+            if (&m_rEntry != &m_rPage.GetURLED())
+            {
+                m_rEntry.set_text(sNewName);
+            }
+            else
+            {
+                OUString aUrl;
+                int nPageNumber;
+                if (SplitUrlAndPage(sNewName, aUrl, nPageNumber))
+                {
+                    m_rEntry.set_text(aUrl);
+                    m_rPage.GetPageCB().set_active(true);
+                    m_rPage.GetPageSB().set_sensitive(true);
+                    m_rPage.GetPageSB().set_value(nPageNumber);
+                }
+                else
+                {
+                    m_rEntry.set_text(sNewName);
+                    m_rPage.GetPageCB().set_active(false);
+                    m_rPage.GetPageSB().set_sensitive(false);
+                    m_rPage.GetPageSB().set_value(0);
+                }
+            }
+
             m_rEntry.save_value();
+            if (&m_rEntry == &m_rPage.GetURLED())
+            {
+                m_rPage.GetPageSB().save_value();
+            }
         }
 
+        /// Updates m_xPropSet based on the UI widget(s).
         virtual void WriteBack() override
         {
-            if (!m_rEntry.get_value_changed_from_saved())
+            if (!m_rEntry.get_value_changed_from_saved()
+                && !(&m_rEntry == &m_rPage.GetURLED()
+                     && m_rPage.GetPageSB().get_value_changed_from_saved()))
                 return;
+
             m_bSelfChanging = true;
 
-            m_xPropSet->setPropertyValue("Text", makeAny(m_rEntry.get_text()));
+            OUString aText;
+            if (&m_rEntry != &m_rPage.GetURLED())
+            {
+                aText = m_rEntry.get_text();
+            }
+            else
+            {
+                aText = MergeUrlAndPage(m_rEntry.get_text(), m_rPage.GetPageSB());
+            }
+            m_xPropSet->setPropertyValue("Text", makeAny(aText));
 
             css::uno::Reference<css::form::XBoundComponent> xBound(m_xPropSet, css::uno::UNO_QUERY);
             if (xBound.is())
@@ -468,6 +573,10 @@ namespace
 
             m_bSelfChanging = false;
             m_rEntry.save_value();
+            if (&m_rEntry == &m_rPage.GetURLED())
+            {
+                m_rPage.GetPageSB().save_value();
+            }
         }
 
     };
@@ -611,6 +720,8 @@ void BibGeneralPage::dispose()
     xURLFT.reset();
     xURLED.reset();
     m_xBrowseButton.reset();
+    m_xPageCB.reset();
+    m_xPageSB.reset();
     xCustom1FT.reset();
     xCustom1ED.reset();
     xCustom2FT.reset();
@@ -624,6 +735,12 @@ void BibGeneralPage::dispose()
     InterimItemWindow::dispose();
 }
 
+weld::Entry& BibGeneralPage::GetURLED() { return *xURLED; }
+
+weld::CheckButton& BibGeneralPage::GetPageCB() { return *m_xPageCB; }
+
+weld::SpinButton& BibGeneralPage::GetPageSB() { return *m_xPageSB; }
+
 bool BibGeneralPage::AddXControl(const OUString& rName, weld::Entry& rEntry)
 {
     uno::Reference< awt::XControlModel >  xCtrModel;
@@ -637,8 +754,13 @@ bool BibGeneralPage::AddXControl(const OUString& rName, weld::Entry& rEntry)
             if( xPropSet.is())
             {
                 uno::Reference< beans::XPropertySetInfo >  xPropInfo = xPropSet->getPropertySetInfo();
-                maChangeListeners.emplace_back(new EntryChangeListener(rEntry, xPropSet));
+                maChangeListeners.emplace_back(new EntryChangeListener(rEntry, xPropSet, *this));
                 maChangeListeners.back()->start();
+                if (&rEntry == xURLED.get())
+                {
+                    m_aURLListener = maChangeListeners.back();
+                    m_xPageSB->connect_focus_out(LINK(this, BibGeneralPage, LosePageFocusHdl));
+                }
             }
         }
     }
@@ -649,6 +771,11 @@ bool BibGeneralPage::AddXControl(const OUString& rName, weld::Entry& rEntry)
     return xCtrModel.is();
 }
 
+IMPL_LINK_NOARG(BibGeneralPage, LosePageFocusHdl, weld::Widget&, void)
+{
+    m_aURLListener->WriteBack();
+}
+
 IMPL_LINK(BibGeneralPage, GainFocusHdl, weld::Widget&, rWidget, void)
 {
     int x, y, width, height;
diff --git a/extensions/source/bibliography/general.hxx b/extensions/source/bibliography/general.hxx
index acf996a52a25..6b3daeacae03 100644
--- a/extensions/source/bibliography/general.hxx
+++ b/extensions/source/bibliography/general.hxx
@@ -108,6 +108,8 @@ class BibGeneralPage : public InterimItemWindow
     std::unique_ptr<weld::Label> xURLFT;
     std::unique_ptr<weld::Entry> xURLED;
     std::unique_ptr<weld::Button> m_xBrowseButton;
+    std::unique_ptr<weld::CheckButton> m_xPageCB;
+    std::unique_ptr<weld::SpinButton> m_xPageSB;
 
     std::unique_ptr<weld::Label> xCustom1FT;
     std::unique_ptr<weld::Entry> xCustom1ED;
@@ -123,6 +125,7 @@ class BibGeneralPage : public InterimItemWindow
     OUString            sTableErrorString;
 
     std::vector<rtl::Reference<ChangeListener>> maChangeListeners;
+    rtl::Reference<ChangeListener> m_aURLListener;
 
     BibDataManager*     pDatMan;
 
@@ -139,6 +142,7 @@ class BibGeneralPage : public InterimItemWindow
     DECL_LINK(FirstElementKeyInputHdl, const KeyEvent&, bool);
     DECL_LINK(LastElementKeyInputHdl, const KeyEvent&, bool);
     DECL_LINK(BrowseHdl, weld::Button&, void);
+    DECL_LINK(LosePageFocusHdl, weld::Widget&, void);
 
 public:
                                 BibGeneralPage(vcl::Window* pParent, BibDataManager* pDatMan);
@@ -149,6 +153,10 @@ public:
     {
         return sTableErrorString;
     }
+
+    weld::Entry& GetURLED();
+    weld::CheckButton& GetPageCB();
+    weld::SpinButton& GetPageSB();
 };
 
 
diff --git a/extensions/uiconfig/sbibliography/ui/generalpage.ui b/extensions/uiconfig/sbibliography/ui/generalpage.ui
index 8baf5fb0aa00..5047ec1f22eb 100644
--- a/extensions/uiconfig/sbibliography/ui/generalpage.ui
+++ b/extensions/uiconfig/sbibliography/ui/generalpage.ui
@@ -2,6 +2,11 @@
 <!-- Generated with glade 3.38.2 -->
 <interface domain="pcr">
   <requires lib="gtk+" version="3.20"/>
+  <object class="GtkAdjustment" id="adjustment1">
+    <property name="upper">55535</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
   <object class="GtkBox" id="GeneralPage">
     <property name="visible">True</property>
     <property name="can-focus">False</property>
@@ -27,7 +32,6 @@
                 <property name="can-focus">False</property>
                 <property name="row-spacing">6</property>
                 <property name="column-spacing">12</property>
-                <property name="row-homogeneous">True</property>
                 <child>
                   <object class="GtkLabel" id="shortname">
                     <property name="visible">True</property>
@@ -762,15 +766,40 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkBox" id="hbox">
+                  <object class="GtkBox" id="vbox">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
                     <child>
-                      <object class="GtkEntry" id="urlcontrol">
+                      <object class="GtkBox" id="hbox">
                         <property name="visible">True</property>
-                        <property name="can-focus">True</property>
-                        <property name="truncate-multiline">True</property>
-                        <property name="hexpand">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkEntry" id="urlcontrol">
+                            <property name="visible">True</property>
+                            <property name="can-focus">True</property>
+                            <property name="truncate-multiline">True</property>
+                            <property name="hexpand">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="browse">
+                            <property name="label" translatable="yes" context="generalpage|browse">Browse...</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
                         <property name="expand">False</property>
@@ -779,11 +808,43 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkButton" id="browse">
-                        <property name="label" translatable="yes" context="generalpage|browse">Browse...</property>
+                      <object class="GtkBox" id="hbox2">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkCheckButton" id="pagecb">
+                            <property name="label" translatable="yes" context="generalpage|pagecb">Page</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="draw_indicator">True</property>
+                            <accessibility>
+                              <relation type="label-for" target="pagesb"/>
+                            </accessibility>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkSpinButton" id="pagesb">
+                            <property name="sensitive">False</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="adjustment">adjustment1</property>
+                            <property name="truncate-multiline">True</property>
+                            <accessibility>
+                              <relation type="labelled-by" target="pagecb"/>
+                            </accessibility>
+                          </object>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
                         <property name="expand">False</property>


More information about the Libreoffice-commits mailing list