office-gobmx/extensions/source/propctrlr/browserlistbox.cxx
Oliver Bolte 9a1c787136 INTEGRATION: CWS formdesign01 (1.5.8); FILE MERGED
2003/12/19 14:25:53 fs 1.5.8.4: RESYNC: (1.5-1.6); FILE MERGED
2003/12/17 10:38:20 fs 1.5.8.3: #i22878# filter and sort order dialog from within the property browser
2003/12/04 14:06:37 fs 1.5.8.2: #i23190# fine control over disabling/enabling parts of the line
2003/12/03 10:06:40 fs 1.5.8.1: #i22878# measurement units for Width and RowHeight
2004-03-19 11:00:20 +00:00

975 lines
33 KiB
C++

/*************************************************************************
*
* $RCSfile: browserlistbox.cxx,v $
*
* $Revision: 1.7 $
*
* last change: $Author: obo $ $Date: 2004-03-19 12:00:20 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (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.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc..
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#ifndef _EXTENSIONS_PROPCTRLR_BROWSERLISTBOX_HXX_
#include "browserlistbox.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPRESID_HRC_
#include "propresid.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPLINELISTENER_HXX_
#include "proplinelistener.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_LINEDESCRIPTOR_HXX_
#include "linedescriptor.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_STANDARDCONTROL_HXX_
#include "standardcontrol.hxx"
#endif
//............................................................................
namespace pcr
{
//............................................................................
#define FRAME_OFFSET 4
// TODO: find out what this is really for ... and check if it does make sense in the new
// browser environment
//==================================================================
//= OBrowserListBox
//==================================================================
DBG_NAME(OBrowserListBox)
//------------------------------------------------------------------
OBrowserListBox::OBrowserListBox( Window* pParent, WinBits nWinStyle)
:Control(pParent, nWinStyle| WB_CLIPCHILDREN)
,m_aVScroll(this,WB_VSCROLL|WB_REPEAT|WB_DRAG)
,m_aPlayGround(this,WB_DIALOGCONTROL | WB_CLIPCHILDREN)
,m_pLineListener(NULL)
,m_bUpdate(sal_True)
,m_aStandard(ModuleRes(RID_STR_STANDARD))
,m_bIsActive(sal_False)
,m_nYOffset(0)
,m_nSelectedLine(0)
,m_nTheNameSize(0)
{
DBG_CTOR(OBrowserListBox,NULL);
ListBox aListBox(this,WB_DROPDOWN);
aListBox.SetPosSizePixel(Point(0,0),Size(100,100));
m_nRowHeight = (sal_uInt16)aListBox.GetSizePixel().Height()+2;
SetBackground(m_aPlayGround.GetBackground());
m_aPlayGround.SetPosPixel(Point(0,0));
m_aPlayGround.SetPaintTransparent(sal_True);
m_aPlayGround.Show();
m_aVScroll.Hide();
m_aVScroll.SetScrollHdl(LINK(this, OBrowserListBox, ScrollHdl));
}
//------------------------------------------------------------------
OBrowserListBox::~OBrowserListBox()
{
OSL_ENSURE( !IsModified(), "OBrowserListBox::~OBrowserListBox: still modified - should have been committed before!" );
// doing the commit here, while we, as well as our owner, as well as some other components,
// are already "half dead" (means within their dtor) is potentially dangerous.
// By definition, CommitModified has to be called (if necessary) before destruction
// #105868# - 2002-12-13 - fs@openoffice.org
Hide();
Clear();
DBG_DTOR(OBrowserListBox,NULL);
}
//------------------------------------------------------------------
sal_Bool OBrowserListBox::IsModified( ) const
{
sal_Bool bModified = sal_False;
if ( m_bIsActive && ( m_aLines.size() > m_nSelectedLine ) )
{ // we have an active line at least
IBrowserControl* pControl = m_aLines[ m_nSelectedLine ]->getControl();
// and the control in this line is modified
bModified = ( NULL != pControl ) && ( pControl->IsModified() );
}
return bModified;
}
//------------------------------------------------------------------
void OBrowserListBox::CommitModified( )
{
if ( IsModified() )
{
if ( m_aLines.size() > m_nSelectedLine )
{
IBrowserControl* pControl = m_aLines[ m_nSelectedLine ]->getControl();
pControl->CommitModified();
}
}
}
//------------------------------------------------------------------
void OBrowserListBox::Activate(sal_Bool _bActive)
{
m_bIsActive = _bActive;
if (m_bIsActive)
{
// TODO: what's the sense of this?
m_aVScroll.SetThumbPos(100);
MoveThumbTo(0);
Resize();
}
}
//------------------------------------------------------------------
void OBrowserListBox::Resize()
{
Size aSize(GetOutputSizePixel());
m_aPlayGround.SetSizePixel(aSize);
UpdateVScroll();
Size a2Size(aSize);
Size aVScrollSize;
sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();
sal_Int32 nLines = CalcVisibleLines();
sal_Bool bNeedScrollbar = m_aLines.size() > (sal_uInt32)nLines;
if (!bNeedScrollbar)
{ // don't need a scrollbar
if (m_aVScroll.IsVisible())
m_aVScroll.Hide();
nThumbPos=0;
m_nYOffset=0;
m_aPlayGround.SetSizePixel(aSize);
m_aVScroll.SetThumbPos(nThumbPos);
}
else
{ // need a scrollbar -> adjust the playground
Point aPos(0,0);
aVScrollSize = m_aVScroll.GetSizePixel();
aVScrollSize.Height() = aSize.Height();
a2Size.Width() -= aVScrollSize.Width();
aPos.X() = a2Size.Width();
m_aVScroll.SetPosPixel(aPos);
m_aVScroll.SetSizePixel(aVScrollSize);
m_aPlayGround.SetSizePixel(a2Size);
}
for (sal_uInt16 i=0; i<m_aLines.size(); ++i)
m_aLines[i]->SetNeedsRepaint(sal_True);
// repaint
EnablePaint(sal_False);
UpdatePlayGround();
EnablePaint(sal_True);
// show the scrollbar
if (bNeedScrollbar)
m_aVScroll.Show();
}
//------------------------------------------------------------------
void OBrowserListBox::setListener(IPropertyLineListener* _pPLL)
{
m_pLineListener = _pPLL;
}
//------------------------------------------------------------------
sal_uInt16 OBrowserListBox::CalcVisibleLines()
{
Size aSize(m_aPlayGround.GetOutputSizePixel());
sal_uInt16 nResult = 0;
if (0 != m_nRowHeight)
nResult = (sal_uInt16) aSize.Height()/m_nRowHeight;
return nResult;
}
//------------------------------------------------------------------
void OBrowserListBox::UpdateVScroll()
{
sal_uInt16 nLines = CalcVisibleLines();
m_aVScroll.SetPageSize(nLines-1);
m_aVScroll.SetVisibleSize(nLines-1);
sal_uInt16 nCount = m_aLines.size();
sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();
if (nCount>0)
{
m_aVScroll.SetRange(Range(0,nCount-1));
m_nYOffset = -m_aVScroll.GetThumbPos()*m_nRowHeight;
}
else
{
m_aVScroll.SetRange(Range(0,0));
m_nYOffset = 0;
}
}
//------------------------------------------------------------------
void OBrowserListBox::ShowLine(sal_uInt16 i)
{
Size aSize(m_aPlayGround.GetOutputSizePixel());
Point aPos(0, m_nYOffset);
aSize.Height() = m_nRowHeight;
aPos.Y() += i * m_nRowHeight;
if (i<m_aLines.size())
{
// adjust the pos and - if needed - the size
if (m_aLines[i]->GetSizePixel() != aSize)
m_aLines[i]->SetPosSizePixel(aPos, aSize);
else
m_aLines[i]->SetPosPixel(aPos);
m_aLines[i]->SetTitleWidth(m_nTheNameSize + 2 * FRAME_OFFSET);
// show the line if necessary
if (!m_aLines[i]->IsVisible())
m_aLines[i]->Show();
}
}
//------------------------------------------------------------------
void OBrowserListBox::UpdatePosNSize()
{
sal_uInt16 i;
for (i=0; i<m_aLines.size(); ++i)
{
if (m_aLines[i]->NeedsRepaint())
ShowLine(i);
}
for (i=0; i<m_aLines.size(); ++i)
m_aLines[i]->SetNeedsRepaint(sal_False);
}
//------------------------------------------------------------------
void OBrowserListBox::UpdatePlayGround()
{
sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();
sal_Int32 nLines = CalcVisibleLines();
sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + nLines);
if (nEnd >= m_aLines.size())
nEnd = m_aLines.size()-1;
if (m_aLines.size()>0)
{
for (sal_uInt16 i = (sal_uInt16)nThumbPos; i<=nEnd; ++i)
m_aLines[i]->SetNeedsRepaint(sal_True);
UpdatePosNSize();
}
}
//------------------------------------------------------------------
void OBrowserListBox::UpdateAll()
{
Resize();
}
//------------------------------------------------------------------
void OBrowserListBox::DisableUpdate()
{
m_bUpdate = sal_False;
}
//------------------------------------------------------------------
void OBrowserListBox::EnableUpdate()
{
m_bUpdate = sal_True;
UpdateAll();
}
//------------------------------------------------------------------
void OBrowserListBox::SetPropertyValue(const ::rtl::OUString& _rEntryName, const ::rtl::OUString& _rValue)
{
// TODO: why not an O(log n) search? would need a map for this ...
sal_uInt16 i, nEnd = m_aLines.size();
for (i = 0 ; i<nEnd ; ++i)
{
OBrowserLine* pLine = m_aLines[i];
IBrowserControl* pControl = pLine->getControl();
if (pControl && (pControl->GetMyName() == _rEntryName))
{
pControl->SetProperty(_rValue);
break;
}
}
}
//------------------------------------------------------------------------
::rtl::OUString OBrowserListBox::GetPropertyValue(const ::rtl::OUString& _rEntryName) const
{
// TODO: O(log n) search
sal_uInt16 i, nEnd = m_aLines.size();
for (i=0; i<nEnd; ++i)
{
OBrowserLine* pLine = m_aLines[i];
IBrowserControl* pControl = pLine->getControl();
if (pControl && (pControl->GetMyName() == _rEntryName))
return pControl->GetProperty();
}
return ::rtl::OUString();
}
//------------------------------------------------------------------------
sal_uInt16 OBrowserListBox::GetPropertyPos(const ::rtl::OUString& _rEntryName) const
{
// TODO: O(log n) search
sal_uInt16 i, nEnd = m_aLines.size();
sal_uInt16 nRet = LISTBOX_ENTRY_NOTFOUND;
for (i=0; i<nEnd; ++i)
{
OBrowserLine* pLine = m_aLines[i];
IBrowserControl* pControl = pLine->getControl();
if (pControl && (pControl->GetMyName() == _rEntryName))
{
nRet = i;
break;
}
}
return nRet;
}
//------------------------------------------------------------------------
void OBrowserListBox::EnablePropertyInput( const ::rtl::OUString& _rEntryName, bool _bEnableInput, bool _bEnableBrowseButton )
{
// TODO: O(log n) search
sal_uInt16 i, nEnd = m_aLines.size();
for ( i = 0 ; i<nEnd ; ++i )
{
OBrowserLine* pLine = m_aLines[i];
IBrowserControl* pControl = pLine->getControl();
if ( pControl && ( pControl->GetMyName() == _rEntryName ) )
{
pLine->EnableInputControls( _bEnableInput, _bEnableBrowseButton );
break;
}
}
}
//------------------------------------------------------------------------
void OBrowserListBox::EnablePropertyLine( const ::rtl::OUString& _rEntryName, bool _bEnable )
{
// TODO: O(log n) search
sal_uInt16 i, nEnd = m_aLines.size();
for ( i = 0 ; i<nEnd ; ++i )
{
OBrowserLine* pLine = m_aLines[i];
IBrowserControl* pControl = pLine->getControl();
if ( pControl && ( pControl->GetMyName() == _rEntryName ) )
{
pLine->Enable( _bEnable );
break;
}
}
}
//------------------------------------------------------------------------
IBrowserControl* OBrowserListBox::GetPropertyControl(const ::rtl::OUString& _rEntryName)
{
// TODO: O(log n) search
sal_uInt16 i, nEnd = m_aLines.size();
for (i = 0 ; i<nEnd ; ++i)
{
OBrowserLine* pLine = m_aLines[i];
IBrowserControl* pControl = pLine->getControl();
if (pControl && (pControl->GetMyName() == _rEntryName))
return pControl;
}
return NULL;
}
//------------------------------------------------------------------------
IBrowserControl* OBrowserListBox::GetCurrentPropertyControl()
{
sal_uInt16 i, nEnd = m_aLines.size();
for (i=0; i<nEnd; ++i)
{
OBrowserLine* pLine = m_aLines[i];
IBrowserControl* pControl = pLine ? pLine->getControl() : NULL;
Window* pControlWindow = pControl ? pControl->GetMe() : NULL;
if (pControlWindow && pControlWindow->HasChildPathFocus())
return pControl;
}
return NULL;
}
//------------------------------------------------------------------------
void OBrowserListBox::SetPropertyData(const ::rtl::OUString& _rEntryName, void* pData)
{
// TODO: O(log n) search
sal_uInt16 i, nEnd = m_aLines.size();
for (i = 0 ; i<nEnd ; ++i)
{
OBrowserLine* pLine = m_aLines[i];
IBrowserControl* pControl = pLine->getControl();
if (pControl && (pControl->GetMyName() == _rEntryName))
{
pControl->SetMyData(pData);
break;
}
}
}
//------------------------------------------------------------------
sal_uInt16 OBrowserListBox::InsertEntry(const OLineDescriptor& _rPropertyData, sal_uInt16 _nPos)
{
// create a new line
OBrowserLine* pBrowserLine = new OBrowserLine(&m_aPlayGround);
sal_uInt16 nInsertPos = _nPos;
if (EDITOR_LIST_APPEND == nInsertPos)
{
nInsertPos = m_aLines.size();
m_aLines.push_back(pBrowserLine);
}
else
m_aLines.insert(m_aLines.begin() + nInsertPos, pBrowserLine);
pBrowserLine->SetTitleWidth(m_nTheNameSize);
if (m_bUpdate)
{
UpdateVScroll();
Invalidate();
}
// initialize the entry
ChangeEntry(_rPropertyData, nInsertPos);
return nInsertPos;
}
// #95343# ---------------------------------------------------------
sal_Int32 OBrowserListBox::GetMinimumWidth()
{
return m_nTheNameSize + 2 * FRAME_OFFSET + (m_nRowHeight - 4) * 8;
}
//------------------------------------------------------------------
sal_uInt16 OBrowserListBox::GetFirstVisibleEntry()
{
return (sal_uInt16)m_aVScroll.GetThumbPos();
}
//------------------------------------------------------------------
void OBrowserListBox::SetFirstVisibleEntry(sal_uInt16 _nPos)
{
if (_nPos<m_aLines.size())
MoveThumbTo(_nPos);
}
//------------------------------------------------------------------
void OBrowserListBox::SetSelectedEntry(sal_uInt16 _nPos)
{
if (_nPos<m_aLines.size())
{
m_nSelectedLine=_nPos;
ShowEntry(_nPos);
m_aLines[_nPos]->GrabFocus();
}
}
//------------------------------------------------------------------
sal_uInt16 OBrowserListBox::GetSelectedEntry()
{
return m_nSelectedLine;
}
//------------------------------------------------------------------
void OBrowserListBox::ShowEntry(sal_uInt16 _nPos)
{
if (_nPos<m_aLines.size())
{
sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();
if (_nPos < nThumbPos)
MoveThumbTo(_nPos);
else
{
sal_Int32 nLines = CalcVisibleLines();
if (_nPos >= nThumbPos + nLines)
MoveThumbTo(_nPos - nLines + 1);
}
}
}
//------------------------------------------------------------------
void OBrowserListBox::MoveThumbTo(sal_Int32 _nNewThumbPos)
{
// disable painting to prevent flicker
m_aPlayGround.EnablePaint(sal_False);
sal_Int32 nDelta = _nNewThumbPos - m_aVScroll.GetThumbPos();
// adjust the scrollbar
m_aVScroll.SetThumbPos(_nNewThumbPos);
sal_Int32 nThumbPos = nThumbPos = _nNewThumbPos;
m_nYOffset = -m_aVScroll.GetThumbPos() * m_nRowHeight;
sal_Int32 nLines = CalcVisibleLines();
sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + nLines);
m_aPlayGround.Scroll(0, -nDelta * m_nRowHeight, SCROLL_CHILDREN);
if (1 == nDelta)
{
// TODO: what's the sense of this two ShowLines? Why not just one call?
ShowLine(nEnd-1);
ShowLine(nEnd);
}
else if (-1 == nDelta)
{
ShowLine((sal_uInt16)nThumbPos);
}
else if (0 != nDelta)
{
UpdatePlayGround();
}
m_aPlayGround.EnablePaint(sal_True);
m_aPlayGround.Invalidate(INVALIDATE_CHILDREN);
}
//------------------------------------------------------------------
IMPL_LINK(OBrowserListBox, ScrollHdl, ScrollBar*, _pScrollBar )
{
DBG_ASSERT(_pScrollBar == &m_aVScroll, "OBrowserListBox::ScrollHdl: where does this come from?");
// disable painting to prevent flicker
m_aPlayGround.EnablePaint(sal_False);
sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();
sal_Int32 nDelta = m_aVScroll.GetDelta();
m_nYOffset = -nThumbPos * m_nRowHeight;
sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + CalcVisibleLines());
m_aPlayGround.Scroll(0, -nDelta * m_nRowHeight, SCROLL_CHILDREN);
if (1 == nDelta)
{
ShowLine(nEnd-1);
ShowLine(nEnd);
}
else if (nDelta==-1)
{
ShowLine((sal_uInt16)nThumbPos);
}
else if (nDelta!=0 || m_aVScroll.GetType() == SCROLL_DONTKNOW)
{
UpdatePlayGround();
}
m_aPlayGround.EnablePaint(sal_True);
return 0;
}
//------------------------------------------------------------------
IMPL_LINK( OBrowserListBox, ClickHdl, PushButton*,pPB)
{
DBG_ASSERT(pPB, "OBrowserListBox::ClickHdl: invalid button!");
if (pPB)
{
// notify our LineListener of the ClickecEvent
if (m_pLineListener)
{
OBrowserLine* pBrowserLine = static_cast<OBrowserLine*>(pPB->GetData());
IBrowserControl* pControl = pBrowserLine->getControl();
m_pLineListener->Clicked(pControl->GetMyName(), pControl->GetProperty(), pControl->GetMyData());
}
}
return 0;
}
//------------------------------------------------------------------
void OBrowserListBox::Modified(IBrowserControl* _pControl)
{
DBG_ASSERT(_pControl, "OBrowserListBox::Modified: invalid event source!");
// notify our line listener
if (_pControl && m_pLineListener)
{
m_pLineListener->Modified(
_pControl->GetMyName(),
_pControl->GetProperty(),
_pControl->GetMyData()
);
}
}
//------------------------------------------------------------------
void OBrowserListBox::GetFocus(IBrowserControl* _pControl)
{
DBG_ASSERT(_pControl, "OBrowserListBox::GetFocus: invalid event source!");
if (!_pControl)
return;
// notify our line listener
if (m_pLineListener)
{
m_pLineListener->Select(
_pControl->GetMyName(),
_pControl->GetMyData()
);
}
m_nSelectedLine = _pControl->GetLine();
ShowEntry(m_nSelectedLine);
}
//------------------------------------------------------------------
void OBrowserListBox::Commit(IBrowserControl* _pControl)
{
DBG_ASSERT(_pControl, "OBrowserListBox::Commit: invalid event source!");
if (!_pControl)
return;
// upon losing the focus, we notify our listener so that it can commit the content
if (m_pLineListener)
{
m_pLineListener->Commit(
_pControl->GetMyName(),
_pControl->GetProperty(),
_pControl->GetMyData()
);
}
}
//------------------------------------------------------------------
void OBrowserListBox::TravelLine(IBrowserControl* _pControl)
{
sal_Int32 nLine = _pControl->GetLine();
if (_pControl->GetDirection())
{
// cycle forwards, 'til we've the next control which can grab the focus
++nLine;
while ((sal_uInt32)nLine<m_aLines.size())
{
if (m_aLines[nLine]->GrabFocus())
break;
++nLine;
}
if ( ((sal_uInt32)nLine >= m_aLines.size())
&& (m_aLines.size() > 0)
)
// wrap around
m_aLines[0]->GrabFocus();
}
else
{ // cycle backwards, 'til we've the next control which can grab the focus
--nLine;
while (nLine>=0)
{
if (m_aLines[nLine]->GrabFocus())
break;
--nLine;
}
if ( (nLine < 0)
&& (0 < m_aLines.size())
)
// wrap around
m_aLines[m_aLines.size() - 1]->GrabFocus();
}
}
//------------------------------------------------------------------
void OBrowserListBox::KeyInput(IBrowserControl* _pControl, const KeyCode& _rKey)
{
DBG_ASSERT(_pControl, "OBrowserListBox::KeyInput: invalid event source!");
if (!_pControl)
return;
// not really interested in ...
}
//------------------------------------------------------------------
void OBrowserListBox::Clear()
{
for ( OBrowserLinesArrayIterator aLoop = m_aLines.begin();
aLoop != m_aLines.end();
++aLoop
)
{
// hide the line
(*aLoop)->Hide();
// reset the listener
(*aLoop)->getControl()->setListener(NULL);
// delete the control
delete (*aLoop)->getControl();
// delete the line
delete *aLoop;
}
m_aLines.clear();
}
//------------------------------------------------------------------
void OBrowserListBox::ChangeEntry(const OLineDescriptor& _rPropertyData, sal_uInt16 nPos)
{
sal_Bool bNew=sal_True;
if (nPos < m_aLines.size())
{
Window* pRefWindow=NULL;
if (nPos>0)
pRefWindow = m_aLines[nPos-1]->GetRefWindow();
// the current line and control
OBrowserLine* pBrowserLine = m_aLines[nPos];
IBrowserControl* pControl = pBrowserLine->getControl();
// position of the control
Point aControlPos;
if (pControl)
aControlPos=pControl->GetCtrPos();
if (pBrowserLine->GetKindOfControl() != _rPropertyData.eControlType)
{
// need to create a new control
bNew = sal_True;
delete pBrowserLine->getControl();
// default winbits: a border only
WinBits nWinBits=WB_BORDER;
if (_rPropertyData.bIsLocked)
nWinBits|=WB_READONLY;
pBrowserLine->SetKindOfControl(_rPropertyData.eControlType); // may be overwritten
// create the new control
IBrowserControl* pNewControl = NULL;
// TODO: source this out (into a factory)
switch(_rPropertyData.eControlType)
{
case BCT_LEDIT:
pNewControl = new OMultilineEditControl(&m_aPlayGround,sal_False, nWinBits | WB_DROPDOWN | WB_TABSTOP);
pBrowserLine->SetKindOfControl(BCT_MEDIT);
break;
case BCT_MEDIT:
pNewControl = new OMultilineEditControl(&m_aPlayGround,sal_True, nWinBits | WB_DROPDOWN | WB_TABSTOP);
break;
case BCT_LISTBOX:
pNewControl = new OListboxControl(&m_aPlayGround, nWinBits | WB_TABSTOP | WB_DROPDOWN);
break;
case BCT_COMBOBOX:
pNewControl = new OComboboxControl(&m_aPlayGround, nWinBits | WB_TABSTOP | WB_SORT | WB_DROPDOWN);
break;
case BCT_EDIT:
pNewControl = new OEditControl(&m_aPlayGround,sal_False,nWinBits | WB_TABSTOP);
break;
case BCT_CHAREDIT:
pNewControl = new OEditControl(&m_aPlayGround,sal_True,nWinBits | WB_TABSTOP);
pBrowserLine->SetKindOfControl(BCT_EDIT);
break;
case BCT_NUMFIELD:
{
ONumericControl* pField = new ONumericControl( &m_aPlayGround, _rPropertyData.nDigits,
nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
if (_rPropertyData.bHaveMinMax)
{
pField->SetMin(_rPropertyData.nMinValue);
pField->SetMax(_rPropertyData.nMaxValue);
}
pField->SetFieldUnit( _rPropertyData.eDisplayUnit );
pField->SetValueUnit( _rPropertyData.eValueUnit );
pNewControl = pField;
}
break;
case BCT_CURFIELD:
pNewControl = new OCurrencyControl( &m_aPlayGround,_rPropertyData.nDigits, nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
break;
case BCT_DATEFIELD:
pNewControl = new ODateControl( &m_aPlayGround,nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
break;
case BCT_TIMEFIELD:
pNewControl = new OTimeControl( &m_aPlayGround,nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
break;
case BCT_COLORBOX:
pNewControl = new OColorControl(&m_aPlayGround, nWinBits | WB_TABSTOP | WB_DROPDOWN);
break;
case BCT_USERDEFINED:
DBG_ASSERT(_rPropertyData.pControl, "OBrowserListBox::ChangeEntry: invalid user defined control!");
pNewControl = _rPropertyData.pControl;
pNewControl->SetCtrParent(&m_aPlayGround);
break;
default:
pNewControl = NULL;
pBrowserLine->SetKindOfControl(BCT_UNDEFINED);
break;
}
pBrowserLine->setControl(pNewControl);
pNewControl->SetCtrPos(aControlPos);
// forward the locking flag to the control
pNewControl->SetLocked(_rPropertyData.bIsLocked);
// remember this new control
pControl = pNewControl;
}
else
{
bNew = sal_False;
if (pControl && pControl->HasList())
pControl->ClearList();
}
if (pControl)
{
pControl->setListener(this);
// forward the data from the descriptor
pControl->SetMyData(_rPropertyData.pDataPtr);
pControl->SetMyName(_rPropertyData.sName);
pControl->SetLine(nPos);
if (pControl->HasList())
{
// the standard entry
if (_rPropertyData.bHasDefaultValue && (BCT_COLORBOX != _rPropertyData.eControlType))
pControl->InsertCtrEntry(m_aStandard);
// all other entries from the descriptor
for (sal_uInt32 i=0;i<_rPropertyData.aListValues.size(); ++i)
pControl->InsertCtrEntry(_rPropertyData.aListValues[i]);
}
// the initial property value
pControl->SetProperty(_rPropertyData.sValue, _rPropertyData.bUnknownValue);
}
pBrowserLine->SetTitle(_rPropertyData.sTitle);
sal_uInt16 nTextWidth = (sal_uInt16)m_aPlayGround.GetTextWidth(_rPropertyData.sTitle);
if (m_nTheNameSize< nTextWidth)
m_nTheNameSize = nTextWidth;
if ( _rPropertyData.nUniqueButtonId )
{
pBrowserLine->ShowBrowseButton();
pBrowserLine->SetClickHdl(LINK( this, OBrowserListBox, ClickHdl ) );
}
else
pBrowserLine->HideBrowseButton();
pBrowserLine->Locked(_rPropertyData.bIsLocked);
pBrowserLine->SetData(_rPropertyData.pDataPtr);
if (bNew)
{
if (nPos>0)
pBrowserLine->SetTabOrder(pRefWindow, WINDOW_ZORDER_BEHIND);
else
pBrowserLine->SetTabOrder(pRefWindow, WINDOW_ZORDER_FIRST );
pBrowserLine->SetNeedsRepaint(sal_True);
pBrowserLine->SetHelpId(_rPropertyData.nHelpId,_rPropertyData.nUniqueButtonId);
}
}
}
//------------------------------------------------------------------
long OBrowserListBox::Notify( NotifyEvent& _rNEvt )
{
// interested in scroll events if we have a scrollbar
if ( m_aVScroll.IsVisible() )
{
if ( EVENT_COMMAND == _rNEvt.GetType() )
{
const CommandEvent* pCommand = _rNEvt.GetCommandEvent();
if ( ( COMMAND_WHEEL == pCommand->GetCommand() )
|| ( COMMAND_STARTAUTOSCROLL == pCommand->GetCommand() )
|| ( COMMAND_AUTOSCROLL == pCommand->GetCommand() )
)
{
HandleScrollCommand( *pCommand, NULL, &m_aVScroll );
}
}
}
return Control::Notify( _rNEvt );
}
//............................................................................
} // namespace pcr
//............................................................................