/**************************************************************
 * 
 * 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 datebase of the Numberformatter
			try
			{
				xSupplier->getNumberFormatSettings()->getPropertyValue(rtl::OUString::createFromAscii("NullDate")) >>= m_aNullDate;
			}
			catch(Exception&)
			{
			}
		}
	}

	m_pDataCursor = new CursorWrapper(_xCursor);

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

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

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

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

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

		sal_Bool bPermanentCursor = IsPermanentCursorEnabled();
		m_nMode = DEFAULT_BROWSE_MODE;

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

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

        adjustModeForScrollbars( m_nMode, m_bNavigationBar, m_bHideScrollbars );

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

		ConnectToFields();
	}

	sal_uInt32 nRecordCount(0);

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

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

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

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

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

	// there are rows so go to the selected current column
	if (nRecordCount)
		GoToRowColumnId(0, GetColumnId(nCurPos));
	// else stop the editing if 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 );
}
// -----------------------------------------------------------------------------


