1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SVTOOLS_EDITBROWSEBOX_HXX
21 #define INCLUDED_SVTOOLS_EDITBROWSEBOX_HXX
22 #define SVTOOLS_IN_EDITBROWSEBOX_HXX
25 #include <svtools/svtdllapi.h>
26 #include <tools/ref.hxx>
27 #include <vcl/window.hxx>
28 #include <vcl/combobox.hxx>
29 #include <vcl/lstbox.hxx>
30 #include <vcl/spinfld.hxx>
32 #include <vcl/button.hxx>
33 #include <svtools/brwbox.hxx>
34 #include <svtools/brwhead.hxx>
35 #include <svtools/svmedit.hxx>
36 #include <o3tl/typed_flags_set.hxx>
39 // EditBrowseBoxFlags (EBBF)
41 enum class EditBrowseBoxFlags
44 /** if this bit is _not_ set, the handle column will be invalidated upon
45 changing the row in the browse box. This is for forcing the row picture to
46 be repainted. If you do not have row pictures or text, you don't need this
47 invalidation, then you would specify this bit to prevent flicker
49 NO_HANDLE_COLUMN_CONTENT
= 0x0001,
50 /** set this bit to activate the cell on a MouseButtonDown, not a MouseButtonUp event
52 ACTIVATE_ON_BUTTONDOWN
= 0x0002,
53 /** if this bit is set and EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT is _not_ set, the handle
54 column is drawn with the text contained in column 0 instead of an image
56 HANDLE_COLUMN_TEXT
= 0x0004,
58 /** If this bit is set, tab traveling is somewhat modified<br/>
59 If the control gets the focus because the user pressed the TAB key, then the
60 first or last cell (depending on whether the traveling was cycling forward or backward)
62 @see Window::GetGetFocusFlags
65 SMART_TAB_TRAVEL
= 0x0008,
70 template<> struct typed_flags
<EditBrowseBoxFlags
> : is_typed_flags
<EditBrowseBoxFlags
, 0x0f> {};
80 class SVT_DLLPUBLIC CellController
: public SvRefBase
82 friend class EditBrowseBox
;
83 Link
<LinkParamNone
*, void> maModifyHdl
;
85 VclPtr
<Control
> pWindow
;
86 bool bSuspended
; // <true> if the window is hidden and disabled
90 CellController(Control
* pW
);
91 virtual ~CellController() override
;
93 Control
& GetWindow() const { return *const_cast< CellController
* >( this )->pWindow
; }
95 virtual void SetModified();
96 virtual void ClearModified() = 0;
97 virtual bool IsModified() const = 0;
99 // commit any current changes. Especially, do any reformatting you need (from input formatting
100 // to output formatting) here
101 virtual void CommitModifications();
103 // suspending the controller is not cumulative!
106 bool isSuspended( ) const { return bSuspended
; }
109 virtual bool MoveAllowed(const KeyEvent
& rEvt
) const;
110 void SetModifyHdl(const Link
<LinkParamNone
*,void>& rLink
) { maModifyHdl
= rLink
; }
111 virtual bool WantMouseEvent() const;
112 virtual void callModifyHdl() { maModifyHdl
.Call(nullptr); }
115 typedef tools::SvRef
<CellController
> CellControllerRef
;
118 //= IEditImplementation
120 class SVT_DLLPUBLIC IEditImplementation
123 virtual ~IEditImplementation() = 0;
125 virtual Control
& GetControl() = 0;
127 virtual OUString
GetText( LineEnd aSeparator
) const = 0;
128 virtual void SetText( const OUString
& _rStr
) = 0;
130 virtual bool IsReadOnly() const = 0;
131 virtual void SetReadOnly( bool bReadOnly
) = 0;
133 virtual sal_Int32
GetMaxTextLen() const = 0;
134 virtual void SetMaxTextLen( sal_Int32 _nMaxLen
) = 0;
136 virtual Selection
GetSelection() const = 0;
137 virtual void SetSelection( const Selection
& _rSelection
) = 0;
139 virtual void ReplaceSelected( const OUString
& _rStr
) = 0;
140 virtual OUString
GetSelected( LineEnd aSeparator
) const = 0;
142 virtual void SetModified() = 0;
143 virtual bool IsModified() const = 0;
144 virtual void ClearModified() = 0;
145 virtual void SetModifyHdl( const Link
<Edit
&,void>& _rLink
) = 0;
149 //= GenericEditImplementation
151 template <class EDIT
>
152 class GenericEditImplementation
: public IEditImplementation
156 GenericEditImplementation( EDIT
& _rEdit
);
158 EDIT
& GetEditWindow() { return static_cast< EDIT
& >( GetControl() ); }
160 virtual Control
& GetControl() override
;
162 virtual OUString
GetText( LineEnd aSeparator
) const override
;
163 virtual void SetText( const OUString
& _rStr
) override
;
165 virtual bool IsReadOnly() const override
;
166 virtual void SetReadOnly( bool bReadOnly
) override
;
168 virtual sal_Int32
GetMaxTextLen() const override
;
169 virtual void SetMaxTextLen( sal_Int32 _nMaxLen
) override
;
171 virtual Selection
GetSelection() const override
;
172 virtual void SetSelection( const Selection
& _rSelection
) override
;
174 virtual void ReplaceSelected( const OUString
& _rStr
) override
;
175 virtual OUString
GetSelected( LineEnd aSeparator
) const override
;
177 virtual void SetModified() override
;
178 virtual bool IsModified() const override
;
179 virtual void ClearModified() override
;
180 virtual void SetModifyHdl( const Link
<Edit
&,void>& _rLink
) override
;
183 #include <svtools/editimplementation.hxx>
186 //= MultiLineTextCell
188 /** a multi line edit which can be used in a cell of a EditBrowseBox
190 class SVT_DLLPUBLIC MultiLineTextCell
: public MultiLineEdit
193 MultiLineTextCell( vcl::Window
* _pParent
, WinBits _nStyle
)
194 :MultiLineEdit( _pParent
, _nStyle
)
199 // Window overridables
200 virtual bool PreNotify( NotifyEvent
& rNEvt
) override
;
202 // MultiLineEdit overridables
203 virtual void Modify() override
;
206 bool dispatchKeyEvent( const KeyEvent
& _rEvent
);
210 //= concrete edit implementations
212 typedef GenericEditImplementation
< Edit
> EditImplementation
;
214 typedef GenericEditImplementation
< MultiLineTextCell
> MultiLineEditImplementation_Base
;
215 class SVT_DLLPUBLIC MultiLineEditImplementation
: public MultiLineEditImplementation_Base
218 MultiLineEditImplementation( MultiLineTextCell
& _rEdit
) : MultiLineEditImplementation_Base( _rEdit
)
222 virtual OUString
GetText( LineEnd aSeparator
) const override
;
223 virtual OUString
GetSelected( LineEnd aSeparator
) const override
;
227 //= EditCellController
229 class SVT_DLLPUBLIC EditCellController
: public CellController
231 IEditImplementation
* m_pEditImplementation
;
232 bool const m_bOwnImplementation
; // did we create m_pEditImplementation?
235 EditCellController( Edit
* _pEdit
);
236 EditCellController( IEditImplementation
* _pImplementation
);
237 virtual ~EditCellController( ) override
;
239 const IEditImplementation
* GetEditImplementation( ) const { return m_pEditImplementation
; }
240 IEditImplementation
* GetEditImplementation( ) { return m_pEditImplementation
; }
242 virtual void SetModified() override
;
243 virtual bool IsModified() const override
;
244 virtual void ClearModified() override
;
247 virtual bool MoveAllowed(const KeyEvent
& rEvt
) const override
;
249 DECL_LINK(ModifyHdl
, Edit
&, void);
253 //= SpinCellController
255 class SVT_DLLPUBLIC SpinCellController
: public CellController
258 SpinCellController(SpinField
* pSpinField
);
259 const SpinField
& GetSpinWindow() const { return static_cast<const SpinField
&>(GetWindow()); }
260 SpinField
& GetSpinWindow() { return static_cast<SpinField
&>(GetWindow()); }
262 virtual void SetModified() override
;
263 virtual bool IsModified() const override
;
264 virtual void ClearModified() override
;
267 virtual bool MoveAllowed(const KeyEvent
& rEvt
) const override
;
269 DECL_LINK(ModifyHdl
, Edit
&, void);
275 class SVT_DLLPUBLIC CheckBoxControl
: public Control
277 VclPtr
<CheckBox
> pBox
;
278 Link
<VclPtr
<CheckBox
>,void> m_aClickLink
;
279 Link
<LinkParamNone
*,void> m_aModifyLink
;
282 CheckBoxControl(vcl::Window
* pParent
);
283 virtual ~CheckBoxControl() override
;
284 virtual void dispose() override
;
286 virtual void GetFocus() override
;
287 virtual bool PreNotify(NotifyEvent
& rEvt
) override
;
288 virtual void Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rClientRect
) override
;
289 virtual void Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
, DrawFlags nFlags
) override
;
290 virtual void StateChanged( StateChangedType nStateChange
) override
;
291 virtual void DataChanged( const DataChangedEvent
& _rEvent
) override
;
292 virtual void Resize() override
;
294 void SetClickHdl(const Link
<VclPtr
<CheckBox
>,void>& rHdl
) {m_aClickLink
= rHdl
;}
296 void SetModifyHdl(const Link
<LinkParamNone
*,void>& rHdl
) {m_aModifyLink
= rHdl
;}
298 CheckBox
& GetBox() {return *pBox
;};
301 DECL_LINK( OnClick
, Button
*, void );
305 //= CheckBoxCellController
307 class SVT_DLLPUBLIC CheckBoxCellController
: public CellController
311 CheckBoxCellController(CheckBoxControl
* pWin
);
312 CheckBox
& GetCheckBox() const;
314 virtual bool IsModified() const override
;
315 virtual void ClearModified() override
;
318 virtual bool WantMouseEvent() const override
;
320 DECL_LINK(ModifyHdl
, LinkParamNone
*, void);
326 class SVT_DLLPUBLIC ComboBoxControl
: public ComboBox
328 friend class ComboBoxCellController
;
331 ComboBoxControl(vcl::Window
* pParent
);
334 virtual bool PreNotify( NotifyEvent
& rNEvt
) override
;
338 //= ComboBoxCellController
340 class SVT_DLLPUBLIC ComboBoxCellController
: public CellController
344 ComboBoxCellController(ComboBoxControl
* pParent
);
345 ComboBoxControl
& GetComboBox() const { return static_cast<ComboBoxControl
&>(GetWindow()); }
347 virtual bool IsModified() const override
;
348 virtual void ClearModified() override
;
351 virtual bool MoveAllowed(const KeyEvent
& rEvt
) const override
;
353 DECL_LINK(ModifyHdl
, Edit
&, void);
359 class SVT_DLLPUBLIC ListBoxControl
: public ListBox
361 friend class ListBoxCellController
;
364 ListBoxControl(vcl::Window
* pParent
);
367 virtual bool PreNotify( NotifyEvent
& rNEvt
) override
;
371 //= ListBoxCellController
373 class SVT_DLLPUBLIC ListBoxCellController
: public CellController
377 ListBoxCellController(ListBoxControl
* pParent
);
378 const ListBoxControl
& GetListBox() const { return static_cast<const ListBoxControl
&>(GetWindow()); }
379 ListBoxControl
& GetListBox() { return static_cast<ListBoxControl
&>(GetWindow()); }
381 virtual bool IsModified() const override
;
382 virtual void ClearModified() override
;
385 virtual bool MoveAllowed(const KeyEvent
& rEvt
) const override
;
387 DECL_LINK(ListBoxSelectHdl
, ListBox
&, void);
391 //= FormattedFieldCellController
393 class SVT_DLLPUBLIC FormattedFieldCellController
: public EditCellController
396 FormattedFieldCellController( FormattedField
* _pFormatted
);
398 virtual void CommitModifications() override
;
402 //= EditBrowserHeader
404 class SVT_DLLPUBLIC EditBrowserHeader
: public BrowserHeader
407 EditBrowserHeader( BrowseBox
* pParent
, WinBits nWinBits
= WB_BUTTONSTYLE
)
408 :BrowserHeader(pParent
, nWinBits
){}
411 virtual void DoubleClick() override
;
417 class EditBrowseBoxImpl
;
418 class SVT_DLLPUBLIC EditBrowseBox
: public BrowseBox
420 friend class EditBrowserHeader
;
440 CURRENT_PRIMARYKEY
= 7,
446 EditBrowseBox(EditBrowseBox
const &) = delete;
447 EditBrowseBox
& operator=(EditBrowseBox
const &) = delete;
449 class BrowserMouseEventPtr
451 std::unique_ptr
<BrowserMouseEvent
> pEvent
;
455 BrowserMouseEventPtr()
460 bool Is() const {return pEvent
!= nullptr;}
461 bool IsDown() const {return bDown
;}
462 const BrowserMouseEvent
* operator->() const {return pEvent
.get();}
464 SVT_DLLPUBLIC
void Clear();
465 void Set(const BrowserMouseEvent
* pEvt
, bool bIsDown
);
468 CellControllerRef aController
,
471 ImplSVEvent
* nStartEvent
, * nEndEvent
, * nCellModifiedEvent
; // event ids
472 VclPtr
<vcl::Window
> m_pFocusWhileRequest
;
473 // In ActivateCell, we grab the focus asynchronously, but if between requesting activation
474 // and the asynchronous event the focus has changed, we won't grab it for ourself.
476 long nPaintRow
; // row being painted
481 mutable bool bPaintStatus
: 1; // paint a status (image) in the handle column
482 bool bActiveBeforeTracking
;
484 VclPtr
<CheckBoxControl
> pCheckBoxPaint
;
486 EditBrowseBoxFlags m_nBrowserFlags
;
487 std::unique_ptr
< EditBrowseBoxImpl
> m_aImpl
;
490 VclPtr
<BrowserHeader
> pHeader
;
492 BrowserMouseEventPtr
& getMouseEvent() { return aMouseEvent
; }
495 BrowserHeader
* GetHeaderBar() const {return pHeader
;}
497 virtual VclPtr
<BrowserHeader
> CreateHeaderBar(BrowseBox
* pParent
) override
;
499 // if you want to have an own header ...
500 virtual VclPtr
<BrowserHeader
> imp_CreateHeaderBar(BrowseBox
* pParent
);
502 virtual void ColumnMoved(sal_uInt16 nId
) override
;
503 virtual void ColumnResized(sal_uInt16 nColId
) override
;
504 virtual void Resize() override
;
505 virtual void ArrangeControls(sal_uInt16
& nX
, sal_uInt16 nY
);
506 virtual bool SeekRow(long nRow
) override
;
508 virtual void GetFocus() override
;
509 virtual void LoseFocus() override
;
510 virtual void KeyInput(const KeyEvent
& rEvt
) override
;
511 virtual void MouseButtonDown(const BrowserMouseEvent
& rEvt
) override
;
512 virtual void MouseButtonUp(const BrowserMouseEvent
& rEvt
) override
;
513 virtual void StateChanged( StateChangedType nType
) override
;
514 virtual void DataChanged( const DataChangedEvent
& rDCEvt
) override
;
516 using BrowseBox::MouseButtonUp
;
517 using BrowseBox::MouseButtonDown
;
519 virtual bool PreNotify(NotifyEvent
& rNEvt
) override
;
520 virtual bool EventNotify(NotifyEvent
& rNEvt
) override
;
522 virtual void EndScroll() override
;
524 // should be used instead of GetFieldRectPixel, 'cause this method here takes into account the borders
525 tools::Rectangle
GetCellRect(long nRow
, sal_uInt16 nColId
, bool bRelToBrowser
= true) const;
526 virtual sal_uInt32
GetTotalCellWidth(long nRow
, sal_uInt16 nColId
);
527 sal_uInt32
GetAutoColumnWidth(sal_uInt16 nColId
);
529 virtual void PaintStatusCell(OutputDevice
& rDev
, const tools::Rectangle
& rRect
) const;
530 virtual void PaintCell(OutputDevice
& rDev
, const tools::Rectangle
& rRect
, sal_uInt16 nColId
) const = 0;
532 virtual RowStatus
GetRowStatus(long nRow
) const;
534 virtual void RowHeightChanged() override
;
536 // callbacks for the data window
537 virtual void ImplStartTracking() override
;
538 virtual void ImplEndTracking() override
;
540 // when changing a row:
541 // CursorMoving: cursor is being moved, but GetCurRow() still provides the old row
542 virtual bool CursorMoving(long nNewRow
, sal_uInt16 nNewCol
);
544 // cursor has been moved
545 virtual void CursorMoved() override
;
547 virtual void CellModified(); // called whenever a cell has been modified
548 virtual bool SaveModified(); // called whenever a cell should be left, and it's content should be saved
549 // return sal_False prevents leaving the cell
550 virtual bool SaveRow(); // commit the current row
552 virtual bool IsModified() const {return aController
.is() && aController
->IsModified();}
554 virtual CellController
* GetController(long nRow
, sal_uInt16 nCol
);
555 virtual void InitController(CellControllerRef
& rController
, long nRow
, sal_uInt16 nCol
);
556 static void ResizeController(CellControllerRef
const & rController
, const tools::Rectangle
&);
557 virtual void DoubleClick(const BrowserMouseEvent
&) override
;
559 void ActivateCell() { ActivateCell(GetCurRow(), GetCurColumnId()); }
561 // retrieve the image for the row status
562 Image
GetImage(RowStatus
) const;
565 // if you don't set a width, this will be calculated automatically
566 // if the id isn't set the smallest unused will do it ...
567 virtual sal_uInt16
AppendColumn(const OUString
& rName
, sal_uInt16 nWidth
, sal_uInt16 nPos
= HEADERBAR_APPEND
, sal_uInt16 nId
= sal_uInt16(-1));
569 // called whenever (Shift)Tab or Enter is pressed. If true is returned, these keys
570 // result in traveling to the next or to th previous cell
571 virtual bool IsTabAllowed(bool bForward
) const;
573 virtual bool IsCursorMoveAllowed(long nNewRow
, sal_uInt16 nNewColId
) const override
;
575 void PaintTristate(const tools::Rectangle
& rRect
, const TriState
& eState
, bool _bEnabled
=true) const;
577 void AsynchGetFocus();
578 // secure starting of StartEditHdl
581 EditBrowseBox(vcl::Window
* pParent
, EditBrowseBoxFlags nBrowserFlags
, WinBits nBits
, BrowserMode nMode
= BrowserMode::NONE
);
582 virtual ~EditBrowseBox() override
;
583 virtual void dispose() override
;
585 bool IsEditing() const {return aController
.is();}
586 void InvalidateStatusCell(long nRow
) {RowModified(nRow
, 0);}
587 void InvalidateHandleColumn();
591 virtual void RemoveRows();
592 virtual void Dispatch(sal_uInt16 nId
);
594 const CellControllerRef
& Controller() const { return aController
; }
595 EditBrowseBoxFlags
GetBrowserFlags() const { return m_nBrowserFlags
; }
596 void SetBrowserFlags(EditBrowseBoxFlags nFlags
);
598 virtual void ActivateCell(long nRow
, sal_uInt16 nCol
, bool bSetCellFocus
= true);
599 virtual void DeactivateCell(bool bUpdate
= true);
600 // Children ---------------------------------------------------------------
602 /** @return The count of additional controls of the control area. */
603 virtual sal_Int32
GetAccessibleControlCount() const override
;
605 /** Creates the accessible object of an additional control.
607 The 0-based index of the control.
609 The XAccessible interface of the specified control. */
610 virtual css::uno::Reference
< css::accessibility::XAccessible
>
611 CreateAccessibleControl( sal_Int32 nIndex
) override
;
613 /** Sets focus to current cell of the data table. */
614 virtual void GrabTableFocus() override
;
616 virtual tools::Rectangle
GetFieldCharacterBounds(sal_Int32 _nRow
,sal_Int32 _nColumnPos
,sal_Int32 nIndex
) override
;
617 virtual sal_Int32
GetFieldIndexAtPoint(sal_Int32 _nRow
,sal_Int32 _nColumnPos
,const Point
& _rPoint
) override
;
619 css::uno::Reference
< css::accessibility::XAccessible
> CreateAccessibleCheckBoxCell(long _nRow
, sal_uInt16 _nColumnPos
,const TriState
& eState
);
621 // creates the accessible which wraps the active cell
622 void implCreateActiveAccessible( );
625 virtual void PaintField(vcl::RenderContext
& rDev
, const tools::Rectangle
& rRect
,
626 sal_uInt16 nColumnId
) const override
;
627 using Control::ImplInitSettings
;
628 SVT_DLLPRIVATE
void ImplInitSettings( bool bFont
, bool bForeground
, bool bBackground
);
629 SVT_DLLPRIVATE
void DetermineFocus( const GetFocusFlags _nGetFocusFlags
= GetFocusFlags::NONE
);
630 inline void EnableAndShow() const;
632 SVT_DLLPRIVATE
void implActivateCellOnMouseEvent(const BrowserMouseEvent
& _rEvt
, bool _bUp
);
633 SVT_DLLPRIVATE
void impl_construct();
635 DECL_DLLPRIVATE_LINK( ModifyHdl
, LinkParamNone
*, void );
636 DECL_DLLPRIVATE_LINK( StartEditHdl
, void*, void );
637 DECL_DLLPRIVATE_LINK( EndEditHdl
, void*, void );
638 DECL_DLLPRIVATE_LINK( CellModifiedHdl
, void*, void );
645 #undef SVTOOLS_IN_EDITBROWSEBOX_HXX
646 #endif // INCLUDED_SVTOOLS_EDITBROWSEBOX_HXX
648 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */