xref: /aoo41x/main/svx/source/fmcomp/gridctrl.cxx (revision f6e50924)
1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #ifndef _SVX_FMHELP_HRC
28cdf0e10cSrcweir #include "fmhelp.hrc"
29cdf0e10cSrcweir #endif
30cdf0e10cSrcweir #include <svx/gridctrl.hxx>
31cdf0e10cSrcweir #include "gridcell.hxx"
32cdf0e10cSrcweir #include "svx/dbtoolsclient.hxx"
33cdf0e10cSrcweir #include "svx/fmtools.hxx"
34cdf0e10cSrcweir #include <svtools/stringtransfer.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #ifndef _SVX_FMPROP_HRC
37cdf0e10cSrcweir #include "fmprop.hrc"
38cdf0e10cSrcweir #endif
39cdf0e10cSrcweir #include <svtools/stringtransfer.hxx>
40cdf0e10cSrcweir #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
41cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessible.hpp>
42cdf0e10cSrcweir #include <com/sun/star/sdb/XResultSetAccess.hpp>
43cdf0e10cSrcweir #include <com/sun/star/sdb/RowChangeAction.hpp>
44cdf0e10cSrcweir #include <com/sun/star/sdb/XRowsChangeBroadcaster.hpp>
45cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSetUpdate.hpp>
46cdf0e10cSrcweir #include <com/sun/star/sdbcx/Privilege.hpp>
47cdf0e10cSrcweir #include <com/sun/star/container/XChild.hpp>
48cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatter.hpp>
49cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
50cdf0e10cSrcweir #include <com/sun/star/util/XCloneable.hpp>
51cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
52cdf0e10cSrcweir #include <com/sun/star/beans/PropertyChangeEvent.hpp>
53cdf0e10cSrcweir #include <comphelper/extract.hxx>
54cdf0e10cSrcweir #include <tools/resid.hxx>
55cdf0e10cSrcweir #include <tools/diagnose_ex.h>
56cdf0e10cSrcweir #include <vcl/sound.hxx>
57cdf0e10cSrcweir #include <vcl/menu.hxx>
58cdf0e10cSrcweir 
59cdf0e10cSrcweir #ifndef _SVX_FMRESIDS_HRC
60cdf0e10cSrcweir #include "svx/fmresids.hrc"
61cdf0e10cSrcweir #endif
62cdf0e10cSrcweir 
63cdf0e10cSrcweir #ifndef _SVX_SVXIDS_HRC
64cdf0e10cSrcweir #include <svx/svxids.hrc>
65cdf0e10cSrcweir #endif
66cdf0e10cSrcweir #include <tools/shl.hxx>
67cdf0e10cSrcweir #include <svx/dialmgr.hxx>
68cdf0e10cSrcweir #include "fmservs.hxx"
69cdf0e10cSrcweir #include "sdbdatacolumn.hxx"
70cdf0e10cSrcweir 
71cdf0e10cSrcweir #define HANDLE_ID	0
72cdf0e10cSrcweir 
73cdf0e10cSrcweir #include <comphelper/stl_types.hxx>
74cdf0e10cSrcweir #include <comphelper/property.hxx>
75cdf0e10cSrcweir #include "trace.hxx"
76cdf0e10cSrcweir 
77cdf0e10cSrcweir #include <algorithm>
78cdf0e10cSrcweir 
79cdf0e10cSrcweir using namespace ::svxform;
80cdf0e10cSrcweir using namespace ::svt;
81cdf0e10cSrcweir using namespace ::com::sun::star::beans;
82cdf0e10cSrcweir using namespace ::com::sun::star::lang;
83cdf0e10cSrcweir using namespace ::com::sun::star::uno;
84cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
85cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx;
86cdf0e10cSrcweir using namespace ::com::sun::star::sdb;
87cdf0e10cSrcweir using namespace ::com::sun::star::datatransfer;
88cdf0e10cSrcweir using namespace ::com::sun::star::container;
89cdf0e10cSrcweir using namespace com::sun::star::accessibility;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir #define ROWSTATUS(row)	!row.Is() ? "NULL" : row->GetStatus() == GRS_CLEAN ? "CLEAN" : row->GetStatus() == GRS_MODIFIED ? "MODIFIED" : row->GetStatus() == GRS_DELETED ? "DELETED" : "INVALID"
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 
94cdf0e10cSrcweir #define DEFAULT_BROWSE_MODE             \
95cdf0e10cSrcweir 			  BROWSER_COLUMNSELECTION   \
96cdf0e10cSrcweir 			| BROWSER_MULTISELECTION    \
97cdf0e10cSrcweir             | BROWSER_KEEPSELECTION     \
98cdf0e10cSrcweir 			| BROWSER_TRACKING_TIPS     \
99cdf0e10cSrcweir 			| BROWSER_HLINESFULL        \
100cdf0e10cSrcweir 			| BROWSER_VLINESFULL        \
101cdf0e10cSrcweir 			| BROWSER_HEADERBAR_NEW     \
102cdf0e10cSrcweir 
103cdf0e10cSrcweir class RowSetEventListener : public ::cppu::WeakImplHelper1<XRowsChangeListener>
104cdf0e10cSrcweir {
105cdf0e10cSrcweir     DbGridControl* m_pControl;
106cdf0e10cSrcweir public:
RowSetEventListener(DbGridControl * i_pControl)107cdf0e10cSrcweir     RowSetEventListener(DbGridControl* i_pControl) : m_pControl(i_pControl)
108cdf0e10cSrcweir     {
109cdf0e10cSrcweir     }
110cdf0e10cSrcweir private:
111cdf0e10cSrcweir     // XEventListener
disposing(const::com::sun::star::lang::EventObject &)112cdf0e10cSrcweir     virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& /*i_aEvt*/) throw ( RuntimeException )
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir     }
rowsChanged(const::com::sun::star::sdb::RowsChangeEvent & i_aEvt)115cdf0e10cSrcweir     virtual void SAL_CALL rowsChanged(const ::com::sun::star::sdb::RowsChangeEvent& i_aEvt) throw ( RuntimeException )
116cdf0e10cSrcweir     {
117cdf0e10cSrcweir         if ( i_aEvt.Action == RowChangeAction::UPDATE )
118cdf0e10cSrcweir         {
119cdf0e10cSrcweir             ::DbGridControl::GrantControlAccess aAccess;
120cdf0e10cSrcweir             CursorWrapper* pSeek = m_pControl->GetSeekCursor(aAccess);
121cdf0e10cSrcweir             const DbGridRowRef& rSeekRow = m_pControl->GetSeekRow(aAccess);
122cdf0e10cSrcweir             const Any* pIter = i_aEvt.Bookmarks.getConstArray();
123cdf0e10cSrcweir             const Any* pEnd  = pIter + i_aEvt.Bookmarks.getLength();
124cdf0e10cSrcweir             for(;pIter != pEnd;++pIter)
125cdf0e10cSrcweir             {
126cdf0e10cSrcweir                 pSeek->moveToBookmark(*pIter);
127cdf0e10cSrcweir 			    // get the data
128cdf0e10cSrcweir 			    rSeekRow->SetState(pSeek, sal_True);
129cdf0e10cSrcweir                 sal_Int32 nSeekPos = pSeek->getRow() - 1;
130cdf0e10cSrcweir 			    m_pControl->SetSeekPos(nSeekPos,aAccess);
131cdf0e10cSrcweir                 m_pControl->RowModified(nSeekPos);
132cdf0e10cSrcweir             }
133cdf0e10cSrcweir         }
134cdf0e10cSrcweir     }
135cdf0e10cSrcweir };
136cdf0e10cSrcweir //==============================================================================
137cdf0e10cSrcweir 
138cdf0e10cSrcweir class GridFieldValueListener;
139cdf0e10cSrcweir DECLARE_STL_MAP(sal_uInt16, GridFieldValueListener*, ::std::less<sal_uInt16>, ColumnFieldValueListeners);
140cdf0e10cSrcweir 
141cdf0e10cSrcweir //==============================================================================
142cdf0e10cSrcweir 
143cdf0e10cSrcweir DBG_NAME(GridFieldValueListener)
144cdf0e10cSrcweir class GridFieldValueListener : protected ::comphelper::OPropertyChangeListener
145cdf0e10cSrcweir {
146cdf0e10cSrcweir 	osl::Mutex							m_aMutex;
147cdf0e10cSrcweir 	DbGridControl&						m_rParent;
148cdf0e10cSrcweir 	::comphelper::OPropertyChangeMultiplexer*	m_pRealListener;
149cdf0e10cSrcweir 	sal_uInt16							m_nId;
150cdf0e10cSrcweir 	sal_Int16							m_nSuspended;
151cdf0e10cSrcweir 	sal_Bool							m_bDisposed : 1;
152cdf0e10cSrcweir 
153cdf0e10cSrcweir public:
154cdf0e10cSrcweir 	GridFieldValueListener(DbGridControl& _rParent, const Reference< XPropertySet >& xField, sal_uInt16 _nId);
155cdf0e10cSrcweir 	virtual ~GridFieldValueListener();
156cdf0e10cSrcweir 
157cdf0e10cSrcweir 	virtual void _propertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException );
158cdf0e10cSrcweir 
suspend()159cdf0e10cSrcweir 	void suspend() { ++m_nSuspended; }
resume()160cdf0e10cSrcweir 	void resume() { --m_nSuspended; }
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 	void dispose();
163cdf0e10cSrcweir };
164cdf0e10cSrcweir //------------------------------------------------------------------------------
GridFieldValueListener(DbGridControl & _rParent,const Reference<XPropertySet> & _rField,sal_uInt16 _nId)165cdf0e10cSrcweir GridFieldValueListener::GridFieldValueListener(DbGridControl& _rParent, const Reference< XPropertySet >& _rField, sal_uInt16 _nId)
166cdf0e10cSrcweir 	:OPropertyChangeListener(m_aMutex)
167cdf0e10cSrcweir 	,m_rParent(_rParent)
168cdf0e10cSrcweir     ,m_pRealListener(NULL)
169cdf0e10cSrcweir 	,m_nId(_nId)
170cdf0e10cSrcweir     ,m_nSuspended(0)
171cdf0e10cSrcweir 	,m_bDisposed(sal_False)
172cdf0e10cSrcweir {
173cdf0e10cSrcweir 	DBG_CTOR(GridFieldValueListener, NULL);
174cdf0e10cSrcweir 	if (_rField.is())
175cdf0e10cSrcweir 	{
176cdf0e10cSrcweir 		m_pRealListener = new ::comphelper::OPropertyChangeMultiplexer(this, _rField);
177cdf0e10cSrcweir 		m_pRealListener->addProperty(FM_PROP_VALUE);
178cdf0e10cSrcweir 		m_pRealListener->acquire();
179cdf0e10cSrcweir 	}
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
182cdf0e10cSrcweir //------------------------------------------------------------------------------
~GridFieldValueListener()183cdf0e10cSrcweir GridFieldValueListener::~GridFieldValueListener()
184cdf0e10cSrcweir {
185cdf0e10cSrcweir 	DBG_DTOR(GridFieldValueListener, NULL);
186cdf0e10cSrcweir 	dispose();
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir //------------------------------------------------------------------------------
_propertyChanged(const PropertyChangeEvent & _evt)190cdf0e10cSrcweir void GridFieldValueListener::_propertyChanged(const PropertyChangeEvent& _evt) throw( RuntimeException )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir 	DBG_ASSERT(m_nSuspended>=0, "GridFieldValueListener::_propertyChanged : resume > suspend !");
193cdf0e10cSrcweir 	if (m_nSuspended <= 0)
194cdf0e10cSrcweir 		m_rParent.FieldValueChanged(m_nId, _evt);
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir //------------------------------------------------------------------------------
dispose()198cdf0e10cSrcweir void GridFieldValueListener::dispose()
199cdf0e10cSrcweir {
200cdf0e10cSrcweir 	if (m_bDisposed)
201cdf0e10cSrcweir 	{
202cdf0e10cSrcweir 		DBG_ASSERT(m_pRealListener == NULL, "GridFieldValueListener::dispose : inconsistent !");
203cdf0e10cSrcweir 		return;
204cdf0e10cSrcweir 	}
205cdf0e10cSrcweir 
206cdf0e10cSrcweir 	if (m_pRealListener)
207cdf0e10cSrcweir 	{
208cdf0e10cSrcweir 		m_pRealListener->dispose();
209cdf0e10cSrcweir 		m_pRealListener->release();
210cdf0e10cSrcweir 		m_pRealListener = NULL;
211cdf0e10cSrcweir 	}
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 	m_bDisposed = sal_True;
214cdf0e10cSrcweir 	m_rParent.FieldListenerDisposing(m_nId);
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir //==============================================================================
218cdf0e10cSrcweir 
219cdf0e10cSrcweir class DisposeListenerGridBridge : public FmXDisposeListener
220cdf0e10cSrcweir {
221cdf0e10cSrcweir 	osl::Mutex				m_aMutex;
222cdf0e10cSrcweir 	DbGridControl&			m_rParent;
223cdf0e10cSrcweir 	FmXDisposeMultiplexer*	m_pRealListener;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir public:
226cdf0e10cSrcweir 	DisposeListenerGridBridge(	DbGridControl& _rParent, const Reference< XComponent >& _rxObject, sal_Int16 _rId = -1);
227cdf0e10cSrcweir 	virtual ~DisposeListenerGridBridge();
228cdf0e10cSrcweir 
disposing(const EventObject & _rEvent,sal_Int16 _nId)229cdf0e10cSrcweir 	virtual void disposing(const EventObject& _rEvent, sal_Int16 _nId) throw( RuntimeException ) { m_rParent.disposing(_nId, _rEvent); }
230cdf0e10cSrcweir };
231cdf0e10cSrcweir 
232cdf0e10cSrcweir //==============================================================================
233cdf0e10cSrcweir 
234cdf0e10cSrcweir 
DBG_NAME(DisposeListenerGridBridge)235cdf0e10cSrcweir DBG_NAME(DisposeListenerGridBridge)
236cdf0e10cSrcweir //------------------------------------------------------------------------------
237cdf0e10cSrcweir DisposeListenerGridBridge::DisposeListenerGridBridge(DbGridControl& _rParent, const Reference< XComponent >& _rxObject, sal_Int16 _rId)
238cdf0e10cSrcweir 	:FmXDisposeListener(m_aMutex)
239cdf0e10cSrcweir 	,m_rParent(_rParent)
240cdf0e10cSrcweir 	,m_pRealListener(NULL)
241cdf0e10cSrcweir {
242cdf0e10cSrcweir 	DBG_CTOR(DisposeListenerGridBridge,NULL);
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 	if (_rxObject.is())
245cdf0e10cSrcweir 	{
246cdf0e10cSrcweir 		m_pRealListener = new FmXDisposeMultiplexer(this, _rxObject, _rId);
247cdf0e10cSrcweir 		m_pRealListener->acquire();
248cdf0e10cSrcweir 	}
249cdf0e10cSrcweir }
250cdf0e10cSrcweir 
251cdf0e10cSrcweir //------------------------------------------------------------------------------
~DisposeListenerGridBridge()252cdf0e10cSrcweir DisposeListenerGridBridge::~DisposeListenerGridBridge()
253cdf0e10cSrcweir {
254cdf0e10cSrcweir 	if (m_pRealListener)
255cdf0e10cSrcweir 	{
256cdf0e10cSrcweir 		m_pRealListener->dispose();
257cdf0e10cSrcweir 		m_pRealListener->release();
258cdf0e10cSrcweir 		m_pRealListener = NULL;
259cdf0e10cSrcweir 	}
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 	DBG_DTOR(DisposeListenerGridBridge,NULL);
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir //==============================================================================
265cdf0e10cSrcweir 
266cdf0e10cSrcweir static sal_uInt16 ControlMap[] =
267cdf0e10cSrcweir 	{
268cdf0e10cSrcweir 		DbGridControl::NavigationBar::RECORD_TEXT,
269cdf0e10cSrcweir 		DbGridControl::NavigationBar::RECORD_ABSOLUTE,
270cdf0e10cSrcweir 		DbGridControl::NavigationBar::RECORD_OF,
271cdf0e10cSrcweir 		DbGridControl::NavigationBar::RECORD_COUNT,
272cdf0e10cSrcweir 		DbGridControl::NavigationBar::RECORD_FIRST,
273cdf0e10cSrcweir 		DbGridControl::NavigationBar::RECORD_NEXT,
274cdf0e10cSrcweir 		DbGridControl::NavigationBar::RECORD_PREV,
275cdf0e10cSrcweir 		DbGridControl::NavigationBar::RECORD_LAST,
276cdf0e10cSrcweir 		DbGridControl::NavigationBar::RECORD_NEW,
277cdf0e10cSrcweir 		0
278cdf0e10cSrcweir 	};
279cdf0e10cSrcweir 
280cdf0e10cSrcweir //------------------------------------------------------------------------------
CompareBookmark(const Any & aLeft,const Any & aRight)281cdf0e10cSrcweir sal_Bool CompareBookmark(const Any& aLeft, const Any& aRight)
282cdf0e10cSrcweir {
283cdf0e10cSrcweir 	return ::comphelper::compare(aLeft, aRight);
284cdf0e10cSrcweir }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir //==============================================================================
287cdf0e10cSrcweir class FmXGridSourcePropListener : public ::comphelper::OPropertyChangeListener
288cdf0e10cSrcweir {
289cdf0e10cSrcweir 	DbGridControl* m_pParent;
290cdf0e10cSrcweir 
291cdf0e10cSrcweir 	// a DbGridControl has no mutex, so we use our own as the base class expects one
292cdf0e10cSrcweir 	osl::Mutex		m_aMutex;
293cdf0e10cSrcweir 	sal_Int16			m_nSuspended;
294cdf0e10cSrcweir 
295cdf0e10cSrcweir public:
296cdf0e10cSrcweir 	FmXGridSourcePropListener(DbGridControl* _pParent);
297cdf0e10cSrcweir 
suspend()298cdf0e10cSrcweir 	void suspend() { ++m_nSuspended; }
resume()299cdf0e10cSrcweir 	void resume() { --m_nSuspended; }
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 	virtual void _propertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException );
302cdf0e10cSrcweir };
303cdf0e10cSrcweir 
304cdf0e10cSrcweir //------------------------------------------------------------------------------
FmXGridSourcePropListener(DbGridControl * _pParent)305cdf0e10cSrcweir FmXGridSourcePropListener::FmXGridSourcePropListener(DbGridControl* _pParent)
306cdf0e10cSrcweir 	:OPropertyChangeListener(m_aMutex)
307cdf0e10cSrcweir 	,m_pParent(_pParent)
308cdf0e10cSrcweir 	,m_nSuspended(0)
309cdf0e10cSrcweir {
310cdf0e10cSrcweir 	DBG_ASSERT(m_pParent, "FmXGridSourcePropListener::FmXGridSourcePropListener : invalid parent !");
311cdf0e10cSrcweir }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir //------------------------------------------------------------------------------
_propertyChanged(const PropertyChangeEvent & evt)314cdf0e10cSrcweir void FmXGridSourcePropListener::_propertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException )
315cdf0e10cSrcweir {
316cdf0e10cSrcweir 	DBG_ASSERT(m_nSuspended>=0, "FmXGridSourcePropListener::_propertyChanged : resume > suspend !");
317cdf0e10cSrcweir 	if (m_nSuspended <= 0)
318cdf0e10cSrcweir 		m_pParent->DataSourcePropertyChanged(evt);
319cdf0e10cSrcweir }
320cdf0e10cSrcweir 
321cdf0e10cSrcweir //==============================================================================
322cdf0e10cSrcweir //------------------------------------------------------------------------------
AbsolutePos(Window * pParent,WinBits nStyle)323cdf0e10cSrcweir DbGridControl::NavigationBar::AbsolutePos::AbsolutePos(Window* pParent, WinBits nStyle)
324cdf0e10cSrcweir 				   :NumericField(pParent, nStyle)
325cdf0e10cSrcweir {
326cdf0e10cSrcweir 	SetMin(1);
327cdf0e10cSrcweir 	SetFirst(1);
328cdf0e10cSrcweir 	SetSpinSize(1);
329cdf0e10cSrcweir 
330cdf0e10cSrcweir 	SetDecimalDigits(0);
331cdf0e10cSrcweir 	SetStrictFormat(sal_True);
332cdf0e10cSrcweir }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir //------------------------------------------------------------------------------
KeyInput(const KeyEvent & rEvt)335cdf0e10cSrcweir void DbGridControl::NavigationBar::AbsolutePos::KeyInput(const KeyEvent& rEvt)
336cdf0e10cSrcweir {
337cdf0e10cSrcweir 	if (rEvt.GetKeyCode() == KEY_RETURN && GetText().Len())
338cdf0e10cSrcweir 	{
339cdf0e10cSrcweir 		sal_Int64 nRecord = GetValue();
340cdf0e10cSrcweir 		if (nRecord < GetMin() || nRecord > GetMax())
341cdf0e10cSrcweir 			return;
342cdf0e10cSrcweir 		else
343cdf0e10cSrcweir 			((NavigationBar*)GetParent())->PositionDataSource(static_cast<sal_Int32>(nRecord));
344cdf0e10cSrcweir 	}
345cdf0e10cSrcweir 	else if (rEvt.GetKeyCode() == KEY_TAB)
346cdf0e10cSrcweir 		GetParent()->GetParent()->GrabFocus();
347cdf0e10cSrcweir 	else
348cdf0e10cSrcweir 		NumericField::KeyInput(rEvt);
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
351cdf0e10cSrcweir //------------------------------------------------------------------------------
LoseFocus()352cdf0e10cSrcweir void DbGridControl::NavigationBar::AbsolutePos::LoseFocus()
353cdf0e10cSrcweir {
354cdf0e10cSrcweir 	NumericField::LoseFocus();
355cdf0e10cSrcweir 	sal_Int64 nRecord = GetValue();
356cdf0e10cSrcweir 	if (nRecord < GetMin() || nRecord > GetMax())
357cdf0e10cSrcweir 		return;
358cdf0e10cSrcweir 	else
359cdf0e10cSrcweir 	{
360cdf0e10cSrcweir 		((NavigationBar*)GetParent())->PositionDataSource(static_cast<sal_Int32>(nRecord));
361cdf0e10cSrcweir 		((NavigationBar*)GetParent())->InvalidateState(NavigationBar::RECORD_ABSOLUTE);
362cdf0e10cSrcweir 	}
363cdf0e10cSrcweir }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir //------------------------------------------------------------------------------
PositionDataSource(sal_Int32 nRecord)366cdf0e10cSrcweir void DbGridControl::NavigationBar::PositionDataSource(sal_Int32 nRecord)
367cdf0e10cSrcweir {
368cdf0e10cSrcweir 	if (m_bPositioning)
369cdf0e10cSrcweir 		return;
370cdf0e10cSrcweir 	// the MoveToPosition may cause a LoseFocus which would lead to a second MoveToPosition, so protect agains this
371cdf0e10cSrcweir 	// recursion
372cdf0e10cSrcweir 	// 68167 - 13.08.99 - FS
373cdf0e10cSrcweir 	m_bPositioning = sal_True;
374cdf0e10cSrcweir 	((DbGridControl*)GetParent())->MoveToPosition(nRecord - 1);
375cdf0e10cSrcweir 	m_bPositioning = sal_False;
376cdf0e10cSrcweir }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir //------------------------------------------------------------------------------
NavigationBar(Window * pParent,WinBits nStyle)379cdf0e10cSrcweir DbGridControl::NavigationBar::NavigationBar(Window* pParent, WinBits nStyle)
380cdf0e10cSrcweir 		  :Control(pParent, nStyle)
381cdf0e10cSrcweir 		  ,m_aRecordText(this, WB_VCENTER)
382cdf0e10cSrcweir 		  ,m_aAbsolute(this, WB_VCENTER)
383cdf0e10cSrcweir 		  ,m_aRecordOf(this, WB_VCENTER)
384cdf0e10cSrcweir 		  ,m_aRecordCount(this, WB_CENTER | WB_VCENTER)
385cdf0e10cSrcweir 		  ,m_aFirstBtn(this, WB_RECTSTYLE|WB_NOPOINTERFOCUS)
386cdf0e10cSrcweir 		  ,m_aPrevBtn(this, WB_REPEAT|WB_RECTSTYLE|WB_NOPOINTERFOCUS)
387cdf0e10cSrcweir 		  ,m_aNextBtn(this, WB_REPEAT|WB_RECTSTYLE|WB_NOPOINTERFOCUS)
388cdf0e10cSrcweir 		  ,m_aLastBtn(this, WB_RECTSTYLE|WB_NOPOINTERFOCUS)
389cdf0e10cSrcweir 		  ,m_aNewBtn(this, WB_RECTSTYLE|WB_NOPOINTERFOCUS)
390cdf0e10cSrcweir 		  ,m_nDefaultWidth(0)
391cdf0e10cSrcweir 		  ,m_nCurrentPos(-1)
392cdf0e10cSrcweir 		  ,m_bPositioning(sal_False)
393cdf0e10cSrcweir {
394cdf0e10cSrcweir 	m_aFirstBtn.SetSymbol(SYMBOL_FIRST);
395cdf0e10cSrcweir 	m_aPrevBtn.SetSymbol(SYMBOL_PREV);
396cdf0e10cSrcweir 	m_aNextBtn.SetSymbol(SYMBOL_NEXT);
397cdf0e10cSrcweir 	m_aLastBtn.SetSymbol(SYMBOL_LAST);
398cdf0e10cSrcweir 	m_aNewBtn.SetModeImage(((DbGridControl*)pParent)->GetImage(DbGridControl_Base::NEW));
399cdf0e10cSrcweir 
400cdf0e10cSrcweir 	m_aFirstBtn.SetHelpId(HID_GRID_TRAVEL_FIRST);
401cdf0e10cSrcweir 	m_aPrevBtn.SetHelpId(HID_GRID_TRAVEL_PREV);
402cdf0e10cSrcweir 	m_aNextBtn.SetHelpId(HID_GRID_TRAVEL_NEXT);
403cdf0e10cSrcweir 	m_aLastBtn.SetHelpId(HID_GRID_TRAVEL_LAST);
404cdf0e10cSrcweir 	m_aNewBtn.SetHelpId(HID_GRID_TRAVEL_NEW);
405cdf0e10cSrcweir 	m_aAbsolute.SetHelpId(HID_GRID_TRAVEL_ABSOLUTE);
406cdf0e10cSrcweir 	m_aRecordCount.SetHelpId(HID_GRID_NUMBEROFRECORDS);
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 	// Handler fuer Buttons einrichten
409cdf0e10cSrcweir 	m_aFirstBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));
410cdf0e10cSrcweir 	m_aPrevBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));
411cdf0e10cSrcweir 	m_aNextBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));
412cdf0e10cSrcweir 	m_aLastBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));
413cdf0e10cSrcweir 	m_aNewBtn.SetClickHdl(LINK(this,NavigationBar,OnClick));
414cdf0e10cSrcweir 
415cdf0e10cSrcweir 	m_aRecordText.SetText(XubString(SVX_RES(RID_STR_REC_TEXT)));
416cdf0e10cSrcweir 	m_aRecordOf.SetText(XubString(SVX_RES(RID_STR_REC_FROM_TEXT)));
417cdf0e10cSrcweir 	m_aRecordCount.SetText('?');
418cdf0e10cSrcweir 
419cdf0e10cSrcweir 	m_nDefaultWidth = ArrangeControls();
420cdf0e10cSrcweir 
421cdf0e10cSrcweir 	m_aFirstBtn.Disable();
422cdf0e10cSrcweir 	m_aPrevBtn.Disable();
423cdf0e10cSrcweir 	m_aNextBtn.Disable();
424cdf0e10cSrcweir 	m_aLastBtn.Disable();
425cdf0e10cSrcweir 	m_aNewBtn.Disable();
426cdf0e10cSrcweir 	m_aRecordText.Disable();
427cdf0e10cSrcweir 	m_aRecordOf.Disable();
428cdf0e10cSrcweir 	m_aRecordCount.Disable();
429cdf0e10cSrcweir 	m_aAbsolute.Disable();
430cdf0e10cSrcweir 
431cdf0e10cSrcweir 	AllSettings aSettings = m_aNextBtn.GetSettings();
432cdf0e10cSrcweir 	MouseSettings aMouseSettings = aSettings.GetMouseSettings();
433cdf0e10cSrcweir 	aMouseSettings.SetButtonRepeat(aMouseSettings.GetButtonRepeat() / 4);
434cdf0e10cSrcweir 	aSettings.SetMouseSettings(aMouseSettings);
435cdf0e10cSrcweir 	m_aNextBtn.SetSettings(aSettings, sal_True);
436cdf0e10cSrcweir 	m_aPrevBtn.SetSettings(aSettings, sal_True);
437cdf0e10cSrcweir 
438cdf0e10cSrcweir 	m_aFirstBtn.Show();
439cdf0e10cSrcweir 	m_aPrevBtn.Show();
440cdf0e10cSrcweir 	m_aNextBtn.Show();
441cdf0e10cSrcweir 	m_aLastBtn.Show();
442cdf0e10cSrcweir 	m_aNewBtn.Show();
443cdf0e10cSrcweir 	m_aRecordText.Show();
444cdf0e10cSrcweir 	m_aRecordOf.Show();
445cdf0e10cSrcweir 	m_aRecordCount.Show();
446cdf0e10cSrcweir 	m_aAbsolute.Show();
447cdf0e10cSrcweir }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir namespace
450cdf0e10cSrcweir {
SetPosAndSize(Button & _rButton,Point & _rPos,const Size & _rSize)451cdf0e10cSrcweir 	void SetPosAndSize(Button& _rButton,Point& _rPos,const Size& _rSize)
452cdf0e10cSrcweir 	{
453cdf0e10cSrcweir 		_rButton.SetPosPixel( _rPos );
454cdf0e10cSrcweir 		_rButton.SetSizePixel( _rSize );
455cdf0e10cSrcweir 		_rPos.X() += (sal_uInt16)_rSize.Width();
456cdf0e10cSrcweir 	}
457cdf0e10cSrcweir }
458cdf0e10cSrcweir //------------------------------------------------------------------------------
ArrangeControls()459cdf0e10cSrcweir sal_uInt16 DbGridControl::NavigationBar::ArrangeControls()
460cdf0e10cSrcweir {
461cdf0e10cSrcweir 	// Positionierung der Controls
462cdf0e10cSrcweir 	// Basisgroessen ermitteln
463cdf0e10cSrcweir 	sal_uInt16		nX = 0;
464cdf0e10cSrcweir 	sal_uInt16		nY = 0;
465cdf0e10cSrcweir 	Rectangle	aRect(((DbGridControl*)GetParent())->GetControlArea());
466cdf0e10cSrcweir 	const long	nH		= aRect.GetSize().Height();
467cdf0e10cSrcweir 	Size		aBorder = LogicToPixel(Size(3, 3),MAP_APPFONT);
468cdf0e10cSrcweir 				aBorder = Size(CalcZoom(aBorder.Width()), CalcZoom(aBorder.Height()));
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 	// Controls Groessen und Positionen setzen
471cdf0e10cSrcweir 	//
472cdf0e10cSrcweir 	XubString aText    = m_aRecordText.GetText();
473cdf0e10cSrcweir 	long nTextWidth = m_aRecordText.GetTextWidth(aText);
474cdf0e10cSrcweir 	m_aRecordText.SetPosPixel(Point(nX,nY) );
475cdf0e10cSrcweir 	m_aRecordText.SetSizePixel(Size(nTextWidth,nH));
476cdf0e10cSrcweir 	nX = sal::static_int_cast< sal_uInt16 >(nX + nTextWidth + aBorder.Width());
477cdf0e10cSrcweir 
478cdf0e10cSrcweir 	m_aAbsolute.SetPosPixel( Point(nX,nY));
479cdf0e10cSrcweir 	m_aAbsolute.SetSizePixel( Size(3*nH,aRect.GetSize().Height()) ); // Heuristik XXXXXXX
480cdf0e10cSrcweir 	nX = sal::static_int_cast< sal_uInt16 >(nX + (3*nH) + aBorder.Width());
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 	aText	   = m_aRecordOf.GetText();
483cdf0e10cSrcweir 	nTextWidth = m_aRecordOf.GetTextWidth(aText);
484cdf0e10cSrcweir 	m_aRecordOf.SetPosPixel(Point(nX,nY) );
485cdf0e10cSrcweir 	m_aRecordOf.SetSizePixel(Size(nTextWidth,nH));
486cdf0e10cSrcweir 	nX = sal::static_int_cast< sal_uInt16 >(nX + nTextWidth + aBorder.Width());
487cdf0e10cSrcweir 
488cdf0e10cSrcweir 	nTextWidth = m_aRecordCount.GetTextWidth( String::CreateFromAscii("0000000 (00000) *") );
489cdf0e10cSrcweir 	m_aRecordCount.SetPosPixel(Point(nX,nY) );
490cdf0e10cSrcweir 	m_aRecordCount.SetSizePixel(Size(nTextWidth,nH));
491cdf0e10cSrcweir 	nX = sal::static_int_cast< sal_uInt16 >(nX + nTextWidth + aBorder.Width());
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 	Point aButtonPos(nX,nY);
494cdf0e10cSrcweir 	Size  aButtonSize(nH,nH);
495cdf0e10cSrcweir 	SetPosAndSize(m_aFirstBtn, aButtonPos, aButtonSize);
496cdf0e10cSrcweir 	SetPosAndSize(m_aPrevBtn, aButtonPos, aButtonSize);
497cdf0e10cSrcweir 	SetPosAndSize(m_aNextBtn, aButtonPos, aButtonSize);
498cdf0e10cSrcweir 	SetPosAndSize(m_aLastBtn, aButtonPos, aButtonSize);
499cdf0e10cSrcweir 	SetPosAndSize(m_aNewBtn, aButtonPos, aButtonSize);
500cdf0e10cSrcweir 
501cdf0e10cSrcweir 	nX = sal::static_int_cast< sal_uInt16 >(
502cdf0e10cSrcweir         aButtonPos.X() + (sal_uInt16)(nH + aBorder.Width()));
503cdf0e10cSrcweir 
504cdf0e10cSrcweir 	// Ist der Font des Edits groesser als das Feld?
505cdf0e10cSrcweir 	Font aOutputFont = m_aAbsolute.GetFont();
506cdf0e10cSrcweir 	if (aOutputFont.GetSize().Height() > nH)
507cdf0e10cSrcweir 	{
508cdf0e10cSrcweir 		Font aApplFont = OutputDevice::GetDefaultFont(
509cdf0e10cSrcweir 			DEFAULTFONT_SANS_UNICODE,
510cdf0e10cSrcweir 			Application::GetSettings().GetUILanguage(),
511cdf0e10cSrcweir 			DEFAULTFONT_FLAGS_ONLYONE,
512cdf0e10cSrcweir 			this
513cdf0e10cSrcweir 		);
514cdf0e10cSrcweir 		aApplFont.SetSize( Size( 0, nH - 2 ) );
515cdf0e10cSrcweir 		m_aAbsolute.SetControlFont( aApplFont );
516cdf0e10cSrcweir 
517cdf0e10cSrcweir 		aApplFont.SetTransparent( sal_True );
518cdf0e10cSrcweir 		m_aRecordText.SetControlFont( aApplFont );
519cdf0e10cSrcweir 		m_aRecordOf.SetControlFont( aApplFont );
520cdf0e10cSrcweir 		m_aRecordCount.SetControlFont( aApplFont );
521cdf0e10cSrcweir 	}
522cdf0e10cSrcweir 	return nX;
523cdf0e10cSrcweir }
524cdf0e10cSrcweir 
525cdf0e10cSrcweir //------------------------------------------------------------------------------
IMPL_LINK(DbGridControl::NavigationBar,OnClick,Button *,pButton)526cdf0e10cSrcweir IMPL_LINK(DbGridControl::NavigationBar, OnClick, Button *, pButton )
527cdf0e10cSrcweir {
528cdf0e10cSrcweir 	DbGridControl* pParent = (DbGridControl*)GetParent();
529cdf0e10cSrcweir 
530cdf0e10cSrcweir 	if (pParent->m_aMasterSlotExecutor.IsSet())
531cdf0e10cSrcweir 	{
532cdf0e10cSrcweir 		long lResult = 0;
533cdf0e10cSrcweir 		if (pButton == &m_aFirstBtn)
534cdf0e10cSrcweir 			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_FIRST);
535cdf0e10cSrcweir 		else if( pButton == &m_aPrevBtn )
536cdf0e10cSrcweir 			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_PREV);
537cdf0e10cSrcweir 		else if( pButton == &m_aNextBtn )
538cdf0e10cSrcweir 			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_NEXT);
539cdf0e10cSrcweir 		else if( pButton == &m_aLastBtn )
540cdf0e10cSrcweir 			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_LAST);
541cdf0e10cSrcweir 		else if( pButton == &m_aNewBtn )
542cdf0e10cSrcweir 			lResult = pParent->m_aMasterSlotExecutor.Call((void*)RECORD_NEW);
543cdf0e10cSrcweir 
544cdf0e10cSrcweir 		if (lResult)
545cdf0e10cSrcweir 			// the link already handled it
546cdf0e10cSrcweir 			return 0;
547cdf0e10cSrcweir 	}
548cdf0e10cSrcweir 
549cdf0e10cSrcweir 	if (pButton == &m_aFirstBtn)
550cdf0e10cSrcweir 		pParent->MoveToFirst();
551cdf0e10cSrcweir 	else if( pButton == &m_aPrevBtn )
552cdf0e10cSrcweir 		pParent->MoveToPrev();
553cdf0e10cSrcweir 	else if( pButton == &m_aNextBtn )
554cdf0e10cSrcweir 		pParent->MoveToNext();
555cdf0e10cSrcweir 	else if( pButton == &m_aLastBtn )
556cdf0e10cSrcweir 		pParent->MoveToLast();
557cdf0e10cSrcweir 	else if( pButton == &m_aNewBtn )
558cdf0e10cSrcweir 		pParent->AppendNew();
559cdf0e10cSrcweir 	return 0;
560cdf0e10cSrcweir }
561cdf0e10cSrcweir 
562cdf0e10cSrcweir //------------------------------------------------------------------------------
InvalidateAll(sal_Int32 nCurrentPos,sal_Bool bAll)563cdf0e10cSrcweir void DbGridControl::NavigationBar::InvalidateAll(sal_Int32 nCurrentPos, sal_Bool bAll)
564cdf0e10cSrcweir {
565cdf0e10cSrcweir 	if (m_nCurrentPos != nCurrentPos || nCurrentPos < 0 || bAll)
566cdf0e10cSrcweir 	{
567cdf0e10cSrcweir 		DbGridControl* pParent = (DbGridControl*)GetParent();
568cdf0e10cSrcweir 
569cdf0e10cSrcweir         sal_Int32 nAdjustedRowCount = pParent->GetRowCount() - ((pParent->GetOptions() & DbGridControl::OPT_INSERT) ? 2 : 1);
570cdf0e10cSrcweir 
571cdf0e10cSrcweir 		// Wann mu� alles invalidiert werden
572cdf0e10cSrcweir         bAll = bAll || m_nCurrentPos <= 0;
573cdf0e10cSrcweir         bAll = bAll || nCurrentPos <= 0;
574cdf0e10cSrcweir         bAll = bAll || m_nCurrentPos >= nAdjustedRowCount;
575cdf0e10cSrcweir         bAll = bAll || nCurrentPos >= nAdjustedRowCount;
576cdf0e10cSrcweir 
577cdf0e10cSrcweir         if ( bAll )
578cdf0e10cSrcweir 		{
579cdf0e10cSrcweir 			m_nCurrentPos = nCurrentPos;
580cdf0e10cSrcweir 			int i = 0;
581cdf0e10cSrcweir 			while (ControlMap[i])
582cdf0e10cSrcweir 				SetState(ControlMap[i++]);
583cdf0e10cSrcweir 		}
584cdf0e10cSrcweir 		else	// befindet sich in der Mitte
585cdf0e10cSrcweir 		{
586cdf0e10cSrcweir 			m_nCurrentPos = nCurrentPos;
587cdf0e10cSrcweir 			SetState(NavigationBar::RECORD_COUNT);
588cdf0e10cSrcweir 			SetState(NavigationBar::RECORD_ABSOLUTE);
589cdf0e10cSrcweir 		}
590cdf0e10cSrcweir 	}
591cdf0e10cSrcweir }
592cdf0e10cSrcweir 
593cdf0e10cSrcweir //------------------------------------------------------------------------------
GetState(sal_uInt16 nWhich) const594cdf0e10cSrcweir sal_Bool DbGridControl::NavigationBar::GetState(sal_uInt16 nWhich) const
595cdf0e10cSrcweir {
596cdf0e10cSrcweir 	DbGridControl* pParent = (DbGridControl*)GetParent();
597cdf0e10cSrcweir 
598cdf0e10cSrcweir 	if (!pParent->IsOpen() || pParent->IsDesignMode() || !pParent->IsEnabled()
599cdf0e10cSrcweir 		|| pParent->IsFilterMode() )
600cdf0e10cSrcweir 		return sal_False;
601cdf0e10cSrcweir 	else
602cdf0e10cSrcweir 	{
603cdf0e10cSrcweir 		// check if we have a master state provider
604cdf0e10cSrcweir 		if (pParent->m_aMasterStateProvider.IsSet())
605cdf0e10cSrcweir 		{
606cdf0e10cSrcweir 			long nState = pParent->m_aMasterStateProvider.Call(reinterpret_cast< void* >( nWhich ) );
607cdf0e10cSrcweir 			if (nState>=0)
608cdf0e10cSrcweir 				return (nState>0);
609cdf0e10cSrcweir 		}
610cdf0e10cSrcweir 
611cdf0e10cSrcweir 		sal_Bool bAvailable = sal_True;
612cdf0e10cSrcweir 
613cdf0e10cSrcweir 		switch (nWhich)
614cdf0e10cSrcweir 		{
615cdf0e10cSrcweir 			case NavigationBar::RECORD_FIRST:
616cdf0e10cSrcweir 			case NavigationBar::RECORD_PREV:
617cdf0e10cSrcweir 				bAvailable = m_nCurrentPos > 0;
618cdf0e10cSrcweir 				break;
619cdf0e10cSrcweir 			case NavigationBar::RECORD_NEXT:
620cdf0e10cSrcweir 				if(pParent->m_bRecordCountFinal)
621cdf0e10cSrcweir 				{
622cdf0e10cSrcweir 					bAvailable = m_nCurrentPos < pParent->GetRowCount() - 1;
623cdf0e10cSrcweir 					if (!bAvailable && pParent->GetOptions() & DbGridControl::OPT_INSERT)
624cdf0e10cSrcweir 						bAvailable = (m_nCurrentPos == pParent->GetRowCount() - 2) && pParent->IsModified();
625cdf0e10cSrcweir 				}
626cdf0e10cSrcweir 				break;
627cdf0e10cSrcweir 			case NavigationBar::RECORD_LAST:
628cdf0e10cSrcweir 				if(pParent->m_bRecordCountFinal)
629cdf0e10cSrcweir 				{
630cdf0e10cSrcweir 					if (pParent->GetOptions() & DbGridControl::OPT_INSERT)
631cdf0e10cSrcweir 						bAvailable = pParent->IsCurrentAppending() ? pParent->GetRowCount() > 1 :
632cdf0e10cSrcweir 									 m_nCurrentPos != pParent->GetRowCount() - 2;
633cdf0e10cSrcweir 					else
634cdf0e10cSrcweir 						bAvailable = m_nCurrentPos != pParent->GetRowCount() - 1;
635cdf0e10cSrcweir 				}
636cdf0e10cSrcweir 				break;
637cdf0e10cSrcweir 			case NavigationBar::RECORD_NEW:
638cdf0e10cSrcweir 				bAvailable = (pParent->GetOptions() & DbGridControl::OPT_INSERT) && pParent->GetRowCount() && m_nCurrentPos < pParent->GetRowCount() - 1;
639cdf0e10cSrcweir 				break;
640cdf0e10cSrcweir 			case NavigationBar::RECORD_ABSOLUTE:
641cdf0e10cSrcweir 				bAvailable = pParent->GetRowCount() > 0;
642cdf0e10cSrcweir 				break;
643cdf0e10cSrcweir 		}
644cdf0e10cSrcweir 		return bAvailable;
645cdf0e10cSrcweir 	}
646cdf0e10cSrcweir }
647cdf0e10cSrcweir 
648cdf0e10cSrcweir //------------------------------------------------------------------------------
SetState(sal_uInt16 nWhich)649cdf0e10cSrcweir void DbGridControl::NavigationBar::SetState(sal_uInt16 nWhich)
650cdf0e10cSrcweir {
651cdf0e10cSrcweir 	sal_Bool bAvailable = GetState(nWhich);
652cdf0e10cSrcweir 	DbGridControl* pParent = (DbGridControl*)GetParent();
653cdf0e10cSrcweir 	Window* pWnd = NULL;
654cdf0e10cSrcweir 	switch (nWhich)
655cdf0e10cSrcweir 	{
656cdf0e10cSrcweir 		case NavigationBar::RECORD_FIRST:
657cdf0e10cSrcweir 			pWnd = &m_aFirstBtn;
658cdf0e10cSrcweir 			break;
659cdf0e10cSrcweir 		case NavigationBar::RECORD_PREV:
660cdf0e10cSrcweir 			pWnd = &m_aPrevBtn;
661cdf0e10cSrcweir 			break;
662cdf0e10cSrcweir 		case NavigationBar::RECORD_NEXT:
663cdf0e10cSrcweir 			pWnd = &m_aNextBtn;
664cdf0e10cSrcweir 			break;
665cdf0e10cSrcweir 		case NavigationBar::RECORD_LAST:
666cdf0e10cSrcweir 			pWnd = &m_aLastBtn;
667cdf0e10cSrcweir 			break;
668cdf0e10cSrcweir 		case NavigationBar::RECORD_NEW:
669cdf0e10cSrcweir 			pWnd = &m_aNewBtn;
670cdf0e10cSrcweir 			break;
671cdf0e10cSrcweir 		case NavigationBar::RECORD_ABSOLUTE:
672cdf0e10cSrcweir 			pWnd = &m_aAbsolute;
673cdf0e10cSrcweir 			if (bAvailable)
674cdf0e10cSrcweir 			{
675cdf0e10cSrcweir 				if (pParent->m_nTotalCount >= 0)
676cdf0e10cSrcweir 				{
677cdf0e10cSrcweir 					if (pParent->IsCurrentAppending())
678cdf0e10cSrcweir 						m_aAbsolute.SetMax(pParent->m_nTotalCount + 1);
679cdf0e10cSrcweir 					else
680cdf0e10cSrcweir 						m_aAbsolute.SetMax(pParent->m_nTotalCount);
681cdf0e10cSrcweir 				}
682cdf0e10cSrcweir 				else
683cdf0e10cSrcweir 					m_aAbsolute.SetMax(LONG_MAX);
684cdf0e10cSrcweir 
685cdf0e10cSrcweir 				m_aAbsolute.SetValue(m_nCurrentPos + 1);
686cdf0e10cSrcweir 			}
687cdf0e10cSrcweir 			else
688cdf0e10cSrcweir 				m_aAbsolute.SetText(String());
689cdf0e10cSrcweir 			break;
690cdf0e10cSrcweir 		case NavigationBar::RECORD_TEXT:
691cdf0e10cSrcweir 			pWnd = &m_aRecordText;
692cdf0e10cSrcweir 			break;
693cdf0e10cSrcweir 		case NavigationBar::RECORD_OF:
694cdf0e10cSrcweir 			pWnd = &m_aRecordOf;
695cdf0e10cSrcweir 			break;
696cdf0e10cSrcweir 		case NavigationBar::RECORD_COUNT:
697cdf0e10cSrcweir 		{
698cdf0e10cSrcweir 			pWnd = &m_aRecordCount;
699cdf0e10cSrcweir 			String aText;
700cdf0e10cSrcweir 			if (bAvailable)
701cdf0e10cSrcweir 			{
702cdf0e10cSrcweir 				if (pParent->GetOptions() & DbGridControl::OPT_INSERT)
703cdf0e10cSrcweir 				{
704cdf0e10cSrcweir 					if (pParent->IsCurrentAppending() && !pParent->IsModified())
705cdf0e10cSrcweir 						aText = String::CreateFromInt32(pParent->GetRowCount());
706cdf0e10cSrcweir 					else
707cdf0e10cSrcweir 						aText = String::CreateFromInt32(pParent->GetRowCount() - 1);
708cdf0e10cSrcweir 				}
709cdf0e10cSrcweir 				else
710cdf0e10cSrcweir 					aText = String::CreateFromInt32(pParent->GetRowCount());
711cdf0e10cSrcweir 				if(!pParent->m_bRecordCountFinal)
712cdf0e10cSrcweir 					aText += String::CreateFromAscii(" *");
713cdf0e10cSrcweir 			}
714cdf0e10cSrcweir 			else
715cdf0e10cSrcweir 				aText = String();
716cdf0e10cSrcweir 
717cdf0e10cSrcweir 			// add the number of selected rows, if applicable
718cdf0e10cSrcweir 			if (pParent->GetSelectRowCount())
719cdf0e10cSrcweir 			{
720cdf0e10cSrcweir 				String aExtendedInfo(aText);
721cdf0e10cSrcweir 				aExtendedInfo.AppendAscii(" (");
722cdf0e10cSrcweir 				aExtendedInfo += String::CreateFromInt32(pParent->GetSelectRowCount());
723cdf0e10cSrcweir 				aExtendedInfo += ')';
724cdf0e10cSrcweir 				pWnd->SetText(aExtendedInfo);
725cdf0e10cSrcweir 			}
726cdf0e10cSrcweir 			else
727cdf0e10cSrcweir 				pWnd->SetText(aText);
728cdf0e10cSrcweir 
729cdf0e10cSrcweir 			pParent->SetRealRowCount(aText);
730cdf0e10cSrcweir 		}	break;
731cdf0e10cSrcweir 	}
732cdf0e10cSrcweir 	DBG_ASSERT(pWnd, "kein Fenster");
733cdf0e10cSrcweir 	if (pWnd && (pWnd->IsEnabled() != bAvailable))
734cdf0e10cSrcweir 		// this "pWnd->IsEnabled() != bAvailable" is a little hack : Window::Enable always generates a user
735cdf0e10cSrcweir 		// event (ImplGenerateMouseMove) even if nothing happened. This may lead to some unwanted effects, so we
736cdf0e10cSrcweir 		// do this check.
737cdf0e10cSrcweir 		// For further explanation see Bug 69900.
738cdf0e10cSrcweir 		// FS - 18.11.99
739cdf0e10cSrcweir 		pWnd->Enable(bAvailable);
740cdf0e10cSrcweir }
741cdf0e10cSrcweir 
742cdf0e10cSrcweir //------------------------------------------------------------------------------
Resize()743cdf0e10cSrcweir void DbGridControl::NavigationBar::Resize()
744cdf0e10cSrcweir {
745cdf0e10cSrcweir 	Control::Resize();
746cdf0e10cSrcweir 	ArrangeControls();
747cdf0e10cSrcweir }
748cdf0e10cSrcweir 
749cdf0e10cSrcweir //------------------------------------------------------------------------------
Paint(const Rectangle & rRect)750cdf0e10cSrcweir void DbGridControl::NavigationBar::Paint(const Rectangle& rRect)
751cdf0e10cSrcweir {
752cdf0e10cSrcweir 	Control::Paint(rRect);
753cdf0e10cSrcweir 	Point aAbsolutePos = m_aAbsolute.GetPosPixel();
754cdf0e10cSrcweir 	Size  aAbsoluteSize = m_aAbsolute.GetSizePixel();
755cdf0e10cSrcweir 
756cdf0e10cSrcweir 	DrawLine(Point(aAbsolutePos.X() - 1, 0 ),
757cdf0e10cSrcweir 			 Point(aAbsolutePos.X() - 1, aAbsolutePos.Y() + aAbsoluteSize.Height()));
758cdf0e10cSrcweir 
759cdf0e10cSrcweir 	DrawLine(Point(aAbsolutePos.X() + aAbsoluteSize.Width() + 1, 0 ),
760cdf0e10cSrcweir 			 Point(aAbsolutePos.X() + aAbsoluteSize.Width() + 1, aAbsolutePos.Y() + aAbsoluteSize.Height()));
761cdf0e10cSrcweir }
762cdf0e10cSrcweir 
763cdf0e10cSrcweir //------------------------------------------------------------------------------
StateChanged(StateChangedType nType)764cdf0e10cSrcweir void DbGridControl::NavigationBar::StateChanged( StateChangedType nType )
765cdf0e10cSrcweir {
766cdf0e10cSrcweir 	Control::StateChanged( nType );
767cdf0e10cSrcweir 
768cdf0e10cSrcweir     Window* pWindows[] = {  &m_aRecordText,
769cdf0e10cSrcweir                             &m_aAbsolute,
770cdf0e10cSrcweir                             &m_aRecordOf,
771cdf0e10cSrcweir                             &m_aRecordCount,
772cdf0e10cSrcweir                             &m_aFirstBtn,
773cdf0e10cSrcweir                             &m_aPrevBtn,
774cdf0e10cSrcweir                             &m_aNextBtn,
775cdf0e10cSrcweir                             &m_aLastBtn,
776cdf0e10cSrcweir                             &m_aNewBtn
777cdf0e10cSrcweir                         };
778cdf0e10cSrcweir 
779cdf0e10cSrcweir     switch ( nType )
780cdf0e10cSrcweir     {
781cdf0e10cSrcweir         case STATE_CHANGE_MIRRORING:
782cdf0e10cSrcweir         {
783cdf0e10cSrcweir             sal_Bool bIsRTLEnabled = IsRTLEnabled();
784cdf0e10cSrcweir             for ( size_t i=0; i < sizeof( pWindows ) / sizeof( pWindows[0] ); ++i )
785cdf0e10cSrcweir                 pWindows[i]->EnableRTL( bIsRTLEnabled );
786cdf0e10cSrcweir         }
787cdf0e10cSrcweir         break;
788cdf0e10cSrcweir 
789cdf0e10cSrcweir         case STATE_CHANGE_ZOOM:
790cdf0e10cSrcweir         {
791cdf0e10cSrcweir             Fraction aZoom = GetZoom();
792cdf0e10cSrcweir 
793cdf0e10cSrcweir             // not all of these controls need to know the new zoom, but to be sure ...
794cdf0e10cSrcweir             Font aFont( GetSettings().GetStyleSettings().GetFieldFont() );
795cdf0e10cSrcweir             if ( IsControlFont() )
796cdf0e10cSrcweir                 aFont.Merge( GetControlFont() );
797cdf0e10cSrcweir 
798cdf0e10cSrcweir             for (size_t i=0; i < sizeof(pWindows)/sizeof(pWindows[0]); ++i)
799cdf0e10cSrcweir             {
800cdf0e10cSrcweir                 pWindows[i]->SetZoom(aZoom);
801cdf0e10cSrcweir                 pWindows[i]->SetZoomedPointFont(aFont);
802cdf0e10cSrcweir             }
803cdf0e10cSrcweir 
804cdf0e10cSrcweir             SetZoomedPointFont( aFont );
805cdf0e10cSrcweir 
806cdf0e10cSrcweir             // rearrange the controls
807cdf0e10cSrcweir             m_nDefaultWidth = ArrangeControls();
808cdf0e10cSrcweir         }
809cdf0e10cSrcweir         break;
810cdf0e10cSrcweir     }
811cdf0e10cSrcweir }
812cdf0e10cSrcweir 
813cdf0e10cSrcweir //------------------------------------------------------------------------------
DbGridRow(CursorWrapper * pCur,sal_Bool bPaintCursor)814cdf0e10cSrcweir DbGridRow::DbGridRow(CursorWrapper* pCur, sal_Bool bPaintCursor)
815cdf0e10cSrcweir 		  :m_bIsNew(sal_False)
816cdf0e10cSrcweir {
817cdf0e10cSrcweir 
818cdf0e10cSrcweir 	if (pCur && pCur->Is())
819cdf0e10cSrcweir 	{
820cdf0e10cSrcweir 		Reference< XIndexAccess >  xColumns(pCur->getColumns(), UNO_QUERY);
821cdf0e10cSrcweir 		DataColumn* pColumn;
822cdf0e10cSrcweir 		for (sal_Int32 i = 0; i < xColumns->getCount(); ++i)
823cdf0e10cSrcweir 		{
824cdf0e10cSrcweir 			Reference< XPropertySet > xColSet;
825cdf0e10cSrcweir 			::cppu::extractInterface(xColSet, xColumns->getByIndex(i));
826cdf0e10cSrcweir 			pColumn = new DataColumn(xColSet);
827cdf0e10cSrcweir 			m_aVariants.Insert(pColumn, LIST_APPEND);
828cdf0e10cSrcweir 		}
829cdf0e10cSrcweir 
830cdf0e10cSrcweir 		if (pCur->rowDeleted())
831cdf0e10cSrcweir 			m_eStatus = GRS_DELETED;
832cdf0e10cSrcweir 		else
833cdf0e10cSrcweir 		{
834cdf0e10cSrcweir 			if (bPaintCursor)
835cdf0e10cSrcweir 				m_eStatus = (pCur->isAfterLast() || pCur->isBeforeFirst()) ? GRS_INVALID : GRS_CLEAN;
836cdf0e10cSrcweir 			else
837cdf0e10cSrcweir 			{
838cdf0e10cSrcweir 				Reference< XPropertySet > xSet = pCur->getPropertySet();
839cdf0e10cSrcweir 				if (xSet.is())
840cdf0e10cSrcweir 				{
841cdf0e10cSrcweir 					m_bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW));
842cdf0e10cSrcweir 					if (!m_bIsNew && (pCur->isAfterLast() || pCur->isBeforeFirst()))
843cdf0e10cSrcweir 						m_eStatus = GRS_INVALID;
844cdf0e10cSrcweir 					else if (::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISMODIFIED)))
845cdf0e10cSrcweir 						m_eStatus = GRS_MODIFIED;
846cdf0e10cSrcweir 					else
847cdf0e10cSrcweir 						m_eStatus = GRS_CLEAN;
848cdf0e10cSrcweir 				}
849cdf0e10cSrcweir 				else
850cdf0e10cSrcweir 					m_eStatus = GRS_INVALID;
851cdf0e10cSrcweir 			}
852cdf0e10cSrcweir 		}
853cdf0e10cSrcweir 		if (!m_bIsNew && IsValid())
854cdf0e10cSrcweir 			m_aBookmark = pCur->getBookmark();
855cdf0e10cSrcweir 		else
856cdf0e10cSrcweir 			m_aBookmark = Any();
857cdf0e10cSrcweir 	}
858cdf0e10cSrcweir 	else
859cdf0e10cSrcweir 		m_eStatus = GRS_INVALID;
860cdf0e10cSrcweir }
861cdf0e10cSrcweir 
862cdf0e10cSrcweir //------------------------------------------------------------------------------
~DbGridRow()863cdf0e10cSrcweir DbGridRow::~DbGridRow()
864cdf0e10cSrcweir {
865cdf0e10cSrcweir 	sal_uInt32 nCount = m_aVariants.Count();
866cdf0e10cSrcweir 	for (sal_uInt32 i = 0; i < nCount; i++)
867cdf0e10cSrcweir 		delete m_aVariants.GetObject(i);
868cdf0e10cSrcweir }
869cdf0e10cSrcweir 
870cdf0e10cSrcweir //------------------------------------------------------------------------------
SetState(CursorWrapper * pCur,sal_Bool bPaintCursor)871cdf0e10cSrcweir void DbGridRow::SetState(CursorWrapper* pCur, sal_Bool bPaintCursor)
872cdf0e10cSrcweir {
873cdf0e10cSrcweir 	if (pCur && pCur->Is())
874cdf0e10cSrcweir 	{
875cdf0e10cSrcweir 		if (pCur->rowDeleted())
876cdf0e10cSrcweir 		{
877cdf0e10cSrcweir 			m_eStatus = GRS_DELETED;
878cdf0e10cSrcweir 			m_bIsNew = sal_False;
879cdf0e10cSrcweir 		}
880cdf0e10cSrcweir 		else
881cdf0e10cSrcweir 		{
882cdf0e10cSrcweir 			m_eStatus = GRS_CLEAN;
883cdf0e10cSrcweir 			if (!bPaintCursor)
884cdf0e10cSrcweir 			{
885cdf0e10cSrcweir 				Reference< XPropertySet > xSet = pCur->getPropertySet();
886cdf0e10cSrcweir 				DBG_ASSERT(xSet.is(), "DbGridRow::SetState : invalid cursor !");
887cdf0e10cSrcweir 
888cdf0e10cSrcweir 				if (::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISMODIFIED)))
889cdf0e10cSrcweir 					m_eStatus = GRS_MODIFIED;
890cdf0e10cSrcweir 				m_bIsNew = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW));
891cdf0e10cSrcweir 			}
892cdf0e10cSrcweir 			else
893cdf0e10cSrcweir 				m_bIsNew = sal_False;
894cdf0e10cSrcweir 		}
895cdf0e10cSrcweir 
896cdf0e10cSrcweir         try
897cdf0e10cSrcweir         {
898cdf0e10cSrcweir 		    if (!m_bIsNew && IsValid())
899cdf0e10cSrcweir 			    m_aBookmark = pCur->getBookmark();
900cdf0e10cSrcweir 		    else
901cdf0e10cSrcweir 			    m_aBookmark = Any();
902cdf0e10cSrcweir         }
903cdf0e10cSrcweir         catch(SQLException&)
904cdf0e10cSrcweir         {
905cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
906cdf0e10cSrcweir             m_aBookmark = Any();
907cdf0e10cSrcweir             m_eStatus = GRS_INVALID;
908cdf0e10cSrcweir 		    m_bIsNew = sal_False;
909cdf0e10cSrcweir         }
910cdf0e10cSrcweir 	}
911cdf0e10cSrcweir 	else
912cdf0e10cSrcweir 	{
913cdf0e10cSrcweir 		m_aBookmark = Any();
914cdf0e10cSrcweir 		m_eStatus = GRS_INVALID;
915cdf0e10cSrcweir 		m_bIsNew = sal_False;
916cdf0e10cSrcweir 	}
917cdf0e10cSrcweir }
918cdf0e10cSrcweir 
919cdf0e10cSrcweir DBG_NAME(DbGridControl);
920cdf0e10cSrcweir //------------------------------------------------------------------------------
DbGridControl(Reference<XMultiServiceFactory> _rxFactory,Window * pParent,WinBits nBits)921cdf0e10cSrcweir DbGridControl::DbGridControl(
922cdf0e10cSrcweir 				Reference< XMultiServiceFactory > _rxFactory,
923cdf0e10cSrcweir 				Window* pParent,
924cdf0e10cSrcweir 				WinBits nBits)
925cdf0e10cSrcweir 			:DbGridControl_Base(pParent, EBBF_NONE, nBits, DEFAULT_BROWSE_MODE )
926cdf0e10cSrcweir             ,m_xServiceFactory(_rxFactory)
927cdf0e10cSrcweir             ,m_aBar(this)
928cdf0e10cSrcweir             ,m_nAsynAdjustEvent(0)
929cdf0e10cSrcweir             ,m_pDataSourcePropMultiplexer(NULL)
930cdf0e10cSrcweir             ,m_pDataSourcePropListener(NULL)
931cdf0e10cSrcweir             ,m_pFieldListeners(NULL)
932cdf0e10cSrcweir             ,m_pCursorDisposeListener(NULL)
933cdf0e10cSrcweir             ,m_pGridListener(NULL)
934cdf0e10cSrcweir             ,m_pDataCursor(NULL)
935cdf0e10cSrcweir             ,m_pSeekCursor(NULL)
936cdf0e10cSrcweir             ,m_nSeekPos(-1)
937cdf0e10cSrcweir             ,m_nTotalCount(-1)
938cdf0e10cSrcweir             ,m_aNullDate(OTypeConversionClient().getStandardDate())
939cdf0e10cSrcweir             ,m_nMode(DEFAULT_BROWSE_MODE)
940cdf0e10cSrcweir             ,m_nCurrentPos(-1)
941cdf0e10cSrcweir             ,m_nDeleteEvent(0)
942cdf0e10cSrcweir             ,m_nOptions(OPT_READONLY)
943cdf0e10cSrcweir             ,m_nOptionMask(OPT_INSERT | OPT_UPDATE | OPT_DELETE)
944cdf0e10cSrcweir 	        ,m_nLastColId((sal_uInt16)-1)
945cdf0e10cSrcweir             ,m_nLastRowId(-1)
946cdf0e10cSrcweir             ,m_bDesignMode(sal_False)
947cdf0e10cSrcweir             ,m_bRecordCountFinal(sal_False)
948cdf0e10cSrcweir             ,m_bMultiSelection(sal_True)
949cdf0e10cSrcweir             ,m_bNavigationBar(sal_True)
950cdf0e10cSrcweir             ,m_bSynchDisplay(sal_True)
951cdf0e10cSrcweir             ,m_bForceROController(sal_False)
952cdf0e10cSrcweir             ,m_bHandle(sal_True)
953cdf0e10cSrcweir             ,m_bFilterMode(sal_False)
954cdf0e10cSrcweir             ,m_bWantDestruction(sal_False)
955cdf0e10cSrcweir             ,m_bInAdjustDataSource(sal_False)
956cdf0e10cSrcweir             ,m_bPendingAdjustRows(sal_False)
957cdf0e10cSrcweir             ,m_bHideScrollbars( sal_False )
958cdf0e10cSrcweir             ,m_bUpdating(sal_False)
959cdf0e10cSrcweir {
960cdf0e10cSrcweir 	DBG_CTOR(DbGridControl,NULL);
961cdf0e10cSrcweir 
962cdf0e10cSrcweir     String sName(SVX_RES(RID_STR_NAVIGATIONBAR));
963cdf0e10cSrcweir     m_aBar.SetAccessibleName(sName);
964cdf0e10cSrcweir     m_aBar.Show();
965cdf0e10cSrcweir     ImplInitWindow( InitAll );
966cdf0e10cSrcweir }
967cdf0e10cSrcweir 
968cdf0e10cSrcweir //------------------------------------------------------------------------------
InsertHandleColumn()969cdf0e10cSrcweir void DbGridControl::InsertHandleColumn()
970cdf0e10cSrcweir {
971cdf0e10cSrcweir 	// Handle Column einfuegen
972cdf0e10cSrcweir 	// Da die BrowseBox ohne handleColums Paintprobleme hat
973cdf0e10cSrcweir 	// wird diese versteckt
974cdf0e10cSrcweir 	if (HasHandle())
975cdf0e10cSrcweir 		BrowseBox::InsertHandleColumn(GetDefaultColumnWidth(String()));
976cdf0e10cSrcweir 	else
977cdf0e10cSrcweir 		BrowseBox::InsertHandleColumn(0);
978cdf0e10cSrcweir }
979cdf0e10cSrcweir 
980cdf0e10cSrcweir //------------------------------------------------------------------------------
Init()981cdf0e10cSrcweir void DbGridControl::Init()
982cdf0e10cSrcweir {
983cdf0e10cSrcweir 	BrowserHeader* pNewHeader = CreateHeaderBar(this);
984cdf0e10cSrcweir 	pHeader->SetMouseTransparent(sal_False);
985cdf0e10cSrcweir 
986cdf0e10cSrcweir     SetHeaderBar(pNewHeader);
987cdf0e10cSrcweir 	SetMode(m_nMode);
988cdf0e10cSrcweir 	SetCursorColor(Color(0xFF, 0, 0));
989cdf0e10cSrcweir 
990cdf0e10cSrcweir 	InsertHandleColumn();
991cdf0e10cSrcweir }
992cdf0e10cSrcweir 
993cdf0e10cSrcweir //------------------------------------------------------------------------------
~DbGridControl()994cdf0e10cSrcweir DbGridControl::~DbGridControl()
995cdf0e10cSrcweir {
996cdf0e10cSrcweir 	RemoveColumns();
997cdf0e10cSrcweir 
998cdf0e10cSrcweir 	{
999cdf0e10cSrcweir 		m_bWantDestruction = sal_True;
1000cdf0e10cSrcweir 		osl::MutexGuard aGuard(m_aDestructionSafety);
1001cdf0e10cSrcweir 		if (m_pFieldListeners)
1002cdf0e10cSrcweir 			DisconnectFromFields();
1003cdf0e10cSrcweir 		if (m_pCursorDisposeListener)
1004cdf0e10cSrcweir 		{
1005cdf0e10cSrcweir 			delete m_pCursorDisposeListener;
1006cdf0e10cSrcweir 			m_pCursorDisposeListener = NULL;
1007cdf0e10cSrcweir 		}
1008cdf0e10cSrcweir 	}
1009cdf0e10cSrcweir 
1010cdf0e10cSrcweir 	if (m_nDeleteEvent)
1011cdf0e10cSrcweir 		Application::RemoveUserEvent(m_nDeleteEvent);
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir 	if (m_pDataSourcePropMultiplexer)
1014cdf0e10cSrcweir 	{
1015cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer->dispose();
1016cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer->release();	// this should delete the multiplexer
1017cdf0e10cSrcweir 		delete m_pDataSourcePropListener;
1018cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer = NULL;
1019cdf0e10cSrcweir 		m_pDataSourcePropListener = NULL;
1020cdf0e10cSrcweir 	}
1021cdf0e10cSrcweir     m_xRowSetListener.clear();
1022cdf0e10cSrcweir 
1023cdf0e10cSrcweir 	delete m_pDataCursor;
1024cdf0e10cSrcweir 	delete m_pSeekCursor;
1025cdf0e10cSrcweir 
1026cdf0e10cSrcweir 	DBG_DTOR(DbGridControl,NULL);
1027cdf0e10cSrcweir }
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir //------------------------------------------------------------------------------
StateChanged(StateChangedType nType)1030cdf0e10cSrcweir void DbGridControl::StateChanged( StateChangedType nType )
1031cdf0e10cSrcweir {
1032cdf0e10cSrcweir 	DbGridControl_Base::StateChanged( nType );
1033cdf0e10cSrcweir 
1034cdf0e10cSrcweir     switch (nType)
1035cdf0e10cSrcweir 	{
1036cdf0e10cSrcweir         case STATE_CHANGE_MIRRORING:
1037cdf0e10cSrcweir 			ImplInitWindow( InitWritingMode );
1038cdf0e10cSrcweir             Invalidate();
1039cdf0e10cSrcweir             break;
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir 		case STATE_CHANGE_ZOOM:
1042cdf0e10cSrcweir 		{
1043cdf0e10cSrcweir 			ImplInitWindow( InitFont );
1044cdf0e10cSrcweir 
1045cdf0e10cSrcweir 			// and give it a chance to rearrange
1046cdf0e10cSrcweir 			Point aPoint = GetControlArea().TopLeft();
1047cdf0e10cSrcweir 			sal_uInt16 nX = (sal_uInt16)aPoint.X();
1048cdf0e10cSrcweir 			ArrangeControls(nX, (sal_uInt16)aPoint.Y());
1049cdf0e10cSrcweir 			ReserveControlArea((sal_uInt16)nX);
1050cdf0e10cSrcweir 		}
1051cdf0e10cSrcweir 		break;
1052cdf0e10cSrcweir 		case STATE_CHANGE_CONTROLFONT:
1053cdf0e10cSrcweir 			ImplInitWindow( InitFont );
1054cdf0e10cSrcweir 			Invalidate();
1055cdf0e10cSrcweir 			break;
1056cdf0e10cSrcweir 		case STATE_CHANGE_CONTROLFOREGROUND:
1057cdf0e10cSrcweir 			ImplInitWindow( InitForeground );
1058cdf0e10cSrcweir 			Invalidate();
1059cdf0e10cSrcweir 			break;
1060cdf0e10cSrcweir 		case STATE_CHANGE_CONTROLBACKGROUND:
1061cdf0e10cSrcweir 			ImplInitWindow( InitBackground );
1062cdf0e10cSrcweir 			Invalidate();
1063cdf0e10cSrcweir 			break;
1064cdf0e10cSrcweir 	}
1065cdf0e10cSrcweir }
1066cdf0e10cSrcweir 
1067cdf0e10cSrcweir //------------------------------------------------------------------------------
DataChanged(const DataChangedEvent & rDCEvt)1068cdf0e10cSrcweir void DbGridControl::DataChanged( const DataChangedEvent& rDCEvt )
1069cdf0e10cSrcweir {
1070cdf0e10cSrcweir 	DbGridControl_Base::DataChanged( rDCEvt );
1071cdf0e10cSrcweir 	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS ) &&
1072cdf0e10cSrcweir 		 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1073cdf0e10cSrcweir 	{
1074cdf0e10cSrcweir 		ImplInitWindow( InitAll );
1075cdf0e10cSrcweir 		Invalidate();
1076cdf0e10cSrcweir 	}
1077cdf0e10cSrcweir }
1078cdf0e10cSrcweir 
1079cdf0e10cSrcweir //------------------------------------------------------------------------------
Select()1080cdf0e10cSrcweir void DbGridControl::Select()
1081cdf0e10cSrcweir {
1082cdf0e10cSrcweir 	DbGridControl_Base::Select();
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir 	// as the selected rows may have changed, udate the according display in our navigation bar
1085cdf0e10cSrcweir 	m_aBar.InvalidateState(NavigationBar::RECORD_COUNT);
1086cdf0e10cSrcweir 
1087cdf0e10cSrcweir 	if (m_pGridListener)
1088cdf0e10cSrcweir 		m_pGridListener->selectionChanged();
1089cdf0e10cSrcweir }
1090cdf0e10cSrcweir 
1091cdf0e10cSrcweir //------------------------------------------------------------------------------
ImplInitWindow(const InitWindowFacet _eInitWhat)1092cdf0e10cSrcweir void DbGridControl::ImplInitWindow( const InitWindowFacet _eInitWhat )
1093cdf0e10cSrcweir {
1094cdf0e10cSrcweir 	for ( sal_uInt32 i = 0; i < m_aColumns.Count(); ++i )
1095cdf0e10cSrcweir 	{
1096cdf0e10cSrcweir 		DbGridColumn* pCol = m_aColumns.GetObject(i);
1097cdf0e10cSrcweir 		if (pCol)
1098cdf0e10cSrcweir 			pCol->ImplInitWindow( GetDataWindow(), _eInitWhat );
1099cdf0e10cSrcweir 	}
1100cdf0e10cSrcweir 
1101cdf0e10cSrcweir     if ( ( _eInitWhat & InitWritingMode ) != 0 )
1102cdf0e10cSrcweir     {
1103cdf0e10cSrcweir 		if ( m_bNavigationBar )
1104cdf0e10cSrcweir         {
1105cdf0e10cSrcweir 			m_aBar.EnableRTL( IsRTLEnabled() );
1106cdf0e10cSrcweir         }
1107cdf0e10cSrcweir     }
1108cdf0e10cSrcweir 
1109cdf0e10cSrcweir     if ( ( _eInitWhat & InitFont ) != 0 )
1110cdf0e10cSrcweir     {
1111cdf0e10cSrcweir 		if ( m_bNavigationBar )
1112cdf0e10cSrcweir         {
1113cdf0e10cSrcweir 	        Font aFont = m_aBar.GetSettings().GetStyleSettings().GetFieldFont();
1114cdf0e10cSrcweir             if ( IsControlFont() )
1115cdf0e10cSrcweir                 m_aBar.SetControlFont( GetControlFont() );
1116cdf0e10cSrcweir             else
1117cdf0e10cSrcweir                 m_aBar.SetControlFont();
1118cdf0e10cSrcweir 
1119cdf0e10cSrcweir 			m_aBar.SetZoom( GetZoom() );
1120cdf0e10cSrcweir         }
1121cdf0e10cSrcweir     }
1122cdf0e10cSrcweir 
1123cdf0e10cSrcweir     if ( ( _eInitWhat & InitBackground ) != 0 )
1124cdf0e10cSrcweir 	{
1125cdf0e10cSrcweir 		if (IsControlBackground())
1126cdf0e10cSrcweir 		{
1127cdf0e10cSrcweir 			GetDataWindow().SetBackground(GetControlBackground());
1128cdf0e10cSrcweir 			GetDataWindow().SetControlBackground(GetControlBackground());
1129cdf0e10cSrcweir 			GetDataWindow().SetFillColor(GetControlBackground());
1130cdf0e10cSrcweir 		}
1131cdf0e10cSrcweir 		else
1132cdf0e10cSrcweir 		{
1133cdf0e10cSrcweir 			GetDataWindow().SetControlBackground();
1134cdf0e10cSrcweir 			GetDataWindow().SetFillColor(GetFillColor());
1135cdf0e10cSrcweir 		}
1136cdf0e10cSrcweir 	}
1137cdf0e10cSrcweir }
1138cdf0e10cSrcweir 
1139cdf0e10cSrcweir //------------------------------------------------------------------------------
RemoveRows(sal_Bool bNewCursor)1140cdf0e10cSrcweir void DbGridControl::RemoveRows(sal_Bool bNewCursor)
1141cdf0e10cSrcweir {
1142cdf0e10cSrcweir 	// Hat sich der DatenCursor verandert ?
1143cdf0e10cSrcweir 	if (!bNewCursor)
1144cdf0e10cSrcweir 	{
1145cdf0e10cSrcweir 		DELETEZ(m_pSeekCursor);
1146cdf0e10cSrcweir 		m_xPaintRow = m_xDataRow = m_xEmptyRow	= m_xCurrentRow = m_xSeekRow = NULL;
1147cdf0e10cSrcweir 		m_nCurrentPos = m_nSeekPos = -1;
1148cdf0e10cSrcweir 		m_nOptions	= OPT_READONLY;
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir 		RowRemoved(0, GetRowCount(), sal_False);
1151cdf0e10cSrcweir 		m_nTotalCount = -1;
1152cdf0e10cSrcweir 	}
1153cdf0e10cSrcweir 	else
1154cdf0e10cSrcweir 	{
1155cdf0e10cSrcweir 		RemoveRows();
1156cdf0e10cSrcweir 	}
1157cdf0e10cSrcweir }
1158cdf0e10cSrcweir 
1159cdf0e10cSrcweir //------------------------------------------------------------------------------
RemoveRows()1160cdf0e10cSrcweir void DbGridControl::RemoveRows()
1161cdf0e10cSrcweir {
1162cdf0e10cSrcweir 	// we're going to remove all columns and all row, so deactivate the current cell
1163cdf0e10cSrcweir 	if (IsEditing())
1164cdf0e10cSrcweir 		DeactivateCell();
1165cdf0e10cSrcweir 
1166cdf0e10cSrcweir 	// alle Columns deinitialisieren
1167cdf0e10cSrcweir 	// existieren Spalten, dann alle Controller freigeben
1168cdf0e10cSrcweir 	for (sal_uInt32 i = 0; i < m_aColumns.Count(); i++)
1169cdf0e10cSrcweir 		m_aColumns.GetObject(i)->Clear();
1170cdf0e10cSrcweir 
1171cdf0e10cSrcweir 	DELETEZ(m_pSeekCursor);
1172cdf0e10cSrcweir 	DELETEZ(m_pDataCursor);
1173cdf0e10cSrcweir 
1174cdf0e10cSrcweir 	m_xPaintRow = m_xDataRow = m_xEmptyRow	= m_xCurrentRow = m_xSeekRow = NULL;
1175cdf0e10cSrcweir 	m_nCurrentPos = m_nSeekPos = m_nTotalCount	= -1;
1176cdf0e10cSrcweir 	m_nOptions	= OPT_READONLY;
1177cdf0e10cSrcweir 
1178cdf0e10cSrcweir 	// Anzahl Saetze im Browser auf 0 zuruecksetzen
1179cdf0e10cSrcweir 	DbGridControl_Base::RemoveRows();
1180cdf0e10cSrcweir 	m_aBar.InvalidateAll(m_nCurrentPos, sal_True);
1181cdf0e10cSrcweir }
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir //------------------------------------------------------------------------------
ArrangeControls(sal_uInt16 & nX,sal_uInt16 nY)1184cdf0e10cSrcweir void DbGridControl::ArrangeControls(sal_uInt16& nX, sal_uInt16 nY)
1185cdf0e10cSrcweir {
1186cdf0e10cSrcweir 	// Positionierung der Controls
1187cdf0e10cSrcweir 	if (m_bNavigationBar)
1188cdf0e10cSrcweir 	{
1189cdf0e10cSrcweir 		nX = m_aBar.GetDefaultWidth();
1190cdf0e10cSrcweir 		Rectangle	aRect(GetControlArea());
1191cdf0e10cSrcweir 		m_aBar.SetPosSizePixel(Point(0,nY + 1), Size(nX, aRect.GetSize().Height() - 1));
1192cdf0e10cSrcweir 	}
1193cdf0e10cSrcweir }
1194cdf0e10cSrcweir 
1195cdf0e10cSrcweir //------------------------------------------------------------------------------
EnableHandle(sal_Bool bEnable)1196cdf0e10cSrcweir void DbGridControl::EnableHandle(sal_Bool bEnable)
1197cdf0e10cSrcweir {
1198cdf0e10cSrcweir 	if (m_bHandle == bEnable)
1199cdf0e10cSrcweir 		return;
1200cdf0e10cSrcweir 
1201cdf0e10cSrcweir 	// HandleColumn wird nur ausgeblendet,
1202cdf0e10cSrcweir 	// da es sonst etliche Probleme mit dem Zeichnen gibt
1203cdf0e10cSrcweir 	RemoveColumn(0);
1204cdf0e10cSrcweir 	m_bHandle = bEnable;
1205cdf0e10cSrcweir 	InsertHandleColumn();
1206cdf0e10cSrcweir }
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir //------------------------------------------------------------------------------
1209cdf0e10cSrcweir namespace
1210cdf0e10cSrcweir {
adjustModeForScrollbars(BrowserMode & _rMode,sal_Bool _bNavigationBar,sal_Bool _bHideScrollbars)1211cdf0e10cSrcweir     bool adjustModeForScrollbars( BrowserMode& _rMode, sal_Bool _bNavigationBar, sal_Bool _bHideScrollbars )
1212cdf0e10cSrcweir     {
1213cdf0e10cSrcweir         BrowserMode nOldMode = _rMode;
1214cdf0e10cSrcweir 
1215cdf0e10cSrcweir 		if ( !_bNavigationBar )
1216cdf0e10cSrcweir         {
1217cdf0e10cSrcweir             _rMode &= ~BROWSER_AUTO_HSCROLL;
1218cdf0e10cSrcweir         }
1219cdf0e10cSrcweir 
1220cdf0e10cSrcweir         if ( _bHideScrollbars )
1221cdf0e10cSrcweir         {
1222cdf0e10cSrcweir             _rMode |= ( BROWSER_NO_HSCROLL | BROWSER_NO_VSCROLL );
1223cdf0e10cSrcweir             _rMode &= ~( BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL );
1224cdf0e10cSrcweir         }
1225cdf0e10cSrcweir         else
1226cdf0e10cSrcweir         {
1227cdf0e10cSrcweir             _rMode |= ( BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL );
1228cdf0e10cSrcweir             _rMode &= ~( BROWSER_NO_HSCROLL | BROWSER_NO_VSCROLL );
1229cdf0e10cSrcweir         }
1230cdf0e10cSrcweir 
1231cdf0e10cSrcweir         // note: if we have a navigation bar, we always have a AUTO_HSCROLL. In particular,
1232cdf0e10cSrcweir         // _bHideScrollbars is ignored then
1233cdf0e10cSrcweir 		if ( _bNavigationBar )
1234cdf0e10cSrcweir         {
1235cdf0e10cSrcweir 			_rMode |= BROWSER_AUTO_HSCROLL;
1236cdf0e10cSrcweir             _rMode &= ~BROWSER_NO_HSCROLL;
1237cdf0e10cSrcweir         }
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir         return nOldMode != _rMode;
1240cdf0e10cSrcweir     }
1241cdf0e10cSrcweir }
1242cdf0e10cSrcweir 
1243cdf0e10cSrcweir //------------------------------------------------------------------------------
EnableNavigationBar(sal_Bool bEnable)1244cdf0e10cSrcweir void DbGridControl::EnableNavigationBar(sal_Bool bEnable)
1245cdf0e10cSrcweir {
1246cdf0e10cSrcweir 	if (m_bNavigationBar == bEnable)
1247cdf0e10cSrcweir 		return;
1248cdf0e10cSrcweir 
1249cdf0e10cSrcweir 	m_bNavigationBar = bEnable;
1250cdf0e10cSrcweir 
1251cdf0e10cSrcweir     if (bEnable)
1252cdf0e10cSrcweir 	{
1253cdf0e10cSrcweir 		m_aBar.Show();
1254cdf0e10cSrcweir 		m_aBar.Enable();
1255cdf0e10cSrcweir 		m_aBar.InvalidateAll(m_nCurrentPos, sal_True);
1256cdf0e10cSrcweir 
1257cdf0e10cSrcweir         if ( adjustModeForScrollbars( m_nMode, m_bNavigationBar, m_bHideScrollbars ) )
1258cdf0e10cSrcweir             SetMode( m_nMode );
1259cdf0e10cSrcweir 
1260cdf0e10cSrcweir 		// liefert die Groe�e der Reserved ControlArea
1261cdf0e10cSrcweir 		Point aPoint = GetControlArea().TopLeft();
1262cdf0e10cSrcweir 		sal_uInt16 nX = (sal_uInt16)aPoint.X();
1263cdf0e10cSrcweir 
1264cdf0e10cSrcweir 		ArrangeControls(nX, (sal_uInt16)aPoint.Y());
1265cdf0e10cSrcweir 		ReserveControlArea((sal_uInt16)nX);
1266cdf0e10cSrcweir 	}
1267cdf0e10cSrcweir 	else
1268cdf0e10cSrcweir 	{
1269cdf0e10cSrcweir 		m_aBar.Hide();
1270cdf0e10cSrcweir 		m_aBar.Disable();
1271cdf0e10cSrcweir 
1272cdf0e10cSrcweir         if ( adjustModeForScrollbars( m_nMode, m_bNavigationBar, m_bHideScrollbars ) )
1273cdf0e10cSrcweir             SetMode( m_nMode );
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir 		ReserveControlArea();
1276cdf0e10cSrcweir 	}
1277cdf0e10cSrcweir }
1278cdf0e10cSrcweir 
1279cdf0e10cSrcweir //------------------------------------------------------------------------------
SetOptions(sal_uInt16 nOpt)1280cdf0e10cSrcweir sal_uInt16 DbGridControl::SetOptions(sal_uInt16 nOpt)
1281cdf0e10cSrcweir {
1282cdf0e10cSrcweir 	DBG_ASSERT(!m_xCurrentRow || !m_xCurrentRow->IsModified(),
1283cdf0e10cSrcweir 		"DbGridControl::SetOptions : please do not call when editing a record (things are much easier this way ;) !");
1284cdf0e10cSrcweir 
1285cdf0e10cSrcweir 	// for the next setDataSource (which is triggered by a refresh, for instance)
1286cdf0e10cSrcweir 	m_nOptionMask = nOpt;
1287cdf0e10cSrcweir 
1288cdf0e10cSrcweir 	// normalize the new options
1289cdf0e10cSrcweir 	Reference< XPropertySet > xDataSourceSet = m_pDataCursor->getPropertySet();
1290cdf0e10cSrcweir 	if (xDataSourceSet.is())
1291cdf0e10cSrcweir 	{
1292cdf0e10cSrcweir 		// feststellen welche Updatem�glichkeiten bestehen
1293cdf0e10cSrcweir 		sal_Int32 nPrivileges = 0;
1294cdf0e10cSrcweir 		xDataSourceSet->getPropertyValue(FM_PROP_PRIVILEGES) >>= nPrivileges;
1295cdf0e10cSrcweir 		if ((nPrivileges & Privilege::INSERT) == 0)
1296cdf0e10cSrcweir 			nOpt &= ~OPT_INSERT;
1297cdf0e10cSrcweir 		if ((nPrivileges & Privilege::UPDATE) == 0)
1298cdf0e10cSrcweir 			nOpt &= ~OPT_UPDATE;
1299cdf0e10cSrcweir 		if ((nPrivileges & Privilege::DELETE) == 0)
1300cdf0e10cSrcweir 			nOpt &= ~OPT_DELETE;
1301cdf0e10cSrcweir 	}
1302cdf0e10cSrcweir 	else
1303cdf0e10cSrcweir 		nOpt = OPT_READONLY;
1304cdf0e10cSrcweir 
1305cdf0e10cSrcweir 	// need to do something after that ?
1306cdf0e10cSrcweir 	if (nOpt == m_nOptions)
1307cdf0e10cSrcweir 		return m_nOptions;
1308cdf0e10cSrcweir 
1309cdf0e10cSrcweir 	// the 'update' option only affects our BrowserMode (with or w/o focus rect)
1310cdf0e10cSrcweir 	BrowserMode nNewMode = m_nMode;
1311cdf0e10cSrcweir 	if ((m_nMode & BROWSER_CURSOR_WO_FOCUS) == 0)
1312cdf0e10cSrcweir 	{
1313cdf0e10cSrcweir 		if (nOpt & OPT_UPDATE)
1314cdf0e10cSrcweir 			nNewMode |= BROWSER_HIDECURSOR;
1315cdf0e10cSrcweir 		else
1316cdf0e10cSrcweir 			nNewMode &= ~BROWSER_HIDECURSOR;
1317cdf0e10cSrcweir 	}
1318cdf0e10cSrcweir 	else
1319cdf0e10cSrcweir 		nNewMode &= ~BROWSER_HIDECURSOR;
1320cdf0e10cSrcweir 		// should not be neccessary if EnablePermanentCursor is used to change the cursor behaviour, but to be sure ...
1321cdf0e10cSrcweir 
1322cdf0e10cSrcweir 	if (nNewMode != m_nMode)
1323cdf0e10cSrcweir 	{
1324cdf0e10cSrcweir 		SetMode(nNewMode);
1325cdf0e10cSrcweir 		m_nMode = nNewMode;
1326cdf0e10cSrcweir 	}
1327cdf0e10cSrcweir 
1328cdf0e10cSrcweir 	// _after_ setting the mode because this results in an ActivateCell
1329cdf0e10cSrcweir 	DeactivateCell();
1330cdf0e10cSrcweir 
1331cdf0e10cSrcweir 	sal_Bool bInsertChanged = (nOpt & OPT_INSERT) != (m_nOptions & OPT_INSERT);
1332cdf0e10cSrcweir 	m_nOptions = nOpt;
1333cdf0e10cSrcweir 		// we need to set this before the code below because it indirectly uses m_nOptions
1334cdf0e10cSrcweir 
1335cdf0e10cSrcweir 	// the 'insert' option affects our empty row
1336cdf0e10cSrcweir 	if (bInsertChanged)
1337cdf0e10cSrcweir 	{
1338cdf0e10cSrcweir 		if (m_nOptions & OPT_INSERT)
1339cdf0e10cSrcweir 		{	// the insert option is to be set
1340cdf0e10cSrcweir 			m_xEmptyRow = new DbGridRow();
1341cdf0e10cSrcweir 			RowInserted(GetRowCount(), 1, sal_True);
1342cdf0e10cSrcweir 		}
1343cdf0e10cSrcweir 		else
1344cdf0e10cSrcweir 		{	// the insert option is to be reset
1345cdf0e10cSrcweir 			m_xEmptyRow = NULL;
1346cdf0e10cSrcweir 			if ((GetCurRow() == GetRowCount() - 1) && (GetCurRow() > 0))
1347cdf0e10cSrcweir 				GoToRowColumnId(GetCurRow() - 1, GetCurColumnId());
1348cdf0e10cSrcweir 			RowRemoved(GetRowCount(), 1, sal_True);
1349cdf0e10cSrcweir 		}
1350cdf0e10cSrcweir 	}
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir 	// the 'delete' options has no immediate consequences
1353cdf0e10cSrcweir 
1354cdf0e10cSrcweir 	ActivateCell();
1355cdf0e10cSrcweir 	Invalidate();
1356cdf0e10cSrcweir 	return m_nOptions;
1357cdf0e10cSrcweir }
1358cdf0e10cSrcweir 
1359cdf0e10cSrcweir //------------------------------------------------------------------------------
ForceHideScrollbars(sal_Bool _bForce)1360cdf0e10cSrcweir void DbGridControl::ForceHideScrollbars( sal_Bool _bForce )
1361cdf0e10cSrcweir {
1362cdf0e10cSrcweir     if ( m_bHideScrollbars == _bForce )
1363cdf0e10cSrcweir         return;
1364cdf0e10cSrcweir 
1365cdf0e10cSrcweir     m_bHideScrollbars = _bForce;
1366cdf0e10cSrcweir 
1367cdf0e10cSrcweir     if ( adjustModeForScrollbars( m_nMode, m_bNavigationBar, m_bHideScrollbars ) )
1368cdf0e10cSrcweir         SetMode( m_nMode );
1369cdf0e10cSrcweir }
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir //------------------------------------------------------------------------------
IsForceHideScrollbars() const1372cdf0e10cSrcweir sal_Bool DbGridControl::IsForceHideScrollbars() const
1373cdf0e10cSrcweir {
1374cdf0e10cSrcweir     return m_bHideScrollbars;
1375cdf0e10cSrcweir }
1376cdf0e10cSrcweir 
1377cdf0e10cSrcweir //------------------------------------------------------------------------------
EnablePermanentCursor(sal_Bool bEnable)1378cdf0e10cSrcweir void DbGridControl::EnablePermanentCursor(sal_Bool bEnable)
1379cdf0e10cSrcweir {
1380cdf0e10cSrcweir 	if (IsPermanentCursorEnabled() == bEnable)
1381cdf0e10cSrcweir 		return;
1382cdf0e10cSrcweir 
1383cdf0e10cSrcweir 	if (bEnable)
1384cdf0e10cSrcweir 	{
1385cdf0e10cSrcweir 		m_nMode &= ~BROWSER_HIDECURSOR; 	// without this BROWSER_CURSOR_WO_FOCUS won't have any affect
1386cdf0e10cSrcweir 		m_nMode |= BROWSER_CURSOR_WO_FOCUS;
1387cdf0e10cSrcweir 	}
1388cdf0e10cSrcweir 	else
1389cdf0e10cSrcweir 	{
1390cdf0e10cSrcweir 		if (m_nOptions & OPT_UPDATE)
1391cdf0e10cSrcweir 			m_nMode |= BROWSER_HIDECURSOR;		// no cursor at all
1392cdf0e10cSrcweir 		else
1393cdf0e10cSrcweir 			m_nMode &= ~BROWSER_HIDECURSOR; 	// at least the "non-permanent" cursor
1394cdf0e10cSrcweir 
1395cdf0e10cSrcweir 		m_nMode &= ~BROWSER_CURSOR_WO_FOCUS;
1396cdf0e10cSrcweir 	}
1397cdf0e10cSrcweir 	SetMode(m_nMode);
1398cdf0e10cSrcweir 
1399cdf0e10cSrcweir 	sal_Bool bWasEditing = IsEditing();
1400cdf0e10cSrcweir 	DeactivateCell();
1401cdf0e10cSrcweir 	if (bWasEditing)
1402cdf0e10cSrcweir 		ActivateCell();
1403cdf0e10cSrcweir }
1404cdf0e10cSrcweir 
1405cdf0e10cSrcweir //------------------------------------------------------------------------------
IsPermanentCursorEnabled() const1406cdf0e10cSrcweir sal_Bool DbGridControl::IsPermanentCursorEnabled() const
1407cdf0e10cSrcweir {
1408cdf0e10cSrcweir 	return ((m_nMode & BROWSER_CURSOR_WO_FOCUS) != 0) && ((m_nMode & BROWSER_HIDECURSOR) == 0);
1409cdf0e10cSrcweir }
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir //------------------------------------------------------------------------------
refreshController(sal_uInt16 _nColId,GrantControlAccess)1412cdf0e10cSrcweir void DbGridControl::refreshController(sal_uInt16 _nColId, GrantControlAccess /*_aAccess*/)
1413cdf0e10cSrcweir {
1414cdf0e10cSrcweir 	if ((GetCurColumnId() == _nColId) && IsEditing())
1415cdf0e10cSrcweir 	{	// the controller which is currently active needs to be refreshed
1416cdf0e10cSrcweir 		DeactivateCell();
1417cdf0e10cSrcweir 		ActivateCell();
1418cdf0e10cSrcweir 	}
1419cdf0e10cSrcweir }
1420cdf0e10cSrcweir 
1421cdf0e10cSrcweir //------------------------------------------------------------------------------
SetMultiSelection(sal_Bool bMulti)1422cdf0e10cSrcweir void DbGridControl::SetMultiSelection(sal_Bool bMulti)
1423cdf0e10cSrcweir {
1424cdf0e10cSrcweir 	m_bMultiSelection = bMulti;
1425cdf0e10cSrcweir 	if (m_bMultiSelection)
1426cdf0e10cSrcweir 		m_nMode |= BROWSER_MULTISELECTION;
1427cdf0e10cSrcweir 	else
1428cdf0e10cSrcweir 		m_nMode &= ~BROWSER_MULTISELECTION;
1429cdf0e10cSrcweir 
1430cdf0e10cSrcweir 	SetMode(m_nMode);
1431cdf0e10cSrcweir }
1432cdf0e10cSrcweir 
1433cdf0e10cSrcweir //------------------------------------------------------------------------------
setDataSource(const Reference<XRowSet> & _xCursor,sal_uInt16 nOpts)1434cdf0e10cSrcweir void DbGridControl::setDataSource(const Reference< XRowSet >& _xCursor, sal_uInt16 nOpts)
1435cdf0e10cSrcweir {
1436cdf0e10cSrcweir 	if (!_xCursor.is() && !m_pDataCursor)
1437cdf0e10cSrcweir 		return;
1438cdf0e10cSrcweir 
1439cdf0e10cSrcweir 	if (m_pDataSourcePropMultiplexer)
1440cdf0e10cSrcweir 	{
1441cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer->dispose();
1442cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer->release();	// this should delete the multiplexer
1443cdf0e10cSrcweir 		delete m_pDataSourcePropListener;
1444cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer = NULL;
1445cdf0e10cSrcweir 		m_pDataSourcePropListener = NULL;
1446cdf0e10cSrcweir 	}
1447cdf0e10cSrcweir     m_xRowSetListener.clear();
1448cdf0e10cSrcweir 
1449cdf0e10cSrcweir 	// is the new cursor valid ?
1450cdf0e10cSrcweir 	// the cursor is only valid if it contains some columns
1451cdf0e10cSrcweir 	// if there is no cursor or the cursor is not valid we have to clean up an leave
1452cdf0e10cSrcweir 	if (!_xCursor.is() || !Reference< XColumnsSupplier > (_xCursor, UNO_QUERY)->getColumns()->hasElements())
1453cdf0e10cSrcweir 	{
1454cdf0e10cSrcweir 		RemoveRows();
1455cdf0e10cSrcweir 		return;
1456cdf0e10cSrcweir 	}
1457cdf0e10cSrcweir 
1458cdf0e10cSrcweir 	// Hat sich der DatenCursor verandert ?
1459cdf0e10cSrcweir 	sal_uInt16 nCurPos = GetColumnPos(GetCurColumnId());
1460cdf0e10cSrcweir 
1461cdf0e10cSrcweir 	SetUpdateMode(sal_False);
1462cdf0e10cSrcweir 	RemoveRows();
1463cdf0e10cSrcweir 	DisconnectFromFields();
1464cdf0e10cSrcweir 
1465cdf0e10cSrcweir 	DELETEZ(m_pCursorDisposeListener);
1466cdf0e10cSrcweir 
1467cdf0e10cSrcweir 	{
1468cdf0e10cSrcweir 		::osl::MutexGuard aGuard(m_aAdjustSafety);
1469cdf0e10cSrcweir 		if (m_nAsynAdjustEvent)
1470cdf0e10cSrcweir 		{
1471cdf0e10cSrcweir 			// the adjust was thought to work with the old cursor which we don't have anymore
1472cdf0e10cSrcweir 			RemoveUserEvent(m_nAsynAdjustEvent);
1473cdf0e10cSrcweir 			m_nAsynAdjustEvent = 0;
1474cdf0e10cSrcweir 		}
1475cdf0e10cSrcweir 	}
1476cdf0e10cSrcweir 
1477cdf0e10cSrcweir 	// get a new formatter and data cursor
1478cdf0e10cSrcweir 	m_xFormatter = NULL;
1479cdf0e10cSrcweir 	OStaticDataAccessTools aStaticTools;
1480cdf0e10cSrcweir 	Reference< ::com::sun::star::util::XNumberFormatsSupplier >  xSupplier = aStaticTools.getNumberFormats(aStaticTools.getRowSetConnection(_xCursor), sal_True);
1481cdf0e10cSrcweir 	if (xSupplier.is() && m_xServiceFactory.is())
1482cdf0e10cSrcweir 	{
1483cdf0e10cSrcweir 		m_xFormatter =	Reference< ::com::sun::star::util::XNumberFormatter >(
1484cdf0e10cSrcweir 			m_xServiceFactory->createInstance(FM_NUMBER_FORMATTER),
1485cdf0e10cSrcweir 			UNO_QUERY);
1486cdf0e10cSrcweir 		if (m_xFormatter.is())
1487cdf0e10cSrcweir 		{
1488cdf0e10cSrcweir 			m_xFormatter->attachNumberFormatsSupplier(xSupplier);
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir 			// retrieve the datebase of the Numberformatter
1491cdf0e10cSrcweir 			try
1492cdf0e10cSrcweir 			{
1493cdf0e10cSrcweir 				xSupplier->getNumberFormatSettings()->getPropertyValue(rtl::OUString::createFromAscii("NullDate")) >>= m_aNullDate;
1494cdf0e10cSrcweir 			}
1495cdf0e10cSrcweir 			catch(Exception&)
1496cdf0e10cSrcweir 			{
1497cdf0e10cSrcweir 			}
1498cdf0e10cSrcweir 		}
1499cdf0e10cSrcweir 	}
1500cdf0e10cSrcweir 
1501cdf0e10cSrcweir 	m_pDataCursor = new CursorWrapper(_xCursor);
1502cdf0e10cSrcweir 
1503cdf0e10cSrcweir 	// now create a cursor for painting rows
1504cdf0e10cSrcweir 	// we need that cursor only if we are not in insert only mode
1505cdf0e10cSrcweir 	Reference< XResultSet > xClone;
1506cdf0e10cSrcweir 	Reference< XResultSetAccess > xAccess( _xCursor, UNO_QUERY );
1507cdf0e10cSrcweir 	try
1508cdf0e10cSrcweir 	{
1509cdf0e10cSrcweir 		xClone = xAccess.is() ? xAccess->createResultSet() : Reference< XResultSet > ();
1510cdf0e10cSrcweir 	}
1511cdf0e10cSrcweir 	catch(Exception&)
1512cdf0e10cSrcweir 	{
1513cdf0e10cSrcweir 	}
1514cdf0e10cSrcweir 	if (xClone.is())
1515cdf0e10cSrcweir 		m_pSeekCursor = new CursorWrapper(xClone);
1516cdf0e10cSrcweir 
1517cdf0e10cSrcweir 	// property listening on the data source
1518cdf0e10cSrcweir 	// (Normally one class would be sufficient : the multiplexer which could forward the property change to us.
1519cdf0e10cSrcweir 	// But for that we would have been derived from ::comphelper::OPropertyChangeListener, which isn't exported.
1520cdf0e10cSrcweir 	// So we introduce a second class, which is a ::comphelper::OPropertyChangeListener (in the implementation file we know this class)
1521cdf0e10cSrcweir 	// and forwards the property changes to a our special method "DataSourcePropertyChanged".)
1522cdf0e10cSrcweir 	if (m_pDataCursor)
1523cdf0e10cSrcweir 	{
1524cdf0e10cSrcweir 		m_pDataSourcePropListener = new FmXGridSourcePropListener(this);
1525cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer = new ::comphelper::OPropertyChangeMultiplexer(m_pDataSourcePropListener, m_pDataCursor->getPropertySet() );
1526cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer->acquire();
1527cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer->addProperty(FM_PROP_ISMODIFIED);
1528cdf0e10cSrcweir 		m_pDataSourcePropMultiplexer->addProperty(FM_PROP_ISNEW);
1529cdf0e10cSrcweir 	}
1530cdf0e10cSrcweir 
1531cdf0e10cSrcweir 	BrowserMode nOldMode = m_nMode;
1532cdf0e10cSrcweir 	if (m_pSeekCursor)
1533cdf0e10cSrcweir 	{
1534cdf0e10cSrcweir 		try
1535cdf0e10cSrcweir 		{
1536cdf0e10cSrcweir 			Reference< XPropertySet >  xSet(_xCursor, UNO_QUERY);
1537cdf0e10cSrcweir 			if (xSet.is())
1538cdf0e10cSrcweir 			{
1539cdf0e10cSrcweir 				// feststellen welche Updatemoeglichkeiten bestehen
1540cdf0e10cSrcweir 				sal_Int32 nConcurrency = ResultSetConcurrency::READ_ONLY;
1541cdf0e10cSrcweir 				xSet->getPropertyValue(FM_PROP_RESULTSET_CONCURRENCY) >>= nConcurrency;
1542cdf0e10cSrcweir 
1543cdf0e10cSrcweir 				if ( ResultSetConcurrency::UPDATABLE == nConcurrency )
1544cdf0e10cSrcweir 				{
1545cdf0e10cSrcweir 					sal_Int32 nPrivileges = 0;
1546cdf0e10cSrcweir 					xSet->getPropertyValue(FM_PROP_PRIVILEGES) >>= nPrivileges;
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir 					// Insert Option should be set if insert only otherwise you won't see any rows
1549cdf0e10cSrcweir 					// and no insertion is possible
1550cdf0e10cSrcweir 					if ((m_nOptionMask & OPT_INSERT) && ((nPrivileges & Privilege::INSERT) == Privilege::INSERT) && (nOpts & OPT_INSERT))
1551cdf0e10cSrcweir 						m_nOptions |= OPT_INSERT;
1552cdf0e10cSrcweir 					if ((m_nOptionMask & OPT_UPDATE) && ((nPrivileges & Privilege::UPDATE) == Privilege::UPDATE) && (nOpts & OPT_UPDATE))
1553cdf0e10cSrcweir 						m_nOptions |= OPT_UPDATE;
1554cdf0e10cSrcweir 					if ((m_nOptionMask & OPT_DELETE) && ((nPrivileges & Privilege::DELETE) == Privilege::DELETE) && (nOpts & OPT_DELETE))
1555cdf0e10cSrcweir 						m_nOptions |= OPT_DELETE;
1556cdf0e10cSrcweir 				}
1557cdf0e10cSrcweir 			}
1558cdf0e10cSrcweir 		}
1559cdf0e10cSrcweir 		catch( const Exception& )
1560cdf0e10cSrcweir 		{
1561cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
1562cdf0e10cSrcweir 		}
1563cdf0e10cSrcweir 
1564cdf0e10cSrcweir 		sal_Bool bPermanentCursor = IsPermanentCursorEnabled();
1565cdf0e10cSrcweir 		m_nMode = DEFAULT_BROWSE_MODE;
1566cdf0e10cSrcweir 
1567cdf0e10cSrcweir         if ( bPermanentCursor )
1568cdf0e10cSrcweir 		{
1569cdf0e10cSrcweir 			m_nMode |= BROWSER_CURSOR_WO_FOCUS;
1570cdf0e10cSrcweir 			m_nMode &= ~BROWSER_HIDECURSOR;
1571cdf0e10cSrcweir 		}
1572cdf0e10cSrcweir 		else
1573cdf0e10cSrcweir         {
1574cdf0e10cSrcweir 			// Duerfen Updates gemacht werden, kein Focus-RechtEck
1575cdf0e10cSrcweir 			if ( m_nOptions & OPT_UPDATE )
1576cdf0e10cSrcweir 				m_nMode |= BROWSER_HIDECURSOR;
1577cdf0e10cSrcweir         }
1578cdf0e10cSrcweir 
1579cdf0e10cSrcweir 		if ( m_bMultiSelection )
1580cdf0e10cSrcweir 			m_nMode |= BROWSER_MULTISELECTION;
1581cdf0e10cSrcweir         else
1582cdf0e10cSrcweir             m_nMode &= ~BROWSER_MULTISELECTION;
1583cdf0e10cSrcweir 
1584cdf0e10cSrcweir         adjustModeForScrollbars( m_nMode, m_bNavigationBar, m_bHideScrollbars );
1585cdf0e10cSrcweir 
1586cdf0e10cSrcweir 		Reference< XColumnsSupplier >  xSupplyColumns(_xCursor, UNO_QUERY);
1587cdf0e10cSrcweir 		if (xSupplyColumns.is())
1588cdf0e10cSrcweir 			InitColumnsByFields(Reference< XIndexAccess > (xSupplyColumns->getColumns(), UNO_QUERY));
1589cdf0e10cSrcweir 
1590cdf0e10cSrcweir 		ConnectToFields();
1591cdf0e10cSrcweir 	}
1592cdf0e10cSrcweir 
1593cdf0e10cSrcweir 	sal_uInt32 nRecordCount(0);
1594cdf0e10cSrcweir 
1595cdf0e10cSrcweir 	if (m_pSeekCursor)
1596cdf0e10cSrcweir 	{
1597cdf0e10cSrcweir 		Reference< XPropertySet > xSet = m_pDataCursor->getPropertySet();
1598cdf0e10cSrcweir 		xSet->getPropertyValue(FM_PROP_ROWCOUNT) >>= nRecordCount;
1599cdf0e10cSrcweir 		m_bRecordCountFinal = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ROWCOUNTFINAL));
1600cdf0e10cSrcweir 
1601cdf0e10cSrcweir         m_xRowSetListener = new RowSetEventListener(this);
1602cdf0e10cSrcweir         Reference< XRowsChangeBroadcaster> xChangeBroad(xSet,UNO_QUERY);
1603cdf0e10cSrcweir         if ( xChangeBroad.is( ) )
1604cdf0e10cSrcweir             xChangeBroad->addRowsChangeListener(m_xRowSetListener);
1605cdf0e10cSrcweir 
1606cdf0e10cSrcweir 
1607cdf0e10cSrcweir 		// insert the currently known rows
1608cdf0e10cSrcweir 		// and one row if we are able to insert rows
1609cdf0e10cSrcweir 		if (m_nOptions & OPT_INSERT)
1610cdf0e10cSrcweir 		{
1611cdf0e10cSrcweir 			// insert the empty row for insertion
1612cdf0e10cSrcweir 			m_xEmptyRow = new DbGridRow();
1613cdf0e10cSrcweir 			++nRecordCount;
1614cdf0e10cSrcweir 		}
1615cdf0e10cSrcweir 		if (nRecordCount)
1616cdf0e10cSrcweir 		{
1617cdf0e10cSrcweir 			m_xPaintRow = m_xSeekRow = new DbGridRow(m_pSeekCursor, sal_True);
1618cdf0e10cSrcweir 			m_xDataRow	= new DbGridRow(m_pDataCursor, sal_False);
1619cdf0e10cSrcweir 			RowInserted(0, nRecordCount, sal_False);
1620cdf0e10cSrcweir 
1621cdf0e10cSrcweir 			if (m_xSeekRow->IsValid())
1622cdf0e10cSrcweir                 try
1623cdf0e10cSrcweir                 {
1624cdf0e10cSrcweir 				    m_nSeekPos = m_pSeekCursor->getRow() - 1;
1625cdf0e10cSrcweir                 }
1626cdf0e10cSrcweir                 catch( const Exception& )
1627cdf0e10cSrcweir                 {
1628cdf0e10cSrcweir                 	DBG_UNHANDLED_EXCEPTION();
1629cdf0e10cSrcweir                     m_nSeekPos = -1;
1630cdf0e10cSrcweir                 }
1631cdf0e10cSrcweir 		}
1632cdf0e10cSrcweir 		else
1633cdf0e10cSrcweir 		{
1634cdf0e10cSrcweir 			// no rows so we don't need a seekcursor
1635cdf0e10cSrcweir 			DELETEZ(m_pSeekCursor);
1636cdf0e10cSrcweir 		}
1637cdf0e10cSrcweir 	}
1638cdf0e10cSrcweir 
1639cdf0e10cSrcweir 	// Zur alten Spalte gehen
1640cdf0e10cSrcweir 	if (!nCurPos || nCurPos >= ColCount())
1641cdf0e10cSrcweir 		nCurPos = 1;
1642cdf0e10cSrcweir 
1643cdf0e10cSrcweir 	// there are rows so go to the selected current column
1644cdf0e10cSrcweir 	if (nRecordCount)
1645cdf0e10cSrcweir 		GoToRowColumnId(0, GetColumnId(nCurPos));
1646cdf0e10cSrcweir 	// else stop the editing if neccessary
1647cdf0e10cSrcweir 	else if (IsEditing())
1648cdf0e10cSrcweir 		DeactivateCell();
1649cdf0e10cSrcweir 
1650cdf0e10cSrcweir 	// now reset the mode
1651cdf0e10cSrcweir 	if (m_nMode != nOldMode)
1652cdf0e10cSrcweir 		SetMode(m_nMode);
1653cdf0e10cSrcweir 
1654cdf0e10cSrcweir 	// beim Resizen wird RecalcRows gerufen
1655cdf0e10cSrcweir 	if (!IsResizing() && GetRowCount())
1656cdf0e10cSrcweir 		RecalcRows(GetTopRow(), GetVisibleRows(), sal_True);
1657cdf0e10cSrcweir 
1658cdf0e10cSrcweir 	m_aBar.InvalidateAll(m_nCurrentPos, sal_True);
1659cdf0e10cSrcweir 	SetUpdateMode(sal_True);
1660cdf0e10cSrcweir 
1661cdf0e10cSrcweir 	// start listening on the seek cursor
1662cdf0e10cSrcweir 	if (m_pSeekCursor)
1663cdf0e10cSrcweir 		m_pCursorDisposeListener = new DisposeListenerGridBridge(*this, Reference< XComponent > ((Reference< XInterface >)*m_pSeekCursor, UNO_QUERY), 0);
1664cdf0e10cSrcweir }
1665cdf0e10cSrcweir 
1666cdf0e10cSrcweir //------------------------------------------------------------------------------
RemoveColumns()1667cdf0e10cSrcweir void DbGridControl::RemoveColumns()
1668cdf0e10cSrcweir {
1669cdf0e10cSrcweir 	if ( IsEditing() )
1670cdf0e10cSrcweir 		DeactivateCell();
1671cdf0e10cSrcweir 
1672cdf0e10cSrcweir 	for (sal_uInt32 i = 0; i < m_aColumns.Count(); i++)
1673cdf0e10cSrcweir 		delete m_aColumns.GetObject(i);
1674cdf0e10cSrcweir 	m_aColumns.Clear();
1675cdf0e10cSrcweir 
1676cdf0e10cSrcweir 	DbGridControl_Base::RemoveColumns();
1677cdf0e10cSrcweir }
1678cdf0e10cSrcweir 
1679cdf0e10cSrcweir //------------------------------------------------------------------------------
CreateColumn(sal_uInt16 nId) const1680cdf0e10cSrcweir DbGridColumn* DbGridControl::CreateColumn(sal_uInt16 nId) const
1681cdf0e10cSrcweir {
1682cdf0e10cSrcweir 	return new DbGridColumn(nId, *(DbGridControl*)this);
1683cdf0e10cSrcweir }
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir //------------------------------------------------------------------------------
AppendColumn(const XubString & rName,sal_uInt16 nWidth,sal_uInt16 nModelPos,sal_uInt16 nId)1686cdf0e10cSrcweir sal_uInt16 DbGridControl::AppendColumn(const XubString& rName, sal_uInt16 nWidth, sal_uInt16 nModelPos, sal_uInt16 nId)
1687cdf0e10cSrcweir {
1688cdf0e10cSrcweir 	DBG_ASSERT(nId == (sal_uInt16)-1, "DbGridControl::AppendColumn : I want to set the ID myself ...");
1689cdf0e10cSrcweir 	sal_uInt16 nRealPos = nModelPos;
1690cdf0e10cSrcweir 	if (nModelPos != HEADERBAR_APPEND)
1691cdf0e10cSrcweir 	{
1692cdf0e10cSrcweir 		// calc the view pos. we can't use our converting functions because the new column
1693cdf0e10cSrcweir 		// has no VCL-representation, yet.
1694cdf0e10cSrcweir 		sal_Int16 nViewPos = nModelPos;
1695cdf0e10cSrcweir 		while (nModelPos--)
1696cdf0e10cSrcweir 		{
1697cdf0e10cSrcweir 			if (m_aColumns.GetObject(nModelPos)->IsHidden())
1698cdf0e10cSrcweir 				--nViewPos;
1699cdf0e10cSrcweir 		}
1700cdf0e10cSrcweir 		// restore nModelPos, we need it later
1701cdf0e10cSrcweir 		nModelPos = nRealPos;
1702cdf0e10cSrcweir 		// the position the base class gets is the view pos + 1 (because of the handle column)
1703cdf0e10cSrcweir 		nRealPos = nViewPos + 1;
1704cdf0e10cSrcweir 	}
1705cdf0e10cSrcweir 
1706cdf0e10cSrcweir 	// calculate the new id
1707cdf0e10cSrcweir     for (nId=1; (GetModelColumnPos(nId) != GRID_COLUMN_NOT_FOUND) && (nId<=m_aColumns.Count()); ++nId)
1708cdf0e10cSrcweir 		;
1709cdf0e10cSrcweir 	DBG_ASSERT(GetViewColumnPos(nId) == (sal_uInt16)-1, "DbGridControl::AppendColumn : inconsistent internal state !");
1710cdf0e10cSrcweir 		// my column's models say "there is no column with id nId", but the view (the base class) says "there is a column ..."
1711cdf0e10cSrcweir 
1712cdf0e10cSrcweir 	DbGridControl_Base::AppendColumn(rName, nWidth, nRealPos, nId);
1713cdf0e10cSrcweir 	if (nModelPos == HEADERBAR_APPEND)
1714cdf0e10cSrcweir 		m_aColumns.Insert(CreateColumn(nId), LIST_APPEND);
1715cdf0e10cSrcweir 	else
1716cdf0e10cSrcweir 		m_aColumns.Insert(CreateColumn(nId), nModelPos);
1717cdf0e10cSrcweir 
1718cdf0e10cSrcweir 	return nId;
1719cdf0e10cSrcweir }
1720cdf0e10cSrcweir 
1721cdf0e10cSrcweir //------------------------------------------------------------------------------
RemoveColumn(sal_uInt16 nId)1722cdf0e10cSrcweir void DbGridControl::RemoveColumn(sal_uInt16 nId)
1723cdf0e10cSrcweir {
1724cdf0e10cSrcweir 	sal_Int16 nIndex = GetModelColumnPos(nId);
1725cdf0e10cSrcweir 	DbGridControl_Base::RemoveColumn(nId);
1726cdf0e10cSrcweir 	delete m_aColumns.Remove(nIndex);
1727cdf0e10cSrcweir }
1728cdf0e10cSrcweir 
1729cdf0e10cSrcweir //------------------------------------------------------------------------------
ColumnMoved(sal_uInt16 nId)1730cdf0e10cSrcweir void DbGridControl::ColumnMoved(sal_uInt16 nId)
1731cdf0e10cSrcweir {
1732cdf0e10cSrcweir 	DbGridControl_Base::ColumnMoved(nId);
1733cdf0e10cSrcweir 
1734cdf0e10cSrcweir 	// remove the col from the model
1735cdf0e10cSrcweir 	sal_Int16 nOldModelPos = GetModelColumnPos(nId);
1736cdf0e10cSrcweir #ifdef DBG_UTIL
1737cdf0e10cSrcweir 	DbGridColumn* pCol = m_aColumns.GetObject((sal_uInt32)nOldModelPos);
1738cdf0e10cSrcweir 	DBG_ASSERT(!pCol->IsHidden(), "DbGridControl::ColumnMoved : moved a hidden col ? how this ?");
1739cdf0e10cSrcweir #endif
1740cdf0e10cSrcweir 
1741cdf0e10cSrcweir 	// for the new model pos we can't use GetModelColumnPos because we are altering the model at the moment
1742cdf0e10cSrcweir 	// so the method won't work (in fact it would return the old model pos)
1743cdf0e10cSrcweir 
1744cdf0e10cSrcweir 	// the new view pos is calculated easily
1745cdf0e10cSrcweir 	sal_uInt16 nNewViewPos = GetViewColumnPos(nId);
1746cdf0e10cSrcweir 
1747cdf0e10cSrcweir 	// from that we can compute the new model pos
1748cdf0e10cSrcweir 	sal_uInt16 nNewModelPos;
1749cdf0e10cSrcweir 	for (nNewModelPos = 0; nNewModelPos < m_aColumns.Count(); ++nNewModelPos)
1750cdf0e10cSrcweir 	{
1751cdf0e10cSrcweir 		if (!m_aColumns.GetObject(nNewModelPos)->IsHidden())
1752cdf0e10cSrcweir 		{
1753cdf0e10cSrcweir 			if (!nNewViewPos)
1754cdf0e10cSrcweir 				break;
1755cdf0e10cSrcweir 			else
1756cdf0e10cSrcweir 				--nNewViewPos;
1757cdf0e10cSrcweir 		}
1758cdf0e10cSrcweir 	}
1759cdf0e10cSrcweir 	DBG_ASSERT(nNewModelPos<m_aColumns.Count(), "DbGridControl::ColumnMoved : could not find the new model position !");
1760cdf0e10cSrcweir 
1761cdf0e10cSrcweir 	// this will work. of course the model isn't fully consistent with our view right now, but let's
1762cdf0e10cSrcweir 	// look at the situation : a column has been moved with in the VIEW from pos m to n, say m<n (in the
1763cdf0e10cSrcweir 	// other case we can use analogue arguments).
1764cdf0e10cSrcweir 	// All cols k with m<k<=n have been shifted left on pos, the former col m now has pos n.
1765cdf0e10cSrcweir 	// In the model this affects a range of cols x to y, where x<=m and y<=n. And the number of hidden cols
1766cdf0e10cSrcweir 	// within this range is constant, so we may calculate the view pos from the model pos in the above way.
1767cdf0e10cSrcweir 	//
1768cdf0e10cSrcweir 	// for instance, let's look at a grid with six columns where the third one is hidden. this will
1769cdf0e10cSrcweir 	// initially look like this :
1770cdf0e10cSrcweir 	//
1771cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1772cdf0e10cSrcweir 	// model pos	| 0 | 1 |*2*| 3 | 4 | 5 |
1773cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1774cdf0e10cSrcweir 	// ID			| 1 | 2 | 3 | 4 | 5 | 6 |
1775cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1776cdf0e10cSrcweir 	// view pos 	| 0 | 1 | - | 2 | 3 | 4 |
1777cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1778cdf0e10cSrcweir 	//
1779cdf0e10cSrcweir 	// if we move the column at (view) pos 1 to (view) pos 3 we have :
1780cdf0e10cSrcweir 	//
1781cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1782cdf0e10cSrcweir 	// model pos	| 0 | 3 |*2*| 4 | 1 | 5 |	// not reflecting the changes, yet
1783cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1784cdf0e10cSrcweir 	// ID			| 1 | 4 | 3 | 5 | 2 | 6 |	// already reflecting the changes
1785cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1786cdf0e10cSrcweir 	// view pos 	| 0 | 1 | - | 2 | 3 | 4 |
1787cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1788cdf0e10cSrcweir 	//
1789cdf0e10cSrcweir 	// or, sorted by the out-of-date model positions :
1790cdf0e10cSrcweir 	//
1791cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1792cdf0e10cSrcweir 	// model pos	| 0 | 1 |*2*| 3 | 4 | 5 |
1793cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1794cdf0e10cSrcweir 	// ID			| 1 | 2 | 3 | 4 | 5 | 6 |
1795cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1796cdf0e10cSrcweir 	// view pos 	| 0 | 3 | - | 1 | 2 | 4 |
1797cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1798cdf0e10cSrcweir 	//
1799cdf0e10cSrcweir 	// We know the new view pos (3) of the moved column because our base class tells us. So we look at our
1800cdf0e10cSrcweir 	// model for the 4th (the pos is zero-based) visible column, it is at (model) position 4. And this is
1801cdf0e10cSrcweir 	// exactly the pos where we have to re-insert our column's model, so it looks ike this :
1802cdf0e10cSrcweir 	//
1803cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1804cdf0e10cSrcweir 	// model pos	| 0 |*1*| 2 | 3 | 4 | 5 |
1805cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1806cdf0e10cSrcweir 	// ID			| 1 | 3 | 4 | 5 | 2 | 6 |
1807cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1808cdf0e10cSrcweir 	// view pos 	| 0 | - | 1 | 2 | 3 | 4 |
1809cdf0e10cSrcweir 	//				+---+---+---+---+---+---+
1810cdf0e10cSrcweir 	//
1811cdf0e10cSrcweir 	// Now, all is consistent again.
1812cdf0e10cSrcweir 	// (except of the hidden column : The cycling of the cols occured on the model, not on the view. maybe
1813cdf0e10cSrcweir 	// the user expected the latter but there really is no good argument against our method ;) ...)
1814cdf0e10cSrcweir 	//
1815cdf0e10cSrcweir 	// And no, this large explanation isn't just because I wanted to play a board game or something like
1816cdf0e10cSrcweir 	// that. It's because it took me a while to see it myself, and the whole theme (hidden cols, model col
1817cdf0e10cSrcweir 	// positions, view col positions)  is really painful (at least for me) so the above pictures helped me a lot ;)
1818cdf0e10cSrcweir 
1819cdf0e10cSrcweir 	m_aColumns.Insert(m_aColumns.Remove((sal_uInt32)nOldModelPos), nNewModelPos);
1820cdf0e10cSrcweir }
1821cdf0e10cSrcweir 
1822cdf0e10cSrcweir //------------------------------------------------------------------------------
SeekRow(long nRow)1823cdf0e10cSrcweir sal_Bool DbGridControl::SeekRow(long nRow)
1824cdf0e10cSrcweir {
1825cdf0e10cSrcweir 	// in filter mode or in insert only mode we don't have any cursor!
1826cdf0e10cSrcweir 	if ( !SeekCursor( nRow ) )
1827cdf0e10cSrcweir         return sal_False;
1828cdf0e10cSrcweir 
1829cdf0e10cSrcweir 	if ( IsFilterMode() )
1830cdf0e10cSrcweir 	{
1831cdf0e10cSrcweir 		DBG_ASSERT( IsFilterRow( nRow ), "DbGridControl::SeekRow(): No filter row, wrong mode" );
1832cdf0e10cSrcweir 		m_xPaintRow = m_xEmptyRow;
1833cdf0e10cSrcweir 	}
1834cdf0e10cSrcweir     else
1835cdf0e10cSrcweir 	{
1836cdf0e10cSrcweir 		// on the current position we have to take the current row for display as we want
1837cdf0e10cSrcweir 		// to have the most recent values for display
1838cdf0e10cSrcweir 		if ( ( nRow == m_nCurrentPos ) && getDisplaySynchron() )
1839cdf0e10cSrcweir 			m_xPaintRow = m_xCurrentRow;
1840cdf0e10cSrcweir 		// seek to the empty insert row
1841cdf0e10cSrcweir 		else if ( IsInsertionRow( nRow ) )
1842cdf0e10cSrcweir 			m_xPaintRow = m_xEmptyRow;
1843cdf0e10cSrcweir 		else
1844cdf0e10cSrcweir 		{
1845cdf0e10cSrcweir 			m_xSeekRow->SetState( m_pSeekCursor, sal_True );
1846cdf0e10cSrcweir 			m_xPaintRow = m_xSeekRow;
1847cdf0e10cSrcweir 		}
1848cdf0e10cSrcweir 	}
1849cdf0e10cSrcweir 
1850cdf0e10cSrcweir     DbGridControl_Base::SeekRow(nRow);
1851cdf0e10cSrcweir 
1852cdf0e10cSrcweir     return m_nSeekPos >= 0;
1853cdf0e10cSrcweir }
1854cdf0e10cSrcweir //------------------------------------------------------------------------------
1855cdf0e10cSrcweir // Wird aufgerufen, wenn die dargestellte Datenmenge sich aendert
1856cdf0e10cSrcweir //------------------------------------------------------------------------------
VisibleRowsChanged(long nNewTopRow,sal_uInt16 nLinesOnScreen)1857cdf0e10cSrcweir void DbGridControl::VisibleRowsChanged( long nNewTopRow, sal_uInt16 nLinesOnScreen )
1858cdf0e10cSrcweir {
1859cdf0e10cSrcweir 	RecalcRows(nNewTopRow, nLinesOnScreen , sal_False);
1860cdf0e10cSrcweir }
1861cdf0e10cSrcweir 
1862cdf0e10cSrcweir //------------------------------------------------------------------------------
RecalcRows(long nNewTopRow,sal_uInt16 nLinesOnScreen,sal_Bool bUpdateCursor)1863cdf0e10cSrcweir void DbGridControl::RecalcRows(long nNewTopRow, sal_uInt16 nLinesOnScreen, sal_Bool bUpdateCursor)
1864cdf0e10cSrcweir {
1865cdf0e10cSrcweir 	DBG_CHKTHIS( DbGridControl, NULL );
1866cdf0e10cSrcweir 	// Wenn kein Cursor -> keine Rows im Browser.
1867cdf0e10cSrcweir 	if (!m_pSeekCursor)
1868cdf0e10cSrcweir 	{
1869cdf0e10cSrcweir 		DBG_ASSERT(GetRowCount() == 0,"DbGridControl: ohne Cursor darf es keine Rows geben");
1870cdf0e10cSrcweir 		return;
1871cdf0e10cSrcweir 	}
1872cdf0e10cSrcweir 
1873cdf0e10cSrcweir 	// ignore any updates implicit made
1874cdf0e10cSrcweir 	sal_Bool bDisablePaint = !bUpdateCursor && IsPaintEnabled();
1875cdf0e10cSrcweir 	if (bDisablePaint)
1876cdf0e10cSrcweir 		EnablePaint(sal_False);
1877cdf0e10cSrcweir 
1878cdf0e10cSrcweir 	// Cache an den sichtbaren Bereich anpassen
1879cdf0e10cSrcweir 	Reference< XPropertySet > xSet = m_pSeekCursor->getPropertySet();
1880cdf0e10cSrcweir 	sal_Int32 nCacheSize = 0;
1881cdf0e10cSrcweir 	xSet->getPropertyValue(FM_PROP_FETCHSIZE) >>= nCacheSize;
1882cdf0e10cSrcweir 	sal_Bool bCacheAligned	 = sal_False;
1883cdf0e10cSrcweir 	// Nach der Initialisierung (m_nSeekPos < 0) keine Cursorbewegung, da bereits auf den ersten
1884cdf0e10cSrcweir 	// Satz positioniert
1885cdf0e10cSrcweir 	long nDelta = nNewTopRow - GetTopRow();
1886cdf0e10cSrcweir 	// Limit fuer relative Positionierung
1887cdf0e10cSrcweir 	long nLimit = (nCacheSize) ? nCacheSize / 2 : 0;
1888cdf0e10cSrcweir 
1889cdf0e10cSrcweir 	// mehr Zeilen auf dem Bildschirm als im Cache
1890cdf0e10cSrcweir 	if (nLimit < nLinesOnScreen)
1891cdf0e10cSrcweir 	{
1892cdf0e10cSrcweir 		Any aCacheSize;
1893cdf0e10cSrcweir 		aCacheSize <<= sal_Int32(nLinesOnScreen*2);
1894cdf0e10cSrcweir 		xSet->setPropertyValue(FM_PROP_FETCHSIZE, aCacheSize);
1895cdf0e10cSrcweir 		// jetzt auf alle Faelle den Cursor anpassen
1896cdf0e10cSrcweir 		bUpdateCursor = sal_True;
1897cdf0e10cSrcweir 		bCacheAligned = sal_True;
1898cdf0e10cSrcweir 		nLimit = nLinesOnScreen;
1899cdf0e10cSrcweir 	}
1900cdf0e10cSrcweir 
1901cdf0e10cSrcweir 	// Im folgenden werden die Positionierungen so vorgenommen, da� sichergestellt ist
1902cdf0e10cSrcweir 	// da� ausreichend Zeilen im DatenCache vorhanden sind
1903cdf0e10cSrcweir 
1904cdf0e10cSrcweir 	// Fenster geht nach unten, weniger als zwei Fenster Differenz
1905cdf0e10cSrcweir 	// oder Cache angepasst und noch kein Rowcount
1906cdf0e10cSrcweir 	if (nDelta < nLimit && (nDelta > 0
1907cdf0e10cSrcweir 		|| (bCacheAligned && m_nTotalCount < 0)) )
1908cdf0e10cSrcweir 		SeekCursor(nNewTopRow + nLinesOnScreen - 1, sal_False);
1909cdf0e10cSrcweir 	else if (nDelta < 0 && Abs(nDelta) < nLimit)
1910cdf0e10cSrcweir 		SeekCursor(nNewTopRow, sal_False);
1911cdf0e10cSrcweir 	else if (nDelta != 0 || bUpdateCursor)
1912cdf0e10cSrcweir 		SeekCursor(nNewTopRow, sal_True);
1913cdf0e10cSrcweir 
1914cdf0e10cSrcweir 	AdjustRows();
1915cdf0e10cSrcweir 
1916cdf0e10cSrcweir 	// ignore any updates implicit made
1917cdf0e10cSrcweir 	EnablePaint(sal_True);
1918cdf0e10cSrcweir }
1919cdf0e10cSrcweir 
1920cdf0e10cSrcweir //------------------------------------------------------------------------------
RowInserted(long nRow,long nNumRows,sal_Bool bDoPaint,sal_Bool bKeepSelection)1921cdf0e10cSrcweir void DbGridControl::RowInserted(long nRow, long nNumRows, sal_Bool bDoPaint, sal_Bool bKeepSelection)
1922cdf0e10cSrcweir {
1923cdf0e10cSrcweir 	if (nNumRows)
1924cdf0e10cSrcweir 	{
1925cdf0e10cSrcweir 		if (m_bRecordCountFinal && m_nTotalCount < 0)
1926cdf0e10cSrcweir 		{
1927cdf0e10cSrcweir 			// if we have an insert row we have to reduce to count by 1
1928cdf0e10cSrcweir 			// as the total count reflects only the existing rows in database
1929cdf0e10cSrcweir 			m_nTotalCount = GetRowCount() + nNumRows;
1930cdf0e10cSrcweir 			if (m_xEmptyRow.Is())
1931cdf0e10cSrcweir 				--m_nTotalCount;
1932cdf0e10cSrcweir 		}
1933cdf0e10cSrcweir 		else if (m_nTotalCount >= 0)
1934cdf0e10cSrcweir 			m_nTotalCount += nNumRows;
1935cdf0e10cSrcweir 
1936cdf0e10cSrcweir 		DbGridControl_Base::RowInserted(nRow, nNumRows, bDoPaint, bKeepSelection);
1937cdf0e10cSrcweir 		m_aBar.InvalidateState(NavigationBar::RECORD_COUNT);
1938cdf0e10cSrcweir 	}
1939cdf0e10cSrcweir }
1940cdf0e10cSrcweir 
1941cdf0e10cSrcweir //------------------------------------------------------------------------------
RowRemoved(long nRow,long nNumRows,sal_Bool bDoPaint)1942cdf0e10cSrcweir void DbGridControl::RowRemoved(long nRow, long nNumRows, sal_Bool bDoPaint)
1943cdf0e10cSrcweir {
1944cdf0e10cSrcweir 	if (nNumRows)
1945cdf0e10cSrcweir 	{
1946cdf0e10cSrcweir 		if (m_bRecordCountFinal && m_nTotalCount < 0)
1947cdf0e10cSrcweir 		{
1948cdf0e10cSrcweir 			m_nTotalCount = GetRowCount() - nNumRows;
1949cdf0e10cSrcweir 			// if we have an insert row reduce by 1
1950cdf0e10cSrcweir 			if (m_xEmptyRow.Is())
1951cdf0e10cSrcweir 				--m_nTotalCount;
1952cdf0e10cSrcweir 		}
1953cdf0e10cSrcweir 		else if (m_nTotalCount >= 0)
1954cdf0e10cSrcweir 			m_nTotalCount -= nNumRows;
1955cdf0e10cSrcweir 
1956cdf0e10cSrcweir 		DbGridControl_Base::RowRemoved(nRow, nNumRows, bDoPaint);
1957cdf0e10cSrcweir 		m_aBar.InvalidateState(NavigationBar::RECORD_COUNT);
1958cdf0e10cSrcweir 	}
1959cdf0e10cSrcweir }
1960cdf0e10cSrcweir 
1961cdf0e10cSrcweir //------------------------------------------------------------------------------
AdjustRows()1962cdf0e10cSrcweir void DbGridControl::AdjustRows()
1963cdf0e10cSrcweir {
1964cdf0e10cSrcweir 	if (!m_pSeekCursor)
1965cdf0e10cSrcweir 		return;
1966cdf0e10cSrcweir 
1967cdf0e10cSrcweir 	Reference< XPropertySet > xSet = m_pDataCursor->getPropertySet();
1968cdf0e10cSrcweir 
1969cdf0e10cSrcweir 	// Aktualisieren des RecordCounts
1970cdf0e10cSrcweir 	sal_Int32 nRecordCount = 0;
1971cdf0e10cSrcweir 	xSet->getPropertyValue(FM_PROP_ROWCOUNT) >>= nRecordCount;
1972cdf0e10cSrcweir 	if (!m_bRecordCountFinal)
1973cdf0e10cSrcweir 		m_bRecordCountFinal = ::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ROWCOUNTFINAL));
1974cdf0e10cSrcweir 
1975cdf0e10cSrcweir 	// hat sich die aktuelle Anzahl Rows veraendert
1976cdf0e10cSrcweir 	// hierbei muss auch beruecksichtigt werden,
1977cdf0e10cSrcweir 	// das eine zusaetzliche Zeile zum einfuegen von Datensaetzen vorhanden sein kann
1978cdf0e10cSrcweir 
1979cdf0e10cSrcweir 	// zusaetzliche AppendRow fuers einfuegen
1980cdf0e10cSrcweir 	if (m_nOptions & OPT_INSERT)
1981cdf0e10cSrcweir 		++nRecordCount;
1982cdf0e10cSrcweir 
1983cdf0e10cSrcweir 	// wird gerade eingefuegt, dann gehoert die gerade hinzuzufuegende
1984cdf0e10cSrcweir 	// Zeile nicht zum RecordCount und die Appendrow ebenfalls nicht
1985cdf0e10cSrcweir 	if (!IsUpdating() && m_bRecordCountFinal && IsModified() && m_xCurrentRow != m_xEmptyRow &&
1986cdf0e10cSrcweir 		m_xCurrentRow->IsNew())
1987cdf0e10cSrcweir 		++nRecordCount;
1988cdf0e10cSrcweir 	// das ist mit !m_bUpdating abgesichert : innerhalb von SaveRow (m_bUpdating == sal_True) wuerde sonst der Datensatz, den ich editiere
1989cdf0e10cSrcweir 	// (und den SaveRow gerade angefuegt hat, wodurch diese Methode hier getriggert wurde), doppelt zaehlen : einmal ist er schon
1990cdf0e10cSrcweir 	// in dem normalen RecordCount drin, zum zweiten wuerde er hier gezaehlt werden (60787 - FS)
1991cdf0e10cSrcweir 
1992cdf0e10cSrcweir 	if (nRecordCount != GetRowCount())
1993cdf0e10cSrcweir 	{
1994cdf0e10cSrcweir 		long nDelta = GetRowCount() - (long)nRecordCount;
1995cdf0e10cSrcweir 		if (nDelta > 0) 										// zuviele
1996cdf0e10cSrcweir 		{
1997cdf0e10cSrcweir 			RowRemoved(GetRowCount() - nDelta, nDelta, sal_False);
1998cdf0e10cSrcweir 			// es sind Zeilen weggefallen, dann ab der aktuellen Position neu zeichen
1999cdf0e10cSrcweir 			Invalidate();
2000cdf0e10cSrcweir 
2001cdf0e10cSrcweir             sal_Int32 nNewPos = AlignSeekCursor();
2002cdf0e10cSrcweir             if (m_bSynchDisplay)
2003cdf0e10cSrcweir 			    DbGridControl_Base::GoToRow(nNewPos);
2004cdf0e10cSrcweir 
2005cdf0e10cSrcweir             SetCurrent(nNewPos);
2006cdf0e10cSrcweir             // there are rows so go to the selected current column
2007cdf0e10cSrcweir 	        if (nRecordCount)
2008cdf0e10cSrcweir 		        GoToRowColumnId(nNewPos, GetColumnId(GetCurColumnId()));
2009cdf0e10cSrcweir 	        if (!IsResizing() && GetRowCount())
2010cdf0e10cSrcweir 		        RecalcRows(GetTopRow(), GetVisibleRows(), sal_True);
2011cdf0e10cSrcweir             m_aBar.InvalidateAll(m_nCurrentPos, sal_True);
2012cdf0e10cSrcweir 		}
2013cdf0e10cSrcweir 		else													// zuwenig
2014cdf0e10cSrcweir 			RowInserted(GetRowCount(), -nDelta, sal_True);
2015cdf0e10cSrcweir 	}
2016cdf0e10cSrcweir 
2017cdf0e10cSrcweir 	if (m_bRecordCountFinal && m_nTotalCount < 0)
2018cdf0e10cSrcweir 	{
2019cdf0e10cSrcweir 		if (m_nOptions & OPT_INSERT)
2020cdf0e10cSrcweir 			m_nTotalCount = GetRowCount() - 1;
2021cdf0e10cSrcweir 		else
2022cdf0e10cSrcweir 			m_nTotalCount = GetRowCount();
2023cdf0e10cSrcweir 	}
2024cdf0e10cSrcweir 	m_aBar.InvalidateState(NavigationBar::RECORD_COUNT);
2025cdf0e10cSrcweir }
2026cdf0e10cSrcweir 
2027cdf0e10cSrcweir //------------------------------------------------------------------------------
GetRowStatus(long nRow) const2028cdf0e10cSrcweir DbGridControl_Base::RowStatus DbGridControl::GetRowStatus(long nRow) const
2029cdf0e10cSrcweir {
2030cdf0e10cSrcweir 	if (IsFilterRow(nRow))
2031cdf0e10cSrcweir 		return DbGridControl_Base::FILTER;
2032cdf0e10cSrcweir 	else if (m_nCurrentPos >= 0 && nRow == m_nCurrentPos)
2033cdf0e10cSrcweir 	{
2034cdf0e10cSrcweir 		// neue Zeile
2035cdf0e10cSrcweir 		if (!IsValid(m_xCurrentRow))
2036cdf0e10cSrcweir 			return DbGridControl_Base::DELETED;
2037cdf0e10cSrcweir 		else if (IsModified())
2038cdf0e10cSrcweir 			return DbGridControl_Base::MODIFIED;
2039cdf0e10cSrcweir 		else if (m_xCurrentRow->IsNew())
2040cdf0e10cSrcweir 			return DbGridControl_Base::CURRENTNEW;
2041cdf0e10cSrcweir 		else
2042cdf0e10cSrcweir 			return DbGridControl_Base::CURRENT;
2043cdf0e10cSrcweir 	}
2044cdf0e10cSrcweir 	else if (IsInsertionRow(nRow))
2045cdf0e10cSrcweir 		return DbGridControl_Base::NEW;
2046cdf0e10cSrcweir 	else if (!IsValid(m_xSeekRow))
2047cdf0e10cSrcweir 		return DbGridControl_Base::DELETED;
2048cdf0e10cSrcweir 	else
2049cdf0e10cSrcweir 		return DbGridControl_Base::CLEAN;
2050cdf0e10cSrcweir }
2051cdf0e10cSrcweir 
2052cdf0e10cSrcweir //------------------------------------------------------------------------------
PaintStatusCell(OutputDevice & rDev,const Rectangle & rRect) const2053cdf0e10cSrcweir void DbGridControl::PaintStatusCell(OutputDevice& rDev, const Rectangle& rRect) const
2054cdf0e10cSrcweir {
2055cdf0e10cSrcweir 	DbGridControl_Base::PaintStatusCell(rDev, rRect);
2056cdf0e10cSrcweir }
2057cdf0e10cSrcweir 
2058cdf0e10cSrcweir //------------------------------------------------------------------------------
PaintCell(OutputDevice & rDev,const Rectangle & rRect,sal_uInt16 nColumnId) const2059cdf0e10cSrcweir void DbGridControl::PaintCell(OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId) const
2060cdf0e10cSrcweir {
2061cdf0e10cSrcweir 	if (!IsValid(m_xPaintRow))
2062cdf0e10cSrcweir 		return;
2063cdf0e10cSrcweir 
2064cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColumnId));
2065cdf0e10cSrcweir 	if (pColumn)
2066cdf0e10cSrcweir 	{
2067cdf0e10cSrcweir 		Rectangle aArea(rRect);
2068cdf0e10cSrcweir 		if ((GetMode() & BROWSER_CURSOR_WO_FOCUS) == BROWSER_CURSOR_WO_FOCUS)
2069cdf0e10cSrcweir 		{
2070cdf0e10cSrcweir 			aArea.Top() += 1;
2071cdf0e10cSrcweir 			aArea.Bottom() -= 1;
2072cdf0e10cSrcweir 		}
2073cdf0e10cSrcweir 		pColumn->Paint(rDev, aArea, m_xPaintRow, getNumberFormatter());
2074cdf0e10cSrcweir 	}
2075cdf0e10cSrcweir }
2076cdf0e10cSrcweir 
2077cdf0e10cSrcweir //------------------------------------------------------------------------------
CursorMoving(long nNewRow,sal_uInt16 nNewCol)2078cdf0e10cSrcweir sal_Bool DbGridControl::CursorMoving(long nNewRow, sal_uInt16 nNewCol)
2079cdf0e10cSrcweir {
2080cdf0e10cSrcweir 	DBG_CHKTHIS( DbGridControl, NULL );
2081cdf0e10cSrcweir 
2082cdf0e10cSrcweir     DeactivateCell( sal_False );
2083cdf0e10cSrcweir 
2084cdf0e10cSrcweir 	if  (   m_pDataCursor
2085cdf0e10cSrcweir         &&  ( m_nCurrentPos != nNewRow )
2086cdf0e10cSrcweir         && !SetCurrent( nNewRow )
2087cdf0e10cSrcweir         )
2088cdf0e10cSrcweir     {
2089cdf0e10cSrcweir         ActivateCell();
2090cdf0e10cSrcweir 		return sal_False;
2091cdf0e10cSrcweir     }
2092cdf0e10cSrcweir 
2093cdf0e10cSrcweir     if ( !DbGridControl_Base::CursorMoving( nNewRow, nNewCol ) )
2094cdf0e10cSrcweir         return sal_False;
2095cdf0e10cSrcweir 
2096cdf0e10cSrcweir 	return sal_True;
2097cdf0e10cSrcweir }
2098cdf0e10cSrcweir 
2099cdf0e10cSrcweir //------------------------------------------------------------------------------
SetCurrent(long nNewRow)2100cdf0e10cSrcweir sal_Bool DbGridControl::SetCurrent(long nNewRow)
2101cdf0e10cSrcweir {
2102cdf0e10cSrcweir 	// Each movement of the datacursor must start with BeginCursorAction and end with
2103cdf0e10cSrcweir 	// EndCursorAction to block all notifications during the movement
2104cdf0e10cSrcweir 	BeginCursorAction();
2105cdf0e10cSrcweir 
2106cdf0e10cSrcweir 	try
2107cdf0e10cSrcweir 	{
2108cdf0e10cSrcweir 		// Abgleichen der Positionen
2109cdf0e10cSrcweir 		if (SeekCursor(nNewRow))
2110cdf0e10cSrcweir 		{
2111cdf0e10cSrcweir 			if (IsFilterRow(nNewRow))	// special mode for filtering
2112cdf0e10cSrcweir 			{
2113cdf0e10cSrcweir 				m_xCurrentRow = m_xDataRow = m_xPaintRow = m_xEmptyRow;
2114cdf0e10cSrcweir 				m_nCurrentPos = nNewRow;
2115cdf0e10cSrcweir 			}
2116cdf0e10cSrcweir 			else
2117cdf0e10cSrcweir 			{
2118cdf0e10cSrcweir 				sal_Bool bNewRowInserted = sal_False;
2119cdf0e10cSrcweir 				// Should we go to the insertrow ?
2120cdf0e10cSrcweir 				if (IsInsertionRow(nNewRow))
2121cdf0e10cSrcweir 				{
2122cdf0e10cSrcweir 					// to we need to move the cursor to the insert row?
2123cdf0e10cSrcweir 					// we need to insert the if the current row isn't the insert row or if the
2124cdf0e10cSrcweir 					// cursor triggered the move by itselt and we need a reinitialization of the row
2125cdf0e10cSrcweir 					Reference< XPropertySet > xCursorProps = m_pDataCursor->getPropertySet();
2126cdf0e10cSrcweir 					if ( !::comphelper::getBOOL(xCursorProps->getPropertyValue(FM_PROP_ISNEW)) )
2127cdf0e10cSrcweir 					{
2128cdf0e10cSrcweir 						Reference< XResultSetUpdate > xUpdateCursor((Reference< XInterface >)*m_pDataCursor, UNO_QUERY);
2129cdf0e10cSrcweir 						xUpdateCursor->moveToInsertRow();
2130cdf0e10cSrcweir 					}
2131cdf0e10cSrcweir 					bNewRowInserted = sal_True;
2132cdf0e10cSrcweir 				}
2133cdf0e10cSrcweir 				else
2134cdf0e10cSrcweir 				{
2135cdf0e10cSrcweir 
2136cdf0e10cSrcweir 					if ( !m_pSeekCursor->isBeforeFirst() && !m_pSeekCursor->isAfterLast() )
2137cdf0e10cSrcweir 					{
2138cdf0e10cSrcweir 						Any aBookmark = m_pSeekCursor->getBookmark();
2139cdf0e10cSrcweir 						if (!m_xCurrentRow || m_xCurrentRow->IsNew() || !CompareBookmark(aBookmark, m_pDataCursor->getBookmark()))
2140cdf0e10cSrcweir 						{
2141cdf0e10cSrcweir 							// adjust the cursor to the new desired row
2142cdf0e10cSrcweir 							if (!m_pDataCursor->moveToBookmark(aBookmark))
2143cdf0e10cSrcweir 							{
2144cdf0e10cSrcweir 								EndCursorAction();
2145cdf0e10cSrcweir 								return sal_False;
2146cdf0e10cSrcweir 							}
2147cdf0e10cSrcweir 						}
2148cdf0e10cSrcweir 					}
2149cdf0e10cSrcweir 				}
2150cdf0e10cSrcweir 				m_xDataRow->SetState(m_pDataCursor, sal_False);
2151cdf0e10cSrcweir 				m_xCurrentRow = m_xDataRow;
2152cdf0e10cSrcweir 
2153cdf0e10cSrcweir 				long nPaintPos = -1;
2154cdf0e10cSrcweir 				// do we have to repaint the last regular row in case of setting defaults or autovalues
2155cdf0e10cSrcweir 				if (m_nCurrentPos >= 0 && m_nCurrentPos >= (GetRowCount() - 2))
2156cdf0e10cSrcweir 					nPaintPos = m_nCurrentPos;
2157cdf0e10cSrcweir 
2158cdf0e10cSrcweir 				m_nCurrentPos = nNewRow;
2159cdf0e10cSrcweir 
2160cdf0e10cSrcweir 				// repaint the new row to display all defaults
2161cdf0e10cSrcweir 				if (bNewRowInserted)
2162cdf0e10cSrcweir 					RowModified(m_nCurrentPos);
2163cdf0e10cSrcweir 				if (nPaintPos >= 0)
2164cdf0e10cSrcweir 					RowModified(nPaintPos);
2165cdf0e10cSrcweir 			}
2166cdf0e10cSrcweir 		}
2167cdf0e10cSrcweir 		else
2168cdf0e10cSrcweir 		{
2169cdf0e10cSrcweir 			DBG_ERROR("DbGridControl::SetCurrent : SeekRow failed !");
2170cdf0e10cSrcweir 			EndCursorAction();
2171cdf0e10cSrcweir 			return sal_False;
2172cdf0e10cSrcweir 		}
2173cdf0e10cSrcweir 	}
2174cdf0e10cSrcweir 	catch ( const Exception& )
2175cdf0e10cSrcweir 	{
2176cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
2177cdf0e10cSrcweir 		EndCursorAction();
2178cdf0e10cSrcweir 		return sal_False;
2179cdf0e10cSrcweir 	}
2180cdf0e10cSrcweir 
2181cdf0e10cSrcweir 	EndCursorAction();
2182cdf0e10cSrcweir 	return sal_True;
2183cdf0e10cSrcweir }
2184cdf0e10cSrcweir 
2185cdf0e10cSrcweir //------------------------------------------------------------------------------
CursorMoved()2186cdf0e10cSrcweir void DbGridControl::CursorMoved()
2187cdf0e10cSrcweir {
2188cdf0e10cSrcweir 	DBG_CHKTHIS( DbGridControl, NULL );
2189cdf0e10cSrcweir 
2190cdf0e10cSrcweir 	// CursorBewegung durch loeschen oder einfuegen von Zeilen
2191cdf0e10cSrcweir 	if (m_pDataCursor && m_nCurrentPos != GetCurRow())
2192cdf0e10cSrcweir 	{
2193cdf0e10cSrcweir 		DeactivateCell(sal_True);
2194cdf0e10cSrcweir 		SetCurrent(GetCurRow());
2195cdf0e10cSrcweir 	}
2196cdf0e10cSrcweir 
2197cdf0e10cSrcweir 	DbGridControl_Base::CursorMoved();
2198cdf0e10cSrcweir 	m_aBar.InvalidateAll(m_nCurrentPos);
2199cdf0e10cSrcweir 
2200cdf0e10cSrcweir 	// select the new column when they moved
2201cdf0e10cSrcweir 	if ( IsDesignMode() && GetSelectedColumnCount() > 0 && GetCurColumnId() )
2202cdf0e10cSrcweir 	{
2203cdf0e10cSrcweir 		SelectColumnId( GetCurColumnId() );
2204cdf0e10cSrcweir 	}
2205cdf0e10cSrcweir 
2206cdf0e10cSrcweir     if ( m_nLastColId != GetCurColumnId() )
2207cdf0e10cSrcweir         onColumnChange();
2208cdf0e10cSrcweir 	m_nLastColId = GetCurColumnId();
2209cdf0e10cSrcweir 
2210cdf0e10cSrcweir     if ( m_nLastRowId != GetCurRow() )
2211cdf0e10cSrcweir         onRowChange();
2212cdf0e10cSrcweir 	m_nLastRowId = GetCurRow();
2213cdf0e10cSrcweir }
2214cdf0e10cSrcweir 
2215cdf0e10cSrcweir //------------------------------------------------------------------------------
onRowChange()2216cdf0e10cSrcweir void DbGridControl::onRowChange()
2217cdf0e10cSrcweir {
2218cdf0e10cSrcweir     // not interested in
2219cdf0e10cSrcweir }
2220cdf0e10cSrcweir 
2221cdf0e10cSrcweir //------------------------------------------------------------------------------
onColumnChange()2222cdf0e10cSrcweir void DbGridControl::onColumnChange()
2223cdf0e10cSrcweir {
2224cdf0e10cSrcweir     if ( m_pGridListener )
2225cdf0e10cSrcweir 		m_pGridListener->columnChanged();
2226cdf0e10cSrcweir }
2227cdf0e10cSrcweir 
2228cdf0e10cSrcweir //------------------------------------------------------------------------------
setDisplaySynchron(sal_Bool bSync)2229cdf0e10cSrcweir void DbGridControl::setDisplaySynchron(sal_Bool bSync)
2230cdf0e10cSrcweir {
2231cdf0e10cSrcweir 	if (bSync != m_bSynchDisplay)
2232cdf0e10cSrcweir 	{
2233cdf0e10cSrcweir 		m_bSynchDisplay = bSync;
2234cdf0e10cSrcweir 		if (m_bSynchDisplay)
2235cdf0e10cSrcweir 			AdjustDataSource(sal_False);
2236cdf0e10cSrcweir 	}
2237cdf0e10cSrcweir }
2238cdf0e10cSrcweir 
2239cdf0e10cSrcweir //------------------------------------------------------------------------------
forceSyncDisplay()2240cdf0e10cSrcweir void DbGridControl::forceSyncDisplay()
2241cdf0e10cSrcweir {
2242cdf0e10cSrcweir 	sal_Bool bOld = getDisplaySynchron();
2243cdf0e10cSrcweir 	setDisplaySynchron(sal_True);
2244cdf0e10cSrcweir 	if (!bOld)
2245cdf0e10cSrcweir 		setDisplaySynchron(bOld);
2246cdf0e10cSrcweir }
2247cdf0e10cSrcweir 
2248cdf0e10cSrcweir //------------------------------------------------------------------------------
forceROController(sal_Bool bForce)2249cdf0e10cSrcweir void DbGridControl::forceROController(sal_Bool bForce)
2250cdf0e10cSrcweir {
2251cdf0e10cSrcweir 	if (m_bForceROController == bForce)
2252cdf0e10cSrcweir 		return;
2253cdf0e10cSrcweir 
2254cdf0e10cSrcweir 	m_bForceROController = bForce;
2255cdf0e10cSrcweir 	// alle Columns durchgehen und denen Bescheid geben
2256cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<m_aColumns.Count(); ++i)
2257cdf0e10cSrcweir 	{
2258cdf0e10cSrcweir 		DbGridColumn* pColumn = m_aColumns.GetObject(i);
2259cdf0e10cSrcweir 		if (!pColumn)
2260cdf0e10cSrcweir 			continue;
2261cdf0e10cSrcweir 
2262cdf0e10cSrcweir 		CellController* pReturn = &pColumn->GetController();
2263cdf0e10cSrcweir 		if (!pReturn)
2264cdf0e10cSrcweir 			continue;
2265cdf0e10cSrcweir 
2266cdf0e10cSrcweir 		// nur wenn es eine Edit-Zeile ist, kann ich ihr das forced read-only mitgeben
2267cdf0e10cSrcweir 		if (!pReturn->ISA(EditCellController) && !pReturn->ISA(SpinCellController))
2268cdf0e10cSrcweir 			continue;
2269cdf0e10cSrcweir 
2270cdf0e10cSrcweir 		Edit& rEdit = (Edit&)pReturn->GetWindow();
2271cdf0e10cSrcweir 		rEdit.SetReadOnly(m_bForceROController);
2272cdf0e10cSrcweir 		if (m_bForceROController)
2273cdf0e10cSrcweir 			rEdit.SetStyle(rEdit.GetStyle() | WB_NOHIDESELECTION);
2274cdf0e10cSrcweir 		else
2275cdf0e10cSrcweir 			rEdit.SetStyle(rEdit.GetStyle() & ~WB_NOHIDESELECTION);
2276cdf0e10cSrcweir 	}
2277cdf0e10cSrcweir 
2278cdf0e10cSrcweir 	// die aktive Zelle erneut aktivieren, da sich ihr Controller geaendert haben kann
2279cdf0e10cSrcweir 	if (IsEditing())
2280cdf0e10cSrcweir 		DeactivateCell();
2281cdf0e10cSrcweir 	ActivateCell();
2282cdf0e10cSrcweir }
2283cdf0e10cSrcweir 
2284cdf0e10cSrcweir 
2285cdf0e10cSrcweir //------------------------------------------------------------------------------
AdjustDataSource(sal_Bool bFull)2286cdf0e10cSrcweir void DbGridControl::AdjustDataSource(sal_Bool bFull)
2287cdf0e10cSrcweir {
2288cdf0e10cSrcweir 	TRACE_RANGE("DbGridControl::AdjustDataSource");
2289cdf0e10cSrcweir 	::vos::OGuard aGuard(Application::GetSolarMutex());
2290cdf0e10cSrcweir 	// wird die aktuelle Zeile gerade neu bestimmt,
2291cdf0e10cSrcweir 	// wird kein abgleich vorgenommen
2292cdf0e10cSrcweir 
2293cdf0e10cSrcweir 	if (bFull)
2294cdf0e10cSrcweir 		m_xCurrentRow = NULL;
2295cdf0e10cSrcweir 	// if we are on the same row only repaint
2296cdf0e10cSrcweir 	// but this is only possible for rows which are not inserted, in that case the comparision result
2297cdf0e10cSrcweir 	// may not be correct
2298cdf0e10cSrcweir 	else
2299cdf0e10cSrcweir         if  (   m_xCurrentRow.Is()
2300cdf0e10cSrcweir             &&  !m_xCurrentRow->IsNew()
2301cdf0e10cSrcweir             &&  !m_pDataCursor->isBeforeFirst()
2302cdf0e10cSrcweir             &&  !m_pDataCursor->isAfterLast()
2303cdf0e10cSrcweir             &&  !m_pDataCursor->rowDeleted()
2304cdf0e10cSrcweir             )
2305cdf0e10cSrcweir 		{
2306cdf0e10cSrcweir 			sal_Bool bEqualBookmarks = CompareBookmark( m_xCurrentRow->GetBookmark(), m_pDataCursor->getBookmark() );
2307cdf0e10cSrcweir 
2308cdf0e10cSrcweir 			sal_Bool bDataCursorIsOnNew = sal_False;
2309cdf0e10cSrcweir 			m_pDataCursor->getPropertySet()->getPropertyValue( FM_PROP_ISNEW ) >>= bDataCursorIsOnNew;
2310cdf0e10cSrcweir 
2311cdf0e10cSrcweir 			if ( bEqualBookmarks && !bDataCursorIsOnNew )
2312cdf0e10cSrcweir 			{
2313cdf0e10cSrcweir 				// position of my data cursor is the same as the position our current row points tpo
2314cdf0e10cSrcweir 				// sync the status, repaint, done
2315cdf0e10cSrcweir 				DBG_ASSERT(m_xDataRow == m_xCurrentRow, "Fehler in den Datenzeilen");
2316cdf0e10cSrcweir 				TRACE_RANGE_MESSAGE1("same position, new state : %s", ROWSTATUS(m_xCurrentRow));
2317cdf0e10cSrcweir 				RowModified(m_nCurrentPos);
2318cdf0e10cSrcweir 				return;
2319cdf0e10cSrcweir 			}
2320cdf0e10cSrcweir 		}
2321cdf0e10cSrcweir 
2322cdf0e10cSrcweir 	// weg von der Row des DatenCursors
2323cdf0e10cSrcweir 	if (m_xPaintRow == m_xCurrentRow)
2324cdf0e10cSrcweir 		m_xPaintRow = m_xSeekRow;
2325cdf0e10cSrcweir 
2326cdf0e10cSrcweir 	// keine aktuelle Zeile dann komplett anpassen
2327cdf0e10cSrcweir 	if (!m_xCurrentRow)
2328cdf0e10cSrcweir 		AdjustRows();
2329cdf0e10cSrcweir 
2330cdf0e10cSrcweir 	sal_Int32 nNewPos = AlignSeekCursor();
2331cdf0e10cSrcweir 	if (nNewPos < 0)	// keine Position gefunden
2332cdf0e10cSrcweir 		return;
2333cdf0e10cSrcweir 
2334cdf0e10cSrcweir 	m_bInAdjustDataSource = sal_True;
2335cdf0e10cSrcweir 	if (nNewPos != m_nCurrentPos)
2336cdf0e10cSrcweir 	{
2337cdf0e10cSrcweir 		if (m_bSynchDisplay)
2338cdf0e10cSrcweir 			DbGridControl_Base::GoToRow(nNewPos);
2339cdf0e10cSrcweir 
2340cdf0e10cSrcweir 		if (!m_xCurrentRow.Is())
2341cdf0e10cSrcweir 			// das tritt zum Beispiel auf, wenn man die n (n>1) letzten Datensaetze geloescht hat, waehrend der Cursor auf dem letzten
2342cdf0e10cSrcweir 			// steht : AdjustRows entfernt dann zwei Zeilen aus der BrowseBox, wodurch diese ihre CurrentRow um zwei nach unten
2343cdf0e10cSrcweir 			// korrigiert, so dass dann das GoToRow in's Leere laeuft (da wir uns ja angeblich schon an der richtigen Position
2344cdf0e10cSrcweir 			// befinden)
2345cdf0e10cSrcweir 			SetCurrent(nNewPos);
2346cdf0e10cSrcweir 	}
2347cdf0e10cSrcweir 	else
2348cdf0e10cSrcweir 	{
2349cdf0e10cSrcweir 		SetCurrent(nNewPos);
2350cdf0e10cSrcweir 		RowModified(nNewPos);
2351cdf0e10cSrcweir 	}
2352cdf0e10cSrcweir 	m_bInAdjustDataSource = sal_False;
2353cdf0e10cSrcweir 
2354cdf0e10cSrcweir 	// Wird der DatenCursor von aussen bewegt, wird die selektion aufgehoben
2355cdf0e10cSrcweir 	SetNoSelection();
2356cdf0e10cSrcweir 	m_aBar.InvalidateAll(m_nCurrentPos, m_xCurrentRow.Is());
2357cdf0e10cSrcweir }
2358cdf0e10cSrcweir 
2359cdf0e10cSrcweir //------------------------------------------------------------------------------
AlignSeekCursor()2360cdf0e10cSrcweir sal_Int32 DbGridControl::AlignSeekCursor()
2361cdf0e10cSrcweir {
2362cdf0e10cSrcweir 	DBG_CHKTHIS( DbGridControl, NULL );
2363cdf0e10cSrcweir 	// Positioniert den SeekCursor auf den DatenCursor, Daten werden nicht uebertragen
2364cdf0e10cSrcweir 
2365cdf0e10cSrcweir 	if (!m_pSeekCursor)
2366cdf0e10cSrcweir 		return -1;
2367cdf0e10cSrcweir 
2368cdf0e10cSrcweir 	Reference< XPropertySet > xSet = m_pDataCursor->getPropertySet();
2369cdf0e10cSrcweir 
2370cdf0e10cSrcweir 	// jetzt den seekcursor an den DatenCursor angleichen
2371cdf0e10cSrcweir 	if (::comphelper::getBOOL(xSet->getPropertyValue(FM_PROP_ISNEW)))
2372cdf0e10cSrcweir 		m_nSeekPos = GetRowCount() - 1;
2373cdf0e10cSrcweir 	else
2374cdf0e10cSrcweir 	{
2375cdf0e10cSrcweir 		try
2376cdf0e10cSrcweir 		{
2377cdf0e10cSrcweir 			if ( m_pDataCursor->isBeforeFirst() )
2378cdf0e10cSrcweir 			{
2379cdf0e10cSrcweir 				// this is somewhat strange, but can nevertheless happen
2380cdf0e10cSrcweir 				DBG_WARNING( "DbGridControl::AlignSeekCursor: nobody should tamper with my cursor this way (before first)!" );
2381cdf0e10cSrcweir 				m_pSeekCursor->first();
2382cdf0e10cSrcweir 				m_pSeekCursor->previous();
2383cdf0e10cSrcweir 				m_nSeekPos = -1;
2384cdf0e10cSrcweir 			}
2385cdf0e10cSrcweir 			else if ( m_pDataCursor->isAfterLast() )
2386cdf0e10cSrcweir 			{
2387cdf0e10cSrcweir 				DBG_WARNING( "DbGridControl::AlignSeekCursor: nobody should tamper with my cursor this way (after last)!" );
2388cdf0e10cSrcweir 				m_pSeekCursor->last();
2389cdf0e10cSrcweir 				m_pSeekCursor->next();
2390cdf0e10cSrcweir 				m_nSeekPos = -1;
2391cdf0e10cSrcweir 			}
2392cdf0e10cSrcweir 			else
2393cdf0e10cSrcweir 			{
2394cdf0e10cSrcweir 				m_pSeekCursor->moveToBookmark(m_pDataCursor->getBookmark());
2395cdf0e10cSrcweir 				if (!CompareBookmark(m_pDataCursor->getBookmark(), m_pSeekCursor->getBookmark()))
2396cdf0e10cSrcweir 					// dummerweise kann das moveToBookmark indirekt dazu fuehren, dass der Seek-Cursor wieder neu positoniert wird (wenn
2397cdf0e10cSrcweir 					// naemlich das mit all seinen zu feuernden Events relativ komplexe moveToBookmark irgendwo ein Update ausloest),
2398cdf0e10cSrcweir 					// also muss ich es nochmal versuchen
2399cdf0e10cSrcweir 					m_pSeekCursor->moveToBookmark(m_pDataCursor->getBookmark());
2400cdf0e10cSrcweir 					// Nicht dass das jetzt nicht auch schief gegangen sein koennte, aber es ist zumindest unwahrscheinlicher geworden.
2401cdf0e10cSrcweir 					// Und die Alternative waere eine Schleife so lange bis es stimmt, und das kann auch nicht die Loesung sein
2402cdf0e10cSrcweir 				m_nSeekPos = m_pSeekCursor->getRow() - 1;
2403cdf0e10cSrcweir 			}
2404cdf0e10cSrcweir 		}
2405cdf0e10cSrcweir 		catch(Exception&)
2406cdf0e10cSrcweir 		{
2407cdf0e10cSrcweir 		}
2408cdf0e10cSrcweir 	}
2409cdf0e10cSrcweir 	return m_nSeekPos;
2410cdf0e10cSrcweir }
2411cdf0e10cSrcweir //------------------------------------------------------------------------------
SeekCursor(long nRow,sal_Bool bAbsolute)2412cdf0e10cSrcweir sal_Bool DbGridControl::SeekCursor(long nRow, sal_Bool bAbsolute)
2413cdf0e10cSrcweir {
2414cdf0e10cSrcweir 	DBG_CHKTHIS( DbGridControl, NULL );
2415cdf0e10cSrcweir 	// Positioniert den SeekCursor, Daten werden nicht uebertragen
2416cdf0e10cSrcweir 
2417cdf0e10cSrcweir 	// additions for the filtermode
2418cdf0e10cSrcweir 	if (IsFilterRow(nRow))
2419cdf0e10cSrcweir 	{
2420cdf0e10cSrcweir 		m_nSeekPos = 0;
2421cdf0e10cSrcweir 		return sal_True;
2422cdf0e10cSrcweir 	}
2423cdf0e10cSrcweir 
2424cdf0e10cSrcweir 	if (!m_pSeekCursor)
2425cdf0e10cSrcweir 		return sal_False;
2426cdf0e10cSrcweir 
2427cdf0e10cSrcweir 	// Befinden wir uns gerade beim Einfuegen
2428cdf0e10cSrcweir 	if (IsValid(m_xCurrentRow) && m_xCurrentRow->IsNew() &&
2429cdf0e10cSrcweir 		nRow >= m_nCurrentPos)
2430cdf0e10cSrcweir 	{
2431cdf0e10cSrcweir 		// dann darf auf alle Faelle nicht weiter nach unten gescrollt werden
2432cdf0e10cSrcweir 		// da der letzte Datensatz bereits erreicht wurde!
2433cdf0e10cSrcweir 		if (nRow == m_nCurrentPos)
2434cdf0e10cSrcweir 		{
2435cdf0e10cSrcweir 			// auf die aktuelle Zeile bewegt, dann muß kein abgleich gemacht werden, wenn
2436cdf0e10cSrcweir 			// gerade ein Datensatz eingefuegt wird
2437cdf0e10cSrcweir 			m_nSeekPos = nRow;
2438cdf0e10cSrcweir 		}
2439cdf0e10cSrcweir 		else if (IsInsertionRow(nRow))	// Leerzeile zum Einfuegen von Datensaetzen
2440cdf0e10cSrcweir 			m_nSeekPos = nRow;
2441cdf0e10cSrcweir 	}
2442cdf0e10cSrcweir 	else if (IsInsertionRow(nRow))	// Leerzeile zum Einfuegen von Datensaetzen
2443cdf0e10cSrcweir 		m_nSeekPos = nRow;
2444cdf0e10cSrcweir 	else if ((-1 == nRow) && (GetRowCount() == ((m_nOptions & OPT_INSERT) ? 1 : 0)) && m_pSeekCursor->isAfterLast())
2445cdf0e10cSrcweir 		m_nSeekPos = nRow;
2446cdf0e10cSrcweir 	else
2447cdf0e10cSrcweir 	{
2448cdf0e10cSrcweir 
2449cdf0e10cSrcweir 		sal_Bool bSuccess=sal_False;
2450cdf0e10cSrcweir 		long nSteps = 0;
2451cdf0e10cSrcweir 		try
2452cdf0e10cSrcweir 		{
2453cdf0e10cSrcweir             if ( m_pSeekCursor->rowDeleted() )
2454cdf0e10cSrcweir             {
2455cdf0e10cSrcweir                 // somebody deleted the current row of the seek cursor. Move it away from this row.
2456cdf0e10cSrcweir                 m_pSeekCursor->next();
2457cdf0e10cSrcweir                 if ( m_pSeekCursor->isAfterLast() || m_pSeekCursor->isBeforeFirst() )
2458cdf0e10cSrcweir 			        bAbsolute = sal_True;
2459cdf0e10cSrcweir             }
2460cdf0e10cSrcweir 
2461cdf0e10cSrcweir     		if ( !bAbsolute )
2462cdf0e10cSrcweir             {
2463cdf0e10cSrcweir                 DBG_ASSERT( !m_pSeekCursor->isAfterLast() && !m_pSeekCursor->isBeforeFirst(),
2464cdf0e10cSrcweir                     "DbGridControl::SeekCursor: how did the seek cursor get to this position?!" );
2465cdf0e10cSrcweir 			    nSteps = nRow - (m_pSeekCursor->getRow() - 1);
2466cdf0e10cSrcweir 			    bAbsolute = bAbsolute || (abs(nSteps) > 100);
2467cdf0e10cSrcweir             }
2468cdf0e10cSrcweir 
2469cdf0e10cSrcweir             if ( bAbsolute )
2470cdf0e10cSrcweir 			{
2471cdf0e10cSrcweir                 bSuccess = m_pSeekCursor->absolute(nRow + 1);
2472cdf0e10cSrcweir 				if (bSuccess)
2473cdf0e10cSrcweir 					m_nSeekPos = nRow;
2474cdf0e10cSrcweir 			}
2475cdf0e10cSrcweir             else
2476cdf0e10cSrcweir             {
2477cdf0e10cSrcweir                 if (nSteps > 0) 								// auf den letzten benoetigten Datensatz positionieren
2478cdf0e10cSrcweir 				{
2479cdf0e10cSrcweir 					if (m_pSeekCursor->isAfterLast())
2480cdf0e10cSrcweir 						bSuccess = sal_False;
2481cdf0e10cSrcweir 					else if (m_pSeekCursor->isBeforeFirst())
2482cdf0e10cSrcweir 						bSuccess = m_pSeekCursor->absolute(nSteps);
2483cdf0e10cSrcweir 					else
2484cdf0e10cSrcweir 						bSuccess = m_pSeekCursor->relative(nSteps);
2485cdf0e10cSrcweir 				}
2486cdf0e10cSrcweir 				else if (nSteps < 0)
2487cdf0e10cSrcweir 				{
2488cdf0e10cSrcweir 					if (m_pSeekCursor->isBeforeFirst())
2489cdf0e10cSrcweir 						bSuccess = sal_False;
2490cdf0e10cSrcweir 					else if (m_pSeekCursor->isAfterLast())
2491cdf0e10cSrcweir 						bSuccess = m_pSeekCursor->absolute(nSteps);
2492cdf0e10cSrcweir 					else
2493cdf0e10cSrcweir 						bSuccess = m_pSeekCursor->relative(nSteps);
2494cdf0e10cSrcweir 				}
2495cdf0e10cSrcweir 				else
2496cdf0e10cSrcweir 				{
2497cdf0e10cSrcweir 					m_nSeekPos = nRow;
2498cdf0e10cSrcweir 					return sal_True;
2499cdf0e10cSrcweir 				}
2500cdf0e10cSrcweir 			}
2501cdf0e10cSrcweir 		}
2502cdf0e10cSrcweir 		catch(Exception&)
2503cdf0e10cSrcweir 		{
2504cdf0e10cSrcweir 			DBG_ERROR("DbGridControl::SeekCursor : failed ...");
2505cdf0e10cSrcweir 		}
2506cdf0e10cSrcweir 
2507cdf0e10cSrcweir 		try
2508cdf0e10cSrcweir 		{
2509cdf0e10cSrcweir 			if (!bSuccess)
2510cdf0e10cSrcweir 			{
2511cdf0e10cSrcweir 				if (bAbsolute || nSteps > 0)
2512cdf0e10cSrcweir 					bSuccess = m_pSeekCursor->last();
2513cdf0e10cSrcweir 				else
2514cdf0e10cSrcweir 					bSuccess = m_pSeekCursor->first();
2515cdf0e10cSrcweir 			}
2516cdf0e10cSrcweir 
2517cdf0e10cSrcweir 			if (bSuccess)
2518cdf0e10cSrcweir 				m_nSeekPos = m_pSeekCursor->getRow() - 1;
2519cdf0e10cSrcweir 			else
2520cdf0e10cSrcweir 				m_nSeekPos = -1;
2521cdf0e10cSrcweir 		}
2522cdf0e10cSrcweir 		catch(Exception&)
2523cdf0e10cSrcweir 		{
2524cdf0e10cSrcweir 			DBG_ERROR("DbGridControl::SeekCursor : failed ...");
2525cdf0e10cSrcweir 			m_nSeekPos = -1;						// kein Datensatz mehr vorhanden
2526cdf0e10cSrcweir 		}
2527cdf0e10cSrcweir 	}
2528cdf0e10cSrcweir 	return m_nSeekPos == nRow;
2529cdf0e10cSrcweir }
2530cdf0e10cSrcweir //------------------------------------------------------------------------------
MoveToFirst()2531cdf0e10cSrcweir void DbGridControl::MoveToFirst()
2532cdf0e10cSrcweir {
2533cdf0e10cSrcweir 	if (m_pSeekCursor && (GetCurRow() != 0))
2534cdf0e10cSrcweir 		MoveToPosition(0);
2535cdf0e10cSrcweir }
2536cdf0e10cSrcweir 
2537cdf0e10cSrcweir //------------------------------------------------------------------------------
MoveToLast()2538cdf0e10cSrcweir void DbGridControl::MoveToLast()
2539cdf0e10cSrcweir {
2540cdf0e10cSrcweir 	if (!m_pSeekCursor)
2541cdf0e10cSrcweir 		return;
2542cdf0e10cSrcweir 
2543cdf0e10cSrcweir 	if (m_nTotalCount < 0)			// RecordCount steht noch nicht fest
2544cdf0e10cSrcweir 	{
2545cdf0e10cSrcweir 		try
2546cdf0e10cSrcweir 		{
2547cdf0e10cSrcweir 			sal_Bool bRes = m_pSeekCursor->last();
2548cdf0e10cSrcweir 
2549cdf0e10cSrcweir 			if (bRes)
2550cdf0e10cSrcweir 			{
2551cdf0e10cSrcweir 				m_nSeekPos = m_pSeekCursor->getRow() - 1;
2552cdf0e10cSrcweir 				AdjustRows();
2553cdf0e10cSrcweir 			}
2554cdf0e10cSrcweir 		}
2555cdf0e10cSrcweir 		catch(Exception&)
2556cdf0e10cSrcweir 		{
2557cdf0e10cSrcweir 		}
2558cdf0e10cSrcweir 	}
2559cdf0e10cSrcweir 
2560cdf0e10cSrcweir 	// auf den letzen Datensatz positionieren, nicht auf die Leerzeile
2561cdf0e10cSrcweir 	if (m_nOptions & OPT_INSERT)
2562cdf0e10cSrcweir 	{
2563cdf0e10cSrcweir 		if ((GetRowCount() - 1) > 0)
2564cdf0e10cSrcweir 			MoveToPosition(GetRowCount() - 2);
2565cdf0e10cSrcweir 	}
2566cdf0e10cSrcweir 	else if (GetRowCount())
2567cdf0e10cSrcweir 		MoveToPosition(GetRowCount() - 1);
2568cdf0e10cSrcweir }
2569cdf0e10cSrcweir 
2570cdf0e10cSrcweir //------------------------------------------------------------------------------
MoveToPrev()2571cdf0e10cSrcweir void DbGridControl::MoveToPrev()
2572cdf0e10cSrcweir {
2573cdf0e10cSrcweir 	long nNewRow = std::max(GetCurRow() - 1L, 0L);
2574cdf0e10cSrcweir 	if (GetCurRow() != nNewRow)
2575cdf0e10cSrcweir 		MoveToPosition(nNewRow);
2576cdf0e10cSrcweir }
2577cdf0e10cSrcweir 
2578cdf0e10cSrcweir //------------------------------------------------------------------------------
MoveToNext()2579cdf0e10cSrcweir void DbGridControl::MoveToNext()
2580cdf0e10cSrcweir {
2581cdf0e10cSrcweir 	if (!m_pSeekCursor)
2582cdf0e10cSrcweir 		return;
2583cdf0e10cSrcweir 
2584cdf0e10cSrcweir 	if (m_nTotalCount > 0)
2585cdf0e10cSrcweir 	{
2586cdf0e10cSrcweir 		// move the data cursor to the right position
2587cdf0e10cSrcweir 		long nNewRow = std::min(GetRowCount() - 1, GetCurRow() + 1);
2588cdf0e10cSrcweir 		if (GetCurRow() != nNewRow)
2589cdf0e10cSrcweir 			MoveToPosition(nNewRow);
2590cdf0e10cSrcweir 	}
2591cdf0e10cSrcweir 	else
2592cdf0e10cSrcweir 	{
2593cdf0e10cSrcweir 		sal_Bool bOk = sal_False;
2594cdf0e10cSrcweir 		try
2595cdf0e10cSrcweir 		{
2596cdf0e10cSrcweir 			// try to move to next row
2597cdf0e10cSrcweir 			// when not possible our paint cursor is already on the last row
2598cdf0e10cSrcweir 			// then we must be sure that the data cursor is on the position
2599cdf0e10cSrcweir 			// we call ourself again
2600cdf0e10cSrcweir             bOk = m_pSeekCursor->next();
2601cdf0e10cSrcweir 			if (bOk)
2602cdf0e10cSrcweir 			{
2603cdf0e10cSrcweir 				m_nSeekPos = m_pSeekCursor->getRow() - 1;
2604cdf0e10cSrcweir 				MoveToPosition(GetCurRow() + 1);
2605cdf0e10cSrcweir 			}
2606cdf0e10cSrcweir 		}
2607cdf0e10cSrcweir 		catch(SQLException &)
2608cdf0e10cSrcweir 		{
2609cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
2610cdf0e10cSrcweir 		}
2611cdf0e10cSrcweir 
2612cdf0e10cSrcweir 		if(!bOk)
2613cdf0e10cSrcweir 		{
2614cdf0e10cSrcweir 			AdjustRows();
2615cdf0e10cSrcweir 			if (m_nTotalCount > 0) // only to avoid infinte recursion
2616cdf0e10cSrcweir 				MoveToNext();
2617cdf0e10cSrcweir 		}
2618cdf0e10cSrcweir 	}
2619cdf0e10cSrcweir }
2620cdf0e10cSrcweir 
2621cdf0e10cSrcweir //------------------------------------------------------------------------------
MoveToPosition(sal_uInt32 nPos)2622cdf0e10cSrcweir void DbGridControl::MoveToPosition(sal_uInt32 nPos)
2623cdf0e10cSrcweir {
2624cdf0e10cSrcweir 	if (!m_pSeekCursor)
2625cdf0e10cSrcweir 		return;
2626cdf0e10cSrcweir 
2627cdf0e10cSrcweir     if (m_nTotalCount < 0 && (long)nPos >= GetRowCount())
2628cdf0e10cSrcweir     {
2629cdf0e10cSrcweir         try
2630cdf0e10cSrcweir         {
2631cdf0e10cSrcweir             if (!m_pSeekCursor->absolute(nPos + 1))
2632cdf0e10cSrcweir             {
2633cdf0e10cSrcweir                 AdjustRows();
2634cdf0e10cSrcweir                 Sound::Beep();
2635cdf0e10cSrcweir                 return;
2636cdf0e10cSrcweir             }
2637cdf0e10cSrcweir             else
2638cdf0e10cSrcweir             {
2639cdf0e10cSrcweir                 m_nSeekPos = m_pSeekCursor->getRow() - 1;
2640cdf0e10cSrcweir                 AdjustRows();
2641cdf0e10cSrcweir             }
2642cdf0e10cSrcweir         }
2643cdf0e10cSrcweir         catch(Exception&)
2644cdf0e10cSrcweir         {
2645cdf0e10cSrcweir             return;
2646cdf0e10cSrcweir         }
2647cdf0e10cSrcweir     }
2648cdf0e10cSrcweir     DbGridControl_Base::GoToRow(nPos);
2649cdf0e10cSrcweir     m_aBar.InvalidateAll(m_nCurrentPos);
2650cdf0e10cSrcweir }
2651cdf0e10cSrcweir 
2652cdf0e10cSrcweir //------------------------------------------------------------------------------
AppendNew()2653cdf0e10cSrcweir void DbGridControl::AppendNew()
2654cdf0e10cSrcweir {
2655cdf0e10cSrcweir 	if (!m_pSeekCursor || !(m_nOptions & OPT_INSERT))
2656cdf0e10cSrcweir 		return;
2657cdf0e10cSrcweir 
2658cdf0e10cSrcweir 	if (m_nTotalCount < 0)			// RecordCount steht noch nicht fest
2659cdf0e10cSrcweir 	{
2660cdf0e10cSrcweir 		try
2661cdf0e10cSrcweir 		{
2662cdf0e10cSrcweir 			sal_Bool bRes = m_pSeekCursor->last();
2663cdf0e10cSrcweir 
2664cdf0e10cSrcweir 			if (bRes)
2665cdf0e10cSrcweir 			{
2666cdf0e10cSrcweir 				m_nSeekPos = m_pSeekCursor->getRow() - 1;
2667cdf0e10cSrcweir 				AdjustRows();
2668cdf0e10cSrcweir 			}
2669cdf0e10cSrcweir 		}
2670cdf0e10cSrcweir 		catch(Exception&)
2671cdf0e10cSrcweir 		{
2672cdf0e10cSrcweir 			return;
2673cdf0e10cSrcweir 		}
2674cdf0e10cSrcweir 	}
2675cdf0e10cSrcweir 
2676cdf0e10cSrcweir 	long nNewRow = m_nTotalCount + 1;
2677cdf0e10cSrcweir 	if (nNewRow > 0 && GetCurRow() != nNewRow)
2678cdf0e10cSrcweir 		MoveToPosition(nNewRow - 1);
2679cdf0e10cSrcweir }
2680cdf0e10cSrcweir 
2681cdf0e10cSrcweir //------------------------------------------------------------------------------
SetDesignMode(sal_Bool bMode)2682cdf0e10cSrcweir void DbGridControl::SetDesignMode(sal_Bool bMode)
2683cdf0e10cSrcweir {
2684cdf0e10cSrcweir 	if (IsDesignMode() != bMode)
2685cdf0e10cSrcweir 	{
2686cdf0e10cSrcweir 		// Enable/Disable f�r den Designmode anpassen damit die Headerbar konfigurierbar bleibt
2687cdf0e10cSrcweir 		if (bMode)
2688cdf0e10cSrcweir 		{
2689cdf0e10cSrcweir 			if (!IsEnabled())
2690cdf0e10cSrcweir 			{
2691cdf0e10cSrcweir 				Enable();
2692cdf0e10cSrcweir 				GetDataWindow().Disable();
2693cdf0e10cSrcweir 			}
2694cdf0e10cSrcweir 		}
2695cdf0e10cSrcweir 		else
2696cdf0e10cSrcweir 		{
2697cdf0e10cSrcweir 			// komplett disablen
2698cdf0e10cSrcweir 			if (!GetDataWindow().IsEnabled())
2699cdf0e10cSrcweir 				Disable();
2700cdf0e10cSrcweir 		}
2701cdf0e10cSrcweir 
2702cdf0e10cSrcweir 		m_bDesignMode = bMode;
2703cdf0e10cSrcweir 		GetDataWindow().SetMouseTransparent(bMode);
2704cdf0e10cSrcweir 		SetMouseTransparent(bMode);
2705cdf0e10cSrcweir 
2706cdf0e10cSrcweir 		m_aBar.InvalidateAll(m_nCurrentPos, sal_True);
2707cdf0e10cSrcweir 	}
2708cdf0e10cSrcweir }
2709cdf0e10cSrcweir 
2710cdf0e10cSrcweir //------------------------------------------------------------------------------
SetFilterMode(sal_Bool bMode)2711cdf0e10cSrcweir void DbGridControl::SetFilterMode(sal_Bool bMode)
2712cdf0e10cSrcweir {
2713cdf0e10cSrcweir 	if (IsFilterMode() != bMode)
2714cdf0e10cSrcweir 	{
2715cdf0e10cSrcweir 		m_bFilterMode = bMode;
2716cdf0e10cSrcweir 
2717cdf0e10cSrcweir 		if (bMode)
2718cdf0e10cSrcweir 		{
2719cdf0e10cSrcweir 			SetUpdateMode(sal_False);
2720cdf0e10cSrcweir 
2721cdf0e10cSrcweir 			// es gibt kein Cursor mehr
2722cdf0e10cSrcweir 			if (IsEditing())
2723cdf0e10cSrcweir 				DeactivateCell();
2724cdf0e10cSrcweir 			RemoveRows(sal_False);
2725cdf0e10cSrcweir 
2726cdf0e10cSrcweir 			m_xEmptyRow = new DbGridRow();
2727cdf0e10cSrcweir 
2728cdf0e10cSrcweir 			// setting the new filter controls
2729cdf0e10cSrcweir 			for (sal_uInt16 i = 0; i<m_aColumns.Count(); ++i)
2730cdf0e10cSrcweir 			{
2731cdf0e10cSrcweir 				DbGridColumn* pCurCol = m_aColumns.GetObject(i);
2732cdf0e10cSrcweir 				if (!pCurCol->IsHidden())
2733cdf0e10cSrcweir 					pCurCol->UpdateControl();
2734cdf0e10cSrcweir 			}
2735cdf0e10cSrcweir 
2736cdf0e10cSrcweir 			// one row for filtering
2737cdf0e10cSrcweir 			RowInserted(0, 1, sal_True);
2738cdf0e10cSrcweir 			SetUpdateMode(sal_True);
2739cdf0e10cSrcweir 		}
2740cdf0e10cSrcweir 		else
2741cdf0e10cSrcweir 			setDataSource(Reference< XRowSet > ());
2742cdf0e10cSrcweir 	}
2743cdf0e10cSrcweir }
2744cdf0e10cSrcweir // -----------------------------------------------------------------------------
GetCellText(long _nRow,sal_uInt16 _nColId) const2745cdf0e10cSrcweir String DbGridControl::GetCellText(long _nRow, sal_uInt16 _nColId) const
2746cdf0e10cSrcweir {
2747cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject( GetModelColumnPos( _nColId ) );
2748cdf0e10cSrcweir 	String sRet;
2749cdf0e10cSrcweir 	if ( const_cast<DbGridControl*>(this)->SeekRow(_nRow) )
2750cdf0e10cSrcweir 		sRet = GetCurrentRowCellText(pColumn, m_xPaintRow);
2751cdf0e10cSrcweir 	return sRet;
2752cdf0e10cSrcweir }
2753cdf0e10cSrcweir //------------------------------------------------------------------------------
GetCurrentRowCellText(DbGridColumn * pColumn,const DbGridRowRef & _rRow) const2754cdf0e10cSrcweir XubString DbGridControl::GetCurrentRowCellText(DbGridColumn* pColumn,const DbGridRowRef& _rRow) const
2755cdf0e10cSrcweir {
2756cdf0e10cSrcweir 	// Ausgabe des Textes fuer eine Zelle
2757cdf0e10cSrcweir 	XubString aText;
2758cdf0e10cSrcweir 	if ( pColumn && IsValid(m_xPaintRow) )
2759cdf0e10cSrcweir 		aText = pColumn->GetCellText(_rRow, m_xFormatter);
2760cdf0e10cSrcweir 	return aText;
2761cdf0e10cSrcweir }
2762cdf0e10cSrcweir 
2763cdf0e10cSrcweir //------------------------------------------------------------------------------
GetTotalCellWidth(long nRow,sal_uInt16 nColId)2764cdf0e10cSrcweir sal_uInt32 DbGridControl::GetTotalCellWidth(long nRow, sal_uInt16 nColId)
2765cdf0e10cSrcweir {
2766cdf0e10cSrcweir 	if (SeekRow(nRow))
2767cdf0e10cSrcweir 	{
2768cdf0e10cSrcweir 		DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColId));
2769cdf0e10cSrcweir 		return GetDataWindow().GetTextWidth(GetCurrentRowCellText(pColumn,m_xPaintRow));
2770cdf0e10cSrcweir 	}
2771cdf0e10cSrcweir 	else
2772cdf0e10cSrcweir 		return 30;	//xxxx
2773cdf0e10cSrcweir }
2774cdf0e10cSrcweir 
2775cdf0e10cSrcweir //------------------------------------------------------------------------------
PreExecuteRowContextMenu(sal_uInt16,PopupMenu & rMenu)2776cdf0e10cSrcweir void DbGridControl::PreExecuteRowContextMenu(sal_uInt16 /*nRow*/, PopupMenu& rMenu)
2777cdf0e10cSrcweir {
2778cdf0e10cSrcweir 	sal_Bool bDelete = (m_nOptions & OPT_DELETE) && GetSelectRowCount() && !IsCurrentAppending();
2779cdf0e10cSrcweir 	// ist nur die Leerzeile selektiert, dann nicht loeschen
2780cdf0e10cSrcweir 	bDelete = bDelete && !((m_nOptions & OPT_INSERT) && GetSelectRowCount() == 1 && IsRowSelected(GetRowCount() - 1));
2781cdf0e10cSrcweir 
2782cdf0e10cSrcweir 	rMenu.EnableItem(SID_FM_DELETEROWS, bDelete);
2783cdf0e10cSrcweir 	rMenu.EnableItem(SID_FM_RECORD_SAVE, IsModified());
2784cdf0e10cSrcweir 
2785cdf0e10cSrcweir 	// the undo is more difficult
2786cdf0e10cSrcweir 	sal_Bool bCanUndo = IsModified();
2787cdf0e10cSrcweir 	long nState = -1;
2788cdf0e10cSrcweir 	if (m_aMasterStateProvider.IsSet())
2789cdf0e10cSrcweir 		nState = m_aMasterStateProvider.Call((void*)SID_FM_RECORD_UNDO);
2790cdf0e10cSrcweir 	bCanUndo &= ( 0 != nState );
2791cdf0e10cSrcweir 
2792cdf0e10cSrcweir 	rMenu.EnableItem(SID_FM_RECORD_UNDO, bCanUndo);
2793cdf0e10cSrcweir }
2794cdf0e10cSrcweir 
2795cdf0e10cSrcweir //------------------------------------------------------------------------------
PostExecuteRowContextMenu(sal_uInt16,const PopupMenu &,sal_uInt16 nExecutionResult)2796cdf0e10cSrcweir void DbGridControl::PostExecuteRowContextMenu(sal_uInt16 /*nRow*/, const PopupMenu& /*rMenu*/, sal_uInt16 nExecutionResult)
2797cdf0e10cSrcweir {
2798cdf0e10cSrcweir 	switch (nExecutionResult)
2799cdf0e10cSrcweir 	{
2800cdf0e10cSrcweir 		case SID_FM_DELETEROWS:
2801cdf0e10cSrcweir 			// delete asynchron
2802cdf0e10cSrcweir 			if (m_nDeleteEvent)
2803cdf0e10cSrcweir 				Application::RemoveUserEvent(m_nDeleteEvent);
2804cdf0e10cSrcweir 			m_nDeleteEvent = Application::PostUserEvent(LINK(this,DbGridControl,OnDelete));
2805cdf0e10cSrcweir 			break;
2806cdf0e10cSrcweir 		case SID_FM_RECORD_UNDO:
2807cdf0e10cSrcweir 			Undo();
2808cdf0e10cSrcweir 			break;
2809cdf0e10cSrcweir 		case SID_FM_RECORD_SAVE:
2810cdf0e10cSrcweir 			SaveRow();
2811cdf0e10cSrcweir 			break;
2812cdf0e10cSrcweir 		default:
2813cdf0e10cSrcweir 			break;
2814cdf0e10cSrcweir 	}
2815cdf0e10cSrcweir }
2816cdf0e10cSrcweir 
2817cdf0e10cSrcweir //------------------------------------------------------------------------------
DataSourcePropertyChanged(const PropertyChangeEvent & evt)2818cdf0e10cSrcweir void DbGridControl::DataSourcePropertyChanged(const PropertyChangeEvent& evt) throw( RuntimeException )
2819cdf0e10cSrcweir {
2820cdf0e10cSrcweir 	TRACE_RANGE("DbGridControl::DataSourcePropertyChanged");
2821cdf0e10cSrcweir 	::vos::OGuard aGuard( Application::GetSolarMutex() );
2822cdf0e10cSrcweir 	// prop "IsModified" changed ?
2823cdf0e10cSrcweir 	// during update don't care about the modified state
2824cdf0e10cSrcweir 	if (!IsUpdating() && evt.PropertyName.compareTo(FM_PROP_ISMODIFIED) == COMPARE_EQUAL)
2825cdf0e10cSrcweir 	{
2826cdf0e10cSrcweir 		Reference< XPropertySet > xSource(evt.Source, UNO_QUERY);
2827cdf0e10cSrcweir 		DBG_ASSERT( xSource.is(), "DbGridControl::DataSourcePropertyChanged: invalid event source!" );
2828cdf0e10cSrcweir 		sal_Bool bIsNew = sal_False;
2829cdf0e10cSrcweir 		if (xSource.is())
2830cdf0e10cSrcweir 			bIsNew = ::comphelper::getBOOL(xSource->getPropertyValue(FM_PROP_ISNEW));
2831cdf0e10cSrcweir 
2832cdf0e10cSrcweir 		if (bIsNew && m_xCurrentRow.Is())
2833cdf0e10cSrcweir 		{
2834cdf0e10cSrcweir 			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 !");
2835cdf0e10cSrcweir 			sal_Int32 nRecordCount = 0;
2836cdf0e10cSrcweir 			xSource->getPropertyValue(FM_PROP_ROWCOUNT) >>= nRecordCount;
2837cdf0e10cSrcweir 			if (::comphelper::getBOOL(evt.NewValue))
2838cdf0e10cSrcweir 			{	// modified state changed from sal_False to sal_True and we're on a insert row
2839cdf0e10cSrcweir 				// -> we've to add a new grid row
2840cdf0e10cSrcweir 				if ((nRecordCount == GetRowCount() - 1)  && m_xCurrentRow->IsNew())
2841cdf0e10cSrcweir 				{
2842cdf0e10cSrcweir 					RowInserted(GetRowCount(), 1, sal_True);
2843cdf0e10cSrcweir 					InvalidateStatusCell(m_nCurrentPos);
2844cdf0e10cSrcweir 					m_aBar.InvalidateAll(m_nCurrentPos);
2845cdf0e10cSrcweir 				}
2846cdf0e10cSrcweir 			}
2847cdf0e10cSrcweir 			else
2848cdf0e10cSrcweir 			{	// modified state changed from sal_True to sal_False and we're on a insert row
2849cdf0e10cSrcweir 				// we have two "new row"s at the moment : the one we're editing currently (where the current
2850cdf0e10cSrcweir 				// column is the only dirty element) and a "new new" row which is completely clean. As the first
2851cdf0e10cSrcweir 				// one is about to be cleaned, too, the second one is obsolet now.
2852cdf0e10cSrcweir 				if (m_xCurrentRow->IsNew() && nRecordCount == (GetRowCount() - 2))
2853cdf0e10cSrcweir 				{
2854cdf0e10cSrcweir 					RowRemoved(GetRowCount() - 1, 1, sal_True);
2855cdf0e10cSrcweir 					InvalidateStatusCell(m_nCurrentPos);
2856cdf0e10cSrcweir 					m_aBar.InvalidateAll(m_nCurrentPos);
2857cdf0e10cSrcweir 				}
2858cdf0e10cSrcweir 			}
2859cdf0e10cSrcweir 		}
2860cdf0e10cSrcweir 		if (m_xCurrentRow.Is())
2861cdf0e10cSrcweir 		{
2862cdf0e10cSrcweir 			m_xCurrentRow->SetStatus(::comphelper::getBOOL(evt.NewValue) ? GRS_MODIFIED : GRS_CLEAN);
2863cdf0e10cSrcweir 			m_xCurrentRow->SetNew( bIsNew );
2864cdf0e10cSrcweir 			InvalidateStatusCell(m_nCurrentPos);
2865cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE1("modified flag changed, new state : %s", ROWSTATUS(m_xCurrentRow));
2866cdf0e10cSrcweir 		}
2867cdf0e10cSrcweir 	}
2868cdf0e10cSrcweir }
2869cdf0e10cSrcweir 
2870cdf0e10cSrcweir //------------------------------------------------------------------------------
StartDrag(sal_Int8,const Point & rPosPixel)2871cdf0e10cSrcweir void DbGridControl::StartDrag( sal_Int8 /*nAction*/, const Point& rPosPixel )
2872cdf0e10cSrcweir {
2873cdf0e10cSrcweir 	if (!m_pSeekCursor || IsResizing())
2874cdf0e10cSrcweir 		return;
2875cdf0e10cSrcweir 
2876cdf0e10cSrcweir 	sal_uInt16 nColId = GetColumnAtXPosPixel(rPosPixel.X());
2877cdf0e10cSrcweir 	long   nRow = GetRowAtYPosPixel(rPosPixel.Y());
2878cdf0e10cSrcweir 	if (nColId != HANDLE_ID && nRow >= 0)
2879cdf0e10cSrcweir 	{
2880cdf0e10cSrcweir 		if (GetDataWindow().IsMouseCaptured())
2881cdf0e10cSrcweir 			GetDataWindow().ReleaseMouse();
2882cdf0e10cSrcweir 
2883cdf0e10cSrcweir 		DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColId));
2884cdf0e10cSrcweir 		OStringTransferable* pTransferable = new OStringTransferable(GetCurrentRowCellText(pColumn,m_xPaintRow));
2885cdf0e10cSrcweir 		Reference< XTransferable > xEnsureDelete(pTransferable);
2886cdf0e10cSrcweir 		pTransferable->StartDrag(this, DND_ACTION_COPY);
2887cdf0e10cSrcweir 	}
2888cdf0e10cSrcweir }
2889cdf0e10cSrcweir 
2890cdf0e10cSrcweir //------------------------------------------------------------------------------
canCopyCellText(sal_Int32 _nRow,sal_Int16 _nColId)2891cdf0e10cSrcweir sal_Bool DbGridControl::canCopyCellText(sal_Int32 _nRow, sal_Int16 _nColId)
2892cdf0e10cSrcweir {
2893cdf0e10cSrcweir 	return	(_nRow >= 0)
2894cdf0e10cSrcweir 		&&	(_nRow < GetRowCount())
2895cdf0e10cSrcweir 		&&	(_nColId > HANDLE_ID)
2896cdf0e10cSrcweir 		&&	(_nColId <= ColCount());
2897cdf0e10cSrcweir }
2898cdf0e10cSrcweir 
2899cdf0e10cSrcweir //------------------------------------------------------------------------------
copyCellText(sal_Int32 _nRow,sal_Int16 _nColId)2900cdf0e10cSrcweir void DbGridControl::copyCellText(sal_Int32 _nRow, sal_Int16 _nColId)
2901cdf0e10cSrcweir {
2902cdf0e10cSrcweir 	DBG_ASSERT(canCopyCellText(_nRow, _nColId), "DbGridControl::copyCellText: invalid call!");
2903cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(_nColId));
2904cdf0e10cSrcweir 	SeekRow(_nRow);
2905cdf0e10cSrcweir 	OStringTransfer::CopyString( GetCurrentRowCellText( pColumn,m_xPaintRow ), this );
2906cdf0e10cSrcweir }
2907cdf0e10cSrcweir 
2908cdf0e10cSrcweir //------------------------------------------------------------------------------
executeRowContextMenu(long _nRow,const Point & _rPreferredPos)2909cdf0e10cSrcweir void DbGridControl::executeRowContextMenu( long _nRow, const Point& _rPreferredPos )
2910cdf0e10cSrcweir {
2911cdf0e10cSrcweir 	PopupMenu aContextMenu( SVX_RES( RID_SVXMNU_ROWS ) );
2912cdf0e10cSrcweir 
2913cdf0e10cSrcweir 	PreExecuteRowContextMenu( (sal_uInt16)_nRow, aContextMenu );
2914cdf0e10cSrcweir 	aContextMenu.RemoveDisabledEntries( sal_True, sal_True );
2915cdf0e10cSrcweir 	PostExecuteRowContextMenu( (sal_uInt16)_nRow, aContextMenu, aContextMenu.Execute( this, _rPreferredPos ) );
2916cdf0e10cSrcweir 
2917cdf0e10cSrcweir 	// TODO: why this weird cast to sal_uInt16? What if we really have more than 65535 lines?
2918cdf0e10cSrcweir 	// -> change this to sal_uInt32
2919cdf0e10cSrcweir }
2920cdf0e10cSrcweir 
2921cdf0e10cSrcweir //------------------------------------------------------------------------------
Command(const CommandEvent & rEvt)2922cdf0e10cSrcweir void DbGridControl::Command(const CommandEvent& rEvt)
2923cdf0e10cSrcweir {
2924cdf0e10cSrcweir 	switch (rEvt.GetCommand())
2925cdf0e10cSrcweir 	{
2926cdf0e10cSrcweir 		case COMMAND_CONTEXTMENU:
2927cdf0e10cSrcweir 		{
2928cdf0e10cSrcweir 			if ( !m_pSeekCursor )
2929cdf0e10cSrcweir 			{
2930cdf0e10cSrcweir 				DbGridControl_Base::Command(rEvt);
2931cdf0e10cSrcweir 				return;
2932cdf0e10cSrcweir 			}
2933cdf0e10cSrcweir 
2934cdf0e10cSrcweir 			if ( !rEvt.IsMouseEvent() )
2935cdf0e10cSrcweir 			{	// context menu requested by keyboard
2936cdf0e10cSrcweir 				if ( GetSelectRowCount() )
2937cdf0e10cSrcweir 				{
2938cdf0e10cSrcweir 					long nRow = FirstSelectedRow( );
2939cdf0e10cSrcweir 
2940cdf0e10cSrcweir 					::Rectangle aRowRect( GetRowRectPixel( nRow, sal_True ) );
2941cdf0e10cSrcweir 					executeRowContextMenu( nRow, aRowRect.LeftCenter() );
2942cdf0e10cSrcweir 
2943cdf0e10cSrcweir 					// handled
2944cdf0e10cSrcweir 					return;
2945cdf0e10cSrcweir 				}
2946cdf0e10cSrcweir 			}
2947cdf0e10cSrcweir 
2948cdf0e10cSrcweir 			sal_uInt16 nColId = GetColumnAtXPosPixel(rEvt.GetMousePosPixel().X());
2949cdf0e10cSrcweir 			long   nRow = GetRowAtYPosPixel(rEvt.GetMousePosPixel().Y());
2950cdf0e10cSrcweir 
2951cdf0e10cSrcweir 			if (nColId == HANDLE_ID)
2952cdf0e10cSrcweir 			{
2953cdf0e10cSrcweir 				executeRowContextMenu( nRow, rEvt.GetMousePosPixel() );
2954cdf0e10cSrcweir 			}
2955cdf0e10cSrcweir 			else if (canCopyCellText(nRow, nColId))
2956cdf0e10cSrcweir 			{
2957cdf0e10cSrcweir 				PopupMenu aContextMenu(SVX_RES(RID_SVXMNU_CELL));
2958cdf0e10cSrcweir 				aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
2959cdf0e10cSrcweir 				switch (aContextMenu.Execute(this, rEvt.GetMousePosPixel()))
2960cdf0e10cSrcweir 				{
2961cdf0e10cSrcweir 					case SID_COPY:
2962cdf0e10cSrcweir 						copyCellText(nRow, nColId);
2963cdf0e10cSrcweir 						break;
2964cdf0e10cSrcweir 				}
2965cdf0e10cSrcweir 			}
2966cdf0e10cSrcweir 			else
2967cdf0e10cSrcweir 			{
2968cdf0e10cSrcweir 				DbGridControl_Base::Command(rEvt);
2969cdf0e10cSrcweir 				return;
2970cdf0e10cSrcweir 			}
2971cdf0e10cSrcweir 		}
2972cdf0e10cSrcweir 		default:
2973cdf0e10cSrcweir 			DbGridControl_Base::Command(rEvt);
2974cdf0e10cSrcweir 	}
2975cdf0e10cSrcweir }
2976cdf0e10cSrcweir 
2977cdf0e10cSrcweir //------------------------------------------------------------------------------
2978cdf0e10cSrcweir IMPL_LINK(DbGridControl, OnDelete, void*, /*EMPTYTAG*/ )
2979cdf0e10cSrcweir {
2980cdf0e10cSrcweir 	DBG_CHKTHIS(DbGridControl, NULL );
2981cdf0e10cSrcweir 	m_nDeleteEvent = 0;
2982cdf0e10cSrcweir 	DeleteSelectedRows();
2983cdf0e10cSrcweir 	return 0;
2984cdf0e10cSrcweir }
2985cdf0e10cSrcweir 
2986cdf0e10cSrcweir //------------------------------------------------------------------------------
DeleteSelectedRows()2987cdf0e10cSrcweir void DbGridControl::DeleteSelectedRows()
2988cdf0e10cSrcweir {
2989cdf0e10cSrcweir 	DBG_ASSERT(GetSelection(), "keine selection!!!");
2990cdf0e10cSrcweir 
2991cdf0e10cSrcweir 	if (!m_pSeekCursor)
2992cdf0e10cSrcweir 		return;
2993cdf0e10cSrcweir 
2994cdf0e10cSrcweir /*	Application::EnterWait();
2995cdf0e10cSrcweir 	Reference< XPropertySet >  xSet = (XPropertySet*)xSeekCursor->queryInterface(XPropertySet::getSmartUik());
2996cdf0e10cSrcweir 
2997cdf0e10cSrcweir 	// wenn mehr als 25 Datensaetze geloescht werden, wird der Cache abgeschaltet
2998cdf0e10cSrcweir 	// da das loeschen ansonsten zu langsam wird
2999cdf0e10cSrcweir 	sal_uInt16 nCacheSize = 0;
3000cdf0e10cSrcweir 	if (GetSelectRowCount() > 25)
3001cdf0e10cSrcweir 	{
3002cdf0e10cSrcweir 		// CacheSize merken und Cache zuruecksetzen
3003cdf0e10cSrcweir 		nCacheSize = xSet->getPropertyValue(L"CacheSize").getUINT16();
3004cdf0e10cSrcweir 		if (nCacheSize)
3005cdf0e10cSrcweir 			xSet->setPropertyValue(L"CacheSize", Any(sal_uInt16(0)));
3006cdf0e10cSrcweir 	} */
3007cdf0e10cSrcweir 
3008cdf0e10cSrcweir 
3009cdf0e10cSrcweir 	/*
3010cdf0e10cSrcweir 	// mu� der Cache wiederhergestellt werden?
3011cdf0e10cSrcweir 	if (nCacheSize)
3012cdf0e10cSrcweir 	{
3013cdf0e10cSrcweir 		// Cache wieder einschalten
3014cdf0e10cSrcweir 		xSet->setPropertyValue(L"CacheSize", Any(sal_uInt16(nCacheSize)));
3015cdf0e10cSrcweir 
3016cdf0e10cSrcweir 		// Browser neu einstellen
3017cdf0e10cSrcweir 		RecalcRows(GetTopRow(), GetVisibleRows(), sal_True);
3018cdf0e10cSrcweir 
3019cdf0e10cSrcweir 		// aktuelle Zeile aktualisieren
3020cdf0e10cSrcweir 		SeekCursor(GetCurRow());
3021cdf0e10cSrcweir 		if (IsAppendRow(m_nSeekPos))
3022cdf0e10cSrcweir 			xDataCursor->addRecord();
3023cdf0e10cSrcweir 		else
3024cdf0e10cSrcweir 		{
3025cdf0e10cSrcweir 			Any aBookmark = xSeekCursor->getBookmark();
3026cdf0e10cSrcweir 			xDataCursor->moveToBookmark(aBookmark);
3027cdf0e10cSrcweir 		}
3028cdf0e10cSrcweir 		m_xCurrentRow = new DbGridRow(xDataCursor);
3029cdf0e10cSrcweir 		m_nCurrentPos = m_nSeekPos;
3030cdf0e10cSrcweir 
3031cdf0e10cSrcweir 		// complett invalidieren
3032cdf0e10cSrcweir 		Invalidate();
3033cdf0e10cSrcweir 	}
3034cdf0e10cSrcweir 	else
3035cdf0e10cSrcweir 		// Browser neu einstellen
3036cdf0e10cSrcweir 		RecalcRows(GetTopRow(), GetVisibleRows(), sal_True);
3037cdf0e10cSrcweir 
3038cdf0e10cSrcweir 	// gibt es keine Selection mehr?
3039cdf0e10cSrcweir 	if (!GetSelectRowCount())
3040cdf0e10cSrcweir 		ActivateCell();
3041cdf0e10cSrcweir 
3042cdf0e10cSrcweir 	m_aBar.InvalidateAll();
3043cdf0e10cSrcweir 	Application::LeaveWait();
3044cdf0e10cSrcweir 
3045cdf0e10cSrcweir 	m_bUpdating = sal_False;
3046cdf0e10cSrcweir */
3047cdf0e10cSrcweir }
3048cdf0e10cSrcweir 
3049cdf0e10cSrcweir //------------------------------------------------------------------------------
GetController(long,sal_uInt16 nColumnId)3050cdf0e10cSrcweir CellController* DbGridControl::GetController(long /*nRow*/, sal_uInt16 nColumnId)
3051cdf0e10cSrcweir {
3052cdf0e10cSrcweir 	if (!IsValid(m_xCurrentRow) || !IsEnabled())
3053cdf0e10cSrcweir 		return NULL;
3054cdf0e10cSrcweir 
3055cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColumnId));
3056cdf0e10cSrcweir 	if (!pColumn)
3057cdf0e10cSrcweir 		return NULL;
3058cdf0e10cSrcweir 
3059cdf0e10cSrcweir 	CellController* pReturn = NULL;
3060cdf0e10cSrcweir 	if (IsFilterMode())
3061cdf0e10cSrcweir 		pReturn = &pColumn->GetController();
3062cdf0e10cSrcweir 	else
3063cdf0e10cSrcweir 	{
3064cdf0e10cSrcweir 		if (::comphelper::hasProperty(FM_PROP_ENABLED, pColumn->getModel()))
3065cdf0e10cSrcweir 		{
3066cdf0e10cSrcweir 			if (!::comphelper::getBOOL(pColumn->getModel()->getPropertyValue(FM_PROP_ENABLED)))
3067cdf0e10cSrcweir 				return NULL;
3068cdf0e10cSrcweir 		}
3069cdf0e10cSrcweir 
3070cdf0e10cSrcweir 		sal_Bool bInsert = (m_xCurrentRow->IsNew() && (m_nOptions & OPT_INSERT));
3071cdf0e10cSrcweir 		sal_Bool bUpdate = (!m_xCurrentRow->IsNew() && (m_nOptions & OPT_UPDATE));
3072cdf0e10cSrcweir 
3073cdf0e10cSrcweir 		if ((bInsert && !pColumn->IsAutoValue()) || bUpdate || m_bForceROController)
3074cdf0e10cSrcweir 		{
3075cdf0e10cSrcweir 			pReturn = &pColumn->GetController();
3076cdf0e10cSrcweir 			if (pReturn)
3077cdf0e10cSrcweir 			{
3078cdf0e10cSrcweir 				// wenn es eine Edit-Zeile ist, kann ich ihr das forced read-only mitgeben
3079cdf0e10cSrcweir 				if (!pReturn->ISA(EditCellController) && !pReturn->ISA(SpinCellController))
3080cdf0e10cSrcweir 					// ich konnte den Controller in forceROController nicht auf ReadOnly setzen
3081cdf0e10cSrcweir 					if (!bInsert && !bUpdate)
3082cdf0e10cSrcweir 						// ich bin nur hier, da m_bForceROController gesetzt war
3083cdf0e10cSrcweir 						// -> lieber kein Controller als einer ohne RO
3084cdf0e10cSrcweir 						pReturn = NULL;
3085cdf0e10cSrcweir 			}
3086cdf0e10cSrcweir 		}
3087cdf0e10cSrcweir 	}
3088cdf0e10cSrcweir 	return pReturn;
3089cdf0e10cSrcweir }
3090cdf0e10cSrcweir 
3091cdf0e10cSrcweir //------------------------------------------------------------------------------
InitController(CellControllerRef &,long,sal_uInt16 nColumnId)3092cdf0e10cSrcweir void DbGridControl::InitController(CellControllerRef& /*rController*/, long /*nRow*/, sal_uInt16 nColumnId)
3093cdf0e10cSrcweir {
3094cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColumnId));
3095cdf0e10cSrcweir 	if (pColumn)
3096cdf0e10cSrcweir 		pColumn->UpdateFromField(m_xCurrentRow, m_xFormatter);
3097cdf0e10cSrcweir }
3098cdf0e10cSrcweir 
3099cdf0e10cSrcweir //------------------------------------------------------------------------------
CellModified()3100cdf0e10cSrcweir void DbGridControl::CellModified()
3101cdf0e10cSrcweir {
3102cdf0e10cSrcweir 	TRACE_RANGE("DbGridControl::CellModified");
3103cdf0e10cSrcweir 
3104cdf0e10cSrcweir 	{
3105cdf0e10cSrcweir 		::osl::MutexGuard aGuard(m_aAdjustSafety);
3106cdf0e10cSrcweir 		if (m_nAsynAdjustEvent)
3107cdf0e10cSrcweir 		{
3108cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE1("forcing a synchron call to ", m_bPendingAdjustRows ? "AdjustRows" : "AdustDataSource");
3109cdf0e10cSrcweir 			RemoveUserEvent(m_nAsynAdjustEvent);
3110cdf0e10cSrcweir 			m_nAsynAdjustEvent = 0;
3111cdf0e10cSrcweir 
3112cdf0e10cSrcweir 			// force the call : this should be no problem as we're probably running in the solar thread here
3113cdf0e10cSrcweir 			// (cell modified is triggered by user actions)
3114cdf0e10cSrcweir 			if (m_bPendingAdjustRows)
3115cdf0e10cSrcweir 				AdjustRows();
3116cdf0e10cSrcweir 			else
3117cdf0e10cSrcweir 				AdjustDataSource();
3118cdf0e10cSrcweir 		}
3119cdf0e10cSrcweir 	}
3120cdf0e10cSrcweir 
3121cdf0e10cSrcweir 	if (!IsFilterMode() && IsValid(m_xCurrentRow) && !m_xCurrentRow->IsModified())
3122cdf0e10cSrcweir 	{
3123cdf0e10cSrcweir 		// Einschalten des Editiermodus
3124cdf0e10cSrcweir 		// Datensatz soll eingefuegt werden
3125cdf0e10cSrcweir 		if (m_xCurrentRow->IsNew())
3126cdf0e10cSrcweir 		{
3127cdf0e10cSrcweir 			m_xCurrentRow->SetStatus(GRS_MODIFIED);
3128cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE("current row is new, new state : MODIFIED");
3129cdf0e10cSrcweir 			// wenn noch keine Zeile hinzugefuegt wurde, dann neue hinzunehmen
3130cdf0e10cSrcweir 			if (m_nCurrentPos == GetRowCount() - 1)
3131cdf0e10cSrcweir 			{
3132cdf0e10cSrcweir 				// RowCount um einen erhoehen
3133cdf0e10cSrcweir 				RowInserted(GetRowCount(), 1, sal_True);
3134cdf0e10cSrcweir 				InvalidateStatusCell(m_nCurrentPos);
3135cdf0e10cSrcweir 				m_aBar.InvalidateAll(m_nCurrentPos);
3136cdf0e10cSrcweir 			}
3137cdf0e10cSrcweir 		}
3138cdf0e10cSrcweir 		else if (m_xCurrentRow->GetStatus() != GRS_MODIFIED)
3139cdf0e10cSrcweir 		{
3140cdf0e10cSrcweir 			m_xCurrentRow->SetState(m_pDataCursor, sal_False);
3141cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE1("current row is not new, after SetState, new state : %s", ROWSTATUS(m_xCurrentRow));
3142cdf0e10cSrcweir 			m_xCurrentRow->SetStatus(GRS_MODIFIED);
3143cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE("current row is not new, new state : MODIFIED");
3144cdf0e10cSrcweir 			InvalidateStatusCell(m_nCurrentPos);
3145cdf0e10cSrcweir 		}
3146cdf0e10cSrcweir 	}
3147cdf0e10cSrcweir }
3148cdf0e10cSrcweir 
3149cdf0e10cSrcweir //------------------------------------------------------------------------------
Dispatch(sal_uInt16 nId)3150cdf0e10cSrcweir void DbGridControl::Dispatch(sal_uInt16 nId)
3151cdf0e10cSrcweir {
3152cdf0e10cSrcweir 	if (nId == BROWSER_CURSORENDOFFILE)
3153cdf0e10cSrcweir 	{
3154cdf0e10cSrcweir 		if (m_nOptions & OPT_INSERT)
3155cdf0e10cSrcweir 			AppendNew();
3156cdf0e10cSrcweir 		else
3157cdf0e10cSrcweir 			MoveToLast();
3158cdf0e10cSrcweir 	}
3159cdf0e10cSrcweir 	else
3160cdf0e10cSrcweir 		DbGridControl_Base::Dispatch(nId);
3161cdf0e10cSrcweir }
3162cdf0e10cSrcweir 
3163cdf0e10cSrcweir //------------------------------------------------------------------------------
Undo()3164cdf0e10cSrcweir void DbGridControl::Undo()
3165cdf0e10cSrcweir {
3166cdf0e10cSrcweir 	if (!IsFilterMode() && IsValid(m_xCurrentRow) && IsModified())
3167cdf0e10cSrcweir 	{
3168cdf0e10cSrcweir 		// check if we have somebody doin' the UNDO for us
3169cdf0e10cSrcweir 		long nState = -1;
3170cdf0e10cSrcweir 		if (m_aMasterStateProvider.IsSet())
3171cdf0e10cSrcweir 			nState = m_aMasterStateProvider.Call((void*)SID_FM_RECORD_UNDO);
3172cdf0e10cSrcweir 		if (nState>0)
3173cdf0e10cSrcweir 		{	// yes, we have, and the slot is enabled
3174cdf0e10cSrcweir 			DBG_ASSERT(m_aMasterSlotExecutor.IsSet(), "DbGridControl::Undo : a state, but no execute link ?");
3175cdf0e10cSrcweir 			long lResult = m_aMasterSlotExecutor.Call((void*)SID_FM_RECORD_UNDO);
3176cdf0e10cSrcweir 			if (lResult)
3177cdf0e10cSrcweir 				// handled
3178cdf0e10cSrcweir 				return;
3179cdf0e10cSrcweir 		}
3180cdf0e10cSrcweir 		else if (nState == 0)
3181cdf0e10cSrcweir 			// yes, we have, and the slot is disabled
3182cdf0e10cSrcweir 			return;
3183cdf0e10cSrcweir 
3184cdf0e10cSrcweir 		BeginCursorAction();
3185cdf0e10cSrcweir 
3186cdf0e10cSrcweir 		sal_Bool bAppending = m_xCurrentRow->IsNew();
3187cdf0e10cSrcweir 		sal_Bool bDirty 	= m_xCurrentRow->IsModified();
3188cdf0e10cSrcweir 
3189cdf0e10cSrcweir 		try
3190cdf0e10cSrcweir 		{
3191cdf0e10cSrcweir 			// Editieren abbrechen
3192cdf0e10cSrcweir 			Reference< XResultSetUpdate >  xUpdateCursor((Reference< XInterface >)*m_pDataCursor, UNO_QUERY);
3193cdf0e10cSrcweir 			// no effects if we're not updating currently
3194cdf0e10cSrcweir 			if (bAppending)
3195cdf0e10cSrcweir 				// just refresh the row
3196cdf0e10cSrcweir 				xUpdateCursor->moveToInsertRow();
3197cdf0e10cSrcweir 			else
3198cdf0e10cSrcweir 				xUpdateCursor->cancelRowUpdates();
3199cdf0e10cSrcweir 
3200cdf0e10cSrcweir 		}
3201cdf0e10cSrcweir 		catch(Exception&)
3202cdf0e10cSrcweir 		{
3203cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
3204cdf0e10cSrcweir 		}
3205cdf0e10cSrcweir 
3206cdf0e10cSrcweir 		EndCursorAction();
3207cdf0e10cSrcweir 
3208cdf0e10cSrcweir 		m_xDataRow->SetState(m_pDataCursor, sal_False);
3209cdf0e10cSrcweir 		if (&m_xPaintRow == &m_xCurrentRow)
3210cdf0e10cSrcweir 			m_xPaintRow = m_xCurrentRow = m_xDataRow;
3211cdf0e10cSrcweir 		else
3212cdf0e10cSrcweir 			m_xCurrentRow = m_xDataRow;
3213cdf0e10cSrcweir 
3214cdf0e10cSrcweir 		if (bAppending && (DbGridControl_Base::IsModified() || bDirty))
3215cdf0e10cSrcweir 		// remove the row
3216cdf0e10cSrcweir 			if (m_nCurrentPos == GetRowCount() - 2)
3217cdf0e10cSrcweir 			{	// maybe we already removed it (in resetCurrentRow, called if the above moveToInsertRow
3218cdf0e10cSrcweir 				// caused our data source form to be reset - which should be the usual case ....)
3219cdf0e10cSrcweir 				RowRemoved(GetRowCount() - 1, 1, sal_True);
3220cdf0e10cSrcweir 				m_aBar.InvalidateAll(m_nCurrentPos);
3221cdf0e10cSrcweir 			}
3222cdf0e10cSrcweir 
3223cdf0e10cSrcweir 		RowModified(m_nCurrentPos);
3224cdf0e10cSrcweir 	}
3225cdf0e10cSrcweir }
3226cdf0e10cSrcweir 
3227cdf0e10cSrcweir //------------------------------------------------------------------------------
resetCurrentRow()3228cdf0e10cSrcweir void DbGridControl::resetCurrentRow()
3229cdf0e10cSrcweir {
3230cdf0e10cSrcweir 	if (IsModified())
3231cdf0e10cSrcweir 	{
3232cdf0e10cSrcweir 		// scenario : we're on the insert row, the row is dirty, and thus there exists a "second" insert row (which
3233cdf0e10cSrcweir 		// is clean). Normally in DataSourcePropertyChanged we would remove this second row if the modified state of
3234cdf0e10cSrcweir 		// the insert row changes from sal_True to sal_False. But if our current cell is the only modified element (means the
3235cdf0e10cSrcweir 		// data source isn't modified) and we're reset this DataSourcePropertyChanged would never be called, so we
3236cdf0e10cSrcweir 		// would never delete the obsolet "second insert row". Thus in this special case this method here
3237cdf0e10cSrcweir 		// is the only possibility to determine the redundance of the row (resetCurrentRow is called when the
3238cdf0e10cSrcweir 		// "first insert row" is about to be cleaned, so of course the "second insert row" is redundant now)
3239cdf0e10cSrcweir 		Reference< XPropertySet > xDataSource = getDataSource()->getPropertySet();
3240cdf0e10cSrcweir 		if (xDataSource.is() && !::comphelper::getBOOL(xDataSource->getPropertyValue(FM_PROP_ISMODIFIED)))
3241cdf0e10cSrcweir 		{
3242cdf0e10cSrcweir 			// are we on a new row currently ?
3243cdf0e10cSrcweir 			if (m_xCurrentRow->IsNew())
3244cdf0e10cSrcweir 			{
3245cdf0e10cSrcweir 				if (m_nCurrentPos == GetRowCount() - 2)
3246cdf0e10cSrcweir 				{
3247cdf0e10cSrcweir 					RowRemoved(GetRowCount() - 1, 1, sal_True);
3248cdf0e10cSrcweir 					m_aBar.InvalidateAll(m_nCurrentPos);
3249cdf0e10cSrcweir 				}
3250cdf0e10cSrcweir 			}
3251cdf0e10cSrcweir 		}
3252cdf0e10cSrcweir 
3253cdf0e10cSrcweir 		// update the rows
3254cdf0e10cSrcweir 		m_xDataRow->SetState(m_pDataCursor, sal_False);
3255cdf0e10cSrcweir 		if (&m_xPaintRow == &m_xCurrentRow)
3256cdf0e10cSrcweir 			m_xPaintRow = m_xCurrentRow = m_xDataRow;
3257cdf0e10cSrcweir 		else
3258cdf0e10cSrcweir 			m_xCurrentRow = m_xDataRow;
3259cdf0e10cSrcweir 	}
3260cdf0e10cSrcweir 
3261cdf0e10cSrcweir 	RowModified(GetCurRow());		// will update the current controller if affected
3262cdf0e10cSrcweir }
3263cdf0e10cSrcweir 
3264cdf0e10cSrcweir //------------------------------------------------------------------------------
RowModified(long nRow,sal_uInt16)3265cdf0e10cSrcweir void DbGridControl::RowModified( long nRow, sal_uInt16 /*nColId*/ )
3266cdf0e10cSrcweir {
3267cdf0e10cSrcweir 	if (nRow == m_nCurrentPos && IsEditing())
3268cdf0e10cSrcweir 	{
3269cdf0e10cSrcweir 		CellControllerRef aTmpRef = Controller();
3270cdf0e10cSrcweir 		aTmpRef->ClearModified();
3271cdf0e10cSrcweir 		InitController(aTmpRef, m_nCurrentPos, GetCurColumnId());
3272cdf0e10cSrcweir 	}
3273cdf0e10cSrcweir 	DbGridControl_Base::RowModified(nRow);
3274cdf0e10cSrcweir }
3275cdf0e10cSrcweir 
3276cdf0e10cSrcweir //------------------------------------------------------------------------------
IsModified() const3277cdf0e10cSrcweir sal_Bool DbGridControl::IsModified() const
3278cdf0e10cSrcweir {
3279cdf0e10cSrcweir 	return !IsFilterMode() && IsValid(m_xCurrentRow) && (m_xCurrentRow->IsModified() || DbGridControl_Base::IsModified());
3280cdf0e10cSrcweir }
3281cdf0e10cSrcweir 
3282cdf0e10cSrcweir //------------------------------------------------------------------------------
IsCurrentAppending() const3283cdf0e10cSrcweir sal_Bool DbGridControl::IsCurrentAppending() const
3284cdf0e10cSrcweir {
3285cdf0e10cSrcweir 	return m_xCurrentRow.Is() && m_xCurrentRow->IsNew();
3286cdf0e10cSrcweir }
3287cdf0e10cSrcweir 
3288cdf0e10cSrcweir //------------------------------------------------------------------------------
IsInsertionRow(long nRow) const3289cdf0e10cSrcweir sal_Bool DbGridControl::IsInsertionRow(long nRow) const
3290cdf0e10cSrcweir {
3291cdf0e10cSrcweir 	return (m_nOptions & OPT_INSERT) && m_nTotalCount >= 0 && (nRow == GetRowCount() - 1);
3292cdf0e10cSrcweir }
3293cdf0e10cSrcweir 
3294cdf0e10cSrcweir //------------------------------------------------------------------------------
SaveModified()3295cdf0e10cSrcweir sal_Bool DbGridControl::SaveModified()
3296cdf0e10cSrcweir {
3297cdf0e10cSrcweir 	TRACE_RANGE("DbGridControl::SaveModified");
3298cdf0e10cSrcweir 	DBG_ASSERT(IsValid(m_xCurrentRow), "GridControl:: Invalid row");
3299cdf0e10cSrcweir 	if (!IsValid(m_xCurrentRow))
3300cdf0e10cSrcweir 		return sal_True;
3301cdf0e10cSrcweir 
3302cdf0e10cSrcweir 	// Uebernimmt die Dateneingabe fuer das Feld
3303cdf0e10cSrcweir 	// Hat es aenderungen im aktuellen Eingabefeld gegeben ?
3304cdf0e10cSrcweir 	if (!DbGridControl_Base::IsModified())
3305cdf0e10cSrcweir 		return sal_True;
3306cdf0e10cSrcweir 
3307cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(GetCurColumnId()));
3308cdf0e10cSrcweir 	sal_Bool bOK = pColumn->Commit();
3309cdf0e10cSrcweir 	DBG_ASSERT( Controller().Is(), "DbGridControl::SaveModified: was modified, by have no controller?!" );
3310cdf0e10cSrcweir     if ( !Controller().Is() )
3311cdf0e10cSrcweir         // this might happen if the callbacks implicitly triggered by Commit
3312cdf0e10cSrcweir         // fiddled with the form or the control ...
3313cdf0e10cSrcweir         // (Note that this here is a workaround, at most. We need a general concept how
3314cdf0e10cSrcweir         // to treat this, you can imagine an arbitrary number of scenarios where a callback
3315cdf0e10cSrcweir         // triggers something which leaves us in an expected state.)
3316cdf0e10cSrcweir         // #i67147# / 2006-07-17 / frank.schoenheit@sun.com
3317cdf0e10cSrcweir         return bOK;
3318cdf0e10cSrcweir 
3319cdf0e10cSrcweir 	if (bOK)
3320cdf0e10cSrcweir 	{
3321cdf0e10cSrcweir 		Controller()->ClearModified();
3322cdf0e10cSrcweir 
3323cdf0e10cSrcweir 		if ( IsValid(m_xCurrentRow) )
3324cdf0e10cSrcweir 		{
3325cdf0e10cSrcweir 			m_xCurrentRow->SetState(m_pDataCursor, sal_False);
3326cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE1("explicit SetState, new state : %s", ROWSTATUS(m_xCurrentRow));
3327cdf0e10cSrcweir 			InvalidateStatusCell( m_nCurrentPos );
3328cdf0e10cSrcweir 		}
3329cdf0e10cSrcweir #ifdef DBG_UTIL
3330cdf0e10cSrcweir 		else
3331cdf0e10cSrcweir 		{
3332cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE1("no SetState, new state : %s", ROWSTATUS(m_xCurrentRow));
3333cdf0e10cSrcweir 		}
3334cdf0e10cSrcweir #endif
3335cdf0e10cSrcweir 	}
3336cdf0e10cSrcweir 	else
3337cdf0e10cSrcweir 	{
3338cdf0e10cSrcweir 		// reset the modified flag ....
3339cdf0e10cSrcweir 		Controller()->SetModified();
3340cdf0e10cSrcweir 	}
3341cdf0e10cSrcweir 
3342cdf0e10cSrcweir 	return bOK;
3343cdf0e10cSrcweir }
3344cdf0e10cSrcweir 
3345cdf0e10cSrcweir //------------------------------------------------------------------------------
SaveRow()3346cdf0e10cSrcweir sal_Bool DbGridControl::SaveRow()
3347cdf0e10cSrcweir {
3348cdf0e10cSrcweir 	TRACE_RANGE("DbGridControl::SaveRow");
3349cdf0e10cSrcweir 	// gueltige Zeile
3350cdf0e10cSrcweir 	if (!IsValid(m_xCurrentRow) || !IsModified())
3351cdf0e10cSrcweir 		return sal_True;
3352cdf0e10cSrcweir 	// Wert des Controllers noch nicht gespeichert
3353cdf0e10cSrcweir 	else if (Controller().Is() && Controller()->IsModified())
3354cdf0e10cSrcweir 	{
3355cdf0e10cSrcweir 		if (!SaveModified())
3356cdf0e10cSrcweir 			return sal_False;
3357cdf0e10cSrcweir 	}
3358cdf0e10cSrcweir 	m_bUpdating = sal_True;
3359cdf0e10cSrcweir 
3360cdf0e10cSrcweir 	BeginCursorAction();
3361cdf0e10cSrcweir 	sal_Bool bAppending = m_xCurrentRow->IsNew();
3362cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
3363cdf0e10cSrcweir 	try
3364cdf0e10cSrcweir 	{
3365cdf0e10cSrcweir 		Reference< XResultSetUpdate >  xUpdateCursor((Reference< XInterface >)*m_pDataCursor, UNO_QUERY);
3366cdf0e10cSrcweir 		if (bAppending)
3367cdf0e10cSrcweir 			xUpdateCursor->insertRow();
3368cdf0e10cSrcweir 		else
3369cdf0e10cSrcweir 			xUpdateCursor->updateRow();
3370cdf0e10cSrcweir 		bSuccess = sal_True;
3371cdf0e10cSrcweir 	}
3372cdf0e10cSrcweir 	catch(SQLException& e)
3373cdf0e10cSrcweir 	{
3374cdf0e10cSrcweir 		(void)e; // make compiler happy
3375cdf0e10cSrcweir 		EndCursorAction();
3376cdf0e10cSrcweir 		m_bUpdating = sal_False;
3377cdf0e10cSrcweir 		return sal_False;
3378cdf0e10cSrcweir 	}
3379cdf0e10cSrcweir 
3380cdf0e10cSrcweir 	try
3381cdf0e10cSrcweir 	{
3382cdf0e10cSrcweir 		if (bSuccess)
3383cdf0e10cSrcweir 		{
3384cdf0e10cSrcweir 			// if we are appending we still sit on the insert row
3385cdf0e10cSrcweir 			// we don't move just clear the flags not to move on the current row
3386cdf0e10cSrcweir 			m_xCurrentRow->SetState(m_pDataCursor, sal_False);
3387cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE1("explicit SetState after a successfull update, new state : %s", ROWSTATUS(m_xCurrentRow));
3388cdf0e10cSrcweir 			m_xCurrentRow->SetNew(sal_False);
3389cdf0e10cSrcweir 
3390cdf0e10cSrcweir 			// adjust the seekcursor if it is on the same position as the datacursor
3391cdf0e10cSrcweir 			if (m_nSeekPos == m_nCurrentPos || bAppending)
3392cdf0e10cSrcweir 			{
3393cdf0e10cSrcweir 				// get the bookmark to refetch the data
3394cdf0e10cSrcweir 				// in insert mode we take the new bookmark of the data cursor
3395cdf0e10cSrcweir 				Any aBookmark = bAppending ? m_pDataCursor->getBookmark() : m_pSeekCursor->getBookmark();
3396cdf0e10cSrcweir 				m_pSeekCursor->moveToBookmark(aBookmark);
3397cdf0e10cSrcweir 				// get the data
3398cdf0e10cSrcweir 				m_xSeekRow->SetState(m_pSeekCursor, sal_True);
3399cdf0e10cSrcweir 				m_nSeekPos = m_pSeekCursor->getRow() - 1;
3400cdf0e10cSrcweir 			}
3401cdf0e10cSrcweir 		}
3402cdf0e10cSrcweir 		// and repaint the row
3403cdf0e10cSrcweir 		RowModified(m_nCurrentPos);
3404cdf0e10cSrcweir 	}
3405cdf0e10cSrcweir 	catch(Exception&)
3406cdf0e10cSrcweir 	{
3407cdf0e10cSrcweir 	}
3408cdf0e10cSrcweir 
3409cdf0e10cSrcweir 	m_bUpdating = sal_False;
3410cdf0e10cSrcweir 	EndCursorAction();
3411cdf0e10cSrcweir 
3412cdf0e10cSrcweir 	// The old code returned (nRecords != 0) here.
3413cdf0e10cSrcweir 	// Me thinks this is wrong : If something goes wrong while update the record, an exception will be thrown,
3414cdf0e10cSrcweir 	// which results in a "return sal_False" (see above). If no exception is thrown, everything is fine. If nRecords
3415cdf0e10cSrcweir 	// is zero, this simply means all fields had their original values.
3416cdf0e10cSrcweir 	// FS - 06.12.99 - 70502
3417cdf0e10cSrcweir 	return sal_True;
3418cdf0e10cSrcweir }
3419cdf0e10cSrcweir 
3420cdf0e10cSrcweir //------------------------------------------------------------------------------
PreNotify(NotifyEvent & rEvt)3421cdf0e10cSrcweir long DbGridControl::PreNotify(NotifyEvent& rEvt)
3422cdf0e10cSrcweir {
3423cdf0e10cSrcweir 	// keine Events der Navbar behandeln
3424cdf0e10cSrcweir 	if (m_aBar.IsWindowOrChild(rEvt.GetWindow()))
3425cdf0e10cSrcweir 		return BrowseBox::PreNotify(rEvt);
3426cdf0e10cSrcweir 
3427cdf0e10cSrcweir 	switch (rEvt.GetType())
3428cdf0e10cSrcweir 	{
3429cdf0e10cSrcweir 		case EVENT_KEYINPUT:
3430cdf0e10cSrcweir 		{
3431cdf0e10cSrcweir 			const KeyEvent* pKeyEvent = rEvt.GetKeyEvent();
3432cdf0e10cSrcweir 
3433cdf0e10cSrcweir 			sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode();
3434cdf0e10cSrcweir 			sal_Bool   bShift = pKeyEvent->GetKeyCode().IsShift();
3435cdf0e10cSrcweir 			sal_Bool   bCtrl = pKeyEvent->GetKeyCode().IsMod1();
3436cdf0e10cSrcweir 			sal_Bool   bAlt = pKeyEvent->GetKeyCode().IsMod2();
3437cdf0e10cSrcweir 			if ( ( KEY_TAB == nCode ) && bCtrl && !bAlt )
3438cdf0e10cSrcweir 			{
3439cdf0e10cSrcweir 				// Ctrl-Tab is used to step out of the control, without traveling to the
3440cdf0e10cSrcweir 				// remaining cells first
3441cdf0e10cSrcweir 				// -> build a new key event without the Ctrl-key, and let the very base class handle it
3442cdf0e10cSrcweir 				KeyCode aNewCode( KEY_TAB, bShift, sal_False, sal_False, sal_False );
3443cdf0e10cSrcweir 				KeyEvent aNewEvent( pKeyEvent->GetCharCode(), aNewCode );
3444cdf0e10cSrcweir 
3445cdf0e10cSrcweir 				// call the Control - our direct base class will interpret this in a way we do not want (and do
3446cdf0e10cSrcweir 				// a cell traveling)
3447cdf0e10cSrcweir 				Control::KeyInput( aNewEvent );
3448cdf0e10cSrcweir 				return 1;
3449cdf0e10cSrcweir 			}
3450cdf0e10cSrcweir 
3451cdf0e10cSrcweir 			if ( !bShift && !bCtrl && ( KEY_ESCAPE == nCode ) )
3452cdf0e10cSrcweir 			{
3453cdf0e10cSrcweir 				if (IsModified())
3454cdf0e10cSrcweir 				{
3455cdf0e10cSrcweir 					Undo();
3456cdf0e10cSrcweir 					return 1;
3457cdf0e10cSrcweir 				}
3458cdf0e10cSrcweir 			}
3459cdf0e10cSrcweir 			else if ( ( KEY_DELETE == nCode ) && !bShift && !bCtrl )	// delete rows
3460cdf0e10cSrcweir 			{
3461cdf0e10cSrcweir 				if ((m_nOptions & OPT_DELETE) && GetSelectRowCount())
3462cdf0e10cSrcweir 				{
3463cdf0e10cSrcweir 					// delete asynchron
3464cdf0e10cSrcweir 					if (m_nDeleteEvent)
3465cdf0e10cSrcweir 						Application::RemoveUserEvent(m_nDeleteEvent);
3466cdf0e10cSrcweir 					m_nDeleteEvent = Application::PostUserEvent(LINK(this,DbGridControl,OnDelete));
3467cdf0e10cSrcweir 					return 1;
3468cdf0e10cSrcweir 				}
3469cdf0e10cSrcweir 			}
3470cdf0e10cSrcweir 		}	// kein break!
3471cdf0e10cSrcweir 		default:
3472cdf0e10cSrcweir 			return DbGridControl_Base::PreNotify(rEvt);
3473cdf0e10cSrcweir 	}
3474cdf0e10cSrcweir }
3475cdf0e10cSrcweir 
3476cdf0e10cSrcweir //------------------------------------------------------------------------------
IsTabAllowed(sal_Bool bRight) const3477cdf0e10cSrcweir sal_Bool DbGridControl::IsTabAllowed(sal_Bool bRight) const
3478cdf0e10cSrcweir {
3479cdf0e10cSrcweir 	if (bRight)
3480cdf0e10cSrcweir 		// Tab nur wenn nicht auf der letzten Zelle
3481cdf0e10cSrcweir 		return GetCurRow() < (GetRowCount() - 1) || !m_bRecordCountFinal ||
3482cdf0e10cSrcweir 			   GetViewColumnPos(GetCurColumnId()) < (GetViewColCount() - 1);
3483cdf0e10cSrcweir 	else
3484cdf0e10cSrcweir 	{
3485cdf0e10cSrcweir 		// Tab nur wenn nicht auf der ersten Zelle
3486cdf0e10cSrcweir 		return GetCurRow() > 0 || (GetCurColumnId() && GetViewColumnPos(GetCurColumnId()) > 0);
3487cdf0e10cSrcweir 	}
3488cdf0e10cSrcweir }
3489cdf0e10cSrcweir 
3490cdf0e10cSrcweir //------------------------------------------------------------------------------
KeyInput(const KeyEvent & rEvt)3491cdf0e10cSrcweir void DbGridControl::KeyInput( const KeyEvent& rEvt )
3492cdf0e10cSrcweir {
3493cdf0e10cSrcweir 	if (rEvt.GetKeyCode().GetFunction() == KEYFUNC_COPY)
3494cdf0e10cSrcweir 	{
3495cdf0e10cSrcweir 		long nRow = GetCurRow();
3496cdf0e10cSrcweir 		sal_uInt16 nColId = GetCurColumnId();
3497cdf0e10cSrcweir 		if (nRow >= 0 && nRow < GetRowCount() && nColId < ColCount())
3498cdf0e10cSrcweir 		{
3499cdf0e10cSrcweir 			DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColId));
3500cdf0e10cSrcweir 			OStringTransfer::CopyString( GetCurrentRowCellText( pColumn,m_xPaintRow ), this );
3501cdf0e10cSrcweir 			return;
3502cdf0e10cSrcweir 		}
3503cdf0e10cSrcweir 	}
3504cdf0e10cSrcweir 	DbGridControl_Base::KeyInput(rEvt);
3505cdf0e10cSrcweir }
3506cdf0e10cSrcweir 
3507cdf0e10cSrcweir //------------------------------------------------------------------------------
HideColumn(sal_uInt16 nId)3508cdf0e10cSrcweir void DbGridControl::HideColumn(sal_uInt16 nId)
3509cdf0e10cSrcweir {
3510cdf0e10cSrcweir 	DeactivateCell();
3511cdf0e10cSrcweir 
3512cdf0e10cSrcweir 	// determine the col for the focus to set to after removal
3513cdf0e10cSrcweir 	sal_uInt16 nPos = GetViewColumnPos(nId);
3514cdf0e10cSrcweir 	sal_uInt16 nNewColId = nPos == (ColCount()-1)
3515cdf0e10cSrcweir 		? GetColumnIdFromViewPos(nPos-1)	// last col is to be removed -> take the previous
3516cdf0e10cSrcweir 		: GetColumnIdFromViewPos(nPos+1);	// take the next
3517cdf0e10cSrcweir 
3518cdf0e10cSrcweir 	long lCurrentWidth = GetColumnWidth(nId);
3519cdf0e10cSrcweir 	DbGridControl_Base::RemoveColumn(nId);
3520cdf0e10cSrcweir 		// don't use my own RemoveColumn, this would remove it from m_aColumns, too
3521cdf0e10cSrcweir 
3522cdf0e10cSrcweir 	// update my model
3523cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nId));
3524cdf0e10cSrcweir 	DBG_ASSERT(pColumn, "DbGridControl::HideColumn : somebody did hide a nonexistent column !");
3525cdf0e10cSrcweir 	if (pColumn)
3526cdf0e10cSrcweir 	{
3527cdf0e10cSrcweir 		pColumn->m_bHidden = sal_True;
3528cdf0e10cSrcweir 		pColumn->m_nLastVisibleWidth = CalcReverseZoom(lCurrentWidth);
3529cdf0e10cSrcweir 	}
3530cdf0e10cSrcweir 
3531cdf0e10cSrcweir 	// and reset the focus
3532cdf0e10cSrcweir 	if ( nId == GetCurColumnId() )
3533cdf0e10cSrcweir 		GoToColumnId( nNewColId );
3534cdf0e10cSrcweir }
3535cdf0e10cSrcweir 
3536cdf0e10cSrcweir //------------------------------------------------------------------------------
ShowColumn(sal_uInt16 nId)3537cdf0e10cSrcweir void DbGridControl::ShowColumn(sal_uInt16 nId)
3538cdf0e10cSrcweir {
3539cdf0e10cSrcweir 	sal_uInt16 nPos = GetModelColumnPos(nId);
3540cdf0e10cSrcweir 	DBG_ASSERT(nPos != (sal_uInt16)-1, "DbGridControl::ShowColumn : invalid argument !");
3541cdf0e10cSrcweir 	if (nPos == (sal_uInt16)-1)
3542cdf0e10cSrcweir 		return;
3543cdf0e10cSrcweir 
3544cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject(nPos);
3545cdf0e10cSrcweir 	if (!pColumn->IsHidden())
3546cdf0e10cSrcweir 	{
3547cdf0e10cSrcweir 		DBG_ASSERT(GetViewColumnPos(nId) != (sal_uInt16)-1, "DbGridControl::ShowColumn : inconsistent internal state !");
3548cdf0e10cSrcweir 			// if the column isn't marked as hidden, it should be visible, shouldn't it ?
3549cdf0e10cSrcweir 		return;
3550cdf0e10cSrcweir 	}
3551cdf0e10cSrcweir 	DBG_ASSERT(GetViewColumnPos(nId) == (sal_uInt16)-1, "DbGridControl::ShowColumn : inconsistent internal state !");
3552cdf0e10cSrcweir 		// the opposite situation ...
3553cdf0e10cSrcweir 
3554cdf0e10cSrcweir 	// to determine the new view position we need an adjacent non-hidden column
3555cdf0e10cSrcweir 	sal_uInt16 nNextNonHidden = (sal_uInt16)-1;
3556cdf0e10cSrcweir 	// first search the cols to the right
3557cdf0e10cSrcweir 	for (sal_uInt16 i = nPos + 1; i<m_aColumns.Count(); ++i)
3558cdf0e10cSrcweir 	{
3559cdf0e10cSrcweir 		DbGridColumn* pCurCol = m_aColumns.GetObject(i);
3560cdf0e10cSrcweir 		if (!pCurCol->IsHidden())
3561cdf0e10cSrcweir 		{
3562cdf0e10cSrcweir 			nNextNonHidden = i;
3563cdf0e10cSrcweir 			break;
3564cdf0e10cSrcweir 		}
3565cdf0e10cSrcweir 	}
3566cdf0e10cSrcweir 	if ((nNextNonHidden == (sal_uInt16)-1) && (nPos > 0))
3567cdf0e10cSrcweir 	{
3568cdf0e10cSrcweir 		// then to the left
3569cdf0e10cSrcweir 		for (sal_uInt16 i = nPos; i>0; --i)
3570cdf0e10cSrcweir 		{
3571cdf0e10cSrcweir 			DbGridColumn* pCurCol = m_aColumns.GetObject(i-1);
3572cdf0e10cSrcweir 			if (!pCurCol->IsHidden())
3573cdf0e10cSrcweir 			{
3574cdf0e10cSrcweir 				nNextNonHidden = i-1;
3575cdf0e10cSrcweir 				break;
3576cdf0e10cSrcweir 			}
3577cdf0e10cSrcweir 		}
3578cdf0e10cSrcweir 	}
3579cdf0e10cSrcweir 	sal_uInt16 nNewViewPos = (nNextNonHidden == (sal_uInt16)-1)
3580cdf0e10cSrcweir 		? 1 // there is no visible column -> insert behinde the handle col
3581cdf0e10cSrcweir 		: GetViewColumnPos(m_aColumns.GetObject(nNextNonHidden)->GetId()) + 1;
3582cdf0e10cSrcweir 			// the first non-handle col has "view pos" 0, but the pos arg for InsertDataColumn expects
3583cdf0e10cSrcweir 			// a position 1 for the first non-handle col -> +1
3584cdf0e10cSrcweir 	DBG_ASSERT(nNewViewPos != (sal_uInt16)-1, "DbGridControl::ShowColumn : inconsistent internal state !");
3585cdf0e10cSrcweir 		// we found a col marked as visible but got no view pos for it ...
3586cdf0e10cSrcweir 
3587cdf0e10cSrcweir 	if ((nNextNonHidden<nPos) && (nNextNonHidden != (sal_uInt16)-1))
3588cdf0e10cSrcweir 		// nNextNonHidden is a column to the left, so we want to insert the new col _right_ beside it's pos
3589cdf0e10cSrcweir 		++nNewViewPos;
3590cdf0e10cSrcweir 
3591cdf0e10cSrcweir 	DeactivateCell();
3592cdf0e10cSrcweir 
3593cdf0e10cSrcweir 	::rtl::OUString aName;
3594cdf0e10cSrcweir 	pColumn->getModel()->getPropertyValue(FM_PROP_LABEL) >>= aName;
3595cdf0e10cSrcweir 	InsertDataColumn(nId, aName, CalcZoom(pColumn->m_nLastVisibleWidth), HIB_CENTER | HIB_VCENTER | HIB_CLICKABLE, nNewViewPos);
3596cdf0e10cSrcweir 	pColumn->m_bHidden = sal_False;
3597cdf0e10cSrcweir 
3598cdf0e10cSrcweir 	ActivateCell();
3599cdf0e10cSrcweir 	Invalidate();
3600cdf0e10cSrcweir }
3601cdf0e10cSrcweir 
3602cdf0e10cSrcweir //------------------------------------------------------------------------------
GetColumnIdFromModelPos(sal_uInt16 nPos) const3603cdf0e10cSrcweir sal_uInt16 DbGridControl::GetColumnIdFromModelPos( sal_uInt16 nPos ) const
3604cdf0e10cSrcweir {
3605cdf0e10cSrcweir 	if (nPos >= m_aColumns.Count())
3606cdf0e10cSrcweir 	{
3607cdf0e10cSrcweir 		DBG_ERROR("DbGridControl::GetColumnIdFromModelPos : invalid argument !");
3608cdf0e10cSrcweir 		return (sal_uInt16)-1;
3609cdf0e10cSrcweir 	}
3610cdf0e10cSrcweir 
3611cdf0e10cSrcweir 	DbGridColumn* pCol = m_aColumns.GetObject(nPos);
3612cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 0) || defined DBG_UTIL
3613cdf0e10cSrcweir 	// in der Debug-Version rechnen wir die ModelPos in eine ViewPos um und vergleichen das mit dem Wert,
3614cdf0e10cSrcweir 	// den wir zurueckliefern werden (nId an der entsprechenden Col in m_aColumns)
3615cdf0e10cSrcweir 
3616cdf0e10cSrcweir 	if (!pCol->IsHidden())
3617cdf0e10cSrcweir 	{	// macht nur Sinn, wenn die Spalte sichtbar ist
3618cdf0e10cSrcweir 		sal_uInt16 nViewPos = nPos;
3619cdf0e10cSrcweir 		for (sal_uInt16 i=0; i<m_aColumns.Count() && i<nPos; ++i)
3620cdf0e10cSrcweir 			if (m_aColumns.GetObject(i)->IsHidden())
3621cdf0e10cSrcweir 				--nViewPos;
3622cdf0e10cSrcweir 
3623cdf0e10cSrcweir 		DBG_ASSERT(pCol && GetColumnIdFromViewPos(nViewPos) == pCol->GetId(),
3624cdf0e10cSrcweir 			"DbGridControl::GetColumnIdFromModelPos : this isn't consistent .... did I misunderstand something ?");
3625cdf0e10cSrcweir 	}
3626cdf0e10cSrcweir #endif
3627cdf0e10cSrcweir 	return pCol->GetId();
3628cdf0e10cSrcweir }
3629cdf0e10cSrcweir 
3630cdf0e10cSrcweir //------------------------------------------------------------------------------
GetModelColumnPos(sal_uInt16 nId) const3631cdf0e10cSrcweir sal_uInt16 DbGridControl::GetModelColumnPos( sal_uInt16 nId ) const
3632cdf0e10cSrcweir {
3633cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<m_aColumns.Count(); ++i)
3634cdf0e10cSrcweir 		if (m_aColumns.GetObject(i)->GetId() == nId)
3635cdf0e10cSrcweir 			return i;
3636cdf0e10cSrcweir 
3637cdf0e10cSrcweir     return GRID_COLUMN_NOT_FOUND;
3638cdf0e10cSrcweir }
3639cdf0e10cSrcweir 
3640cdf0e10cSrcweir //------------------------------------------------------------------------------
implAdjustInSolarThread(sal_Bool _bRows)3641cdf0e10cSrcweir void DbGridControl::implAdjustInSolarThread(sal_Bool _bRows)
3642cdf0e10cSrcweir {
3643cdf0e10cSrcweir 	TRACE_RANGE("DbGridControl::implAdjustInSolarThread");
3644cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_aAdjustSafety);
3645cdf0e10cSrcweir 	if (::vos::OThread::getCurrentIdentifier() != Application::GetMainThreadIdentifier())
3646cdf0e10cSrcweir 	{
3647cdf0e10cSrcweir 		m_nAsynAdjustEvent = PostUserEvent(LINK(this, DbGridControl, OnAsyncAdjust), reinterpret_cast< void* >( _bRows ));
3648cdf0e10cSrcweir 		m_bPendingAdjustRows = _bRows;
3649cdf0e10cSrcweir #ifdef DBG_UTIL
3650cdf0e10cSrcweir 		if (_bRows)
3651cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE("posting an AdjustRows")
3652cdf0e10cSrcweir 		else
3653cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE("posting an AdjustDataSource")
3654cdf0e10cSrcweir #endif
3655cdf0e10cSrcweir 	}
3656cdf0e10cSrcweir 	else
3657cdf0e10cSrcweir 	{
3658cdf0e10cSrcweir #ifdef DBG_UTIL
3659cdf0e10cSrcweir 		if (_bRows)
3660cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE("doing an AdjustRows")
3661cdf0e10cSrcweir 		else
3662cdf0e10cSrcweir 			TRACE_RANGE_MESSAGE("doing an AdjustDataSource")
3663cdf0e10cSrcweir #endif
3664cdf0e10cSrcweir 		// always adjust the rows before adjusting the data source
3665cdf0e10cSrcweir 		// If this is not necessary (because the row count did not change), nothing is done
3666cdf0e10cSrcweir 		// The problem is that we can't rely on the order of which the calls come in: If the cursor was moved
3667cdf0e10cSrcweir 		// to a position behind row count know 'til now, the cursorMoved notification may come before the
3668cdf0e10cSrcweir 		// RowCountChanged notification
3669cdf0e10cSrcweir 		// 94093 - 02.11.2001 - frank.schoenheit@sun.com
3670cdf0e10cSrcweir 		AdjustRows();
3671cdf0e10cSrcweir 
3672cdf0e10cSrcweir 		if ( !_bRows )
3673cdf0e10cSrcweir 			AdjustDataSource();
3674cdf0e10cSrcweir 	}
3675cdf0e10cSrcweir }
3676cdf0e10cSrcweir 
3677cdf0e10cSrcweir //------------------------------------------------------------------------------
IMPL_LINK(DbGridControl,OnAsyncAdjust,void *,pAdjustWhat)3678cdf0e10cSrcweir IMPL_LINK(DbGridControl, OnAsyncAdjust, void*, pAdjustWhat)
3679cdf0e10cSrcweir {
3680cdf0e10cSrcweir 	m_nAsynAdjustEvent = 0;
3681cdf0e10cSrcweir 
3682cdf0e10cSrcweir 	AdjustRows();
3683cdf0e10cSrcweir 		// see implAdjustInSolarThread for a comment why we do this every time
3684cdf0e10cSrcweir 
3685cdf0e10cSrcweir 	if ( !pAdjustWhat )
3686cdf0e10cSrcweir 		AdjustDataSource();
3687cdf0e10cSrcweir 
3688cdf0e10cSrcweir 	return 0L;
3689cdf0e10cSrcweir }
3690cdf0e10cSrcweir 
3691cdf0e10cSrcweir //------------------------------------------------------------------------------
BeginCursorAction()3692cdf0e10cSrcweir void DbGridControl::BeginCursorAction()
3693cdf0e10cSrcweir {
3694cdf0e10cSrcweir 	if (m_pFieldListeners)
3695cdf0e10cSrcweir 	{
3696cdf0e10cSrcweir 		ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
3697cdf0e10cSrcweir 		ConstColumnFieldValueListenersIterator aIter = pListeners->begin();
3698cdf0e10cSrcweir 		while (aIter != pListeners->end())
3699cdf0e10cSrcweir 		{
3700cdf0e10cSrcweir 			GridFieldValueListener* pCurrent = (*aIter).second;
3701cdf0e10cSrcweir 			if (pCurrent)
3702cdf0e10cSrcweir 				pCurrent->suspend();
3703cdf0e10cSrcweir 			++aIter;
3704cdf0e10cSrcweir 		}
3705cdf0e10cSrcweir 	}
3706cdf0e10cSrcweir 
3707cdf0e10cSrcweir 	if (m_pDataSourcePropListener)
3708cdf0e10cSrcweir 		m_pDataSourcePropListener->suspend();
3709cdf0e10cSrcweir }
3710cdf0e10cSrcweir 
3711cdf0e10cSrcweir //------------------------------------------------------------------------------
EndCursorAction()3712cdf0e10cSrcweir void DbGridControl::EndCursorAction()
3713cdf0e10cSrcweir {
3714cdf0e10cSrcweir 	if (m_pFieldListeners)
3715cdf0e10cSrcweir 	{
3716cdf0e10cSrcweir 		ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
3717cdf0e10cSrcweir 		ConstColumnFieldValueListenersIterator aIter = pListeners->begin();
3718cdf0e10cSrcweir 		while (aIter != pListeners->end())
3719cdf0e10cSrcweir 		{
3720cdf0e10cSrcweir 			GridFieldValueListener* pCurrent = (*aIter).second;
3721cdf0e10cSrcweir 			if (pCurrent)
3722cdf0e10cSrcweir 				pCurrent->resume();
3723cdf0e10cSrcweir 			++aIter;
3724cdf0e10cSrcweir 		}
3725cdf0e10cSrcweir 	}
3726cdf0e10cSrcweir 
3727cdf0e10cSrcweir 	if (m_pDataSourcePropListener)
3728cdf0e10cSrcweir 		m_pDataSourcePropListener->resume();
3729cdf0e10cSrcweir }
3730cdf0e10cSrcweir 
3731cdf0e10cSrcweir //------------------------------------------------------------------------------
ConnectToFields()3732cdf0e10cSrcweir void DbGridControl::ConnectToFields()
3733cdf0e10cSrcweir {
3734cdf0e10cSrcweir 	ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
3735cdf0e10cSrcweir 	DBG_ASSERT(!pListeners || pListeners->size() == 0, "DbGridControl::ConnectToFields : please call DisconnectFromFields first !");
3736cdf0e10cSrcweir 
3737cdf0e10cSrcweir 	if (!pListeners)
3738cdf0e10cSrcweir 	{
3739cdf0e10cSrcweir 		pListeners = new ColumnFieldValueListeners;
3740cdf0e10cSrcweir 		m_pFieldListeners = pListeners;
3741cdf0e10cSrcweir 	}
3742cdf0e10cSrcweir 
3743cdf0e10cSrcweir 	for (sal_Int32 i=0; i<(sal_Int32)m_aColumns.Count(); ++i)
3744cdf0e10cSrcweir 	{
3745cdf0e10cSrcweir 		DbGridColumn* pCurrent = m_aColumns.GetObject(i);
3746cdf0e10cSrcweir 		sal_uInt16 nViewPos = pCurrent ? GetViewColumnPos(pCurrent->GetId()) : (sal_uInt16)-1;
3747cdf0e10cSrcweir 		if ((sal_uInt16)-1 == nViewPos)
3748cdf0e10cSrcweir 			continue;
3749cdf0e10cSrcweir 
3750cdf0e10cSrcweir 		Reference< XPropertySet >  xField = pCurrent->GetField();
3751cdf0e10cSrcweir 		if (!xField.is())
3752cdf0e10cSrcweir 			continue;
3753cdf0e10cSrcweir 
3754cdf0e10cSrcweir 		// column is visible and bound here
3755cdf0e10cSrcweir 		GridFieldValueListener*& rpListener = (*pListeners)[pCurrent->GetId()];
3756cdf0e10cSrcweir 		DBG_ASSERT(!rpListener, "DbGridControl::ConnectToFields : already a listener for this column ?!");
3757cdf0e10cSrcweir 		rpListener = new GridFieldValueListener(*this, xField, pCurrent->GetId());
3758cdf0e10cSrcweir 	}
3759cdf0e10cSrcweir }
3760cdf0e10cSrcweir 
3761cdf0e10cSrcweir //------------------------------------------------------------------------------
DisconnectFromFields()3762cdf0e10cSrcweir void DbGridControl::DisconnectFromFields()
3763cdf0e10cSrcweir {
3764cdf0e10cSrcweir 	if (!m_pFieldListeners)
3765cdf0e10cSrcweir 		return;
3766cdf0e10cSrcweir 
3767cdf0e10cSrcweir 	ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
3768cdf0e10cSrcweir 	while (pListeners->size())
3769cdf0e10cSrcweir 	{
3770cdf0e10cSrcweir #ifdef DBG_UTIL
3771cdf0e10cSrcweir 		sal_Int32 nOldSize = pListeners->size();
3772cdf0e10cSrcweir #endif
3773cdf0e10cSrcweir 		pListeners->begin()->second->dispose();
3774cdf0e10cSrcweir 		DBG_ASSERT(nOldSize > (sal_Int32)pListeners->size(), "DbGridControl::DisconnectFromFields : dispose on a listener should result in a removal from my list !");
3775cdf0e10cSrcweir 	}
3776cdf0e10cSrcweir 
3777cdf0e10cSrcweir 	delete pListeners;
3778cdf0e10cSrcweir 	m_pFieldListeners = NULL;
3779cdf0e10cSrcweir }
3780cdf0e10cSrcweir 
3781cdf0e10cSrcweir //------------------------------------------------------------------------------
FieldValueChanged(sal_uInt16 _nId,const PropertyChangeEvent &)3782cdf0e10cSrcweir void DbGridControl::FieldValueChanged(sal_uInt16 _nId, const PropertyChangeEvent& /*_evt*/)
3783cdf0e10cSrcweir {
3784cdf0e10cSrcweir 	osl::MutexGuard aPreventDestruction(m_aDestructionSafety);
3785cdf0e10cSrcweir 	// needed as this may run in a thread other than the main one
3786cdf0e10cSrcweir 	if (GetRowStatus(GetCurRow()) != DbGridControl_Base::MODIFIED)
3787cdf0e10cSrcweir 		// all other cases are handled elsewhere
3788cdf0e10cSrcweir 		return;
3789cdf0e10cSrcweir 
3790cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(_nId));
3791cdf0e10cSrcweir 	if (pColumn)
3792cdf0e10cSrcweir 	{
3793cdf0e10cSrcweir 		sal_Bool bAcquiredPaintSafety = sal_False;
3794cdf0e10cSrcweir 		while (!m_bWantDestruction && !bAcquiredPaintSafety)
3795cdf0e10cSrcweir 			bAcquiredPaintSafety  = Application::GetSolarMutex().tryToAcquire();
3796cdf0e10cSrcweir 
3797cdf0e10cSrcweir 		if (m_bWantDestruction)
3798cdf0e10cSrcweir 		{	// at this moment, within another thread, our destructor tries to destroy the listener which called this method
3799cdf0e10cSrcweir 			// => don't do anything
3800cdf0e10cSrcweir 			// 73365 - 23.02.00 - FS
3801cdf0e10cSrcweir 			if (bAcquiredPaintSafety)
3802cdf0e10cSrcweir 				// though the above while-loop suggests that (m_bWantDestruction && bAcquiredPaintSafety) is impossible,
3803cdf0e10cSrcweir 				// it isnt't, as m_bWantDestruction isn't protected with any mutex
3804cdf0e10cSrcweir 				Application::GetSolarMutex().release();
3805cdf0e10cSrcweir 			return;
3806cdf0e10cSrcweir 		}
3807cdf0e10cSrcweir 		// here we got the solar mutex, transfer it to a guard for safety reasons
3808cdf0e10cSrcweir 		::vos::OGuard aPaintSafety(Application::GetSolarMutex());
3809cdf0e10cSrcweir 		Application::GetSolarMutex().release();
3810cdf0e10cSrcweir 
3811cdf0e10cSrcweir 		// and finally do the update ...
3812cdf0e10cSrcweir 		pColumn->UpdateFromField(m_xCurrentRow, m_xFormatter);
3813cdf0e10cSrcweir 		RowModified(GetCurRow(), _nId);
3814cdf0e10cSrcweir 	}
3815cdf0e10cSrcweir }
3816cdf0e10cSrcweir 
3817cdf0e10cSrcweir //------------------------------------------------------------------------------
FieldListenerDisposing(sal_uInt16 _nId)3818cdf0e10cSrcweir void DbGridControl::FieldListenerDisposing(sal_uInt16 _nId)
3819cdf0e10cSrcweir {
3820cdf0e10cSrcweir 	ColumnFieldValueListeners* pListeners = (ColumnFieldValueListeners*)m_pFieldListeners;
3821cdf0e10cSrcweir 	if (!pListeners)
3822cdf0e10cSrcweir 	{
3823cdf0e10cSrcweir 		DBG_ERROR("DbGridControl::FieldListenerDisposing : invalid call (have no listener array) !");
3824cdf0e10cSrcweir 		return;
3825cdf0e10cSrcweir 	}
3826cdf0e10cSrcweir 
3827cdf0e10cSrcweir 	ColumnFieldValueListenersIterator aPos = pListeners->find(_nId);
3828cdf0e10cSrcweir 	if (aPos == pListeners->end())
3829cdf0e10cSrcweir 	{
3830cdf0e10cSrcweir 		DBG_ERROR("DbGridControl::FieldListenerDisposing : invalid call (did not find the listener) !");
3831cdf0e10cSrcweir 		return;
3832cdf0e10cSrcweir 	}
3833cdf0e10cSrcweir 
3834cdf0e10cSrcweir 	delete aPos->second;
3835cdf0e10cSrcweir 
3836cdf0e10cSrcweir 	pListeners->erase(aPos);
3837cdf0e10cSrcweir }
3838cdf0e10cSrcweir 
3839cdf0e10cSrcweir //------------------------------------------------------------------------------
disposing(sal_uInt16 _nId,const EventObject &)3840cdf0e10cSrcweir void DbGridControl::disposing(sal_uInt16 _nId, const EventObject& /*_rEvt*/)
3841cdf0e10cSrcweir {
3842cdf0e10cSrcweir 	if (_nId == 0)
3843cdf0e10cSrcweir 	{	// the seek cursor is beeing disposed
3844cdf0e10cSrcweir 		::osl::MutexGuard aGuard(m_aAdjustSafety);
3845cdf0e10cSrcweir 		setDataSource(NULL,0); // our clone was disposed so we set our datasource to null to avoid later acces to it
3846cdf0e10cSrcweir 		if (m_nAsynAdjustEvent)
3847cdf0e10cSrcweir 		{
3848cdf0e10cSrcweir 			RemoveUserEvent(m_nAsynAdjustEvent);
3849cdf0e10cSrcweir 			m_nAsynAdjustEvent = 0;
3850cdf0e10cSrcweir 		}
3851cdf0e10cSrcweir 	}
3852cdf0e10cSrcweir }
3853cdf0e10cSrcweir // -----------------------------------------------------------------------------
GetAccessibleControlCount() const3854cdf0e10cSrcweir sal_Int32 DbGridControl::GetAccessibleControlCount() const
3855cdf0e10cSrcweir {
3856cdf0e10cSrcweir 	return DbGridControl_Base::GetAccessibleControlCount() + 1; // the navigation control
3857cdf0e10cSrcweir }
3858cdf0e10cSrcweir // -----------------------------------------------------------------------------
CreateAccessibleControl(sal_Int32 _nIndex)3859cdf0e10cSrcweir Reference<XAccessible > DbGridControl::CreateAccessibleControl( sal_Int32 _nIndex )
3860cdf0e10cSrcweir {
3861cdf0e10cSrcweir 	Reference<XAccessible > xRet;
3862cdf0e10cSrcweir 	if ( _nIndex == DbGridControl_Base::GetAccessibleControlCount() )
3863cdf0e10cSrcweir 	{
3864cdf0e10cSrcweir 		xRet = m_aBar.GetAccessible();
3865cdf0e10cSrcweir 	}
3866cdf0e10cSrcweir 	else
3867cdf0e10cSrcweir 		xRet = DbGridControl_Base::CreateAccessibleControl( _nIndex );
3868cdf0e10cSrcweir 	return xRet;
3869cdf0e10cSrcweir }
3870cdf0e10cSrcweir // -----------------------------------------------------------------------------
CreateAccessibleCell(sal_Int32 _nRow,sal_uInt16 _nColumnPos)3871cdf0e10cSrcweir Reference< XAccessible > DbGridControl::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
3872cdf0e10cSrcweir {
3873cdf0e10cSrcweir 	sal_uInt16 nColumnId = GetColumnId( _nColumnPos );
3874cdf0e10cSrcweir 	DbGridColumn* pColumn = m_aColumns.GetObject(GetModelColumnPos(nColumnId));
3875cdf0e10cSrcweir 	if ( pColumn )
3876cdf0e10cSrcweir 	{
3877cdf0e10cSrcweir 		Reference< ::com::sun::star::awt::XControl> xInt(pColumn->GetCell());
3878cdf0e10cSrcweir 		Reference< ::com::sun::star::awt::XCheckBox> xBox(xInt,UNO_QUERY);
3879cdf0e10cSrcweir 		if ( xBox.is() )
3880cdf0e10cSrcweir 		{
3881cdf0e10cSrcweir 			TriState eValue = STATE_NOCHECK;
3882cdf0e10cSrcweir 			switch( xBox->getState() )
3883cdf0e10cSrcweir 			{
3884cdf0e10cSrcweir 				case 0:
3885cdf0e10cSrcweir 					eValue = STATE_NOCHECK;
3886cdf0e10cSrcweir 					break;
3887cdf0e10cSrcweir 				case 1:
3888cdf0e10cSrcweir 					eValue = STATE_CHECK;
3889cdf0e10cSrcweir 					break;
3890cdf0e10cSrcweir 				case 2:
3891cdf0e10cSrcweir 					eValue = STATE_DONTKNOW;
3892cdf0e10cSrcweir 					break;
3893cdf0e10cSrcweir 			}
3894cdf0e10cSrcweir 			return DbGridControl_Base::CreateAccessibleCheckBoxCell( _nRow, _nColumnPos,eValue,sal_True );
3895cdf0e10cSrcweir 		}
3896cdf0e10cSrcweir 	}
3897cdf0e10cSrcweir 	return DbGridControl_Base::CreateAccessibleCell( _nRow, _nColumnPos );
3898cdf0e10cSrcweir }
3899cdf0e10cSrcweir // -----------------------------------------------------------------------------
3900cdf0e10cSrcweir 
3901cdf0e10cSrcweir 
3902