/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#ifndef _SVX_FMHELP_HRC
#include "fmhelp.hrc"
#endif
#include <svx/gridctrl.hxx>
#include "gridcell.hxx"
#include "svx/dbtoolsclient.hxx"
#include "svx/fmtools.hxx"
#include <svtools/stringtransfer.hxx>

#ifndef _SVX_FMPROP_HRC
#include "fmprop.hrc"
#endif
#include <svtools/stringtransfer.hxx>
#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
#include <com/sun/star/accessibility/XAccessible.hpp>
#include <com/sun/star/sdb/XResultSetAccess.hpp>
#include <com/sun/star/sdb/RowChangeAction.hpp>
#include <com/sun/star/sdb/XRowsChangeBroadcaster.hpp>
#include <com/sun/star/sdbc/XResultSetUpdate.hpp>
#include <com/sun/star/sdbcx/Privilege.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/util/XNumberFormatter.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#include <com/sun/star/util/XCloneable.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyChangeEvent.hpp>
#include <comphelper/extract.hxx>
#include <tools/resid.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/sound.hxx>
#include <vcl/menu.hxx>

#ifndef _SVX_FMRESIDS_HRC
#include "svx/fmresids.hrc"
#endif

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#include <tools/shl.hxx>
#include <svx/dialmgr.hxx>
#include "fmservs.hxx"
#include "sdbdatacolumn.hxx"

#define HANDLE_ID	0

#include <comphelper/stl_types.hxx>
#include <comphelper/property.hxx>
#include "trace.hxx"

#include <algorithm>

using namespace ::svxform;
using namespace ::svt;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::datatransfer;
using namespace ::com::sun::star::container;
using namespace com::sun::star::accessibility;

#define ROWSTATUS(row)	!row.Is() ? "NULL" : row->GetStatus() == GRS_CLEAN ? "CLEAN" : row->GetStatus() == GRS_MODIFIED ? "MODIFIED" : row->GetStatus() == GRS_DELETED ? "DELETED" : "INVALID"


#define DEFAULT_BROWSE_MODE             \
			  BROWSER_COLUMNSELECTION   \
			| BROWSER_MULTISELECTION    \
            | BROWSER_KEEPSELECTION     \
			| BROWSER_TRACKING_TIPS     \
			| BROWSER_HLINESFULL        \
			| BROWSER_VLINESFULL        \
			| BROWSER_HEADERBAR_NEW     \

class RowSetEventListener : public ::cppu::WeakImplHelper1<XRowsChangeListener>
{
    DbGridControl* m_pControl;
public:
    RowSetEventListener(DbGridControl* i_pControl) : m_pControl(i_pControl)
    {
    }
private:
    // XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& /*i_aEvt*/) throw ( RuntimeException )
    {
    }
    virtual void SAL_CALL rowsChanged(const ::com::sun::star::sdb::RowsChangeEvent& i_aEvt) throw ( RuntimeException )
    {
        if ( i_aEvt.Action == RowChangeAction::UPDATE )
        {
            ::DbGridControl::GrantControlAccess aAccess;
            CursorWrapper* pSeek = m_pControl->GetSeekCursor(aAccess);
            const DbGridRowRef& rSeekRow = m_pControl->GetSeekRow(aAccess);
            const Any* pIter = i_aEvt.Bookmarks.getConstArray();
            const Any* pEnd  = pIter + i_aEvt.Bookmarks.getLength();
            for(;pIter != pEnd;++pIter)
            {
                pSeek->moveToBookmark(*pIter);
			    // get the data
			    rSeekRow->SetState(pSeek, sal_True);
                sal_Int32 nSeekPos = pSeek->getRow() - 1;
			    m_pControl->SetSeekPos(nSeekPos,aAccess);
                m_pControl->RowModified(nSeekPos);
            }
        }
    }
};
//==============================================================================

class GridFieldValueListener;
DECLARE_STL_MAP(sal_uInt16, GridFieldValueListener*, ::std::less<sal_uInt16>, ColumnFieldValueListeners);

//==============================================================================

DBG_NAME(GridFieldValueListener)
class GridFieldValueListener : protected ::comphelper::OPropertyChangeListener
{
	osl::Mutex							m_aMutex;
	DbGridControl&						m_rParent;
	::comphelper::OPropertyChangeMultiplexer*	m_pRealListener;
	sal_uInt16							m_nId;
	sal_Int16							m_nSuspended;
	sal_Bool							m_bDisposed : 1;

public:
	GridFieldValueListener(DbGridControl& _rParent, const Reference< XPropertySet >& xField, sal_uInt16 _nId);
	virtual ~GridFieldValueListener();

	virtual void _propertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException );

	void suspend() { ++m_nSuspended; }
	void resume() { --m_nSuspended; }

	void dispose();
};
//------------------------------------------------------------------------------
GridFieldValueListener::GridFieldValueListener(DbGridControl& _rParent, const Reference< XPropertySet >& _rField, sal_uInt16 _nId)
	:OPropertyChangeListener(m_aMutex)
	,m_rParent(_rParent)
    ,m_pRealListener(NULL)
	,m_nId(_nId)
    ,m_nSuspended(0)
	,m_bDisposed(sal_False)
{
	DBG_CTOR(GridFieldValueListener, NULL);
	if (_rField.is())
	{
		m_pRealListener = new ::comphelper::OPropertyChangeMultiplexer(this, _rField);
		m_pRealListener->addProperty(FM_PROP_VALUE);
		m_pRealListener->acquire();
	}
}

//------------------------------------------------------------------------------
GridFieldValueListener::~GridFieldValueListener()
{
	DBG_DTOR(GridFieldValueListener, NULL);
	dispose();
}

//------------------------------------------------------------------------------
void GridFieldValueListener::_propertyChanged(const PropertyChangeEvent& _evt) throw( RuntimeException )
{
	DBG_ASSERT(m_nSuspended>=0, "GridFieldValueListener::_propertyChanged : resume > suspend !");
	if (m_nSuspended <= 0)
		m_rParent.FieldValueChanged(m_nId, _evt);
}

//------------------------------------------------------------------------------
void GridFieldValueListener::dispose()
{
	if (m_bDisposed)
	{
		DBG_ASSERT(m_pRealListener == NULL, "GridFieldValueListener::dispose : inconsistent !");
		return;
	}

	if (m_pRealListener)
	{
		m_pRealListener->dispose();
		m_pRealListener->release();
		m_pRealListener = NULL;
	}

	m_bDisposed = sal_True;
	m_rParent.FieldListenerDisposing(m_nId);
}

//==============================================================================

class DisposeListenerGridBridge : public FmXDisposeListener
{
	osl::Mutex				m_aMutex;
	DbGridControl&			m_rParent;
	FmXDisposeMultiplexer*	m_pRealListener;

public:
	DisposeListenerGridBridge(	DbGridControl& _rParent, const Reference< XComponent >& _rxObject, sal_Int16 _rId = -1);
	virtual ~DisposeListenerGridBridge();

	virtual void disposing(const EventObject& _rEvent, sal_Int16 _nId) throw( RuntimeException ) { m_rParent.disposing(_nId, _rEvent); }
};

//==============================================================================


DBG_NAME(DisposeListenerGridBridge)
//------------------------------------------------------------------------------
DisposeListenerGridBridge::DisposeListenerGridBridge(DbGridControl& _rParent, const Reference< XComponent >& _rxObject, sal_Int16 _rId)
	:FmXDisposeListener(m_aMutex)
	,m_rParent(_rParent)
	,m_pRealListener(NULL)
{
	DBG_CTOR(DisposeListenerGridBridge,NULL);

	if (_rxObject.is())
	{
		m_pRealListener = new FmXDisposeMultiplexer(this, _rxObject, _rId);
		m_pRealListener->acquire();
	}
}

//------------------------------------------------------------------------------
DisposeListenerGridBridge::~DisposeListenerGridBridge()
{
	if (m_pRealListener)
	{
		m_pRealListener->dispose();
		m_pRealListener->release();
		m_pRealListener = NULL;
	}

	DBG_DTOR(DisposeListenerGridBridge,NULL);
}

//==============================================================================

static sal_uInt16 ControlMap[] =
	{
		DbGridControl::NavigationBar::RECORD_TEXT,
		DbGridControl::NavigationBar::RECORD_ABSOLUTE,
		DbGridControl::NavigationBar::RECORD_OF,
		DbGridControl::NavigationBar::RECORD_COUNT,
		DbGridControl::NavigationBar::RECORD_FIRST,
		DbGridControl::NavigationBar::RECORD_NEXT,
		DbGridControl::NavigationBar::RECORD_PREV,
		DbGridControl::NavigationBar::RECORD_LAST,
		DbGridControl::NavigationBar::RECORD_NEW,
		0
	};

//------------------------------------------------------------------------------
sal_Bool CompareBookmark(const Any& aLeft, const Any& aRight)
{
	return ::comphelper::compare(aLeft, aRight);
}

//==============================================================================
class FmXGridSourcePropListener : public ::comphelper::OPropertyChangeListener
{
	DbGridControl* m_pParent;

	// a DbGridControl has no mutex, so we use our own as the base class expects one
	osl::Mutex		m_aMutex;
	sal_Int16			m_nSuspended;

public:
	FmXGridSourcePropListener(DbGridControl* _pParent);

	void suspend() { ++m_nSuspended; }
	void resume() { --m_nSuspended; }

	virtual void _propertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException );
};

//------------------------------------------------------------------------------
FmXGridSourcePropListener::FmXGridSourcePropListener(DbGridControl* _pParent)
	:OPropertyChangeListener(m_aMutex)
	,m_pParent(_pParent)
	,m_nSuspended(0)
{
	DBG_ASSERT(m_pParent, "FmXGridSourcePropListener::FmXGridSourcePropListener : invalid parent !");
}

//------------------------------------------------------------------------------
void FmXGridSourcePropListener::_propertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException )
{
	DBG_ASSERT(m_nSuspended>=0, "FmXGridSourcePropListener::_propertyChanged : resume > suspend !");
	if (m_nSuspended <= 0)
		m_pParent->DataSourcePropertyChanged(evt);
}

//==============================================================================
//------------------------------------------------------------------------------
DbGridControl::NavigationBar::AbsolutePos::AbsolutePos(Window* pParent, WinBits nStyle)
				   :NumericField(pParent, nStyle)
{
	SetMin(1);
	SetFirst(1);
	SetSpinSize(1);

	SetDecimalDigits(0);
	SetStrictFormat(sal_True);
}

//------------------------------------------------------------------------------
void DbGridControl::NavigationBar::AbsolutePos::KeyInput(const KeyEvent& rEvt)
{
	if (rEvt.GetKeyCode() == KEY_RETURN && GetText().Len())
	{
		sal_Int64 nRecord = GetValue();
		if (nRecord < GetMin() || nRecord > GetMax())
			return;
		else
			((NavigationBar*)GetParent())->PositionDataSource(static_cast<sal_Int32>(nRecord));
	}
	else if (rEvt.GetKeyCode() == KEY_TAB)
		GetParent()->GetParent()->GrabFocus();
	else
		NumericField::KeyInput(rEvt);
}

//------------------------------------------------------------------------------
void DbGridControl::NavigationBar::AbsolutePos::LoseFocus()
{
	NumericField::LoseFocus();
	sal_Int64 nRecord = GetValue();
	if (nRecord < GetMin() || nRecord > GetMax())
		return;
	else
	{
		((NavigationBar*)GetParent())->PositionDataSource(static_cast<sal_Int32>(nRecord));
		((NavigationBar*)GetParent())->InvalidateState(NavigationBar::RECORD_ABSOLUTE);
	}
}

//------------------------------------------------------------------------------
void DbGridControl::NavigationBar::PositionDataSource(sal_Int32 nRecord)
{
	if (m_bPositioning)
		return;
	// the MoveToPosition may cause a LoseFocus which would lead to a second MoveToPosition, so protect agains this
	// recursion
	// 68167 - 13.08.99 - FS
	m_bPositioning = sal_True;
	((DbGridControl*)GetParent())->MoveToPosition(nRecord - 1);
	m_bPositioning = sal_False;
}

//------------------------------------------------------------------------------
DbGridControl::NavigationBar::NavigationBar(Window* pParent, WinBits nStyle)
		  :Control(pParent, nStyle)
		  ,m_aRecordText(this, WB_VCENTER)
		  ,m_aAbsolute(this, WB_VCENTER)
		  ,m_aRecordOf(this, WB_VCENTER)
		  ,m_aRecordCount(this, WB_CENTER | WB_VCENTER)
		  ,m_aFirstBtn(this, WB_RECTSTYLE|WB_NOPOINTERFOCUS)
		  ,m_aPrevBtn(this, WB_REPEAT|WB_RECTSTYLE|WB_NOPOINTERFOCUS)
		  ,m_aNextBtn(this, WB_REPEAT|WB_RECTSTYLE|WB_NOPOINTERFOCUS)
		  ,m_aLastBtn(this, WB_RECTSTYLE|WB_NOPOINTERFOCUS)
		  ,m_aNewBtn(this, WB_RECTSTYLE|WB_NOPOINTERFOCUS)
		  ,m_nDefaultWidth(0)
		  ,m_nCurrentPos(-1)
		  ,m_bPositioning(sal_False)
{
	m_aFirstBtn.SetSymbol(SYMBOL_FIRST);
	m_aPrevBtn.SetSymbol(SYMBOL_PREV);
	m_aNextBtn.SetSymbol(SYMBOL_NEXT);
	m_aLastBtn.SetSymbol(SYMBOL_LAST);
	m_aNewBtn.SetModeImage(((DbGridControl*)pParent)->GetImage(DbGridControl_Base::NEW));

	m_aFirstBtn.SetHelpId(HID_GRID_TRAVEL_FIRST);
	m_aPrevBtn.SetHelpId(HID_GRID_TRAVEL_PREV);
	m_aNextBtn.SetHelpId(HID_GRID_TRAVEL_NEXT);
	m_aLastBtn.SetHelpId(HID_GRID_TRAVEL_LAST);
	m_aNewBtn.SetHelpId(HID_GRID_TRAVEL_NEW);
	m_aAbsolute.SetHelpId(HID_GRID_TRAVEL_ABSOLUTE);
	m_aRecordCount.SetHelpId(HID_GRID_NUMBEROFRECORDS);

	// Handler fuer Buttons einrichten
	m_aFirstBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));
	m_aPrevBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));
	m_aNextBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));
	m_aLastBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));
	m_aNewBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));

	m_aRecordText.SetText(XubString(SVX_RES(RID_STR_REC_TEXT)));
	m_aRecordOf.SetText(XubString(SVX_RES(RID_STR_REC_FROM_TEXT)));
	m_aRecordCount.SetText('?');

	m_nDefaultWidth = ArrangeControls();

	m_aFirstBtn.Disable();
	m_aPrevBtn.Disable();
	m_aNextBtn.Disable();
	m_aLastBtn.Disable();
	m_aNewBtn.Disable();
	m_aRecordText.Disable();
	m_aRecordOf.Disable();
	m_aRecordCount.Disable();
	m_aAbsolute.Disable();

	AllSettings aSettings = m_aNextBtn.GetSettings();
	MouseSettings aMouseSettings = aSettings.GetMouseSettings();
	aMouseSettings.SetButtonRepeat(aMouseSettings.GetButtonRepeat() / 4);
	aSettings.SetMouseSettings(aMouseSettings);
	m_aNextBtn.SetSettings(aSettings, sal_True);
	m_aPrevBtn.SetSettings(aSettings, sal_True);

	m_aFirstBtn.Show();
	m_aPrevBtn.Show();
	m_aNextBtn.Show();
	m_aLastBtn.Show();
	m_aNewBtn.Show();
	m_aRecordText.Show();
	m_aRecordOf.Show();
	m_aRecordCount.Show();
	m_aAbsolute.Show();
}

namespace
{
	void SetPosAndSize(Button& _rButton,Point& _rPos,const Size& _rSize)
	{
		_rButton.SetPosPixel( _rPos );
		_rButton.SetSizePixel( _rSize );
		_rPos.X() += (sal_uInt16)_rSize.Width();
	}
}
//------------------------------------------------------------------------------
sal_uInt16 DbGridControl::NavigationBar::ArrangeControls()
{
	// Positionierung der Controls
	// Basisgroessen ermitteln
	sal_uInt16		nX = 0;
	sal_uInt16		nY = 0;
	Rectangle	aRect(((DbGridControl*)GetParent())->GetControlArea());
	const long	nH		= aRect.GetSize().Height();
	Size		aBorder = LogicToPixel(Size(3, 3),MAP_APPFONT);
				aBorder = Size(CalcZoom(aBorder.Width()), CalcZoom(aBorder.Height()));

	// Controls Groessen und Positionen setzen
	//
	XubString aText    = m_aRecordText.GetText();
	long nTextWidth = m_aRecordText.GetTextWidth(aText);
	m_aRecordText.SetPosPixel(Point(nX,nY) );
	m_aRecordText.SetSizePixel(Size(nTextWidth,nH));
	nX = sal::static_int_cast< sal_uInt16 >(nX + nTextWidth + aBorder.Width());

	m_aAbsolute.SetPosPixel( Point(nX,nY));
	m_aAbsolute.SetSizePixel( Size(3*nH,aRect.GetSize().Height()) ); // Heuristik XXXXXXX
	nX = sal::static_int_cast< sal_uInt16 >(nX + (3*nH) + aBorder.Width());

	aText	   = m_aRecordOf.GetText();
	nTextWidth = m_aRecordOf.GetTextWidth(aText);
	m_aRecordOf.SetPosPixel(Point(nX,nY) );
	m_aRecordOf.SetSizePixel(Size(nTextWidth,nH));
	nX = sal::static_int_cast< sal_uInt16 >(nX + nTextWidth + aBorder.Width());

	nTextWidth = m_aRecordCount.GetTextWidth( String::CreateFromAscii("0000000 (00000) *") );
	m_aRecordCount.SetPosPixel(Point(nX,nY) );
	m_aRecordCount.SetSizePixel(Size(nTextWidth,nH));
	nX = sal::static_int_cast< sal_uInt16 >(nX + nTextWidth + aBorder.Width());

	Point aButtonPos(nX,nY);
	Size  aButtonSize(nH,nH);
	SetPosAndSize(m_aFirstBtn, aButtonPos, aButtonSize);
	SetPosAndSize(m_aPrevBtn, aButtonPos, aButtonSize);
	SetPosAndSize(m_aNextBtn, aButtonPos, aButtonSize);
	SetPosAndSize(m_aLastBtn, aButtonPos, aButtonSize);
	SetPosAndSize(m_aNewBtn, aButtonPos, aButtonSize);

	nX = sal::static_int_cast< sal_uInt16 >(
        aButtonPos.X() + (sal_uInt16)(nH + aBorder.Width()));

	// Ist der Font des Edits groesser als das Feld?
	Font aOutputFont = m_aAbsolute.GetFont();
	if (aOutputFont.GetSize().Height() > nH)
	{
		Font aApplFont = OutputDevice::GetDefaultFont(
			DEFAULTFONT_SANS_UNICODE,
			Application::GetSettings().GetUILanguage(),
			DEFAULTFONT_FLAGS_ONLYONE,
			this
		);
		aApplFont.SetSize( Size( 0, nH - 2 ) );
		m_aAbsolute.SetControlFont( aApplFont );

		aApplFont.SetTransparent( sal_True );
		m_aRecordText.SetControlFont( aApplFont );
		m_aRecordOf.SetControlFont( aApplFont );
		m_aRecordCount.SetControlFont( aApplFont );
	}
	return nX;
}

//------------------------------------------------------------------------------
IMPL_LINK(DbGridControl::NavigationBar, OnClick, Button *, pButton )
{
	DbGridControl* pParent = (DbGridControl*)GetParent();

	if (pParent->m_aMasterSlotExecutor.IsSet())
	{
		long lResult = 0;
		if (pButton == &m_aFirstBtn)
			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_FIRST);
		else if( pButton == &m_aPrevBtn )
			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_PREV);
		else if( pButton == &m_aNextBtn )
			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_NEXT);
		else if( pButton == &m_aLastBtn )
			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_LAST);
		else if( pButton == &m_aNewBtn )
			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_NEW);

		if (lResult)
			// the link already handled it
			return 0;
	}

	if (pButton == &m_aFirstBtn)
		pParent->MoveToFirst();
	else if( pButton == &m_aPrevBtn )
		pParent->MoveToPrev();
	else if( pButton == &m_aNextBtn )
		pParent->MoveToNext();
	else if( pButton == &m_aLastBtn )
		pParent->MoveToLast();
	else if( pButton == &m_aNewBtn )
		pParent->AppendNew();
	return 0;
}

//------------------------------------------------------------------------------
void DbGridControl::NavigationBar::InvalidateAll(sal_Int32 nCurrentPos, sal_Bool bAll)
{
	if (m_nCurrentPos != nCurrentPos || nCurrentPos < 0 || bAll)
	{
		DbGridControl* pParent = (DbGridControl*)GetParent();

        sal_Int32 nAdjustedRowCount = pParent->GetRowCount() - ((pParent->GetOptions() & DbGridControl::OPT_INSERT) ? 2 : 1);

		// Wann mu� alles invalidiert werden
        bAll = bAll || m_nCurrentPos <= 0;
        bAll = bAll || nCurrentPos <= 0;
        bAll = bAll || m_nCurrentPos >= nAdjustedRowCount;
        bAll = bAll || nCurrentPos >= nAdjustedRowCount;

        if ( bAll )
		{
			m_nCurrentPos = nCurrentPos;
			int i = 0;
			while (ControlMap[i])
				SetState(ControlMap[i++]);
		}
		else	// befindet sich in der Mitte
		{
			m_nCurrentPos = nCurrentPos;
			SetState(NavigationBar::RECORD_COUNT);
			SetState(NavigationBar::RECORD_ABSOLUTE);
		}
	}
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::NavigationBar::GetState(sal_uInt16 nWhich) const
{
	DbGridControl* pParent = (DbGridControl*)GetParent();

	if (!pParent->IsOpen() || pParent->IsDesignMode() || !pParent->IsEnabled()
		|| pParent->IsFilterMode() )
		return sal_False;
	else
	{
		// check if we have a master state provider
		if (pParent->m_aMasterStateProvider.IsSet())
		{
			long nState = pParent->m_aMasterStateProvider.Call(reinterpret_cast< void* >( nWhich ) );
			if (nState>=0)
				return (nState>0);
		}

		sal_Bool bAvailable = sal_True;

		switch (nWhich)
		{
			case NavigationBar::RECORD_FIRST:
			case NavigationBar::RECORD_PREV:
				bAvailable = m_nCurrentPos > 0;
				break;
			case NavigationBar::RECORD_NEXT:
				if(pParent->m_bRecordCountFinal)
				{
					bAvailable = m_nCurrentPos < pParent->GetRowCount() - 1;
					if (!bAvailable && pParent->GetOptions() & DbGridControl::OPT_INSERT)
						bAvailable = (m_nCurrentPos == pParent->GetRowCount() - 2) && pParent->IsModified();
				}
				break;
			case NavigationBar::RECORD_LAST:
				if(pParent->m_bRecordCountFinal)
				{
					if (pParent->GetOptions() & DbGridControl::OPT_INSERT)
						bAvailable = pParent->IsCurrentAppending() ? pParent->GetRowCount() > 1 :
									 m_nCurrentPos != pParent->GetRowCount() - 2;
					else
						bAvailable = m_nCurrentPos != pParent->GetRowCount() - 1;
				}
				break;
			case NavigationBar::RECORD_NEW:
				bAvailable = (pParent->GetOptions() & DbGridControl::OPT_INSERT) && pParent->GetRowCount() && m_nCurrentPos < pParent->GetRowCount() - 1;
				break;
			case NavigationBar::RECORD_ABSOLUTE:
				bAvailable = pParent->GetRowCount() > 0;
				break;
		}
		return bAvailable;
	}
}

//------------------------------------------------------------------------------
void DbGridControl::NavigationBar::SetState(sal_uInt16 nWhich)
{
	sal_Bool bAvailable = GetState(nWhich);
	DbGridControl* pParent = (DbGridControl*)GetParent();
	Window* pWnd = NULL;
	switch (nWhich)
	{
		case NavigationBar::RECORD_FIRST:
			pWnd = &m_aFirstBtn;
			break;
		case NavigationBar::RECORD_PREV:
			pWnd = &m_aPrevBtn;
			break;
		case NavigationBar::RECORD_NEXT:
			pWnd = &m_aNextBtn;
			break;
		case NavigationBar::RECORD_LAST:
			pWnd = &m_aLastBtn;
			break;
		case NavigationBar::RECORD_NEW:
			pWnd = &m_aNewBtn;
			break;
		case NavigationBar::RECORD_ABSOLUTE:
			pWnd = &m_aAbsolute;
			if (bAvailable)
			{
				if (pParent->m_nTotalCount >= 0)
				{
					if (pParent->IsCurrentAppending())
						m_aAbsolute.SetMax(pParent->m_nTotalCount + 1);
					else
						m_aAbsolute.SetMax(pParent->m_nTotalCount);
				}
				else
					m_aAbsolute.SetMax(LONG_MAX);

				m_aAbsolute.SetValue(m_nCurrentPos + 1);
			}
			else
				m_aAbsolute.SetText(String());
			break;
		case NavigationBar::RECORD_TEXT:
			pWnd = &m_aRecordText;
			break;
		case NavigationBar::RECORD_OF:
			pWnd = &m_aRecordOf;
			break;
		case NavigationBar::RECORD_COUNT:
		{
			pWnd = &m_aRecordCount;
			String aText;
			if (bAvailable)
			{
				if (pParent->GetOptions() & DbGridControl::OPT_INSERT)
				{
					if (pParent->IsCurrentAppending() && !pParent->IsModified())
						aText = String::CreateFromInt32(pParent->GetRowCount());
					else
						aText = String::CreateFromInt32(pParent->GetRowCount() - 1);
				}
				else
					aText = String::CreateFromInt32(pParent->GetRowCount());
				if(!pParent->m_bRecordCountFinal)
					aText += String::CreateFromAscii(" *");
			}
			else
				aText = String();

			// add the number of selected rows, if applicable
			if (pParent->GetSelectRowCount())
			{
				String aExtendedInfo(aText);
				aExtendedInfo.AppendAscii(" (");
				aExtendedInfo += String::CreateFromInt32(pParent->GetSelectRowCount());
				aExtendedInfo += ')';
				pWnd->SetText(aExtendedInfo);
			}
			else
				pWnd->SetText(aText);

			pParent->SetRealRowCount(aText);
		}	break;
	}
	DBG_ASSERT(pWnd, "kein Fenster");
	if (pWnd && (pWnd->IsEnabled() != bAvailable))
		// this "pWnd->IsEnabled() != bAvailable" is a little hack : Window::Enable always generates a user
		// event (ImplGenerateMouseMove) even if nothing happened. This may lead to some unwanted effects, so we
		// do this check.
		// For further explanation see Bug 69900.
		// FS - 18.11.99
		pWnd->Enable(bAvailable);
}

//------------------------------------------------------------------------------
void DbGridControl::NavigationBar::Resize()
{
	Control::Resize();
	ArrangeControls();
}

//------------------------------------------------------------------------------
void DbGridControl::NavigationBar::Paint(const Rectangle& rRect)
{
	Control::Paint(rRect);
	Point aAbsolutePos = m_aAbsolute.GetPosPixel();
	Size  aAbsoluteSize = m_aAbsolute.GetSizePixel();

	DrawLine(Point(aAbsolutePos.X() - 1, 0 ),
			 Point(aAbsolutePos.X() - 1, aAbsolutePos.Y() + aAbsoluteSize.Height()));

	DrawLine(Point(aAbsolutePos.X() + aAbsoluteSize.Width() + 1, 0 ),
			 Point(aAbsolutePos.X() + aAbsoluteSize.Width() + 1, aAbsolutePos.Y() + aAbsoluteSize.Height()));
}

//------------------------------------------------------------------------------
void DbGridControl::NavigationBar::StateChanged( StateChangedType nType )
{
	Control::StateChanged( nType );

    Window* pWindows[] = {  &m_aRecordText,
                            &m_aAbsolute,
                            &m_aRecordOf,
                            &m_aRecordCount,
                            &m_aFirstBtn,
                            &m_aPrevBtn,
                            &m_aNextBtn,
                            &m_aLastBtn,
                            &m_aNewBtn
                        };

    switch ( nType )
    {
        case STATE_CHANGE_MIRRORING:
        {
            sal_Bool bIsRTLEnabled = IsRTLEnabled();
            for ( size_t i=0; i < sizeof( pWindows ) / sizeof( pWindows[0] ); ++i )
                pWindows[i]->EnableRTL( bIsRTLEnabled );
        }
        break;

        case STATE_CHANGE_ZOOM:
        {
            Fraction aZoom = GetZoom();

            // not all of these controls need to know the new zoom, but to be sure ...
            Font aFont( GetSettings().GetStyleSettings().GetFieldFont() );
            if ( IsControlFont() )
                aFont.Merge( GetControlFont() );

            for (size_t i=0; i < sizeof(pWindows)/sizeof(pWindows[0]); ++i)
            {
                pWindows[i]->SetZoom(aZoom);
                pWindows[i]->SetZoomedPointFont(aFont);
            }

            SetZoomedPointFont( aFont );

            // rearrange the controls
            m_nDefaultWidth = ArrangeControls();
        }
        break;
    }
}

//------------------------------------------------------------------------------
DbGridRow::DbGridRow(CursorWrapper* pCur, sal_Bool bPaintCursor)
		  :m_bIsNew(sal_False)
{

	if (pCur && pCur->Is())
	{
		Reference< XIndexAccess >  xColumns(pCur->getColumns(), UNO_QUERY);
		DataColumn* pColumn;
		for (sal_Int32 i = 0; i < xColumns->getCount(); ++i)
		{
			Reference< XPropertySet > xColSet;
			::cppu::extractInterface(xColSet, xColumns->getByIndex(i));
			pColumn = new DataColumn(xColSet);
			m_aVariants.Insert(pColumn, LIST_APPEND);
		}

		if (pCur->rowDeleted())
			m_eStatus = GRS_DELETED;
		else
		{
			if (bPaintCursor)
				m_eStatus = (pCur->isAfterLast() || pCur->isBeforeFirst()) ? GRS_INVALID : GRS_CLEAN;
			else
			{
				Reference< XPropertySet > xSet = pCur->getPropertySet();
				if (xSet.is())
				{
					m_bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW));
					if (!m_bIsNew && (pCur->isAfterLast() || pCur->isBeforeFirst()))
						m_eStatus = GRS_INVALID;
					else if (::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISMODIFIED)))
						m_eStatus = GRS_MODIFIED;
					else
						m_eStatus = GRS_CLEAN;
				}
				else
					m_eStatus = GRS_INVALID;
			}
		}
		if (!m_bIsNew && IsValid())
			m_aBookmark = pCur->getBookmark();
		else
			m_aBookmark = Any();
	}
	else
		m_eStatus = GRS_INVALID;
}

//------------------------------------------------------------------------------
DbGridRow::~DbGridRow()
{
	sal_uInt32 nCount = m_aVariants.Count();
	for (sal_uInt32 i = 0; i < nCount; i++)
		delete m_aVariants.GetObject(i);
}

//------------------------------------------------------------------------------
void DbGridRow::SetState(CursorWrapper* pCur, sal_Bool bPaintCursor)
{
	if (pCur && pCur->Is())
	{
		if (pCur->rowDeleted())
		{
			m_eStatus = GRS_DELETED;
			m_bIsNew = sal_False;
		}
		else
		{
			m_eStatus = GRS_CLEAN;
			if (!bPaintCursor)
			{
				Reference< XPropertySet > xSet = pCur->getPropertySet();
				DBG_ASSERT(xSet.is(), "DbGridRow::SetState : invalid cursor !");

				if (::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISMODIFIED)))
					m_eStatus = GRS_MODIFIED;
				m_bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW));
			}
			else
				m_bIsNew = sal_False;
		}

        try
        {
		    if (!m_bIsNew && IsValid())
			    m_aBookmark = pCur->getBookmark();
		    else
			    m_aBookmark = Any();
        }
        catch(SQLException&)
        {
            DBG_UNHANDLED_EXCEPTION();
            m_aBookmark = Any();
            m_eStatus = GRS_INVALID;
		    m_bIsNew = sal_False;
        }
	}
	else
	{
		m_aBookmark = Any();
		m_eStatus = GRS_INVALID;
		m_bIsNew = sal_False;
	}
}

DBG_NAME(DbGridControl);
//------------------------------------------------------------------------------
DbGridControl::DbGridControl(
				Reference< XMultiServiceFactory > _rxFactory,
				Window* pParent,
				WinBits nBits)
			:DbGridControl_Base(pParent, EBBF_NONE, nBits, DEFAULT_BROWSE_MODE )
            ,m_xServiceFactory(_rxFactory)
            ,m_aBar(this)
            ,m_nAsynAdjustEvent(0)
            ,m_pDataSourcePropMultiplexer(NULL)
            ,m_pDataSourcePropListener(NULL)
            ,m_pFieldListeners(NULL)
            ,m_pCursorDisposeListener(NULL)
            ,m_pGridListener(NULL)
            ,m_pDataCursor(NULL)
            ,m_pSeekCursor(NULL)
            ,m_nSeekPos(-1)
            ,m_nTotalCount(-1)
            ,m_aNullDate(OTypeConversionClient().getStandardDate())
            ,m_nMode(DEFAULT_BROWSE_MODE)
            ,m_nCurrentPos(-1)
            ,m_nDeleteEvent(0)
            ,m_nOptions(OPT_READONLY)
            ,m_nOptionMask(OPT_INSERT | OPT_UPDATE | OPT_DELETE)
	        ,m_nLastColId((sal_uInt16)-1)
            ,m_nLastRowId(-1)
            ,m_bDesignMode(sal_False)
            ,m_bRecordCountFinal(sal_False)
            ,m_bMultiSelection(sal_True)
            ,m_bNavigationBar(sal_True)
            ,m_bSynchDisplay(sal_True)
            ,m_bForceROController(sal_False)
            ,m_bHandle(sal_True)
            ,m_bFilterMode(sal_False)
            ,m_bWantDestruction(sal_False)
            ,m_bInAdjustDataSource(sal_False)
            ,m_bPendingAdjustRows(sal_False)
            ,m_bHideScrollbars( sal_False )
            ,m_bUpdating(sal_False)
{
	DBG_CTOR(DbGridControl,NULL);

    String sName(SVX_RES(RID_STR_NAVIGATIONBAR));
    m_aBar.SetAccessibleName(sName);
    m_aBar.Show();
    ImplInitWindow( InitAll );
}

//------------------------------------------------------------------------------
void DbGridControl::InsertHandleColumn()
{
	// Handle Column einfuegen
	// Da die BrowseBox ohne handleColums Paintprobleme hat
	// wird diese versteckt
	if (HasHandle())
		BrowseBox::InsertHandleColumn(GetDefaultColumnWidth(String()));
	else
		BrowseBox::InsertHandleColumn(0);
}

//------------------------------------------------------------------------------
void DbGridControl::Init()
{
	BrowserHeader* pNewHeader = CreateHeaderBar(this);
	pHeader->SetMouseTransparent(sal_False);

    SetHeaderBar(pNewHeader);
	SetMode(m_nMode);
	SetCursorColor(Color(0xFF, 0, 0));

	InsertHandleColumn();
}

//------------------------------------------------------------------------------
DbGridControl::~DbGridControl()
{
	RemoveColumns();

	{
		m_bWantDestruction = sal_True;
		osl::MutexGuard aGuard(m_aDestructionSafety);
		if (m_pFieldListeners)
			DisconnectFromFields();
		if (m_pCursorDisposeListener)
		{
			delete m_pCursorDisposeListener;
			m_pCursorDisposeListener = NULL;
		}
	}

	if (m_nDeleteEvent)
		Application::RemoveUserEvent(m_nDeleteEvent);

	if (m_pDataSourcePropMultiplexer)
	{
		m_pDataSourcePropMultiplexer->dispose();
		m_pDataSourcePropMultiplexer->release();	// this should delete the multiplexer
		delete m_pDataSourcePropListener;
		m_pDataSourcePropMultiplexer = NULL;
		m_pDataSourcePropListener = NULL;
	}
    m_xRowSetListener.clear();

	delete m_pDataCursor;
	delete m_pSeekCursor;

	DBG_DTOR(DbGridControl,NULL);
}

//------------------------------------------------------------------------------
void DbGridControl::StateChanged( StateChangedType nType )
{
	DbGridControl_Base::StateChanged( nType );

    switch (nType)
	{
        case STATE_CHANGE_MIRRORING:
			ImplInitWindow( InitWritingMode );
            Invalidate();
            break;

		case STATE_CHANGE_ZOOM:
		{
			ImplInitWindow( InitFont );

			// and give it a chance to rearrange
			Point aPoint = GetControlArea().TopLeft();
			sal_uInt16 nX = (sal_uInt16)aPoint.X();
			ArrangeControls(nX, (sal_uInt16)aPoint.Y());
			ReserveControlArea((sal_uInt16)nX);
		}
		break;
		case STATE_CHANGE_CONTROLFONT:
			ImplInitWindow( InitFont );
			Invalidate();
			break;
		case STATE_CHANGE_CONTROLFOREGROUND:
			ImplInitWindow( InitForeground );
			Invalidate();
			break;
		case STATE_CHANGE_CONTROLBACKGROUND:
			ImplInitWindow( InitBackground );
			Invalidate();
			break;
	}
}

//------------------------------------------------------------------------------
void DbGridControl::DataChanged( const DataChangedEvent& rDCEvt )
{
	DbGridControl_Base::DataChanged( rDCEvt );
	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS ) &&
		 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
	{
		ImplInitWindow( InitAll );
		Invalidate();
	}
}

//------------------------------------------------------------------------------
void DbGridControl::Select()
{
	DbGridControl_Base::Select();

	// as the selected rows may have changed, udate the according display in our navigation bar
	m_aBar.InvalidateState(NavigationBar::RECORD_COUNT);

	if (m_pGridListener)
		m_pGridListener->selectionChanged();
}

//------------------------------------------------------------------------------
void DbGridControl::ImplInitWindow( const InitWindowFacet _eInitWhat )
{
	for ( sal_uInt32 i = 0; i < m_aColumns.Count(); ++i )
	{
		DbGridColumn* pCol = m_aColumns.GetObject(i);
		if (pCol)
			pCol->ImplInitWindow( GetDataWindow(), _eInitWhat );
	}

    if ( ( _eInitWhat & InitWritingMode ) != 0 )
    {
		if ( m_bNavigationBar )
        {
			m_aBar.EnableRTL( IsRTLEnabled() );
        }
    }

    if ( ( _eInitWhat & InitFont ) != 0 )
    {
		if ( m_bNavigationBar )
        {
	        Font aFont = m_aBar.GetSettings().GetStyleSettings().GetFieldFont();
            if ( IsControlFont() )
                m_aBar.SetControlFont( GetControlFont() );
            else
                m_aBar.SetControlFont();

			m_aBar.SetZoom( GetZoom() );
        }
    }

    if ( ( _eInitWhat & InitBackground ) != 0 )
	{
		if (IsControlBackground())
		{
			GetDataWindow().SetBackground(GetControlBackground());
			GetDataWindow().SetControlBackground(GetControlBackground());
			GetDataWindow().SetFillColor(GetControlBackground());
		}
		else
		{
			GetDataWindow().SetControlBackground();
			GetDataWindow().SetFillColor(GetFillColor());
		}
	}
}

//------------------------------------------------------------------------------
void DbGridControl::RemoveRows(sal_Bool bNewCursor)
{
	// Hat sich der DatenCursor verandert ?
	if (!bNewCursor)
	{
		DELETEZ(m_pSeekCursor);
		m_xPaintRow = m_xDataRow = m_xEmptyRow	= m_xCurrentRow = m_xSeekRow = NULL;
		m_nCurrentPos = m_nSeekPos = -1;
		m_nOptions	= OPT_READONLY;

		RowRemoved(0, GetRowCount(), sal_False);
		m_nTotalCount = -1;
	}
	else
	{
		RemoveRows();
	}
}

//------------------------------------------------------------------------------
void DbGridControl::RemoveRows()
{
	// we're going to remove all columns and all row, so deactivate the current cell
	if (IsEditing())
		DeactivateCell();

	// alle Columns deinitialisieren
	// existieren Spalten, dann alle Controller freigeben
	for (sal_uInt32 i = 0; i < m_aColumns.Count(); i++)
		m_aColumns.GetObject(i)->Clear();

	DELETEZ(m_pSeekCursor);
	DELETEZ(m_pDataCursor);

	m_xPaintRow = m_xDataRow = m_xEmptyRow	= m_xCurrentRow = m_xSeekRow = NULL;
	m_nCurrentPos = m_nSeekPos = m_nTotalCount	= -1;
	m_nOptions	= OPT_READONLY;

	// Anzahl Saetze im Browser auf 0 zuruecksetzen
	DbGridControl_Base::RemoveRows();
	m_aBar.InvalidateAll(m_nCurrentPos, sal_True);
}

//------------------------------------------------------------------------------
void DbGridControl::ArrangeControls(sal_uInt16& nX, sal_uInt16 nY)
{
	// Positionierung der Controls
	if (m_bNavigationBar)
	{
		nX = m_aBar.GetDefaultWidth();
		Rectangle	aRect(GetControlArea());
		m_aBar.SetPosSizePixel(Point(0,nY + 1), Size(nX, aRect.GetSize().Height() - 1));
	}
}

//------------------------------------------------------------------------------
void DbGridControl::EnableHandle(sal_Bool bEnable)
{
	if (m_bHandle == bEnable)
		return;

	// HandleColumn wird nur ausgeblendet,
	// da es sonst etliche Probleme mit dem Zeichnen gibt
	RemoveColumn(0);
	m_bHandle = bEnable;
	InsertHandleColumn();
}

//------------------------------------------------------------------------------
namespace
{
    bool adjustModeForScrollbars( BrowserMode& _rMode, sal_Bool _bNavigationBar, sal_Bool _bHideScrollbars )
    {
        BrowserMode nOldMode = _rMode;

		if ( !_bNavigationBar )
        {
            _rMode &= ~BROWSER_AUTO_HSCROLL;
        }

        if ( _bHideScrollbars )
        {
            _rMode |= ( BROWSER_NO_HSCROLL | BROWSER_NO_VSCROLL );
            _rMode &= ~( BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL );
        }
        else
        {
            _rMode |= ( BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL );
            _rMode &= ~( BROWSER_NO_HSCROLL | BROWSER_NO_VSCROLL );
        }

        // note: if we have a navigation bar, we always have a AUTO_HSCROLL. In particular,
        // _bHideScrollbars is ignored then
		if ( _bNavigationBar )
        {
			_rMode |= BROWSER_AUTO_HSCROLL;
            _rMode &= ~BROWSER_NO_HSCROLL;
        }

        return nOldMode != _rMode;
    }
}

//------------------------------------------------------------------------------
void DbGridControl::EnableNavigationBar(sal_Bool bEnable)
{
	if (m_bNavigationBar == bEnable)
		return;

	m_bNavigationBar = bEnable;

    if (bEnable)
	{
		m_aBar.Show();
		m_aBar.Enable();
		m_aBar.InvalidateAll(m_nCurrentPos, sal_True);

        if ( adjustModeForScrollbars( m_nMode, m_bNavigationBar, m_bHideScrollbars ) )
            SetMode( m_nMode );

		// liefert die Groe�e der Reserved ControlArea
		Point aPoint = GetControlArea().TopLeft();
		sal_uInt16 nX = (sal_uInt16)aPoint.X();

		ArrangeControls(nX, (sal_uInt16)aPoint.Y());
		ReserveControlArea((sal_uInt16)nX);
	}
	else
	{
		m_aBar.Hide();
		m_aBar.Disable();

        if ( adjustModeForScrollbars( m_nMode, m_bNavigationBar, m_bHideScrollbars ) )
            SetMode( m_nMode );

		ReserveControlArea();
	}
}

//------------------------------------------------------------------------------
sal_uInt16 DbGridControl::SetOptions(sal_uInt16 nOpt)
{
	DBG_ASSERT(!m_xCurrentRow || !m_xCurrentRow->IsModified(),
		"DbGridControl::SetOptions : please do not call when editing a record (things are much easier this way ;) !");

	// for the next setDataSource (which is triggered by a refresh, for instance)
	m_nOptionMask = nOpt;

	// normalize the new options
	Reference< XPropertySet > xDataSourceSet = m_pDataCursor->getPropertySet();
	if (xDataSourceSet.is())
	{
		// feststellen welche Updatem�glichkeiten bestehen
		sal_Int32 nPrivileges = 0;
		xDataSourceSet->getPropertyValue(FM_PROP_PRIVILEGES) >>= nPrivileges;
		if ((nPrivileges & Privilege::INSERT) == 0)
			nOpt &= ~OPT_INSERT;
		if ((nPrivileges & Privilege::UPDATE) == 0)
			nOpt &= ~OPT_UPDATE;
		if ((nPrivileges & Privilege::DELETE) == 0)
			nOpt &= ~OPT_DELETE;
	}
	else
		nOpt = OPT_READONLY;

	// need to do something after that ?
	if (nOpt == m_nOptions)
		return m_nOptions;

	// the 'update' option only affects our BrowserMode (with or w/o focus rect)
	BrowserMode nNewMode = m_nMode;
	if ((m_nMode & BROWSER_CURSOR_WO_FOCUS) == 0)
	{
		if (nOpt & OPT_UPDATE)
			nNewMode |= BROWSER_HIDECURSOR;
		else
			nNewMode &= ~BROWSER_HIDECURSOR;
	}
	else
		nNewMode &= ~BROWSER_HIDECURSOR;
		// should not be neccessary if EnablePermanentCursor is used to change the cursor behaviour, but to be sure ...

	if (nNewMode != m_nMode)
	{
		SetMode(nNewMode);
		m_nMode = nNewMode;
	}

	// _after_ setting the mode because this results in an ActivateCell
	DeactivateCell();

	sal_Bool bInsertChanged = (nOpt & OPT_INSERT) != (m_nOptions & OPT_INSERT);
	m_nOptions = nOpt;
		// we need to set this before the code below because it indirectly uses m_nOptions

	// the 'insert' option affects our empty row
	if (bInsertChanged)
	{
		if (m_nOptions & OPT_INSERT)
		{	// the insert option is to be set
			m_xEmptyRow = new DbGridRow();
			RowInserted(GetRowCount(), 1, sal_True);
		}
		else
		{	// the insert option is to be reset
			m_xEmptyRow = NULL;
			if ((GetCurRow() == GetRowCount() - 1) && (GetCurRow() > 0))
				GoToRowColumnId(GetCurRow() - 1, GetCurColumnId());
			RowRemoved(GetRowCount(), 1, sal_True);
		}
	}

	// the 'delete' options has no immediate consequences

	ActivateCell();
	Invalidate();
	return m_nOptions;
}

//------------------------------------------------------------------------------
void DbGridControl::ForceHideScrollbars( sal_Bool _bForce )
{
    if ( m_bHideScrollbars == _bForce )
        return;

    m_bHideScrollbars = _bForce;

    if ( adjustModeForScrollbars( m_nMode, m_bNavigationBar, m_bHideScrollbars ) )
        SetMode( m_nMode );
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::IsForceHideScrollbars() const
{
    return m_bHideScrollbars;
}

//------------------------------------------------------------------------------
void DbGridControl::EnablePermanentCursor(sal_Bool bEnable)
{
	if (IsPermanentCursorEnabled() == bEnable)
		return;

	if (bEnable)
	{
		m_nMode &= ~BROWSER_HIDECURSOR; 	// without this BROWSER_CURSOR_WO_FOCUS won't have any affect
		m_nMode |= BROWSER_CURSOR_WO_FOCUS;
	}
	else
	{
		if (m_nOptions & OPT_UPDATE)
			m_nMode |= BROWSER_HIDECURSOR;		// no cursor at all
		else
			m_nMode &= ~BROWSER_HIDECURSOR; 	// at least the "non-permanent" cursor

		m_nMode &= ~BROWSER_CURSOR_WO_FOCUS;
	}
	SetMode(m_nMode);

	sal_Bool bWasEditing = IsEditing();
	DeactivateCell();
	if (bWasEditing)
		ActivateCell();
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::IsPermanentCursorEnabled() const
{
	return ((m_nMode & BROWSER_CURSOR_WO_FOCUS) != 0) && ((m_nMode & BROWSER_HIDECURSOR) == 0);
}

//------------------------------------------------------------------------------
void DbGridControl::refreshController(sal_uInt16 _nColId, GrantControlAccess /*_aAccess*/)
{
	if ((GetCurColumnId() == _nColId) && IsEditing())
	{	// the controller which is currently active needs to be refreshed
		DeactivateCell();
		ActivateCell();
	}
}

//------------------------------------------------------------------------------
void DbGridControl::SetMultiSelection(sal_Bool bMulti)
{
	m_bMultiSelection = bMulti;
	if (m_bMultiSelection)
		m_nMode |= BROWSER_MULTISELECTION;
	else
		m_nMode &= ~BROWSER_MULTISELECTION;

	SetMode(m_nMode);
}

//------------------------------------------------------------------------------
void DbGridControl::setDataSource(const Reference< XRowSet >& _xCursor, sal_uInt16 nOpts)
{
	if (!_xCursor.is() && !m_pDataCursor)
		return;

	if (m_pDataSourcePropMultiplexer)
	{
		m_pDataSourcePropMultiplexer->dispose();
		m_pDataSourcePropMultiplexer->release();	// this should delete the multiplexer
		delete m_pDataSourcePropListener;
		m_pDataSourcePropMultiplexer = NULL;
		m_pDataSourcePropListener = NULL;
	}
    m_xRowSetListener.clear();

	// is the new cursor valid ?
	// the cursor is only valid if it contains some columns
	// if there is no cursor or the cursor is not valid we have to clean up an leave
	if (!_xCursor.is() || !Reference< XColumnsSupplier > (_xCursor, UNO_QUERY)->getColumns()->hasElements())
	{
		RemoveRows();
		return;
	}

	// Hat sich der DatenCursor verandert ?
	sal_uInt16 nCurPos = GetColumnPos(GetCurColumnId());

	SetUpdateMode(sal_False);
	RemoveRows();
	DisconnectFromFields();

	DELETEZ(m_pCursorDisposeListener);

	{
		::osl::MutexGuard aGuard(m_aAdjustSafety);
		if (m_nAsynAdjustEvent)
		{
			// the adjust was thought to work with the old cursor which we don't have anymore
			RemoveUserEvent(m_nAsynAdjustEvent);
			m_nAsynAdjustEvent = 0;
		}
	}

	// get a new formatter and data cursor
	m_xFormatter = NULL;
	OStaticDataAccessTools aStaticTools;
	Reference< ::com::sun::star::util::XNumberFormatsSupplier >  xSupplier = aStaticTools.getNumberFormats(aStaticTools.getRowSetConnection(_xCursor), sal_True);
	if (xSupplier.is() && m_xServiceFactory.is())
	{
		m_xFormatter =	Reference< ::com::sun::star::util::XNumberFormatter >(
			m_xServiceFactory->createInstance(FM_NUMBER_FORMATTER),
			UNO_QUERY);
		if (m_xFormatter.is())
		{
			m_xFormatter->attachNumberFormatsSupplier(xSupplier);

			// retrieve the datebase of the Numberformatter
			try
			{
				xSupplier->getNumberFormatSettings()->getPropertyValue(rtl::OUString::createFromAscii("NullDate")) >>= m_aNullDate;
			}
			catch(Exception&)
			{
			}
		}
	}

	m_pDataCursor = new CursorWrapper(_xCursor);

	// now create a cursor for painting rows
	// we need that cursor only if we are not in insert only mode
	Reference< XResultSet > xClone;
	Reference< XResultSetAccess > xAccess( _xCursor, UNO_QUERY );
	try
	{
		xClone = xAccess.is() ? xAccess->createResultSet() : Reference< XResultSet > ();
	}
	catch(Exception&)
	{
	}
	if (xClone.is())
		m_pSeekCursor = new CursorWrapper(xClone);

	// property listening on the data source
	// (Normally one class would be sufficient : the multiplexer which could forward the property change to us.
	// But for that we would have been derived from ::comphelper::OPropertyChangeListener, which isn't exported.
	// So we introduce a second class, which is a ::comphelper::OPropertyChangeListener (in the implementation file we know this class)
	// and forwards the property changes to a our special method "DataSourcePropertyChanged".)
	if (m_pDataCursor)
	{
		m_pDataSourcePropListener = new FmXGridSourcePropListener(this);
		m_pDataSourcePropMultiplexer = new ::comphelper::OPropertyChangeMultiplexer(m_pDataSourcePropListener, m_pDataCursor->getPropertySet() );
		m_pDataSourcePropMultiplexer->acquire();
		m_pDataSourcePropMultiplexer->addProperty(FM_PROP_ISMODIFIED);
		m_pDataSourcePropMultiplexer->addProperty(FM_PROP_ISNEW);
	}

	BrowserMode nOldMode = m_nMode;
	if (m_pSeekCursor)
	{
		try
		{
			Reference< XPropertySet >  xSet(_xCursor, UNO_QUERY);
			if (xSet.is())
			{
				// feststellen welche Updatemoeglichkeiten bestehen
				sal_Int32 nConcurrency = ResultSetConcurrency::READ_ONLY;
				xSet->getPropertyValue(FM_PROP_RESULTSET_CONCURRENCY) >>= nConcurrency;

				if ( ResultSetConcurrency::UPDATABLE == nConcurrency )
				{
					sal_Int32 nPrivileges = 0;
					xSet->getPropertyValue(FM_PROP_PRIVILEGES) >>= nPrivileges;

					// Insert Option should be set if insert only otherwise you won't see any rows
					// and no insertion is possible
					if ((m_nOptionMask & OPT_INSERT) && ((nPrivileges & Privilege::INSERT) == Privilege::INSERT) && (nOpts & OPT_INSERT))
						m_nOptions |= OPT_INSERT;
					if ((m_nOptionMask & OPT_UPDATE) && ((nPrivileges & Privilege::UPDATE) == Privilege::UPDATE) && (nOpts & OPT_UPDATE))
						m_nOptions |= OPT_UPDATE;
					if ((m_nOptionMask & OPT_DELETE) && ((nPrivileges & Privilege::DELETE) == Privilege::DELETE) && (nOpts & OPT_DELETE))
						m_nOptions |= OPT_DELETE;
				}
			}
		}
		catch( const Exception& )
		{
            DBG_UNHANDLED_EXCEPTION();
		}

		sal_Bool bPermanentCursor = IsPermanentCursorEnabled();
		m_nMode = DEFAULT_BROWSE_MODE;

        if ( bPermanentCursor )
		{
			m_nMode |= BROWSER_CURSOR_WO_FOCUS;
			m_nMode &= ~BROWSER_HIDECURSOR;
		}
		else
        {
			// Duerfen Updates gemacht werden, kein Focus-RechtEck
			if ( m_nOptions & OPT_UPDATE )
				m_nMode |= BROWSER_HIDECURSOR;
        }

		if ( m_bMultiSelection )
			m_nMode |= BROWSER_MULTISELECTION;
        else
            m_nMode &= ~BROWSER_MULTISELECTION;

        adjustModeForScrollbars( m_nMode, m_bNavigationBar, m_bHideScrollbars );

		Reference< XColumnsSupplier >  xSupplyColumns(_xCursor, UNO_QUERY);
		if (xSupplyColumns.is())
			InitColumnsByFields(Reference< XIndexAccess > (xSupplyColumns->getColumns(), UNO_QUERY));

		ConnectToFields();
	}

	sal_uInt32 nRecordCount(0);

	if (m_pSeekCursor)
	{
		Reference< XPropertySet > xSet = m_pDataCursor->getPropertySet();
		xSet->getPropertyValue(FM_PROP_ROWCOUNT) >>= nRecordCount;
		m_bRecordCountFinal = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ROWCOUNTFINAL));

        m_xRowSetListener = new RowSetEventListener(this);
        Reference< XRowsChangeBroadcaster> xChangeBroad(xSet,UNO_QUERY);
        if ( xChangeBroad.is( ) )
            xChangeBroad->addRowsChangeListener(m_xRowSetListener);
        

		// insert the currently known rows
		// and one row if we are able to insert rows
		if (m_nOptions & OPT_INSERT)
		{
			// insert the empty row for insertion
			m_xEmptyRow = new DbGridRow();
			++nRecordCount;
		}
		if (nRecordCount)
		{
			m_xPaintRow = m_xSeekRow = new DbGridRow(m_pSeekCursor, sal_True);
			m_xDataRow	= new DbGridRow(m_pDataCursor, sal_False);
			RowInserted(0, nRecordCount, sal_False);

			if (m_xSeekRow->IsValid())
                try
                {
				    m_nSeekPos = m_pSeekCursor->getRow() - 1;
                }
                catch( const Exception& )
                {
                	DBG_UNHANDLED_EXCEPTION();
                    m_nSeekPos = -1;
                }
		}
		else
		{
			// no rows so we don't need a seekcursor
			DELETEZ(m_pSeekCursor);
		}
	}

	// Zur alten Spalte gehen
	if (!nCurPos || nCurPos >= ColCount())
		nCurPos = 1;

	// there are rows so go to the selected current column
	if (nRecordCount)
		GoToRowColumnId(0, GetColumnId(nCurPos));
	// else stop the editing if neccessary
	else if (IsEditing())
		DeactivateCell();

	// now reset the mode
	if (m_nMode != nOldMode)
		SetMode(m_nMode);

	// beim Resizen wird RecalcRows gerufen
	if (!IsResizing() && GetRowCount())
		RecalcRows(GetTopRow(), GetVisibleRows(), sal_True);

	m_aBar.InvalidateAll(m_nCurrentPos, sal_True);
	SetUpdateMode(sal_True);

	// start listening on the seek cursor
	if (m_pSeekCursor)
		m_pCursorDisposeListener = new DisposeListenerGridBridge(*this, Reference< XComponent > ((Reference< XInterface >)*m_pSeekCursor, UNO_QUERY), 0);
}

//------------------------------------------------------------------------------
void DbGridControl::RemoveColumns()
{
	if ( IsEditing() )
		DeactivateCell();

	for (sal_uInt32 i = 0; i < m_aColumns.Count(); i++)
		delete m_aColumns.GetObject(i);
	m_aColumns.Clear();

	DbGridControl_Base::RemoveColumns();
}

//------------------------------------------------------------------------------
DbGridColumn* DbGridControl::CreateColumn(sal_uInt16 nId) const
{
	return new DbGridColumn(nId, *(DbGridControl*)this);
}

//------------------------------------------------------------------------------
sal_uInt16 DbGridControl::AppendColumn(const XubString& rName, sal_uInt16 nWidth, sal_uInt16 nModelPos, sal_uInt16 nId)
{
	DBG_ASSERT(nId == (sal_uInt16)-1, "DbGridControl::AppendColumn : I want to set the ID myself ...");
	sal_uInt16 nRealPos = nModelPos;
	if (nModelPos != HEADERBAR_APPEND)
	{
		// calc the view pos. we can't use our converting functions because the new column
		// has no VCL-representation, yet.
		sal_Int16 nViewPos = nModelPos;
		while (nModelPos--)
		{
			if (m_aColumns.GetObject(nModelPos)->IsHidden())
				--nViewPos;
		}
		// restore nModelPos, we need it later
		nModelPos = nRealPos;
		// the position the base class gets is the view pos + 1 (because of the handle column)
		nRealPos = nViewPos + 1;
	}

	// calculate the new id
    for (nId=1; (GetModelColumnPos(nId) != GRID_COLUMN_NOT_FOUND) && (nId<=m_aColumns.Count()); ++nId)
		;
	DBG_ASSERT(GetViewColumnPos(nId) == (sal_uInt16)-1, "DbGridControl::AppendColumn : inconsistent internal state !");
		// my column's models say "there is no column with id nId", but the view (the base class) says "there is a column ..."

	DbGridControl_Base::AppendColumn(rName, nWidth, nRealPos, nId);
	if (nModelPos == HEADERBAR_APPEND)
		m_aColumns.Insert(CreateColumn(nId), LIST_APPEND);
	else
		m_aColumns.Insert(CreateColumn(nId), nModelPos);

	return nId;
}

//------------------------------------------------------------------------------
void DbGridControl::RemoveColumn(sal_uInt16 nId)
{
	sal_Int16 nIndex = GetModelColumnPos(nId);
	DbGridControl_Base::RemoveColumn(nId);
	delete m_aColumns.Remove(nIndex);
}

//------------------------------------------------------------------------------
void DbGridControl::ColumnMoved(sal_uInt16 nId)
{
	DbGridControl_Base::ColumnMoved(nId);

	// remove the col from the model
	sal_Int16 nOldModelPos = GetModelColumnPos(nId);
#ifdef DBG_UTIL
	DbGridColumn* pCol = m_aColumns.GetObject((sal_uInt32)nOldModelPos);
	DBG_ASSERT(!pCol->IsHidden(), "DbGridControl::ColumnMoved : moved a hidden col ? how this ?");
#endif

	// for the new model pos we can't use GetModelColumnPos because we are altering the model at the moment
	// so the method won't work (in fact it would return the old model pos)

	// the new view pos is calculated easily
	sal_uInt16 nNewViewPos = GetViewColumnPos(nId);

	// from that we can compute the new model pos
	sal_uInt16 nNewModelPos;
	for (nNewModelPos = 0; nNewModelPos < m_aColumns.Count(); ++nNewModelPos)
	{
		if (!m_aColumns.GetObject(nNewModelPos)->IsHidden())
		{
			if (!nNewViewPos)
				break;
			else
				--nNewViewPos;
		}
	}
	DBG_ASSERT(nNewModelPos<m_aColumns.Count(), "DbGridControl::ColumnMoved : could not find the new model position !");

	// this will work. of course the model isn't fully consistent with our view right now, but let's
	// look at the situation : a column has been moved with in the VIEW from pos m to n, say m<n (in the
	// other case we can use analogue arguments).
	// All cols k with m<k<=n have been shifted left on pos, the former col m now has pos n.
	// In the model this affects a range of cols x to y, where x<=m and y<=n. And the number of hidden cols
	// within this range is constant, so we may calculate the view pos from the model pos in the above way.
	//
	// for instance, let's look at a grid with six columns where the third one is hidden. this will
	// initially look like this :
	//
	//				+---+---+---+---+---+---+
	// model pos	| 0 | 1 |*2*| 3 | 4 | 5 |
	//				+---+---+---+---+---+---+
	// ID			| 1 | 2 | 3 | 4 | 5 | 6 |
	//				+---+---+---+---+---+---+
	// view pos 	| 0 | 1 | - | 2 | 3 | 4 |
	//				+---+---+---+---+---+---+
	//
	// if we move the column at (view) pos 1 to (view) pos 3 we have :
	//
	//				+---+---+---+---+---+---+
	// model pos	| 0 | 3 |*2*| 4 | 1 | 5 |	// not reflecting the changes, yet
	//				+---+---+---+---+---+---+
	// ID			| 1 | 4 | 3 | 5 | 2 | 6 |	// already reflecting the changes
	//				+---+---+---+---+---+---+
	// view pos 	| 0 | 1 | - | 2 | 3 | 4 |
	//				+---+---+---+---+---+---+
	//
	// or, sorted by the out-of-date model positions :
	//
	//				+---+---+---+---+---+---+
	// model pos	| 0 | 1 |*2*| 3 | 4 | 5 |
	//				+---+---+---+---+---+---+
	// ID			| 1 | 2 | 3 | 4 | 5 | 6 |
	//				+---+---+---+---+---+---+
	// view pos 	| 0 | 3 | - | 1 | 2 | 4 |
	//				+---+---+---+---+---+---+
	//
	// We know the new view pos (3) of the moved column because our base class tells us. So we look at our
	// model for the 4th (the pos is zero-based) visible column, it is at (model) position 4. And this is
	// exactly the pos where we have to re-insert our column's model, so it looks ike this :
	//
	//				+---+---+---+---+---+---+
	// model pos	| 0 |*1*| 2 | 3 | 4 | 5 |
	//				+---+---+---+---+---+---+
	// ID			| 1 | 3 | 4 | 5 | 2 | 6 |
	//				+---+---+---+---+---+---+
	// view pos 	| 0 | - | 1 | 2 | 3 | 4 |
	//				+---+---+---+---+---+---+
	//
	// Now, all is consistent again.
	// (except of the hidden column : The cycling of the cols occured on the model, not on the view. maybe
	// the user expected the latter but there really is no good argument against our method ;) ...)
	//
	// And no, this large explanation isn't just because I wanted to play a board game or something like
	// that. It's because it took me a while to see it myself, and the whole theme (hidden cols, model col
	// positions, view col positions)  is really painful (at least for me) so the above pictures helped me a lot ;)

	m_aColumns.Insert(m_aColumns.Remove((sal_uInt32)nOldModelPos), nNewModelPos);
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::SeekRow(long nRow)
{
	// in filter mode or in insert only mode we don't have any cursor!
	if ( !SeekCursor( nRow ) )
        return sal_False;

	if ( IsFilterMode() )
	{
		DBG_ASSERT( IsFilterRow( nRow ), "DbGridControl::SeekRow(): No filter row, wrong mode" );
		m_xPaintRow = m_xEmptyRow;
	}
    else
	{
		// on the current position we have to take the current row for display as we want
		// to have the most recent values for display
		if ( ( nRow == m_nCurrentPos ) && getDisplaySynchron() )
			m_xPaintRow = m_xCurrentRow;
		// seek to the empty insert row
		else if ( IsInsertionRow( nRow ) )
			m_xPaintRow = m_xEmptyRow;
		else
		{
			m_xSeekRow->SetState( m_pSeekCursor, sal_True );
			m_xPaintRow = m_xSeekRow;
		}
	}

    DbGridControl_Base::SeekRow(nRow);

    return m_nSeekPos >= 0;
}
//------------------------------------------------------------------------------
// Wird aufgerufen, wenn die dargestellte Datenmenge sich aendert
//------------------------------------------------------------------------------
void DbGridControl::VisibleRowsChanged( long nNewTopRow, sal_uInt16 nLinesOnScreen )
{
	RecalcRows(nNewTopRow, nLinesOnScreen , sal_False);
}

//------------------------------------------------------------------------------
void DbGridControl::RecalcRows(long nNewTopRow, sal_uInt16 nLinesOnScreen, sal_Bool bUpdateCursor)
{
	DBG_CHKTHIS( DbGridControl, NULL );
	// Wenn kein Cursor -> keine Rows im Browser.
	if (!m_pSeekCursor)
	{
		DBG_ASSERT(GetRowCount() == 0,"DbGridControl: ohne Cursor darf es keine Rows geben");
		return;
	}

	// ignore any updates implicit made
	sal_Bool bDisablePaint = !bUpdateCursor && IsPaintEnabled();
	if (bDisablePaint)
		EnablePaint(sal_False);

	// Cache an den sichtbaren Bereich anpassen
	Reference< XPropertySet > xSet = m_pSeekCursor->getPropertySet();
	sal_Int32 nCacheSize = 0;
	xSet->getPropertyValue(FM_PROP_FETCHSIZE) >>= nCacheSize;
	sal_Bool bCacheAligned	 = sal_False;
	// Nach der Initialisierung (m_nSeekPos < 0) keine Cursorbewegung, da bereits auf den ersten
	// Satz positioniert
	long nDelta = nNewTopRow - GetTopRow();
	// Limit fuer relative Positionierung
	long nLimit = (nCacheSize) ? nCacheSize / 2 : 0;

	// mehr Zeilen auf dem Bildschirm als im Cache
	if (nLimit < nLinesOnScreen)
	{
		Any aCacheSize;
		aCacheSize <<= sal_Int32(nLinesOnScreen*2);
		xSet->setPropertyValue(FM_PROP_FETCHSIZE, aCacheSize);
		// jetzt auf alle Faelle den Cursor anpassen
		bUpdateCursor = sal_True;
		bCacheAligned = sal_True;
		nLimit = nLinesOnScreen;
	}

	// Im folgenden werden die Positionierungen so vorgenommen, da� sichergestellt ist
	// da� ausreichend Zeilen im DatenCache vorhanden sind

	// Fenster geht nach unten, weniger als zwei Fenster Differenz
	// oder Cache angepasst und noch kein Rowcount
	if (nDelta < nLimit && (nDelta > 0
		|| (bCacheAligned && m_nTotalCount < 0)) )
		SeekCursor(nNewTopRow + nLinesOnScreen - 1, sal_False);
	else if (nDelta < 0 && Abs(nDelta) < nLimit)
		SeekCursor(nNewTopRow, sal_False);
	else if (nDelta != 0 || bUpdateCursor)
		SeekCursor(nNewTopRow, sal_True);

	AdjustRows();

	// ignore any updates implicit made
	EnablePaint(sal_True);
}

//------------------------------------------------------------------------------
void DbGridControl::RowInserted(long nRow, long nNumRows, sal_Bool bDoPaint, sal_Bool bKeepSelection)
{
	if (nNumRows)
	{
		if (m_bRecordCountFinal && m_nTotalCount < 0)
		{
			// if we have an insert row we have to reduce to count by 1
			// as the total count reflects only the existing rows in database
			m_nTotalCount = GetRowCount() + nNumRows;
			if (m_xEmptyRow.Is())
				--m_nTotalCount;
		}
		else if (m_nTotalCount >= 0)
			m_nTotalCount += nNumRows;

		DbGridControl_Base::RowInserted(nRow, nNumRows, bDoPaint, bKeepSelection);
		m_aBar.InvalidateState(NavigationBar::RECORD_COUNT);
	}
}

//------------------------------------------------------------------------------
void DbGridControl::RowRemoved(long nRow, long nNumRows, sal_Bool bDoPaint)
{
	if (nNumRows)
	{
		if (m_bRecordCountFinal && m_nTotalCount < 0)
		{
			m_nTotalCount = GetRowCount() - nNumRows;
			// if we have an insert row reduce by 1
			if (m_xEmptyRow.Is())
				--m_nTotalCount;
		}
		else if (m_nTotalCount >= 0)
			m_nTotalCount -= nNumRows;

		DbGridControl_Base::RowRemoved(nRow, nNumRows, bDoPaint);
		m_aBar.InvalidateState(NavigationBar::RECORD_COUNT);
	}
}

//------------------------------------------------------------------------------
void DbGridControl::AdjustRows()
{
	if (!m_pSeekCursor)
		return;

	Reference< XPropertySet > xSet = m_pDataCursor->getPropertySet();

	// Aktualisieren des RecordCounts
	sal_Int32 nRecordCount = 0;
	xSet->getPropertyValue(FM_PROP_ROWCOUNT) >>= nRecordCount;
	if (!m_bRecordCountFinal)
		m_bRecordCountFinal = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ROWCOUNTFINAL));

	// hat sich die aktuelle Anzahl Rows veraendert
	// hierbei muss auch beruecksichtigt werden,
	// das eine zusaetzliche Zeile zum einfuegen von Datensaetzen vorhanden sein kann

	// zusaetzliche AppendRow fuers einfuegen
	if (m_nOptions & OPT_INSERT)
		++nRecordCount;

	// wird gerade eingefuegt, dann gehoert die gerade hinzuzufuegende
	// Zeile nicht zum RecordCount und die Appendrow ebenfalls nicht
	if (!IsUpdating() && m_bRecordCountFinal && IsModified() && m_xCurrentRow != m_xEmptyRow &&
		m_xCurrentRow->IsNew())
		++nRecordCount;
	// das ist mit !m_bUpdating abgesichert : innerhalb von SaveRow (m_bUpdating == sal_True) wuerde sonst der Datensatz, den ich editiere
	// (und den SaveRow gerade angefuegt hat, wodurch diese Methode hier getriggert wurde), doppelt zaehlen : einmal ist er schon
	// in dem normalen RecordCount drin, zum zweiten wuerde er hier gezaehlt werden (60787 - FS)

	if (nRecordCount != GetRowCount())
	{
		long nDelta = GetRowCount() - (long)nRecordCount;
		if (nDelta > 0) 										// zuviele
		{
			RowRemoved(GetRowCount() - nDelta, nDelta, sal_False);
			// es sind Zeilen weggefallen, dann ab der aktuellen Position neu zeichen
			Invalidate();

            sal_Int32 nNewPos = AlignSeekCursor();
            if (m_bSynchDisplay)
			    DbGridControl_Base::GoToRow(nNewPos);
            
            SetCurrent(nNewPos);
            // there are rows so go to the selected current column
	        if (nRecordCount)
		        GoToRowColumnId(nNewPos, GetColumnId(GetCurColumnId()));
	        if (!IsResizing() && GetRowCount())
		        RecalcRows(GetTopRow(), GetVisibleRows(), sal_True);
            m_aBar.InvalidateAll(m_nCurrentPos, sal_True);
		}
		else													// zuwenig
			RowInserted(GetRowCount(), -nDelta, sal_True);
	}

	if (m_bRecordCountFinal && m_nTotalCount < 0)
	{
		if (m_nOptions & OPT_INSERT)
			m_nTotalCount = GetRowCount() - 1;
		else
			m_nTotalCount = GetRowCount();
	}
	m_aBar.InvalidateState(NavigationBar::RECORD_COUNT);
}

//------------------------------------------------------------------------------
DbGridControl_Base::RowStatus DbGridControl::GetRowStatus(long nRow) const
{
	if (IsFilterRow(nRow))
		return DbGridControl_Base::FILTER;
	else if (m_nCurrentPos >= 0 && nRow == m_nCurrentPos)
	{
		// neue Zeile
		if (!IsValid(m_xCurrentRow))
			return DbGridControl_Base::DELETED;
		else if (IsModified())
			return DbGridControl_Base::MODIFIED;
		else if (m_xCurrentRow->IsNew())
			return DbGridControl_Base::CURRENTNEW;
		else
			return DbGridControl_Base::CURRENT;
	}
	else if (IsInsertionRow(nRow))
		return DbGridControl_Base::NEW;
	else if (!IsValid(m_xSeekRow))
		return DbGridControl_Base::DELETED;
	else
		return DbGridControl_Base::CLEAN;
}

//------------------------------------------------------------------------------
void DbGridControl::PaintStatusCell(OutputDevice& rDev, const Rectangle& rRect) const
{
	DbGridControl_Base::PaintStatusCell(rDev, rRect);
}

//------------------------------------------------------------------------------
void DbGridControl::PaintCell(OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId) const
{
	if (!IsValid(m_xPaintRow))
		return;

	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColumnId));
	if (pColumn)
	{
		Rectangle aArea(rRect);
		if ((GetMode() & BROWSER_CURSOR_WO_FOCUS) == BROWSER_CURSOR_WO_FOCUS)
		{
			aArea.Top() += 1;
			aArea.Bottom() -= 1;
		}
		pColumn->Paint(rDev, aArea, m_xPaintRow, getNumberFormatter());
	}
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::CursorMoving(long nNewRow, sal_uInt16 nNewCol)
{
	DBG_CHKTHIS( DbGridControl, NULL );

    DeactivateCell( sal_False );

	if  (   m_pDataCursor
        &&  ( m_nCurrentPos != nNewRow )
        && !SetCurrent( nNewRow )
        )
    {
        ActivateCell();
		return sal_False;
    }

    if ( !DbGridControl_Base::CursorMoving( nNewRow, nNewCol ) )
        return sal_False;

	return sal_True;
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::SetCurrent(long nNewRow)
{
	// Each movement of the datacursor must start with BeginCursorAction and end with
	// EndCursorAction to block all notifications during the movement
	BeginCursorAction();

	try
	{
		// Abgleichen der Positionen
		if (SeekCursor(nNewRow))
		{
			if (IsFilterRow(nNewRow))	// special mode for filtering
			{
				m_xCurrentRow = m_xDataRow = m_xPaintRow = m_xEmptyRow;
				m_nCurrentPos = nNewRow;
			}
			else
			{
				sal_Bool bNewRowInserted = sal_False;
				// Should we go to the insertrow ?
				if (IsInsertionRow(nNewRow))
				{
					// to we need to move the cursor to the insert row?
					// we need to insert the if the current row isn't the insert row or if the
					// cursor triggered the move by itselt and we need a reinitialization of the row
					Reference< XPropertySet > xCursorProps = m_pDataCursor->getPropertySet();
					if ( !::comphelper::getBOOL(xCursorProps->getPropertyValue(FM_PROP_ISNEW)) )
					{
						Reference< XResultSetUpdate > xUpdateCursor((Reference< XInterface >)*m_pDataCursor, UNO_QUERY);
						xUpdateCursor->moveToInsertRow();
					}
					bNewRowInserted = sal_True;
				}
				else
				{

					if ( !m_pSeekCursor->isBeforeFirst() && !m_pSeekCursor->isAfterLast() )
					{
						Any aBookmark = m_pSeekCursor->getBookmark();
						if (!m_xCurrentRow || m_xCurrentRow->IsNew() || !CompareBookmark(aBookmark, m_pDataCursor->getBookmark()))
						{
							// adjust the cursor to the new desired row
							if (!m_pDataCursor->moveToBookmark(aBookmark))
							{
								EndCursorAction();
								return sal_False;
							}
						}
					}
				}
				m_xDataRow->SetState(m_pDataCursor, sal_False);
				m_xCurrentRow = m_xDataRow;

				long nPaintPos = -1;
				// do we have to repaint the last regular row in case of setting defaults or autovalues
				if (m_nCurrentPos >= 0 && m_nCurrentPos >= (GetRowCount() - 2))
					nPaintPos = m_nCurrentPos;

				m_nCurrentPos = nNewRow;

				// repaint the new row to display all defaults
				if (bNewRowInserted)
					RowModified(m_nCurrentPos);
				if (nPaintPos >= 0)
					RowModified(nPaintPos);
			}
		}
		else
		{
			DBG_ERROR("DbGridControl::SetCurrent : SeekRow failed !");
			EndCursorAction();
			return sal_False;
		}
	}
	catch ( const Exception& )
	{
        DBG_UNHANDLED_EXCEPTION();
		EndCursorAction();
		return sal_False;
	}

	EndCursorAction();
	return sal_True;
}

//------------------------------------------------------------------------------
void DbGridControl::CursorMoved()
{
	DBG_CHKTHIS( DbGridControl, NULL );

	// CursorBewegung durch loeschen oder einfuegen von Zeilen
	if (m_pDataCursor && m_nCurrentPos != GetCurRow())
	{
		DeactivateCell(sal_True);
		SetCurrent(GetCurRow());
	}

	DbGridControl_Base::CursorMoved();
	m_aBar.InvalidateAll(m_nCurrentPos);

	// select the new column when they moved
	if ( IsDesignMode() && GetSelectedColumnCount() > 0 && GetCurColumnId() )
	{
		SelectColumnId( GetCurColumnId() );
	}

    if ( m_nLastColId != GetCurColumnId() )
        onColumnChange();
	m_nLastColId = GetCurColumnId();

    if ( m_nLastRowId != GetCurRow() )
        onRowChange();
	m_nLastRowId = GetCurRow();
}

//------------------------------------------------------------------------------
void DbGridControl::onRowChange()
{
    // not interested in
}

//------------------------------------------------------------------------------
void DbGridControl::onColumnChange()
{
    if ( m_pGridListener )
		m_pGridListener->columnChanged();
}

//------------------------------------------------------------------------------
void DbGridControl::setDisplaySynchron(sal_Bool bSync)
{
	if (bSync != m_bSynchDisplay)
	{
		m_bSynchDisplay = bSync;
		if (m_bSynchDisplay)
			AdjustDataSource(sal_False);
	}
}

//------------------------------------------------------------------------------
void DbGridControl::forceSyncDisplay()
{
	sal_Bool bOld = getDisplaySynchron();
	setDisplaySynchron(sal_True);
	if (!bOld)
		setDisplaySynchron(bOld);
}

//------------------------------------------------------------------------------
void DbGridControl::forceROController(sal_Bool bForce)
{
	if (m_bForceROController == bForce)
		return;

	m_bForceROController = bForce;
	// alle Columns durchgehen und denen Bescheid geben
	for (sal_uInt16 i=0; i<m_aColumns.Count(); ++i)
	{
		DbGridColumn* pColumn = m_aColumns.GetObject(i);
		if (!pColumn)
			continue;

		CellController* pReturn = &pColumn->GetController();
		if (!pReturn)
			continue;

		// nur wenn es eine Edit-Zeile ist, kann ich ihr das forced read-only mitgeben
		if (!pReturn->ISA(EditCellController) && !pReturn->ISA(SpinCellController))
			continue;

		Edit& rEdit = (Edit&)pReturn->GetWindow();
		rEdit.SetReadOnly(m_bForceROController);
		if (m_bForceROController)
			rEdit.SetStyle(rEdit.GetStyle() | WB_NOHIDESELECTION);
		else
			rEdit.SetStyle(rEdit.GetStyle() & ~WB_NOHIDESELECTION);
	}

	// die aktive Zelle erneut aktivieren, da sich ihr Controller geaendert haben kann
	if (IsEditing())
		DeactivateCell();
	ActivateCell();
}


//------------------------------------------------------------------------------
void DbGridControl::AdjustDataSource(sal_Bool bFull)
{
	TRACE_RANGE("DbGridControl::AdjustDataSource");
	::vos::OGuard aGuard(Application::GetSolarMutex());
	// wird die aktuelle Zeile gerade neu bestimmt,
	// wird kein abgleich vorgenommen

	if (bFull)
		m_xCurrentRow = NULL;
	// if we are on the same row only repaint
	// but this is only possible for rows which are not inserted, in that case the comparision result
	// may not be correct
	else
        if  (   m_xCurrentRow.Is()
            &&  !m_xCurrentRow->IsNew()
            &&  !m_pDataCursor->isBeforeFirst()
            &&  !m_pDataCursor->isAfterLast()
            &&  !m_pDataCursor->rowDeleted()
            )
		{
			sal_Bool bEqualBookmarks = CompareBookmark( m_xCurrentRow->GetBookmark(), m_pDataCursor->getBookmark() );

			sal_Bool bDataCursorIsOnNew = sal_False;
			m_pDataCursor->getPropertySet()->getPropertyValue( FM_PROP_ISNEW ) >>= bDataCursorIsOnNew;

			if ( bEqualBookmarks && !bDataCursorIsOnNew )
			{
				// position of my data cursor is the same as the position our current row points tpo
				// sync the status, repaint, done
				DBG_ASSERT(m_xDataRow == m_xCurrentRow, "Fehler in den Datenzeilen");
				TRACE_RANGE_MESSAGE1("same position, new state : %s", ROWSTATUS(m_xCurrentRow));
				RowModified(m_nCurrentPos);
				return;
			}
		}

	// weg von der Row des DatenCursors
	if (m_xPaintRow == m_xCurrentRow)
		m_xPaintRow = m_xSeekRow;

	// keine aktuelle Zeile dann komplett anpassen
	if (!m_xCurrentRow)
		AdjustRows();

	sal_Int32 nNewPos = AlignSeekCursor();
	if (nNewPos < 0)	// keine Position gefunden
		return;

	m_bInAdjustDataSource = sal_True;
	if (nNewPos != m_nCurrentPos)
	{
		if (m_bSynchDisplay)
			DbGridControl_Base::GoToRow(nNewPos);

		if (!m_xCurrentRow.Is())
			// das tritt zum Beispiel auf, wenn man die n (n>1) letzten Datensaetze geloescht hat, waehrend der Cursor auf dem letzten
			// steht : AdjustRows entfernt dann zwei Zeilen aus der BrowseBox, wodurch diese ihre CurrentRow um zwei nach unten
			// korrigiert, so dass dann das GoToRow in's Leere laeuft (da wir uns ja angeblich schon an der richtigen Position
			// befinden)
			SetCurrent(nNewPos);
	}
	else
	{
		SetCurrent(nNewPos);
		RowModified(nNewPos);
	}
	m_bInAdjustDataSource = sal_False;

	// Wird der DatenCursor von aussen bewegt, wird die selektion aufgehoben
	SetNoSelection();
	m_aBar.InvalidateAll(m_nCurrentPos, m_xCurrentRow.Is());
}

//------------------------------------------------------------------------------
sal_Int32 DbGridControl::AlignSeekCursor()
{
	DBG_CHKTHIS( DbGridControl, NULL );
	// Positioniert den SeekCursor auf den DatenCursor, Daten werden nicht uebertragen

	if (!m_pSeekCursor)
		return -1;

	Reference< XPropertySet > xSet = m_pDataCursor->getPropertySet();

	// jetzt den seekcursor an den DatenCursor angleichen
	if (::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW)))
		m_nSeekPos = GetRowCount() - 1;
	else
	{
		try
		{
			if ( m_pDataCursor->isBeforeFirst() )
			{
				// this is somewhat strange, but can nevertheless happen
				DBG_WARNING( "DbGridControl::AlignSeekCursor: nobody should tamper with my cursor this way (before first)!" );
				m_pSeekCursor->first();
				m_pSeekCursor->previous();
				m_nSeekPos = -1;
			}
			else if ( m_pDataCursor->isAfterLast() )
			{
				DBG_WARNING( "DbGridControl::AlignSeekCursor: nobody should tamper with my cursor this way (after last)!" );
				m_pSeekCursor->last();
				m_pSeekCursor->next();
				m_nSeekPos = -1;
			}
			else
			{
				m_pSeekCursor->moveToBookmark(m_pDataCursor->getBookmark());
				if (!CompareBookmark(m_pDataCursor->getBookmark(), m_pSeekCursor->getBookmark()))
					// dummerweise kann das moveToBookmark indirekt dazu fuehren, dass der Seek-Cursor wieder neu positoniert wird (wenn
					// naemlich das mit all seinen zu feuernden Events relativ komplexe moveToBookmark irgendwo ein Update ausloest),
					// also muss ich es nochmal versuchen
					m_pSeekCursor->moveToBookmark(m_pDataCursor->getBookmark());
					// Nicht dass das jetzt nicht auch schief gegangen sein koennte, aber es ist zumindest unwahrscheinlicher geworden.
					// Und die Alternative waere eine Schleife so lange bis es stimmt, und das kann auch nicht die Loesung sein
				m_nSeekPos = m_pSeekCursor->getRow() - 1;
			}
		}
		catch(Exception&)
		{
		}
	}
	return m_nSeekPos;
}
//------------------------------------------------------------------------------
sal_Bool DbGridControl::SeekCursor(long nRow, sal_Bool bAbsolute)
{
	DBG_CHKTHIS( DbGridControl, NULL );
	// Positioniert den SeekCursor, Daten werden nicht uebertragen

	// additions for the filtermode
	if (IsFilterRow(nRow))
	{
		m_nSeekPos = 0;
		return sal_True;
	}

	if (!m_pSeekCursor)
		return sal_False;

	// Befinden wir uns gerade beim Einfuegen
	if (IsValid(m_xCurrentRow) && m_xCurrentRow->IsNew() &&
		nRow >= m_nCurrentPos)
	{
		// dann darf auf alle Faelle nicht weiter nach unten gescrollt werden
		// da der letzte Datensatz bereits erreicht wurde!
		if (nRow == m_nCurrentPos)
		{
			// auf die aktuelle Zeile bewegt, dann muß kein abgleich gemacht werden, wenn
			// gerade ein Datensatz eingefuegt wird
			m_nSeekPos = nRow;
		}
		else if (IsInsertionRow(nRow))	// Leerzeile zum Einfuegen von Datensaetzen
			m_nSeekPos = nRow;
	}
	else if (IsInsertionRow(nRow))	// Leerzeile zum Einfuegen von Datensaetzen
		m_nSeekPos = nRow;
	else if ((-1 == nRow) && (GetRowCount() == ((m_nOptions & OPT_INSERT) ? 1 : 0)) && m_pSeekCursor->isAfterLast())
		m_nSeekPos = nRow;
	else
	{

		sal_Bool bSuccess=sal_False;
		long nSteps = 0;
		try
		{
            if ( m_pSeekCursor->rowDeleted() )
            {
                // somebody deleted the current row of the seek cursor. Move it away from this row.
                m_pSeekCursor->next();
                if ( m_pSeekCursor->isAfterLast() || m_pSeekCursor->isBeforeFirst() )
			        bAbsolute = sal_True;
            }

    		if ( !bAbsolute )
            {
                DBG_ASSERT( !m_pSeekCursor->isAfterLast() && !m_pSeekCursor->isBeforeFirst(),
                    "DbGridControl::SeekCursor: how did the seek cursor get to this position?!" );
			    nSteps = nRow - (m_pSeekCursor->getRow() - 1);
			    bAbsolute = bAbsolute || (abs(nSteps) > 100);
            }

            if ( bAbsolute )
			{
                bSuccess = m_pSeekCursor->absolute(nRow + 1);
				if (bSuccess)
					m_nSeekPos = nRow;
			}
            else
            {
                if (nSteps > 0) 								// auf den letzten benoetigten Datensatz positionieren
				{
					if (m_pSeekCursor->isAfterLast())
						bSuccess = sal_False;
					else if (m_pSeekCursor->isBeforeFirst())
						bSuccess = m_pSeekCursor->absolute(nSteps);
					else
						bSuccess = m_pSeekCursor->relative(nSteps);
				}
				else if (nSteps < 0)
				{
					if (m_pSeekCursor->isBeforeFirst())
						bSuccess = sal_False;
					else if (m_pSeekCursor->isAfterLast())
						bSuccess = m_pSeekCursor->absolute(nSteps);
					else
						bSuccess = m_pSeekCursor->relative(nSteps);
				}
				else
				{
					m_nSeekPos = nRow;
					return sal_True;
				}
			}
		}
		catch(Exception&)
		{
			DBG_ERROR("DbGridControl::SeekCursor : failed ...");
		}

		try
		{
			if (!bSuccess)
			{
				if (bAbsolute || nSteps > 0)
					bSuccess = m_pSeekCursor->last();
				else
					bSuccess = m_pSeekCursor->first();
			}

			if (bSuccess)
				m_nSeekPos = m_pSeekCursor->getRow() - 1;
			else
				m_nSeekPos = -1;
		}
		catch(Exception&)
		{
			DBG_ERROR("DbGridControl::SeekCursor : failed ...");
			m_nSeekPos = -1;						// kein Datensatz mehr vorhanden
		}
	}
	return m_nSeekPos == nRow;
}
//------------------------------------------------------------------------------
void DbGridControl::MoveToFirst()
{
	if (m_pSeekCursor && (GetCurRow() != 0))
		MoveToPosition(0);
}

//------------------------------------------------------------------------------
void DbGridControl::MoveToLast()
{
	if (!m_pSeekCursor)
		return;

	if (m_nTotalCount < 0)			// RecordCount steht noch nicht fest
	{
		try
		{
			sal_Bool bRes = m_pSeekCursor->last();

			if (bRes)
			{
				m_nSeekPos = m_pSeekCursor->getRow() - 1;
				AdjustRows();
			}
		}
		catch(Exception&)
		{
		}
	}

	// auf den letzen Datensatz positionieren, nicht auf die Leerzeile
	if (m_nOptions & OPT_INSERT)
	{
		if ((GetRowCount() - 1) > 0)
			MoveToPosition(GetRowCount() - 2);
	}
	else if (GetRowCount())
		MoveToPosition(GetRowCount() - 1);
}

//------------------------------------------------------------------------------
void DbGridControl::MoveToPrev()
{
	long nNewRow = std::max(GetCurRow() - 1L, 0L);
	if (GetCurRow() != nNewRow)
		MoveToPosition(nNewRow);
}

//------------------------------------------------------------------------------
void DbGridControl::MoveToNext()
{
	if (!m_pSeekCursor)
		return;

	if (m_nTotalCount > 0)
	{
		// move the data cursor to the right position
		long nNewRow = std::min(GetRowCount() - 1, GetCurRow() + 1);
		if (GetCurRow() != nNewRow)
			MoveToPosition(nNewRow);
	}
	else
	{
		sal_Bool bOk = sal_False;
		try
		{
			// try to move to next row
			// when not possible our paint cursor is already on the last row
			// then we must be sure that the data cursor is on the position
			// we call ourself again
            bOk = m_pSeekCursor->next();
			if (bOk)
			{
				m_nSeekPos = m_pSeekCursor->getRow() - 1;
				MoveToPosition(GetCurRow() + 1);
			}
		}
		catch(SQLException &)
		{
            DBG_UNHANDLED_EXCEPTION();
		}

		if(!bOk)
		{
			AdjustRows();
			if (m_nTotalCount > 0) // only to avoid infinte recursion
				MoveToNext();
		}
	}
}

//------------------------------------------------------------------------------
void DbGridControl::MoveToPosition(sal_uInt32 nPos)
{
	if (!m_pSeekCursor)
		return;

    if (m_nTotalCount < 0 && (long)nPos >= GetRowCount())
    {
        try
        {
            if (!m_pSeekCursor->absolute(nPos + 1))
            {
                AdjustRows();
                Sound::Beep();
                return;
            }
            else
            {
                m_nSeekPos = m_pSeekCursor->getRow() - 1;
                AdjustRows();
            }
        }
        catch(Exception&)
        {
            return;
        }
    }
    DbGridControl_Base::GoToRow(nPos);
    m_aBar.InvalidateAll(m_nCurrentPos);
}

//------------------------------------------------------------------------------
void DbGridControl::AppendNew()
{
	if (!m_pSeekCursor || !(m_nOptions & OPT_INSERT))
		return;

	if (m_nTotalCount < 0)			// RecordCount steht noch nicht fest
	{
		try
		{
			sal_Bool bRes = m_pSeekCursor->last();

			if (bRes)
			{
				m_nSeekPos = m_pSeekCursor->getRow() - 1;
				AdjustRows();
			}
		}
		catch(Exception&)
		{
			return;
		}
	}

	long nNewRow = m_nTotalCount + 1;
	if (nNewRow > 0 && GetCurRow() != nNewRow)
		MoveToPosition(nNewRow - 1);
}

//------------------------------------------------------------------------------
void DbGridControl::SetDesignMode(sal_Bool bMode)
{
	if (IsDesignMode() != bMode)
	{
		// Enable/Disable f�r den Designmode anpassen damit die Headerbar konfigurierbar bleibt
		if (bMode)
		{
			if (!IsEnabled())
			{
				Enable();
				GetDataWindow().Disable();
			}
		}
		else
		{
			// komplett disablen
			if (!GetDataWindow().IsEnabled())
				Disable();
		}

		m_bDesignMode = bMode;
		GetDataWindow().SetMouseTransparent(bMode);
		SetMouseTransparent(bMode);

		m_aBar.InvalidateAll(m_nCurrentPos, sal_True);
	}
}

//------------------------------------------------------------------------------
void DbGridControl::SetFilterMode(sal_Bool bMode)
{
	if (IsFilterMode() != bMode)
	{
		m_bFilterMode = bMode;

		if (bMode)
		{
			SetUpdateMode(sal_False);

			// es gibt kein Cursor mehr
			if (IsEditing())
				DeactivateCell();
			RemoveRows(sal_False);

			m_xEmptyRow = new DbGridRow();

			// setting the new filter controls
			for (sal_uInt16 i = 0; i<m_aColumns.Count(); ++i)
			{
				DbGridColumn* pCurCol = m_aColumns.GetObject(i);
				if (!pCurCol->IsHidden())
					pCurCol->UpdateControl();
			}

			// one row for filtering
			RowInserted(0, 1, sal_True);
			SetUpdateMode(sal_True);
		}
		else
			setDataSource(Reference< XRowSet > ());
	}
}
// -----------------------------------------------------------------------------
String DbGridControl::GetCellText(long _nRow, sal_uInt16 _nColId) const
{
	DbGridColumn* pColumn = m_aColumns.GetObject( GetModelColumnPos( _nColId ) );
	String sRet;
	if ( const_cast<DbGridControl*>(this)->SeekRow(_nRow) )
		sRet = GetCurrentRowCellText(pColumn, m_xPaintRow);
	return sRet;
}
//------------------------------------------------------------------------------
XubString DbGridControl::GetCurrentRowCellText(DbGridColumn* pColumn,const DbGridRowRef& _rRow) const
{
	// Ausgabe des Textes fuer eine Zelle
	XubString aText;
	if ( pColumn && IsValid(m_xPaintRow) )
		aText = pColumn->GetCellText(_rRow, m_xFormatter);
	return aText;
}

//------------------------------------------------------------------------------
sal_uInt32 DbGridControl::GetTotalCellWidth(long nRow, sal_uInt16 nColId)
{
	if (SeekRow(nRow))
	{
		DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColId));
		return GetDataWindow().GetTextWidth(GetCurrentRowCellText(pColumn,m_xPaintRow));
	}
	else
		return 30;	//xxxx
}

//------------------------------------------------------------------------------
void DbGridControl::PreExecuteRowContextMenu(sal_uInt16 /*nRow*/, PopupMenu& rMenu)
{
	sal_Bool bDelete = (m_nOptions & OPT_DELETE) && GetSelectRowCount() && !IsCurrentAppending();
	// ist nur die Leerzeile selektiert, dann nicht loeschen
	bDelete = bDelete && !((m_nOptions & OPT_INSERT) && GetSelectRowCount() == 1 && IsRowSelected(GetRowCount() - 1));

	rMenu.EnableItem(SID_FM_DELETEROWS, bDelete);
	rMenu.EnableItem(SID_FM_RECORD_SAVE, IsModified());

	// the undo is more difficult
	sal_Bool bCanUndo = IsModified();
	long nState = -1;
	if (m_aMasterStateProvider.IsSet())
		nState = m_aMasterStateProvider.Call((void*)SID_FM_RECORD_UNDO);
	bCanUndo &= ( 0 != nState );

	rMenu.EnableItem(SID_FM_RECORD_UNDO, bCanUndo);
}

//------------------------------------------------------------------------------
void DbGridControl::PostExecuteRowContextMenu(sal_uInt16 /*nRow*/, const PopupMenu& /*rMenu*/, sal_uInt16 nExecutionResult)
{
	switch (nExecutionResult)
	{
		case SID_FM_DELETEROWS:
			// delete asynchron
			if (m_nDeleteEvent)
				Application::RemoveUserEvent(m_nDeleteEvent);
			m_nDeleteEvent = Application::PostUserEvent(LINK(this,DbGridControl,OnDelete));
			break;
		case SID_FM_RECORD_UNDO:
			Undo();
			break;
		case SID_FM_RECORD_SAVE:
			SaveRow();
			break;
		default:
			break;
	}
}

//------------------------------------------------------------------------------
void DbGridControl::DataSourcePropertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException )
{
	TRACE_RANGE("DbGridControl::DataSourcePropertyChanged");
	::vos::OGuard aGuard( Application::GetSolarMutex() );
	// prop "IsModified" changed ?
	// during update don't care about the modified state
	if (!IsUpdating() && evt.PropertyName.compareTo(FM_PROP_ISMODIFIED) == COMPARE_EQUAL)
	{
		Reference< XPropertySet > xSource(evt.Source, UNO_QUERY);
		DBG_ASSERT( xSource.is(), "DbGridControl::DataSourcePropertyChanged: invalid event source!" );
		sal_Bool bIsNew = sal_False;
		if (xSource.is())
			bIsNew = ::comphelper::getBOOL(xSource->getPropertyValue(FM_PROP_ISNEW));

		if (bIsNew && m_xCurrentRow.Is())
		{
			DBG_ASSERT(::comphelper::getBOOL(xSource->getPropertyValue(FM_PROP_ROWCOUNTFINAL)), "DbGridControl::DataSourcePropertyChanged : somebody moved the form to a new record before the row count was final !");
			sal_Int32 nRecordCount = 0;
			xSource->getPropertyValue(FM_PROP_ROWCOUNT) >>= nRecordCount;
			if (::comphelper::getBOOL(evt.NewValue))
			{	// modified state changed from sal_False to sal_True and we're on a insert row
				// -> we've to add a new grid row
				if ((nRecordCount == GetRowCount() - 1)  && m_xCurrentRow->IsNew())
				{
					RowInserted(GetRowCount(), 1, sal_True);
					InvalidateStatusCell(m_nCurrentPos);
					m_aBar.InvalidateAll(m_nCurrentPos);
				}
			}
			else
			{	// modified state changed from sal_True to sal_False and we're on a insert row
				// we have two "new row"s at the moment : the one we're editing currently (where the current
				// column is the only dirty element) and a "new new" row which is completely clean. As the first
				// one is about to be cleaned, too, the second one is obsolet now.
				if (m_xCurrentRow->IsNew() && nRecordCount == (GetRowCount() - 2))
				{
					RowRemoved(GetRowCount() - 1, 1, sal_True);
					InvalidateStatusCell(m_nCurrentPos);
					m_aBar.InvalidateAll(m_nCurrentPos);
				}
			}
		}
		if (m_xCurrentRow.Is())
		{
			m_xCurrentRow->SetStatus(::comphelper::getBOOL(evt.NewValue) ? GRS_MODIFIED : GRS_CLEAN);
			m_xCurrentRow->SetNew( bIsNew );
			InvalidateStatusCell(m_nCurrentPos);
			TRACE_RANGE_MESSAGE1("modified flag changed, new state : %s", ROWSTATUS(m_xCurrentRow));
		}
	}
}

//------------------------------------------------------------------------------
void DbGridControl::StartDrag( sal_Int8 /*nAction*/, const Point& rPosPixel )
{
	if (!m_pSeekCursor || IsResizing())
		return;

	sal_uInt16 nColId = GetColumnAtXPosPixel(rPosPixel.X());
	long   nRow = GetRowAtYPosPixel(rPosPixel.Y());
	if (nColId != HANDLE_ID && nRow >= 0)
	{
		if (GetDataWindow().IsMouseCaptured())
			GetDataWindow().ReleaseMouse();

		DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColId));
		OStringTransferable* pTransferable = new OStringTransferable(GetCurrentRowCellText(pColumn,m_xPaintRow));
		Reference< XTransferable > xEnsureDelete(pTransferable);
		pTransferable->StartDrag(this, DND_ACTION_COPY);
	}
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::canCopyCellText(sal_Int32 _nRow, sal_Int16 _nColId)
{
	return	(_nRow >= 0)
		&&	(_nRow < GetRowCount())
		&&	(_nColId > HANDLE_ID)
		&&	(_nColId <= ColCount());
}

//------------------------------------------------------------------------------
void DbGridControl::copyCellText(sal_Int32 _nRow, sal_Int16 _nColId)
{
	DBG_ASSERT(canCopyCellText(_nRow, _nColId), "DbGridControl::copyCellText: invalid call!");
	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(_nColId));
	SeekRow(_nRow);
	OStringTransfer::CopyString( GetCurrentRowCellText( pColumn,m_xPaintRow ), this );
}

//------------------------------------------------------------------------------
void DbGridControl::executeRowContextMenu( long _nRow, const Point& _rPreferredPos )
{
	PopupMenu aContextMenu( SVX_RES( RID_SVXMNU_ROWS ) );

	PreExecuteRowContextMenu( (sal_uInt16)_nRow, aContextMenu );
	aContextMenu.RemoveDisabledEntries( sal_True, sal_True );
	PostExecuteRowContextMenu( (sal_uInt16)_nRow, aContextMenu, aContextMenu.Execute( this, _rPreferredPos ) );

	// TODO: why this weird cast to sal_uInt16? What if we really have more than 65535 lines?
	// -> change this to sal_uInt32
}

//------------------------------------------------------------------------------
void DbGridControl::Command(const CommandEvent& rEvt)
{
	switch (rEvt.GetCommand())
	{
		case COMMAND_CONTEXTMENU:
		{
			if ( !m_pSeekCursor )
			{
				DbGridControl_Base::Command(rEvt);
				return;
			}

			if ( !rEvt.IsMouseEvent() )
			{	// context menu requested by keyboard
				if ( GetSelectRowCount() )
				{
					long nRow = FirstSelectedRow( );

					::Rectangle aRowRect( GetRowRectPixel( nRow, sal_True ) );
					executeRowContextMenu( nRow, aRowRect.LeftCenter() );

					// handled
					return;
				}
			}

			sal_uInt16 nColId = GetColumnAtXPosPixel(rEvt.GetMousePosPixel().X());
			long   nRow = GetRowAtYPosPixel(rEvt.GetMousePosPixel().Y());

			if (nColId == HANDLE_ID)
			{
				executeRowContextMenu( nRow, rEvt.GetMousePosPixel() );
			}
			else if (canCopyCellText(nRow, nColId))
			{
				PopupMenu aContextMenu(SVX_RES(RID_SVXMNU_CELL));
				aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
				switch (aContextMenu.Execute(this, rEvt.GetMousePosPixel()))
				{
					case SID_COPY:
						copyCellText(nRow, nColId);
						break;
				}
			}
			else
			{
				DbGridControl_Base::Command(rEvt);
				return;
			}
		}
		default:
			DbGridControl_Base::Command(rEvt);
	}
}

//------------------------------------------------------------------------------
IMPL_LINK(DbGridControl, OnDelete, void*, /*EMPTYTAG*/ )
{
	DBG_CHKTHIS(DbGridControl, NULL );
	m_nDeleteEvent = 0;
	DeleteSelectedRows();
	return 0;
}

//------------------------------------------------------------------------------
void DbGridControl::DeleteSelectedRows()
{
	DBG_ASSERT(GetSelection(), "keine selection!!!");

	if (!m_pSeekCursor)
		return;

/*	Application::EnterWait();
	Reference< XPropertySet >  xSet = (XPropertySet*)xSeekCursor->queryInterface(XPropertySet::getSmartUik());

	// wenn mehr als 25 Datensaetze geloescht werden, wird der Cache abgeschaltet
	// da das loeschen ansonsten zu langsam wird
	sal_uInt16 nCacheSize = 0;
	if (GetSelectRowCount() > 25)
	{
		// CacheSize merken und Cache zuruecksetzen
		nCacheSize = xSet->getPropertyValue(L"CacheSize").getUINT16();
		if (nCacheSize)
			xSet->setPropertyValue(L"CacheSize", Any(sal_uInt16(0)));
	} */


	/*
	// mu� der Cache wiederhergestellt werden?
	if (nCacheSize)
	{
		// Cache wieder einschalten
		xSet->setPropertyValue(L"CacheSize", Any(sal_uInt16(nCacheSize)));

		// Browser neu einstellen
		RecalcRows(GetTopRow(), GetVisibleRows(), sal_True);

		// aktuelle Zeile aktualisieren
		SeekCursor(GetCurRow());
		if (IsAppendRow(m_nSeekPos))
			xDataCursor->addRecord();
		else
		{
			Any aBookmark = xSeekCursor->getBookmark();
			xDataCursor->moveToBookmark(aBookmark);
		}
		m_xCurrentRow = new DbGridRow(xDataCursor);
		m_nCurrentPos = m_nSeekPos;

		// complett invalidieren
		Invalidate();
	}
	else
		// Browser neu einstellen
		RecalcRows(GetTopRow(), GetVisibleRows(), sal_True);

	// gibt es keine Selection mehr?
	if (!GetSelectRowCount())
		ActivateCell();

	m_aBar.InvalidateAll();
	Application::LeaveWait();

	m_bUpdating = sal_False;
*/
}

//------------------------------------------------------------------------------
CellController* DbGridControl::GetController(long /*nRow*/, sal_uInt16 nColumnId)
{
	if (!IsValid(m_xCurrentRow) || !IsEnabled())
		return NULL;

	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColumnId));
	if (!pColumn)
		return NULL;

	CellController* pReturn = NULL;
	if (IsFilterMode())
		pReturn = &pColumn->GetController();
	else
	{
		if (::comphelper::hasProperty(FM_PROP_ENABLED, pColumn->getModel()))
		{
			if (!::comphelper::getBOOL(pColumn->getModel()->getPropertyValue(FM_PROP_ENABLED)))
				return NULL;
		}

		sal_Bool bInsert = (m_xCurrentRow->IsNew() && (m_nOptions & OPT_INSERT));
		sal_Bool bUpdate = (!m_xCurrentRow->IsNew() && (m_nOptions & OPT_UPDATE));

		if ((bInsert && !pColumn->IsAutoValue()) || bUpdate || m_bForceROController)
		{
			pReturn = &pColumn->GetController();
			if (pReturn)
			{
				// wenn es eine Edit-Zeile ist, kann ich ihr das forced read-only mitgeben
				if (!pReturn->ISA(EditCellController) && !pReturn->ISA(SpinCellController))
					// ich konnte den Controller in forceROController nicht auf ReadOnly setzen
					if (!bInsert && !bUpdate)
						// ich bin nur hier, da m_bForceROController gesetzt war
						// -> lieber kein Controller als einer ohne RO
						pReturn = NULL;
			}
		}
	}
	return pReturn;
}

//------------------------------------------------------------------------------
void DbGridControl::InitController(CellControllerRef& /*rController*/, long /*nRow*/, sal_uInt16 nColumnId)
{
	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColumnId));
	if (pColumn)
		pColumn->UpdateFromField(m_xCurrentRow, m_xFormatter);
}

//------------------------------------------------------------------------------
void DbGridControl::CellModified()
{
	TRACE_RANGE("DbGridControl::CellModified");

	{
		::osl::MutexGuard aGuard(m_aAdjustSafety);
		if (m_nAsynAdjustEvent)
		{
			TRACE_RANGE_MESSAGE1("forcing a synchron call to ", m_bPendingAdjustRows ? "AdjustRows" : "AdustDataSource");
			RemoveUserEvent(m_nAsynAdjustEvent);
			m_nAsynAdjustEvent = 0;

			// force the call : this should be no problem as we're probably running in the solar thread here
			// (cell modified is triggered by user actions)
			if (m_bPendingAdjustRows)
				AdjustRows();
			else
				AdjustDataSource();
		}
	}

	if (!IsFilterMode() && IsValid(m_xCurrentRow) && !m_xCurrentRow->IsModified())
	{
		// Einschalten des Editiermodus
		// Datensatz soll eingefuegt werden
		if (m_xCurrentRow->IsNew())
		{
			m_xCurrentRow->SetStatus(GRS_MODIFIED);
			TRACE_RANGE_MESSAGE("current row is new, new state : MODIFIED");
			// wenn noch keine Zeile hinzugefuegt wurde, dann neue hinzunehmen
			if (m_nCurrentPos == GetRowCount() - 1)
			{
				// RowCount um einen erhoehen
				RowInserted(GetRowCount(), 1, sal_True);
				InvalidateStatusCell(m_nCurrentPos);
				m_aBar.InvalidateAll(m_nCurrentPos);
			}
		}
		else if (m_xCurrentRow->GetStatus() != GRS_MODIFIED)
		{
			m_xCurrentRow->SetState(m_pDataCursor, sal_False);
			TRACE_RANGE_MESSAGE1("current row is not new, after SetState, new state : %s", ROWSTATUS(m_xCurrentRow));
			m_xCurrentRow->SetStatus(GRS_MODIFIED);
			TRACE_RANGE_MESSAGE("current row is not new, new state : MODIFIED");
			InvalidateStatusCell(m_nCurrentPos);
		}
	}
}

//------------------------------------------------------------------------------
void DbGridControl::Dispatch(sal_uInt16 nId)
{
	if (nId == BROWSER_CURSORENDOFFILE)
	{
		if (m_nOptions & OPT_INSERT)
			AppendNew();
		else
			MoveToLast();
	}
	else
		DbGridControl_Base::Dispatch(nId);
}

//------------------------------------------------------------------------------
void DbGridControl::Undo()
{
	if (!IsFilterMode() && IsValid(m_xCurrentRow) && IsModified())
	{
		// check if we have somebody doin' the UNDO for us
		long nState = -1;
		if (m_aMasterStateProvider.IsSet())
			nState = m_aMasterStateProvider.Call((void*)SID_FM_RECORD_UNDO);
		if (nState>0)
		{	// yes, we have, and the slot is enabled
			DBG_ASSERT(m_aMasterSlotExecutor.IsSet(), "DbGridControl::Undo : a state, but no execute link ?");
			long lResult = m_aMasterSlotExecutor.Call((void*)SID_FM_RECORD_UNDO);
			if (lResult)
				// handled
				return;
		}
		else if (nState == 0)
			// yes, we have, and the slot is disabled
			return;

		BeginCursorAction();

		sal_Bool bAppending = m_xCurrentRow->IsNew();
		sal_Bool bDirty 	= m_xCurrentRow->IsModified();

		try
		{
			// Editieren abbrechen
			Reference< XResultSetUpdate >  xUpdateCursor((Reference< XInterface >)*m_pDataCursor, UNO_QUERY);
			// no effects if we're not updating currently
			if (bAppending)
				// just refresh the row
				xUpdateCursor->moveToInsertRow();
			else
				xUpdateCursor->cancelRowUpdates();

		}
		catch(Exception&)
		{
            DBG_UNHANDLED_EXCEPTION();
		}

		EndCursorAction();

		m_xDataRow->SetState(m_pDataCursor, sal_False);
		if (&m_xPaintRow == &m_xCurrentRow)
			m_xPaintRow = m_xCurrentRow = m_xDataRow;
		else
			m_xCurrentRow = m_xDataRow;

		if (bAppending && (DbGridControl_Base::IsModified() || bDirty))
		// remove the row
			if (m_nCurrentPos == GetRowCount() - 2)
			{	// maybe we already removed it (in resetCurrentRow, called if the above moveToInsertRow
				// caused our data source form to be reset - which should be the usual case ....)
				RowRemoved(GetRowCount() - 1, 1, sal_True);
				m_aBar.InvalidateAll(m_nCurrentPos);
			}

		RowModified(m_nCurrentPos);
	}
}

//------------------------------------------------------------------------------
void DbGridControl::resetCurrentRow()
{
	if (IsModified())
	{
		// scenario : we're on the insert row, the row is dirty, and thus there exists a "second" insert row (which
		// is clean). Normally in DataSourcePropertyChanged we would remove this second row if the modified state of
		// the insert row changes from sal_True to sal_False. But if our current cell is the only modified element (means the
		// data source isn't modified) and we're reset this DataSourcePropertyChanged would never be called, so we
		// would never delete the obsolet "second insert row". Thus in this special case this method here
		// is the only possibility to determine the redundance of the row (resetCurrentRow is called when the
		// "first insert row" is about to be cleaned, so of course the "second insert row" is redundant now)
		Reference< XPropertySet > xDataSource = getDataSource()->getPropertySet();
		if (xDataSource.is() && !::comphelper::getBOOL(xDataSource->getPropertyValue(FM_PROP_ISMODIFIED)))
		{
			// are we on a new row currently ?
			if (m_xCurrentRow->IsNew())
			{
				if (m_nCurrentPos == GetRowCount() - 2)
				{
					RowRemoved(GetRowCount() - 1, 1, sal_True);
					m_aBar.InvalidateAll(m_nCurrentPos);
				}
			}
		}

		// update the rows
		m_xDataRow->SetState(m_pDataCursor, sal_False);
		if (&m_xPaintRow == &m_xCurrentRow)
			m_xPaintRow = m_xCurrentRow = m_xDataRow;
		else
			m_xCurrentRow = m_xDataRow;
	}

	RowModified(GetCurRow());		// will update the current controller if affected
}

//------------------------------------------------------------------------------
void DbGridControl::RowModified( long nRow, sal_uInt16 /*nColId*/ )
{
	if (nRow == m_nCurrentPos && IsEditing())
	{
		CellControllerRef aTmpRef = Controller();
		aTmpRef->ClearModified();
		InitController(aTmpRef, m_nCurrentPos, GetCurColumnId());
	}
	DbGridControl_Base::RowModified(nRow);
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::IsModified() const
{
	return !IsFilterMode() && IsValid(m_xCurrentRow) && (m_xCurrentRow->IsModified() || DbGridControl_Base::IsModified());
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::IsCurrentAppending() const
{
	return m_xCurrentRow.Is() && m_xCurrentRow->IsNew();
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::IsInsertionRow(long nRow) const
{
	return (m_nOptions & OPT_INSERT) && m_nTotalCount >= 0 && (nRow == GetRowCount() - 1);
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::SaveModified()
{
	TRACE_RANGE("DbGridControl::SaveModified");
	DBG_ASSERT(IsValid(m_xCurrentRow), "GridControl:: Invalid row");
	if (!IsValid(m_xCurrentRow))
		return sal_True;

	// Uebernimmt die Dateneingabe fuer das Feld
	// Hat es aenderungen im aktuellen Eingabefeld gegeben ?
	if (!DbGridControl_Base::IsModified())
		return sal_True;

	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(GetCurColumnId()));
	sal_Bool bOK = pColumn->Commit();
	DBG_ASSERT( Controller().Is(), "DbGridControl::SaveModified: was modified, by have no controller?!" );
    if ( !Controller().Is() )
        // this might happen if the callbacks implicitly triggered by Commit
        // fiddled with the form or the control ...
        // (Note that this here is a workaround, at most. We need a general concept how
        // to treat this, you can imagine an arbitrary number of scenarios where a callback
        // triggers something which leaves us in an expected state.)
        // #i67147# / 2006-07-17 / frank.schoenheit@sun.com
        return bOK;

	if (bOK)
	{
		Controller()->ClearModified();

		if ( IsValid(m_xCurrentRow) )
		{
			m_xCurrentRow->SetState(m_pDataCursor, sal_False);
			TRACE_RANGE_MESSAGE1("explicit SetState, new state : %s", ROWSTATUS(m_xCurrentRow));
			InvalidateStatusCell( m_nCurrentPos );
		}
#ifdef DBG_UTIL
		else
		{
			TRACE_RANGE_MESSAGE1("no SetState, new state : %s", ROWSTATUS(m_xCurrentRow));
		}
#endif
	}
	else
	{
		// reset the modified flag ....
		Controller()->SetModified();
	}

	return bOK;
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::SaveRow()
{
	TRACE_RANGE("DbGridControl::SaveRow");
	// gueltige Zeile
	if (!IsValid(m_xCurrentRow) || !IsModified())
		return sal_True;
	// Wert des Controllers noch nicht gespeichert
	else if (Controller().Is() && Controller()->IsModified())
	{
		if (!SaveModified())
			return sal_False;
	}
	m_bUpdating = sal_True;

	BeginCursorAction();
	sal_Bool bAppending = m_xCurrentRow->IsNew();
	sal_Bool bSuccess = sal_False;
	try
	{
		Reference< XResultSetUpdate >  xUpdateCursor((Reference< XInterface >)*m_pDataCursor, UNO_QUERY);
		if (bAppending)
			xUpdateCursor->insertRow();
		else
			xUpdateCursor->updateRow();
		bSuccess = sal_True;
	}
	catch(SQLException& e)
	{
		(void)e; // make compiler happy
		EndCursorAction();
		m_bUpdating = sal_False;
		return sal_False;
	}

	try
	{
		if (bSuccess)
		{
			// if we are appending we still sit on the insert row
			// we don't move just clear the flags not to move on the current row
			m_xCurrentRow->SetState(m_pDataCursor, sal_False);
			TRACE_RANGE_MESSAGE1("explicit SetState after a successfull update, new state : %s", ROWSTATUS(m_xCurrentRow));
			m_xCurrentRow->SetNew(sal_False);

			// adjust the seekcursor if it is on the same position as the datacursor
			if (m_nSeekPos == m_nCurrentPos || bAppending)
			{
				// get the bookmark to refetch the data
				// in insert mode we take the new bookmark of the data cursor
				Any aBookmark = bAppending ? m_pDataCursor->getBookmark() : m_pSeekCursor->getBookmark();
				m_pSeekCursor->moveToBookmark(aBookmark);
				// get the data
				m_xSeekRow->SetState(m_pSeekCursor, sal_True);
				m_nSeekPos = m_pSeekCursor->getRow() - 1;
			}
		}
		// and repaint the row
		RowModified(m_nCurrentPos);
	}
	catch(Exception&)
	{
	}

	m_bUpdating = sal_False;
	EndCursorAction();

	// The old code returned (nRecords != 0) here.
	// Me thinks this is wrong : If something goes wrong while update the record, an exception will be thrown,
	// which results in a "return sal_False" (see above). If no exception is thrown, everything is fine. If nRecords
	// is zero, this simply means all fields had their original values.
	// FS - 06.12.99 - 70502
	return sal_True;
}

//------------------------------------------------------------------------------
long DbGridControl::PreNotify(NotifyEvent& rEvt)
{
	// keine Events der Navbar behandeln
	if (m_aBar.IsWindowOrChild(rEvt.GetWindow()))
		return BrowseBox::PreNotify(rEvt);

	switch (rEvt.GetType())
	{
		case EVENT_KEYINPUT:
		{
			const KeyEvent* pKeyEvent = rEvt.GetKeyEvent();

			sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode();
			sal_Bool   bShift = pKeyEvent->GetKeyCode().IsShift();
			sal_Bool   bCtrl = pKeyEvent->GetKeyCode().IsMod1();
			sal_Bool   bAlt = pKeyEvent->GetKeyCode().IsMod2();
			if ( ( KEY_TAB == nCode ) && bCtrl && !bAlt )
			{
				// Ctrl-Tab is used to step out of the control, without traveling to the
				// remaining cells first
				// -> build a new key event without the Ctrl-key, and let the very base class handle it
				KeyCode aNewCode( KEY_TAB, bShift, sal_False, sal_False, sal_False );
				KeyEvent aNewEvent( pKeyEvent->GetCharCode(), aNewCode );

				// call the Control - our direct base class will interpret this in a way we do not want (and do
				// a cell traveling)
				Control::KeyInput( aNewEvent );
				return 1;
			}

			if ( !bShift && !bCtrl && ( KEY_ESCAPE == nCode ) )
			{
				if (IsModified())
				{
					Undo();
					return 1;
				}
			}
			else if ( ( KEY_DELETE == nCode ) && !bShift && !bCtrl )	// delete rows
			{
				if ((m_nOptions & OPT_DELETE) && GetSelectRowCount())
				{
					// delete asynchron
					if (m_nDeleteEvent)
						Application::RemoveUserEvent(m_nDeleteEvent);
					m_nDeleteEvent = Application::PostUserEvent(LINK(this,DbGridControl,OnDelete));
					return 1;
				}
			}
		}	// kein break!
		default:
			return DbGridControl_Base::PreNotify(rEvt);
	}
}

//------------------------------------------------------------------------------
sal_Bool DbGridControl::IsTabAllowed(sal_Bool bRight) const
{
	if (bRight)
		// Tab nur wenn nicht auf der letzten Zelle
		return GetCurRow() < (GetRowCount() - 1) || !m_bRecordCountFinal ||
			   GetViewColumnPos(GetCurColumnId()) < (GetViewColCount() - 1);
	else
	{
		// Tab nur wenn nicht auf der ersten Zelle
		return GetCurRow() > 0 || (GetCurColumnId() && GetViewColumnPos(GetCurColumnId()) > 0);
	}
}

//------------------------------------------------------------------------------
void DbGridControl::KeyInput( const KeyEvent& rEvt )
{
	if (rEvt.GetKeyCode().GetFunction() == KEYFUNC_COPY)
	{
		long nRow = GetCurRow();
		sal_uInt16 nColId = GetCurColumnId();
		if (nRow >= 0 && nRow < GetRowCount() && nColId < ColCount())
		{
			DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColId));
			OStringTransfer::CopyString( GetCurrentRowCellText( pColumn,m_xPaintRow ), this );
			return;
		}
	}
	DbGridControl_Base::KeyInput(rEvt);
}

//------------------------------------------------------------------------------
void DbGridControl::HideColumn(sal_uInt16 nId)
{
	DeactivateCell();

	// determine the col for the focus to set to after removal
	sal_uInt16 nPos = GetViewColumnPos(nId);
	sal_uInt16 nNewColId = nPos == (ColCount()-1)
		? GetColumnIdFromViewPos(nPos-1)	// last col is to be removed -> take the previous
		: GetColumnIdFromViewPos(nPos+1);	// take the next

	long lCurrentWidth = GetColumnWidth(nId);
	DbGridControl_Base::RemoveColumn(nId);
		// don't use my own RemoveColumn, this would remove it from m_aColumns, too

	// update my model
	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nId));
	DBG_ASSERT(pColumn, "DbGridControl::HideColumn : somebody did hide a nonexistent column !");
	if (pColumn)
	{
		pColumn->m_bHidden = sal_True;
		pColumn->m_nLastVisibleWidth = CalcReverseZoom(lCurrentWidth);
	}

	// and reset the focus
	if ( nId == GetCurColumnId() )
		GoToColumnId( nNewColId );
}

//------------------------------------------------------------------------------
void DbGridControl::ShowColumn(sal_uInt16 nId)
{
	sal_uInt16 nPos = GetModelColumnPos(nId);
	DBG_ASSERT(nPos != (sal_uInt16)-1, "DbGridControl::ShowColumn : invalid argument !");
	if (nPos == (sal_uInt16)-1)
		return;

	DbGridColumn* pColumn = m_aColumns.GetObject(nPos);
	if (!pColumn->IsHidden())
	{
		DBG_ASSERT(GetViewColumnPos(nId) != (sal_uInt16)-1, "DbGridControl::ShowColumn : inconsistent internal state !");
			// if the column isn't marked as hidden, it should be visible, shouldn't it ?
		return;
	}
	DBG_ASSERT(GetViewColumnPos(nId) == (sal_uInt16)-1, "DbGridControl::ShowColumn : inconsistent internal state !");
		// the opposite situation ...

	// to determine the new view position we need an adjacent non-hidden column
	sal_uInt16 nNextNonHidden = (sal_uInt16)-1;
	// first search the cols to the right
	for (sal_uInt16 i = nPos + 1; i<m_aColumns.Count(); ++i)
	{
		DbGridColumn* pCurCol = m_aColumns.GetObject(i);
		if (!pCurCol->IsHidden())
		{
			nNextNonHidden = i;
			break;
		}
	}
	if ((nNextNonHidden == (sal_uInt16)-1) && (nPos > 0))
	{
		// then to the left
		for (sal_uInt16 i = nPos; i>0; --i)
		{
			DbGridColumn* pCurCol = m_aColumns.GetObject(i-1);
			if (!pCurCol->IsHidden())
			{
				nNextNonHidden = i-1;
				break;
			}
		}
	}
	sal_uInt16 nNewViewPos = (nNextNonHidden == (sal_uInt16)-1)
		? 1 // there is no visible column -> insert behinde the handle col
		: GetViewColumnPos(m_aColumns.GetObject(nNextNonHidden)->GetId()) + 1;
			// the first non-handle col has "view pos" 0, but the pos arg for InsertDataColumn expects
			// a position 1 for the first non-handle col -> +1
	DBG_ASSERT(nNewViewPos != (sal_uInt16)-1, "DbGridControl::ShowColumn : inconsistent internal state !");
		// we found a col marked as visible but got no view pos for it ...

	if ((nNextNonHidden<nPos) && (nNextNonHidden != (sal_uInt16)-1))
		// nNextNonHidden is a column to the left, so we want to insert the new col _right_ beside it's pos
		++nNewViewPos;

	DeactivateCell();

	::rtl::OUString aName;
	pColumn->getModel()->getPropertyValue(FM_PROP_LABEL) >>= aName;
	InsertDataColumn(nId, aName, CalcZoom(pColumn->m_nLastVisibleWidth), HIB_CENTER | HIB_VCENTER | HIB_CLICKABLE, nNewViewPos);
	pColumn->m_bHidden = sal_False;

	ActivateCell();
	Invalidate();
}

//------------------------------------------------------------------------------
sal_uInt16 DbGridControl::GetColumnIdFromModelPos( sal_uInt16 nPos ) const
{
	if (nPos >= m_aColumns.Count())
	{
		DBG_ERROR("DbGridControl::GetColumnIdFromModelPos : invalid argument !");
		return (sal_uInt16)-1;
	}

	DbGridColumn* pCol = m_aColumns.GetObject(nPos);
#if (OSL_DEBUG_LEVEL > 0) || defined DBG_UTIL
	// in der Debug-Version rechnen wir die ModelPos in eine ViewPos um und vergleichen das mit dem Wert,
	// den wir zurueckliefern werden (nId an der entsprechenden Col in m_aColumns)

	if (!pCol->IsHidden())
	{	// macht nur Sinn, wenn die Spalte sichtbar ist
		sal_uInt16 nViewPos = nPos;
		for (sal_uInt16 i=0; i<m_aColumns.Count() && i<nPos; ++i)
			if (m_aColumns.GetObject(i)->IsHidden())
				--nViewPos;

		DBG_ASSERT(pCol && GetColumnIdFromViewPos(nViewPos) == pCol->GetId(),
			"DbGridControl::GetColumnIdFromModelPos : this isn't consistent .... did I misunderstand something ?");
	}
#endif
	return pCol->GetId();
}

//------------------------------------------------------------------------------
sal_uInt16 DbGridControl::GetModelColumnPos( sal_uInt16 nId ) const
{
	for (sal_uInt16 i=0; i<m_aColumns.Count(); ++i)
		if (m_aColumns.GetObject(i)->GetId() == nId)
			return i;

    return GRID_COLUMN_NOT_FOUND;
}

//------------------------------------------------------------------------------
void DbGridControl::implAdjustInSolarThread(sal_Bool _bRows)
{
	TRACE_RANGE("DbGridControl::implAdjustInSolarThread");
	::osl::MutexGuard aGuard(m_aAdjustSafety);
	if (::vos::OThread::getCurrentIdentifier() != Application::GetMainThreadIdentifier())
	{
		m_nAsynAdjustEvent = PostUserEvent(LINK(this, DbGridControl, OnAsyncAdjust), reinterpret_cast< void* >( _bRows ));
		m_bPendingAdjustRows = _bRows;
#ifdef DBG_UTIL
		if (_bRows)
			TRACE_RANGE_MESSAGE("posting an AdjustRows")
		else
			TRACE_RANGE_MESSAGE("posting an AdjustDataSource")
#endif
	}
	else
	{
#ifdef DBG_UTIL
		if (_bRows)
			TRACE_RANGE_MESSAGE("doing an AdjustRows")
		else
			TRACE_RANGE_MESSAGE("doing an AdjustDataSource")
#endif
		// always adjust the rows before adjusting the data source
		// If this is not necessary (because the row count did not change), nothing is done
		// The problem is that we can't rely on the order of which the calls come in: If the cursor was moved
		// to a position behind row count know 'til now, the cursorMoved notification may come before the
		// RowCountChanged notification
		// 94093 - 02.11.2001 - frank.schoenheit@sun.com
		AdjustRows();

		if ( !_bRows )
			AdjustDataSource();
	}
}

//------------------------------------------------------------------------------
IMPL_LINK(DbGridControl, OnAsyncAdjust, void*, pAdjustWhat)
{
	m_nAsynAdjustEvent = 0;

	AdjustRows();
		// see implAdjustInSolarThread for a comment why we do this every time

	if ( !pAdjustWhat )
		AdjustDataSource();

	return 0L;
}

//------------------------------------------------------------------------------
void DbGridControl::BeginCursorAction()
{
	if (m_pFieldListeners)
	{
		ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
		ConstColumnFieldValueListenersIterator aIter = pListeners->begin();
		while (aIter != pListeners->end())
		{
			GridFieldValueListener* pCurrent = (*aIter).second;
			if (pCurrent)
				pCurrent->suspend();
			++aIter;
		}
	}

	if (m_pDataSourcePropListener)
		m_pDataSourcePropListener->suspend();
}

//------------------------------------------------------------------------------
void DbGridControl::EndCursorAction()
{
	if (m_pFieldListeners)
	{
		ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
		ConstColumnFieldValueListenersIterator aIter = pListeners->begin();
		while (aIter != pListeners->end())
		{
			GridFieldValueListener* pCurrent = (*aIter).second;
			if (pCurrent)
				pCurrent->resume();
			++aIter;
		}
	}

	if (m_pDataSourcePropListener)
		m_pDataSourcePropListener->resume();
}

//------------------------------------------------------------------------------
void DbGridControl::ConnectToFields()
{
	ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
	DBG_ASSERT(!pListeners || pListeners->size() == 0, "DbGridControl::ConnectToFields : please call DisconnectFromFields first !");

	if (!pListeners)
	{
		pListeners = new ColumnFieldValueListeners;
		m_pFieldListeners = pListeners;
	}

	for (sal_Int32 i=0; i<(sal_Int32)m_aColumns.Count(); ++i)
	{
		DbGridColumn* pCurrent = m_aColumns.GetObject(i);
		sal_uInt16 nViewPos = pCurrent ? GetViewColumnPos(pCurrent->GetId()) : (sal_uInt16)-1;
		if ((sal_uInt16)-1 == nViewPos)
			continue;

		Reference< XPropertySet >  xField = pCurrent->GetField();
		if (!xField.is())
			continue;

		// column is visible and bound here
		GridFieldValueListener*& rpListener = (*pListeners)[pCurrent->GetId()];
		DBG_ASSERT(!rpListener, "DbGridControl::ConnectToFields : already a listener for this column ?!");
		rpListener = new GridFieldValueListener(*this, xField, pCurrent->GetId());
	}
}

//------------------------------------------------------------------------------
void DbGridControl::DisconnectFromFields()
{
	if (!m_pFieldListeners)
		return;

	ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
	while (pListeners->size())
	{
#ifdef DBG_UTIL
		sal_Int32 nOldSize = pListeners->size();
#endif
		pListeners->begin()->second->dispose();
		DBG_ASSERT(nOldSize > (sal_Int32)pListeners->size(), "DbGridControl::DisconnectFromFields : dispose on a listener should result in a removal from my list !");
	}

	delete pListeners;
	m_pFieldListeners = NULL;
}

//------------------------------------------------------------------------------
void DbGridControl::FieldValueChanged(sal_uInt16 _nId, const PropertyChangeEvent& /*_evt*/)
{
	osl::MutexGuard aPreventDestruction(m_aDestructionSafety);
	// needed as this may run in a thread other than the main one
	if (GetRowStatus(GetCurRow()) != DbGridControl_Base::MODIFIED)
		// all other cases are handled elsewhere
		return;

	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(_nId));
	if (pColumn)
	{
		sal_Bool bAcquiredPaintSafety = sal_False;
		while (!m_bWantDestruction && !bAcquiredPaintSafety)
			bAcquiredPaintSafety  = Application::GetSolarMutex().tryToAcquire();

		if (m_bWantDestruction)
		{	// at this moment, within another thread, our destructor tries to destroy the listener which called this method
			// => don't do anything
			// 73365 - 23.02.00 - FS
			if (bAcquiredPaintSafety)
				// though the above while-loop suggests that (m_bWantDestruction && bAcquiredPaintSafety) is impossible,
				// it isnt't, as m_bWantDestruction isn't protected with any mutex
				Application::GetSolarMutex().release();
			return;
		}
		// here we got the solar mutex, transfer it to a guard for safety reasons
		::vos::OGuard aPaintSafety(Application::GetSolarMutex());
		Application::GetSolarMutex().release();

		// and finally do the update ...
		pColumn->UpdateFromField(m_xCurrentRow, m_xFormatter);
		RowModified(GetCurRow(), _nId);
	}
}

//------------------------------------------------------------------------------
void DbGridControl::FieldListenerDisposing(sal_uInt16 _nId)
{
	ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
	if (!pListeners)
	{
		DBG_ERROR("DbGridControl::FieldListenerDisposing : invalid call (have no listener array) !");
		return;
	}

	ColumnFieldValueListenersIterator aPos = pListeners->find(_nId);
	if (aPos == pListeners->end())
	{
		DBG_ERROR("DbGridControl::FieldListenerDisposing : invalid call (did not find the listener) !");
		return;
	}

	delete aPos->second;

	pListeners->erase(aPos);
}

//------------------------------------------------------------------------------
void DbGridControl::disposing(sal_uInt16 _nId, const EventObject& /*_rEvt*/)
{
	if (_nId == 0)
	{	// the seek cursor is beeing disposed
		::osl::MutexGuard aGuard(m_aAdjustSafety);
		setDataSource(NULL,0); // our clone was disposed so we set our datasource to null to avoid later acces to it
		if (m_nAsynAdjustEvent)
		{
			RemoveUserEvent(m_nAsynAdjustEvent);
			m_nAsynAdjustEvent = 0;
		}
	}
}
// -----------------------------------------------------------------------------
sal_Int32 DbGridControl::GetAccessibleControlCount() const
{
	return DbGridControl_Base::GetAccessibleControlCount() + 1; // the navigation control
}
// -----------------------------------------------------------------------------
Reference<XAccessible > DbGridControl::CreateAccessibleControl( sal_Int32 _nIndex )
{
	Reference<XAccessible > xRet;
	if ( _nIndex == DbGridControl_Base::GetAccessibleControlCount() )
	{
		xRet = m_aBar.GetAccessible();
	}
	else
		xRet = DbGridControl_Base::CreateAccessibleControl( _nIndex );
	return xRet;
}
// -----------------------------------------------------------------------------
Reference< XAccessible > DbGridControl::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
{
	sal_uInt16 nColumnId = GetColumnId( _nColumnPos );
	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColumnId));
	if ( pColumn )
	{
		Reference< ::com::sun::star::awt::XControl> xInt(pColumn->GetCell());
		Reference< ::com::sun::star::awt::XCheckBox> xBox(xInt,UNO_QUERY);
		if ( xBox.is() )
		{
			TriState eValue = STATE_NOCHECK;
			switch( xBox->getState() )
			{
				case 0:
					eValue = STATE_NOCHECK;
					break;
				case 1:
					eValue = STATE_CHECK;
					break;
				case 2:
					eValue = STATE_DONTKNOW;
					break;
			}
			return DbGridControl_Base::CreateAccessibleCheckBoxCell( _nRow, _nColumnPos,eValue,sal_True );
		}
	}
	return DbGridControl_Base::CreateAccessibleCell( _nRow, _nColumnPos );
}
// -----------------------------------------------------------------------------


