summaryrefslogtreecommitdiffstats
path: root/include/svtools/editbrowsebox.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'include/svtools/editbrowsebox.hxx')
-rw-r--r--include/svtools/editbrowsebox.hxx1119
1 files changed, 1119 insertions, 0 deletions
diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx
new file mode 100644
index 000000000..2297c45a6
--- /dev/null
+++ b/include/svtools/editbrowsebox.hxx
@@ -0,0 +1,1119 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <memory>
+#include <svtools/svtdllapi.h>
+#include <tools/ref.hxx>
+
+#include <svtools/brwbox.hxx>
+#include <svtools/brwhead.hxx>
+#include <tools/lineend.hxx>
+#include <vcl/InterimItemWindow.hxx>
+#include <vcl/weldutils.hxx>
+#include <o3tl/typed_flags_set.hxx>
+
+class BrowserDataWin;
+
+// EditBrowseBoxFlags (EBBF)
+enum class EditBrowseBoxFlags
+{
+ NONE = 0x0000,
+/** if this bit is _not_ set, the handle column will be invalidated upon
+ changing the row in the browse box. This is for forcing the row picture to
+ be repainted. If you do not have row pictures or text, you don't need this
+ invalidation, then you would specify this bit to prevent flicker
+*/
+ NO_HANDLE_COLUMN_CONTENT = 0x0001,
+/** set this bit to activate the cell on a MouseButtonDown, not a MouseButtonUp event
+ */
+ ACTIVATE_ON_BUTTONDOWN = 0x0002,
+/** if this bit is set and EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT is _not_ set, the handle
+ column is drawn with the text contained in column 0 instead of an image
+*/
+ HANDLE_COLUMN_TEXT = 0x0004,
+
+/** If this bit is set, tab traveling is somewhat modified<br/>
+ If the control gets the focus because the user pressed the TAB key, then the
+ first or last cell (depending on whether the traveling was cycling forward or backward)
+ gets activated.
+ @see Window::GetGetFocusFlags
+ @see GETFOCUS_*
+*/
+ SMART_TAB_TRAVEL = 0x0008,
+
+};
+namespace o3tl
+{
+ template<> struct typed_flags<EditBrowseBoxFlags> : is_typed_flags<EditBrowseBoxFlags, 0x0f> {};
+}
+
+namespace svt
+{
+ class ControlBase;
+
+ class SVT_DLLPUBLIC CellController : public SvRefBase
+ {
+ friend class EditBrowseBox;
+ Link<LinkParamNone*, void> maModifyHdl;
+
+ VclPtr<ControlBase> pWindow;
+ bool bSuspended; // <true> if the window is hidden and disabled
+
+ public:
+
+ CellController(ControlBase* pW);
+ virtual ~CellController() override;
+
+ ControlBase& GetWindow() const { return *const_cast<CellController*>(this)->pWindow; }
+
+ virtual void SaveValue() = 0;
+ virtual bool IsValueChangedFromSaved() const = 0;
+
+ // commit any current changes. Especially, do any reformatting you need (from input formatting
+ // to output formatting) here
+ virtual void CommitModifications();
+
+ // suspending the controller is not cumulative!
+ void suspend( );
+ void resume( );
+ bool isSuspended( ) const { return bSuspended; }
+
+ protected:
+ virtual bool MoveAllowed(const KeyEvent& rEvt) const;
+ void SetModifyHdl(const Link<LinkParamNone*,void>& rLink) { maModifyHdl = rLink; }
+ virtual void ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool bUp);
+ virtual void callModifyHdl() { maModifyHdl.Call(nullptr); }
+ };
+
+ typedef tools::SvRef<CellController> CellControllerRef;
+
+
+ //= IEditImplementation
+
+ class SVT_DLLPUBLIC IEditImplementation
+ {
+ public:
+ virtual ~IEditImplementation() = 0;
+
+ virtual ControlBase& GetControl() = 0;
+
+ virtual OUString GetText( LineEnd aSeparator ) const = 0;
+ virtual void SetText( const OUString& _rStr ) = 0;
+
+ virtual bool IsReadOnly() const = 0;
+ virtual void SetReadOnly( bool bReadOnly ) = 0;
+
+ virtual sal_Int32 GetMaxTextLen() const = 0;
+ virtual void SetMaxTextLen( sal_Int32 _nMaxLen ) = 0;
+
+ virtual Selection GetSelection() const = 0;
+ virtual void SetSelection( const Selection& _rSelection ) = 0;
+
+ virtual void ReplaceSelected( const OUString& _rStr ) = 0;
+ virtual OUString GetSelected( LineEnd aSeparator ) const = 0;
+
+ virtual bool IsValueChangedFromSaved() const = 0;
+ virtual void SaveValue() = 0;
+
+ virtual bool CanUp() const = 0;
+ virtual bool CanDown() const = 0;
+
+ virtual void Cut() = 0;
+ virtual void Copy() = 0;
+ virtual void Paste() = 0;
+
+ // sets a link to call when the text is changed by the user
+ void SetModifyHdl(const Link<LinkParamNone*,void>& rLink)
+ {
+ m_aModify1Hdl = rLink;
+ }
+
+ // sets an additional link to call when the text is changed by the user
+ void SetAuxModifyHdl(const Link<LinkParamNone*,void>& rLink)
+ {
+ m_aModify2Hdl = rLink;
+ }
+
+ private:
+ Link<LinkParamNone*,void> m_aModify1Hdl;
+ Link<LinkParamNone*,void> m_aModify2Hdl;
+
+ protected:
+ void CallModifyHdls()
+ {
+ m_aModify1Hdl.Call(nullptr);
+ m_aModify2Hdl.Call(nullptr);
+ }
+ };
+
+ class SVT_DLLPUBLIC ControlBase : public InterimItemWindow
+ {
+ public:
+ ControlBase(BrowserDataWin* pParent, const OUString& rUIXMLDescription, const OString& rID);
+
+ virtual void SetEditableReadOnly(bool bReadOnly);
+
+ virtual bool ProcessKey(const KeyEvent& rKEvt);
+
+ virtual void SetPointFont(const vcl::Font& rFont) = 0;
+
+ // chain after the FocusInHdl
+ void SetFocusInHdl(const Link<LinkParamNone*,void>& rHdl)
+ {
+ m_aFocusInHdl = rHdl;
+ }
+
+ // chain after the FocusOutHdl
+ void SetFocusOutHdl(const Link<LinkParamNone*,void>& rHdl)
+ {
+ m_aFocusOutHdl = rHdl;
+ }
+
+ void SetMousePressHdl(const Link<const MouseEvent&,void>& rHdl)
+ {
+ m_aMousePressHdl = rHdl;
+ }
+
+ void SetMouseReleaseHdl(const Link<const MouseEvent&,void>& rHdl)
+ {
+ m_aMouseReleaseHdl = rHdl;
+ }
+
+ void SetMouseMoveHdl(const Link<const MouseEvent&,void>& rHdl)
+ {
+ m_aMouseMoveHdl = rHdl;
+ }
+
+ void SetKeyInputHdl(const Link<const KeyEvent&,void>& rHdl)
+ {
+ m_aKeyInputHdl = rHdl;
+ }
+
+ void SetKeyReleaseHdl(const Link<const KeyEvent&,void>& rHdl)
+ {
+ m_aKeyReleaseHdl = rHdl;
+ }
+
+ protected:
+ DECL_DLLPRIVATE_LINK(KeyInputHdl, const KeyEvent&, bool);
+ DECL_DLLPRIVATE_LINK(KeyReleaseHdl, const KeyEvent&, bool);
+ DECL_DLLPRIVATE_LINK(FocusInHdl, weld::Widget&, void);
+ DECL_DLLPRIVATE_LINK(FocusOutHdl, weld::Widget&, void);
+ DECL_DLLPRIVATE_LINK(MousePressHdl, const MouseEvent&, bool);
+ DECL_DLLPRIVATE_LINK(MouseReleaseHdl, const MouseEvent&, bool);
+ DECL_DLLPRIVATE_LINK(MouseMoveHdl, const MouseEvent&, bool);
+ private:
+ Link<LinkParamNone*,void> m_aFocusInHdl;
+ Link<LinkParamNone*,void> m_aFocusOutHdl;
+ Link<const MouseEvent&,void> m_aMousePressHdl;
+ Link<const MouseEvent&,void> m_aMouseReleaseHdl;
+ Link<const MouseEvent&,void> m_aMouseMoveHdl;
+ Link<const KeyEvent&,void> m_aKeyInputHdl;
+ Link<const KeyEvent&,void> m_aKeyReleaseHdl;
+ };
+
+ class SVT_DLLPUBLIC EditControlBase : public ControlBase
+ {
+ public:
+ EditControlBase(BrowserDataWin* pParent);
+
+ virtual void SetEditableReadOnly(bool bReadOnly) override
+ {
+ m_pEntry->set_editable(!bReadOnly);
+ }
+
+ virtual void SetPointFont(const vcl::Font& rFont) override
+ {
+ m_pEntry->set_font(rFont);
+ }
+
+ virtual void dispose() override;
+
+ weld::Entry& get_widget() { return *m_pEntry; }
+
+ virtual void connect_changed(const Link<weld::Entry&, void>& rLink) = 0;
+ virtual void connect_focus_in(const Link<weld::Widget&, void>& rLink) = 0;
+ virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) = 0;
+ virtual void connect_key_press(const Link<const KeyEvent&, bool>& rLink) = 0;
+
+ protected:
+ void InitEditControlBase(weld::Entry* pEntry);
+
+ private:
+ weld::Entry* m_pEntry;
+ };
+
+ class SVT_DLLPUBLIC EditControl : public EditControlBase
+ {
+ public:
+ EditControl(BrowserDataWin* pParent);
+
+ virtual void dispose() override;
+
+ virtual void connect_changed(const Link<weld::Entry&, void>& rLink) override
+ {
+ m_xWidget->connect_changed(rLink);
+ }
+
+ virtual void connect_focus_in(const Link<weld::Widget&, void>& rLink) override
+ {
+ m_xWidget->connect_focus_in(rLink);
+ }
+
+ virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) override
+ {
+ m_xWidget->connect_focus_out(rLink);
+ }
+
+ virtual void connect_key_press(const Link<const KeyEvent&, bool>& rLink) override
+ {
+ m_xWidget->connect_key_press(rLink);
+ }
+
+ protected:
+ std::unique_ptr<weld::Entry> m_xWidget;
+ };
+
+ class SVT_DLLPUBLIC EntryImplementation final : public IEditImplementation
+ {
+ EditControlBase& m_rEdit;
+ int m_nMaxTextLen;
+
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ public:
+ EntryImplementation(EditControlBase& rEdit)
+ : m_rEdit(rEdit)
+ , m_nMaxTextLen(0)
+ {
+ m_rEdit.connect_changed(LINK(this, EntryImplementation, ModifyHdl));
+ }
+
+ virtual ControlBase& GetControl() override
+ {
+ return m_rEdit;
+ }
+
+ virtual OUString GetText( LineEnd /*aSeparator*/ ) const override
+ {
+ // ignore the line end - this base implementation does not support it
+ return m_rEdit.get_widget().get_text();
+ }
+
+ virtual void SetText( const OUString& _rStr ) override
+ {
+ return m_rEdit.get_widget().set_text(_rStr);
+ }
+
+ virtual bool IsReadOnly() const override
+ {
+ return !m_rEdit.get_widget().get_editable();
+ }
+
+ virtual void SetReadOnly( bool bReadOnly ) override
+ {
+ m_rEdit.SetEditableReadOnly(bReadOnly);
+ }
+
+ virtual sal_Int32 GetMaxTextLen() const override
+ {
+ return m_nMaxTextLen;
+ }
+
+ virtual void SetMaxTextLen( sal_Int32 nMaxLen ) override
+ {
+ m_nMaxTextLen = nMaxLen;
+ m_rEdit.get_widget().set_max_length(m_nMaxTextLen);
+ }
+
+ virtual Selection GetSelection() const override
+ {
+ int nStartPos, nEndPos;
+ m_rEdit.get_widget().get_selection_bounds(nStartPos, nEndPos);
+ return Selection(nStartPos, nEndPos);
+ }
+
+ virtual void SetSelection( const Selection& rSelection ) override
+ {
+ auto nMin = rSelection.Min();
+ auto nMax = rSelection.Max();
+ m_rEdit.get_widget().select_region(nMin < 0 ? 0 : nMin, nMax == SELECTION_MAX ? -1 : nMax);
+ }
+
+ virtual void ReplaceSelected( const OUString& rStr ) override
+ {
+ m_rEdit.get_widget().replace_selection(rStr);
+ }
+
+ virtual OUString GetSelected( LineEnd /*aSeparator*/ ) const override
+ // ignore the line end - this base implementation does not support it
+ {
+ int nStartPos, nEndPos;
+ weld::Entry& rEntry = m_rEdit.get_widget();
+ rEntry.get_selection_bounds(nStartPos, nEndPos);
+ return rEntry.get_text().copy(nStartPos, nEndPos - nStartPos);
+ }
+
+ virtual bool IsValueChangedFromSaved() const override
+ {
+ return m_rEdit.get_widget().get_value_changed_from_saved();
+ }
+
+ virtual void SaveValue() override
+ {
+ m_rEdit.get_widget().save_value();
+ }
+
+ virtual bool CanUp() const override
+ {
+ return false;
+ }
+
+ virtual bool CanDown() const override
+ {
+ return false;
+ }
+
+ virtual void Cut() override
+ {
+ m_rEdit.get_widget().cut_clipboard();
+ }
+
+ virtual void Copy() override
+ {
+ m_rEdit.get_widget().copy_clipboard();
+ }
+
+ virtual void Paste() override
+ {
+ m_rEdit.get_widget().paste_clipboard();
+ }
+ };
+
+ //= MultiLineTextCell
+
+ /** a multi line edit which can be used in a cell of an EditBrowseBox
+ */
+ class SVT_DLLPUBLIC MultiLineTextCell final : public ControlBase
+ {
+ public:
+ MultiLineTextCell(BrowserDataWin* pParent);
+
+ virtual void SetEditableReadOnly(bool bReadOnly) override
+ {
+ m_xWidget->set_editable(!bReadOnly);
+ }
+
+ virtual void SetPointFont(const vcl::Font& rFont) override
+ {
+ m_xWidget->set_font(rFont);
+ }
+
+ virtual void GetFocus() override;
+
+ virtual void dispose() override;
+
+ void connect_changed(const Link<weld::TextView&, void>& rLink)
+ {
+ m_xWidget->connect_changed(rLink);
+ }
+
+ weld::TextView& get_widget() { return *m_xWidget; }
+
+ private:
+ std::unique_ptr<weld::TextView> m_xWidget;
+
+ virtual bool ProcessKey(const KeyEvent& rKEvt) override;
+ };
+
+ class SVT_DLLPUBLIC MultiLineEditImplementation final : public IEditImplementation
+ {
+ MultiLineTextCell& m_rEdit;
+ int m_nMaxTextLen;
+
+ DECL_LINK(ModifyHdl, weld::TextView&, void);
+ public:
+ MultiLineEditImplementation(MultiLineTextCell& rEdit)
+ : m_rEdit(rEdit)
+ , m_nMaxTextLen(0)
+ {
+ m_rEdit.connect_changed(LINK(this, MultiLineEditImplementation, ModifyHdl));
+ }
+
+ virtual ControlBase& GetControl() override
+ {
+ return m_rEdit;
+ }
+
+ virtual OUString GetText(LineEnd aSeparator) const override;
+
+ virtual void SetText(const OUString& rStr) override
+ {
+ return m_rEdit.get_widget().set_text(rStr);
+ }
+
+ virtual bool IsReadOnly() const override
+ {
+ return !m_rEdit.get_widget().get_editable();
+ }
+
+ virtual void SetReadOnly( bool bReadOnly ) override
+ {
+ m_rEdit.SetEditableReadOnly(bReadOnly);
+ }
+
+ virtual sal_Int32 GetMaxTextLen() const override
+ {
+ return m_nMaxTextLen;
+ }
+
+ virtual void SetMaxTextLen( sal_Int32 nMaxLen ) override
+ {
+ m_nMaxTextLen = nMaxLen;
+ m_rEdit.get_widget().set_max_length(m_nMaxTextLen);
+ }
+
+ virtual Selection GetSelection() const override
+ {
+ int nStartPos, nEndPos;
+ m_rEdit.get_widget().get_selection_bounds(nStartPos, nEndPos);
+ return Selection(nStartPos, nEndPos);
+ }
+
+ virtual void SetSelection( const Selection& rSelection ) override
+ {
+ auto nMin = rSelection.Min();
+ auto nMax = rSelection.Max();
+ m_rEdit.get_widget().select_region(nMin < 0 ? 0 : nMin, nMax == SELECTION_MAX ? -1 : nMax);
+ }
+
+ virtual void ReplaceSelected( const OUString& rStr ) override
+ {
+ m_rEdit.get_widget().replace_selection(rStr);
+ }
+
+ virtual OUString GetSelected( LineEnd aSeparator ) const override;
+
+ virtual bool IsValueChangedFromSaved() const override
+ {
+ return m_rEdit.get_widget().get_value_changed_from_saved();
+ }
+
+ virtual void SaveValue() override
+ {
+ m_rEdit.get_widget().save_value();
+ }
+
+ virtual bool CanUp() const override
+ {
+ return m_rEdit.get_widget().can_move_cursor_with_up();
+ }
+
+ virtual bool CanDown() const override
+ {
+ return m_rEdit.get_widget().can_move_cursor_with_down();
+ }
+
+ virtual void Cut() override
+ {
+ m_rEdit.get_widget().cut_clipboard();
+ }
+
+ virtual void Copy() override
+ {
+ m_rEdit.get_widget().copy_clipboard();
+ }
+
+ virtual void Paste() override
+ {
+ m_rEdit.get_widget().paste_clipboard();
+ }
+ };
+
+
+ //= EditCellController
+ class SVT_DLLPUBLIC EditCellController : public CellController
+ {
+ IEditImplementation* m_pEditImplementation;
+ bool m_bOwnImplementation; // did we create m_pEditImplementation?
+
+ public:
+ EditCellController( EditControlBase* _pEdit );
+ EditCellController( IEditImplementation* _pImplementation );
+ virtual ~EditCellController( ) override;
+
+ const IEditImplementation* GetEditImplementation( ) const { return m_pEditImplementation; }
+ IEditImplementation* GetEditImplementation( ) { return m_pEditImplementation; }
+
+ virtual bool IsValueChangedFromSaved() const override;
+ virtual void SaveValue() override;
+
+ void Modify()
+ {
+ ModifyHdl(nullptr);
+ }
+
+ protected:
+ virtual bool MoveAllowed(const KeyEvent& rEvt) const override;
+ private:
+ DECL_LINK(ModifyHdl, LinkParamNone*, void);
+ };
+
+ //= CheckBoxControl
+ class SVT_DLLPUBLIC CheckBoxControl final : public ControlBase
+ {
+ std::unique_ptr<weld::CheckButton> m_xBox;
+ weld::TriStateEnabled m_aModeState;
+ Link<weld::CheckButton&,void> m_aToggleLink;
+ Link<LinkParamNone*,void> m_aModify1Hdl;
+ Link<LinkParamNone*,void> m_aModify2Hdl;
+
+ public:
+ CheckBoxControl(BrowserDataWin* pParent);
+ virtual ~CheckBoxControl() override;
+ virtual void dispose() override;
+
+ virtual void SetPointFont(const vcl::Font& rFont) override;
+
+ void SetToggleHdl(const Link<weld::CheckButton&,void>& rHdl) {m_aToggleLink = rHdl;}
+
+ // sets a link to call when the text is changed by the user
+ void SetModifyHdl(const Link<LinkParamNone*,void>& rHdl)
+ {
+ m_aModify1Hdl = rHdl;
+ }
+
+ // sets an additional link to call when the text is changed by the user
+ void SetAuxModifyHdl(const Link<LinkParamNone*,void>& rLink)
+ {
+ m_aModify2Hdl = rLink;
+ }
+
+ void SetState(TriState eState);
+ TriState GetState() const { return m_xBox->get_state(); }
+
+ void EnableTriState(bool bTriState);
+
+ weld::CheckButton& GetBox() {return *m_xBox;};
+
+ // for pseudo-click when initially clicking in a cell activates
+ // the cell and performs a state change on the button as if
+ // it was clicked on
+ void Clicked();
+
+ private:
+ DECL_DLLPRIVATE_LINK(OnToggle, weld::Toggleable&, void);
+
+ void CallModifyHdls()
+ {
+ m_aModify1Hdl.Call(nullptr);
+ m_aModify2Hdl.Call(nullptr);
+ }
+ };
+
+ //= CheckBoxCellController
+ class SVT_DLLPUBLIC CheckBoxCellController final : public CellController
+ {
+ public:
+
+ CheckBoxCellController(CheckBoxControl* pWin);
+ weld::CheckButton& GetCheckBox() const;
+
+ virtual bool IsValueChangedFromSaved() const override;
+ virtual void SaveValue() override;
+
+ private:
+ virtual void ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool bUp) override;
+ DECL_DLLPRIVATE_LINK(ModifyHdl, LinkParamNone*, void);
+ };
+
+ //= ComboBoxControl
+ class SVT_DLLPUBLIC ComboBoxControl final : public ControlBase
+ {
+ private:
+ std::unique_ptr<weld::ComboBox> m_xWidget;
+ Link<LinkParamNone*,void> m_aModify1Hdl;
+ Link<bool,void> m_aModify2Hdl;
+
+ friend class ComboBoxCellController;
+
+ public:
+ ComboBoxControl(BrowserDataWin* pParent);
+
+ virtual void SetPointFont(const vcl::Font& rFont) override;
+
+ virtual void SetEditableReadOnly(bool bReadOnly) override
+ {
+ m_xWidget->set_entry_editable(!bReadOnly);
+ }
+
+ weld::ComboBox& get_widget() { return *m_xWidget; }
+
+ // sets a link to call when the selection is changed by the user
+ void SetModifyHdl(const Link<LinkParamNone*,void>& rHdl)
+ {
+ m_aModify1Hdl = rHdl;
+ }
+
+ // sets an additional link to call when the selection is changed by the user
+ // bool arg is true when triggered interactively by the user
+ void SetAuxModifyHdl(const Link<bool,void>& rLink)
+ {
+ m_aModify2Hdl = rLink;
+ }
+
+ void TriggerAuxModify()
+ {
+ m_aModify2Hdl.Call(false);
+ }
+
+ virtual void dispose() override;
+
+ private:
+ DECL_DLLPRIVATE_LINK(SelectHdl, weld::ComboBox&, void);
+
+ void CallModifyHdls()
+ {
+ m_aModify1Hdl.Call(nullptr);
+ m_aModify2Hdl.Call(true);
+ }
+ };
+
+ //= ComboBoxCellController
+ class SVT_DLLPUBLIC ComboBoxCellController final : public CellController
+ {
+ public:
+
+ ComboBoxCellController(ComboBoxControl* pParent);
+ weld::ComboBox& GetComboBox() const { return static_cast<ComboBoxControl&>(GetWindow()).get_widget(); }
+
+ virtual bool IsValueChangedFromSaved() const override;
+ virtual void SaveValue() override;
+
+ private:
+ virtual bool MoveAllowed(const KeyEvent& rEvt) const override;
+ DECL_DLLPRIVATE_LINK(ModifyHdl, LinkParamNone*, void);
+ };
+
+ //= ListBoxControl
+ class SVT_DLLPUBLIC ListBoxControl final : public ControlBase
+ {
+ private:
+ std::unique_ptr<weld::ComboBox> m_xWidget;
+ Link<LinkParamNone*,void> m_aModify1Hdl;
+ Link<bool,void> m_aModify2Hdl;
+
+ friend class ListBoxCellController;
+
+ public:
+ ListBoxControl(BrowserDataWin* pParent);
+
+ virtual void SetPointFont(const vcl::Font& rFont) override;
+
+ weld::ComboBox& get_widget() { return *m_xWidget; }
+
+ // sets a link to call when the selection is changed by the user
+ void SetModifyHdl(const Link<LinkParamNone*,void>& rHdl)
+ {
+ m_aModify1Hdl = rHdl;
+ }
+
+ // sets an additional link to call when the selection is changed,
+ // bool arg is true when triggered interactively by the user
+ void SetAuxModifyHdl(const Link<bool,void>& rLink)
+ {
+ m_aModify2Hdl = rLink;
+ }
+
+ void TriggerAuxModify()
+ {
+ m_aModify2Hdl.Call(false);
+ }
+
+ virtual void dispose() override;
+ private:
+ DECL_DLLPRIVATE_LINK(SelectHdl, weld::ComboBox&, void);
+
+ void CallModifyHdls()
+ {
+ m_aModify1Hdl.Call(nullptr);
+ m_aModify2Hdl.Call(true);
+ }
+ };
+
+ //= ListBoxCellController
+ class SVT_DLLPUBLIC ListBoxCellController : public CellController
+ {
+ public:
+
+ ListBoxCellController(ListBoxControl* pParent);
+ weld::ComboBox& GetListBox() const { return static_cast<ListBoxControl&>(GetWindow()).get_widget(); }
+
+ virtual bool IsValueChangedFromSaved() const override;
+ virtual void SaveValue() override;
+
+ protected:
+ virtual bool MoveAllowed(const KeyEvent& rEvt) const override;
+ private:
+ DECL_DLLPRIVATE_LINK(ListBoxSelectHdl, LinkParamNone*, void);
+ };
+
+ class SVT_DLLPUBLIC FormattedControlBase : public EditControlBase
+ {
+ public:
+ FormattedControlBase(BrowserDataWin* pParent, bool bSpinVariant);
+
+ virtual void dispose() override;
+
+ virtual void connect_changed(const Link<weld::Entry&, void>& rLink) override;
+ virtual void connect_focus_in(const Link<weld::Widget&, void>& rLink) override;
+ virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) override;
+ virtual void connect_key_press(const Link<const KeyEvent&, bool>& rLink) override;
+
+ weld::EntryFormatter& get_formatter();
+
+ protected:
+ bool m_bSpinVariant;
+ std::unique_ptr<weld::Entry> m_xEntry;
+ std::unique_ptr<weld::FormattedSpinButton> m_xSpinButton;
+ std::unique_ptr<weld::EntryFormatter> m_xEntryFormatter;
+
+ void InitFormattedControlBase();
+ };
+
+ class SVT_DLLPUBLIC FormattedControl final : public FormattedControlBase
+ {
+ public:
+ FormattedControl(BrowserDataWin* pParent, bool bSpinVariant);
+ };
+
+ class SVT_DLLPUBLIC DoubleNumericControl final : public FormattedControlBase
+ {
+ public:
+ DoubleNumericControl(BrowserDataWin* pParent, bool bSpinVariant);
+ };
+
+ class SVT_DLLPUBLIC LongCurrencyControl final : public FormattedControlBase
+ {
+ public:
+ LongCurrencyControl(BrowserDataWin* pParent, bool bSpinVariant);
+ };
+
+ class SVT_DLLPUBLIC TimeControl final : public FormattedControlBase
+ {
+ public:
+ TimeControl(BrowserDataWin* pParent, bool bSpinVariant);
+ };
+
+ class SVT_DLLPUBLIC DateControl final : public FormattedControlBase
+ {
+ public:
+ DateControl(BrowserDataWin* pParent, bool bDropDown);
+
+ void SetDate(const Date& rDate);
+
+ virtual void dispose() override;
+ private:
+ std::unique_ptr<weld::MenuButton> m_xMenuButton;
+ std::unique_ptr<weld::Builder> m_xCalendarBuilder;
+ std::unique_ptr<weld::Widget> m_xTopLevel;
+ std::unique_ptr<weld::Calendar> m_xCalendar;
+ std::unique_ptr<weld::Widget> m_xExtras;
+ std::unique_ptr<weld::Button> m_xTodayBtn;
+ std::unique_ptr<weld::Button> m_xNoneBtn;
+
+ DECL_DLLPRIVATE_LINK(ToggleHdl, weld::Toggleable&, void);
+ DECL_DLLPRIVATE_LINK(ActivateHdl, weld::Calendar&, void);
+ DECL_DLLPRIVATE_LINK(ImplClickHdl, weld::Button&, void);
+ };
+
+ class SVT_DLLPUBLIC PatternControl final : public EditControlBase
+ {
+ public:
+ PatternControl(BrowserDataWin* pParent);
+
+ weld::PatternFormatter& get_formatter() { return *m_xEntryFormatter; }
+
+ virtual void connect_changed(const Link<weld::Entry&, void>& rLink) override;
+ virtual void connect_focus_in(const Link<weld::Widget&, void>& rLink) override;
+ virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) override;
+ virtual void connect_key_press(const Link<const KeyEvent&, bool>& rLink) override;
+
+ virtual void dispose() override;
+ private:
+ std::unique_ptr<weld::Entry> m_xWidget;
+ std::unique_ptr<weld::PatternFormatter> m_xEntryFormatter;
+ };
+
+ //= FormattedFieldCellController
+ class SVT_DLLPUBLIC FormattedFieldCellController final : public EditCellController
+ {
+ public:
+ FormattedFieldCellController( FormattedControlBase* _pFormatted );
+
+ virtual void CommitModifications() override;
+ };
+
+ //= EditBrowserHeader
+ class SVT_DLLPUBLIC EditBrowserHeader : public BrowserHeader
+ {
+ public:
+ EditBrowserHeader( BrowseBox* pParent, WinBits nWinBits = WB_BUTTONSTYLE )
+ :BrowserHeader(pParent, nWinBits){}
+
+ protected:
+ virtual void DoubleClick() override;
+ };
+
+
+ //= EditBrowseBox
+ class EditBrowseBoxImpl;
+ class SVT_DLLPUBLIC EditBrowseBox: public BrowseBox
+ {
+ friend class EditBrowserHeader;
+
+ enum BrowseInfo
+ {
+ COLSELECT = 1,
+ ROWSELECT = 2,
+ ROWCHANGE = 4,
+ COLCHANGE = 8
+ };
+
+ public:
+ enum RowStatus
+ {
+ CLEAN = 0,
+ CURRENT = 1,
+ CURRENTNEW = 2,
+ MODIFIED = 3,
+ NEW = 4,
+ DELETED = 5,
+ PRIMARYKEY = 6,
+ CURRENT_PRIMARYKEY = 7,
+ FILTER = 8,
+ HEADERFOOTER = 9
+ };
+
+ private:
+ EditBrowseBox(EditBrowseBox const &) = delete;
+ EditBrowseBox& operator=(EditBrowseBox const &) = delete;
+
+ class BrowserMouseEventPtr
+ {
+ std::unique_ptr<BrowserMouseEvent> pEvent;
+ bool bDown;
+
+ public:
+ BrowserMouseEventPtr()
+ : bDown(false)
+ {
+ }
+
+ bool Is() const {return pEvent != nullptr;}
+ bool IsDown() const {return bDown;}
+ const BrowserMouseEvent* operator->() const {return pEvent.get();}
+
+ SVT_DLLPUBLIC void Clear();
+ void Set(const BrowserMouseEvent* pEvt, bool bIsDown);
+ } aMouseEvent;
+
+ CellControllerRef aController,
+ aOldController;
+
+ ImplSVEvent * nStartEvent, * nEndEvent, * nCellModifiedEvent; // event ids
+ VclPtr<vcl::Window> m_pFocusWhileRequest;
+ // In ActivateCell, we grab the focus asynchronously, but if between requesting activation
+ // and the asynchronous event the focus has changed, we won't grab it for ourself.
+
+ sal_Int32 nPaintRow; // row being painted
+ sal_Int32 nEditRow;
+ sal_uInt16 nEditCol;
+
+ bool bHasFocus : 1;
+ mutable bool bPaintStatus : 1; // paint a status (image) in the handle column
+ bool bActiveBeforeTracking;
+
+ VclPtr<CheckBoxControl> pCheckBoxPaint;
+
+ EditBrowseBoxFlags m_nBrowserFlags;
+ std::unique_ptr< EditBrowseBoxImpl> m_aImpl;
+
+ protected:
+ VclPtr<BrowserHeader> pHeader;
+
+ BrowserMouseEventPtr& getMouseEvent() { return aMouseEvent; }
+
+ protected:
+ BrowserHeader* GetHeaderBar() const {return pHeader;}
+
+ virtual VclPtr<BrowserHeader> CreateHeaderBar(BrowseBox* pParent) override;
+
+ // if you want to have an own header ...
+ virtual VclPtr<BrowserHeader> imp_CreateHeaderBar(BrowseBox* pParent);
+
+ virtual void ColumnMoved(sal_uInt16 nId) override;
+ virtual void ColumnResized(sal_uInt16 nColId) override;
+ virtual void Resize() override;
+ virtual void ArrangeControls(sal_uInt16& nX, sal_uInt16 nY);
+ virtual bool SeekRow(sal_Int32 nRow) override;
+
+ virtual void GetFocus() override;
+ virtual void LoseFocus() override;
+ virtual void KeyInput(const KeyEvent& rEvt) override;
+ virtual void MouseButtonDown(const BrowserMouseEvent& rEvt) override;
+ virtual void MouseButtonUp(const BrowserMouseEvent& rEvt) override;
+ virtual void StateChanged( StateChangedType nType ) override;
+ virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
+
+ using BrowseBox::MouseButtonUp;
+ using BrowseBox::MouseButtonDown;
+
+ virtual bool PreNotify(NotifyEvent& rNEvt ) override;
+ virtual bool EventNotify(NotifyEvent& rNEvt) override;
+
+ virtual void EndScroll() override;
+
+ // should be used instead of GetFieldRectPixel, 'cause this method here takes into account the borders
+ tools::Rectangle GetCellRect(sal_Int32 nRow, sal_uInt16 nColId, bool bRelToBrowser = true) const;
+ virtual sal_uInt32 GetTotalCellWidth(sal_Int32 nRow, sal_uInt16 nColId);
+ sal_uInt32 GetAutoColumnWidth(sal_uInt16 nColId);
+
+ virtual void PaintStatusCell(OutputDevice& rDev, const tools::Rectangle& rRect) const;
+ virtual void PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColId) const = 0;
+
+ virtual RowStatus GetRowStatus(sal_Int32 nRow) const;
+
+ virtual void RowHeightChanged() override;
+
+ // callbacks for the data window
+ virtual void ImplStartTracking() override;
+ virtual void ImplEndTracking() override;
+
+ // when changing a row:
+ // CursorMoving: cursor is being moved, but GetCurRow() still provides the old row
+ virtual bool CursorMoving(sal_Int32 nNewRow, sal_uInt16 nNewCol);
+
+ // cursor has been moved
+ virtual void CursorMoved() override;
+
+ virtual void CellModified(); // called whenever a cell has been modified
+ virtual bool SaveModified(); // called whenever a cell should be left, and it's content should be saved
+ // return sal_False prevents leaving the cell
+ virtual bool SaveRow(); // commit the current row
+
+ virtual bool IsModified() const {return aController.is() && aController->IsValueChangedFromSaved();}
+
+ virtual CellController* GetController(sal_Int32 nRow, sal_uInt16 nCol);
+ virtual void InitController(CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol);
+ static void ResizeController(CellControllerRef const & rController, const tools::Rectangle&);
+ virtual void DoubleClick(const BrowserMouseEvent&) override;
+
+ void ActivateCell() { ActivateCell(GetCurRow(), GetCurColumnId()); }
+
+ // retrieve the image for the row status
+ Image GetImage(RowStatus) const;
+
+ // inserting columns
+ // if you don't set a width, this will be calculated automatically
+ // if the id isn't set the smallest unused will do it ...
+ virtual sal_uInt16 AppendColumn(const OUString& rName, sal_uInt16 nWidth, sal_uInt16 nPos = HEADERBAR_APPEND, sal_uInt16 nId = sal_uInt16(-1));
+
+ // called whenever (Shift)Tab or Enter is pressed. If true is returned, these keys
+ // result in traveling to the next or to th previous cell
+ virtual bool IsTabAllowed(bool bForward) const;
+
+ virtual bool IsCursorMoveAllowed(sal_Int32 nNewRow, sal_uInt16 nNewColId) const override;
+
+ void PaintTristate(const tools::Rectangle& rRect, const TriState& eState, bool _bEnabled=true) const;
+
+ void AsynchGetFocus();
+ // secure starting of StartEditHdl
+
+ public:
+ EditBrowseBox(vcl::Window* pParent, EditBrowseBoxFlags nBrowserFlags, WinBits nBits, BrowserMode nMode = BrowserMode::NONE );
+ virtual ~EditBrowseBox() override;
+ virtual void dispose() override;
+
+ bool IsEditing() const {return aController.is();}
+ void InvalidateStatusCell(sal_Int32 nRow) {RowModified(nRow, 0);}
+ void InvalidateHandleColumn();
+
+ // late construction
+ virtual void Init();
+ virtual void RemoveRows();
+ virtual void Dispatch(sal_uInt16 nId);
+
+ const CellControllerRef& Controller() const { return aController; }
+ EditBrowseBoxFlags GetBrowserFlags() const { return m_nBrowserFlags; }
+ void SetBrowserFlags(EditBrowseBoxFlags nFlags);
+
+ virtual void ActivateCell(sal_Int32 nRow, sal_uInt16 nCol, bool bSetCellFocus = true);
+ virtual void DeactivateCell(bool bUpdate = true);
+ // Children ---------------------------------------------------------------
+
+ /** @return The count of additional controls of the control area. */
+ virtual sal_Int32 GetAccessibleControlCount() const override;
+
+ /** Creates the accessible object of an additional control.
+ @param nIndex
+ The 0-based index of the control.
+ @return
+ The XAccessible interface of the specified control. */
+ virtual css::uno::Reference< css::accessibility::XAccessible >
+ CreateAccessibleControl( sal_Int32 nIndex ) override;
+
+ /** Sets focus to current cell of the data table. */
+ virtual void GrabTableFocus() override;
+
+ virtual tools::Rectangle GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 nIndex) override;
+ virtual sal_Int32 GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint) override;
+
+ virtual bool ProcessKey(const KeyEvent& rEvt) override;
+
+ virtual void ChildFocusIn() override;
+ virtual void ChildFocusOut() override;
+
+ css::uno::Reference< css::accessibility::XAccessible > CreateAccessibleCheckBoxCell(sal_Int32 _nRow, sal_uInt16 _nColumnPos,const TriState& eState);
+ bool ControlHasFocus() const;
+ protected:
+ // creates the accessible which wraps the active cell
+ void implCreateActiveAccessible( );
+
+ private:
+ virtual void PaintField(vcl::RenderContext& rDev, const tools::Rectangle& rRect,
+ sal_uInt16 nColumnId ) const override;
+ using Control::ImplInitSettings;
+ SVT_DLLPRIVATE void ImplInitSettings( bool bFont, bool bForeground, bool bBackground );
+ SVT_DLLPRIVATE void DetermineFocus( const GetFocusFlags _nGetFocusFlags = GetFocusFlags::NONE);
+ inline void EnableAndShow() const;
+
+ SVT_DLLPRIVATE void implActivateCellOnMouseEvent(const BrowserMouseEvent& _rEvt, bool _bUp);
+
+ DECL_DLLPRIVATE_LINK( ModifyHdl, LinkParamNone*, void );
+ DECL_DLLPRIVATE_LINK( StartEditHdl, void*, void );
+ DECL_DLLPRIVATE_LINK( EndEditHdl, void*, void );
+ DECL_DLLPRIVATE_LINK( CellModifiedHdl, void*, void );
+ };
+
+
+} // namespace svt
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */