diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-07-16 12:27:44 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2021-07-16 14:45:23 +0200 |
commit | 1e2420e7add9ca78e5f4de095dac2cef5c0f5940 (patch) | |
tree | 531e94b455575e3d814d2289b5f3c5977cddebe7 | |
parent | 64f885a6c9d51999b737c0f61bc3a7fa311a5a94 (diff) |
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@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | extensions/source/bibliography/general.cxx | 143 | ||||
-rw-r--r-- | extensions/source/bibliography/general.hxx | 8 | ||||
-rw-r--r-- | extensions/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 <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> |