/**************************************************************
 *
 * 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 against 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 necessary 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 database 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 necessary
	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 occurred 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 comparison 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 successful 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 being disposed
		::osl::MutexGuard aGuard(m_aAdjustSafety);
		setDataSource(NULL,0); // our clone was disposed so we set our datasource to null to avoid later access 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 );
}
// -----------------------------------------------------------------------------
