summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-02-13 17:41:03 +0000
committerCaolán McNamara <caolanm@redhat.com>2018-02-16 00:35:34 +0100
commit6a3f9de585fc0e8e6191db5210729ae6b3730e7d (patch)
tree5d053ebe13d08608812c2321dd60a6c9c23ffc70
parent7faa218231b7a807412feada3aa1223b43b5626e (diff)
native dialog initial basis
Change-Id: I392be563e38257390f748c70bb71c67a66778ddd Reviewed-on: https://gerrit.libreoffice.org/49677 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--desktop/source/app/app.cxx4
-rw-r--r--framework/source/jobs/helponstartup.cxx2
-rw-r--r--include/sfx2/sfxhelp.hxx2
-rw-r--r--include/vcl/field.hxx4
-rw-r--r--include/vcl/help.hxx7
-rw-r--r--include/vcl/layout.hxx28
-rw-r--r--include/vcl/lstbox.hxx2
-rw-r--r--include/vcl/svapp.hxx11
-rw-r--r--include/vcl/weld.hxx495
-rw-r--r--include/vcl/window.hxx3
-rw-r--r--sfx2/source/appl/appserv.cxx2
-rw-r--r--sfx2/source/appl/sfxhelp.cxx200
-rw-r--r--sw/inc/swabstdlg.hxx2
-rw-r--r--sw/source/ui/chrdlg/break.cxx168
-rw-r--r--sw/source/ui/dialog/swdlgfact.cxx17
-rw-r--r--sw/source/ui/dialog/swdlgfact.hxx13
-rw-r--r--sw/source/uibase/inc/break.hxx51
-rw-r--r--sw/source/uibase/inc/uitool.hxx2
-rw-r--r--sw/source/uibase/shells/textsh1.cxx7
-rw-r--r--sw/source/uibase/utlui/uitool.cxx14
-rw-r--r--sw/uiconfig/swriter/ui/insertbreak.ui1
-rw-r--r--vcl/inc/salframe.hxx6
-rw-r--r--vcl/inc/salinst.hxx11
-rw-r--r--vcl/inc/unx/gtk/gtkframe.hxx1
-rw-r--r--vcl/inc/unx/gtk/gtkinst.hxx2
-rw-r--r--vcl/source/app/help.cxx5
-rw-r--r--vcl/source/app/salvtables.cxx1085
-rw-r--r--vcl/source/control/combobox.cxx2
-rw-r--r--vcl/source/control/field.cxx14
-rw-r--r--vcl/source/control/listbox.cxx5
-rw-r--r--vcl/source/window/builder.cxx116
-rw-r--r--vcl/source/window/menuwindow.cxx4
-rw-r--r--vcl/source/window/window2.cxx6
-rw-r--r--vcl/unx/gtk3/gtk3gtkframe.cxx2
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx1572
35 files changed, 3699 insertions, 167 deletions
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index d00adb195ac0..936671f07e58 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -1995,7 +1995,7 @@ void Desktop::OpenClients()
#elif defined WNT
aHelpURL += "&System=WIN";
#endif
- Application::GetHelp()->Start(aHelpURL, nullptr);
+ Application::GetHelp()->Start(aHelpURL, static_cast<const vcl::Window*>(nullptr));
return;
}
}
@@ -2361,7 +2361,7 @@ void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
break;
case ApplicationEvent::Type::OpenHelpUrl:
// start help for a specific URL
- Application::GetHelp()->Start(rAppEvent.GetStringData(), nullptr);
+ Application::GetHelp()->Start(rAppEvent.GetStringData(), static_cast<vcl::Window*>(nullptr));
break;
case ApplicationEvent::Type::Print:
{
diff --git a/framework/source/jobs/helponstartup.cxx b/framework/source/jobs/helponstartup.cxx
index ebabadf6fd7b..67f670f31e3e 100644
--- a/framework/source/jobs/helponstartup.cxx
+++ b/framework/source/jobs/helponstartup.cxx
@@ -139,7 +139,7 @@ css::uno::Any SAL_CALL HelpOnStartup::execute(const css::uno::Sequence< css::bea
// Note: The help window brings itself to front ...
Help* pHelp = Application::GetHelp();
if (pHelp)
- pHelp->Start(sModuleDependentHelpURL, nullptr);
+ pHelp->Start(sModuleDependentHelpURL, static_cast<vcl::Window*>(nullptr));
}
}
diff --git a/include/sfx2/sfxhelp.hxx b/include/sfx2/sfxhelp.hxx
index fb2eeac49707..d9b41b6544f7 100644
--- a/include/sfx2/sfxhelp.hxx
+++ b/include/sfx2/sfxhelp.hxx
@@ -34,8 +34,10 @@ class SFX2_DLLPUBLIC SfxHelp : public Help
private:
SAL_DLLPRIVATE static bool Start_Impl( const OUString& rURL, const vcl::Window* pWindow, const OUString& rKeyword );
+ SAL_DLLPRIVATE static bool Start_Impl(const OUString& rURL, weld::Widget* pWidget, const OUString& rKeyword);
SAL_DLLPRIVATE virtual void SearchKeyword( const OUString& rKeyWord ) override;
SAL_DLLPRIVATE virtual bool Start( const OUString& rURL, const vcl::Window* pWindow ) override;
+ SAL_DLLPRIVATE virtual bool Start(const OUString& rURL, weld::Widget* pWidget) override;
SAL_DLLPRIVATE static OUString GetHelpModuleName_Impl(const OUString &rHelpId);
SAL_DLLPRIVATE static OUString CreateHelpURL_Impl( const OUString& aCommandURL, const OUString& rModuleName );
diff --git a/include/vcl/field.hxx b/include/vcl/field.hxx
index be973f6d8bdf..0380259acf01 100644
--- a/include/vcl/field.hxx
+++ b/include/vcl/field.hxx
@@ -40,6 +40,7 @@ class VCL_DLLPUBLIC FormatterBase
{
private:
VclPtr<Edit> mpField;
+ Link<Edit&, bool> maOutputHdl;
std::unique_ptr<LocaleDataWrapper>
mpLocaleDataWrapper;
bool mbReformat;
@@ -84,8 +85,9 @@ public:
void EnableEmptyFieldValue( bool bEnable ) { mbEmptyFieldValueEnabled = bEnable; }
bool IsEmptyFieldValueEnabled() const { return mbEmptyFieldValueEnabled; }
-};
+ void SetOutputHdl(const Link<Edit&, bool>& rLink) { maOutputHdl = rLink; }
+};
#define PATTERN_FORMAT_EMPTYLITERALS (sal_uInt16(0x0001))
diff --git a/include/vcl/help.hxx b/include/vcl/help.hxx
index ee51fe40014f..47fcb0264623 100644
--- a/include/vcl/help.hxx
+++ b/include/vcl/help.hxx
@@ -55,6 +55,10 @@ namespace o3tl
#define OOO_HELP_INDEX ".help:index"
+namespace weld
+{
+ class Widget;
+}
class VCL_DLLPUBLIC Help
{
@@ -62,7 +66,8 @@ public:
Help();
virtual ~Help();
- virtual bool Start( const OUString& rHelpId, const vcl::Window* pWindow );
+ virtual bool Start(const OUString& rHelpId, const vcl::Window* pWindow);
+ virtual bool Start(const OUString& rHelpId, weld::Widget* pWidget);
virtual void SearchKeyword( const OUString& rKeyWord );
virtual OUString GetHelpText( const OUString& aHelpURL, const vcl::Window* pWindow );
diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx
index d73fa7166ce2..ca60679d346c 100644
--- a/include/vcl/layout.hxx
+++ b/include/vcl/layout.hxx
@@ -654,6 +654,34 @@ public:
VclMultiLineEdit *pSecondaryMessage);
};
+class VCL_DLLPUBLIC VclDrawingArea : public vcl::Window
+{
+private:
+ Link<vcl::RenderContext&, void> m_aPaintHdl;
+ Link<const Size&, void> m_aResizeHdl;
+public:
+ VclDrawingArea(vcl::Window *pParent, WinBits nStyle)
+ : vcl::Window(pParent, nStyle)
+ {
+ }
+ void SetPaintHdl(const Link<vcl::RenderContext&, void>& rLink)
+ {
+ m_aPaintHdl = rLink;
+ }
+ void SetResizeHdl(const Link<const Size&, void>& rLink)
+ {
+ m_aResizeHdl = rLink;
+ }
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/) override
+ {
+ m_aPaintHdl.Call(rRenderContext);
+ }
+ virtual void Resize() override
+ {
+ m_aResizeHdl.Call(GetOutputSizePixel());
+ }
+};
+
//Get first window of a pTopLevel window as
//if any intermediate layout widgets didn't exist
//i.e. acts like pChild = pChild->GetWindow(GetWindowType::FirstChild);
diff --git a/include/vcl/lstbox.hxx b/include/vcl/lstbox.hxx
index 9509ac0d25ae..5c8c6d29938e 100644
--- a/include/vcl/lstbox.hxx
+++ b/include/vcl/lstbox.hxx
@@ -139,6 +139,8 @@ public:
tools::Rectangle GetDropDownPosSizePixel() const;
+ long CalcWindowSizePixel(sal_uInt16 nLines) const;
+
void AdaptDropDownLineCountToMaximum();
void SetDropDownLineCount( sal_uInt16 nLines );
sal_uInt16 GetDropDownLineCount() const;
diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx
index f68173fe340c..29b8f2c258b3 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -47,6 +47,13 @@
class BitmapEx;
+namespace weld
+{
+ class Builder;
+ class Container;
+ class MessageDialog;
+ class Widget;
+}
class AllSettings;
class DataChangedEvent;
class Accelerator;
@@ -1384,6 +1391,10 @@ public:
// For vclbootstrapprotector:
static void setDeInitHook(Link<LinkParamNone*,void> const & hook);
+ static weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString &rUIFile);
+
+ static weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
+ VclButtonsType eButtonType, const OUString& rPrimaryMessage);
private:
DECL_STATIC_LINK( Application, PostEventHandler, void*, void );
};
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
new file mode 100644
index 000000000000..6d438633277c
--- /dev/null
+++ b/include/vcl/weld.hxx
@@ -0,0 +1,495 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_VCL_WELD_HXX
+#define INCLUDED_VCL_WELD_HXX
+
+#include <rtl/ustring.hxx>
+#include <tools/gen.hxx>
+#include <tools/link.hxx>
+#include <vcl/dllapi.h>
+#include <vcl/field.hxx>
+#include <vcl/virdev.hxx>
+
+namespace weld
+{
+class VCL_DLLPUBLIC Widget
+{
+public:
+ virtual void set_sensitive(bool sensitive) = 0;
+ virtual bool get_sensitive() const = 0;
+ virtual void set_visible(bool visible) = 0;
+ virtual bool get_visible() const = 0;
+ virtual void grab_focus() = 0;
+ virtual bool has_focus() const = 0;
+ virtual void show() = 0;
+ virtual void hide() = 0;
+ void show(bool bShow)
+ {
+ if (bShow)
+ show();
+ else
+ hide();
+ }
+ virtual void set_size_request(int nWidth, int nHeight) = 0;
+ virtual Size get_preferred_size() const = 0;
+ virtual float approximate_char_width() const = 0;
+ virtual Size get_pixel_size(const OUString& rText) const = 0;
+ virtual OString get_buildable_name() const = 0;
+ virtual OString get_help_id() const = 0;
+ virtual Widget* weld_parent() const = 0;
+
+ virtual ~Widget() {}
+};
+
+class VCL_DLLPUBLIC Container : virtual public Widget
+{
+};
+
+class VCL_DLLPUBLIC Frame : virtual public Container
+{
+public:
+ virtual void set_label(const OUString& rText) = 0;
+ virtual OUString get_label() const = 0;
+};
+
+class VCL_DLLPUBLIC Notebook : virtual public Container
+{
+protected:
+ Link<const OString&, bool> m_aLeavePageHdl;
+ Link<const OString&, void> m_aEnterPageHdl;
+
+public:
+ virtual int get_current_page() const = 0;
+ virtual OString get_current_page_ident() const = 0;
+ virtual void set_current_page(int nPage) = 0;
+ virtual void set_current_page(const OString& rIdent) = 0;
+ virtual int get_n_pages() const = 0;
+ virtual weld::Container* get_page(const OString& rIdent) const = 0;
+
+ void connect_leave_page(const Link<const OString&, bool>& rLink) { m_aLeavePageHdl = rLink; }
+
+ void connect_enter_page(const Link<const OString&, void>& rLink) { m_aEnterPageHdl = rLink; }
+};
+
+class VCL_DLLPUBLIC Window : virtual public Container
+{
+protected:
+ Link<Widget&, bool> m_aHelpRequestHdl;
+
+public:
+ virtual void set_title(const OUString& rTitle) = 0;
+ virtual OUString get_title() const = 0;
+
+ void connect_help(const Link<Widget&, bool>& rLink) { m_aHelpRequestHdl = rLink; }
+};
+
+class VCL_DLLPUBLIC Dialog : virtual public Window
+{
+public:
+ virtual int run() = 0;
+ virtual void response(int response) = 0;
+};
+
+class VCL_DLLPUBLIC MessageDialog : virtual public Dialog
+{
+public:
+ virtual void set_primary_text(const OUString& rText) = 0;
+ virtual OUString get_primary_text() const = 0;
+ virtual void set_secondary_text(const OUString& rText) = 0;
+ virtual OUString get_secondary_text() const = 0;
+};
+
+class VCL_DLLPUBLIC ComboBoxText : virtual public Container
+{
+private:
+ OUString m_sSavedValue;
+
+protected:
+ Link<ComboBoxText&, void> m_aChangeHdl;
+
+ void signal_changed() { m_aChangeHdl.Call(*this); }
+
+public:
+ virtual int get_active() const = 0;
+ virtual void set_active(int pos) = 0;
+ virtual OUString get_active_text() const = 0;
+ virtual OUString get_active_id() const = 0;
+ virtual void set_active_id(const OUString& rStr) = 0;
+ virtual OUString get_text(int pos) const = 0;
+ virtual OUString get_id(int pos) const = 0;
+ virtual void append_text(const OUString& rStr) = 0;
+ virtual void insert_text(int pos, const OUString& rStr) = 0;
+ virtual void append(const OUString& rId, const OUString& rStr) = 0;
+ virtual void insert(int pos, const OUString& rId, const OUString& rStr) = 0;
+ virtual int find_text(const OUString& rStr) const = 0;
+ virtual int get_count() const = 0;
+ virtual void make_sorted() = 0;
+ virtual void clear() = 0;
+
+ void connect_changed(const Link<ComboBoxText&, void>& rLink) { m_aChangeHdl = rLink; }
+
+ void set_active(const OUString& rStr) { set_active(find_text(rStr)); }
+
+ void save_value() { m_sSavedValue = get_active_text(); }
+
+ bool get_value_changed_from_saved() const { return m_sSavedValue != get_active_text(); }
+};
+
+class VCL_DLLPUBLIC TreeView : virtual public Container
+{
+protected:
+ Link<TreeView&, void> m_aChangeHdl;
+ Link<TreeView&, void> m_aRowActivatedHdl;
+
+ void signal_changed() { m_aChangeHdl.Call(*this); }
+
+ void signal_row_activated() { m_aRowActivatedHdl.Call(*this); }
+
+public:
+ virtual void append(const OUString& rText) = 0;
+ virtual void insert(const OUString& rText, int pos) = 0;
+ virtual int n_children() const = 0;
+ virtual void select(int pos) = 0;
+ virtual void remove(int pos) = 0;
+ virtual int find(const OUString& rText) const = 0;
+ virtual void set_top_entry(int pos) = 0;
+ virtual void clear() = 0;
+ virtual OUString get_selected() = 0;
+ virtual int get_selected_index() = 0;
+ virtual OUString get(int pos) = 0;
+ virtual int get_height_rows(int nRows) const = 0;
+
+ virtual void freeze() = 0;
+ virtual void thaw() = 0;
+
+ void connect_changed(const Link<TreeView&, void>& rLink) { m_aChangeHdl = rLink; }
+
+ void connect_row_activated(const Link<TreeView&, void>& rLink) { m_aRowActivatedHdl = rLink; }
+
+ void select(const OUString& rText) { select(find(rText)); }
+
+ void remove(const OUString& rText) { remove(find(rText)); }
+};
+
+class VCL_DLLPUBLIC Button : virtual public Container
+{
+protected:
+ Link<Button&, void> m_aClickHdl;
+
+ void signal_clicked() { m_aClickHdl.Call(*this); }
+
+public:
+ virtual void set_label(const OUString& rText) = 0;
+ virtual OUString get_label() const = 0;
+
+ void connect_clicked(const Link<Button&, void>& rLink) { m_aClickHdl = rLink; }
+};
+
+class VCL_DLLPUBLIC ToggleButton : virtual public Button
+{
+protected:
+ Link<ToggleButton&, void> m_aToggleHdl;
+ TriState m_eSavedValue = TRISTATE_FALSE;
+
+ void signal_toggled() { m_aToggleHdl.Call(*this); }
+
+public:
+ virtual void set_active(bool active) = 0;
+ virtual bool get_active() const = 0;
+
+ virtual void set_inconsistent(bool inconsistent) = 0;
+ virtual bool get_inconsistent() const = 0;
+
+ TriState get_state() const
+ {
+ if (get_inconsistent())
+ return TRISTATE_INDET;
+ else if (get_active())
+ return TRISTATE_TRUE;
+ return TRISTATE_FALSE;
+ }
+
+ void save_state() { m_eSavedValue = get_state(); }
+
+ TriState get_saved_state() const { return m_eSavedValue; }
+
+ void set_state(TriState eState)
+ {
+ switch (eState)
+ {
+ case TRISTATE_INDET:
+ set_inconsistent(true);
+ break;
+ case TRISTATE_TRUE:
+ set_inconsistent(false);
+ set_active(true);
+ break;
+ case TRISTATE_FALSE:
+ set_inconsistent(false);
+ set_active(false);
+ break;
+ }
+ }
+
+ bool get_state_changed_from_saved() const { return m_eSavedValue != get_state(); }
+
+ void connect_toggled(const Link<ToggleButton&, void>& rLink) { m_aToggleHdl = rLink; }
+};
+
+class VCL_DLLPUBLIC CheckButton : virtual public ToggleButton
+{
+};
+
+class VCL_DLLPUBLIC RadioButton : virtual public ToggleButton
+{
+};
+
+class VCL_DLLPUBLIC Entry : virtual public Widget
+{
+private:
+ OUString m_sSavedValue;
+
+protected:
+ Link<Entry&, void> m_aChangeHdl;
+ Link<OUString&, bool> m_aInsertTextHdl;
+
+ void signal_changed() { m_aChangeHdl.Call(*this); }
+
+ void signal_insert_text(OUString& rString);
+
+public:
+ virtual void set_text(const OUString& rText) = 0;
+ virtual OUString get_text() const = 0;
+ virtual void set_width_chars(int nChars) = 0;
+
+ void connect_changed(const Link<Entry&, void>& rLink) { m_aChangeHdl = rLink; }
+
+ void connect_insert_text(const Link<OUString&, bool>& rLink) { m_aInsertTextHdl = rLink; }
+
+ void save_value() { m_sSavedValue = get_text(); }
+
+ bool get_value_changed_from_saved() const { return m_sSavedValue != get_text(); }
+};
+
+class VCL_DLLPUBLIC SpinButton : virtual public Entry
+{
+protected:
+ Link<SpinButton&, void> m_aValueChangedHdl;
+ Link<SpinButton&, void> m_aOutputHdl;
+
+ void signal_value_changed() { m_aValueChangedHdl.Call(*this); }
+
+ bool signal_output()
+ {
+ if (!m_aOutputHdl.IsSet())
+ return false;
+ m_aOutputHdl.Call(*this);
+ return true;
+ }
+
+public:
+ virtual void set_value(int value) = 0;
+ virtual int get_value() const = 0;
+ virtual void set_range(int min, int max) = 0;
+ virtual void get_range(int& min, int& max) const = 0;
+ virtual void set_increments(int step, int page) = 0;
+ virtual void get_increments(int& step, int& page) const = 0;
+ virtual void set_digits(unsigned int digits) = 0;
+ virtual unsigned int get_digits() const = 0;
+
+ void connect_value_changed(const Link<SpinButton&, void>& rLink) { m_aValueChangedHdl = rLink; }
+
+ void connect_output(const Link<SpinButton&, void>& rLink) { m_aOutputHdl = rLink; }
+
+ int normalize(int nValue) const { return (nValue * Power10(get_digits())); }
+
+ int denormalize(int nValue) const;
+
+ static unsigned int Power10(unsigned int n);
+};
+
+class VCL_DLLPUBLIC MetricSpinButton
+{
+protected:
+ FieldUnit m_eSrcUnit;
+ std::unique_ptr<weld::SpinButton> m_xSpinButton;
+ Link<MetricSpinButton&, void> m_aValueChangedHdl;
+
+ DECL_LINK(spin_button_value_changed, weld::SpinButton&, void);
+ DECL_LINK(spin_button_output, weld::SpinButton&, void);
+
+ void signal_value_changed() { m_aValueChangedHdl.Call(*this); }
+
+ int ConvertValue(int nValue, FieldUnit eInUnit, FieldUnit eOutUnit) const;
+ OUString format_number(int nValue) const;
+ void update_width_chars();
+
+public:
+ MetricSpinButton(SpinButton* pSpinButton)
+ : m_eSrcUnit(FUNIT_CM)
+ , m_xSpinButton(pSpinButton)
+ {
+ update_width_chars();
+ m_xSpinButton->connect_output(LINK(this, MetricSpinButton, spin_button_output));
+ m_xSpinButton->connect_value_changed(
+ LINK(this, MetricSpinButton, spin_button_value_changed));
+ }
+
+ FieldUnit get_unit() const { return m_eSrcUnit; }
+
+ void set_unit(FieldUnit eUnit)
+ {
+ m_eSrcUnit = eUnit;
+ update_width_chars();
+ }
+
+ void set_value(int nValue, FieldUnit eValueUnit)
+ {
+ m_xSpinButton->set_value(ConvertValue(nValue, eValueUnit, m_eSrcUnit));
+ }
+
+ int get_value(FieldUnit eDestUnit) const
+ {
+ int nValue = m_xSpinButton->get_value();
+ return ConvertValue(nValue, m_eSrcUnit, eDestUnit);
+ }
+
+ void set_range(int min, int max, FieldUnit eValueUnit)
+ {
+ min = ConvertValue(min, eValueUnit, m_eSrcUnit);
+ max = ConvertValue(max, eValueUnit, m_eSrcUnit);
+ m_xSpinButton->set_range(min, max);
+ update_width_chars();
+ }
+
+ void get_range(int& min, int& max, FieldUnit eDestUnit) const
+ {
+ m_xSpinButton->get_range(min, max);
+ min = ConvertValue(min, m_eSrcUnit, eDestUnit);
+ max = ConvertValue(max, m_eSrcUnit, eDestUnit);
+ }
+
+ void set_increments(int step, int page, FieldUnit eValueUnit)
+ {
+ step = ConvertValue(step, eValueUnit, m_eSrcUnit);
+ page = ConvertValue(page, eValueUnit, m_eSrcUnit);
+ m_xSpinButton->set_increments(step, page);
+ }
+
+ void get_increments(int& step, int& page, FieldUnit eDestUnit) const
+ {
+ m_xSpinButton->get_increments(step, page);
+ step = ConvertValue(step, m_eSrcUnit, eDestUnit);
+ page = ConvertValue(page, m_eSrcUnit, eDestUnit);
+ }
+
+ void connect_value_changed(const Link<MetricSpinButton&, void>& rLink)
+ {
+ m_aValueChangedHdl = rLink;
+ }
+
+ int normalize(int nValue) const { return m_xSpinButton->normalize(nValue); }
+ int denormalize(int nValue) const { return m_xSpinButton->denormalize(nValue); }
+ void set_sensitive(bool sensitive) { m_xSpinButton->set_sensitive(sensitive); }
+ bool get_sensitive() const { return m_xSpinButton->get_sensitive(); }
+ bool get_visible() const { return m_xSpinButton->get_visible(); }
+ void grab_focus() { m_xSpinButton->grab_focus(); }
+ bool has_focus() const { return m_xSpinButton->has_focus(); }
+ void show() { m_xSpinButton->show(); }
+ void hide() { m_xSpinButton->hide(); }
+ void set_digits(unsigned int digits) { m_xSpinButton->set_digits(digits); }
+ unsigned int get_digits() const { return m_xSpinButton->get_digits(); }
+ void save_value() { m_xSpinButton->save_value(); }
+ bool get_value_changed_from_saved() const
+ {
+ return m_xSpinButton->get_value_changed_from_saved();
+ }
+ void set_text(const OUString& rText) { m_xSpinButton->set_text(rText); }
+ OUString get_text() const { return m_xSpinButton->get_text(); }
+ void set_size_request(int nWidth, int nHeight)
+ {
+ m_xSpinButton->set_size_request(nWidth, nHeight);
+ }
+ Size get_preferred_size() const { return m_xSpinButton->get_preferred_size(); }
+};
+
+class VCL_DLLPUBLIC Label : virtual public Widget
+{
+public:
+ virtual void set_label(const OUString& rText) = 0;
+};
+
+class VCL_DLLPUBLIC TextView : virtual public Container
+{
+public:
+ virtual void set_text(const OUString& rText) = 0;
+ virtual OUString get_text() const = 0;
+ virtual Selection get_selection() const = 0;
+ virtual void set_selection(const Selection&) = 0;
+};
+
+class VCL_DLLPUBLIC DrawingArea : virtual public Widget
+{
+protected:
+ Link<vcl::RenderContext&, void> m_aDrawHdl;
+ Link<const Size&, void> m_aSizeAllocateHdl;
+
+public:
+ void connect_draw(const Link<vcl::RenderContext&, void>& rLink) { m_aDrawHdl = rLink; }
+ void connect_size_allocate(const Link<const Size&, void>& rLink) { m_aSizeAllocateHdl = rLink; }
+ virtual void queue_draw() = 0;
+};
+
+class VCL_DLLPUBLIC Builder
+{
+private:
+ OString m_sHelpRoot;
+
+public:
+ Builder(const OUString& rUIFile)
+ : m_sHelpRoot(OUStringToOString(rUIFile, RTL_TEXTENCODING_UTF8))
+ {
+ sal_Int32 nIdx = m_sHelpRoot.lastIndexOf('.');
+ if (nIdx != -1)
+ m_sHelpRoot = m_sHelpRoot.copy(0, nIdx);
+ m_sHelpRoot = m_sHelpRoot + OString('/');
+ }
+ virtual MessageDialog* weld_message_dialog(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual Dialog* weld_dialog(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual Window* weld_window(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual Widget* weld_widget(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual Container* weld_container(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual Button* weld_button(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual Frame* weld_frame(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual Notebook* weld_notebook(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual RadioButton* weld_radio_button(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual CheckButton* weld_check_button(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual SpinButton* weld_spin_button(const OString& id, bool bTakeOwnership = false) = 0;
+ MetricSpinButton* weld_metric_spin_button(const OString& id, bool bTakeOwnership = false)
+ {
+ return new MetricSpinButton(weld_spin_button(id, bTakeOwnership));
+ }
+ virtual ComboBoxText* weld_combo_box_text(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual TreeView* weld_tree_view(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual Label* weld_label(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual TextView* weld_text_view(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual Entry* weld_entry(const OString& id, bool bTakeOwnership = false) = 0;
+ virtual DrawingArea* weld_drawing_area(const OString& id, bool bTakeOwnership = false) = 0;
+ OString get_help_id(const Widget& rWidget) const
+ {
+ return m_sHelpRoot + rWidget.get_buildable_name();
+ }
+ virtual ~Builder() {}
+};
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 486ae567c1bc..4c286ba861c7 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -106,6 +106,8 @@ namespace vcl {
namespace svt { class PopupWindowControllerImpl; }
+namespace weld { class Window; }
+
template<class T> class VclPtr;
enum class TrackingEventFlags
@@ -550,6 +552,7 @@ public:
SAL_DLLPRIVATE static void ImplInitAppFontData( vcl::Window const * pWindow );
SAL_DLLPRIVATE vcl::Window* ImplGetFrameWindow() const;
+ weld::Window* GetFrameWeld() const;
SalFrame* ImplGetFrame() const;
SAL_DLLPRIVATE ImplFrameData* ImplGetFrameData();
diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx
index defe7f1fdd2e..e118bbafae24 100644
--- a/sfx2/source/appl/appserv.cxx
+++ b/sfx2/source/appl/appserv.cxx
@@ -541,7 +541,7 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
Help* pHelp = Application::GetHelp();
if ( pHelp )
{
- pHelp->Start( ".uno:HelpIndex", nullptr ); // show start page
+ pHelp->Start(".uno:HelpIndex", static_cast<vcl::Window*>(nullptr)); // show start page
bDone = true;
}
break;
diff --git a/sfx2/source/appl/sfxhelp.cxx b/sfx2/source/appl/sfxhelp.cxx
index 367f4ad68494..9803d63fdb75 100644
--- a/sfx2/source/appl/sfxhelp.cxx
+++ b/sfx2/source/appl/sfxhelp.cxx
@@ -55,6 +55,7 @@
#include <rtl/uri.hxx>
#include <vcl/commandinfoprovider.hxx>
#include <vcl/layout.hxx>
+#include <vcl/weld.hxx>
#include <svtools/ehdl.hxx>
#include <svtools/sfxecode.hxx>
#include <openuriexternally.hxx>
@@ -82,23 +83,48 @@ using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::system;
-class NoHelpErrorBox : public MessageDialog
+namespace old
{
-public:
- explicit NoHelpErrorBox( vcl::Window* _pParent );
+ class NoHelpErrorBox : public MessageDialog
+ {
+ public:
+ explicit NoHelpErrorBox(vcl::Window* _pParent)
+ : MessageDialog(_pParent, SfxResId(RID_STR_HLPFILENOTEXIST))
+ {
+ // Error message: "No help available"
+ }
- virtual void RequestHelp( const HelpEvent& rHEvt ) override;
-};
+ virtual void RequestHelp( const HelpEvent& ) override
+ {
+ // do nothing, because no help available
+ }
+ };
+}
-NoHelpErrorBox::NoHelpErrorBox( vcl::Window* _pParent )
- : MessageDialog(_pParent, SfxResId(RID_STR_HLPFILENOTEXIST))
+class NoHelpErrorBox
{
- // Error message: "No help available"
-}
+private:
+ std::unique_ptr<weld::MessageDialog> m_xErrBox;
+public:
+ DECL_STATIC_LINK(NoHelpErrorBox, HelpRequestHdl, weld::Widget&, bool);
+public:
+ explicit NoHelpErrorBox(weld::Widget* pParent)
+ : m_xErrBox(Application::CreateMessageDialog(pParent, VclMessageType::Error, VclButtonsType::Ok,
+ SfxResId(RID_STR_HLPFILENOTEXIST)))
+ {
+ // Error message: "No help available"
+ m_xErrBox->connect_help(LINK(nullptr, NoHelpErrorBox, HelpRequestHdl));
+ }
+ void run()
+ {
+ m_xErrBox->run();
+ }
+};
-void NoHelpErrorBox::RequestHelp( const HelpEvent& )
+IMPL_STATIC_LINK_NOARG(NoHelpErrorBox, HelpRequestHdl, weld::Widget&, bool)
{
// do nothing, because no help available
+ return false;
}
static OUString HelpLocaleString();
@@ -625,7 +651,7 @@ OUString SfxHelp::GetHelpText( const OUString& aCommandURL, const vcl::Window* p
void SfxHelp::SearchKeyword( const OUString& rKeyword )
{
- Start_Impl( OUString(), nullptr, rKeyword );
+ Start_Impl(OUString(), static_cast<vcl::Window*>(nullptr), rKeyword);
}
bool SfxHelp::Start( const OUString& rURL, const vcl::Window* pWindow )
@@ -633,6 +659,11 @@ bool SfxHelp::Start( const OUString& rURL, const vcl::Window* pWindow )
return Start_Impl( rURL, pWindow, OUString() );
}
+bool SfxHelp::Start(const OUString& rURL, weld::Widget* pWidget)
+{
+ return Start_Impl(rURL, pWidget, OUString());
+}
+
/// Redirect the vnd.sun.star.help:// urls to http://help.libreoffice.org
static bool impl_showOnlineHelp( const OUString& rURL )
{
@@ -709,7 +740,6 @@ static bool impl_showOfflineHelp( const OUString& rURL )
return false;
}
-
bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const OUString& rKeyword)
{
OUStringBuffer aHelpRootURL("vnd.sun.star.help://");
@@ -821,7 +851,7 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const
return true;
else
{
- ScopedVclPtrInstance< NoHelpErrorBox > aErrBox(const_cast< vcl::Window* >( pWindow ));
+ ScopedVclPtrInstance< old::NoHelpErrorBox > aErrBox(const_cast< vcl::Window* >( pWindow ));
aErrBox->Execute();
return false;
}
@@ -865,7 +895,151 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const
xTopWindow->toFront();
return true;
+}
+
+bool SfxHelp::Start_Impl(const OUString& rURL, weld::Widget* pWidget, const OUString& rKeyword)
+{
+ OUStringBuffer aHelpRootURL("vnd.sun.star.help://");
+ AppendConfigToken(aHelpRootURL, true);
+ SfxContentHelper::GetResultSet(aHelpRootURL.makeStringAndClear());
+
+ /* rURL may be
+ * - a "real" URL
+ * - a HelpID (formerly a long, now a string)
+ * If rURL is a URL, CreateHelpURL should be called for this URL
+ * If rURL is an arbitrary string, the same should happen, but the URL should be tried out
+ * if it delivers real help content. In case only the Help Error Document is returned, the
+ * parent of the window for that help was called, is asked for its HelpID.
+ * For compatibility reasons this upward search is not implemented for "real" URLs.
+ * Help keyword search now is implemented as own method; in former versions it
+ * was done via Help::Start, but this implementation conflicted with the upward search.
+ */
+ OUString aHelpURL;
+ INetURLObject aParser( rURL );
+ INetProtocol nProtocol = aParser.GetProtocol();
+
+ switch ( nProtocol )
+ {
+ case INetProtocol::VndSunStarHelp:
+ // already a vnd.sun.star.help URL -> nothing to do
+ aHelpURL = rURL;
+ break;
+ default:
+ {
+ OUString aHelpModuleName(GetHelpModuleName_Impl(rURL));
+ OUString aRealCommand;
+
+ if ( nProtocol == INetProtocol::Uno )
+ // Command can be just an alias to another command.
+ aRealCommand = vcl::CommandInfoProvider::GetRealCommandForCommand( rURL, getCurrentModuleIdentifier_Impl() );
+
+ // no URL, just a HelpID (maybe empty in case of keyword search)
+ aHelpURL = CreateHelpURL_Impl( aRealCommand.isEmpty() ? rURL : aRealCommand, aHelpModuleName );
+
+ if ( impl_hasHelpInstalled() && pWidget && SfxContentHelper::IsHelpErrorDocument( aHelpURL ) )
+ {
+ // no help found -> try with parent help id.
+ std::unique_ptr<weld::Widget> xParent(pWidget->weld_parent());
+ while (xParent)
+ {
+ OString aHelpId = xParent->get_help_id();
+ aHelpURL = CreateHelpURL( OStringToOUString(aHelpId, RTL_TEXTENCODING_UTF8), aHelpModuleName );
+
+ if ( !SfxContentHelper::IsHelpErrorDocument( aHelpURL ) )
+ {
+ break;
+ }
+ else
+ {
+ xParent.reset(xParent->weld_parent());
+ if (!xParent)
+ {
+ // create help url of start page ( helpid == 0 -> start page)
+ aHelpURL = CreateHelpURL( OUString(), aHelpModuleName );
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ if ( comphelper::LibreOfficeKit::isActive() )
+ {
+ impl_showOnlineHelp( aHelpURL );
+ return true;
+ }
+
+ if ( impl_hasHTMLHelpInstalled() )
+ {
+ impl_showOfflineHelp(aHelpURL);
+ return true;
+ }
+
+ if ( !impl_hasHelpInstalled() )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pWidget, "sfx/ui/helpmanual.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("onlinehelpmanual"));
+
+ LanguageTag aLangTag = Application::GetSettings().GetUILanguageTag();
+ OUString sLocaleString = SvtLanguageTable::GetLanguageString( aLangTag.getLanguageType() );
+ OUString sPrimText = xQueryBox->get_primary_text();
+ xQueryBox->set_primary_text(Translate::GetReadStringHook()(sPrimText).replaceAll("$UILOCALE", sLocaleString));
+ xQueryBox->set_title(Translate::GetReadStringHook()(xQueryBox->get_title()));
+ xQueryBox->connect_help(LINK(nullptr, NoHelpErrorBox, HelpRequestHdl));
+ short OnlineHelpBox = xQueryBox->run();
+ xQueryBox->hide();
+ if (OnlineHelpBox == RET_OK)
+ {
+ if (impl_showOnlineHelp( aHelpURL ) )
+ return true;
+ else
+ {
+ NoHelpErrorBox aErrBox(pWidget);
+ aErrBox.run();
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ }
+
+ // old-help to display
+ Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
+
+ // check if help window is still open
+ // If not, create a new one and return access directly to the internal sub frame showing the help content
+ // search must be done here; search one desktop level could return an arbitrary frame
+ Reference< XFrame2 > xHelp(
+ xDesktop->findFrame( "OFFICE_HELP_TASK", FrameSearchFlag::CHILDREN),
+ UNO_QUERY);
+ Reference< XFrame > xHelpContent = xDesktop->findFrame(
+ "OFFICE_HELP",
+ FrameSearchFlag::CHILDREN);
+
+ SfxHelpWindow_Impl* pHelpWindow = nullptr;
+ if (!xHelp.is())
+ pHelpWindow = impl_createHelp(xHelp, xHelpContent);
+ else
+ pHelpWindow = static_cast<SfxHelpWindow_Impl*>(VCLUnoHelper::GetWindow(xHelp->getComponentWindow()).get());
+ if (!xHelp.is() || !xHelpContent.is() || !pHelpWindow)
+ return false;
+
+ SAL_INFO("sfx.appl", "HelpId = " << aHelpURL);
+
+ pHelpWindow->SetHelpURL( aHelpURL );
+ pHelpWindow->loadHelpContent(aHelpURL);
+ if (!rKeyword.isEmpty())
+ pHelpWindow->OpenKeyword( rKeyword );
+
+ Reference < css::awt::XTopWindow > xTopWindow( xHelp->getContainerWindow(), UNO_QUERY );
+ if ( xTopWindow.is() )
+ xTopWindow->toFront();
+
+ return true;
}
OUString SfxHelp::CreateHelpURL(const OUString& aCommandURL, const OUString& rModuleName)
diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx
index 615b40552fb8..f79fa593433c 100644
--- a/sw/inc/swabstdlg.hxx
+++ b/sw/inc/swabstdlg.hxx
@@ -394,7 +394,7 @@ public:
SvStream* pStream ) = 0;
virtual VclPtr<VclAbstractDialog> CreateSwInsertBookmarkDlg( vcl::Window *pParent, SwWrtShell &rSh, SfxRequest& rReq ) = 0;
- virtual VclPtr<AbstractSwBreakDlg> CreateSwBreakDlg(vcl::Window *pParent, SwWrtShell &rSh) = 0;
+ virtual VclPtr<AbstractSwBreakDlg> CreateSwBreakDlg(weld::Window *pParent, SwWrtShell &rSh) = 0;
virtual VclPtr<VclAbstractDialog> CreateSwChangeDBDlg(SwView& rVw) = 0;
virtual VclPtr<SfxAbstractTabDialog> CreateSwCharDlg(vcl::Window* pParent, SwView& pVw, const SfxItemSet& rCoreSet,
SwCharDlgMode nDialogMode, const OUString* pFormatStr = nullptr) = 0;
diff --git a/sw/source/ui/chrdlg/break.cxx b/sw/source/ui/chrdlg/break.cxx
index 0e2386f64dc6..c6b61d34acce 100644
--- a/sw/source/ui/chrdlg/break.cxx
+++ b/sw/source/ui/chrdlg/break.cxx
@@ -36,52 +36,52 @@
#include <strings.hrc>
#include <SwStyleNameMapper.hxx>
-void SwBreakDlg::Apply()
+short SwBreakDlg::Execute()
{
- nKind = 0;
- if(m_pLineBtn->IsChecked())
- nKind = 1;
- else if(m_pColumnBtn->IsChecked())
- nKind = 2;
- else if(m_pPageBtn->IsChecked())
+ short nRet = m_xDialog->run();
+ if (nRet == RET_OK)
{
- nKind = 3;
- const sal_Int32 nPos = m_pPageCollBox->GetSelectedEntryPos();
- if(0 != nPos && LISTBOX_ENTRY_NOTFOUND != nPos)
+ nKind = 0;
+ if (m_xLineBtn->get_active())
+ nKind = 1;
+ else if(m_xColumnBtn->get_active())
+ nKind = 2;
+ else if(m_xPageBtn->get_active())
{
- aTemplate = m_pPageCollBox->GetSelectedEntry();
- oPgNum = boost::none;
- if (m_pPageNumBox->IsChecked())
+ nKind = 3;
+ const int nPos = m_xPageCollBox->get_active();
+ if (nPos != 0 && nPos != -1)
{
- oPgNum = static_cast<sal_uInt16>(m_pPageNumEdit->GetValue());
+ oPgNum = static_cast<sal_uInt16>(m_xPageNumEdit->get_value());
}
}
}
+ return nRet;
}
-IMPL_LINK_NOARG(SwBreakDlg, ClickHdl, Button*, void)
+IMPL_LINK_NOARG(SwBreakDlg, ToggleHdl, weld::ToggleButton&, void)
{
CheckEnable();
}
-IMPL_LINK_NOARG(SwBreakDlg, SelectHdl, ListBox&, void)
+IMPL_LINK_NOARG(SwBreakDlg, ChangeHdl, weld::ComboBoxText&, void)
{
CheckEnable();
}
// Handler for Change Page Number
-IMPL_LINK( SwBreakDlg, PageNumHdl, Button*, pBox, void )
+IMPL_LINK(SwBreakDlg, PageNumHdl, weld::ToggleButton&, rBox, void)
{
- if(static_cast<CheckBox*>(pBox)->IsChecked())
- m_pPageNumEdit->SetValue(1);
+ if (rBox.get_active())
+ m_xPageNumEdit->set_value(1);
else
- m_pPageNumEdit->SetText(OUString());
+ m_xPageNumEdit->set_text(OUString());
}
// By changing the Page number the checkbox is checked.
-IMPL_LINK_NOARG(SwBreakDlg, PageNumModifyHdl, Edit&, void)
+IMPL_LINK_NOARG(SwBreakDlg, PageNumModifyHdl, weld::SpinButton&, void)
{
- m_pPageNumBox->Check();
+ m_xPageNumBox->set_active(true);
}
/*
@@ -89,21 +89,21 @@ IMPL_LINK_NOARG(SwBreakDlg, PageNumModifyHdl, Edit&, void)
* checks whether pagenumber nPage is a legal pagenumber (left pages with even
* numbers etc. for a page template with alternating pages)
*/
-IMPL_LINK_NOARG(SwBreakDlg, OkHdl, Button*, void)
+IMPL_LINK_NOARG(SwBreakDlg, OkHdl, weld::Button&, void)
{
- if(m_pPageNumBox->IsChecked()) {
+ if (m_xPageNumBox->get_active())
+ {
// In case of differing page descriptions, test validity
- const sal_Int32 nPos = m_pPageCollBox->GetSelectedEntryPos();
+ const int nPos = m_xPageCollBox->get_active();
// position 0 says 'Without'.
const SwPageDesc *pPageDesc;
- if ( 0 != nPos && LISTBOX_ENTRY_NOTFOUND != nPos )
- pPageDesc = rSh.FindPageDescByName( m_pPageCollBox->GetSelectedEntry(),
- true );
+ if (nPos != 0 && nPos != -1)
+ pPageDesc = rSh.FindPageDescByName(m_xPageCollBox->get_active_text(), true);
else
pPageDesc = &rSh.GetPageDesc(rSh.GetCurPageDesc());
OSL_ENSURE(pPageDesc, "Page description not found.");
- const sal_uInt16 nUserPage = sal_uInt16(m_pPageNumEdit->GetValue());
+ const sal_uInt16 nUserPage = sal_uInt16(m_xPageNumEdit->get_value());
bool bOk = true;
switch(pPageDesc->GetUseOn())
{
@@ -113,77 +113,65 @@ IMPL_LINK_NOARG(SwBreakDlg, OkHdl, Button*, void)
case UseOnPage::Right: bOk = 1 == nUserPage % 2; break;
default:; //prevent warning
}
- if(!bOk) {
- ScopedVclPtrInstance<MessageDialog>(this, SwResId(STR_ILLEGAL_PAGENUM), VclMessageType::Info)->Execute();
- m_pPageNumEdit->GrabFocus();
+ if(!bOk)
+ {
+ std::unique_ptr<weld::Dialog> xDialog(Application::CreateMessageDialog(m_xPageNumEdit.get(), VclMessageType::Info,
+ VclButtonsType::Ok, SwResId(STR_ILLEGAL_PAGENUM)));
+ xDialog->run();
+ m_xPageNumEdit->grab_focus();
return;
}
}
- EndDialog(RET_OK);
+ m_xDialog->response(RET_OK);
}
-SwBreakDlg::SwBreakDlg( vcl::Window *pParent, SwWrtShell &rS )
- : SvxStandardDialog(pParent, "BreakDialog", "modules/swriter/ui/insertbreak.ui")
- , rSh(rS)
+SwBreakDlg::SwBreakDlg(weld::Window *pParent, SwWrtShell &rS)
+ : rSh(rS)
+ , m_xBuilder(Application::CreateBuilder(pParent, "modules/swriter/ui/insertbreak.ui"))
, nKind(0)
, bHtmlMode(0 != ::GetHtmlMode(rS.GetView().GetDocShell()))
{
- get(m_pLineBtn, "linerb");
- get(m_pColumnBtn, "columnrb");
- get(m_pPageBtn, "pagerb");
- get(m_pPageCollText, "styleft");
- get(m_pPageCollBox, "stylelb");
- get(m_pPageNumBox, "pagenumcb");
- get(m_pPageNumEdit, "pagenumsb");
-
- Link<Button*,void> aLk = LINK(this,SwBreakDlg,ClickHdl);
- m_pPageBtn->SetClickHdl( aLk );
- m_pLineBtn->SetClickHdl( aLk );
- m_pColumnBtn->SetClickHdl( aLk );
- m_pPageCollBox->SetSelectHdl( LINK(this,SwBreakDlg,SelectHdl) );
-
- get<OKButton>("ok")->SetClickHdl(LINK(this,SwBreakDlg,OkHdl));
- m_pPageNumBox->SetClickHdl(LINK(this,SwBreakDlg,PageNumHdl));
- m_pPageNumEdit->SetModifyHdl(LINK(this,SwBreakDlg,PageNumModifyHdl));
+ m_xDialog.reset(m_xBuilder->weld_dialog("BreakDialog"));
+ m_xLineBtn.reset(m_xBuilder->weld_radio_button("linerb"));
+ m_xColumnBtn.reset(m_xBuilder->weld_radio_button("columnrb"));
+ m_xPageBtn.reset(m_xBuilder->weld_radio_button("pagerb"));
+ m_xPageCollBox.reset(m_xBuilder->weld_combo_box_text("stylelb"));
+ m_xPageNumBox.reset(m_xBuilder->weld_check_button("pagenumcb"));
+ m_xPageNumEdit.reset(m_xBuilder->weld_spin_button("pagenumsb"));
+ m_xPageCollText.reset(m_xBuilder->weld_label("styleft"));
+ m_xOkBtn.reset(m_xBuilder->weld_button("ok"));
+
+ Link<weld::ToggleButton&,void> aLk = LINK(this, SwBreakDlg, ToggleHdl);
+ m_xPageBtn->connect_toggled(aLk);
+ m_xLineBtn->connect_toggled(aLk);
+ m_xColumnBtn->connect_toggled(aLk);
+ m_xPageCollBox->connect_changed(LINK(this, SwBreakDlg, ChangeHdl));
+
+ m_xOkBtn->connect_clicked(LINK(this, SwBreakDlg, OkHdl));
+ m_xPageNumBox->connect_toggled(LINK(this, SwBreakDlg, PageNumHdl));
+ m_xPageNumEdit->connect_value_changed(LINK(this, SwBreakDlg, PageNumModifyHdl));
// Insert page description to Listbox
const size_t nCount = rSh.GetPageDescCnt();
- for( size_t i = 0; i < nCount; ++i)
+ for (size_t i = 0; i < nCount; ++i)
{
const SwPageDesc &rPageDesc = rSh.GetPageDesc(i);
- ::InsertStringSorted(rPageDesc.GetName(), *m_pPageCollBox, 1 );
+ ::InsertStringSorted(rPageDesc.GetName(), *m_xPageCollBox, 1 );
}
OUString aFormatName;
- for(sal_uInt16 i = RES_POOLPAGE_BEGIN; i < RES_POOLPAGE_END; ++i)
+ for (sal_uInt16 i = RES_POOLPAGE_BEGIN; i < RES_POOLPAGE_END; ++i)
{
aFormatName = SwStyleNameMapper::GetUIName( i, aFormatName );
- if(LISTBOX_ENTRY_NOTFOUND == m_pPageCollBox->GetEntryPos(aFormatName))
- ::InsertStringSorted(aFormatName, *m_pPageCollBox, 1 );
+ if (m_xPageCollBox->find_text(aFormatName) == -1)
+ ::InsertStringSorted(aFormatName, *m_xPageCollBox, 1 );
}
//add landscape page
aFormatName = SwStyleNameMapper::GetUIName( RES_POOLPAGE_LANDSCAPE, aFormatName );
- if(LISTBOX_ENTRY_NOTFOUND == m_pPageCollBox->GetEntryPos(aFormatName))
- ::InsertStringSorted(aFormatName, *m_pPageCollBox, 1 );
+ if (m_xPageCollBox->find_text(aFormatName) == -1)
+ ::InsertStringSorted(aFormatName, *m_xPageCollBox, 1);
CheckEnable();
- m_pPageNumEdit->SetText(OUString());
-}
-
-SwBreakDlg::~SwBreakDlg()
-{
- disposeOnce();
-}
-
-void SwBreakDlg::dispose()
-{
- m_pLineBtn.clear();
- m_pColumnBtn.clear();
- m_pPageBtn.clear();
- m_pPageCollText.clear();
- m_pPageCollBox.clear();
- m_pPageNumBox.clear();
- m_pPageNumEdit.clear();
- SvxStandardDialog::dispose();
+ m_xPageNumEdit->set_text(OUString());
}
void SwBreakDlg::CheckEnable()
@@ -191,32 +179,32 @@ void SwBreakDlg::CheckEnable()
bool bEnable = true;
if ( bHtmlMode )
{
- m_pColumnBtn->Enable(false);
- m_pPageCollBox->Enable(false);
+ m_xColumnBtn->set_sensitive(false);
+ m_xPageCollBox->set_sensitive(false);
bEnable = false;
}
else if(rSh.GetFrameType(nullptr,true)
& (FrameTypeFlags::FLY_ANY | FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FOOTNOTE))
{
- m_pPageBtn->Enable(false);
- if(m_pPageBtn->IsChecked())
- m_pLineBtn->Check();
+ m_xPageBtn->set_sensitive(false);
+ if (m_xPageBtn->get_active())
+ m_xLineBtn->set_active(true);
bEnable = false;
}
- const bool bPage = m_pPageBtn->IsChecked();
- m_pPageCollText->Enable( bPage );
- m_pPageCollBox->Enable ( bPage );
+ const bool bPage = m_xPageBtn->get_active();
+ m_xPageCollText->set_sensitive(bPage);
+ m_xPageCollBox->set_sensitive(bPage);
bEnable &= bPage;
if ( bEnable )
{
// position 0 says 'Without' page template.
- const sal_Int32 nPos = m_pPageCollBox->GetSelectedEntryPos();
- if ( 0 == nPos || LISTBOX_ENTRY_NOTFOUND == nPos )
+ const int nPos = m_xPageCollBox->get_active();
+ if (nPos == 0 || nPos == -1)
bEnable = false;
}
- m_pPageNumBox->Enable(bEnable);
- m_pPageNumEdit->Enable(bEnable);
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPageNumEdit->set_sensitive(bEnable);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/swdlgfact.cxx b/sw/source/ui/dialog/swdlgfact.cxx
index 031efef1198e..95f0e34a99bc 100644
--- a/sw/source/ui/dialog/swdlgfact.cxx
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -93,7 +93,10 @@ IMPL_ABSTDLG_BASE(SwAbstractSfxDialog_Impl);
IMPL_ABSTDLG_BASE(AbstractSwAsciiFilterDlg_Impl);
IMPL_ABSTDLG_BASE(VclAbstractDialog_Impl);
IMPL_ABSTDLG_BASE(AbstractSplitTableDialog_Impl);
-IMPL_ABSTDLG_BASE(AbstractSwBreakDlg_Impl);
+short AbstractSwBreakDlg_Impl::Execute()
+{
+ return m_xDlg->Execute();
+}
IMPL_ABSTDLG_BASE(AbstractTabDialog_Impl);
IMPL_ABSTDLG_BASE(AbstractSwConvertTableDlg_Impl);
IMPL_ABSTDLG_BASE(AbstractSwInsertDBColAutoPilot_Impl);
@@ -193,17 +196,17 @@ SplitTable_HeadlineOption AbstractSplitTableDialog_Impl::GetSplitMode()
OUString AbstractSwBreakDlg_Impl::GetTemplateName()
{
- return pDlg->GetTemplateName();
+ return m_xDlg->GetTemplateName();
}
sal_uInt16 AbstractSwBreakDlg_Impl:: GetKind()
{
- return pDlg->GetKind();
+ return m_xDlg->GetKind();
}
::boost::optional<sal_uInt16> AbstractSwBreakDlg_Impl:: GetPageNumber()
{
- return pDlg->GetPageNumber();
+ return m_xDlg->GetPageNumber();
}
void AbstractSwConvertTableDlg_Impl::GetValues( sal_Unicode& rDelim,SwInsertTableOptions& rInsTableFlags,
@@ -676,11 +679,9 @@ VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwInsertBookmarkDl
return VclPtr<VclAbstractDialog_Impl>::Create( pDlg );
}
-VclPtr<AbstractSwBreakDlg> SwAbstractDialogFactory_Impl::CreateSwBreakDlg(vcl::Window *pParent,
- SwWrtShell &rSh)
+VclPtr<AbstractSwBreakDlg> SwAbstractDialogFactory_Impl::CreateSwBreakDlg(weld::Window* pParent, SwWrtShell &rSh)
{
- VclPtr<SwBreakDlg> pDlg = VclPtr<SwBreakDlg>::Create(pParent, rSh);
- return VclPtr<AbstractSwBreakDlg_Impl>::Create(pDlg);
+ return VclPtr<AbstractSwBreakDlg_Impl>::Create(new SwBreakDlg(pParent, rSh));
}
VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwChangeDBDlg(SwView& rVw)
diff --git a/sw/source/ui/dialog/swdlgfact.hxx b/sw/source/ui/dialog/swdlgfact.hxx
index 2eeca35fa7f8..dbc95b9c31e9 100644
--- a/sw/source/ui/dialog/swdlgfact.hxx
+++ b/sw/source/ui/dialog/swdlgfact.hxx
@@ -103,12 +103,19 @@ class VclAbstractDialog_Impl : public VclAbstractDialog
class AbstractSwBreakDlg_Impl : public AbstractSwBreakDlg
{
- DECL_ABSTDLG_BASE(AbstractSwBreakDlg_Impl,SwBreakDlg)
+protected:
+ std::unique_ptr<SwBreakDlg> m_xDlg;
+public:
+ explicit AbstractSwBreakDlg_Impl(SwBreakDlg* p)
+ : m_xDlg(p)
+ {
+ }
+ virtual short Execute() override;
virtual OUString GetTemplateName() override;
virtual sal_uInt16 GetKind() override;
virtual ::boost::optional<sal_uInt16> GetPageNumber() override;
-
};
+
class AbstractSplitTableDialog_Impl : public AbstractSplitTableDialog // add for
{
DECL_ABSTDLG_BASE(AbstractSplitTableDialog_Impl, SwSplitTableDlg)
@@ -384,7 +391,7 @@ public:
virtual VclPtr<AbstractSwAsciiFilterDlg> CreateSwAsciiFilterDlg ( SwDocShell& rDocSh,
SvStream* pStream ) override;
virtual VclPtr<VclAbstractDialog> CreateSwInsertBookmarkDlg( vcl::Window *pParent, SwWrtShell &rSh, SfxRequest& rReq ) override;
- virtual VclPtr<AbstractSwBreakDlg> CreateSwBreakDlg(vcl::Window *pParent, SwWrtShell &rSh) override;
+ virtual VclPtr<AbstractSwBreakDlg> CreateSwBreakDlg(weld::Window *pParent, SwWrtShell &rSh) override;
virtual VclPtr<VclAbstractDialog> CreateSwChangeDBDlg(SwView& rVw) override;
virtual VclPtr<SfxAbstractTabDialog> CreateSwCharDlg(vcl::Window* pParent, SwView& pVw, const SfxItemSet& rCoreSet,
SwCharDlgMode nDialogMode, const OUString* pFormatStr = nullptr) override;
diff --git a/sw/source/uibase/inc/break.hxx b/sw/source/uibase/inc/break.hxx
index 822e0e436bde..17ac6f34bbc9 100644
--- a/sw/source/uibase/inc/break.hxx
+++ b/sw/source/uibase/inc/break.hxx
@@ -20,30 +20,28 @@
#ifndef INCLUDED_SW_SOURCE_UIBASE_INC_BREAK_HXX
#define INCLUDED_SW_SOURCE_UIBASE_INC_BREAK_HXX
-#include <svx/stddlg.hxx>
-
+#include <vcl/weld.hxx>
#include <vcl/button.hxx>
-
#include <vcl/fixed.hxx>
-
#include <vcl/lstbox.hxx>
-
#include <vcl/field.hxx>
-
#include <boost/optional.hpp>
class SwWrtShell;
-class SwBreakDlg: public SvxStandardDialog
+class SwBreakDlg
{
SwWrtShell &rSh;
- VclPtr<RadioButton> m_pLineBtn;
- VclPtr<RadioButton> m_pColumnBtn;
- VclPtr<RadioButton> m_pPageBtn;
- VclPtr<FixedText> m_pPageCollText;
- VclPtr<ListBox> m_pPageCollBox;
- VclPtr<CheckBox> m_pPageNumBox;
- VclPtr<NumericField> m_pPageNumEdit;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Dialog> m_xDialog;
+ std::unique_ptr<weld::RadioButton> m_xLineBtn;
+ std::unique_ptr<weld::RadioButton> m_xColumnBtn;
+ std::unique_ptr<weld::RadioButton> m_xPageBtn;
+ std::unique_ptr<weld::Label> m_xPageCollText;
+ std::unique_ptr<weld::ComboBoxText> m_xPageCollBox;
+ std::unique_ptr<weld::CheckButton> m_xPageNumBox;
+ std::unique_ptr<weld::SpinButton> m_xPageNumEdit;
+ std::unique_ptr<weld::Button> m_xOkBtn;
OUString aTemplate;
sal_uInt16 nKind;
@@ -51,25 +49,20 @@ class SwBreakDlg: public SvxStandardDialog
bool bHtmlMode;
- DECL_LINK( ClickHdl, Button*, void );
- DECL_LINK( SelectHdl, ListBox&, void );
- DECL_LINK( PageNumHdl, Button*, void );
- DECL_LINK(PageNumModifyHdl, Edit&, void);
- DECL_LINK(OkHdl, Button*, void);
+ DECL_LINK(ToggleHdl, weld::ToggleButton&, void);
+ DECL_LINK(ChangeHdl, weld::ComboBoxText&, void);
+ DECL_LINK(PageNumHdl, weld::ToggleButton&, void);
+ DECL_LINK(PageNumModifyHdl, weld::SpinButton&, void);
+ DECL_LINK(OkHdl, weld::Button&, void);
void CheckEnable();
-protected:
- virtual void Apply() override;
-
public:
- SwBreakDlg( vcl::Window *pParent, SwWrtShell &rSh );
- virtual ~SwBreakDlg() override;
- virtual void dispose() override;
-
- const OUString& GetTemplateName() { return aTemplate; }
- sal_uInt16 GetKind() { return nKind; }
- const ::boost::optional<sal_uInt16>& GetPageNumber() { return oPgNum; }
+ SwBreakDlg(weld::Window *pParent, SwWrtShell &rSh);
+ short Execute();
+ const OUString& GetTemplateName() const { return aTemplate; }
+ sal_uInt16 GetKind() const { return nKind; }
+ const ::boost::optional<sal_uInt16>& GetPageNumber() const { return oPgNum; }
};
#endif
diff --git a/sw/source/uibase/inc/uitool.hxx b/sw/source/uibase/inc/uitool.hxx
index 2e2924df78b7..932c57ec0638 100644
--- a/sw/source/uibase/inc/uitool.hxx
+++ b/sw/source/uibase/inc/uitool.hxx
@@ -30,6 +30,7 @@ class SwPageDesc;
class SvxTabStopItem;
class SwWrtShell;
class ListBox;
+namespace weld { class ComboBoxText; }
class SwDocShell;
class SwFrameFormat;
class SwTabCols;
@@ -94,6 +95,7 @@ SW_DLLPUBLIC void FillCharStyleListBox(ListBox& rToFill, SwDocShell* pDocSh, boo
//inserts a string sorted into a ListBox,
SW_DLLPUBLIC sal_Int32 InsertStringSorted(const OUString& rEntry, ListBox& rToFill, sal_Int32 nOffset);
+SW_DLLPUBLIC void InsertStringSorted(const OUString& rEntry, weld::ComboBoxText& rToFill, int nOffset);
// Get table width and alignment
SwTwips GetTableWidth( SwFrameFormat const * pFormat, SwTabCols const & rCols, sal_uInt16 *pPercent,
diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx
index 2266877d68e0..839326e70c34 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -647,10 +647,9 @@ void SwTextShell::Execute(SfxRequest &rReq)
else
{
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
- OSL_ENSURE(pFact, "SwAbstractDialogFactory fail!");
-
- ScopedVclPtr<AbstractSwBreakDlg> pDlg(pFact->CreateSwBreakDlg(GetView().GetWindow(), rWrtSh));
- OSL_ENSURE(pDlg, "Dialog creation failed!");
+ assert(pFact && "SwAbstractDialogFactory fail!");
+ ScopedVclPtr<AbstractSwBreakDlg> pDlg(pFact->CreateSwBreakDlg(GetView().GetWindow()->GetFrameWeld(), rWrtSh));
+ assert(pDlg && "Dialog creation failed!");
if ( pDlg->Execute() == RET_OK )
{
nKind = pDlg->GetKind();
diff --git a/sw/source/uibase/utlui/uitool.cxx b/sw/source/uibase/utlui/uitool.cxx
index 5ff91b633337..c8a8bfd49eca 100644
--- a/sw/source/uibase/utlui/uitool.cxx
+++ b/sw/source/uibase/utlui/uitool.cxx
@@ -22,6 +22,7 @@
#include <osl/diagnose.h>
#include <tools/datetime.hxx>
#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
#include <unotools/collatorwrapper.hxx>
#include <svl/urihelper.hxx>
#include <svl/stritem.hxx>
@@ -713,6 +714,19 @@ sal_Int32 InsertStringSorted(const OUString& rEntry, ListBox& rToFill, sal_Int32
return rToFill.InsertEntry(rEntry, nOffset);
}
+void InsertStringSorted(const OUString& rEntry, weld::ComboBoxText& rToFill, int nOffset)
+{
+ CollatorWrapper& rCaseColl = ::GetAppCaseCollator();
+ const int nCount = rToFill.get_count();
+ while (nOffset < nCount)
+ {
+ if (0 < rCaseColl.compareString(rToFill.get_text(nOffset), rEntry))
+ break;
+ ++nOffset;
+ }
+ rToFill.insert_text(nOffset, rEntry);
+}
+
void FillCharStyleListBox(ListBox& rToFill, SwDocShell* pDocSh, bool bSorted, bool bWithDefault)
{
const sal_Int32 nOffset = rToFill.GetEntryCount() > 0 ? 1 : 0;
diff --git a/sw/uiconfig/swriter/ui/insertbreak.ui b/sw/uiconfig/swriter/ui/insertbreak.ui
index 23dac4839f34..9cfe1bab7732 100644
--- a/sw/uiconfig/swriter/ui/insertbreak.ui
+++ b/sw/uiconfig/swriter/ui/insertbreak.ui
@@ -261,7 +261,6 @@
</object>
</child>
<action-widgets>
- <action-widget response="0">ok</action-widget>
<action-widget response="-6">cancel</action-widget>
<action-widget response="-11">help</action-widget>
</action-widgets>
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx
index 766301256f6e..c04f0a8f767e 100644
--- a/vcl/inc/salframe.hxx
+++ b/vcl/inc/salframe.hxx
@@ -28,6 +28,7 @@
#include <o3tl/typed_flags_set.hxx>
#include <vcl/window.hxx>
+#include <vcl/weld.hxx>
// complete vcl::Window for SalFrame::CallCallback under -fsanitize=function
class AllSettings;
@@ -107,7 +108,8 @@ private:
// the VCL window corresponding to this frame
VclPtr<vcl::Window> m_pWindow;
SALFRAMEPROC m_pProc;
-
+protected:
+ mutable std::unique_ptr<weld::Window> m_xFrameWeld;
public:
SalFrame();
virtual ~SalFrame() override;
@@ -261,6 +263,8 @@ public:
return false;
}
+ virtual weld::Window* GetFrameWeld() const;
+
// Callbacks (indepent part in vcl/source/window/winproc.cxx)
// for default message handling return 0
void SetCallback( vcl::Window* pWindow, SALFRAMEPROC pProc );
diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx
index f33d9d4d912a..1eadc7ac382f 100644
--- a/vcl/inc/salinst.hxx
+++ b/vcl/inc/salinst.hxx
@@ -26,6 +26,7 @@
#include <vcl/dllapi.h>
#include <vcl/salgtype.hxx>
#include <osl/thread.hxx>
+#include <vcl/vclenum.hxx>
#include "displayconnectiondispatch.hxx"
@@ -34,6 +35,12 @@
#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
namespace comphelper { class SolarMutex; }
+namespace vcl { class Window; }
+namespace weld {
+ class Builder;
+ class MessageDialog;
+ class Widget;
+}
struct SystemParentData;
struct SalPrinterQueueInfo;
class ImplJobSetup;
@@ -147,6 +154,10 @@ public:
virtual OpenGLContext* CreateOpenGLContext() = 0;
+ virtual weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile);
+ virtual weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
+ VclButtonsType eButtonType, const OUString& rPrimaryMessage);
+
// methods for XDisplayConnection
void SetEventCallback( rtl::Reference< vcl::DisplayConnectionDispatch > const & pInstance )
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 0ae8250c82f6..6f4e0db8dc7f 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -536,6 +536,7 @@ public:
virtual void* ShowPopover(const OUString& rHelpText, const tools::Rectangle& rHelpArea, QuickHelpFlags nFlags) override;
virtual bool UpdatePopover(void* nId, const OUString& rHelpText, const tools::Rectangle& rHelpArea) override;
virtual bool HidePopover(void* nId) override;
+ virtual weld::Window* GetFrameWeld() const override;
#endif
static GtkSalFrame *getFromWindow( GtkWindow *pWindow );
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index 4b48a4b3762e..2da209730e93 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -227,6 +227,8 @@ public:
virtual css::uno::Reference< css::uno::XInterface > CreateDragSource() override;
virtual css::uno::Reference< css::uno::XInterface > CreateDropTarget() override;
virtual OpenGLContext* CreateOpenGLContext() override;
+ virtual weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile) override;
+ virtual weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage) override;
#endif
virtual const cairo_font_options_t* GetCairoFontOptions() override;
diff --git a/vcl/source/app/help.cxx b/vcl/source/app/help.cxx
index 8d3f406bd30e..7172bc709612 100644
--- a/vcl/source/app/help.cxx
+++ b/vcl/source/app/help.cxx
@@ -58,6 +58,11 @@ bool Help::Start( const OUString&, const vcl::Window* )
return false;
}
+bool Help::Start(const OUString&, weld::Widget*)
+{
+ return false;
+}
+
void Help::SearchKeyword( const OUString& )
{
}
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 93697a61ad2d..12ce25351a46 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -27,7 +27,14 @@
#include <salbmp.hxx>
#include <salobj.hxx>
#include <salmenu.hxx>
-
+#include <vcl/builder.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/layout.hxx>
+#include <vcl/tabctrl.hxx>
+#include <vcl/tabpage.hxx>
+#include <vcl/weld.hxx>
SalFrame::SalFrame()
: m_pWindow(nullptr)
@@ -164,4 +171,1080 @@ SalMenuItem::~SalMenuItem()
{
}
+class SalInstanceWidget : public virtual weld::Widget
+{
+private:
+ VclPtr<vcl::Window> m_xWidget;
+ bool m_bTakeOwnership;
+
+public:
+ SalInstanceWidget(vcl::Window* pWidget, bool bTakeOwnership)
+ : m_xWidget(pWidget)
+ , m_bTakeOwnership(bTakeOwnership)
+ {
+ }
+
+ virtual void set_sensitive(bool sensitive) override
+ {
+ m_xWidget->Enable(sensitive);
+ }
+
+ virtual bool get_sensitive() const override
+ {
+ return m_xWidget->IsEnabled();
+ }
+
+ virtual void set_visible(bool visible) override
+ {
+ m_xWidget->Show(visible);
+ }
+
+ virtual bool get_visible() const override
+ {
+ return m_xWidget->IsVisible();
+ }
+
+ virtual void grab_focus() override
+ {
+ m_xWidget->GrabFocus();
+ }
+
+ virtual bool has_focus() const override
+ {
+ return m_xWidget->HasFocus();
+ }
+
+ virtual void show() override
+ {
+ m_xWidget->Show();
+ }
+
+ virtual void hide() override
+ {
+ m_xWidget->Hide();
+ }
+
+ virtual void set_size_request(int nWidth, int nHeight) override
+ {
+ m_xWidget->set_width_request(nWidth);
+ m_xWidget->set_height_request(nHeight);
+ }
+
+ virtual Size get_preferred_size() const override
+ {
+ return m_xWidget->get_preferred_size();
+ }
+
+ virtual float approximate_char_width() const override
+ {
+ return m_xWidget->approximate_char_width();
+ }
+
+ virtual Size get_pixel_size(const OUString& rText) const override
+ {
+ //TODO, or do I want GetTextBoundRect ?, just using width at the moment anyway
+ return Size(m_xWidget->GetTextWidth(rText), m_xWidget->GetTextHeight());
+ }
+
+ virtual OString get_buildable_name() const override
+ {
+ return m_xWidget->get_id().toUtf8();
+ }
+
+ virtual OString get_help_id() const override
+ {
+ return m_xWidget->GetHelpId();
+ }
+
+ virtual Widget* weld_parent() const override
+ {
+ vcl::Window* pParent = m_xWidget->GetParent();
+ return pParent ? new SalInstanceWidget(pParent, false) : nullptr;
+ }
+
+ virtual ~SalInstanceWidget() override
+ {
+ if (m_bTakeOwnership)
+ m_xWidget.disposeAndClear();
+ }
+
+ vcl::Window* getWidget()
+ {
+ return m_xWidget;
+ }
+
+ SystemWindow* getSystemWindow()
+ {
+ return m_xWidget->GetSystemWindow();
+ }
+};
+
+class SalInstanceContainer : public SalInstanceWidget, public virtual weld::Container
+{
+private:
+ VclPtr<vcl::Window> m_xContainer;
+public:
+ SalInstanceContainer(vcl::Window* pContainer, bool bTakeOwnership)
+ : SalInstanceWidget(pContainer, bTakeOwnership)
+ , m_xContainer(pContainer)
+ {
+ }
+};
+
+class SalInstanceWindow : public SalInstanceContainer, public virtual weld::Window
+{
+private:
+ VclPtr<SystemWindow> m_xWindow;
+
+public:
+ SalInstanceWindow(SystemWindow* pWindow, bool bTakeOwnership)
+ : SalInstanceContainer(pWindow, bTakeOwnership)
+ , m_xWindow(pWindow)
+ {
+ }
+
+ virtual void set_title(const OUString& rTitle) override
+ {
+ m_xWindow->SetText(rTitle);
+ }
+
+ virtual OUString get_title() const override
+ {
+ return m_xWindow->GetText();
+ }
+};
+
+class SalInstanceDialog : public SalInstanceWindow, public virtual weld::Dialog
+{
+private:
+ VclPtr<::Dialog> m_xDialog;
+
+public:
+ SalInstanceDialog(::Dialog* pDialog, bool bTakeOwnership)
+ : SalInstanceWindow(pDialog, bTakeOwnership)
+ , m_xDialog(pDialog)
+ {
+ }
+
+ virtual int run() override
+ {
+ m_xDialog->Show();
+ return m_xDialog->Execute();
+ }
+
+ virtual void response(int nResponse) override
+ {
+ m_xDialog->EndDialog(nResponse);
+ }
+};
+
+class SalInstanceMessageDialog : public SalInstanceDialog, public virtual weld::MessageDialog
+{
+private:
+ VclPtr<::MessageDialog> m_xMessageDialog;
+public:
+ SalInstanceMessageDialog(::MessageDialog* pDialog, bool bTakeOwnership)
+ : SalInstanceDialog(pDialog, bTakeOwnership)
+ , m_xMessageDialog(pDialog)
+ {
+ }
+
+ virtual void set_primary_text(const OUString& rText) override
+ {
+ m_xMessageDialog->set_primary_text(rText);
+ }
+
+ virtual OUString get_primary_text() const override
+ {
+ return m_xMessageDialog->get_primary_text();
+ }
+
+ virtual void set_secondary_text(const OUString& rText) override
+ {
+ m_xMessageDialog->set_secondary_text(rText);
+ }
+
+ virtual OUString get_secondary_text() const override
+ {
+ return m_xMessageDialog->get_secondary_text();
+ }
+};
+
+class SalInstanceFrame : public SalInstanceContainer, public virtual weld::Frame
+{
+private:
+ VclPtr<VclFrame> m_xFrame;
+public:
+ SalInstanceFrame(VclFrame* pFrame, bool bTakeOwnership)
+ : SalInstanceContainer(pFrame, bTakeOwnership)
+ , m_xFrame(pFrame)
+ {
+ }
+
+ virtual void set_label(const OUString& rText) override
+ {
+ m_xFrame->set_label(rText);
+ }
+
+ virtual OUString get_label() const override
+ {
+ return m_xFrame->get_label();
+ }
+};
+
+class SalInstanceNotebook : public SalInstanceContainer, public virtual weld::Notebook
+{
+private:
+ VclPtr<TabControl> m_xNotebook;
+ mutable std::vector<std::unique_ptr<SalInstanceContainer>> m_aPages;
+
+ DECL_LINK(DeactivatePageHdl, TabControl*, bool);
+ DECL_LINK(ActivatePageHdl, TabControl*, void);
+
+public:
+ SalInstanceNotebook(TabControl* pNotebook, bool bTakeOwnership)
+ : SalInstanceContainer(pNotebook, bTakeOwnership)
+ , m_xNotebook(pNotebook)
+ {
+ m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceNotebook, ActivatePageHdl));
+ m_xNotebook->SetDeactivatePageHdl(LINK(this, SalInstanceNotebook, DeactivatePageHdl));
+ }
+
+ virtual int get_current_page() const override
+ {
+ return m_xNotebook->GetPagePos(m_xNotebook->GetCurPageId());
+ }
+
+ virtual OString get_current_page_ident() const override
+ {
+ return m_xNotebook->GetPageName(m_xNotebook->GetCurPageId());
+ }
+
+ virtual weld::Container* get_page(const OString& rIdent) const override
+ {
+ sal_uInt16 nPageId = m_xNotebook->GetPageId(rIdent);
+ sal_uInt16 nPageIndex = m_xNotebook->GetPagePos(nPageId);
+ if (nPageIndex == TAB_PAGE_NOTFOUND)
+ return nullptr;
+ TabPage* pPage = m_xNotebook->GetTabPage(nPageId);
+ vcl::Window* pChild = pPage->GetChild(0);
+ if (m_aPages.size() < nPageIndex + 1U)
+ m_aPages.resize(nPageIndex + 1U);
+ if (!m_aPages[nPageIndex])
+ m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, false));
+ return m_aPages[nPageIndex].get();
+ }
+
+ virtual void set_current_page(int nPage) override
+ {
+ m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(nPage));
+ }
+
+ virtual void set_current_page(const OString& rIdent) override
+ {
+ m_xNotebook->SetCurPageId(m_xNotebook->GetPageId(rIdent));
+ }
+
+ virtual int get_n_pages() const override
+ {
+ return m_xNotebook->GetPageCount();
+ }
+
+ virtual ~SalInstanceNotebook() override
+ {
+ m_xNotebook->SetActivatePageHdl(Link<TabControl*,void>());
+ m_xNotebook->SetDeactivatePageHdl(Link<TabControl*,bool>());
+ }
+};
+
+IMPL_LINK_NOARG(SalInstanceNotebook, DeactivatePageHdl, TabControl*, bool)
+{
+ return m_aLeavePageHdl.Call(get_current_page_ident());
+}
+
+IMPL_LINK_NOARG(SalInstanceNotebook, ActivatePageHdl, TabControl*, void)
+{
+ m_aEnterPageHdl.Call(get_current_page_ident());
+}
+
+class SalInstanceButton : public SalInstanceContainer, public virtual weld::Button
+{
+private:
+ VclPtr<::Button> m_xButton;
+
+ DECL_LINK(ClickHdl, ::Button*, void);
+public:
+ SalInstanceButton(::Button* pButton, bool bTakeOwnership)
+ : SalInstanceContainer(pButton, bTakeOwnership)
+ , m_xButton(pButton)
+ {
+ m_xButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
+ }
+
+ virtual void set_label(const OUString& rText) override
+ {
+ m_xButton->SetText(rText);
+ }
+
+ virtual OUString get_label() const override
+ {
+ return m_xButton->GetText();
+ }
+
+ virtual ~SalInstanceButton() override
+ {
+ m_xButton->SetClickHdl(Link<::Button*,void>());
+ }
+};
+
+IMPL_LINK(SalInstanceButton, ClickHdl, ::Button*, pButton, void)
+{
+ //if there's no handler set, disengage our intercept and
+ //run the click again to get default behaviour for cancel/ok
+ //etc buttons.
+ if (!m_aClickHdl.IsSet())
+ {
+ pButton->SetClickHdl(Link<::Button*,void>());
+ pButton->Click();
+ pButton->SetClickHdl(LINK(this, SalInstanceButton, ClickHdl));
+ return;
+ }
+ signal_clicked();
+}
+
+class SalInstanceRadioButton : public SalInstanceButton, public virtual weld::RadioButton
+{
+private:
+ VclPtr<::RadioButton> m_xRadioButton;
+
+ DECL_LINK(ToggleHdl, ::RadioButton&, void);
+
+public:
+ SalInstanceRadioButton(::RadioButton* pButton, bool bTakeOwnership)
+ : SalInstanceButton(pButton, bTakeOwnership)
+ , m_xRadioButton(pButton)
+ {
+ m_xRadioButton->SetToggleHdl(LINK(this, SalInstanceRadioButton, ToggleHdl));
+ }
+
+ virtual void set_active(bool active) override
+ {
+ m_xRadioButton->Check(active);
+ }
+
+ virtual bool get_active() const override
+ {
+ return m_xRadioButton->IsChecked();
+ }
+
+ virtual void set_inconsistent(bool /*inconsistent*/) override
+ {
+ //not available
+ }
+
+ virtual bool get_inconsistent() const override
+ {
+ return false;
+ }
+
+ virtual ~SalInstanceRadioButton() override
+ {
+ m_xRadioButton->SetToggleHdl(Link<::RadioButton&, void>());
+ }
+};
+
+IMPL_LINK_NOARG(SalInstanceRadioButton, ToggleHdl, ::RadioButton&, void)
+{
+ signal_toggled();
+}
+
+class SalInstanceCheckButton : public SalInstanceButton, public virtual weld::CheckButton
+{
+private:
+ VclPtr<CheckBox> m_xCheckButton;
+
+ DECL_LINK(ToggleHdl, CheckBox&, void);
+public:
+ SalInstanceCheckButton(CheckBox* pButton, bool bTakeOwnership)
+ : SalInstanceButton(pButton, bTakeOwnership)
+ , m_xCheckButton(pButton)
+ {
+ m_xCheckButton->SetToggleHdl(LINK(this, SalInstanceCheckButton, ToggleHdl));
+ }
+
+ virtual void set_active(bool active) override
+ {
+ m_xCheckButton->Check(active);
+ }
+
+ virtual bool get_active() const override
+ {
+ return m_xCheckButton->IsChecked();
+ }
+
+ virtual void set_inconsistent(bool inconsistent) override
+ {
+ m_xCheckButton->SetState(inconsistent ? TRISTATE_INDET : TRISTATE_FALSE);
+ }
+
+ virtual bool get_inconsistent() const override
+ {
+ return m_xCheckButton->GetState() == TRISTATE_INDET;
+ }
+
+ virtual ~SalInstanceCheckButton() override
+ {
+ m_xCheckButton->SetToggleHdl(Link<CheckBox&, void>());
+ }
+};
+
+IMPL_LINK_NOARG(SalInstanceCheckButton, ToggleHdl, CheckBox&, void)
+{
+ signal_toggled();
+}
+
+class SalInstanceEntry : public SalInstanceWidget, public virtual weld::Entry
+{
+private:
+ VclPtr<Edit> m_xEntry;
+
+ DECL_LINK(ChangeHdl, Edit&, void);
+
+ class WeldTextFilter : public TextFilter
+ {
+ private:
+ Link<OUString&, bool>& m_rInsertTextHdl;
+ public:
+ WeldTextFilter(Link<OUString&, bool>& rInsertTextHdl)
+ : TextFilter(OUString())
+ , m_rInsertTextHdl(rInsertTextHdl)
+ {
+ }
+
+ virtual OUString filter(const OUString &rText) override
+ {
+ if (!m_rInsertTextHdl.IsSet())
+ return rText;
+ OUString sText(rText);
+ const bool bContinue = m_rInsertTextHdl.Call(sText);
+ if (!bContinue)
+ return OUString();
+ return sText;
+ }
+ };
+
+ WeldTextFilter m_aTextFilter;
+public:
+ SalInstanceEntry(Edit* pEntry, bool bTakeOwnership)
+ : SalInstanceWidget(pEntry, bTakeOwnership)
+ , m_xEntry(pEntry)
+ , m_aTextFilter(m_aInsertTextHdl)
+ {
+ m_xEntry->SetModifyHdl(LINK(this, SalInstanceEntry, ChangeHdl));
+ m_xEntry->SetTextFilter(&m_aTextFilter);
+ }
+
+ virtual void set_text(const OUString& rText) override
+ {
+ m_xEntry->SetText(rText);
+ }
+
+ virtual OUString get_text() const override
+ {
+ return m_xEntry->GetText();
+ }
+
+ virtual void set_width_chars(int nChars) override
+ {
+ m_xEntry->SetWidthInChars(nChars);
+ }
+
+ virtual ~SalInstanceEntry() override
+ {
+ m_xEntry->SetTextFilter(nullptr);
+ m_xEntry->SetModifyHdl(Link<Edit&, void>());
+ }
+};
+
+IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void)
+{
+ signal_changed();
+}
+
+class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView
+{
+private:
+ VclPtr<ListBox> m_xTreeView;
+
+ DECL_LINK(SelectHdl, ListBox&, void);
+ DECL_LINK(DoubleClickHdl, ListBox&, void);
+
+public:
+ SalInstanceTreeView(ListBox* pTreeView, bool bTakeOwnership)
+ : SalInstanceContainer(pTreeView, bTakeOwnership)
+ , m_xTreeView(pTreeView)
+ {
+ m_xTreeView->SetSelectHdl(LINK(this, SalInstanceTreeView, SelectHdl));
+ m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
+ }
+
+ virtual void append(const OUString& rText) override
+ {
+ m_xTreeView->InsertEntry(rText);
+ }
+
+ virtual void insert(const OUString& rText, int pos) override
+ {
+ m_xTreeView->InsertEntry(rText, pos);
+ }
+
+ virtual void remove(int pos) override
+ {
+ m_xTreeView->RemoveEntry(pos);
+ }
+
+ virtual int find(const OUString& rText) const override
+ {
+ sal_Int32 nRet = m_xTreeView->GetEntryPos(rText);
+ if (nRet == LISTBOX_ENTRY_NOTFOUND)
+ return -1;
+ return nRet;
+ }
+
+ virtual void set_top_entry(int pos) override
+ {
+ m_xTreeView->SetTopEntry(pos);
+ }
+
+ virtual void clear() override
+ {
+ m_xTreeView->Clear();
+ }
+
+ virtual int n_children() const override
+ {
+ return m_xTreeView->GetEntryCount();
+ }
+
+ virtual void select(int pos) override
+ {
+ if (pos == -1)
+ {
+ m_xTreeView->SetNoSelection();
+ return;
+ }
+ m_xTreeView->SelectEntryPos(pos);
+ }
+
+ virtual OUString get_selected() override
+ {
+ return m_xTreeView->GetSelectedEntry();
+ }
+
+ virtual OUString get(int pos) override
+ {
+ return m_xTreeView->GetEntry(pos);
+ }
+
+ virtual int get_selected_index() override
+ {
+ const sal_Int32 nRet = m_xTreeView->GetSelectedEntryPos();
+ if (nRet == LISTBOX_ENTRY_NOTFOUND)
+ return -1;
+ return nRet;
+ }
+
+ virtual void freeze() override
+ {
+ m_xTreeView->SetUpdateMode(false);
+ }
+
+ virtual void thaw() override
+ {
+ m_xTreeView->SetUpdateMode(true);
+ }
+
+ virtual int get_height_rows(int nRows) const override
+ {
+ return m_xTreeView->CalcWindowSizePixel(nRows);
+ }
+
+ virtual ~SalInstanceTreeView() override
+ {
+ m_xTreeView->SetDoubleClickHdl(Link<ListBox&, void>());
+ m_xTreeView->SetSelectHdl(Link<ListBox&, void>());
+ }
+};
+
+IMPL_LINK_NOARG(SalInstanceTreeView, SelectHdl, ListBox&, void)
+{
+ signal_changed();
+}
+
+IMPL_LINK_NOARG(SalInstanceTreeView, DoubleClickHdl, ListBox&, void)
+{
+ signal_row_activated();
+}
+
+class SalInstanceSpinButton : public SalInstanceEntry, public virtual weld::SpinButton
+{
+private:
+ VclPtr<NumericField> m_xButton;
+
+ DECL_LINK(UpDownHdl, SpinField&, void);
+ DECL_LINK(LoseFocusHdl, Control&, void);
+ DECL_LINK(OutputHdl, Edit&, bool);
+
+public:
+ SalInstanceSpinButton(NumericField* pButton, bool bTakeOwnership)
+ : SalInstanceEntry(pButton, bTakeOwnership)
+ , m_xButton(pButton)
+ {
+ m_xButton->SetUpHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
+ m_xButton->SetDownHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
+ m_xButton->SetLoseFocusHdl(LINK(this, SalInstanceSpinButton, LoseFocusHdl));
+ m_xButton->SetOutputHdl(LINK(this, SalInstanceSpinButton, OutputHdl));
+ }
+
+ virtual int get_value() const override
+ {
+ return m_xButton->GetValue();
+ }
+
+ virtual void set_value(int value) override
+ {
+ m_xButton->SetValue(value);
+ }
+
+ virtual void set_range(int min, int max) override
+ {
+ m_xButton->SetMin(min);
+ m_xButton->SetFirst(min);
+ m_xButton->SetMax(max);
+ m_xButton->SetLast(max);
+ }
+
+ virtual void get_range(int& min, int& max) const override
+ {
+ min = m_xButton->GetMin();
+ max = m_xButton->GetMax();
+ }
+
+ virtual void set_increments(int step, int /*page*/) override
+ {
+ m_xButton->SetSpinSize(step);
+ }
+
+ virtual void get_increments(int& step, int& page) const override
+ {
+ step = m_xButton->GetSpinSize();
+ page = m_xButton->GetSpinSize();
+ }
+
+ virtual void set_digits(unsigned int digits) override
+ {
+ m_xButton->SetDecimalDigits(digits);
+ }
+
+ virtual unsigned int get_digits() const override
+ {
+ return m_xButton->GetDecimalDigits();
+ }
+
+ virtual ~SalInstanceSpinButton() override
+ {
+ m_xButton->SetOutputHdl(Link<Edit&, bool>());
+ m_xButton->SetLoseFocusHdl(Link<Control&, void>());
+ m_xButton->SetDownHdl(Link<SpinField&, void>());
+ m_xButton->SetUpHdl(Link<SpinField&, void>());
+ }
+};
+
+IMPL_LINK_NOARG(SalInstanceSpinButton, UpDownHdl, SpinField&, void)
+{
+ signal_value_changed();
+}
+
+IMPL_LINK_NOARG(SalInstanceSpinButton, LoseFocusHdl, Control&, void)
+{
+ signal_value_changed();
+}
+
+IMPL_LINK_NOARG(SalInstanceSpinButton, OutputHdl, Edit&, bool)
+{
+ return signal_output();
+}
+
+class SalInstanceLabel : public SalInstanceWidget, public virtual weld::Label
+{
+private:
+ VclPtr<FixedText> m_xLabel;
+public:
+ SalInstanceLabel(FixedText* pLabel, bool bTakeOwnership)
+ : SalInstanceWidget(pLabel, bTakeOwnership)
+ , m_xLabel(pLabel)
+ {
+ }
+
+ virtual void set_label(const OUString& rText) override
+ {
+ m_xLabel->SetText(rText);
+ }
+};
+
+class SalInstanceTextView : public SalInstanceContainer, public virtual weld::TextView
+{
+private:
+ VclPtr<VclMultiLineEdit> m_xTextView;
+
+public:
+ SalInstanceTextView(VclMultiLineEdit* pTextView, bool bTakeOwnership)
+ : SalInstanceContainer(pTextView, bTakeOwnership)
+ , m_xTextView(pTextView)
+ {
+ }
+
+ virtual void set_text(const OUString& rText) override
+ {
+ m_xTextView->SetText(rText);
+ }
+
+ virtual OUString get_text() const override
+ {
+ return m_xTextView->GetText();
+ }
+
+ virtual Selection get_selection() const override
+ {
+ return m_xTextView->GetSelection();
+ }
+
+ virtual void set_selection(const Selection& rSelection) override
+ {
+ m_xTextView->SetSelection(rSelection);
+ }
+};
+
+class SalInstanceDrawingArea : public SalInstanceWidget, public virtual weld::DrawingArea
+{
+private:
+ VclPtr<VclDrawingArea> m_xDrawingArea;
+
+ DECL_LINK(PaintHdl, vcl::RenderContext&, void);
+ DECL_LINK(ResizeHdl, const Size&, void);
+
+public:
+ SalInstanceDrawingArea(VclDrawingArea* pDrawingArea, bool bTakeOwnership)
+ : SalInstanceWidget(pDrawingArea, bTakeOwnership)
+ , m_xDrawingArea(pDrawingArea)
+ {
+ m_xDrawingArea->SetPaintHdl(LINK(this, SalInstanceDrawingArea, PaintHdl));
+ m_xDrawingArea->SetResizeHdl(LINK(this, SalInstanceDrawingArea, ResizeHdl));
+ }
+
+ virtual void queue_draw() override
+ {
+ m_xDrawingArea->Invalidate();
+ }
+
+ virtual ~SalInstanceDrawingArea() override
+ {
+ m_xDrawingArea->SetResizeHdl(Link<const Size&, void>());
+ m_xDrawingArea->SetPaintHdl(Link<vcl::RenderContext&, void>());
+ }
+};
+
+IMPL_LINK(SalInstanceDrawingArea, PaintHdl, vcl::RenderContext&, rDevice, void)
+{
+ m_aDrawHdl.Call(rDevice);
+}
+
+IMPL_LINK(SalInstanceDrawingArea, ResizeHdl, const Size&, rSize, void)
+{
+ m_aSizeAllocateHdl.Call(rSize);
+}
+
+//ComboBox and ListBox have the same apis, ComboBoxes in LibreOffice have an edit box and ListBoxes
+//don't. This distinction isn't there in Gtk. Use a template to sort this problem out.
+template <class vcl_type>
+class SalInstanceComboBoxText : public SalInstanceContainer, public virtual weld::ComboBoxText
+{
+private:
+ VclPtr<vcl_type> m_xComboBoxText;
+
+ static void LinkStubSetSelectHdl(void* instance, vcl_type&)
+ {
+ return static_cast<SalInstanceComboBoxText*>(instance)->signal_changed();
+ }
+
+public:
+ SalInstanceComboBoxText(vcl_type* pComboBoxText, bool bTakeOwnership)
+ : SalInstanceContainer(pComboBoxText, bTakeOwnership)
+ , m_xComboBoxText(pComboBoxText)
+ {
+ m_xComboBoxText->SetSelectHdl(LINK(this, SalInstanceComboBoxText, SetSelectHdl));
+ }
+
+ virtual int get_active() const override
+ {
+ const sal_Int32 nRet = m_xComboBoxText->GetSelectedEntryPos();
+ if (nRet == LISTBOX_ENTRY_NOTFOUND)
+ return -1;
+ return nRet;
+ }
+
+ const OUString* getEntryData(int index) const
+ {
+ return static_cast<const OUString*>(m_xComboBoxText->GetEntryData(index));
+ }
+
+ virtual OUString get_active_id() const override
+ {
+ const OUString* pRet = getEntryData(m_xComboBoxText->GetSelectedEntryPos());
+ if (!pRet)
+ return OUString();
+ return *pRet;
+ }
+
+ virtual void set_active_id(const OUString& rStr) override
+ {
+ for (int i = 0; i < get_count(); ++i)
+ {
+ const OUString* pId = getEntryData(i);
+ if (!pId)
+ continue;
+ if (*pId == rStr)
+ m_xComboBoxText->SelectEntryPos(i);
+ }
+ }
+
+ virtual void set_active(int pos) override
+ {
+ if (pos == -1)
+ {
+ m_xComboBoxText->SetNoSelection();
+ return;
+ }
+ m_xComboBoxText->SelectEntryPos(pos);
+ }
+
+ virtual OUString get_active_text() const override
+ {
+ return m_xComboBoxText->GetSelectedEntry();
+ }
+
+ virtual OUString get_text(int pos) const override
+ {
+ return m_xComboBoxText->GetEntry(pos);
+ }
+
+ virtual OUString get_id(int pos) const override
+ {
+ const OUString* pRet = getEntryData(pos);
+ if (!pRet)
+ return OUString();
+ return *pRet;
+ }
+
+ virtual void append_text(const OUString& rStr) override
+ {
+ m_xComboBoxText->InsertEntry(rStr);
+ }
+
+ virtual void insert_text(int pos, const OUString& rStr) override
+ {
+ m_xComboBoxText->InsertEntry(rStr, pos);
+ }
+
+ virtual void append(const OUString& rId, const OUString& rStr) override
+ {
+ m_xComboBoxText->SetEntryData(m_xComboBoxText->InsertEntry(rStr), new OUString(rId));
+ }
+
+ virtual void insert(int pos, const OUString& rId, const OUString& rStr) override
+ {
+ m_xComboBoxText->SetEntryData(m_xComboBoxText->InsertEntry(rStr, pos), new OUString(rId));
+ }
+
+ virtual int get_count() const override
+ {
+ return m_xComboBoxText->GetEntryCount();
+ }
+
+ virtual int find_text(const OUString& rStr) const override
+ {
+ const sal_Int32 nRet = m_xComboBoxText->GetEntryPos(rStr);
+ if (nRet == LISTBOX_ENTRY_NOTFOUND)
+ return -1;
+ return nRet;
+ }
+
+ virtual void clear() override
+ {
+ for (int i = 0; i < get_count(); ++i)
+ {
+ const OUString* pId = getEntryData(i);
+ delete pId;
+ }
+ return m_xComboBoxText->Clear();
+ }
+
+ virtual void make_sorted() override
+ {
+ m_xComboBoxText->SetStyle(m_xComboBoxText->GetStyle() | WB_SORT);
+ }
+
+ virtual ~SalInstanceComboBoxText() override
+ {
+ m_xComboBoxText->SetSelectHdl(Link<vcl_type&, void>());
+ clear();
+ }
+};
+
+class SalInstanceBuilder : public weld::Builder
+{
+private:
+ VclBuilder m_aBuilder;
+public:
+ SalInstanceBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile)
+ : weld::Builder(rUIFile)
+ , m_aBuilder(pParent, rUIRoot, rUIFile)
+ {
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ virtual weld::Window* weld_window(const OString &id, bool bTakeOwnership) override
+ {
+ SystemWindow* pWindow = m_aBuilder.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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ ComboBox* pComboBox = dynamic_cast<ComboBox*>(pComboBoxText);
+ if (pComboBox)
+ return new SalInstanceComboBoxText<ComboBox>(pComboBox, bTakeOwnership);
+ ListBox* pListBox = dynamic_cast<ListBox*>(pComboBoxText);
+ return pListBox ? new SalInstanceComboBoxText<ListBox>(pListBox, bTakeOwnership) : nullptr;
+ }
+
+ virtual weld::TreeView* weld_tree_view(const OString &id, bool bTakeOwnership) override
+ {
+ ListBox* pTreeView = m_aBuilder.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);
+ 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);
+ 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);
+ return pDrawingArea ? new SalInstanceDrawingArea(pDrawingArea, bTakeOwnership) : nullptr;
+ }
+};
+
+weld::Builder* SalInstance::CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile)
+{
+ SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
+ vcl::Window* pParentWidget = pParentInstance ? pParentInstance->getWidget() : nullptr;
+ return new SalInstanceBuilder(pParentWidget, rUIRoot, rUIFile);
+}
+
+weld::MessageDialog* SalInstance::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonsType, const OUString& rPrimaryMessage)
+{
+ SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
+ SystemWindow* pParentWidget = pParentInstance ? pParentInstance->getSystemWindow() : nullptr;
+ VclPtrInstance<MessageDialog> xMessageDialog(pParentWidget, rPrimaryMessage, eMessageType, eButtonsType);
+ return new SalInstanceMessageDialog(xMessageDialog, true);
+}
+
+weld::Window* SalFrame::GetFrameWeld() const
+{
+ if (!m_xFrameWeld)
+ {
+ vcl::Window* pWindow = GetWindow();
+ pWindow = pWindow ? pWindow->ImplGetWindow() : nullptr;
+ SystemWindow* pSystemWindow = pWindow ? pWindow->GetSystemWindow() : nullptr;
+ if (pSystemWindow)
+ m_xFrameWeld.reset(new SalInstanceWindow(pSystemWindow, false));
+ }
+ return m_xFrameWeld.get();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
index daf90a3333bc..8e1cc649cb31 100644
--- a/vcl/source/control/combobox.cxx
+++ b/vcl/source/control/combobox.cxx
@@ -986,7 +986,7 @@ void ComboBox::SetDoubleClickHdl(const Link<ComboBox&,void>& rLink) { m_pImpl->m
const Link<ComboBox&,void>& ComboBox::GetDoubleClickHdl() const { return m_pImpl->m_DoubleClickHdl; }
-long ComboBox::CalcWindowSizePixel( sal_uInt16 nLines ) const
+long ComboBox::CalcWindowSizePixel(sal_uInt16 nLines) const
{
return m_pImpl->m_pImplLB->GetEntryHeight() * nLines;
}
diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx
index 1e5085cf007e..d04886eeb228 100644
--- a/vcl/source/control/field.cxx
+++ b/vcl/source/control/field.cxx
@@ -445,15 +445,21 @@ void FormatterBase::ImplSetText( const OUString& rText, Selection const * pNewSe
{
if ( mpField )
{
- if ( pNewSelection )
- mpField->SetText( rText, *pNewSelection );
+ if (pNewSelection)
+ mpField->SetText(rText, *pNewSelection);
else
{
Selection aSel = mpField->GetSelection();
aSel.Min() = aSel.Max();
- mpField->SetText( rText, aSel );
+ mpField->SetText(rText, aSel);
+ }
+ if (maOutputHdl.IsSet())
+ {
+ OUString sText(mpField->GetText());
+ mpField->SetText(OUString());
+ if (!maOutputHdl.Call(*mpField))
+ mpField->SetText(sText);
}
-
MarkToBeReformatted( false );
}
}
diff --git a/vcl/source/control/listbox.cxx b/vcl/source/control/listbox.cxx
index df21ca2b1741..c693223bb21a 100644
--- a/vcl/source/control/listbox.cxx
+++ b/vcl/source/control/listbox.cxx
@@ -1242,6 +1242,11 @@ Size ListBox::CalcSubEditSize() const
return aSz;
}
+long ListBox::CalcWindowSizePixel(sal_uInt16 nLines) const
+{
+ return mpImplLB->GetEntryHeight() * nLines;
+}
+
Size ListBox::GetOptimalSize() const
{
return CalcMinimumSize();
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 353db7d5c633..d36bc390f319 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -11,7 +11,9 @@
#include <com/sun/star/packages/zip/ZipFileAccess.hpp>
#include <comphelper/processfactory.hxx>
+#include <i18nutil/unicode.hxx>
#include <osl/module.hxx>
+#include <osl/file.hxx>
#include <sal/log.hxx>
#include <unotools/resmgr.hxx>
#include <vcl/builder.hxx>
@@ -37,12 +39,14 @@
#include <vcl/settings.hxx>
#include <vcl/slider.hxx>
#include <vcl/listctrl.hxx>
+#include <vcl/weld.hxx>
#include <vcl/commandinfoprovider.hxx>
#include <svdata.hxx>
#include <bitmaps.hlst>
#include <window.h>
#include <xmlreader/xmlreader.hxx>
#include <desktop/crashreport.hxx>
+#include <salinst.hxx>
#include <strings.hrc>
#include <tools/svlibrary.h>
@@ -120,6 +124,114 @@ namespace
}
#endif
+weld::Builder* Application::CreateBuilder(weld::Widget* pParent, const OUString &rUIFile)
+{
+ return ImplGetSVData()->mpDefInst->CreateBuilder(pParent, VclBuilderContainer::getUIRootDir(), rUIFile);
+}
+
+weld::MessageDialog* Application::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
+ VclButtonsType eButtonType, const OUString& rPrimaryMessage)
+{
+ return ImplGetSVData()->mpDefInst->CreateMessageDialog(pParent, eMessageType, eButtonType, rPrimaryMessage);
+}
+
+namespace
+{
+ const OUString MetricToString(FieldUnit rUnit)
+ {
+ FieldUnitStringList* pList = ImplGetFieldUnits();
+ if (pList)
+ {
+ // return unit's default string (ie, the first one )
+ for (auto it = pList->begin(); it != pList->end(); ++it)
+ {
+ if (it->second == rUnit)
+ return it->first;
+ }
+ }
+
+ return OUString();
+ }
+}
+
+namespace weld
+{
+ IMPL_LINK_NOARG(MetricSpinButton, spin_button_value_changed, SpinButton&, void)
+ {
+ signal_value_changed();
+ }
+
+ IMPL_LINK(MetricSpinButton, spin_button_output, SpinButton&, rSpinButton, void)
+ {
+ rSpinButton.set_text(format_number(rSpinButton.get_value()));
+ }
+
+ void MetricSpinButton::update_width_chars()
+ {
+ int min, max;
+ m_xSpinButton->get_range(min, max);
+ auto width = std::max(m_xSpinButton->get_pixel_size(format_number(min)).Width(),
+ m_xSpinButton->get_pixel_size(format_number(max)).Width());
+ int chars = ceil(width / m_xSpinButton->approximate_char_width());
+ m_xSpinButton->set_width_chars(chars);
+ }
+
+ unsigned int SpinButton::Power10(unsigned int n)
+ {
+ unsigned int nValue = 1;
+ for (unsigned int i = 0; i < n; ++i)
+ nValue *= 10;
+ return nValue;
+ }
+
+ int SpinButton::denormalize(int nValue) const
+ {
+ const int nFactor = Power10(get_digits());
+
+ if ((nValue < (SAL_MIN_INT32 + nFactor)) || (nValue > (SAL_MAX_INT32 - nFactor)))
+ {
+ return nValue / nFactor;
+ }
+
+ const int nHalf = nFactor / 2;
+
+ if (nValue < 0)
+ return (nValue - nHalf) / nFactor;
+ return (nValue + nHalf) / nFactor;
+ }
+
+ OUString MetricSpinButton::format_number(int nValue) const
+ {
+ OUString aStr;
+
+ unsigned int nDecimalDigits = m_xSpinButton->get_digits();
+ //pawn percent off to icu to decide whether percent is separated from its number for this locale
+ if (m_eSrcUnit == FUNIT_PERCENT)
+ {
+ double fValue = nValue;
+ fValue /= SpinButton::Power10(nDecimalDigits);
+ aStr = unicode::formatPercent(fValue, Application::GetSettings().GetUILanguageTag());
+ }
+ else
+ {
+ const SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData();
+ aStr = rLocaleData.getNum(nValue, nDecimalDigits, true, true);
+ if (m_eSrcUnit != FUNIT_NONE && m_eSrcUnit != FUNIT_DEGREE)
+ aStr += " ";
+ assert(m_eSrcUnit != FUNIT_PERCENT);
+ aStr += MetricToString(m_eSrcUnit);
+ }
+
+ return aStr;
+ }
+
+ int MetricSpinButton::ConvertValue(int nValue, FieldUnit eInUnit, FieldUnit eOutUnit) const
+ {
+ return MetricField::ConvertValue(nValue, 0, m_xSpinButton->get_digits(), eInUnit, eOutUnit);
+ }
+}
+
VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUString& sUIFile, const OString& sID, const css::uno::Reference<css::frame::XFrame>& rFrame)
: m_sID(sID)
, m_sHelpRoot(OUStringToOString(sUIFile, RTL_TEXTENCODING_UTF8))
@@ -1189,7 +1301,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
WinBits nBits = WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
if (extractResizable(rMap))
nBits |= WB_SIZEABLE;
- xWindow = VclPtr<Dialog>::Create(pParent, nBits);
+ xWindow = VclPtr<Dialog>::Create(pParent, nBits, !pParent ? Dialog::InitFlag::NoParent : Dialog::InitFlag::Default);
}
else if (name == "GtkMessageDialog")
{
@@ -1515,7 +1627,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
else if (name == "GtkDrawingArea")
{
OUString sBorder = BuilderUtils::extractCustomProperty(rMap);
- xWindow = VclPtr<vcl::Window>::Create(pParent, sBorder.isEmpty() ? 0 : WB_BORDER);
+ xWindow = VclPtr<VclDrawingArea>::Create(pParent, sBorder.isEmpty() ? 0 : WB_BORDER);
}
else if (name == "GtkTextView")
{
diff --git a/vcl/source/window/menuwindow.cxx b/vcl/source/window/menuwindow.cxx
index 8abfe172af9d..4577f38abdc1 100644
--- a/vcl/source/window/menuwindow.cxx
+++ b/vcl/source/window/menuwindow.cxx
@@ -99,9 +99,9 @@ bool MenuWindow::ImplHandleHelpEvent(vcl::Window* pMenuWindow, Menu const * pMen
aHelpId = OOO_HELP_INDEX;
if ( !aCommand.isEmpty() )
- pHelp->Start( aCommand, nullptr );
+ pHelp->Start(aCommand, static_cast<vcl::Window*>(nullptr));
else
- pHelp->Start( OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), nullptr );
+ pHelp->Start(OStringToOUString(aHelpId, RTL_TEXTENCODING_UTF8), static_cast<vcl::Window*>(nullptr));
}
bDone = true;
}
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx
index 85b72726ebc2..6aa4182b11bd 100644
--- a/vcl/source/window/window2.cxx
+++ b/vcl/source/window/window2.cxx
@@ -897,6 +897,12 @@ SalFrame* Window::ImplGetFrame() const
return mpWindowImpl ? mpWindowImpl->mpFrame : nullptr;
}
+weld::Window* Window::GetFrameWeld() const
+{
+ SalFrame* pFrame = ImplGetFrame();
+ return pFrame ? pFrame->GetFrameWeld() : nullptr;
+}
+
vcl::Window* Window::ImplGetParent() const
{
return mpWindowImpl ? mpWindowImpl->mpParent.get() : nullptr;
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index bfdba2f717c1..42c0014a81d8 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -38,6 +38,7 @@
#include <rtl/process.h>
#include <vcl/floatwin.hxx>
#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
#include <vcl/window.hxx>
#include <vcl/settings.hxx>
#include <cppuhelper/exc_hlp.hxx>
@@ -3572,6 +3573,7 @@ void GtkSalFrame::signalDestroy( GtkWidget* pObj, gpointer frame )
pThis->m_pEventBox = nullptr;
pThis->m_pTopLevelGrid = nullptr;
pThis->m_pWindow = nullptr;
+ pThis->m_xFrameWeld.reset();
pThis->InvalidateGraphics();
}
}
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 5497a3d7de4b..0acaed180b20 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -25,8 +25,14 @@
#include <comphelper/processfactory.hxx>
#include <comphelper/sequence.hxx>
#include <cppuhelper/compbase.hxx>
+#include <comphelper/string.hxx>
#include <cppuhelper/implbase.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <rtl/bootstrap.hxx>
+#include <tools/fract.hxx>
+#include <tools/stream.hxx>
+#include <vcl/pngwrite.hxx>
+#include <vcl/weld.hxx>
using namespace com::sun::star;
using namespace com::sun::star::uno;
@@ -130,7 +136,7 @@ std::vector<css::datatransfer::DataFlavor> GtkTransferable::getTransferDataFlavo
}
aFlavor.MimeType = OUString(pFinalName,
- rtl_str_getLength(pFinalName),
+ strlen(pFinalName),
RTL_TEXTENCODING_UTF8);
m_aMimeTypeToAtom[aFlavor.MimeType] = targets[i];
@@ -1148,4 +1154,1568 @@ OpenGLContext* GtkInstance::CreateOpenGLContext()
return new GtkOpenGLContext;
}
+class GtkInstanceBuilder;
+
+namespace
+{
+ OString get_help_id(const GtkWidget *pWidget)
+ {
+ void* pData = g_object_get_data(G_OBJECT(pWidget), "helpid");
+ const gchar* pStr = static_cast<const gchar*>(pData);
+ return OString(pStr, pStr ? strlen(pStr) : 0);
+ }
+}
+
+class GtkInstanceWidget : public virtual weld::Widget
+{
+protected:
+ GtkWidget* m_pWidget;
+private:
+ bool m_bTakeOwnership;
+
+public:
+ GtkInstanceWidget(GtkWidget* pWidget, bool bTakeOwnership)
+ : m_pWidget(pWidget)
+ , m_bTakeOwnership(bTakeOwnership)
+ {
+ }
+
+ virtual void set_sensitive(bool sensitive) override
+ {
+ gtk_widget_set_sensitive(m_pWidget, sensitive);
+ }
+
+ virtual bool get_sensitive() const override
+ {
+ return gtk_widget_get_sensitive(m_pWidget);
+ }
+
+ virtual void set_visible(bool visible) override
+ {
+ gtk_widget_set_visible(m_pWidget, visible);
+ }
+
+ virtual bool get_visible() const override
+ {
+ return gtk_widget_get_visible(m_pWidget);
+ }
+
+ virtual void grab_focus() override
+ {
+ gtk_widget_grab_focus(m_pWidget);
+ }
+
+ virtual bool has_focus() const override
+ {
+ return gtk_widget_has_focus(m_pWidget);
+ }
+
+ virtual void show() override
+ {
+ gtk_widget_show(m_pWidget);
+ }
+
+ virtual void hide() override
+ {
+ gtk_widget_hide(m_pWidget);
+ }
+
+ virtual void set_size_request(int nWidth, int nHeight) override
+ {
+ gtk_widget_set_size_request(m_pWidget, nWidth, nHeight);
+ }
+
+ virtual Size get_preferred_size() const override
+ {
+ GtkRequisition size;
+ gtk_widget_get_preferred_size(m_pWidget, nullptr, &size);
+ return Size(size.width, size.height);
+ }
+
+ virtual float approximate_char_width() const override
+ {
+ PangoContext* pContext = gtk_widget_get_pango_context(m_pWidget);
+ PangoFontMetrics* pMetrics = pango_context_get_metrics(pContext,
+ pango_context_get_font_description(pContext),
+ pango_context_get_language(pContext));
+ float nCharWidth = pango_font_metrics_get_approximate_char_width(pMetrics);
+ float nDigitWidth = pango_font_metrics_get_approximate_digit_width(pMetrics);
+ pango_font_metrics_unref(pMetrics);
+
+ return std::max(nCharWidth, nDigitWidth) / PANGO_SCALE;
+ }
+
+ virtual Size get_pixel_size(const OUString& rText) const override
+ {
+ OString aStr(OUStringToOString(rText, RTL_TEXTENCODING_UTF8));
+ PangoLayout* pLayout = gtk_widget_create_pango_layout(m_pWidget, aStr.getStr());
+ gint nWidth, nHeight;
+ pango_layout_get_pixel_size(pLayout, &nWidth, &nHeight);
+ g_object_unref(pLayout);
+ return Size(nWidth, nHeight);
+ }
+
+ virtual weld::Widget* weld_parent() const override
+ {
+ GtkWidget* pParent = gtk_widget_get_parent(m_pWidget);
+ return pParent ? new GtkInstanceWidget(pParent, false) : nullptr;
+ }
+
+ virtual OString get_buildable_name() const override
+ {
+ const gchar* pStr = gtk_buildable_get_name(GTK_BUILDABLE(m_pWidget));
+ return OString(pStr, pStr ? strlen(pStr) : 0);
+ }
+
+ virtual OString get_help_id() const override
+ {
+ OString sRet = ::get_help_id(m_pWidget);
+ if (sRet.isEmpty())
+ sRet = OString("null");
+ return sRet;
+ }
+
+ GtkWidget* getWidget()
+ {
+ return m_pWidget;
+ }
+
+ GtkWindow* getWindow()
+ {
+ return GTK_WINDOW(gtk_widget_get_toplevel(m_pWidget));
+ }
+
+ virtual ~GtkInstanceWidget() override
+ {
+ if (m_bTakeOwnership)
+ gtk_widget_destroy(m_pWidget);
+ }
+};
+
+class GtkInstanceContainer : public GtkInstanceWidget, public virtual weld::Container
+{
+private:
+ GtkContainer* m_pContainer;
+public:
+ GtkInstanceContainer(GtkContainer* pContainer, bool bTakeOwnership)
+ : GtkInstanceWidget(GTK_WIDGET(pContainer), bTakeOwnership)
+ , m_pContainer(pContainer)
+ {
+ (void)m_pContainer;
+ }
+};
+
+class GtkInstanceWindow : public GtkInstanceContainer, public virtual weld::Window
+{
+private:
+ GtkWindow* m_pWindow;
+
+ static void help_pressed(GtkAccelGroup*, GObject*, guint, GdkModifierType, gpointer widget)
+ {
+ GtkInstanceWindow* pThis = static_cast<GtkInstanceWindow*>(widget);
+ pThis->help();
+ }
+protected:
+ void help();
+public:
+ GtkInstanceWindow(GtkWindow* pWindow, bool bTakeOwnership)
+ : GtkInstanceContainer(GTK_CONTAINER(pWindow), bTakeOwnership)
+ , m_pWindow(pWindow)
+ {
+ //hook up F1 to show help
+ GtkAccelGroup *pGroup = gtk_accel_group_new();
+ GClosure* closure = g_cclosure_new(G_CALLBACK(help_pressed), this, nullptr);
+ gtk_accel_group_connect(pGroup, GDK_KEY_F1, static_cast<GdkModifierType>(0), GTK_ACCEL_LOCKED, closure);
+ gtk_window_add_accel_group(pWindow, pGroup);
+ }
+
+ virtual void set_title(const OUString& rTitle) override
+ {
+ gtk_window_set_title(m_pWindow, OUStringToOString(rTitle, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ virtual OUString get_title() const override
+ {
+ const gchar* pStr = gtk_window_get_title(m_pWindow);
+ return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+ }
+};
+
+class GtkInstanceDialog : public GtkInstanceWindow, public virtual weld::Dialog
+{
+private:
+ GtkDialog* m_pDialog;
+ gulong m_nCloseSignalId;
+
+ static void signalClose(GtkWidget *, gpointer widget)
+ {
+ GtkInstanceDialog* pThis = static_cast<GtkInstanceDialog*>(widget);
+ pThis->response(RET_CANCEL);
+ }
+public:
+ GtkInstanceDialog(GtkDialog* pDialog, bool bTakeOwnership)
+ : GtkInstanceWindow(GTK_WINDOW(pDialog), bTakeOwnership)
+ , m_pDialog(pDialog)
+ , m_nCloseSignalId(g_signal_connect(m_pDialog, "close", G_CALLBACK(signalClose), this))
+ {
+ }
+
+ virtual int run() override
+ {
+ int ret;
+ while (true)
+ {
+ ret = gtk_dialog_run(m_pDialog);
+ if (ret == GTK_RESPONSE_HELP)
+ {
+ help();
+ continue;
+ }
+ else if (ret == GTK_RESPONSE_OK)
+ ret = RET_OK;
+ else if (ret == GTK_RESPONSE_CANCEL)
+ ret = RET_CANCEL;
+ break;
+ }
+ hide();
+ return ret;
+ }
+
+ virtual void response(int nResponse) override
+ {
+ if (nResponse == RET_OK)
+ nResponse = GTK_RESPONSE_OK;
+ else if (nResponse == RET_CANCEL)
+ nResponse = GTK_RESPONSE_CANCEL;
+ else if (nResponse == RET_HELP)
+ nResponse = GTK_RESPONSE_HELP;
+ gtk_dialog_response(m_pDialog, nResponse);
+ }
+
+ virtual ~GtkInstanceDialog() override
+ {
+ g_signal_handler_disconnect(m_pDialog, m_nCloseSignalId);
+ }
+};
+
+class GtkInstanceMessageDialog : public GtkInstanceDialog, public virtual weld::MessageDialog
+{
+private:
+ GtkMessageDialog* m_pMessageDialog;
+public:
+ GtkInstanceMessageDialog(GtkMessageDialog* pMessageDialog, bool bTakeOwnership)
+ : GtkInstanceDialog(GTK_DIALOG(pMessageDialog), bTakeOwnership)
+ , m_pMessageDialog(pMessageDialog)
+ {
+ }
+
+ virtual void set_primary_text(const OUString& rText) override
+ {
+ g_object_set(G_OBJECT(m_pMessageDialog), "text",
+ OUStringToOString(rText, RTL_TEXTENCODING_UTF8).getStr(),
+ nullptr);
+ }
+
+ virtual OUString get_primary_text() const override
+ {
+ gchar* pText = nullptr;
+ g_object_get(G_OBJECT(m_pMessageDialog), "text", &pText, nullptr);
+ return OUString(pText, pText ? strlen(pText) : 0, RTL_TEXTENCODING_UTF8);
+ }
+
+ virtual void set_secondary_text(const OUString& rText) override
+ {
+ g_object_set(G_OBJECT(m_pMessageDialog), "secondary-text",
+ OUStringToOString(rText, RTL_TEXTENCODING_UTF8).getStr(),
+ nullptr);
+ }
+
+ virtual OUString get_secondary_text() const override
+ {
+ gchar* pText = nullptr;
+ g_object_get(G_OBJECT(m_pMessageDialog), "secondary-text", &pText, nullptr);
+ return OUString(pText, pText ? strlen(pText) : 0, RTL_TEXTENCODING_UTF8);
+ }
+};
+
+static OString MapToGtkAccelerator(const OUString &rStr)
+{
+ return OUStringToOString(rStr.replaceFirst("~", "_"), RTL_TEXTENCODING_UTF8);
+}
+
+class GtkInstanceFrame : public GtkInstanceContainer, public virtual weld::Frame
+{
+private:
+ GtkFrame* m_pFrame;
+public:
+ GtkInstanceFrame(GtkFrame* pFrame, bool bTakeOwnership)
+ : GtkInstanceContainer(GTK_CONTAINER(pFrame), bTakeOwnership)
+ , m_pFrame(pFrame)
+ {
+ }
+
+ virtual void set_label(const OUString& rText) override
+ {
+ gtk_label_set_label(GTK_LABEL(gtk_frame_get_label_widget(m_pFrame)), MapToGtkAccelerator(rText).getStr());
+ }
+
+ virtual OUString get_label() const override
+ {
+ const gchar* pStr = gtk_frame_get_label(m_pFrame);
+ return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+ }
+};
+
+class GtkInstanceNotebook : public GtkInstanceContainer, public virtual weld::Notebook
+{
+private:
+ GtkNotebook* m_pNotebook;
+ gulong m_nSignalId;
+ mutable std::vector<std::unique_ptr<GtkInstanceContainer>> m_aPages;
+
+ static void signalSwitchPage(GtkNotebook*, GtkWidget*, guint nNewPage, gpointer widget)
+ {
+ GtkInstanceNotebook* pThis = static_cast<GtkInstanceNotebook*>(widget);
+ pThis->signal_switch_page(nNewPage);
+ }
+
+ void signal_switch_page(guint nNewPage)
+ {
+ bool bAllow = m_aLeavePageHdl.Call(get_current_page_ident());
+ if (!bAllow)
+ {
+ g_signal_stop_emission_by_name(m_pNotebook, "switch-page");
+ OString sNewIdent(get_page_ident(nNewPage));
+ m_aEnterPageHdl.Call(sNewIdent);
+ }
+ }
+
+ OString get_page_ident(guint nPage) const
+ {
+ const GtkWidget* pTabWidget = gtk_notebook_get_tab_label(m_pNotebook, gtk_notebook_get_nth_page(m_pNotebook, nPage));
+ const gchar* pStr = gtk_buildable_get_name(GTK_BUILDABLE(pTabWidget));
+ return OString(pStr, pStr ? strlen(pStr) : 0);
+ }
+
+ gint get_page_number(const OString& rIdent) const
+ {
+ gint nPages = gtk_notebook_get_n_pages(m_pNotebook);
+ for (gint i = 0; i < nPages; ++i)
+ {
+ const GtkWidget* pTabWidget = gtk_notebook_get_tab_label(m_pNotebook, gtk_notebook_get_nth_page(m_pNotebook, i));
+ const gchar* pStr = gtk_buildable_get_name(GTK_BUILDABLE(pTabWidget));
+ if (strcmp(pStr, rIdent.getStr()) == 0)
+ return i;
+ }
+ return -1;
+ }
+
+public:
+ GtkInstanceNotebook(GtkNotebook* pNotebook, bool bTakeOwnership)
+ : GtkInstanceContainer(GTK_CONTAINER(pNotebook), bTakeOwnership)
+ , m_pNotebook(pNotebook)
+ , m_nSignalId(g_signal_connect(pNotebook, "switch-page", G_CALLBACK(signalSwitchPage), this))
+ {
+ }
+
+ virtual int get_current_page() const override
+ {
+ return gtk_notebook_get_current_page(m_pNotebook);
+ }
+
+ virtual OString get_current_page_ident() const override
+ {
+ return get_page_ident(get_current_page());
+ }
+
+ virtual weld::Container* get_page(const OString& rIdent) const override
+ {
+ int nPage = get_page_number(rIdent);
+ if (nPage < 0)
+ return nullptr;
+ GtkContainer* pChild = GTK_CONTAINER(gtk_notebook_get_nth_page(m_pNotebook, nPage));
+ unsigned int nPageIndex = static_cast<unsigned int>(nPage);
+ if (m_aPages.size() < nPageIndex + 1)
+ m_aPages.resize(nPageIndex + 1);
+ if (!m_aPages[nPageIndex])
+ m_aPages[nPageIndex].reset(new GtkInstanceContainer(pChild, false));
+ return m_aPages[nPageIndex].get();
+ }
+
+ virtual void set_current_page(int nPage) override
+ {
+ gtk_notebook_set_current_page(m_pNotebook, nPage);
+ }
+
+ virtual void set_current_page(const OString& rIdent) override
+ {
+ gint nPage = get_page_number(rIdent);
+ set_current_page(nPage);
+ }
+
+ virtual int get_n_pages() const override
+ {
+ return gtk_notebook_get_n_pages(m_pNotebook);
+ }
+
+ virtual ~GtkInstanceNotebook() override
+ {
+ g_signal_handler_disconnect(m_pNotebook, m_nSignalId);
+ }
+};
+
+class GtkInstanceButton : public GtkInstanceContainer, public virtual weld::Button
+{
+private:
+ GtkButton* m_pButton;
+ gulong m_nSignalId;
+
+ static void signalClicked(GtkButton*, gpointer widget)
+ {
+ GtkInstanceButton* pThis = static_cast<GtkInstanceButton*>(widget);
+ pThis->signal_clicked();
+ }
+public:
+ GtkInstanceButton(GtkButton* pButton, bool bTakeOwnership)
+ : GtkInstanceContainer(GTK_CONTAINER(pButton), bTakeOwnership)
+ , m_pButton(pButton)
+ , m_nSignalId(g_signal_connect(pButton, "clicked", G_CALLBACK(signalClicked), this))
+ {
+ }
+
+ virtual void set_label(const OUString& rText) override
+ {
+ gtk_button_set_label(m_pButton, MapToGtkAccelerator(rText).getStr());
+ }
+
+ virtual OUString get_label() const override
+ {
+ const gchar* pStr = gtk_button_get_label(m_pButton);
+ return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+ }
+
+ virtual ~GtkInstanceButton() override
+ {
+ g_signal_handler_disconnect(m_pButton, m_nSignalId);
+ }
+};
+
+class GtkInstanceToggleButton : public GtkInstanceButton, public virtual weld::ToggleButton
+{
+private:
+ GtkToggleButton* m_pToggleButton;
+ gulong m_nSignalId;
+
+ static void signalToggled(GtkToggleButton*, gpointer widget)
+ {
+ GtkInstanceToggleButton* pThis = static_cast<GtkInstanceToggleButton*>(widget);
+ pThis->signal_toggled();
+ }
+public:
+ GtkInstanceToggleButton(GtkToggleButton* pButton, bool bTakeOwnership)
+ : GtkInstanceButton(GTK_BUTTON(pButton), bTakeOwnership)
+ , m_pToggleButton(pButton)
+ , m_nSignalId(g_signal_connect(m_pToggleButton, "toggled", G_CALLBACK(signalToggled), this))
+ {
+ }
+
+ virtual void set_active(bool active) override
+ {
+ gtk_toggle_button_set_active(m_pToggleButton, active);
+ }
+
+ virtual bool get_active() const override
+ {
+ return gtk_toggle_button_get_active(m_pToggleButton);
+ }
+
+ virtual void set_inconsistent(bool inconsistent) override
+ {
+ gtk_toggle_button_set_inconsistent(m_pToggleButton, inconsistent);
+ }
+
+ virtual bool get_inconsistent() const override
+ {
+ return gtk_toggle_button_get_inconsistent(m_pToggleButton);
+ }
+
+ virtual ~GtkInstanceToggleButton() override
+ {
+ g_signal_handler_disconnect(m_pToggleButton, m_nSignalId);
+ }
+};
+
+class GtkInstanceRadioButton : public GtkInstanceToggleButton, public virtual weld::RadioButton
+{
+public:
+ GtkInstanceRadioButton(GtkRadioButton* pButton, bool bTakeOwnership)
+ : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(pButton), bTakeOwnership)
+ {
+ }
+};
+
+class GtkInstanceCheckButton : public GtkInstanceToggleButton, public virtual weld::CheckButton
+{
+public:
+ GtkInstanceCheckButton(GtkCheckButton* pButton, bool bTakeOwnership)
+ : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(pButton), bTakeOwnership)
+ {
+ }
+};
+
+class GtkInstanceEntry : public GtkInstanceWidget, public virtual weld::Entry
+{
+private:
+ GtkEntry* m_pEntry;
+ gulong m_nChangedSignalId;
+ gulong m_nInsertTextSignalId;
+
+ static void signalChanged(GtkEntry*, gpointer widget)
+ {
+ GtkInstanceEntry* pThis = static_cast<GtkInstanceEntry*>(widget);
+ pThis->signal_changed();
+ }
+
+ static void signalInsertText(GtkEntry* pEntry, const gchar* pNewText, gint nNewTextLength,
+ gint* position, gpointer widget)
+ {
+ GtkInstanceEntry* pThis = static_cast<GtkInstanceEntry*>(widget);
+ pThis->signal_insert_text(pEntry, pNewText, nNewTextLength, position);
+ }
+
+ void signal_insert_text(GtkEntry* pEntry, const gchar* pNewText, gint nNewTextLength, gint* position)
+ {
+ if (!m_aInsertTextHdl.IsSet())
+ return;
+ OUString sText(pNewText, nNewTextLength, RTL_TEXTENCODING_UTF8);
+ const bool bContinue = m_aInsertTextHdl.Call(sText);
+ if (bContinue && !sText.isEmpty())
+ {
+ OString sFinalText(OUStringToOString(sText, RTL_TEXTENCODING_UTF8));
+ g_signal_handlers_block_by_func(pEntry, gpointer(signalInsertText), this);
+ gtk_editable_insert_text(GTK_EDITABLE(pEntry), sFinalText.getStr(), sFinalText.getLength(), position);
+ g_signal_handlers_unblock_by_func(pEntry, gpointer(signalInsertText), this);
+ }
+ g_signal_stop_emission_by_name(pEntry, "insert-text");
+ }
+public:
+ GtkInstanceEntry(GtkEntry* pEntry, bool bTakeOwnership)
+ : GtkInstanceWidget(GTK_WIDGET(pEntry), bTakeOwnership)
+ , m_pEntry(pEntry)
+ , m_nChangedSignalId(g_signal_connect(pEntry, "changed", G_CALLBACK(signalChanged), this))
+ , m_nInsertTextSignalId(g_signal_connect(pEntry, "insert-text", G_CALLBACK(signalInsertText), this))
+ {
+ }
+
+ virtual void set_text(const OUString& rText) override
+ {
+ gtk_entry_set_text(m_pEntry, OUStringToOString(rText, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ virtual OUString get_text() const override
+ {
+ const gchar* pText = gtk_entry_get_text(m_pEntry);
+ OUString sRet(pText, pText ? strlen(pText) : 0, RTL_TEXTENCODING_UTF8);
+ return sRet;
+ }
+
+ virtual void set_width_chars(int nChars) override
+ {
+ gtk_entry_set_width_chars(m_pEntry, nChars);
+ }
+
+ virtual ~GtkInstanceEntry() override
+ {
+ g_signal_handler_disconnect(m_pEntry, m_nInsertTextSignalId);
+ g_signal_handler_disconnect(m_pEntry, m_nChangedSignalId);
+ }
+};
+
+namespace
+{
+ struct Search
+ {
+ OString str;
+ int index = -1;
+ Search(const OUString& rText)
+ : str(OUStringToOString(rText, RTL_TEXTENCODING_UTF8))
+ , index(-1)
+ {
+ }
+ };
+
+ gboolean foreach_find(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer data)
+ {
+ Search* search = static_cast<Search*>(data);
+ gchar *pStr = nullptr;
+ gtk_tree_model_get(model, iter, 0, &pStr, -1);
+ bool found = strcmp(pStr, search->str.getStr()) == 0;
+ if (found)
+ search->index = gtk_tree_path_get_indices(path)[0];
+ g_free(pStr);
+ return found;
+ }
+}
+
+class GtkInstanceTreeView : public GtkInstanceContainer, public virtual weld::TreeView
+{
+private:
+ GtkTreeView* m_pTreeView;
+ GtkListStore* m_pListStore;
+ gulong m_nChangedSignalId;
+ gulong m_nRowActivatedSignalId;
+
+ static void signalChanged(GtkTreeView*, gpointer widget)
+ {
+ GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
+ pThis->signal_changed();
+ }
+
+ static void signalRowActivated(GtkTreeView*, gpointer widget)
+ {
+ GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
+ pThis->signal_row_activated();
+ }
+public:
+ GtkInstanceTreeView(GtkTreeView* pTreeView, bool bTakeOwnership)
+ : GtkInstanceContainer(GTK_CONTAINER(pTreeView), bTakeOwnership)
+ , m_pTreeView(pTreeView)
+ , m_pListStore(GTK_LIST_STORE(gtk_tree_view_get_model(m_pTreeView)))
+ , m_nChangedSignalId(g_signal_connect(gtk_tree_view_get_selection(pTreeView), "changed",
+ G_CALLBACK(signalChanged), this))
+ , m_nRowActivatedSignalId(g_signal_connect(pTreeView, "row-activated", G_CALLBACK(signalRowActivated), this))
+ {
+ }
+
+ virtual void append(const OUString& rText) override
+ {
+ insert(rText, -1);
+ }
+
+ virtual void insert(const OUString& rText, int pos) override
+ {
+ GtkTreeIter iter;
+ gtk_list_store_insert(m_pListStore, &iter, pos);
+ gtk_list_store_set(m_pListStore, &iter, 0, OUStringToOString(rText, RTL_TEXTENCODING_UTF8).getStr(), -1);
+ }
+
+ virtual void remove(int pos) override
+ {
+ GtkTreeIter iter;
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pListStore), &iter, nullptr, pos);
+ gtk_list_store_remove(m_pListStore, &iter);
+ }
+
+ virtual int find(const OUString& rText) const override
+ {
+ Search aSearch(rText);
+ gtk_tree_model_foreach(GTK_TREE_MODEL(m_pListStore), foreach_find, &aSearch);
+ return aSearch.index;
+ }
+
+ void move_before(int pos, int before)
+ {
+ if (pos == before)
+ return;
+
+ GtkTreeIter iter;
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pListStore), &iter, nullptr, pos);
+
+ GtkTreeIter position;
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pListStore), &position, nullptr, before);
+
+ gtk_list_store_move_before(m_pListStore, &iter, &position);
+ }
+
+ virtual void set_top_entry(int pos) override
+ {
+ move_before(pos, 0);
+ }
+
+ virtual void clear() override
+ {
+ gtk_list_store_clear(m_pListStore);
+ }
+
+ virtual int n_children() const override
+ {
+ return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(m_pListStore), nullptr);
+ }
+
+ virtual void select(int pos) override
+ {
+ if (pos != -1)
+ {
+ GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
+ gtk_tree_selection_select_path(gtk_tree_view_get_selection(m_pTreeView), path);
+ gtk_tree_path_free(path);
+ }
+ else
+ {
+ gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(m_pTreeView));
+ }
+ }
+
+ virtual OUString get_selected() override
+ {
+ OUString sRet;
+ GtkTreeIter iter;
+ GtkTreeModel* pModel;
+ if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(m_pTreeView), &pModel, &iter))
+ {
+ gchar *pStr = nullptr;
+ gtk_tree_model_get(pModel, &iter, 0, &pStr, -1);
+ sRet = OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+ g_free(pStr);
+ }
+ return sRet;
+ }
+
+ virtual OUString get(int pos) override
+ {
+ GtkTreeIter iter;
+ gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_pListStore), &iter, nullptr, pos);
+ gchar *pStr = nullptr;
+ gtk_tree_model_get(GTK_TREE_MODEL(m_pListStore), &iter, 0, &pStr, -1);
+ OUString sRet = OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+ g_free(pStr);
+ return sRet;
+ }
+
+ virtual int get_selected_index() override
+ {
+ int nRet = -1;
+ GtkTreeIter iter;
+ GtkTreeModel* pModel;
+ if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(m_pTreeView), &pModel, &iter))
+ {
+ GtkTreePath* path = gtk_tree_model_get_path(pModel, &iter);
+ nRet = gtk_tree_path_get_indices(path)[0];
+ gtk_tree_path_free(path);
+ }
+ return nRet;
+ }
+
+ virtual void freeze() override
+ {
+ g_object_ref(m_pListStore);
+ gtk_tree_view_set_model(m_pTreeView, nullptr);
+ }
+
+ virtual void thaw() override
+ {
+ gtk_tree_view_set_model(m_pTreeView, GTK_TREE_MODEL(m_pListStore));
+ g_object_unref(m_pListStore);
+ }
+
+ virtual int get_height_rows(int nRows) const override
+ {
+ GtkTreeViewColumn* pColumn = gtk_tree_view_get_column(m_pTreeView, 0);
+ GList *pRenderers = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(pColumn));
+ GtkCellRenderer* pRenderer = GTK_CELL_RENDERER(g_list_nth_data(pRenderers, 0));
+ gint nRowHeight;
+ gtk_cell_renderer_get_preferred_height(pRenderer, GTK_WIDGET(m_pTreeView), nullptr, &nRowHeight);
+ g_list_free(pRenderers);
+
+ gint nVerticalSeparator;
+ gtk_widget_style_get(GTK_WIDGET(m_pTreeView), "vertical-separator", &nVerticalSeparator, nullptr);
+
+ return (nRowHeight * nRows) + (nVerticalSeparator * (nRows + 1));
+ }
+
+ virtual ~GtkInstanceTreeView() override
+ {
+ g_signal_handler_disconnect(gtk_tree_view_get_selection(m_pTreeView), m_nChangedSignalId);
+ g_signal_handler_disconnect(m_pTreeView, m_nRowActivatedSignalId);
+ }
+};
+
+
+class GtkInstanceSpinButton : public GtkInstanceEntry, public virtual weld::SpinButton
+{
+private:
+ GtkSpinButton* m_pButton;
+ gulong m_nValueChangedSignalId;
+ gulong m_nOutputSignalId;
+
+ static void signalValueChanged(GtkSpinButton*, gpointer widget)
+ {
+ GtkInstanceSpinButton* pThis = static_cast<GtkInstanceSpinButton*>(widget);
+ pThis->signal_value_changed();
+ }
+
+ static gboolean signalOutput(GtkSpinButton*, gpointer widget)
+ {
+ GtkInstanceSpinButton* pThis = static_cast<GtkInstanceSpinButton*>(widget);
+ return pThis->signal_output();
+ }
+
+ double toGtk(int nValue) const
+ {
+ return static_cast<double>(nValue) / Power10(get_digits());
+ }
+
+ int fromGtk(double fValue) const
+ {
+ return FRound(fValue * Power10(get_digits()));
+ }
+
+public:
+ GtkInstanceSpinButton(GtkSpinButton* pButton, bool bTakeOwnership)
+ : GtkInstanceEntry(GTK_ENTRY(pButton), bTakeOwnership)
+ , m_pButton(pButton)
+ , m_nValueChangedSignalId(g_signal_connect(pButton, "value-changed", G_CALLBACK(signalValueChanged), this))
+ , m_nOutputSignalId(g_signal_connect(pButton, "output", G_CALLBACK(signalOutput), this))
+ {
+ }
+
+ virtual int get_value() const override
+ {
+ return fromGtk(gtk_spin_button_get_value(m_pButton));
+ }
+
+ virtual void set_value(int value) override
+ {
+ gtk_spin_button_set_value(m_pButton, toGtk(value));
+ }
+
+ virtual void set_range(int min, int max) override
+ {
+ gtk_spin_button_set_range(m_pButton, toGtk(min), toGtk(max));
+ }
+
+ virtual void get_range(int& min, int& max) const override
+ {
+ double gtkmin, gtkmax;
+ gtk_spin_button_get_range(m_pButton, &gtkmin, &gtkmax);
+ min = fromGtk(gtkmin);
+ max = fromGtk(gtkmax);
+ }
+
+ virtual void set_increments(int step, int page) override
+ {
+ gtk_spin_button_set_increments(m_pButton, toGtk(step), toGtk(page));
+ }
+
+ virtual void get_increments(int& step, int& page) const override
+ {
+ double gtkstep, gtkpage;
+ gtk_spin_button_get_increments(m_pButton, &gtkstep, &gtkpage);
+ step = fromGtk(gtkstep);
+ page = fromGtk(gtkpage);
+ }
+
+ virtual void set_digits(unsigned int digits) override
+ {
+ gtk_spin_button_set_digits(m_pButton, digits);
+ }
+
+ virtual unsigned int get_digits() const override
+ {
+ return gtk_spin_button_get_digits(m_pButton);
+ }
+
+ virtual ~GtkInstanceSpinButton() override
+ {
+ g_signal_handler_disconnect(m_pButton, m_nOutputSignalId);
+ g_signal_handler_disconnect(m_pButton, m_nValueChangedSignalId);
+ }
+};
+
+class GtkInstanceLabel : public GtkInstanceWidget, public virtual weld::Label
+{
+private:
+ GtkLabel* m_pLabel;
+public:
+ GtkInstanceLabel(GtkLabel* pLabel, bool bTakeOwnership)
+ : GtkInstanceWidget(GTK_WIDGET(pLabel), bTakeOwnership)
+ , m_pLabel(pLabel)
+ {
+ }
+
+ virtual void set_label(const OUString& rText) override
+ {
+ gtk_label_set_label(m_pLabel, MapToGtkAccelerator(rText).getStr());
+ }
+};
+
+class GtkInstanceTextView : public GtkInstanceContainer, public virtual weld::TextView
+{
+private:
+ GtkTextView* m_pTextView;
+public:
+ GtkInstanceTextView(GtkTextView* pTextView, bool bTakeOwnership)
+ : GtkInstanceContainer(GTK_CONTAINER(pTextView), bTakeOwnership)
+ , m_pTextView(pTextView)
+ {
+ }
+
+ virtual void set_text(const OUString& rText) override
+ {
+ GtkTextBuffer* pBuffer = gtk_text_view_get_buffer(m_pTextView);
+ OString sText(OUStringToOString(rText, RTL_TEXTENCODING_UTF8));
+ gtk_text_buffer_set_text(pBuffer, sText.getStr(), sText.getLength());
+ }
+
+ virtual OUString get_text() const override
+ {
+ GtkTextBuffer* pBuffer = gtk_text_view_get_buffer(m_pTextView);
+ GtkTextIter start, end;
+ gtk_text_buffer_get_bounds(pBuffer, &start, &end);
+ char* pStr = gtk_text_buffer_get_text(pBuffer, &start, &end, true);
+ OUString sRet = OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
+ g_free(pStr);
+ return sRet;
+ }
+
+ virtual Selection get_selection() const override
+ {
+ GtkTextBuffer* pBuffer = gtk_text_view_get_buffer(m_pTextView);
+ GtkTextIter start, end;
+ gtk_text_buffer_get_selection_bounds(pBuffer, &start, &end);
+ return Selection(gtk_text_iter_get_offset(&start), gtk_text_iter_get_offset(&end));
+ }
+
+ virtual void set_selection(const Selection& rSelection) override
+ {
+ GtkTextBuffer* pBuffer = gtk_text_view_get_buffer(m_pTextView);
+ GtkTextIter start, end;
+ gtk_text_buffer_get_iter_at_offset(pBuffer, &start, rSelection.Min());
+ gtk_text_buffer_get_iter_at_offset(pBuffer, &end, rSelection.Max());
+ gtk_text_buffer_select_range(pBuffer, &start, &end);
+ GtkTextMark* mark = gtk_text_buffer_create_mark(pBuffer, "scroll", &end, true);
+ gtk_text_view_scroll_mark_onscreen(m_pTextView, mark);
+ }
+
+};
+
+class GtkInstanceDrawingArea : public GtkInstanceWidget, public virtual weld::DrawingArea
+{
+private:
+ GtkDrawingArea* m_pDrawingArea;
+ ScopedVclPtrInstance<VirtualDevice> m_xDevice;
+ std::vector<unsigned char> m_aBuffer;
+ cairo_surface_t* m_pSurface;
+ gulong m_nDrawSignalId;
+ gulong m_nSizeAllocateSignalId;
+ static gboolean signalDraw(GtkWidget*, cairo_t* cr, gpointer widget)
+ {
+ GtkInstanceDrawingArea* pThis = static_cast<GtkInstanceDrawingArea*>(widget);
+ pThis->signal_draw(cr);
+ return false;
+ }
+ static void signalSizeAllocate(GtkWidget*, GdkRectangle* allocation, gpointer widget)
+ {
+ GtkInstanceDrawingArea* pThis = static_cast<GtkInstanceDrawingArea*>(widget);
+ pThis->signal_size_allocate(allocation->width, allocation->height);
+ }
+ void signal_size_allocate(guint nWidth, guint nHeight)
+ {
+ if (m_pSurface)
+ cairo_surface_destroy(m_pSurface);
+
+ const int nScale = gtk_widget_get_scale_factor(GTK_WIDGET(m_pDrawingArea));
+ const int nStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, nWidth * nScale);
+ m_aBuffer.resize(nHeight * nScale * nStride);
+ m_xDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nWidth, nHeight), Fraction(1.0), Point(),
+ m_aBuffer.data());
+ m_pSurface = cairo_image_surface_create_for_data(m_aBuffer.data(), CAIRO_FORMAT_ARGB32,
+ nWidth * nScale, nHeight * nScale, nStride);
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
+ cairo_surface_set_device_scale(m_pSurface, nScale, nScale);
+#endif
+ m_aSizeAllocateHdl.Call(Size(nWidth, nHeight));
+ }
+ void signal_draw(cairo_t* cr)
+ {
+ m_aDrawHdl.Call(*m_xDevice);
+ cairo_surface_mark_dirty(m_pSurface);
+
+ cairo_set_source_surface(cr, m_pSurface, 0, 0);
+ cairo_paint(cr);
+ }
+public:
+ GtkInstanceDrawingArea(GtkDrawingArea* pDrawingArea, bool bTakeOwnership)
+ : GtkInstanceWidget(GTK_WIDGET(pDrawingArea), bTakeOwnership)
+ , m_pDrawingArea(pDrawingArea)
+ , m_xDevice(nullptr, Size(1, 1), DeviceFormat::DEFAULT)
+ , m_pSurface(nullptr)
+ , m_nDrawSignalId(g_signal_connect(pDrawingArea, "draw", G_CALLBACK(signalDraw), this))
+ , m_nSizeAllocateSignalId(g_signal_connect(pDrawingArea, "size_allocate", G_CALLBACK(signalSizeAllocate), this))
+ {
+ }
+
+ virtual void queue_draw() override
+ {
+ gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea));
+ }
+
+ virtual ~GtkInstanceDrawingArea() override
+ {
+ if (m_pSurface)
+ cairo_surface_destroy(m_pSurface);
+ g_signal_handler_disconnect(m_pDrawingArea, m_nSizeAllocateSignalId);
+ g_signal_handler_disconnect(m_pDrawingArea, m_nDrawSignalId);
+ }
+};
+
+namespace
+{
+ gint sort_func(GtkTreeModel* pModel, GtkTreeIter* a, GtkTreeIter* b, gpointer data)
+ {
+ comphelper::string::NaturalStringSorter* pSorter = static_cast<comphelper::string::NaturalStringSorter*>(data);
+ gchar* pName1;
+ gchar* pName2;
+ gtk_tree_model_get(pModel, a, 0, &pName1, -1);
+ gtk_tree_model_get(pModel, b, 0, &pName2, -1);
+ gint ret = pSorter->compare(OUString(pName1, strlen(pName1), RTL_TEXTENCODING_UTF8),
+ OUString(pName2, strlen(pName2), RTL_TEXTENCODING_UTF8));
+ g_free(pName1);
+ g_free(pName2);
+ return ret;
+ }
+}
+
+class GtkInstanceComboBoxText : public GtkInstanceContainer, public virtual weld::ComboBoxText
+{
+private:
+ GtkComboBoxText* m_pComboBoxText;
+ std::unique_ptr<comphelper::string::NaturalStringSorter> m_xSorter;
+ gulong m_nSignalId;
+
+ static void signalChanged(GtkComboBox*, gpointer widget)
+ {
+ GtkInstanceComboBoxText* pThis = static_cast<GtkInstanceComboBoxText*>(widget);
+ pThis->signal_changed();
+ }
+
+ OUString get(int pos, int col) const
+ {
+ OUString sRet;
+ GtkTreeModel *pModel = gtk_combo_box_get_model(GTK_COMBO_BOX(m_pComboBoxText));
+ GtkTreeIter iter;
+ if (gtk_tree_model_iter_nth_child(pModel, &iter, nullptr, pos))
+ {
+ gchar* pStr;
+ gtk_tree_model_get(pModel, &iter, col, &pStr, -1);
+ sRet = OUString(pStr, strlen(pStr), RTL_TEXTENCODING_UTF8);
+ g_free(pStr);
+ }
+ return sRet;
+ }
+
+public:
+ GtkInstanceComboBoxText(GtkComboBoxText* pComboBoxText, bool bTakeOwnership)
+ : GtkInstanceContainer(GTK_CONTAINER(pComboBoxText), bTakeOwnership)
+ , m_pComboBoxText(pComboBoxText)
+ , m_nSignalId(g_signal_connect(pComboBoxText, "changed", G_CALLBACK(signalChanged), this))
+ {
+ }
+
+ virtual int get_active() const override
+ {
+ return gtk_combo_box_get_active(GTK_COMBO_BOX(m_pComboBoxText));
+ }
+
+ virtual OUString get_active_id() const override
+ {
+ const gchar* pText = gtk_combo_box_get_active_id(GTK_COMBO_BOX(m_pComboBoxText));
+ return OUString(pText, strlen(pText), RTL_TEXTENCODING_UTF8);
+ }
+
+ virtual void set_active_id(const OUString& rStr) override
+ {
+ OString aId(OUStringToOString(rStr, RTL_TEXTENCODING_UTF8));
+ gtk_combo_box_set_active_id(GTK_COMBO_BOX(m_pComboBoxText), aId.getStr());
+ }
+
+ virtual void set_active(int pos) override
+ {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(m_pComboBoxText), pos);
+ }
+
+ virtual OUString get_active_text() const override
+ {
+ gchar* pText = gtk_combo_box_text_get_active_text(m_pComboBoxText);
+ OUString sRet(pText, pText ? strlen(pText) : 0, RTL_TEXTENCODING_UTF8);
+ g_free(pText);
+ return sRet;
+ }
+
+ virtual OUString get_text(int pos) const override
+ {
+ return get(pos, 0);
+ }
+
+ virtual OUString get_id(int pos) const override
+ {
+ gint id_column = gtk_combo_box_get_id_column(GTK_COMBO_BOX(m_pComboBoxText));
+ return get(pos, id_column);
+ }
+
+ virtual void append_text(const OUString& rStr) override
+ {
+ gtk_combo_box_text_append_text(m_pComboBoxText, OUStringToOString(rStr, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ virtual void insert_text(int pos, const OUString& rStr) override
+ {
+ gtk_combo_box_text_insert_text(m_pComboBoxText, pos, OUStringToOString(rStr, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ virtual void append(const OUString& rId, const OUString& rStr) override
+ {
+ gtk_combo_box_text_append(m_pComboBoxText,
+ OUStringToOString(rId, RTL_TEXTENCODING_UTF8).getStr(),
+ OUStringToOString(rStr, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ virtual void insert(int pos, const OUString& rId, const OUString& rStr) override
+ {
+ gtk_combo_box_text_insert(m_pComboBoxText, pos,
+ OUStringToOString(rId, RTL_TEXTENCODING_UTF8).getStr(),
+ OUStringToOString(rStr, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ virtual int get_count() const override
+ {
+ GtkTreeModel *pModel = gtk_combo_box_get_model(GTK_COMBO_BOX(m_pComboBoxText));
+ return gtk_tree_model_iter_n_children(pModel, nullptr);
+ }
+
+ virtual int find_text(const OUString& rStr) const override
+ {
+ GtkTreeModel *pModel = gtk_combo_box_get_model(GTK_COMBO_BOX(m_pComboBoxText));
+ GtkTreeIter iter;
+ if (!gtk_tree_model_get_iter_first(pModel, &iter))
+ return -1;
+
+ OString aStr(OUStringToOString(rStr, RTL_TEXTENCODING_UTF8).getStr());
+ int nRet = 0;
+ do
+ {
+ gchar* pStr;
+ gtk_tree_model_get(pModel, &iter, 0, &pStr, -1);
+ const bool bEqual = strcmp(pStr, aStr.getStr()) == 0;
+ g_free(pStr);
+ if (bEqual)
+ return nRet;
+ ++nRet;
+ } while (gtk_tree_model_iter_next(pModel, &iter));
+
+ return -1;
+ }
+
+ virtual void clear() override
+ {
+ GtkTreeModel *pModel = gtk_combo_box_get_model(GTK_COMBO_BOX(m_pComboBoxText));
+ gtk_list_store_clear(GTK_LIST_STORE(pModel));
+ }
+
+ virtual void make_sorted() override
+ {
+ m_xSorter.reset(new comphelper::string::NaturalStringSorter(
+ ::comphelper::getProcessComponentContext(),
+ Application::GetSettings().GetLanguageTag().getLocale()));
+ GtkTreeModel* pModel = gtk_combo_box_get_model(GTK_COMBO_BOX(m_pComboBoxText));
+ GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(pModel);
+ gtk_tree_sortable_set_sort_func(pSortable, 0, sort_func, m_xSorter.get(), nullptr);
+ gtk_tree_sortable_set_sort_column_id(pSortable, 0, GTK_SORT_ASCENDING);
+ }
+
+ virtual ~GtkInstanceComboBoxText() override
+ {
+ g_signal_handler_disconnect(m_pComboBoxText, m_nSignalId);
+ }
+};
+
+namespace
+{
+ gboolean signalTooltipQuery(GtkWidget* pWidget, gint /*x*/, gint /*y*/,
+ gboolean /*keyboard_mode*/, GtkTooltip *tooltip)
+ {
+ const ImplSVData* pSVData = ImplGetSVData();
+ if (pSVData->maHelpData.mbBalloonHelp)
+ {
+ AtkObject* pAtkObject = gtk_widget_get_accessible(pWidget);
+ const char* pDesc = pAtkObject ? atk_object_get_description(pAtkObject) : nullptr;
+ if (pDesc)
+ {
+ gtk_tooltip_set_text(tooltip, pDesc);
+ return true;
+ }
+ }
+
+ const char* pDesc = gtk_widget_get_tooltip_text(pWidget);
+ if (pDesc)
+ {
+ gtk_tooltip_set_text(tooltip, pDesc);
+ return true;
+ }
+
+ return false;
+ }
+
+ void postprocess(gpointer data, gpointer user_data)
+ {
+ GObject* pObject = static_cast<GObject*>(data);
+ if (!GTK_IS_WIDGET(pObject))
+ return;
+ OString* pHelpRoot = static_cast<OString*>(user_data);
+ //fixup icons
+ //wanted: better way to do this, e.g. make gtk use gio for
+ //loading from a filename and provide gio protocol handler
+ //for our image in a zip urls
+ //
+ //unpack the images and keep them as dirs and just
+ //add the paths to the gtk icon theme dir
+ if (GTK_IS_IMAGE(pObject))
+ {
+ GtkImage* pImage = GTK_IMAGE(pObject);
+ const gchar* icon_name;
+ gtk_image_get_icon_name(pImage, &icon_name, nullptr);
+ GtkIconSize size;
+ g_object_get(pImage, "icon-size", &size, nullptr);
+ if (icon_name)
+ {
+ OUString aIconName(icon_name, strlen(icon_name), RTL_TEXTENCODING_UTF8);
+
+ SvMemoryStream aMemStm;
+ BitmapEx aBitmap(aIconName);
+ vcl::PNGWriter aWriter(aBitmap);
+ aWriter.Write(aMemStm);
+
+ GdkPixbufLoader *pixbuf_loader = gdk_pixbuf_loader_new();
+ gdk_pixbuf_loader_write(pixbuf_loader, static_cast<const guchar*>(aMemStm.GetData()),
+ aMemStm.Seek(STREAM_SEEK_TO_END), nullptr);
+ gdk_pixbuf_loader_close(pixbuf_loader, nullptr);
+ GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(pixbuf_loader);
+
+ gtk_image_set_from_pixbuf(pImage, pixbuf);
+ g_object_unref(pixbuf_loader);
+ }
+ }
+ //set helpids
+ GtkWidget* pWidget = GTK_WIDGET(pObject);
+ const gchar* pStr = gtk_buildable_get_name(GTK_BUILDABLE(pWidget));
+ size_t nLen = pStr ? strlen(pStr) : 0;
+ if (!nLen)
+ return;
+ OString sHelpId = *pHelpRoot + OString(pStr, nLen);
+ gchar *helpid = g_strdup(sHelpId.getStr());
+ g_object_set_data_full(pObject, "helpid", helpid, g_free);
+ //hook up for extended help
+ const ImplSVData* pSVData = ImplGetSVData();
+ if (pSVData->maHelpData.mbBalloonHelp)
+ {
+ AtkObject* pAtkObject = gtk_widget_get_accessible(pWidget);
+ if (pAtkObject && atk_object_get_description(pAtkObject))
+ {
+ gtk_widget_set_has_tooltip(pWidget, true);
+ g_signal_connect(pObject, "query-tooltip", G_CALLBACK(signalTooltipQuery), nullptr);
+ }
+ }
+ }
+
+ void destroy_toplevels(gpointer data, gpointer /*user_data*/)
+ {
+ GObject* pObject = static_cast<GObject*>(data);
+ if (!GTK_IS_WINDOW(pObject))
+ return;
+ gtk_widget_destroy(GTK_WIDGET(pObject));
+ }
+}
+
+class GtkInstanceBuilder : public weld::Builder
+{
+private:
+ OUString m_sHelpRoot;
+ GtkBuilder* m_pBuilder;
+ GSList* m_pObjectList;
+ GtkWidget* m_pParentWidget;
+public:
+ GtkInstanceBuilder(GtkWidget* pParent, const OUString& rUIRoot, const OUString& rUIFile)
+ : weld::Builder(rUIFile)
+ , m_sHelpRoot(rUIFile)
+ , m_pParentWidget(pParent)
+ {
+ OUString aUri(rUIRoot + rUIFile);
+ OUString aPath;
+ osl::FileBase::getSystemPathFromFileURL(aUri, aPath);
+ m_pBuilder = gtk_builder_new_from_file(OUStringToOString(aPath, RTL_TEXTENCODING_UTF8).getStr());
+
+ sal_Int32 nIdx = m_sHelpRoot.lastIndexOf('.');
+ if (nIdx != -1)
+ m_sHelpRoot = m_sHelpRoot.copy(0, nIdx);
+ m_sHelpRoot = m_sHelpRoot + OUString('/');
+
+ m_pObjectList = gtk_builder_get_objects(m_pBuilder);
+ OString aUtf8HelpRoot(OUStringToOString(m_sHelpRoot, RTL_TEXTENCODING_UTF8));
+ g_slist_foreach(m_pObjectList, postprocess, &aUtf8HelpRoot);
+ }
+
+ virtual ~GtkInstanceBuilder() override
+ {
+ g_slist_foreach(m_pObjectList, destroy_toplevels, nullptr);
+ g_slist_free(m_pObjectList);
+ g_object_unref(m_pBuilder);
+ }
+
+ //ideally we would have/use weld::Container add and explicitly
+ //call add when we want to do this, but in the vcl impl the
+ //parent has to be set when the child is created, so for the
+ //gtk impl emulate this by doing this implicitly at weld time
+ void auto_add_parentless_widgets_to_container(GtkWidget* pWidget)
+ {
+ if (gtk_widget_get_toplevel(pWidget) == pWidget)
+ gtk_container_add(GTK_CONTAINER(m_pParentWidget), pWidget);
+ }
+
+ virtual weld::MessageDialog* weld_message_dialog(const OString &id, bool bTakeOwnership) override
+ {
+ GtkMessageDialog* pMessageDialog = GTK_MESSAGE_DIALOG(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pMessageDialog)
+ return nullptr;
+ gtk_window_set_transient_for(GTK_WINDOW(pMessageDialog), GTK_WINDOW(gtk_widget_get_toplevel(m_pParentWidget)));
+ return new GtkInstanceMessageDialog(pMessageDialog, bTakeOwnership);
+ }
+
+ virtual weld::Dialog* weld_dialog(const OString &id, bool bTakeOwnership) override
+ {
+ GtkDialog* pDialog = GTK_DIALOG(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pDialog)
+ return nullptr;
+ gtk_window_set_transient_for(GTK_WINDOW(pDialog), GTK_WINDOW(gtk_widget_get_toplevel(m_pParentWidget)));
+ return new GtkInstanceDialog(pDialog, bTakeOwnership);
+ }
+
+ virtual weld::Window* weld_window(const OString &id, bool bTakeOwnership) override
+ {
+ GtkWindow* pWindow = GTK_WINDOW(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ return pWindow ? new GtkInstanceWindow(pWindow, bTakeOwnership) : nullptr;
+ }
+
+ virtual weld::Widget* weld_widget(const OString &id, bool bTakeOwnership) override
+ {
+ GtkWidget* pWidget = GTK_WIDGET(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pWidget)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(pWidget);
+ return new GtkInstanceWidget(pWidget, bTakeOwnership);
+ }
+
+ virtual weld::Container* weld_container(const OString &id, bool bTakeOwnership) override
+ {
+ GtkContainer* pContainer = GTK_CONTAINER(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pContainer)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pContainer));
+ return new GtkInstanceContainer(pContainer, bTakeOwnership);
+ }
+
+ virtual weld::Frame* weld_frame(const OString &id, bool bTakeOwnership) override
+ {
+ GtkFrame* pFrame = GTK_FRAME(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pFrame)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pFrame));
+ return new GtkInstanceFrame(pFrame, bTakeOwnership);
+ }
+
+ virtual weld::Notebook* weld_notebook(const OString &id, bool bTakeOwnership) override
+ {
+ GtkNotebook* pNotebook = GTK_NOTEBOOK(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pNotebook)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pNotebook));
+ return new GtkInstanceNotebook(pNotebook, bTakeOwnership);
+ }
+
+ virtual weld::Button* weld_button(const OString &id, bool bTakeOwnership) override
+ {
+ GtkButton* pButton = GTK_BUTTON(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pButton)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pButton));
+ return new GtkInstanceButton(pButton, bTakeOwnership);
+ }
+
+ virtual weld::RadioButton* weld_radio_button(const OString &id, bool bTakeOwnership) override
+ {
+ GtkRadioButton* pRadioButton = GTK_RADIO_BUTTON(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pRadioButton)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pRadioButton));
+ return new GtkInstanceRadioButton(pRadioButton, bTakeOwnership);
+ }
+
+ virtual weld::CheckButton* weld_check_button(const OString &id, bool bTakeOwnership) override
+ {
+ GtkCheckButton* pCheckButton = GTK_CHECK_BUTTON(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pCheckButton)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pCheckButton));
+ return new GtkInstanceCheckButton(pCheckButton, bTakeOwnership);
+ }
+
+ virtual weld::Entry* weld_entry(const OString &id, bool bTakeOwnership) override
+ {
+ GtkEntry* pEntry = GTK_ENTRY(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pEntry)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pEntry));
+ return new GtkInstanceEntry(pEntry, bTakeOwnership);
+ }
+
+ virtual weld::SpinButton* weld_spin_button(const OString &id, bool bTakeOwnership) override
+ {
+ GtkSpinButton* pSpinButton = GTK_SPIN_BUTTON(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pSpinButton)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pSpinButton));
+ return new GtkInstanceSpinButton(pSpinButton, bTakeOwnership);
+ }
+
+ virtual weld::ComboBoxText* weld_combo_box_text(const OString &id, bool bTakeOwnership) override
+ {
+ GtkComboBoxText* pComboBoxText = GTK_COMBO_BOX_TEXT(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pComboBoxText)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pComboBoxText));
+ return new GtkInstanceComboBoxText(pComboBoxText, bTakeOwnership);
+ }
+
+ virtual weld::TreeView* weld_tree_view(const OString &id, bool bTakeOwnership) override
+ {
+ GtkTreeView* pTreeView = GTK_TREE_VIEW(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pTreeView)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pTreeView));
+ return new GtkInstanceTreeView(pTreeView, bTakeOwnership);
+ }
+
+ virtual weld::Label* weld_label(const OString &id, bool bTakeOwnership) override
+ {
+ GtkLabel* pLabel = GTK_LABEL(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pLabel)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pLabel));
+ return new GtkInstanceLabel(pLabel, bTakeOwnership);
+ }
+
+ virtual weld::TextView* weld_text_view(const OString &id, bool bTakeOwnership) override
+ {
+ GtkTextView* pTextView = GTK_TEXT_VIEW(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pTextView)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pTextView));
+ return new GtkInstanceTextView(pTextView, bTakeOwnership);
+ }
+
+ virtual weld::DrawingArea* weld_drawing_area(const OString &id, bool bTakeOwnership) override
+ {
+ GtkDrawingArea* pDrawingArea = GTK_DRAWING_AREA(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pDrawingArea)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pDrawingArea));
+ return new GtkInstanceDrawingArea(pDrawingArea, bTakeOwnership);
+ }
+};
+
+void GtkInstanceWindow::help()
+{
+ //show help for widget with keyboard focus
+ GtkWidget* pWidget = gtk_window_get_focus(m_pWindow);
+ if (!pWidget)
+ pWidget = GTK_WIDGET(m_pWindow);
+ OString sHelpId = ::get_help_id(pWidget);
+ while (sHelpId.isEmpty())
+ {
+ pWidget = gtk_widget_get_parent(pWidget);
+ if (!pWidget)
+ break;
+ sHelpId = ::get_help_id(pWidget);
+ }
+ std::unique_ptr<weld::Widget> xTemp(pWidget != m_pWidget ? new GtkInstanceWidget(pWidget, false) : nullptr);
+ weld::Widget* pSource = xTemp ? xTemp.get() : this;
+ bool bRunNormalHelpRequest = true;
+ if (m_aHelpRequestHdl.IsSet())
+ bRunNormalHelpRequest = m_aHelpRequestHdl.Call(*pSource);
+ Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr;
+ if (pHelp)
+ pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource);
+}
+
+weld::Builder* GtkInstance::CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile)
+{
+ GtkInstanceWidget* pParentWidget = dynamic_cast<GtkInstanceWidget*>(pParent);
+ GtkWidget* pBuilderParent = pParentWidget ? pParentWidget->getWidget() : nullptr;
+ return new GtkInstanceBuilder(pBuilderParent, rUIRoot, rUIFile);
+}
+
+GtkMessageType VclToGtk(VclMessageType eType)
+{
+ GtkMessageType eRet(GTK_MESSAGE_INFO);
+ switch (eType)
+ {
+ case VclMessageType::Info:
+ eRet = GTK_MESSAGE_INFO;
+ break;
+ case VclMessageType::Warning:
+ eRet = GTK_MESSAGE_WARNING;
+ break;
+ case VclMessageType::Question:
+ eRet = GTK_MESSAGE_QUESTION;
+ break;
+ case VclMessageType::Error:
+ eRet = GTK_MESSAGE_ERROR;
+ break;
+ }
+ return eRet;
+}
+
+GtkButtonsType VclToGtk(VclButtonsType eType)
+{
+ GtkButtonsType eRet(GTK_BUTTONS_NONE);
+ switch (eType)
+ {
+ case VclButtonsType::NONE:
+ eRet = GTK_BUTTONS_NONE;
+ break;
+ case VclButtonsType::Ok:
+ eRet = GTK_BUTTONS_OK;
+ break;
+ case VclButtonsType::Close:
+ eRet = GTK_BUTTONS_CLOSE;
+ break;
+ case VclButtonsType::Cancel:
+ eRet = GTK_BUTTONS_CANCEL;
+ break;
+ case VclButtonsType::YesNo:
+ eRet = GTK_BUTTONS_YES_NO;
+ break;
+ case VclButtonsType::OkCancel:
+ eRet = GTK_BUTTONS_OK_CANCEL;
+ break;
+ }
+ return eRet;
+}
+
+weld::MessageDialog* GtkInstance::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonsType, const OUString &rPrimaryMessage)
+{
+ GtkInstanceWidget* pParentInstance = dynamic_cast<GtkInstanceWidget*>(pParent);
+ GtkWindow* pParentWindow = pParentInstance ? pParentInstance->getWindow() : nullptr;
+ GtkMessageDialog* pMessageDialog = GTK_MESSAGE_DIALOG(gtk_message_dialog_new(pParentWindow, GTK_DIALOG_MODAL,
+ VclToGtk(eMessageType), VclToGtk(eButtonsType), "%s",
+ OUStringToOString(rPrimaryMessage, RTL_TEXTENCODING_UTF8).getStr()));
+ return new GtkInstanceMessageDialog(pMessageDialog, true);
+}
+
+weld::Window* GtkSalFrame::GetFrameWeld() const
+{
+ if (!m_xFrameWeld)
+ m_xFrameWeld.reset(new GtkInstanceWindow(GTK_WINDOW(getWindow()), false));
+ return m_xFrameWeld.get();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */