From 6a3f9de585fc0e8e6191db5210729ae6b3730e7d Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Tue, 13 Feb 2018 17:41:03 +0000 Subject: native dialog initial basis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I392be563e38257390f748c70bb71c67a66778ddd Reviewed-on: https://gerrit.libreoffice.org/49677 Tested-by: Jenkins Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- vcl/inc/salframe.hxx | 6 +- vcl/inc/salinst.hxx | 11 + vcl/inc/unx/gtk/gtkframe.hxx | 1 + vcl/inc/unx/gtk/gtkinst.hxx | 2 + vcl/source/app/help.cxx | 5 + vcl/source/app/salvtables.cxx | 1085 +++++++++++++++++++++++++- vcl/source/control/combobox.cxx | 2 +- vcl/source/control/field.cxx | 14 +- vcl/source/control/listbox.cxx | 5 + vcl/source/window/builder.cxx | 116 ++- vcl/source/window/menuwindow.cxx | 4 +- vcl/source/window/window2.cxx | 6 + vcl/unx/gtk3/gtk3gtkframe.cxx | 2 + vcl/unx/gtk3/gtk3gtkinst.cxx | 1572 +++++++++++++++++++++++++++++++++++++- 14 files changed, 2819 insertions(+), 12 deletions(-) (limited to 'vcl') 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 #include +#include // complete vcl::Window for SalFrame::CallCallback under -fsanitize=function class AllSettings; @@ -107,7 +108,8 @@ private: // the VCL window corresponding to this frame VclPtr m_pWindow; SALFRAMEPROC m_pProc; - +protected: + mutable std::unique_ptr 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 #include #include +#include #include "displayconnectiondispatch.hxx" @@ -34,6 +35,12 @@ #include 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 #include #include - +#include +#include +#include +#include +#include +#include +#include +#include SalFrame::SalFrame() : m_pWindow(nullptr) @@ -164,4 +171,1080 @@ SalMenuItem::~SalMenuItem() { } +class SalInstanceWidget : public virtual weld::Widget +{ +private: + VclPtr 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 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 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 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 m_xNotebook; + mutable std::vector> 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()); + m_xNotebook->SetDeactivatePageHdl(Link()); + } +}; + +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 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()); + } +}; + +IMPL_LINK_NOARG(SalInstanceCheckButton, ToggleHdl, CheckBox&, void) +{ + signal_toggled(); +} + +class SalInstanceEntry : public SalInstanceWidget, public virtual weld::Entry +{ +private: + VclPtr m_xEntry; + + DECL_LINK(ChangeHdl, Edit&, void); + + class WeldTextFilter : public TextFilter + { + private: + Link& m_rInsertTextHdl; + public: + WeldTextFilter(Link& 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()); + } +}; + +IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void) +{ + signal_changed(); +} + +class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView +{ +private: + VclPtr 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()); + m_xTreeView->SetSelectHdl(Link()); + } +}; + +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 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()); + m_xButton->SetLoseFocusHdl(Link()); + m_xButton->SetDownHdl(Link()); + m_xButton->SetUpHdl(Link()); + } +}; + +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 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 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 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()); + m_xDrawingArea->SetPaintHdl(Link()); + } +}; + +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 SalInstanceComboBoxText : public SalInstanceContainer, public virtual weld::ComboBoxText +{ +private: + VclPtr m_xComboBoxText; + + static void LinkStubSetSelectHdl(void* instance, vcl_type&) + { + return static_cast(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(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()); + 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(id); + return pMessageDialog ? new SalInstanceMessageDialog(pMessageDialog, bTakeOwnership) : nullptr; + } + + virtual weld::Dialog* weld_dialog(const OString &id, bool bTakeOwnership) override + { + Dialog* pDialog = m_aBuilder.get(id); + return pDialog ? new SalInstanceDialog(pDialog, bTakeOwnership) : nullptr; + } + + virtual weld::Window* weld_window(const OString &id, bool bTakeOwnership) override + { + SystemWindow* pWindow = m_aBuilder.get(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(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(id); + return pContainer ? new SalInstanceContainer(pContainer, bTakeOwnership) : nullptr; + } + + virtual weld::Frame* weld_frame(const OString &id, bool bTakeOwnership) override + { + VclFrame* pFrame = m_aBuilder.get(id); + return pFrame ? new SalInstanceFrame(pFrame, bTakeOwnership) : nullptr; + } + + virtual weld::Notebook* weld_notebook(const OString &id, bool bTakeOwnership) override + { + TabControl* pNotebook = m_aBuilder.get(id); + return pNotebook ? new SalInstanceNotebook(pNotebook, bTakeOwnership) : nullptr; + } + + virtual weld::Button* weld_button(const OString &id, bool bTakeOwnership) override + { + Button* pButton = m_aBuilder.get