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 #include <svtools/editbrowsebox.hxx>
22 #include "editbrowsebox.hrc"
24 #include <vcl/svapp.hxx>
25 #include <tools/debug.hxx>
26 #include <vcl/window.hxx>
28 #include <vcl/edit.hxx>
29 #include <tools/resid.hxx>
30 #include <vcl/spinfld.hxx>
31 #include <svtools/svtresid.hxx>
33 #include <svtools/svtools.hrc>
36 #include <tools/multisel.hxx>
37 #include "editbrowseboximpl.hxx"
38 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
39 #include <com/sun/star/accessibility/XAccessible.hpp>
40 #include <comphelper/types.hxx>
42 // .......................................................................
45 // .......................................................................
48 //..............................................................
49 sal_uInt16
getRealGetFocusFlags( Window
* _pWindow
)
51 sal_uInt16 nFlags
= 0;
52 while ( _pWindow
&& !nFlags
)
54 nFlags
= _pWindow
->GetGetFocusFlags( );
55 _pWindow
= _pWindow
->GetParent();
61 using namespace ::com::sun::star::uno
;
62 using namespace com::sun::star::accessibility::AccessibleEventId
;
63 using com::sun::star::accessibility::XAccessible
;
64 //==================================================================
66 IEditImplementation::~IEditImplementation()
70 //==================================================================
72 //==================================================================
73 //------------------------------------------------------------------------------
74 void EditBrowserHeader::DoubleClick()
76 sal_uInt16 nColId
= GetCurItemId();
79 sal_uInt32 nAutoWidth
= ((EditBrowseBox
*)GetParent())->GetAutoColumnWidth(nColId
);
80 if (nAutoWidth
!= ((EditBrowseBox
*)GetParent())->GetColumnWidth(nColId
))
82 ((EditBrowseBox
*)GetParent())->SetColumnWidth(nColId
, nAutoWidth
);
83 ((EditBrowseBox
*)GetParent())->ColumnResized(nColId
);
89 //==================================================================
91 //==================================================================
92 //------------------------------------------------------------------------------
93 void EditBrowseBox::BrowserMouseEventPtr::Clear()
98 //------------------------------------------------------------------------------
99 void EditBrowseBox::BrowserMouseEventPtr::Set(const BrowserMouseEvent
* pEvt
, sal_Bool bIsDown
)
109 pEvent
= new BrowserMouseEvent(pEvt
->GetWindow(),
119 //------------------------------------------------------------------------------
120 DBG_NAME(EditBrowseBox
);
121 void EditBrowseBox::impl_construct()
123 m_aImpl
= ::std::auto_ptr
<EditBrowseBoxImpl
>(new EditBrowseBoxImpl());
125 SetCompoundControl(sal_True
);
126 SetGridLineColor( Color( COL_LIGHTGRAY
) );
128 ImplInitSettings(sal_True
, sal_True
, sal_True
);
130 pCheckBoxPaint
= new CheckBoxControl(&GetDataWindow());
131 pCheckBoxPaint
->SetPaintTransparent( sal_True
);
132 pCheckBoxPaint
->SetBackground();
135 //------------------------------------------------------------------------------
136 EditBrowseBox::EditBrowseBox(Window
* pParent
, const ResId
& rId
, sal_Int32 nBrowserFlags
, BrowserMode _nMode
)
137 :BrowseBox( pParent
, rId
, _nMode
)
140 ,nCellModifiedEvent(0)
146 ,bHasFocus(sal_False
)
147 ,bPaintStatus(sal_True
)
148 ,bActiveBeforeTracking( sal_False
)
149 ,m_nBrowserFlags(nBrowserFlags
)
151 DBG_CTOR(EditBrowseBox
,NULL
);
156 //==================================================================
157 EditBrowseBox::EditBrowseBox( Window
* pParent
, sal_Int32 nBrowserFlags
, WinBits nBits
, BrowserMode _nMode
)
158 :BrowseBox( pParent
, nBits
, _nMode
)
161 ,nCellModifiedEvent(0)
167 ,bHasFocus(sal_False
)
168 ,bPaintStatus(sal_True
)
169 ,bActiveBeforeTracking( sal_False
)
170 ,m_nBrowserFlags(nBrowserFlags
)
173 DBG_CTOR(EditBrowseBox
,NULL
);
178 //------------------------------------------------------------------------------
179 void EditBrowseBox::Init()
184 //------------------------------------------------------------------------------
185 EditBrowseBox::~EditBrowseBox()
188 Application::RemoveUserEvent(nStartEvent
);
190 Application::RemoveUserEvent(nEndEvent
);
191 if (nCellModifiedEvent
)
192 Application::RemoveUserEvent(nCellModifiedEvent
);
194 delete pCheckBoxPaint
;
196 DBG_DTOR(EditBrowseBox
,NULL
);
199 //------------------------------------------------------------------------------
200 void EditBrowseBox::RemoveRows()
203 nOldEditRow
= nEditRow
= nPaintRow
= -1;
204 nEditCol
= nOldEditCol
= 0;
207 //------------------------------------------------------------------------------
208 BrowserHeader
* EditBrowseBox::CreateHeaderBar(BrowseBox
* pParent
)
210 pHeader
= imp_CreateHeaderBar(pParent
);
212 pHeader
->SetUpdateMode(sal_False
);
216 //------------------------------------------------------------------------------
217 BrowserHeader
* EditBrowseBox::imp_CreateHeaderBar(BrowseBox
* pParent
)
219 return new EditBrowserHeader(pParent
);
222 //------------------------------------------------------------------------------
223 void EditBrowseBox::LoseFocus()
225 BrowseBox::LoseFocus();
229 //------------------------------------------------------------------------------
230 void EditBrowseBox::GetFocus()
232 BrowseBox::GetFocus();
234 // This should handle the case that the BrowseBox (or one of it's children)
235 // gets the focus from outside by pressing Tab
236 if (IsEditing() && Controller()->GetWindow().IsVisible())
237 Controller()->GetWindow().GrabFocus();
239 DetermineFocus( getRealGetFocusFlags( this ) );
242 //------------------------------------------------------------------------------
243 sal_Bool
EditBrowseBox::SeekRow(long nRow
)
249 //------------------------------------------------------------------------------
250 IMPL_LINK_NOARG(EditBrowseBox
, StartEditHdl
)
256 if (!aController
->GetWindow().HasFocus() && (m_pFocusWhileRequest
== Application::GetFocusWindow()))
257 aController
->GetWindow().GrabFocus();
262 //------------------------------------------------------------------------------
263 void EditBrowseBox::PaintField( OutputDevice
& rDev
, const Rectangle
& rRect
,
264 sal_uInt16 nColumnId
) const
266 if (nColumnId
== HandleColumnId
)
269 PaintStatusCell(rDev
, rRect
);
273 // don't paint the current cell
274 if (&rDev
== &GetDataWindow())
275 // but only if we're painting onto our data win (which is the usual painting)
276 if (nPaintRow
== nEditRow
)
278 if (IsEditing() && nEditCol
== nColumnId
&& aController
->GetWindow().IsVisible())
281 PaintCell(rDev
, rRect
, nColumnId
);
285 //------------------------------------------------------------------------------
286 Image
EditBrowseBox::GetImage(RowStatus eStatus
) const
288 if ( !m_aStatusImages
.GetImageCount() )
290 const_cast<EditBrowseBox
*>(this)->m_aStatusImages
= ImageList( SvtResId( RID_SVTOOLS_IMAGELIST_EDITBROWSEBOX
) );
294 bool bNeedMirror
= IsRTLEnabled();
298 aImage
= m_aStatusImages
.GetImage(IMG_EBB_CURRENT
);
301 aImage
= m_aStatusImages
.GetImage(IMG_EBB_CURRENTNEW
);
304 aImage
= m_aStatusImages
.GetImage(IMG_EBB_MODIFIED
);
305 bNeedMirror
= false; // the pen is not mirrored
308 aImage
= m_aStatusImages
.GetImage(IMG_EBB_NEW
);
311 aImage
= m_aStatusImages
.GetImage(IMG_EBB_DELETED
);
314 aImage
= m_aStatusImages
.GetImage(IMG_EBB_PRIMARYKEY
);
316 case CURRENT_PRIMARYKEY
:
317 aImage
= m_aStatusImages
.GetImage(IMG_EBB_CURRENT_PRIMARYKEY
);
320 aImage
= m_aStatusImages
.GetImage(IMG_EBB_FILTER
);
323 aImage
= m_aStatusImages
.GetImage(IMG_EBB_HEADERFOOTER
);
330 BitmapEx
aBitmap( aImage
.GetBitmapEx() );
331 aBitmap
.Mirror( BMP_MIRROR_HORZ
);
332 aImage
= Image( aBitmap
);
337 //------------------------------------------------------------------------------
338 void EditBrowseBox::PaintStatusCell(OutputDevice
& rDev
, const Rectangle
& rRect
) const
343 RowStatus eStatus
= GetRowStatus( nPaintRow
);
344 sal_Int32 nBrowserFlags
= GetBrowserFlags();
346 if (nBrowserFlags
& EBBF_NO_HANDLE_COLUMN_CONTENT
)
349 // draw the text of the header column
350 if (nBrowserFlags
& EBBF_HANDLE_COLUMN_TEXT
)
352 rDev
.DrawText( rRect
, GetCellText( nPaintRow
, 0 ),
353 TEXT_DRAW_CENTER
| TEXT_DRAW_VCENTER
| TEXT_DRAW_CLIP
);
356 else if (eStatus
!= CLEAN
&& rDev
.GetOutDevType() == OUTDEV_WINDOW
)
358 Image
aImage(GetImage(eStatus
));
359 // calc the image position
360 Size
aImageSize(aImage
.GetSizePixel());
361 aImageSize
.Width() = CalcZoom(aImageSize
.Width());
362 aImageSize
.Height() = CalcZoom(aImageSize
.Height());
363 Point
aPos( rRect
.TopLeft() );
365 if ( ( aImageSize
.Width() > rRect
.GetWidth() ) || ( aImageSize
.Height() > rRect
.GetHeight() ) )
366 rDev
.SetClipRegion(Region(rRect
));
368 if ( aImageSize
.Width() < rRect
.GetWidth() )
369 aPos
.X() += ( rRect
.GetWidth() - aImageSize
.Width() ) / 2;
371 if ( aImageSize
.Height() < rRect
.GetHeight() )
372 aPos
.Y() += ( rRect
.GetHeight() - aImageSize
.Height() ) / 2;
375 rDev
.DrawImage( aPos
, aImageSize
, aImage
, 0 );
377 rDev
.DrawImage( aPos
, aImage
, 0 );
379 if (rDev
.IsClipRegion())
380 rDev
.SetClipRegion();
384 //------------------------------------------------------------------------------
385 void EditBrowseBox::ImplStartTracking()
387 bActiveBeforeTracking
= IsEditing();
388 if ( bActiveBeforeTracking
)
394 BrowseBox::ImplStartTracking();
397 //------------------------------------------------------------------------------
398 void EditBrowseBox::ImplTracking()
400 BrowseBox::ImplTracking();
403 //------------------------------------------------------------------------------
404 void EditBrowseBox::ImplEndTracking()
406 if ( bActiveBeforeTracking
)
408 bActiveBeforeTracking
= sal_False
;
410 BrowseBox::ImplEndTracking();
413 //------------------------------------------------------------------------------
414 void EditBrowseBox::RowHeightChanged()
418 Rectangle
aRect( GetCellRect( nEditRow
, nEditCol
, sal_False
) );
419 CellControllerRef
aCellController( Controller() );
420 ResizeController( aCellController
, aRect
);
421 aCellController
->GetWindow().GrabFocus();
424 BrowseBox::RowHeightChanged();
427 //------------------------------------------------------------------------------
428 EditBrowseBox::RowStatus
EditBrowseBox::GetRowStatus(long) const
433 //------------------------------------------------------------------------------
434 void EditBrowseBox::KeyInput( const KeyEvent
& rEvt
)
436 sal_uInt16 nCode
= rEvt
.GetKeyCode().GetCode();
437 sal_Bool bShift
= rEvt
.GetKeyCode().IsShift();
438 sal_Bool bCtrl
= rEvt
.GetKeyCode().IsMod1();
443 if (!bCtrl
&& !bShift
&& IsTabAllowed(sal_True
))
445 Dispatch(BROWSER_CURSORRIGHT
);
448 BrowseBox::KeyInput(rEvt
);
451 if (!bCtrl
&& !bShift
)
453 if (IsTabAllowed(sal_True
))
454 Dispatch(BROWSER_CURSORRIGHT
);
456 // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
457 // that tab isn't allowed here. So give the Control class a chance
458 Control::KeyInput(rEvt
);
461 else if (!bCtrl
&& bShift
)
463 if (IsTabAllowed(sal_False
))
464 Dispatch(BROWSER_CURSORLEFT
);
466 // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
467 // that tab isn't allowed here. So give the Control class a chance
468 Control::KeyInput(rEvt
);
472 BrowseBox::KeyInput(rEvt
);
476 //------------------------------------------------------------------------------
477 void EditBrowseBox::MouseButtonDown(const BrowserMouseEvent
& rEvt
)
479 sal_uInt16 nColPos
= GetColumnPos( rEvt
.GetColumnId() );
480 long nRow
= rEvt
.GetRow();
482 // absorb double clicks
483 if (rEvt
.GetClicks() > 1 && rEvt
.GetRow() >= 0)
486 // change to a new position
487 if (IsEditing() && (nColPos
!= nEditCol
|| nRow
!= nEditRow
) && (nColPos
!= BROWSER_INVALIDID
) && (nRow
< GetRowCount()))
489 CellControllerRef
aCellController(Controller());
490 HideAndDisable(aCellController
);
493 // we are about to leave the current cell. If there is a "this cell has been modified" notification
494 // pending (asynchronously), this may be deadly -> do it synchronously
495 if ( nCellModifiedEvent
)
497 Application::RemoveUserEvent( nCellModifiedEvent
);
498 nCellModifiedEvent
= 0;
499 LINK( this, EditBrowseBox
, CellModifiedHdl
).Call( NULL
);
502 if (rEvt
.GetColumnId() == HandleColumnId
)
503 { // it was the handle column. save the current cell content if necessary
504 // (clicking on the handle column results in selecting the current row)
505 if (IsEditing() && aController
->IsModified())
509 aMouseEvent
.Set(&rEvt
,sal_True
);
510 BrowseBox::MouseButtonDown(rEvt
);
513 if (0 != (m_nBrowserFlags
& EBBF_ACTIVATE_ON_BUTTONDOWN
))
515 // the base class does not travel upon MouseButtonDown, but implActivateCellOnMouseEvent assumes we traveled ...
516 GoToRowColumnId( rEvt
.GetRow(), rEvt
.GetColumnId() );
517 if (rEvt
.GetRow() >= 0)
518 implActivateCellOnMouseEvent(rEvt
, sal_False
);
522 //------------------------------------------------------------------------------
523 void EditBrowseBox::MouseButtonUp( const BrowserMouseEvent
& rEvt
)
525 // absorb double clicks
526 if (rEvt
.GetClicks() > 1 && rEvt
.GetRow() >= 0)
529 aMouseEvent
.Set(&rEvt
,sal_False
);
530 BrowseBox::MouseButtonUp(rEvt
);
533 if (0 == (m_nBrowserFlags
& EBBF_ACTIVATE_ON_BUTTONDOWN
))
534 if (rEvt
.GetRow() >= 0)
535 implActivateCellOnMouseEvent(rEvt
, sal_True
);
538 //------------------------------------------------------------------------------
539 void EditBrowseBox::implActivateCellOnMouseEvent(const BrowserMouseEvent
& _rEvt
, sal_Bool _bUp
)
543 else if (IsEditing() && !aController
->GetWindow().IsEnabled())
545 else if (IsEditing() && !aController
->GetWindow().HasChildPathFocus())
548 if (IsEditing() && aController
->GetWindow().IsEnabled() && aController
->WantMouseEvent())
549 { // forwards the event to the control
551 // If the field has been moved previously, we have to adjust the position
553 aController
->GetWindow().GrabFocus();
555 // the position of the event relative to the controller's window
556 Point aPos
= _rEvt
.GetPosPixel() - _rEvt
.GetRect().TopLeft();
557 // the (child) window which should really get the event
558 Window
* pRealHandler
= aController
->GetWindow().FindWindow(aPos
);
560 // the coords relative to this real handler
561 aPos
-= pRealHandler
->GetPosPixel();
563 pRealHandler
= &aController
->GetWindow();
566 MouseEvent
aEvent(aPos
, _rEvt
.GetClicks(), _rEvt
.GetMode(),
568 _rEvt
.GetModifier());
570 pRealHandler
->MouseButtonDown(aEvent
);
572 pRealHandler
->MouseButtonUp(aEvent
);
574 Window
*pWin
= &aController
->GetWindow();
575 if (!pWin
->IsTracking())
577 for (pWin
= pWin
->GetWindow(WINDOW_FIRSTCHILD
);
578 pWin
&& !pWin
->IsTracking();
579 pWin
= pWin
->GetWindow(WINDOW_NEXT
))
583 if (pWin
&& pWin
->IsTracking())
588 //------------------------------------------------------------------------------
589 void EditBrowseBox::Dispatch( sal_uInt16 _nId
)
591 if ( _nId
== BROWSER_ENHANCESELECTION
)
592 { // this is a workaround for the bug in the base class:
593 // if the row selection is to be extended (which is what BROWSER_ENHANCESELECTION tells us)
594 // then the base class does not revert any column selections, while, for doing a "simple"
595 // selection (BROWSER_SELECT), it does. In fact, it does not only revert the col selection then,
596 // but also any current row selections.
597 // This clearly tells me that the both ids are for row selection only - there this behaviour does
599 // But here, where we have column selection, too, we take care of this ourself.
600 if ( GetSelectColumnCount( ) )
602 while ( GetSelectColumnCount( ) )
604 sal::static_int_cast
< sal_uInt16
>(FirstSelectedColumn()),
609 BrowseBox::Dispatch( _nId
);
612 //------------------------------------------------------------------------------
613 long EditBrowseBox::PreNotify(NotifyEvent
& rEvt
)
615 switch (rEvt
.GetType())
618 if ( (IsEditing() && Controller()->GetWindow().HasChildPathFocus())
619 || rEvt
.GetWindow() == &GetDataWindow()
620 || (!IsEditing() && HasChildPathFocus())
623 const KeyEvent
* pKeyEvent
= rEvt
.GetKeyEvent();
624 sal_uInt16 nCode
= pKeyEvent
->GetKeyCode().GetCode();
625 sal_Bool bShift
= pKeyEvent
->GetKeyCode().IsShift();
626 sal_Bool bCtrl
= pKeyEvent
->GetKeyCode().IsMod1();
627 sal_Bool bAlt
= pKeyEvent
->GetKeyCode().IsMod2();
628 sal_Bool bLocalSelect
= sal_False
;
629 sal_Bool bNonEditOnly
= sal_False
;
630 sal_uInt16 nId
= BROWSER_NONE
;
632 if (!bAlt
&& !bCtrl
&& !bShift
)
635 case KEY_DOWN
: nId
= BROWSER_CURSORDOWN
; break;
636 case KEY_UP
: nId
= BROWSER_CURSORUP
; break;
637 case KEY_PAGEDOWN
: nId
= BROWSER_CURSORPAGEDOWN
; break;
638 case KEY_PAGEUP
: nId
= BROWSER_CURSORPAGEUP
; break;
639 case KEY_HOME
: nId
= BROWSER_CURSORHOME
; break;
640 case KEY_END
: nId
= BROWSER_CURSOREND
; break;
643 // ask if traveling to the next cell is allowed
644 if (IsTabAllowed(sal_True
))
645 nId
= BROWSER_CURSORRIGHT
;
649 // save the cell content (if necessary)
650 if (IsEditing() && aController
->IsModified() && !((EditBrowseBox
*) this)->SaveModified())
652 // maybe we're not visible ...
654 aController
->GetWindow().GrabFocus();
657 // ask if traveling to the next cell is allowed
658 if (IsTabAllowed(sal_True
))
659 nId
= BROWSER_CURSORRIGHT
;
662 case KEY_RIGHT
: nId
= BROWSER_CURSORRIGHT
; break;
663 case KEY_LEFT
: nId
= BROWSER_CURSORLEFT
; break;
664 case KEY_SPACE
: nId
= BROWSER_SELECT
; bNonEditOnly
= bLocalSelect
= sal_True
;break;
667 if ( !bAlt
&& !bCtrl
&& bShift
)
670 case KEY_DOWN
: nId
= BROWSER_SELECTDOWN
; bLocalSelect
= sal_True
;break;
671 case KEY_UP
: nId
= BROWSER_SELECTUP
; bLocalSelect
= sal_True
;break;
672 case KEY_HOME
: nId
= BROWSER_SELECTHOME
; bLocalSelect
= sal_True
;break;
673 case KEY_END
: nId
= BROWSER_SELECTEND
; bLocalSelect
= sal_True
;break;
675 if (IsTabAllowed(sal_False
))
676 nId
= BROWSER_CURSORLEFT
;
680 if ( !bAlt
&& bCtrl
&& bShift
)
683 case KEY_SPACE
: nId
= BROWSER_SELECTCOLUMN
; bLocalSelect
= sal_True
; break;
687 if ( !bAlt
&& bCtrl
&& !bShift
)
690 case KEY_DOWN
: nId
= BROWSER_SCROLLUP
; break;
691 case KEY_UP
: nId
= BROWSER_SCROLLDOWN
; break;
692 case KEY_PAGEDOWN
: nId
= BROWSER_CURSORENDOFFILE
; break;
693 case KEY_PAGEUP
: nId
= BROWSER_CURSORTOPOFFILE
; break;
694 case KEY_HOME
: nId
= BROWSER_CURSORTOPOFSCREEN
; break;
695 case KEY_END
: nId
= BROWSER_CURSORENDOFSCREEN
; break;
696 case KEY_SPACE
: nId
= BROWSER_ENHANCESELECTION
; bLocalSelect
= sal_True
;break;
700 if ( ( nId
!= BROWSER_NONE
)
703 && aController
->MoveAllowed( *pKeyEvent
)
708 if (nId
== BROWSER_SELECT
|| BROWSER_SELECTCOLUMN
== nId
)
710 // save the cell content (if necessary)
711 if (IsEditing() && aController
->IsModified() && !((EditBrowseBox
*) this)->SaveModified())
713 // maybe we're not visible ...
715 aController
->GetWindow().GrabFocus();
722 if (bLocalSelect
&& (GetSelectRowCount() || GetSelection() != NULL
))
728 return BrowseBox::PreNotify(rEvt
);
731 //------------------------------------------------------------------------------
732 sal_Bool
EditBrowseBox::IsTabAllowed(sal_Bool
) const
737 //------------------------------------------------------------------------------
738 long EditBrowseBox::Notify(NotifyEvent
& rEvt
)
740 switch (rEvt
.GetType())
743 DetermineFocus( getRealGetFocusFlags( this ) );
746 case EVENT_LOSEFOCUS
:
750 return BrowseBox::Notify(rEvt
);
753 //------------------------------------------------------------------------------
754 void EditBrowseBox::StateChanged( StateChangedType nType
)
756 BrowseBox::StateChanged( nType
);
758 bool bNeedCellReActivation
= false;
759 if ( nType
== STATE_CHANGE_MIRRORING
)
761 bNeedCellReActivation
= true;
763 else if ( nType
== STATE_CHANGE_ZOOM
)
765 ImplInitSettings( sal_True
, sal_False
, sal_False
);
766 bNeedCellReActivation
= true;
768 else if ( nType
== STATE_CHANGE_CONTROLFONT
)
770 ImplInitSettings( sal_True
, sal_False
, sal_False
);
773 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
775 ImplInitSettings( sal_False
, sal_True
, sal_False
);
778 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
780 ImplInitSettings( sal_False
, sal_False
, sal_True
);
783 else if (nType
== STATE_CHANGE_STYLE
)
785 WinBits nStyle
= GetStyle();
786 if (!(nStyle
& WB_NOTABSTOP
) )
787 nStyle
|= WB_TABSTOP
;
791 if ( bNeedCellReActivation
)
801 //------------------------------------------------------------------------------
802 void EditBrowseBox::DataChanged( const DataChangedEvent
& rDCEvt
)
804 BrowseBox::DataChanged( rDCEvt
);
806 if ((( rDCEvt
.GetType() == DATACHANGED_SETTINGS
) ||
807 ( rDCEvt
.GetType() == DATACHANGED_DISPLAY
)) &&
808 ( rDCEvt
.GetFlags() & SETTINGS_STYLE
))
810 ImplInitSettings( sal_True
, sal_True
, sal_True
);
815 //------------------------------------------------------------------------------
816 void EditBrowseBox::ImplInitSettings( sal_Bool bFont
, sal_Bool bForeground
, sal_Bool bBackground
)
818 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
822 Font aFont
= rStyleSettings
.GetFieldFont();
825 GetDataWindow().SetControlFont(GetControlFont());
826 aFont
.Merge(GetControlFont());
829 GetDataWindow().SetControlFont();
831 GetDataWindow().SetZoomedPointFont(aFont
);
834 if ( bFont
|| bForeground
)
836 Color aTextColor
= rStyleSettings
.GetFieldTextColor();
837 if (IsControlForeground())
839 aTextColor
= GetControlForeground();
840 GetDataWindow().SetControlForeground(aTextColor
);
843 GetDataWindow().SetControlForeground();
845 GetDataWindow().SetTextColor( aTextColor
);
850 if (GetDataWindow().IsControlBackground())
852 GetDataWindow().SetControlBackground(GetControlBackground());
853 GetDataWindow().SetBackground(GetDataWindow().GetControlBackground());
854 GetDataWindow().SetFillColor(GetDataWindow().GetControlBackground());
858 GetDataWindow().SetControlBackground();
859 GetDataWindow().SetBackground( rStyleSettings
.GetFieldColor() );
860 GetDataWindow().SetFillColor( rStyleSettings
.GetFieldColor() );
865 //------------------------------------------------------------------------------
866 sal_Bool
EditBrowseBox::IsCursorMoveAllowed(long nNewRow
, sal_uInt16 nNewColId
) const
868 sal_uInt16 nInfo
= 0;
870 if (GetSelectColumnCount() || (aMouseEvent
.Is() && aMouseEvent
->GetRow() < 0))
872 if ((GetSelection() != NULL
&& GetSelectRowCount()) ||
873 (aMouseEvent
.Is() && aMouseEvent
->GetColumnId() == HandleColumnId
))
875 if (!nInfo
&& nNewRow
!= nEditRow
)
877 if (!nInfo
&& nNewColId
!= nEditCol
)
880 if (nInfo
== 0) // nothing happened
883 // save the cell content
884 if (IsEditing() && aController
->IsModified() && !((EditBrowseBox
*) this)->SaveModified())
886 // maybe we're not visible ...
888 aController
->GetWindow().GrabFocus();
892 EditBrowseBox
* pTHIS
= const_cast<EditBrowseBox
*> (this);
894 // save the cell content if
895 // a) a selection is beeing made
896 // b) the row is changing
897 if (IsModified() && (nInfo
& (ROWCHANGE
| COLSELECT
| ROWSELECT
)) &&
900 if (nInfo
& COLSELECT
||
904 pTHIS
->SetNoSelection();
909 if (!Controller()->GetWindow().IsVisible())
913 aController
->GetWindow().GrabFocus();
918 if (nNewRow
!= nEditRow
)
920 Window
& rWindow
= GetDataWindow();
921 if ((nEditRow
>= 0) && (GetBrowserFlags() & EBBF_NO_HANDLE_COLUMN_CONTENT
) == 0)
923 Rectangle aRect
= GetFieldRectPixel(nEditRow
, 0, sal_False
);
924 // status cell should be painted if and only if text is displayed
925 // note: bPaintStatus is mutable, but Solaris has problems with assigning
926 // probably because it is part of a bitfield
927 pTHIS
->bPaintStatus
= static_cast< sal_Bool
>
928 (( GetBrowserFlags() & EBBF_HANDLE_COLUMN_TEXT
) == EBBF_HANDLE_COLUMN_TEXT
);
929 rWindow
.Invalidate(aRect
);
930 pTHIS
->bPaintStatus
= sal_True
;
933 // don't paint during row change
934 rWindow
.EnablePaint(sal_False
);
936 // the last veto chance for derived classes
937 if (!pTHIS
->CursorMoving(nNewRow
, nNewColId
))
939 pTHIS
->InvalidateStatusCell(nEditRow
);
940 rWindow
.EnablePaint(sal_True
);
945 rWindow
.EnablePaint(sal_True
);
950 return pTHIS
->CursorMoving(nNewRow
, nNewColId
);
953 //------------------------------------------------------------------------------
954 void EditBrowseBox::ColumnMoved(sal_uInt16 nId
)
956 BrowseBox::ColumnMoved(nId
);
959 Rectangle
aRect( GetCellRect(nEditRow
, nEditCol
, sal_False
));
960 CellControllerRef aControllerRef
= Controller();
961 ResizeController(aControllerRef
, aRect
);
962 Controller()->GetWindow().GrabFocus();
966 //------------------------------------------------------------------------------
967 sal_Bool
EditBrowseBox::SaveRow()
972 //------------------------------------------------------------------------------
973 sal_Bool
EditBrowseBox::CursorMoving(long, sal_uInt16
)
975 ((EditBrowseBox
*) this)->DeactivateCell(sal_False
);
979 //------------------------------------------------------------------------------
980 void EditBrowseBox::CursorMoved()
982 long nNewRow
= GetCurRow();
983 if (nEditRow
!= nNewRow
)
985 if ((GetBrowserFlags() & EBBF_NO_HANDLE_COLUMN_CONTENT
) == 0)
986 InvalidateStatusCell(nNewRow
);
990 GetDataWindow().EnablePaint(sal_True
);
991 // should not be called here because the descant event is not needed here
992 //BrowseBox::CursorMoved();
995 //------------------------------------------------------------------------------
996 void EditBrowseBox::EndScroll()
1000 Rectangle aRect
= GetCellRect(nEditRow
, nEditCol
, sal_False
);
1001 ResizeController(aController
,aRect
);
1004 BrowseBox::EndScroll();
1007 //------------------------------------------------------------------------------
1008 void EditBrowseBox::ActivateCell(long nRow
, sal_uInt16 nCol
, sal_Bool bCellFocus
)
1015 if ((GetSelectRowCount() && GetSelection() != NULL
) || GetSelectColumnCount() ||
1016 (aMouseEvent
.Is() && (aMouseEvent
.IsDown() || aMouseEvent
->GetClicks() > 1))) // nothing happens on MouseDown
1021 if (nEditRow
>= 0 && nEditCol
> HandleColumnId
)
1023 aController
= GetController(nRow
, nCol
);
1024 if (aController
.Is())
1026 Rectangle
aRect( GetCellRect(nEditRow
, nEditCol
, sal_False
));
1027 ResizeController(aController
, aRect
);
1029 InitController(aController
, nEditRow
, nEditCol
);
1031 aController
->ClearModified();
1032 aController
->SetModifyHdl(LINK(this,EditBrowseBox
,ModifyHdl
));
1035 if ( isAccessibleAlive() )
1036 implCreateActiveAccessible();
1038 // activate the cell only of the browser has the focus
1039 if ( bHasFocus
&& bCellFocus
)
1044 // no controller -> we have a new "active descendant"
1045 if ( isAccessibleAlive() && HasFocus() )
1048 ACTIVE_DESCENDANT_CHANGED
,
1049 makeAny( CreateAccessibleCell( nRow
, GetColumnPos( nCol
) ) ),
1057 //------------------------------------------------------------------------------
1058 void EditBrowseBox::DeactivateCell(sal_Bool bUpdate
)
1062 if ( isAccessibleAlive() )
1064 commitBrowseBoxEvent( CHILD
, Any(), makeAny( m_aImpl
->m_xActiveCell
) );
1065 m_aImpl
->clearActiveCell();
1068 aOldController
= aController
;
1069 aController
.Clear();
1071 // reset the modify handler
1072 aOldController
->SetModifyHdl(Link());
1075 GrabFocus(); // ensure that we have (and keep) the focus
1077 HideAndDisable(aOldController
);
1079 // update if requested
1083 nOldEditCol
= nEditCol
;
1084 nOldEditRow
= nEditRow
;
1086 // release the controller (asynchronously)
1088 Application::RemoveUserEvent(nEndEvent
);
1089 nEndEvent
= Application::PostUserEvent(LINK(this,EditBrowseBox
,EndEditHdl
));
1093 //------------------------------------------------------------------------------
1094 Rectangle
EditBrowseBox::GetCellRect(long nRow
, sal_uInt16 nColId
, sal_Bool bRel
) const
1096 Rectangle
aRect( GetFieldRectPixel(nRow
, nColId
, bRel
));
1097 if ((GetMode() & BROWSER_CURSOR_WO_FOCUS
) == BROWSER_CURSOR_WO_FOCUS
)
1100 aRect
.Bottom() -= 1;
1105 //------------------------------------------------------------------------------
1106 IMPL_LINK_NOARG(EditBrowseBox
, EndEditHdl
)
1109 ReleaseController(aOldController
, nOldEditRow
, nOldEditCol
);
1111 aOldController
= CellControllerRef();
1118 //------------------------------------------------------------------------------
1119 IMPL_LINK_NOARG(EditBrowseBox
, ModifyHdl
)
1121 if (nCellModifiedEvent
)
1122 Application::RemoveUserEvent(nCellModifiedEvent
);
1123 nCellModifiedEvent
= Application::PostUserEvent(LINK(this,EditBrowseBox
,CellModifiedHdl
));
1127 //------------------------------------------------------------------------------
1128 IMPL_LINK_NOARG(EditBrowseBox
, CellModifiedHdl
)
1130 nCellModifiedEvent
= 0;
1135 //------------------------------------------------------------------------------
1136 void EditBrowseBox::ColumnResized( sal_uInt16
)
1140 Rectangle
aRect( GetCellRect(nEditRow
, nEditCol
, sal_False
));
1141 CellControllerRef aControllerRef
= Controller();
1142 ResizeController(aControllerRef
, aRect
);
1143 Controller()->GetWindow().GrabFocus();
1147 //------------------------------------------------------------------------------
1148 sal_uInt16
EditBrowseBox::AppendColumn(const String
& rName
, sal_uInt16 nWidth
, sal_uInt16 nPos
, sal_uInt16 nId
)
1150 if (nId
== BROWSER_INVALIDID
)
1152 // look for the next free id
1153 for (nId
= ColCount(); nId
> 0 && GetColumnPos(nId
) != BROWSER_INVALIDID
; nId
--)
1158 // if there is no handle column
1160 if ( ColCount() == 0 || GetColumnId(0) != HandleColumnId
)
1161 nId
= ColCount() + 1;
1165 DBG_ASSERT(nId
, "EditBrowseBox::AppendColumn: invalid id!");
1169 w
= GetDefaultColumnWidth(rName
);
1171 InsertDataColumn(nId
, rName
, w
, (HIB_CENTER
| HIB_VCENTER
| HIB_CLICKABLE
), nPos
);
1175 //------------------------------------------------------------------------------
1176 void EditBrowseBox::Resize()
1178 BrowseBox::Resize();
1180 // if the window is smaller than "title line height" + "control area",
1182 if (GetOutputSizePixel().Height() <
1183 (GetControlArea().GetHeight() + GetDataWindow().GetPosPixel().Y()))
1186 // the size of the control area
1187 Point
aPoint(GetControlArea().TopLeft());
1188 sal_uInt16 nX
= (sal_uInt16
)aPoint
.X();
1190 ArrangeControls(nX
, (sal_uInt16
)aPoint
.Y());
1194 ReserveControlArea((sal_uInt16
)nX
);
1197 //------------------------------------------------------------------------------
1198 void EditBrowseBox::ArrangeControls(sal_uInt16
&, sal_uInt16
)
1202 //------------------------------------------------------------------------------
1203 CellController
* EditBrowseBox::GetController(long, sal_uInt16
)
1208 //-----------------------------------------------------------------------------
1209 void EditBrowseBox::ResizeController(CellControllerRef
& rController
, const Rectangle
& rRect
)
1211 rController
->GetWindow().SetPosSizePixel(rRect
.TopLeft(), rRect
.GetSize());
1214 //------------------------------------------------------------------------------
1215 void EditBrowseBox::InitController(CellControllerRef
&, long, sal_uInt16
)
1219 //------------------------------------------------------------------------------
1220 void EditBrowseBox::ReleaseController(CellControllerRef
&, long, sal_uInt16
)
1224 //------------------------------------------------------------------------------
1225 void EditBrowseBox::CellModified()
1230 //------------------------------------------------------------------------------
1231 sal_Bool
EditBrowseBox::SaveModified()
1236 //------------------------------------------------------------------------------
1237 void EditBrowseBox::DoubleClick(const BrowserMouseEvent
& rEvt
)
1239 // when double clicking on the column, the optimum size will be calculated
1240 sal_uInt16 nColId
= rEvt
.GetColumnId();
1241 if (nColId
!= HandleColumnId
)
1242 SetColumnWidth(nColId
, GetAutoColumnWidth(nColId
));
1245 //------------------------------------------------------------------------------
1246 sal_uInt32
EditBrowseBox::GetAutoColumnWidth(sal_uInt16 nColId
)
1248 sal_uInt32 nCurColWidth
= GetColumnWidth(nColId
);
1249 sal_uInt32 nMinColWidth
= CalcZoom(20); // minimum
1250 sal_uInt32 nNewColWidth
= nMinColWidth
;
1251 long nMaxRows
= std::min(long(GetVisibleRows()), GetRowCount());
1252 long nLastVisRow
= GetTopRow() + nMaxRows
- 1;
1254 if (GetTopRow() <= nLastVisRow
) // calc the column with using the cell contents
1256 for (long i
= GetTopRow(); i
<= nLastVisRow
; ++i
)
1257 nNewColWidth
= std::max(nNewColWidth
,GetTotalCellWidth(i
,nColId
) + 12);
1259 if (nNewColWidth
== nCurColWidth
) // size has not changed
1260 nNewColWidth
= GetDefaultColumnWidth(GetColumnTitle(nColId
));
1263 nNewColWidth
= GetDefaultColumnWidth(GetColumnTitle(nColId
));
1264 return nNewColWidth
;
1267 //------------------------------------------------------------------------------
1268 sal_uInt32
EditBrowseBox::GetTotalCellWidth(long, sal_uInt16
)
1273 //------------------------------------------------------------------------------
1274 void EditBrowseBox::InvalidateHandleColumn()
1276 Rectangle
aHdlFieldRect( GetFieldRectPixel( 0, 0 ));
1277 Rectangle
aInvalidRect( Point(0,0), GetOutputSizePixel() );
1278 aInvalidRect
.Right() = aHdlFieldRect
.Right();
1279 Invalidate( aInvalidRect
);
1282 //------------------------------------------------------------------------------
1283 void EditBrowseBox::PaintTristate(OutputDevice
&, const Rectangle
& rRect
,const TriState
& eState
,sal_Bool _bEnabled
) const
1285 pCheckBoxPaint
->GetBox().SetState(eState
);
1286 pCheckBoxPaint
->SetPosSizePixel(rRect
.TopLeft(), rRect
.GetSize());
1288 // First update the parent, preventing that while painting this window
1289 // an update for the parent is done (because it's in the queue already)
1290 // which may lead to hiding this window immediately
1291 // #95598# comment out OJ
1292 /* if (pCheckBoxPaint->GetParent())
1293 pCheckBoxPaint->GetParent()->Update();
1295 pCheckBoxPaint
->GetBox().Enable(_bEnabled
);
1296 pCheckBoxPaint
->Show();
1297 pCheckBoxPaint
->SetParentUpdateMode( sal_False
);
1298 pCheckBoxPaint
->Update();
1299 pCheckBoxPaint
->Hide();
1300 pCheckBoxPaint
->SetParentUpdateMode( sal_True
);
1303 //------------------------------------------------------------------------------
1304 void EditBrowseBox::AsynchGetFocus()
1307 Application::RemoveUserEvent(nStartEvent
);
1309 m_pFocusWhileRequest
= Application::GetFocusWindow();
1310 nStartEvent
= Application::PostUserEvent(LINK(this,EditBrowseBox
,StartEditHdl
));
1313 //------------------------------------------------------------------------------
1314 void EditBrowseBox::SetBrowserFlags(sal_Int32 nFlags
)
1316 if (m_nBrowserFlags
== nFlags
)
1319 sal_Bool RowPicturesChanges
= ((m_nBrowserFlags
& EBBF_NO_HANDLE_COLUMN_CONTENT
) !=
1320 (nFlags
& EBBF_NO_HANDLE_COLUMN_CONTENT
));
1321 m_nBrowserFlags
= nFlags
;
1323 if (RowPicturesChanges
)
1324 InvalidateStatusCell(GetCurRow());
1326 //------------------------------------------------------------------------------
1327 inline void EditBrowseBox::HideAndDisable(CellControllerRef
& rController
)
1329 rController
->suspend();
1331 //------------------------------------------------------------------------------
1332 inline void EditBrowseBox::EnableAndShow() const
1334 Controller()->resume();
1336 //===============================================================================
1338 DBG_NAME(CellController
);
1339 //------------------------------------------------------------------------------
1340 CellController::CellController(Control
* pW
)
1342 ,bSuspended( sal_True
)
1344 DBG_CTOR(CellController
,NULL
);
1346 DBG_ASSERT(pWindow
, "CellController::CellController: missing the window!");
1347 DBG_ASSERT(!pWindow
->IsVisible(), "CellController::CellController: window should not be visible!");
1350 //-----------------------------------------------------------------------------
1351 CellController::~CellController()
1354 DBG_DTOR(CellController
,NULL
);
1357 //-----------------------------------------------------------------------------
1358 void CellController::suspend( )
1360 DBG_ASSERT( bSuspended
== !GetWindow().IsVisible(), "CellController::suspend: inconsistence!" );
1361 if ( !isSuspended( ) )
1363 CommitModifications();
1364 GetWindow().Hide( );
1365 GetWindow().Disable( );
1366 bSuspended
= sal_True
;
1370 //-----------------------------------------------------------------------------
1371 void CellController::resume( )
1373 DBG_ASSERT( bSuspended
== !GetWindow().IsVisible(), "CellController::resume: inconsistence!" );
1374 if ( isSuspended( ) )
1376 GetWindow().Enable( );
1377 GetWindow().Show( );
1378 bSuspended
= sal_False
;
1382 //-----------------------------------------------------------------------------
1383 void CellController::CommitModifications()
1385 // nothing to do in this base class
1388 //-----------------------------------------------------------------------------
1389 sal_Bool
CellController::WantMouseEvent() const
1394 //-----------------------------------------------------------------------------
1395 void CellController::SetModified()
1399 //-----------------------------------------------------------------------------
1400 sal_Bool
CellController::MoveAllowed(const KeyEvent
&) const
1404 // .......................................................................
1406 // .......................................................................
1408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */