weld ImplTabButtons
create a separate .ui for the ltr-in-rtl scroll arrow region
Change-Id: I2ec9099f7441ba82555270b5a99541cd7a989890
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106288
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/svtools/tabbar.hxx b/include/svtools/tabbar.hxx
index 2a9d8a4..8735e07 100644
--- a/include/svtools/tabbar.hxx
+++ b/include/svtools/tabbar.hxx
@@ -267,7 +267,9 @@ carried out over an item resp. over which item the mouse click has
been carried out.
*/
namespace weld {
class Button;
}
#define WB_RANGESELECT (WinBits(0x00200000))
#define WB_MULTISELECT (WinBits(0x00400000))
@@ -308,7 +310,6 @@ struct TabBar_Impl;
class SVT_DLLPUBLIC TabBar : public vcl::Window
{
friend class ImplTabButton;
friend class ImplTabSizer;
private:
@@ -363,9 +364,10 @@ private:
SVT_DLLPRIVATE void ImplPrePaint();
SVT_DLLPRIVATE ImplTabBarItem* ImplGetLastTabBarItem( sal_uInt16 nItemCount );
DECL_DLLPRIVATE_LINK(ImplClickHdl, Button*, void);
DECL_DLLPRIVATE_LINK(ImplAddClickHandler, Button*, void);
DECL_DLLPRIVATE_LINK(ImplClickHdl, weld::Button&, void);
DECL_DLLPRIVATE_LINK(ImplAddClickHandler, weld::Button&, void);
DECL_DLLPRIVATE_LINK(MousePressHdl, const MouseEvent&, bool);
DECL_DLLPRIVATE_LINK(ContextMenuHdl, const CommandEvent&, void);
ImplTabBarItem* seek( size_t i );
ImplTabBarItem* prev();
diff --git a/include/vcl/weldutils.hxx b/include/vcl/weldutils.hxx
index d956849..ddd34d1 100644
--- a/include/vcl/weldutils.hxx
+++ b/include/vcl/weldutils.hxx
@@ -397,6 +397,7 @@ private:
weld::Button& m_rButton;
AutoTimer m_aRepeat;
const Link<Button&, void> m_aLink;
const Link<const CommandEvent&, void> m_aContextLink;
bool m_bModKey;
DECL_LINK(MousePressHdl, const MouseEvent&, bool);
@@ -404,7 +405,9 @@ private:
DECL_LINK(RepeatTimerHdl, Timer*, void);
public:
ButtonPressRepeater(weld::Button& rButton, const Link<Button&, void>& rLink);
ButtonPressRepeater(weld::Button& rButton, const Link<Button&, void>& rLink,
const Link<const CommandEvent&, void>& rContextLink
= Link<const CommandEvent&, void>());
void Stop() { m_aRepeat.Stop(); }
bool IsModKeyPressed() const { return m_bModKey; }
};
diff --git a/solenv/sanitizers/ui/svt.suppr b/solenv/sanitizers/ui/svt.suppr
index 2ee5632..40c22f8 100644
--- a/solenv/sanitizers/ui/svt.suppr
+++ b/solenv/sanitizers/ui/svt.suppr
@@ -26,5 +26,15 @@ svtools/uiconfig/ui/restartdialog.ui://GtkLabel[@id='reason_skia'] orphan-label
svtools/uiconfig/ui/restartdialog.ui://GtkLabel[@id='label'] orphan-label
svtools/uiconfig/ui/spinfieldcontrol.ui://GtkSpinButton[@id='spinbutton'] no-labelled-by
svtools/uiconfig/ui/tabbaredit.ui://GtkEntry[@id='entry'] no-labelled-by
svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='first'] button-no-label
svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='next'] button-no-label
svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='prev'] button-no-label
svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='last'] button-no-label
svtools/uiconfig/ui/tabbuttons.ui://GtkButton[@id='add'] button-no-label
svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='first'] button-no-label
svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='next'] button-no-label
svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='prev'] button-no-label
svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='last'] button-no-label
svtools/uiconfig/ui/tabbuttonsmirrored.ui://GtkButton[@id='add'] button-no-label
svtools/uiconfig/ui/thineditcontrol.ui://GtkEntry[@id='entry'] no-labelled-by
svtools/uiconfig/ui/thineditcontrol.ui://GtkSpinButton[@id='spinbutton'] no-labelled-by
diff --git a/svtools/UIConfig_svt.mk b/svtools/UIConfig_svt.mk
index 4414ba3..5df446e6 100644
--- a/svtools/UIConfig_svt.mk
+++ b/svtools/UIConfig_svt.mk
@@ -30,6 +30,8 @@ $(eval $(call gb_UIConfig_add_uifiles,svt,\
svtools/uiconfig/ui/querydeletedialog \
svtools/uiconfig/ui/restartdialog \
svtools/uiconfig/ui/spinfieldcontrol \
svtools/uiconfig/ui/tabbuttons \
svtools/uiconfig/ui/tabbuttonsmirrored \
svtools/uiconfig/ui/tabbaredit \
svtools/uiconfig/ui/textviewcontrol \
svtools/uiconfig/ui/thineditcontrol \
diff --git a/svtools/source/control/tabbar.cxx b/svtools/source/control/tabbar.cxx
index e41696c..d44dd06 100644
--- a/svtools/source/control/tabbar.cxx
+++ b/svtools/source/control/tabbar.cxx
@@ -22,16 +22,17 @@
#include <tools/time.hxx>
#include <tools/poly.hxx>
#include <vcl/InterimItemWindow.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/svapp.hxx>
#include <vcl/help.hxx>
#include <vcl/decoview.hxx>
#include <vcl/button.hxx>
#include <vcl/event.hxx>
#include <vcl/settings.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/svtaccessiblefactory.hxx>
#include <vcl/accessiblefactory.hxx>
#include <vcl/ptrstyle.hxx>
#include <vcl/weldutils.hxx>
#include <svtools/svtresid.hxx>
#include <svtools/strings.hrc>
#include <limits>
@@ -48,7 +49,6 @@ constexpr sal_uInt16 TABBAR_DRAG_SCROLLOFF = 5;
constexpr sal_uInt16 TABBAR_MINSIZE = 5;
constexpr sal_uInt16 ADDNEWPAGE_AREAWIDTH = 10;
constexpr sal_uInt16 BUTTON_MARGIN = 6;
class TabDrawer
{
@@ -233,68 +233,6 @@ struct ImplTabBarItem
}
};
class ImplTabButton : public PushButton
{
bool mbModKey : 1;
public:
ImplTabButton(TabBar* pParent, WinBits nWinStyle = 0)
: PushButton(pParent, nWinStyle | WB_FLATBUTTON | WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOLIGHTBORDER | WB_NOPOINTERFOCUS)
, mbModKey(false)
{}
TabBar* GetParent() const
{
return static_cast<TabBar*>(Window::GetParent());
}
bool isModKeyPressed() const
{
return mbModKey;
}
virtual bool PreNotify(NotifyEvent& rNotifyEvent) override;
virtual void MouseButtonDown(const MouseEvent& rMouseEvent) override;
virtual void MouseButtonUp(const MouseEvent& rMouseEvent) override;
virtual void Command(const CommandEvent& rCommandEvent) override;
};
void ImplTabButton::MouseButtonDown(const MouseEvent& rMouseEvent)
{
mbModKey = rMouseEvent.IsMod1();
PushButton::MouseButtonDown(rMouseEvent);
}
void ImplTabButton::MouseButtonUp(const MouseEvent& rMouseEvent)
{
mbModKey = false;
PushButton::MouseButtonUp(rMouseEvent);
}
void ImplTabButton::Command(const CommandEvent& rCommandEvent)
{
if (rCommandEvent.GetCommand() == CommandEventId::ContextMenu)
{
TabBar* pParent = GetParent();
pParent->maScrollAreaContextHdl.Call(rCommandEvent);
}
PushButton::Command(rCommandEvent);
}
bool ImplTabButton::PreNotify(NotifyEvent& rNotifyEvent)
{
if (rNotifyEvent.GetType() == MouseNotifyEvent::MOUSEBUTTONDOWN)
{
if (GetParent()->IsInEditMode())
{
GetParent()->EndEditMode();
return true;
}
}
return PushButton::PreNotify(rNotifyEvent);
}
class ImplTabSizer : public vcl::Window
{
public:
@@ -471,14 +409,74 @@ IMPL_LINK_NOARG(TabBarEdit, ImplEndTimerHdl, Timer *, void)
GetParent()->EndEditMode( true );
}
namespace {
class TabButtons final : public InterimItemWindow
{
public:
std::unique_ptr<weld::Button> m_xFirstButton;
std::unique_ptr<weld::Button> m_xPrevButton;
std::unique_ptr<weld::Button> m_xNextButton;
std::unique_ptr<weld::Button> m_xLastButton;
std::unique_ptr<weld::Button> m_xAddButton;
std::unique_ptr<weld::ButtonPressRepeater> m_xAddRepeater;
std::unique_ptr<weld::ButtonPressRepeater> m_xPrevRepeater;
std::unique_ptr<weld::ButtonPressRepeater> m_xNextRepeater;
TabButtons(TabBar* pParent)
: InterimItemWindow(pParent,
pParent->IsMirrored() ? OUString("svt/ui/tabbuttonsmirrored.ui")
: OUString("svt/ui/tabbuttons.ui"),
"TabButtons")
, m_xFirstButton(m_xBuilder->weld_button("first"))
, m_xPrevButton(m_xBuilder->weld_button("prev"))
, m_xNextButton(m_xBuilder->weld_button("next"))
, m_xLastButton(m_xBuilder->weld_button("last"))
, m_xAddButton(m_xBuilder->weld_button("add"))
{
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
SetPaintTransparent(false);
SetBackground(rStyleSettings.GetFaceColor());
m_xFirstButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_MOVET0HOME));
m_xPrevButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_MOVELEFT));
m_xNextButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_MOVERIGHT));
m_xLastButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_MOVETOEND));
m_xAddButton->set_accessible_name(SvtResId(STR_TABBAR_PUSHBUTTON_ADDTAB));
}
void AdaptToHeight(int nHeight)
{
if (m_xFirstButton->get_preferred_size() == Size(nHeight, nHeight))
return;
m_xFirstButton->set_size_request(nHeight, nHeight);
m_xPrevButton->set_size_request(nHeight, nHeight);
m_xNextButton->set_size_request(nHeight, nHeight);
m_xLastButton->set_size_request(nHeight, nHeight);
m_xAddButton->set_size_request(nHeight, nHeight);
InvalidateChildSizeCache();
}
virtual void dispose() override
{
m_xNextRepeater.reset();
m_xPrevRepeater.reset();
m_xAddRepeater.reset();
m_xAddButton.reset();
m_xLastButton.reset();
m_xNextButton.reset();
m_xPrevButton.reset();
m_xFirstButton.reset();
InterimItemWindow::dispose();
}
};
}
struct TabBar_Impl
{
ScopedVclPtr<ImplTabSizer> mpSizer;
ScopedVclPtr<ImplTabButton> mpFirstButton;
ScopedVclPtr<ImplTabButton> mpPrevButton;
ScopedVclPtr<ImplTabButton> mpNextButton;
ScopedVclPtr<ImplTabButton> mpLastButton;
ScopedVclPtr<ImplTabButton> mpAddButton;
ScopedVclPtr<TabButtons> mxButtonBox;
ScopedVclPtr<TabBarEdit> mxEdit;
std::vector<std::unique_ptr<ImplTabBarItem>> mpItemList;
@@ -541,18 +539,6 @@ void TabBar::ImplInit( WinBits nWinStyle )
ImplInitControls();
if (mpImpl->mpFirstButton)
mpImpl->mpFirstButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_MOVET0HOME));
if (mpImpl->mpPrevButton)
mpImpl->mpPrevButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_MOVELEFT));
if (mpImpl->mpNextButton)
mpImpl->mpNextButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_MOVERIGHT));
if (mpImpl->mpLastButton)
mpImpl->mpLastButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_MOVETOEND));
if (mpImpl->mpAddButton)
mpImpl->mpAddButton->SetAccessibleName(SvtResId(STR_TABBAR_PUSHBUTTON_ADDTAB));
SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
ImplInitSettings( true, true );
}
@@ -753,6 +739,18 @@ sal_uInt16 TabBar::ImplGetLastFirstPos()
return nLastFirstPos;
}
IMPL_LINK(TabBar, ContextMenuHdl, const CommandEvent&, rCommandEvent, void)
{
maScrollAreaContextHdl.Call(rCommandEvent);
}
IMPL_LINK(TabBar, MousePressHdl, const MouseEvent&, rMouseEvent, bool)
{
if (rMouseEvent.IsRight())
ContextMenuHdl(CommandEvent(rMouseEvent.GetPosPixel(), CommandEventId::ContextMenu, true));
return false;
}
void TabBar::ImplInitControls()
{
if (mnWinStyle & WB_SIZEABLE)
@@ -768,65 +766,43 @@ void TabBar::ImplInitControls()
mpImpl->mpSizer.disposeAndClear();
}
if ((mnWinStyle & WB_INSERTTAB) && !mpImpl->mpAddButton)
mpImpl->mxButtonBox.disposeAndReset(VclPtr<TabButtons>::Create(this));
Link<const CommandEvent&, void> aContextLink = LINK( this, TabBar, ContextMenuHdl );
if (mnWinStyle & WB_INSERTTAB)
{
Link<Button*,void> aLink = LINK(this, TabBar, ImplAddClickHandler);
mpImpl->mpAddButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this, WB_REPEAT));
mpImpl->mpAddButton->SetClickHdl(aLink);
mpImpl->mpAddButton->SetSymbol(SymbolType::PLUS);
mpImpl->mpAddButton->Show();
Link<weld::Button&,void> aLink = LINK(this, TabBar, ImplAddClickHandler);
mpImpl->mxButtonBox->m_xAddRepeater.reset(new weld::ButtonPressRepeater(
*mpImpl->mxButtonBox->m_xAddButton, aLink, aContextLink));
mpImpl->mxButtonBox->m_xAddButton->show();
}
Link<Button*,void> aLink = LINK( this, TabBar, ImplClickHdl );
Link<weld::Button&,void> aLink = LINK( this, TabBar, ImplClickHdl );
if (mnWinStyle & (WB_MINSCROLL | WB_SCROLL))
{
if (!mpImpl->mpPrevButton)
{
mpImpl->mpPrevButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this, WB_REPEAT));
mpImpl->mpPrevButton->SetClickHdl(aLink);
}
mpImpl->mpPrevButton->SetSymbol(mbMirrored ? SymbolType::NEXT : SymbolType::PREV);
mpImpl->mpPrevButton->Show();
if (!mpImpl->mpNextButton)
{
mpImpl->mpNextButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this, WB_REPEAT));
mpImpl->mpNextButton->SetClickHdl(aLink);
}
mpImpl->mpNextButton->SetSymbol(mbMirrored ? SymbolType::PREV : SymbolType::NEXT);
mpImpl->mpNextButton->Show();
}
else
{
mpImpl->mpPrevButton.disposeAndClear();
mpImpl->mpNextButton.disposeAndClear();
mpImpl->mxButtonBox->m_xPrevRepeater.reset(new weld::ButtonPressRepeater(
*mpImpl->mxButtonBox->m_xPrevButton, aLink, aContextLink));
mpImpl->mxButtonBox->m_xPrevButton->show();
mpImpl->mxButtonBox->m_xNextRepeater.reset(new weld::ButtonPressRepeater(
*mpImpl->mxButtonBox->m_xNextButton, aLink, aContextLink));
mpImpl->mxButtonBox->m_xNextButton->show();
}
if (mnWinStyle & WB_SCROLL)
{
if (!mpImpl->mpFirstButton)
{
mpImpl->mpFirstButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this));
mpImpl->mpFirstButton->SetClickHdl(aLink);
}
mpImpl->mpFirstButton->SetSymbol(mbMirrored ? SymbolType::LAST : SymbolType::FIRST);
mpImpl->mpFirstButton->Show();
Link<const MouseEvent&, bool> aBtnContextLink = LINK(this, TabBar, MousePressHdl);
if (!mpImpl->mpLastButton)
{
mpImpl->mpLastButton.disposeAndReset(VclPtr<ImplTabButton>::Create(this));
mpImpl->mpLastButton->SetClickHdl(aLink);
}
mpImpl->mpLastButton->SetSymbol(mbMirrored ? SymbolType::FIRST : SymbolType::LAST);
mpImpl->mpLastButton->Show();
mpImpl->mxButtonBox->m_xFirstButton->connect_clicked(aLink);
mpImpl->mxButtonBox->m_xFirstButton->connect_mouse_press(aBtnContextLink);
mpImpl->mxButtonBox->m_xFirstButton->show();
mpImpl->mxButtonBox->m_xLastButton->connect_clicked(aLink);
mpImpl->mxButtonBox->m_xLastButton->connect_mouse_press(aBtnContextLink);
mpImpl->mxButtonBox->m_xLastButton->show();
}
else
{
mpImpl->mpFirstButton.disposeAndClear();
mpImpl->mpLastButton.disposeAndClear();
}
mpImpl->mxButtonBox->Show();
}
void TabBar::ImplEnableControls()
@@ -836,16 +812,15 @@ void TabBar::ImplEnableControls()
// enable/disable buttons
bool bEnableBtn = mbScrollAlwaysEnabled || mnFirstPos > 0;
if (mpImpl->mpFirstButton)
mpImpl->mpFirstButton->Enable(bEnableBtn);
if (mpImpl->mpPrevButton)
mpImpl->mpPrevButton->Enable(bEnableBtn);
mpImpl->mxButtonBox->m_xFirstButton->set_sensitive(bEnableBtn);
mpImpl->mxButtonBox->m_xPrevButton->set_sensitive(bEnableBtn);
if (!bEnableBtn && mpImpl->mxButtonBox->m_xPrevRepeater)
mpImpl->mxButtonBox->m_xPrevRepeater->Stop();
bEnableBtn = mbScrollAlwaysEnabled || mnFirstPos < ImplGetLastFirstPos();
if (mpImpl->mpNextButton)
mpImpl->mpNextButton->Enable(bEnableBtn);
if (mpImpl->mpLastButton)
mpImpl->mpLastButton->Enable(bEnableBtn);
mpImpl->mxButtonBox->m_xLastButton->set_sensitive(bEnableBtn);
mpImpl->mxButtonBox->m_xNextButton->set_sensitive(bEnableBtn);
if (!bEnableBtn && mpImpl->mxButtonBox->m_xNextRepeater)
mpImpl->mxButtonBox->m_xNextRepeater->Stop();
}
void TabBar::SetScrollAlwaysEnabled(bool bScrollAlwaysEnabled)
@@ -878,29 +853,30 @@ void TabBar::ImplShowPage( sal_uInt16 nPos )
}
}
IMPL_LINK( TabBar, ImplClickHdl, Button*, pButton, void )
IMPL_LINK( TabBar, ImplClickHdl, weld::Button&, rBtn, void )
{
ImplTabButton* pBtn = static_cast<ImplTabButton*>(pButton);
EndEditMode();
sal_uInt16 nNewPos = mnFirstPos;
if (pBtn == mpImpl->mpFirstButton.get() || (pBtn == mpImpl->mpPrevButton.get() && pBtn->isModKeyPressed()))
if (&rBtn == mpImpl->mxButtonBox->m_xFirstButton.get() || (&rBtn == mpImpl->mxButtonBox->m_xPrevButton.get() &&
mpImpl->mxButtonBox->m_xPrevRepeater->IsModKeyPressed()))
{
nNewPos = 0;
}
else if (pBtn == mpImpl->mpLastButton.get() || (pBtn == mpImpl->mpNextButton.get() && pBtn->isModKeyPressed()))
else if (&rBtn == mpImpl->mxButtonBox->m_xLastButton.get() || (&rBtn == mpImpl->mxButtonBox->m_xNextButton.get() &&
mpImpl->mxButtonBox->m_xNextRepeater->IsModKeyPressed()))
{
sal_uInt16 nCount = GetPageCount();
if (nCount)
nNewPos = nCount - 1;
}
else if (pBtn == mpImpl->mpPrevButton.get())
else if (&rBtn == mpImpl->mxButtonBox->m_xPrevButton.get())
{
if (mnFirstPos)
nNewPos = mnFirstPos - 1;
}
else if (pBtn == mpImpl->mpNextButton.get())
else if (&rBtn == mpImpl->mxButtonBox->m_xNextButton.get())
{
sal_uInt16 nCount = GetPageCount();
if (mnFirstPos < nCount)
@@ -915,8 +891,9 @@ IMPL_LINK( TabBar, ImplClickHdl, Button*, pButton, void )
SetFirstPageId(GetPageId(nNewPos));
}
IMPL_LINK_NOARG(TabBar, ImplAddClickHandler, Button*, void)
IMPL_LINK_NOARG(TabBar, ImplAddClickHandler, weld::Button&, void)
{
EndEditMode();
AddTabClick();
}
@@ -1242,7 +1219,6 @@ void TabBar::Resize()
Size aNewSize = GetOutputSizePixel();
tools::Long nSizerWidth = 0;
tools::Long nButtonWidth = 0;
// order the Sizer
if ( mpImpl->mpSizer )
@@ -1259,35 +1235,11 @@ void TabBar::Resize()
// adapt font height?
ImplInitSettings( true, false );
tools::Long nButtonMargin = BUTTON_MARGIN * GetDPIScaleFactor();
tools::Long nX = mbMirrored ? (aNewSize.Width() - nHeight - nButtonMargin) : nButtonMargin;
tools::Long const nXDiff = mbMirrored ? -nHeight : nHeight;
nButtonWidth += nButtonMargin;
Size const aBtnSize( nHeight, nHeight );
auto setButton = [aBtnSize, nXDiff, nHeight, &nX, &nButtonWidth](
ScopedVclPtr<ImplTabButton> const & button)
{
if (button) {
button->SetPosSizePixel(Point(nX, 0), aBtnSize);
nX += nXDiff;
nButtonWidth += nHeight;
}
};
setButton(mpImpl->mpFirstButton);
setButton(mpImpl->mpPrevButton);
setButton(mpImpl->mpNextButton);
setButton(mpImpl->mpLastButton);
nButtonWidth += nButtonMargin;
nX += mbMirrored ? -nButtonMargin : nButtonMargin;
setButton(mpImpl->mpAddButton);
nButtonWidth += nButtonMargin;
mpImpl->mxButtonBox->AdaptToHeight(nHeight);
Size const aBtnsSize(mpImpl->mxButtonBox->get_preferred_size().Width(), nHeight);
Point aPos(mbMirrored ? (aNewSize.Width() - aBtnsSize.Width()) : 0, 0);
mpImpl->mxButtonBox->SetPosSizePixel(aPos, aBtnsSize);
auto nButtonWidth = aBtnsSize.Width();
// store size
maWinSize = aNewSize;
@@ -1433,23 +1385,22 @@ void TabBar::StateChanged(StateChangedType nType)
}
else if (nType == StateChangedType::Mirroring)
{
bool bIsRTLEnabled = IsRTLEnabled();
// reacts on calls of EnableRTL, have to mirror all child controls
if (mpImpl->mpFirstButton)
mpImpl->mpFirstButton->EnableRTL(IsRTLEnabled());
if (mpImpl->mpPrevButton)
mpImpl->mpPrevButton->EnableRTL(IsRTLEnabled());
if (mpImpl->mpNextButton)
mpImpl->mpNextButton->EnableRTL(IsRTLEnabled());
if (mpImpl->mpLastButton)
mpImpl->mpLastButton->EnableRTL(IsRTLEnabled());
if (mpImpl->mpSizer)
mpImpl->mpSizer->EnableRTL(IsRTLEnabled());
if (mpImpl->mpAddButton)
mpImpl->mpAddButton->EnableRTL(IsRTLEnabled());
mpImpl->mpSizer->EnableRTL(bIsRTLEnabled);
if (mpImpl->mxButtonBox)
{
mpImpl->mxButtonBox->m_xFirstButton->set_direction(bIsRTLEnabled);
mpImpl->mxButtonBox->m_xPrevButton->set_direction(bIsRTLEnabled);
mpImpl->mxButtonBox->m_xNextButton->set_direction(bIsRTLEnabled);
mpImpl->mxButtonBox->m_xLastButton->set_direction(bIsRTLEnabled);
mpImpl->mxButtonBox->m_xAddButton->set_direction(bIsRTLEnabled);
}
if (mpImpl->mxEdit)
{
weld::Entry& rEntry = mpImpl->mxEdit->get_widget();
rEntry.set_direction(IsRTLEnabled());
rEntry.set_direction(bIsRTLEnabled);
}
}
}
@@ -2491,6 +2442,8 @@ void TabBar::EndSwitchPage()
void TabBar::SetStyle(WinBits nStyle)
{
if (mnWinStyle == nStyle)
return;
mnWinStyle = nStyle;
ImplInitControls();
// order possible controls
diff --git a/svtools/uiconfig/ui/tabbuttons.ui b/svtools/uiconfig/ui/tabbuttons.ui
new file mode 100644
index 0000000..ae6c6fa
--- /dev/null
+++ b/svtools/uiconfig/ui/tabbuttons.ui
@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.1 -->
<interface domain="svt">
<requires lib="gtk+" version="3.20"/>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-new</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-media-previous</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-media-next</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-goto-first</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="image5">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-goto-last</property>
<property name="icon_size">1</property>
</object>
<object class="GtkBox" id="TabButtons">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-left">6</property>
<property name="margin-right">6</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child>
<object class="GtkButton" id="first">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="image">image4</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="prev">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="image">image2</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="next">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="image">image3</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="last">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="image">image5</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="add">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="margin-left">6</property>
<property name="image">image1</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
</interface>
diff --git a/svtools/uiconfig/ui/tabbuttonsmirrored.ui b/svtools/uiconfig/ui/tabbuttonsmirrored.ui
new file mode 100644
index 0000000..abec1f5
--- /dev/null
+++ b/svtools/uiconfig/ui/tabbuttonsmirrored.ui
@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.1 -->
<interface domain="svt">
<requires lib="gtk+" version="3.20"/>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-new</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-media-previous</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-media-next</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-goto-first</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="image5">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-goto-last</property>
<property name="icon_size">1</property>
</object>
<object class="GtkBox" id="TabButtons">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-left">6</property>
<property name="margin-right">6</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child>
<object class="GtkButton" id="add">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="margin-right">6</property>
<property name="image">image1</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="last">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="image">image4</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="next">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="image">image2</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="prev">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="image">image3</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="first">
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="no-show-all">True</property>
<property name="image">image5</property>
<property name="relief">none</property>
<property name="always-show-image">True</property>
<style>
<class name="small-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
</interface>
diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx
index 76e887c..8372204 100644
--- a/vcl/source/app/weldutils.cxx
+++ b/vcl/source/app/weldutils.cxx
@@ -13,6 +13,7 @@
#include <svl/zforlist.hxx>
#include <svl/zformat.hxx>
#include <vcl/builderpage.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/commandinfoprovider.hxx>
#include <vcl/event.hxx>
#include <vcl/settings.hxx>
@@ -548,9 +549,11 @@ void WidgetStatusListener::dispose()
mWidget = nullptr;
}
ButtonPressRepeater::ButtonPressRepeater(weld::Button& rButton, const Link<Button&, void>& rLink)
ButtonPressRepeater::ButtonPressRepeater(weld::Button& rButton, const Link<Button&, void>& rLink,
const Link<const CommandEvent&, void>& rContextLink)
: m_rButton(rButton)
, m_aLink(rLink)
, m_aContextLink(rContextLink)
, m_bModKey(false)
{
// instead of connect_clicked because we want a button held down to
@@ -563,6 +566,12 @@ ButtonPressRepeater::ButtonPressRepeater(weld::Button& rButton, const Link<Butto
IMPL_LINK(ButtonPressRepeater, MousePressHdl, const MouseEvent&, rMouseEvent, bool)
{
if (rMouseEvent.IsRight())
{
m_aContextLink.Call(
CommandEvent(rMouseEvent.GetPosPixel(), CommandEventId::ContextMenu, true));
return false;
}
m_bModKey = rMouseEvent.IsMod1();
if (!m_rButton.get_sensitive())
return false;