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
This commit is contained in:
Miklos Vajna
2021-07-16 14:45:23 +02:00
parent 64f885a6c9
commit 1e2420e7ad
3 changed files with 214 additions and 18 deletions
+135 -8
View File
@@ -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;
@@ -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();
};
@@ -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>