summaryrefslogtreecommitdiff
path: root/vcl/source
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-02-17 21:21:32 +0000
committerCaolán McNamara <caolanm@redhat.com>2018-02-19 16:54:33 +0100
commit837ba68ac04ed52716eef531f034b6a49f576178 (patch)
tree0b0188a7280d7722cb29f72d9b10f519ccfc13ad /vcl/source
parent82a213880ff3927d8b2b3e5135743002a3b4df35 (diff)
weld: hook up help response
and keep the current legacy ownership behaviour when welding the legacy backend Change-Id: I7e1f90f2d235abf0e10062b4be11ba5150bbdbfb Reviewed-on: https://gerrit.libreoffice.org/49918 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source')
-rw-r--r--vcl/source/app/salvtables.cxx116
-rw-r--r--vcl/source/window/builder.cxx62
-rw-r--r--vcl/source/window/layout.cxx3
-rw-r--r--vcl/source/window/window.cxx7
4 files changed, 149 insertions, 39 deletions
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 12ce25351a46..d2bef1fe030a 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -27,6 +27,7 @@
#include <salbmp.hxx>
#include <salobj.hxx>
#include <salmenu.hxx>
+#include <svdata.hxx>
#include <vcl/builder.hxx>
#include <vcl/combobox.hxx>
#include <vcl/lstbox.hxx>
@@ -296,11 +297,28 @@ class SalInstanceWindow : public SalInstanceContainer, public virtual weld::Wind
private:
VclPtr<SystemWindow> m_xWindow;
+ DECL_LINK(HelpHdl, vcl::Window&, bool);
+
+ void override_child_help(vcl::Window* pParent)
+ {
+ for (vcl::Window *pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
+ override_child_help(pChild);
+ pParent->SetHelpHdl(LINK(this, SalInstanceWindow, HelpHdl));
+ }
+
+ void clear_child_help(vcl::Window* pParent)
+ {
+ for (vcl::Window *pChild = pParent->GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
+ clear_child_help(pChild);
+ pParent->SetHelpHdl(Link<vcl::Window&,bool>());
+ }
+
public:
SalInstanceWindow(SystemWindow* pWindow, bool bTakeOwnership)
: SalInstanceContainer(pWindow, bTakeOwnership)
, m_xWindow(pWindow)
{
+ override_child_help(m_xWindow);
}
virtual void set_title(const OUString& rTitle) override
@@ -312,8 +330,41 @@ public:
{
return m_xWindow->GetText();
}
+
+ bool help()
+ {
+ //show help for widget with keyboard focus
+ vcl::Window* pWidget = ImplGetSVData()->maWinData.mpFocusWin;
+ if (!pWidget)
+ pWidget = m_xWindow;
+ OString sHelpId = pWidget->GetHelpId();
+ while (sHelpId.isEmpty())
+ {
+ pWidget = pWidget->GetParent();
+ if (!pWidget)
+ break;
+ sHelpId = pWidget->GetHelpId();
+ }
+ std::unique_ptr<weld::Widget> xTemp(pWidget != m_xWindow ? new SalInstanceWidget(pWidget, false) : nullptr);
+ weld::Widget* pSource = xTemp ? xTemp.get() : this;
+ bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource);
+ Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr;
+ if (pHelp)
+ pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource);
+ return false;
+ }
+
+ virtual ~SalInstanceWindow() override
+ {
+ clear_child_help(m_xWindow);
+ }
};
+IMPL_LINK_NOARG(SalInstanceWindow, HelpHdl, vcl::Window&, bool)
+{
+ return help();
+}
+
class SalInstanceDialog : public SalInstanceWindow, public virtual weld::Dialog
{
private:
@@ -328,7 +379,6 @@ public:
virtual int run() override
{
- m_xDialog->Show();
return m_xDialog->Execute();
}
@@ -1104,89 +1154,104 @@ public:
class SalInstanceBuilder : public weld::Builder
{
private:
- VclBuilder m_aBuilder;
+ std::unique_ptr<VclBuilder> m_xBuilder;
+ VclPtr<vcl::Window> m_aOwnedToplevel;
public:
SalInstanceBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile)
: weld::Builder(rUIFile)
- , m_aBuilder(pParent, rUIRoot, rUIFile)
+ , m_xBuilder(new VclBuilder(pParent, rUIRoot, rUIFile, OString(), css::uno::Reference<css::frame::XFrame>(), false))
{
}
virtual weld::MessageDialog* weld_message_dialog(const OString &id, bool bTakeOwnership) override
{
- MessageDialog* pMessageDialog = m_aBuilder.get<MessageDialog>(id);
- return pMessageDialog ? new SalInstanceMessageDialog(pMessageDialog, bTakeOwnership) : nullptr;
+ MessageDialog* pMessageDialog = m_xBuilder->get<MessageDialog>(id);
+ weld::MessageDialog* pRet = pMessageDialog ? new SalInstanceMessageDialog(pMessageDialog, false) : nullptr;
+ if (bTakeOwnership && pMessageDialog)
+ {
+ assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
+ m_aOwnedToplevel.set(pMessageDialog);
+ m_xBuilder->drop_ownership(pMessageDialog);
+ }
+ return pRet;
}
virtual weld::Dialog* weld_dialog(const OString &id, bool bTakeOwnership) override
{
- Dialog* pDialog = m_aBuilder.get<Dialog>(id);
- return pDialog ? new SalInstanceDialog(pDialog, bTakeOwnership) : nullptr;
+ Dialog* pDialog = m_xBuilder->get<Dialog>(id);
+ weld::Dialog* pRet = pDialog ? new SalInstanceDialog(pDialog, false) : nullptr;
+ if (bTakeOwnership && pDialog)
+ {
+ assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
+ m_aOwnedToplevel.set(pDialog);
+ m_xBuilder->drop_ownership(pDialog);
+ }
+ return pRet;
}
virtual weld::Window* weld_window(const OString &id, bool bTakeOwnership) override
{
- SystemWindow* pWindow = m_aBuilder.get<SystemWindow>(id);
+ SystemWindow* pWindow = m_xBuilder->get<SystemWindow>(id);
return pWindow ? new SalInstanceWindow(pWindow, bTakeOwnership) : nullptr;
}
virtual weld::Widget* weld_widget(const OString &id, bool bTakeOwnership) override
{
- vcl::Window* pWidget = m_aBuilder.get<vcl::Window>(id);
+ vcl::Window* pWidget = m_xBuilder->get<vcl::Window>(id);
return pWidget ? new SalInstanceWidget(pWidget, bTakeOwnership) : nullptr;
}
virtual weld::Container* weld_container(const OString &id, bool bTakeOwnership) override
{
- vcl::Window* pContainer = m_aBuilder.get<vcl::Window>(id);
+ vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(id);
return pContainer ? new SalInstanceContainer(pContainer, bTakeOwnership) : nullptr;
}
virtual weld::Frame* weld_frame(const OString &id, bool bTakeOwnership) override
{
- VclFrame* pFrame = m_aBuilder.get<VclFrame>(id);
+ VclFrame* pFrame = m_xBuilder->get<VclFrame>(id);
return pFrame ? new SalInstanceFrame(pFrame, bTakeOwnership) : nullptr;
}
virtual weld::Notebook* weld_notebook(const OString &id, bool bTakeOwnership) override
{
- TabControl* pNotebook = m_aBuilder.get<TabControl>(id);
+ TabControl* pNotebook = m_xBuilder->get<TabControl>(id);
return pNotebook ? new SalInstanceNotebook(pNotebook, bTakeOwnership) : nullptr;
}
virtual weld::Button* weld_button(const OString &id, bool bTakeOwnership) override
{
- Button* pButton = m_aBuilder.get<Button>(id);
+ Button* pButton = m_xBuilder->get<Button>(id);
return pButton ? new SalInstanceButton(pButton, bTakeOwnership) : nullptr;
}
virtual weld::RadioButton* weld_radio_button(const OString &id, bool bTakeOwnership) override
{
- RadioButton* pRadioButton = m_aBuilder.get<RadioButton>(id);
+ RadioButton* pRadioButton = m_xBuilder->get<RadioButton>(id);
return pRadioButton ? new SalInstanceRadioButton(pRadioButton, bTakeOwnership) : nullptr;
}
virtual weld::CheckButton* weld_check_button(const OString &id, bool bTakeOwnership) override
{
- CheckBox* pCheckButton = m_aBuilder.get<CheckBox>(id);
+ CheckBox* pCheckButton = m_xBuilder->get<CheckBox>(id);
return pCheckButton ? new SalInstanceCheckButton(pCheckButton, bTakeOwnership) : nullptr;
}
virtual weld::Entry* weld_entry(const OString &id, bool bTakeOwnership) override
{
- Edit* pEntry = m_aBuilder.get<Edit>(id);
+ Edit* pEntry = m_xBuilder->get<Edit>(id);
return pEntry ? new SalInstanceEntry(pEntry, bTakeOwnership) : nullptr;
}
virtual weld::SpinButton* weld_spin_button(const OString &id, bool bTakeOwnership) override
{
- NumericField* pSpinButton = m_aBuilder.get<NumericField>(id);
+ NumericField* pSpinButton = m_xBuilder->get<NumericField>(id);
return pSpinButton ? new SalInstanceSpinButton(pSpinButton, bTakeOwnership) : nullptr;
}
virtual weld::ComboBoxText* weld_combo_box_text(const OString &id, bool bTakeOwnership) override
{
- vcl::Window* pComboBoxText = m_aBuilder.get<vcl::Window>(id);
+ vcl::Window* pComboBoxText = m_xBuilder->get<vcl::Window>(id);
ComboBox* pComboBox = dynamic_cast<ComboBox*>(pComboBoxText);
if (pComboBox)
return new SalInstanceComboBoxText<ComboBox>(pComboBox, bTakeOwnership);
@@ -1196,27 +1261,34 @@ public:
virtual weld::TreeView* weld_tree_view(const OString &id, bool bTakeOwnership) override
{
- ListBox* pTreeView = m_aBuilder.get<ListBox>(id);
+ ListBox* pTreeView = m_xBuilder->get<ListBox>(id);
return pTreeView ? new SalInstanceTreeView(pTreeView, bTakeOwnership) : nullptr;
}
virtual weld::Label* weld_label(const OString &id, bool bTakeOwnership) override
{
- FixedText* pLabel = m_aBuilder.get<FixedText>(id);
+ FixedText* pLabel = m_xBuilder->get<FixedText>(id);
return pLabel ? new SalInstanceLabel(pLabel, bTakeOwnership) : nullptr;
}
virtual weld::TextView* weld_text_view(const OString &id, bool bTakeOwnership) override
{
- VclMultiLineEdit* pTextView = m_aBuilder.get<VclMultiLineEdit>(id);
+ VclMultiLineEdit* pTextView = m_xBuilder->get<VclMultiLineEdit>(id);
return pTextView ? new SalInstanceTextView(pTextView, bTakeOwnership) : nullptr;
}
virtual weld::DrawingArea* weld_drawing_area(const OString &id, bool bTakeOwnership) override
{
- VclDrawingArea* pDrawingArea = m_aBuilder.get<VclDrawingArea>(id);
+ VclDrawingArea* pDrawingArea = m_xBuilder->get<VclDrawingArea>(id);
return pDrawingArea ? new SalInstanceDrawingArea(pDrawingArea, bTakeOwnership) : nullptr;
}
+
+ virtual ~SalInstanceBuilder() override
+ {
+ if (VclBuilderContainer* pOwnedToplevel = dynamic_cast<VclBuilderContainer*>(m_aOwnedToplevel.get()))
+ pOwnedToplevel->m_pUIBuilder = std::move(m_xBuilder);
+ m_aOwnedToplevel.disposeAndClear();
+ }
};
weld::Builder* SalInstance::CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile)
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index cd7ffe99d051..c6d345434bc6 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -232,12 +232,14 @@ namespace weld
}
}
-VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUString& sUIFile, const OString& sID, const css::uno::Reference<css::frame::XFrame>& rFrame)
+VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUString& sUIFile, const OString& sID,
+ const css::uno::Reference<css::frame::XFrame>& rFrame, bool bLegacy)
: m_sID(sID)
, m_sHelpRoot(OUStringToOString(sUIFile, RTL_TEXTENCODING_UTF8))
, m_pStringReplace(Translate::GetReadStringHook())
, m_pParent(pParent)
, m_bToplevelParentFound(false)
+ , m_bLegacy(bLegacy)
, m_pParserState(new ParserState)
, m_xFrame(rFrame)
{
@@ -869,7 +871,7 @@ namespace
pButton->SetCommandHandler(aCommand);
}
- VclPtr<Button> extractStockAndBuildPushButton(vcl::Window *pParent, VclBuilder::stringmap &rMap)
+ VclPtr<Button> extractStockAndBuildPushButton(vcl::Window *pParent, VclBuilder::stringmap &rMap, bool bLegacy)
{
WinBits nBits = WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER;
@@ -880,15 +882,18 @@ namespace
if (extractStock(rMap))
{
OUString sType = extractLabel(rMap);
- if (sType == "gtk-ok")
- xWindow = VclPtr<OKButton>::Create(pParent, nBits);
- else if (sType == "gtk-cancel")
- xWindow = VclPtr<CancelButton>::Create(pParent, nBits);
- else if (sType == "gtk-close")
- xWindow = VclPtr<CloseButton>::Create(pParent, nBits);
- else if (sType == "gtk-help")
- xWindow = VclPtr<HelpButton>::Create(pParent, nBits);
- else
+ if (bLegacy)
+ {
+ if (sType == "gtk-ok")
+ xWindow = VclPtr<OKButton>::Create(pParent, nBits);
+ else if (sType == "gtk-cancel")
+ xWindow = VclPtr<CancelButton>::Create(pParent, nBits);
+ else if (sType == "gtk-close")
+ xWindow = VclPtr<CloseButton>::Create(pParent, nBits);
+ else if (sType == "gtk-help")
+ xWindow = VclPtr<HelpButton>::Create(pParent, nBits);
+ }
+ if (!xWindow)
{
xWindow = VclPtr<PushButton>::Create(pParent, nBits);
xWindow->SetText(getStockText(sType));
@@ -1305,7 +1310,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
}
else if (name == "GtkMessageDialog")
{
- WinBits nBits = WB_CLIPCHILDREN|WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
+ WinBits nBits = WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
if (extractResizable(rMap))
nBits |= WB_SIZEABLE;
xWindow = VclPtr<MessageDialog>::Create(pParent, nBits);
@@ -1357,7 +1362,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
VclPtr<Button> xButton;
OUString sMenu = BuilderUtils::extractCustomProperty(rMap);
if (sMenu.isEmpty())
- xButton = extractStockAndBuildPushButton(pParent, rMap);
+ xButton = extractStockAndBuildPushButton(pParent, rMap, m_bLegacy);
else
{
xButton = extractStockAndBuildMenuButton(pParent, rMap);
@@ -3386,6 +3391,23 @@ short VclBuilder::get_response(const vcl::Window *pWindow) const
return RET_CANCEL;
}
+IMPL_LINK(VclBuilder, ResponseHdl, ::Button*, pButton, void)
+{
+ short nResponse = get_response(pButton);
+ Dialog* pDialog = pButton->GetParentDialog();
+ assert(pDialog && "who puts a response without a dialog");
+ if (nResponse == RET_HELP)
+ {
+ vcl::Window* pFocusWin = Application::GetFocusWindow();
+ if (!pFocusWin)
+ pFocusWin = pButton;
+ HelpEvent aEvt(pFocusWin->GetPointerPosPixel(), HelpEventMode::CONTEXT);
+ pFocusWin->RequestHelp(aEvt);
+ }
+ else
+ pDialog->EndDialog(nResponse);
+}
+
void VclBuilder::set_response(const OString& sID, short nResponse)
{
switch (nResponse)
@@ -3412,17 +3434,27 @@ void VclBuilder::set_response(const OString& sID, short nResponse)
assert(nResponse >= 0);
+ bool bFound = false;
+
for (auto & child : m_aChildren)
{
if (child.m_sID == sID)
{
child.m_nResponseId = nResponse;
- return;
+ bFound = true;
+ break;
}
}
+ if (!m_bLegacy)
+ {
+ PushButton* pPushButton = get<PushButton>(sID);
+ assert(pPushButton);
+ pPushButton->SetClickHdl(LINK(this, VclBuilder, ResponseHdl));
+ }
+
//how did we not find sID ?
- assert(false);
+ assert(bFound); (void)bFound;
}
void VclBuilder::delete_by_name(const OString& sID)
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 83f9616f5933..b36923871d10 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -2252,7 +2252,8 @@ void MessageDialog::setButtonHandlers(VclButtonBox const *pButtonBox)
case WindowType::PUSHBUTTON:
{
PushButton* pButton = static_cast<PushButton*>(pChild);
- pButton->SetClickHdl(LINK(this, MessageDialog, ButtonHdl));
+ if (!pButton->GetClickHdl().IsSet())
+ pButton->SetClickHdl(LINK(this, MessageDialog, ButtonHdl));
break;
}
//insist that the response ids match the default actions for those
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 111194255057..0945f881e7e9 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1851,6 +1851,11 @@ void Window::LoseFocus()
CompatNotify( aNEvt );
}
+void Window::SetHelpHdl(const Link<vcl::Window&, bool>& rLink)
+{
+ mpWindowImpl->maHelpRequestHdl = rLink;
+}
+
void Window::RequestHelp( const HelpEvent& rHEvt )
{
// if Balloon-Help is requested, show the balloon
@@ -1889,7 +1894,7 @@ void Window::RequestHelp( const HelpEvent& rHEvt )
Help::ShowQuickHelp( this, aRect, rStr, aHelpText, QuickHelpFlags::CtrlText );
}
}
- else
+ else if (!mpWindowImpl->maHelpRequestHdl.IsSet() || mpWindowImpl->maHelpRequestHdl.Call(*this))
{
OUString aStrHelpId( OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
if ( aStrHelpId.isEmpty() && ImplGetParent() )