From 1e2420e7add9ca78e5f4de095dac2cef5c0f5940 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Fri, 16 Jul 2021 12:27:44 +0200 Subject: 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 Tested-by: Jenkins --- extensions/source/bibliography/general.cxx | 143 +++++++++++++++++++-- extensions/source/bibliography/general.hxx | 8 ++ .../uiconfig/sbibliography/ui/generalpage.ui | 81 ++++++++++-- 3 files changed, 214 insertions(+), 18 deletions(-) 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 #include #include +#include #include #include @@ -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 xUriReferenceFactory + = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext()); + uno::Reference 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 xUriReferenceFactory + = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext()); + uno::Reference 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 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& rPropSet) + explicit EntryChangeListener(weld::Entry& rEntry, css::uno::Reference& 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 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 xURLFT; std::unique_ptr xURLED; std::unique_ptr m_xBrowseButton; + std::unique_ptr m_xPageCB; + std::unique_ptr m_xPageSB; std::unique_ptr xCustom1FT; std::unique_ptr xCustom1ED; @@ -123,6 +125,7 @@ class BibGeneralPage : public InterimItemWindow OUString sTableErrorString; std::vector> maChangeListeners; + rtl::Reference 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 @@ + + 55535 + 1 + 10 + True False @@ -27,7 +32,6 @@ False 6 12 - True True @@ -762,15 +766,40 @@ - + True False + vertical - + True - True - True - True + False + + + True + True + True + True + + + False + True + 0 + + + + + Browse... + True + True + True + + + False + True + 1 + + False @@ -779,11 +808,43 @@ - - Browse... + True - True - True + False + + + Page + True + True + False + True + + + + + + False + True + 0 + + + + + False + True + True + adjustment1 + True + + + + + + True + True + 1 + + False -- cgit