1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_dbaccess.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #ifndef DBAUI_QUERYTABLEVIEW_HXX
32*cdf0e10cSrcweir #include "QueryTableView.hxx"
33*cdf0e10cSrcweir #endif
34*cdf0e10cSrcweir #ifndef DBAUI_TABLEFIELDINFO_HXX
35*cdf0e10cSrcweir #include "TableFieldInfo.hxx"
36*cdf0e10cSrcweir #endif
37*cdf0e10cSrcweir #ifndef DBAUI_TABLEFIELDDESC_HXX
38*cdf0e10cSrcweir #include "TableFieldDescription.hxx"
39*cdf0e10cSrcweir #endif
40*cdf0e10cSrcweir #ifndef _TOOLS_DEBUG_HXX
41*cdf0e10cSrcweir #include <tools/debug.hxx>
42*cdf0e10cSrcweir #endif
43*cdf0e10cSrcweir #ifndef TOOLS_DIAGNOSE_EX_H
44*cdf0e10cSrcweir #include <tools/diagnose_ex.h>
45*cdf0e10cSrcweir #endif
46*cdf0e10cSrcweir #ifndef _DBA_DBACCESS_HELPID_HRC_
47*cdf0e10cSrcweir #include "dbaccess_helpid.hrc"
48*cdf0e10cSrcweir #endif
49*cdf0e10cSrcweir #ifndef DBAUI_QUERY_TABLEWINDOW_HXX
50*cdf0e10cSrcweir #include "QTableWindow.hxx"
51*cdf0e10cSrcweir #endif
52*cdf0e10cSrcweir #ifndef DBAUI_QUERYTABLECONNECTION_HXX
53*cdf0e10cSrcweir #include "QTableConnection.hxx"
54*cdf0e10cSrcweir #endif
55*cdf0e10cSrcweir #ifndef DBAUI_QTABLECONNECTIONDATA_HXX
56*cdf0e10cSrcweir #include "QTableConnectionData.hxx"
57*cdf0e10cSrcweir #endif
58*cdf0e10cSrcweir #ifndef DBAUI_QUERYDESIGNVIEW_HXX
59*cdf0e10cSrcweir #include "QueryDesignView.hxx"
60*cdf0e10cSrcweir #endif
61*cdf0e10cSrcweir #ifndef DBAUI_QUERYCONTROLLER_HXX
62*cdf0e10cSrcweir #include "querycontroller.hxx"
63*cdf0e10cSrcweir #endif
64*cdf0e10cSrcweir #ifndef DBAUI_QUERYADDTABCONNUNDOACTION_HXX
65*cdf0e10cSrcweir #include "QueryAddTabConnUndoAction.hxx"
66*cdf0e10cSrcweir #endif
67*cdf0e10cSrcweir #ifndef DBAUI_QUERYTABWINSHOWUNDOACT_HXX
68*cdf0e10cSrcweir #include "QueryTabWinShowUndoAct.hxx"
69*cdf0e10cSrcweir #endif
70*cdf0e10cSrcweir #ifndef DBACCESS_UI_BROWSER_ID_HXX
71*cdf0e10cSrcweir #include "browserids.hxx"
72*cdf0e10cSrcweir #endif
73*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
74*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
75*cdf0e10cSrcweir #endif
76*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
77*cdf0e10cSrcweir #include <com/sun/star/sdbc/XConnection.hpp>
78*cdf0e10cSrcweir #endif
79*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_
80*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
81*cdf0e10cSrcweir #endif
82*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
83*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
84*cdf0e10cSrcweir #endif
85*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
86*cdf0e10cSrcweir #ifndef DBACCESS_JACCESS_HXX
87*cdf0e10cSrcweir #include "JAccess.hxx"
88*cdf0e10cSrcweir #endif
89*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_
90*cdf0e10cSrcweir #include <com/sun/star/sdbcx/KeyType.hpp>
91*cdf0e10cSrcweir #endif
92*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
93*cdf0e10cSrcweir #include <com/sun/star/container/XIndexAccess.hpp>
94*cdf0e10cSrcweir #endif
95*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
96*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
97*cdf0e10cSrcweir #endif
98*cdf0e10cSrcweir #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
99*cdf0e10cSrcweir #include "dbustrings.hrc"
100*cdf0e10cSrcweir #endif
101*cdf0e10cSrcweir #ifndef _CONNECTIVITY_DBTOOLS_HXX_
102*cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
103*cdf0e10cSrcweir #endif
104*cdf0e10cSrcweir #ifndef _COMPHELPER_SEQUENCE_HXX_
105*cdf0e10cSrcweir #include <comphelper/sequence.hxx>
106*cdf0e10cSrcweir #endif
107*cdf0e10cSrcweir #ifndef DBAUI_QUERYDLG_HXX
108*cdf0e10cSrcweir #include "querydlg.hxx"
109*cdf0e10cSrcweir #endif
110*cdf0e10cSrcweir #ifndef DBAUI_JOINEXCHANGE_HXX
111*cdf0e10cSrcweir #include "JoinExchange.hxx"
112*cdf0e10cSrcweir #endif
113*cdf0e10cSrcweir #ifndef _COMPHELPER_EXTRACT_HXX_
114*cdf0e10cSrcweir #include <comphelper/extract.hxx>
115*cdf0e10cSrcweir #endif
116*cdf0e10cSrcweir #ifndef DBAUI_QUERYDESIGNVIEW_HXX
117*cdf0e10cSrcweir #include "QueryDesignView.hxx"
118*cdf0e10cSrcweir #endif
119*cdf0e10cSrcweir #ifndef _DBU_QRY_HRC_
120*cdf0e10cSrcweir #include "dbu_qry.hrc"
121*cdf0e10cSrcweir #endif
122*cdf0e10cSrcweir #ifndef _SV_MSGBOX_HXX
123*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
124*cdf0e10cSrcweir #endif
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir using namespace dbaui;
127*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
128*cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
129*cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx;
130*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
131*cdf0e10cSrcweir using namespace ::com::sun::star::container;
132*cdf0e10cSrcweir using namespace ::com::sun::star::accessibility;
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir //------------------------------------------------------------------------------
135*cdf0e10cSrcweir namespace
136*cdf0e10cSrcweir {
137*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
138*cdf0e10cSrcweir 	sal_Bool isColumnInKeyType(const Reference<XIndexAccess>& _rxKeys,const ::rtl::OUString& _rColumnName,sal_Int32 _nKeyType)
139*cdf0e10cSrcweir 	{
140*cdf0e10cSrcweir 		sal_Bool bReturn = sal_False;
141*cdf0e10cSrcweir 		if(_rxKeys.is())
142*cdf0e10cSrcweir 		{
143*cdf0e10cSrcweir 			Reference<XColumnsSupplier> xColumnsSupplier;
144*cdf0e10cSrcweir 			// search the one and only primary key
145*cdf0e10cSrcweir             const sal_Int32 nCount = _rxKeys->getCount();
146*cdf0e10cSrcweir 			for(sal_Int32 i=0;i< nCount;++i)
147*cdf0e10cSrcweir 			{
148*cdf0e10cSrcweir 				Reference<XPropertySet> xProp(_rxKeys->getByIndex(i),UNO_QUERY);
149*cdf0e10cSrcweir 				if(xProp.is())
150*cdf0e10cSrcweir 				{
151*cdf0e10cSrcweir 					sal_Int32 nKeyType = 0;
152*cdf0e10cSrcweir 					xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
153*cdf0e10cSrcweir 					if(_nKeyType == nKeyType)
154*cdf0e10cSrcweir 					{
155*cdf0e10cSrcweir 						xColumnsSupplier.set(xProp,UNO_QUERY);
156*cdf0e10cSrcweir 						if(xColumnsSupplier.is())
157*cdf0e10cSrcweir 						{
158*cdf0e10cSrcweir 							Reference<XNameAccess> xColumns = xColumnsSupplier->getColumns();
159*cdf0e10cSrcweir 							if(xColumns.is() && xColumns->hasByName(_rColumnName))
160*cdf0e10cSrcweir 							{
161*cdf0e10cSrcweir 								bReturn = sal_True;
162*cdf0e10cSrcweir 								break;
163*cdf0e10cSrcweir 							}
164*cdf0e10cSrcweir 						}
165*cdf0e10cSrcweir 					}
166*cdf0e10cSrcweir 				}
167*cdf0e10cSrcweir 			}
168*cdf0e10cSrcweir 		}
169*cdf0e10cSrcweir 		return bReturn;
170*cdf0e10cSrcweir 	}
171*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
172*cdf0e10cSrcweir 	/** appends a new TabAdd Undo action at controller
173*cdf0e10cSrcweir 		@param	_pView			the view which we use
174*cdf0e10cSrcweir 		@param	_pUndoAction	the undo action which should be added
175*cdf0e10cSrcweir 		@param	_pConnection	the connection for which the undo action should be appended
176*cdf0e10cSrcweir 		@param	_bOwner			is the undo action the owner
177*cdf0e10cSrcweir 	*/
178*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
179*cdf0e10cSrcweir 	void addUndoAction(	OQueryTableView* _pView,
180*cdf0e10cSrcweir 						OQueryTabConnUndoAction* _pUndoAction,
181*cdf0e10cSrcweir 						OQueryTableConnection* _pConnection,
182*cdf0e10cSrcweir 						sal_Bool _bOwner = sal_False)
183*cdf0e10cSrcweir 	{
184*cdf0e10cSrcweir 		_pUndoAction->SetOwnership(_bOwner);
185*cdf0e10cSrcweir 		_pUndoAction->SetConnection(_pConnection);
186*cdf0e10cSrcweir 		_pView->getDesignView()->getController().addUndoActionAndInvalidate(_pUndoAction);
187*cdf0e10cSrcweir 	}
188*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
189*cdf0e10cSrcweir 	/** openJoinDialog opens the join dialog with this connection data
190*cdf0e10cSrcweir 		@param	_pView				the view which we use
191*cdf0e10cSrcweir 		@param	_pConnectionData	the connection data
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 		@return	true when OK was pressed otherwise false
194*cdf0e10cSrcweir 	*/
195*cdf0e10cSrcweir     sal_Bool openJoinDialog(OQueryTableView* _pView,const TTableConnectionData::value_type& _pConnectionData,sal_Bool _bSelectableTables)
196*cdf0e10cSrcweir 	{
197*cdf0e10cSrcweir 		OQueryTableConnectionData* pData = static_cast< OQueryTableConnectionData*>(_pConnectionData.get());
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir 		DlgQryJoin aDlg(_pView,_pConnectionData,_pView->GetTabWinMap(),_pView->getDesignView()->getController().getConnection(),_bSelectableTables);
200*cdf0e10cSrcweir 		sal_Bool bOk = aDlg.Execute() == RET_OK;
201*cdf0e10cSrcweir 		if( bOk )
202*cdf0e10cSrcweir 		{
203*cdf0e10cSrcweir 			pData->SetJoinType(aDlg.GetJoinType());
204*cdf0e10cSrcweir 			_pView->getDesignView()->getController().setModified(sal_True);
205*cdf0e10cSrcweir 		}
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 		return bOk;
208*cdf0e10cSrcweir 	}
209*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
210*cdf0e10cSrcweir 	/** connectionModified adds an undo action for the modified connection and forces an redraw
211*cdf0e10cSrcweir 		@param	_pView				the view which we use
212*cdf0e10cSrcweir 		@param	_pConnection	the connection which was modified
213*cdf0e10cSrcweir 		@param	_bAddUndo		true when an undo action should be appended
214*cdf0e10cSrcweir 	*/
215*cdf0e10cSrcweir 	void connectionModified(OQueryTableView* _pView,
216*cdf0e10cSrcweir 							OTableConnection* _pConnection,
217*cdf0e10cSrcweir 							sal_Bool _bAddUndo)
218*cdf0e10cSrcweir 	{
219*cdf0e10cSrcweir 		OSL_ENSURE(_pConnection,"Invalid connection!");
220*cdf0e10cSrcweir 		_pConnection->UpdateLineList();
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir 		// add an undo action
223*cdf0e10cSrcweir 		if ( _bAddUndo )
224*cdf0e10cSrcweir 			addUndoAction(	_pView,
225*cdf0e10cSrcweir 							new OQueryAddTabConnUndoAction(_pView),
226*cdf0e10cSrcweir 							static_cast< OQueryTableConnection*>(_pConnection));
227*cdf0e10cSrcweir 		// redraw
228*cdf0e10cSrcweir 		_pConnection->RecalcLines();
229*cdf0e10cSrcweir 		// force an invalidation of the bounding rectangle
230*cdf0e10cSrcweir 		_pConnection->InvalidateConnection();
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir 		_pView->Invalidate(INVALIDATE_NOCHILDREN);
233*cdf0e10cSrcweir 	}
234*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
235*cdf0e10cSrcweir 	void addConnections(OQueryTableView* _pView,
236*cdf0e10cSrcweir 						const OQueryTableWindow& _rSource,
237*cdf0e10cSrcweir 						const OQueryTableWindow& _rDest,
238*cdf0e10cSrcweir 						const Reference<XNameAccess>& _rxSourceForeignKeyColumns)
239*cdf0e10cSrcweir 	{
240*cdf0e10cSrcweir         if ( _rSource.GetData()->isQuery() || _rDest.GetData()->isQuery() )
241*cdf0e10cSrcweir             // nothing to do if one of both denotes a query
242*cdf0e10cSrcweir             return;
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir 		// we found a table in our view where we can insert some connections
245*cdf0e10cSrcweir 		// the key columns have a property called RelatedColumn
246*cdf0e10cSrcweir 		// OQueryTableConnectionData aufbauen
247*cdf0e10cSrcweir         OQueryTableConnectionData* pNewConnData = new OQueryTableConnectionData( _rSource.GetData(), _rDest.GetData() );
248*cdf0e10cSrcweir         TTableConnectionData::value_type aNewConnData(pNewConnData);
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 		Reference<XIndexAccess> xReferencedKeys( _rDest.GetData()->getKeys());
251*cdf0e10cSrcweir 		::rtl::OUString sRelatedColumn;
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir 		// iterate through all foreignkey columns to create the connections
254*cdf0e10cSrcweir 		Sequence< ::rtl::OUString> aElements(_rxSourceForeignKeyColumns->getElementNames());
255*cdf0e10cSrcweir 		const ::rtl::OUString* pIter = aElements.getConstArray();
256*cdf0e10cSrcweir 		const ::rtl::OUString* pEnd   = pIter + aElements.getLength();
257*cdf0e10cSrcweir 		for(sal_Int32 i=0;pIter != pEnd;++pIter,++i)
258*cdf0e10cSrcweir 		{
259*cdf0e10cSrcweir 			Reference<XPropertySet> xColumn;
260*cdf0e10cSrcweir             if ( !( _rxSourceForeignKeyColumns->getByName(*pIter) >>= xColumn ) )
261*cdf0e10cSrcweir             {
262*cdf0e10cSrcweir                 OSL_ENSURE( false, "addConnections: invalid foreign key column!" );
263*cdf0e10cSrcweir                 continue;
264*cdf0e10cSrcweir             }
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir 			pNewConnData->SetFieldType(JTCS_FROM,TAB_NORMAL_FIELD);
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir 			xColumn->getPropertyValue(PROPERTY_RELATEDCOLUMN) >>= sRelatedColumn;
269*cdf0e10cSrcweir 			pNewConnData->SetFieldType(JTCS_TO,isColumnInKeyType(xReferencedKeys,sRelatedColumn,KeyType::PRIMARY) ? TAB_PRIMARY_FIELD : TAB_NORMAL_FIELD);
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir 			{
272*cdf0e10cSrcweir 				Sequence< sal_Int16> aFind(::comphelper::findValue(_rSource.GetOriginalColumns()->getElementNames(),*pIter,sal_True));
273*cdf0e10cSrcweir 				if(aFind.getLength())
274*cdf0e10cSrcweir 					pNewConnData->SetFieldIndex(JTCS_FROM,aFind[0]+1);
275*cdf0e10cSrcweir 				else
276*cdf0e10cSrcweir 					OSL_ENSURE(0,"Column not found!");
277*cdf0e10cSrcweir 			}
278*cdf0e10cSrcweir 			// get the position inside the tabe
279*cdf0e10cSrcweir 			Reference<XNameAccess> xRefColumns = _rDest.GetOriginalColumns();
280*cdf0e10cSrcweir 			if(xRefColumns.is())
281*cdf0e10cSrcweir 			{
282*cdf0e10cSrcweir 				Sequence< sal_Int16> aFind(::comphelper::findValue(xRefColumns->getElementNames(),sRelatedColumn,sal_True));
283*cdf0e10cSrcweir 				if(aFind.getLength())
284*cdf0e10cSrcweir 					pNewConnData->SetFieldIndex(JTCS_TO,aFind[0]+1);
285*cdf0e10cSrcweir 				else
286*cdf0e10cSrcweir 					OSL_ENSURE(0,"Column not found!");
287*cdf0e10cSrcweir 			}
288*cdf0e10cSrcweir 			pNewConnData->AppendConnLine(*pIter,sRelatedColumn);
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir 			// dann die Conn selber dazu
291*cdf0e10cSrcweir 			OQueryTableConnection aNewConn(_pView, aNewConnData);
292*cdf0e10cSrcweir 				// der Verweis auf die lokale Variable ist unkritisch, da NotifyQueryTabConn eine neue Kopie anlegt
293*cdf0e10cSrcweir 			// und mir hinzufuegen (wenn nicht schon existent)
294*cdf0e10cSrcweir 			_pView->NotifyTabConnection(aNewConn, sal_False);
295*cdf0e10cSrcweir 				// don't create an Undo-Action for the new connection : the connection is
296*cdf0e10cSrcweir 				// covered by the Undo-Action for the tabwin, as the "Undo the insert" will
297*cdf0e10cSrcweir 				// automatically remove all connections adjacent to the win.
298*cdf0e10cSrcweir 				// (Because of this automatism we would have an ownerhsip ambiguity for
299*cdf0e10cSrcweir 				// the connection data if we would insert the conn-Undo-Action)
300*cdf0e10cSrcweir 				// FS - 21.10.99 - 69183
301*cdf0e10cSrcweir 		}
302*cdf0e10cSrcweir 	}
303*cdf0e10cSrcweir }
304*cdf0e10cSrcweir //==================================================================
305*cdf0e10cSrcweir // class OQueryTableView
306*cdf0e10cSrcweir //==================================================================
307*cdf0e10cSrcweir DBG_NAME(OQueryTableView)
308*cdf0e10cSrcweir //------------------------------------------------------------------------
309*cdf0e10cSrcweir OQueryTableView::OQueryTableView( Window* pParent,OQueryDesignView* pView)
310*cdf0e10cSrcweir 	: OJoinTableView( pParent,pView)
311*cdf0e10cSrcweir {
312*cdf0e10cSrcweir 	DBG_CTOR(OQueryTableView,NULL);
313*cdf0e10cSrcweir 	SetHelpId(HID_CTL_QRYDGNTAB);
314*cdf0e10cSrcweir }
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir //------------------------------------------------------------------------
317*cdf0e10cSrcweir OQueryTableView::~OQueryTableView()
318*cdf0e10cSrcweir {
319*cdf0e10cSrcweir 	DBG_DTOR(OQueryTableView,NULL);
320*cdf0e10cSrcweir }
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir //------------------------------------------------------------------------
323*cdf0e10cSrcweir sal_Int32 OQueryTableView::CountTableAlias(const String& rName, sal_Int32& rMax)
324*cdf0e10cSrcweir {
325*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
326*cdf0e10cSrcweir 	sal_Int32 nRet = 0;
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir 	OTableWindowMapIterator aIter = GetTabWinMap()->find(rName);
329*cdf0e10cSrcweir 	while(aIter != GetTabWinMap()->end())
330*cdf0e10cSrcweir 	{
331*cdf0e10cSrcweir 		String aNewName;
332*cdf0e10cSrcweir 		aNewName = rName;
333*cdf0e10cSrcweir 		aNewName += '_';
334*cdf0e10cSrcweir 		aNewName += String::CreateFromInt32(++nRet);
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir 		aIter = GetTabWinMap()->find(aNewName);
337*cdf0e10cSrcweir 	}
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir 	rMax = nRet;
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir 	return nRet;
342*cdf0e10cSrcweir }
343*cdf0e10cSrcweir //------------------------------------------------------------------------
344*cdf0e10cSrcweir void OQueryTableView::ReSync()
345*cdf0e10cSrcweir {
346*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
347*cdf0e10cSrcweir 	TTableWindowData* pTabWinDataList = m_pView->getController().getTableWindowData();
348*cdf0e10cSrcweir 	DBG_ASSERT((getTableConnections()->size()==0) && (GetTabWinMap()->size()==0),
349*cdf0e10cSrcweir 		"vor OQueryTableView::ReSync() bitte ClearAll aufrufen !");
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir 	// ich brauche eine Sammlung aller Fensternamen, deren Anlegen schief geht, damit ich die entsprechenden Connections
352*cdf0e10cSrcweir 	// gar nicht erst anlege
353*cdf0e10cSrcweir 	::std::vector<String> arrInvalidTables;
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir 	TTableWindowData::reverse_iterator aIter = pTabWinDataList->rbegin();
356*cdf0e10cSrcweir 	// Fenster kreieren und einfuegen
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir 	for(;aIter != pTabWinDataList->rend();++aIter)
359*cdf0e10cSrcweir 	{
360*cdf0e10cSrcweir 		OQueryTableWindowData* pData = static_cast<OQueryTableWindowData*>(aIter->get());
361*cdf0e10cSrcweir 		OTableWindow* pTabWin = createWindow(*aIter);
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir 		// ich gehe jetzt NICHT ueber ShowTabWin, da dieses die Daten des Fensters in die Liste des Docs einfuegt, was
364*cdf0e10cSrcweir 		// schlecht waere, denn genau von dort hole ich sie ja gerade
365*cdf0e10cSrcweir 		// also Schritt fuer Schritt
366*cdf0e10cSrcweir 		if (!pTabWin->Init())
367*cdf0e10cSrcweir 		{
368*cdf0e10cSrcweir 			// das Initialisieren ging schief, dass heisst, dieses TabWin steht nicht zur Verfuegung, also muss ich es inklusive
369*cdf0e10cSrcweir 			// seiner Daten am Dokument aufraeumen
370*cdf0e10cSrcweir 			pTabWin->clearListBox();
371*cdf0e10cSrcweir 			delete pTabWin;
372*cdf0e10cSrcweir 			arrInvalidTables.push_back(pData->GetAliasName());
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir 			pTabWinDataList->erase( ::std::remove(pTabWinDataList->begin(),pTabWinDataList->end(),*aIter) ,pTabWinDataList->end());
375*cdf0e10cSrcweir 			continue;
376*cdf0e10cSrcweir 		}
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir 		(*GetTabWinMap())[pData->GetAliasName()] = pTabWin;	// am Anfang einfuegen, da ich die DataList ja rueckwaerts durchlaufe
379*cdf0e10cSrcweir 		// wenn in den Daten keine Position oder Groesse steht -> Default
380*cdf0e10cSrcweir 		if (!pData->HasPosition() && !pData->HasSize())
381*cdf0e10cSrcweir 			SetDefaultTabWinPosSize(pTabWin);
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir 		pTabWin->Show();
384*cdf0e10cSrcweir 	}
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir 	// Verbindungen einfuegen
387*cdf0e10cSrcweir 	TTableConnectionData* pTabConnDataList = m_pView->getController().getTableConnectionData();
388*cdf0e10cSrcweir 	TTableConnectionData::reverse_iterator aConIter = pTabConnDataList->rbegin();
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir 	for(;aConIter != pTabConnDataList->rend();++aConIter)
391*cdf0e10cSrcweir 	{
392*cdf0e10cSrcweir 		OQueryTableConnectionData* pTabConnData =  static_cast<OQueryTableConnectionData*>(aConIter->get());
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir 		// gibt es die beiden Tabellen zur Connection ?
395*cdf0e10cSrcweir 		String strTabExistenceTest = pTabConnData->getReferencingTable()->GetWinName();
396*cdf0e10cSrcweir 		sal_Bool bInvalid = ::std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end();
397*cdf0e10cSrcweir 		strTabExistenceTest = pTabConnData->getReferencedTable()->GetWinName();
398*cdf0e10cSrcweir 		bInvalid = bInvalid && ::std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end();
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir 		if (bInvalid)
401*cdf0e10cSrcweir 		{	// nein -> Pech gehabt, die Connection faellt weg
402*cdf0e10cSrcweir 			pTabConnDataList->erase( ::std::remove(pTabConnDataList->begin(),pTabConnDataList->end(),*aConIter) ,pTabConnDataList->end());
403*cdf0e10cSrcweir 			continue;
404*cdf0e10cSrcweir 		}
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir 		// adds a new connection to join view and notifies our accessible and invaldates the controller
407*cdf0e10cSrcweir 		addConnection(new OQueryTableConnection(this, *aConIter));
408*cdf0e10cSrcweir 	}
409*cdf0e10cSrcweir }
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir //------------------------------------------------------------------------
412*cdf0e10cSrcweir void OQueryTableView::ClearAll()
413*cdf0e10cSrcweir {
414*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
415*cdf0e10cSrcweir 	OJoinTableView::ClearAll();
416*cdf0e10cSrcweir 
417*cdf0e10cSrcweir 	SetUpdateMode(sal_True);
418*cdf0e10cSrcweir 	m_pView->getController().setModified(sal_True);
419*cdf0e10cSrcweir }
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir // -----------------------------------------------------------------------------
422*cdf0e10cSrcweir OTableWindow* OQueryTableView::createWindow(const TTableWindowData::value_type& _pData)
423*cdf0e10cSrcweir {
424*cdf0e10cSrcweir 	return new OQueryTableWindow(this,_pData);
425*cdf0e10cSrcweir }
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir //------------------------------------------------------------------------------
428*cdf0e10cSrcweir void OQueryTableView::NotifyTabConnection(const OQueryTableConnection& rNewConn, sal_Bool _bCreateUndoAction)
429*cdf0e10cSrcweir {
430*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
431*cdf0e10cSrcweir 	// erst mal schauen, ob ich diese Connection schon habe
432*cdf0e10cSrcweir 	OQueryTableConnection* pTabConn = NULL;
433*cdf0e10cSrcweir 	const ::std::vector<OTableConnection*>*	pConnections = getTableConnections();
434*cdf0e10cSrcweir     ::std::vector<OTableConnection*>::const_iterator aEnd = pConnections->end();
435*cdf0e10cSrcweir 	::std::vector<OTableConnection*>::const_iterator aIter = ::std::find(	pConnections->begin(),
436*cdf0e10cSrcweir 													aEnd,
437*cdf0e10cSrcweir 													static_cast<const OTableConnection*>(&rNewConn)
438*cdf0e10cSrcweir 													);
439*cdf0e10cSrcweir 	if(aIter == aEnd )
440*cdf0e10cSrcweir 	{
441*cdf0e10cSrcweir 		aIter = pConnections->begin();
442*cdf0e10cSrcweir 		for(;aIter != aEnd;++aIter)
443*cdf0e10cSrcweir 		{
444*cdf0e10cSrcweir 			if(*static_cast<OQueryTableConnection*>(*aIter) == rNewConn)
445*cdf0e10cSrcweir 			{
446*cdf0e10cSrcweir 				pTabConn = static_cast<OQueryTableConnection*>(*aIter);
447*cdf0e10cSrcweir 				break;
448*cdf0e10cSrcweir 			}
449*cdf0e10cSrcweir 		}
450*cdf0e10cSrcweir 	}
451*cdf0e10cSrcweir 	else
452*cdf0e10cSrcweir 		pTabConn = static_cast<OQueryTableConnection*>(*aIter);
453*cdf0e10cSrcweir 	// nein -> einfuegen
454*cdf0e10cSrcweir 	if (pTabConn == NULL)
455*cdf0e10cSrcweir 	{
456*cdf0e10cSrcweir 		// die neuen Daten ...
457*cdf0e10cSrcweir 		OQueryTableConnectionData* pNewData = static_cast< OQueryTableConnectionData*>(rNewConn.GetData()->NewInstance());
458*cdf0e10cSrcweir 		pNewData->CopyFrom(*rNewConn.GetData());
459*cdf0e10cSrcweir         TTableConnectionData::value_type aData(pNewData);
460*cdf0e10cSrcweir 		OQueryTableConnection* pNewConn = new OQueryTableConnection(this, aData);
461*cdf0e10cSrcweir 		GetConnection(pNewConn);
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir 		connectionModified(this,pNewConn,_bCreateUndoAction);
464*cdf0e10cSrcweir 	}
465*cdf0e10cSrcweir }
466*cdf0e10cSrcweir // -----------------------------------------------------------------------------
467*cdf0e10cSrcweir OTableWindowData* OQueryTableView::CreateImpl(const ::rtl::OUString& _rComposedName
468*cdf0e10cSrcweir                                              ,const ::rtl::OUString& _sTableName
469*cdf0e10cSrcweir 											 ,const ::rtl::OUString& _rWinName)
470*cdf0e10cSrcweir {
471*cdf0e10cSrcweir 	return new OQueryTableWindowData( _rComposedName, _sTableName,_rWinName );
472*cdf0e10cSrcweir }
473*cdf0e10cSrcweir //------------------------------------------------------------------------------
474*cdf0e10cSrcweir void OQueryTableView::AddTabWin(const ::rtl::OUString& _rTableName, const ::rtl::OUString& _rAliasName, sal_Bool bNewTable)
475*cdf0e10cSrcweir {
476*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
477*cdf0e10cSrcweir 	// das ist die aus der Basisklasse geerbte Methode, die fuehre ich auf die an meinem Parent zurueck, die mir eventuell einen
478*cdf0e10cSrcweir 	// Alias dazu bastelt und das an mein anderes AddTabWin weiterreicht
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir 	// leider ist _rTableName voll qualifiziert, das OQueryDesignView erwartet aber einen String, der
481*cdf0e10cSrcweir 	// nur aus Schema und Tabelle besteht und keinen Katalog enthaelt.
482*cdf0e10cSrcweir 	Reference< XConnection> xConnection = m_pView->getController().getConnection();
483*cdf0e10cSrcweir 	if(!xConnection.is())
484*cdf0e10cSrcweir 		return;
485*cdf0e10cSrcweir 	try
486*cdf0e10cSrcweir 	{
487*cdf0e10cSrcweir 		Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
488*cdf0e10cSrcweir 		::rtl::OUString sCatalog, sSchema, sTable;
489*cdf0e10cSrcweir 		::dbtools::qualifiedNameComponents(xMetaData,
490*cdf0e10cSrcweir 									_rTableName,
491*cdf0e10cSrcweir 									sCatalog,
492*cdf0e10cSrcweir 									sSchema,
493*cdf0e10cSrcweir 									sTable,
494*cdf0e10cSrcweir 									::dbtools::eInDataManipulation);
495*cdf0e10cSrcweir 		::rtl::OUString sRealName(sSchema);
496*cdf0e10cSrcweir 		if (sRealName.getLength())
497*cdf0e10cSrcweir 			sRealName+= ::rtl::OUString('.');
498*cdf0e10cSrcweir 		sRealName += sTable;
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir 		AddTabWin(_rTableName, sRealName, _rAliasName, bNewTable);
501*cdf0e10cSrcweir 	}
502*cdf0e10cSrcweir 	catch(SQLException&)
503*cdf0e10cSrcweir 	{
504*cdf0e10cSrcweir 		OSL_ASSERT(!"qualifiedNameComponents");
505*cdf0e10cSrcweir 	}
506*cdf0e10cSrcweir }
507*cdf0e10cSrcweir // -----------------------------------------------------------------------------
508*cdf0e10cSrcweir // find the table which has a foreign key with this referencedTable name
509*cdf0e10cSrcweir Reference<XPropertySet> getKeyReferencedTo(const Reference<XIndexAccess>& _rxKeys,const ::rtl::OUString& _rReferencedTable)
510*cdf0e10cSrcweir {
511*cdf0e10cSrcweir 	if(!_rxKeys.is())
512*cdf0e10cSrcweir 		return Reference<XPropertySet>();
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir 	if ( !_rxKeys.is() )
515*cdf0e10cSrcweir 		return Reference<XPropertySet>();
516*cdf0e10cSrcweir 	// search the one and only primary key
517*cdf0e10cSrcweir     const sal_Int32 nCount = _rxKeys->getCount();
518*cdf0e10cSrcweir 	for(sal_Int32 i=0;i<nCount ;++i)
519*cdf0e10cSrcweir 	{
520*cdf0e10cSrcweir 		Reference<XPropertySet> xKey(_rxKeys->getByIndex(i),UNO_QUERY);
521*cdf0e10cSrcweir 		if(xKey.is())
522*cdf0e10cSrcweir 		{
523*cdf0e10cSrcweir 			sal_Int32 nKeyType = 0;
524*cdf0e10cSrcweir 			xKey->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
525*cdf0e10cSrcweir 			if(KeyType::FOREIGN == nKeyType)
526*cdf0e10cSrcweir 			{
527*cdf0e10cSrcweir 				::rtl::OUString sReferencedTable;
528*cdf0e10cSrcweir 				xKey->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= sReferencedTable;
529*cdf0e10cSrcweir 				// TODO check case
530*cdf0e10cSrcweir 				if(sReferencedTable == _rReferencedTable)
531*cdf0e10cSrcweir 					return xKey;
532*cdf0e10cSrcweir 			}
533*cdf0e10cSrcweir 		}
534*cdf0e10cSrcweir 	}
535*cdf0e10cSrcweir 	return Reference<XPropertySet>();
536*cdf0e10cSrcweir }
537*cdf0e10cSrcweir //------------------------------------------------------------------------------
538*cdf0e10cSrcweir void OQueryTableView::AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& _rTableName, const ::rtl::OUString& strAlias, sal_Bool bNewTable)
539*cdf0e10cSrcweir {
540*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
541*cdf0e10cSrcweir 	DBG_ASSERT(_rTableName.getLength() || strAlias.getLength(), "OQueryTableView::AddTabWin : kein Tabellen- und kein Aliasname !");
542*cdf0e10cSrcweir 		// wenn der Tabellenname nicht gesetzt ist, steht das fuer ein Dummy-Fenster, das braucht aber wenigstens einen Alias-Namen
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir 	// neue Datenstruktur erzeugen
545*cdf0e10cSrcweir 	// first check if this already hav it's data
546*cdf0e10cSrcweir 	sal_Bool bAppend = bNewTable;
547*cdf0e10cSrcweir 	TTableWindowData::value_type pNewTabWinData;
548*cdf0e10cSrcweir 	TTableWindowData* pWindowData = getDesignView()->getController().getTableWindowData();
549*cdf0e10cSrcweir 	TTableWindowData::iterator aWinIter = pWindowData->begin();
550*cdf0e10cSrcweir     TTableWindowData::iterator aWinEnd = pWindowData->end();
551*cdf0e10cSrcweir 	for(;aWinIter != aWinEnd;++aWinIter)
552*cdf0e10cSrcweir 	{
553*cdf0e10cSrcweir 		pNewTabWinData = *aWinIter;
554*cdf0e10cSrcweir 		if (pNewTabWinData && pNewTabWinData->GetWinName() == strAlias && pNewTabWinData->GetComposedName() == _rComposedName && pNewTabWinData->GetTableName() == _rTableName)
555*cdf0e10cSrcweir 			break;
556*cdf0e10cSrcweir 	}
557*cdf0e10cSrcweir     if ( !bAppend )
558*cdf0e10cSrcweir         bAppend = ( aWinIter == aWinEnd );
559*cdf0e10cSrcweir 	if ( bAppend )
560*cdf0e10cSrcweir 		pNewTabWinData = createTableWindowData(_rComposedName, _rTableName, strAlias);
561*cdf0e10cSrcweir 		// die TabWinData brauche ich nicht in die entsprechende Liste der DocShell eintragen, das macht ShowTabWin
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir 	// neues Fenster erzeugen
564*cdf0e10cSrcweir 	OQueryTableWindow* pNewTabWin = static_cast<OQueryTableWindow*>(createWindow(pNewTabWinData));
565*cdf0e10cSrcweir 	// das Init kann ich hier weglassen, da das in ShowTabWin passiert
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir 	// Neue UndoAction
568*cdf0e10cSrcweir 	OQueryTabWinShowUndoAct* pUndoAction = new OQueryTabWinShowUndoAct(this);
569*cdf0e10cSrcweir 	pUndoAction->SetTabWin(pNewTabWin);	// Fenster
570*cdf0e10cSrcweir 	sal_Bool bSuccess = ShowTabWin(pNewTabWin, pUndoAction,bAppend);
571*cdf0e10cSrcweir 	if(!bSuccess)
572*cdf0e10cSrcweir 	{
573*cdf0e10cSrcweir 		// reset table window
574*cdf0e10cSrcweir 		pUndoAction->SetTabWin(NULL);
575*cdf0e10cSrcweir 		pUndoAction->SetOwnership(sal_False);
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir 		delete pUndoAction;
578*cdf0e10cSrcweir 		return;
579*cdf0e10cSrcweir 	}
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir 	// Relationen zwischen den einzelnen Tabellen anzeigen
582*cdf0e10cSrcweir 	OTableWindowMap* pTabWins = GetTabWinMap();
583*cdf0e10cSrcweir 	if(bNewTable && !pTabWins->empty() && _rTableName.getLength())
584*cdf0e10cSrcweir 	{
585*cdf0e10cSrcweir 		modified();
586*cdf0e10cSrcweir 		if ( m_pAccessible )
587*cdf0e10cSrcweir 			m_pAccessible->notifyAccessibleEvent(	AccessibleEventId::CHILD,
588*cdf0e10cSrcweir 													Any(),
589*cdf0e10cSrcweir 													makeAny(pNewTabWin->GetAccessible())
590*cdf0e10cSrcweir 													);
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir         do {
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir         if ( pNewTabWin->GetData()->isQuery() )
595*cdf0e10cSrcweir             break;
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir         try
598*cdf0e10cSrcweir         {
599*cdf0e10cSrcweir             //////////////////////////////////////////////////////////////////////
600*cdf0e10cSrcweir 			// find relations between the table an the tables already inserted
601*cdf0e10cSrcweir 			Reference< XIndexAccess> xKeyIndex = pNewTabWin->GetData()->getKeys();
602*cdf0e10cSrcweir 			if ( !xKeyIndex.is() )
603*cdf0e10cSrcweir                 break;
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir             Reference<XNameAccess> xFKeyColumns;
606*cdf0e10cSrcweir 			::rtl::OUString aReferencedTable;
607*cdf0e10cSrcweir 			Reference<XColumnsSupplier> xColumnsSupplier;
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir             const sal_Int32 nKeyCount = xKeyIndex->getCount();
610*cdf0e10cSrcweir             for ( sal_Int32 i=0; i<nKeyCount ; ++i )
611*cdf0e10cSrcweir 			{
612*cdf0e10cSrcweir                 Reference< XPropertySet > xProp( xKeyIndex->getByIndex(i), UNO_QUERY_THROW );
613*cdf0e10cSrcweir                 xColumnsSupplier.set( xProp, UNO_QUERY_THROW );
614*cdf0e10cSrcweir 				xFKeyColumns.set( xColumnsSupplier->getColumns(), UNO_QUERY_THROW );
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir                 sal_Int32 nKeyType = 0;
617*cdf0e10cSrcweir 				xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir                 switch ( nKeyType )
620*cdf0e10cSrcweir                 {
621*cdf0e10cSrcweir                 case KeyType::FOREIGN:
622*cdf0e10cSrcweir 				{	// our new table has a foreign key
623*cdf0e10cSrcweir 					// so look if the referenced table is already in our list
624*cdf0e10cSrcweir 					xProp->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= aReferencedTable;
625*cdf0e10cSrcweir 					OSL_ENSURE(aReferencedTable.getLength(),"Foreign key without referencedTableName");
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir 					OTableWindowMap::const_iterator aIter = pTabWins->find(aReferencedTable);
628*cdf0e10cSrcweir                     OTableWindowMap::const_iterator aEnd  = pTabWins->end();
629*cdf0e10cSrcweir 					if(aIter == aEnd)
630*cdf0e10cSrcweir 					{
631*cdf0e10cSrcweir 						for(aIter = pTabWins->begin();aIter != aEnd;++aIter)
632*cdf0e10cSrcweir 						{
633*cdf0e10cSrcweir 							OQueryTableWindow* pTabWinTmp = static_cast<OQueryTableWindow*>(aIter->second);
634*cdf0e10cSrcweir 							OSL_ENSURE( pTabWinTmp,"TableWindow is null!" );
635*cdf0e10cSrcweir 							if ( pTabWinTmp != pNewTabWin && pTabWinTmp->GetComposedName() == aReferencedTable )
636*cdf0e10cSrcweir 								break;
637*cdf0e10cSrcweir 						}
638*cdf0e10cSrcweir 					}
639*cdf0e10cSrcweir 					if ( aIter != aEnd && pNewTabWin != aIter->second )
640*cdf0e10cSrcweir 						addConnections( this, *pNewTabWin, *static_cast<OQueryTableWindow*>(aIter->second), xFKeyColumns );
641*cdf0e10cSrcweir 				}
642*cdf0e10cSrcweir                 break;
643*cdf0e10cSrcweir 
644*cdf0e10cSrcweir                 case KeyType::PRIMARY:
645*cdf0e10cSrcweir 				{
646*cdf0e10cSrcweir 					// we have a primary key so look in our list if there exsits a key which this is refered to
647*cdf0e10cSrcweir 					OTableWindowMap::const_iterator aIter = pTabWins->begin();
648*cdf0e10cSrcweir                     OTableWindowMap::const_iterator aEnd  = pTabWins->end();
649*cdf0e10cSrcweir 					for(;aIter != aEnd;++aIter)
650*cdf0e10cSrcweir 					{
651*cdf0e10cSrcweir 						OQueryTableWindow* pTabWinTmp = static_cast<OQueryTableWindow*>(aIter->second);
652*cdf0e10cSrcweir 						if ( pTabWinTmp == pNewTabWin )
653*cdf0e10cSrcweir                             continue;
654*cdf0e10cSrcweir 
655*cdf0e10cSrcweir                         if ( pTabWinTmp->GetData()->isQuery() )
656*cdf0e10cSrcweir                             continue;
657*cdf0e10cSrcweir 
658*cdf0e10cSrcweir                         OSL_ENSURE(pTabWinTmp,"TableWindow is null!");
659*cdf0e10cSrcweir 						Reference< XPropertySet > xFKKey = getKeyReferencedTo( pTabWinTmp->GetData()->getKeys(), pNewTabWin->GetComposedName() );
660*cdf0e10cSrcweir                         if ( !xFKKey.is() )
661*cdf0e10cSrcweir                             continue;
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir                         Reference<XColumnsSupplier> xFKColumnsSupplier( xFKKey, UNO_QUERY_THROW );
664*cdf0e10cSrcweir 						Reference< XNameAccess > xTColumns( xFKColumnsSupplier->getColumns(), UNO_QUERY_THROW );
665*cdf0e10cSrcweir 						addConnections( this, *pTabWinTmp, *pNewTabWin, xTColumns );
666*cdf0e10cSrcweir 					}
667*cdf0e10cSrcweir 				}
668*cdf0e10cSrcweir                 break;
669*cdf0e10cSrcweir                 }
670*cdf0e10cSrcweir             }
671*cdf0e10cSrcweir 		}
672*cdf0e10cSrcweir         catch( const Exception& )
673*cdf0e10cSrcweir         {
674*cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
675*cdf0e10cSrcweir         }
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir         } while ( false );
678*cdf0e10cSrcweir 	}
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir 	// mein Parent brauche ich, da es vom Loeschen erfahren soll
681*cdf0e10cSrcweir 	m_pView->getController().addUndoActionAndInvalidate( pUndoAction );
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir 	if (bSuccess && m_lnkTabWinsChangeHandler.IsSet())
684*cdf0e10cSrcweir 	{
685*cdf0e10cSrcweir 		TabWinsChangeNotification aHint(TabWinsChangeNotification::AT_ADDED_WIN, pNewTabWin->GetAliasName());
686*cdf0e10cSrcweir 		m_lnkTabWinsChangeHandler.Call(&aHint);
687*cdf0e10cSrcweir 	}
688*cdf0e10cSrcweir }
689*cdf0e10cSrcweir // -----------------------------------------------------------------------------
690*cdf0e10cSrcweir // -----------------------------------------------------------------------------
691*cdf0e10cSrcweir void OQueryTableView::AddConnection(const OJoinExchangeData& jxdSource, const OJoinExchangeData& jxdDest)
692*cdf0e10cSrcweir {
693*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
694*cdf0e10cSrcweir 	OQueryTableWindow* pSourceWin = static_cast< OQueryTableWindow*>(jxdSource.pListBox->GetTabWin());
695*cdf0e10cSrcweir 	OQueryTableWindow* pDestWin = static_cast< OQueryTableWindow*>(jxdDest.pListBox->GetTabWin());
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir 	String aSourceFieldName, aDestFieldName;
698*cdf0e10cSrcweir 	aSourceFieldName	= jxdSource.pListBox->GetEntryText(jxdSource.pEntry);
699*cdf0e10cSrcweir 	aDestFieldName		= jxdDest.pListBox->GetEntryText(jxdDest.pEntry);
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir 	OTableConnection* pConn = GetTabConn(pSourceWin,pDestWin,true);
702*cdf0e10cSrcweir 	if ( !pConn )
703*cdf0e10cSrcweir 	{
704*cdf0e10cSrcweir 		// neues Daten-Objekt
705*cdf0e10cSrcweir 		OQueryTableConnectionData* pNewConnectionData = new OQueryTableConnectionData(pSourceWin->GetData(), pDestWin->GetData());
706*cdf0e10cSrcweir         TTableConnectionData::value_type aNewConnectionData(pNewConnectionData);
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir 		sal_uInt32			nSourceFieldIndex, nDestFieldIndex;
709*cdf0e10cSrcweir 		ETableFieldType	eSourceFieldType, eDestFieldType;
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir 		// Namen/Position/Typ der beiden betroffenen Felder besorgen ...
712*cdf0e10cSrcweir 		// Source
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir 		nSourceFieldIndex = jxdSource.pListBox->GetModel()->GetAbsPos(jxdSource.pEntry);
715*cdf0e10cSrcweir 		eSourceFieldType = static_cast< OTableFieldInfo*>(jxdSource.pEntry->GetUserData())->GetKeyType();
716*cdf0e10cSrcweir 
717*cdf0e10cSrcweir 		// Dest
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir 		nDestFieldIndex = jxdDest.pListBox->GetModel()->GetAbsPos(jxdDest.pEntry);
720*cdf0e10cSrcweir 		eDestFieldType = static_cast< OTableFieldInfo*>(jxdDest.pEntry->GetUserData())->GetKeyType();
721*cdf0e10cSrcweir 
722*cdf0e10cSrcweir 		// ... und setzen
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir 		pNewConnectionData->SetFieldIndex(JTCS_FROM, nSourceFieldIndex);
725*cdf0e10cSrcweir 		pNewConnectionData->SetFieldIndex(JTCS_TO, nDestFieldIndex);
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir 		pNewConnectionData->SetFieldType(JTCS_FROM, eSourceFieldType);
728*cdf0e10cSrcweir 		pNewConnectionData->SetFieldType(JTCS_TO, eDestFieldType);
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir 		pNewConnectionData->AppendConnLine( aSourceFieldName,aDestFieldName );
731*cdf0e10cSrcweir 
732*cdf0e10cSrcweir 		OQueryTableConnection aNewConnection(this, aNewConnectionData);
733*cdf0e10cSrcweir 		NotifyTabConnection(aNewConnection);
734*cdf0e10cSrcweir 			// wie immer bei NotifyTabConnection ist das Verwenden lokaler Variablen unkritisch, da sowieso eine Kopie erzeugt wird
735*cdf0e10cSrcweir 	}
736*cdf0e10cSrcweir 	else
737*cdf0e10cSrcweir 	{
738*cdf0e10cSrcweir 		// the connection could point on the other side
739*cdf0e10cSrcweir 		if(pConn->GetSourceWin() == pDestWin)
740*cdf0e10cSrcweir 		{
741*cdf0e10cSrcweir 			String aTmp(aSourceFieldName);
742*cdf0e10cSrcweir 			aSourceFieldName = aDestFieldName;
743*cdf0e10cSrcweir 			aDestFieldName = aTmp;
744*cdf0e10cSrcweir 		}
745*cdf0e10cSrcweir 
746*cdf0e10cSrcweir 		pConn->GetData()->AppendConnLine( aSourceFieldName,aDestFieldName );
747*cdf0e10cSrcweir 
748*cdf0e10cSrcweir 		connectionModified(this,pConn,sal_False);
749*cdf0e10cSrcweir 	}
750*cdf0e10cSrcweir }
751*cdf0e10cSrcweir // -----------------------------------------------------------------------------
752*cdf0e10cSrcweir void OQueryTableView::ConnDoubleClicked(OTableConnection* pConnection)
753*cdf0e10cSrcweir {
754*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
755*cdf0e10cSrcweir 	if( openJoinDialog(this,pConnection->GetData(),sal_False) )
756*cdf0e10cSrcweir 	{
757*cdf0e10cSrcweir 		connectionModified(this,pConnection,sal_False);
758*cdf0e10cSrcweir 		SelectConn( pConnection );
759*cdf0e10cSrcweir 	}
760*cdf0e10cSrcweir }
761*cdf0e10cSrcweir // -----------------------------------------------------------------------------
762*cdf0e10cSrcweir void OQueryTableView::createNewConnection()
763*cdf0e10cSrcweir {
764*cdf0e10cSrcweir     TTableConnectionData::value_type pData(new OQueryTableConnectionData());
765*cdf0e10cSrcweir 	if( openJoinDialog(this,pData,sal_True) )
766*cdf0e10cSrcweir 	{
767*cdf0e10cSrcweir 		OTableWindowMap* pMap = GetTabWinMap();
768*cdf0e10cSrcweir 		OQueryTableWindow* pSourceWin	= static_cast< OQueryTableWindow*>((*pMap)[pData->getReferencingTable()->GetWinName()]);
769*cdf0e10cSrcweir 		OQueryTableWindow* pDestWin		= static_cast< OQueryTableWindow*>((*pMap)[pData->getReferencedTable()->GetWinName()]);
770*cdf0e10cSrcweir 		// first we have to look if the this connection already exists
771*cdf0e10cSrcweir 		OTableConnection* pConn = GetTabConn(pSourceWin,pDestWin,true);
772*cdf0e10cSrcweir 		sal_Bool bNew = sal_True;
773*cdf0e10cSrcweir 		if ( pConn )
774*cdf0e10cSrcweir 		{
775*cdf0e10cSrcweir 			pConn->GetData()->CopyFrom( *pData );
776*cdf0e10cSrcweir 			bNew = sal_False;
777*cdf0e10cSrcweir 		}
778*cdf0e10cSrcweir 		else
779*cdf0e10cSrcweir 		{
780*cdf0e10cSrcweir 			// create a new conenction and append it
781*cdf0e10cSrcweir 			OQueryTableConnection* pQConn = new OQueryTableConnection(this, pData);
782*cdf0e10cSrcweir 			GetConnection(pQConn);
783*cdf0e10cSrcweir 			pConn = pQConn;
784*cdf0e10cSrcweir 		}
785*cdf0e10cSrcweir 		connectionModified(this,pConn,bNew);
786*cdf0e10cSrcweir 		if ( !bNew && pConn == GetSelectedConn() ) // our connection was selected before so we have to reselect it
787*cdf0e10cSrcweir 			SelectConn( pConn );
788*cdf0e10cSrcweir 	}
789*cdf0e10cSrcweir }
790*cdf0e10cSrcweir //------------------------------------------------------------------------------
791*cdf0e10cSrcweir bool OQueryTableView::RemoveConnection( OTableConnection* _pConnection,sal_Bool /*_bDelete*/ )
792*cdf0e10cSrcweir {
793*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir 	// we don't want that our connection will be deleted, we put it in the undo manager
796*cdf0e10cSrcweir 	bool bRet = OJoinTableView::RemoveConnection( _pConnection,sal_False);
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir 	// add undo action
799*cdf0e10cSrcweir 	addUndoAction(	this,
800*cdf0e10cSrcweir 					new OQueryDelTabConnUndoAction(this),
801*cdf0e10cSrcweir 					static_cast< OQueryTableConnection*>(_pConnection),
802*cdf0e10cSrcweir 					sal_True);
803*cdf0e10cSrcweir 	return bRet;
804*cdf0e10cSrcweir }
805*cdf0e10cSrcweir 
806*cdf0e10cSrcweir //------------------------------------------------------------------------------
807*cdf0e10cSrcweir void OQueryTableView::KeyInput( const KeyEvent& rEvt )
808*cdf0e10cSrcweir {
809*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
810*cdf0e10cSrcweir 	OJoinTableView::KeyInput( rEvt );
811*cdf0e10cSrcweir }
812*cdf0e10cSrcweir 
813*cdf0e10cSrcweir //------------------------------------------------------------------------------
814*cdf0e10cSrcweir OQueryTableWindow* OQueryTableView::FindTable(const String& rAliasName)
815*cdf0e10cSrcweir {
816*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
817*cdf0e10cSrcweir 	DBG_ASSERT(rAliasName.Len(), "OQueryTableView::FindTable : der AliasName sollte nicht leer sein !");
818*cdf0e10cSrcweir 		// (nicht dass es schadet, aber es ist sinnlos und weist vielleicht auf Fehler beim Aufrufer hin)
819*cdf0e10cSrcweir 	OTableWindowMap::const_iterator aIter = GetTabWinMap()->find(rAliasName);
820*cdf0e10cSrcweir 	if(aIter != GetTabWinMap()->end())
821*cdf0e10cSrcweir 		return static_cast<OQueryTableWindow*>(aIter->second);
822*cdf0e10cSrcweir 	return NULL;
823*cdf0e10cSrcweir }
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir //------------------------------------------------------------------------------
826*cdf0e10cSrcweir sal_Bool OQueryTableView::FindTableFromField(const String& rFieldName, OTableFieldDescRef& rInfo, sal_uInt16& rCnt)
827*cdf0e10cSrcweir {
828*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
829*cdf0e10cSrcweir 	rCnt = 0;
830*cdf0e10cSrcweir 	OTableWindowMap::const_iterator aIter = GetTabWinMap()->begin();
831*cdf0e10cSrcweir     OTableWindowMap::const_iterator aEnd  = GetTabWinMap()->end();
832*cdf0e10cSrcweir 	for(;aIter != aEnd;++aIter)
833*cdf0e10cSrcweir 	{
834*cdf0e10cSrcweir 		if(static_cast<OQueryTableWindow*>(aIter->second)->ExistsField(rFieldName, rInfo))
835*cdf0e10cSrcweir 			++rCnt;
836*cdf0e10cSrcweir 	}
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir 	return rCnt == 1;
839*cdf0e10cSrcweir }
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir //------------------------------------------------------------------------------
842*cdf0e10cSrcweir void OQueryTableView::RemoveTabWin(OTableWindow* pTabWin)
843*cdf0e10cSrcweir {
844*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
845*cdf0e10cSrcweir 	DBG_ASSERT(pTabWin != NULL, "OQueryTableView::RemoveTabWin : Fenster sollte ungleich NULL sein !");
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir 	// mein Parent brauche ich, da es vom Loeschen erfahren soll
848*cdf0e10cSrcweir 	OQueryDesignView* pParent = static_cast<OQueryDesignView*>(getDesignView());
849*cdf0e10cSrcweir 
850*cdf0e10cSrcweir 	SfxUndoManager& rUndoMgr = m_pView->getController().GetUndoManager();
851*cdf0e10cSrcweir 	rUndoMgr.EnterListAction( String( ModuleRes(STR_QUERY_UNDO_TABWINDELETE) ), String() );
852*cdf0e10cSrcweir 
853*cdf0e10cSrcweir 	// Undo-Action anlegen
854*cdf0e10cSrcweir 	OQueryTabWinDelUndoAct* pUndoAction = new OQueryTabWinDelUndoAct(this);
855*cdf0e10cSrcweir 	pUndoAction->SetTabWin(static_cast< OQueryTableWindow*>(pTabWin));
856*cdf0e10cSrcweir 
857*cdf0e10cSrcweir 	// und Fenster verstecken
858*cdf0e10cSrcweir 	HideTabWin(static_cast< OQueryTableWindow*>(pTabWin), pUndoAction);
859*cdf0e10cSrcweir 
860*cdf0e10cSrcweir 	// Undo Actions und Loeschen der Felder in SelectionBrowseBox
861*cdf0e10cSrcweir 	pParent->TableDeleted( static_cast< OQueryTableWindowData*>(pTabWin->GetData().get())->GetAliasName() );
862*cdf0e10cSrcweir 
863*cdf0e10cSrcweir 	m_pView->getController().addUndoActionAndInvalidate( pUndoAction );
864*cdf0e10cSrcweir 	rUndoMgr.LeaveListAction();
865*cdf0e10cSrcweir 
866*cdf0e10cSrcweir 	if (m_lnkTabWinsChangeHandler.IsSet())
867*cdf0e10cSrcweir 	{
868*cdf0e10cSrcweir 		TabWinsChangeNotification aHint(TabWinsChangeNotification::AT_REMOVED_WIN, static_cast< OQueryTableWindow*>(pTabWin)->GetAliasName());
869*cdf0e10cSrcweir 		m_lnkTabWinsChangeHandler.Call(&aHint);
870*cdf0e10cSrcweir 	}
871*cdf0e10cSrcweir 
872*cdf0e10cSrcweir 	modified();
873*cdf0e10cSrcweir 	if ( m_pAccessible )
874*cdf0e10cSrcweir 		m_pAccessible->notifyAccessibleEvent(	AccessibleEventId::CHILD,
875*cdf0e10cSrcweir 												makeAny(pTabWin->GetAccessible()),
876*cdf0e10cSrcweir 												Any()
877*cdf0e10cSrcweir 												);
878*cdf0e10cSrcweir }
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir //------------------------------------------------------------------------
881*cdf0e10cSrcweir void OQueryTableView::EnsureVisible(const OTableWindow* pWin)
882*cdf0e10cSrcweir {
883*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
884*cdf0e10cSrcweir 
885*cdf0e10cSrcweir 	Invalidate(INVALIDATE_NOCHILDREN);
886*cdf0e10cSrcweir 	OJoinTableView::EnsureVisible(pWin);
887*cdf0e10cSrcweir }
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir //------------------------------------------------------------------------
890*cdf0e10cSrcweir void OQueryTableView::GetConnection(OQueryTableConnection* pConn)
891*cdf0e10cSrcweir {
892*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
893*cdf0e10cSrcweir 	// bei mir und dem Dokument einfuegen
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir 	addConnection( pConn );
896*cdf0e10cSrcweir 	// invalidieren (damit es neu gezeichnet wird)
897*cdf0e10cSrcweir 	//	pConn->Invalidate();
898*cdf0e10cSrcweir }
899*cdf0e10cSrcweir 
900*cdf0e10cSrcweir //------------------------------------------------------------------------
901*cdf0e10cSrcweir void OQueryTableView::DropConnection(OQueryTableConnection* pConn)
902*cdf0e10cSrcweir {
903*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
904*cdf0e10cSrcweir 	// Selektion beachten
905*cdf0e10cSrcweir 	// bei mir und dem Dokument rausnehmen
906*cdf0e10cSrcweir 	RemoveConnection( pConn ,sal_False);
907*cdf0e10cSrcweir }
908*cdf0e10cSrcweir 
909*cdf0e10cSrcweir //------------------------------------------------------------------------
910*cdf0e10cSrcweir void OQueryTableView::HideTabWin( OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction )
911*cdf0e10cSrcweir {
912*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
913*cdf0e10cSrcweir 	OTableWindowMap* pTabWins = GetTabWinMap();
914*cdf0e10cSrcweir 	DBG_ASSERT(pTabWins != NULL, "OQueryTableView::HideTabWin : habe keine TabWins !");
915*cdf0e10cSrcweir 
916*cdf0e10cSrcweir 	if (pTabWin)
917*cdf0e10cSrcweir 	{
918*cdf0e10cSrcweir 		// Fenster
919*cdf0e10cSrcweir 		// die Position in seinen Daten speichern
920*cdf0e10cSrcweir 		getDesignView()->SaveTabWinUIConfig(pTabWin);
921*cdf0e10cSrcweir 			// (ich muss ueber das Parent gehen, da nur das die Position der Scrollbars kennt)
922*cdf0e10cSrcweir 		// dann aus der Liste der TabWins raus und verstecken
923*cdf0e10cSrcweir         OTableWindowMap::iterator aIter = pTabWins->begin();
924*cdf0e10cSrcweir         OTableWindowMap::iterator aEnd  = pTabWins->end();
925*cdf0e10cSrcweir         for ( ;aIter != aEnd ; ++aIter )
926*cdf0e10cSrcweir             if ( aIter->second == pTabWin )
927*cdf0e10cSrcweir             {
928*cdf0e10cSrcweir                 pTabWins->erase( aIter );
929*cdf0e10cSrcweir                 break;
930*cdf0e10cSrcweir             }
931*cdf0e10cSrcweir 
932*cdf0e10cSrcweir 		pTabWin->Hide();	// nicht zerstoeren, steht im Undo!!
933*cdf0e10cSrcweir 
934*cdf0e10cSrcweir 		// die Daten zum TabWin muessen auch aus meiner Verantwortung entlassen werden
935*cdf0e10cSrcweir 		TTableWindowData* pTabWinDataList = m_pView->getController().getTableWindowData();
936*cdf0e10cSrcweir 		pTabWinDataList->erase( ::std::remove(pTabWinDataList->begin(),pTabWinDataList->end(),pTabWin->GetData()),pTabWinDataList->end());
937*cdf0e10cSrcweir 			// NICHT loeschen, da ja das TabWin selber - das noch lebt - sie auch noch braucht
938*cdf0e10cSrcweir 			// Entweder geht es irgendwann wieder in meine Verantwortung ueber, (ueber ShowTabWin), dann fuege ich
939*cdf0e10cSrcweir 			// auch die Daten wieder ein, oder die Undo-Action, die im Augenblick die alleinige Verantwortung fuer das Fenster
940*cdf0e10cSrcweir 			// und dessen Daten hat, wird zestoert, dann loescht es beides
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir 		if (m_pLastFocusTabWin == pTabWin)
943*cdf0e10cSrcweir 			m_pLastFocusTabWin = NULL;
944*cdf0e10cSrcweir 
945*cdf0e10cSrcweir 		// Verbindungen, die zum Fenster gehoeren, einsammeln und der UndoAction uebergeben
946*cdf0e10cSrcweir 		sal_Int16 nCnt = 0;
947*cdf0e10cSrcweir 		const ::std::vector<OTableConnection*>* pTabConList = getTableConnections();
948*cdf0e10cSrcweir 		::std::vector<OTableConnection*>::const_iterator aIter2 = pTabConList->begin();
949*cdf0e10cSrcweir 		for(;aIter2 != pTabConList->end();)// the end may change
950*cdf0e10cSrcweir 		{
951*cdf0e10cSrcweir 			OQueryTableConnection* pTmpEntry = static_cast<OQueryTableConnection*>(*aIter2);
952*cdf0e10cSrcweir 			OSL_ENSURE(pTmpEntry,"OQueryTableConnection is null!");
953*cdf0e10cSrcweir 			if( pTmpEntry->GetAliasName(JTCS_FROM) == pTabWin->GetAliasName() ||
954*cdf0e10cSrcweir 				pTmpEntry->GetAliasName(JTCS_TO) == pTabWin->GetAliasName() )
955*cdf0e10cSrcweir 			{
956*cdf0e10cSrcweir 				// add to undo list
957*cdf0e10cSrcweir 				pUndoAction->InsertConnection(pTmpEntry);
958*cdf0e10cSrcweir 
959*cdf0e10cSrcweir 				// call base class because we append an undo action
960*cdf0e10cSrcweir 				// but this time we are in a undo action list
961*cdf0e10cSrcweir 				OJoinTableView::RemoveConnection(pTmpEntry,sal_False);
962*cdf0e10cSrcweir                 aIter2 = pTabConList->begin();
963*cdf0e10cSrcweir 				++nCnt;
964*cdf0e10cSrcweir 			}
965*cdf0e10cSrcweir 			else
966*cdf0e10cSrcweir 				++aIter2;
967*cdf0e10cSrcweir 		}
968*cdf0e10cSrcweir 
969*cdf0e10cSrcweir 		if (nCnt)
970*cdf0e10cSrcweir 			InvalidateConnections();
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir 		m_pView->getController().InvalidateFeature(ID_BROWSER_ADDTABLE);
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir 		// der UndoAction sagen, dass das Fenster (inklusive der Connections) jetzt in seinem Besitzt ist
975*cdf0e10cSrcweir 		pUndoAction->SetOwnership(sal_True);
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir 		// damit habe ich das Doc natuerlich modifiziert
978*cdf0e10cSrcweir 		m_pView->getController().setModified( sal_True );
979*cdf0e10cSrcweir 		m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
980*cdf0e10cSrcweir 	}
981*cdf0e10cSrcweir }
982*cdf0e10cSrcweir 
983*cdf0e10cSrcweir //------------------------------------------------------------------------
984*cdf0e10cSrcweir sal_Bool OQueryTableView::ShowTabWin( OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction,sal_Bool _bAppend )
985*cdf0e10cSrcweir {
986*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
989*cdf0e10cSrcweir 
990*cdf0e10cSrcweir 	if (pTabWin)
991*cdf0e10cSrcweir 	{
992*cdf0e10cSrcweir 		if (pTabWin->Init())
993*cdf0e10cSrcweir 		{
994*cdf0e10cSrcweir 			TTableWindowData::value_type pData = pTabWin->GetData();
995*cdf0e10cSrcweir 			DBG_ASSERT(pData != NULL, "OQueryTableView::ShowTabWin : TabWin hat keine Daten !");
996*cdf0e10cSrcweir 			// Wenn die Daten schon PosSize haben, diese benutzen
997*cdf0e10cSrcweir 			if (pData->HasPosition() && pData->HasSize())
998*cdf0e10cSrcweir 			{
999*cdf0e10cSrcweir 				Size aSize(CalcZoom(pData->GetSize().Width()),CalcZoom(pData->GetSize().Height()));
1000*cdf0e10cSrcweir 				pTabWin->SetPosSizePixel(pData->GetPosition(), aSize);
1001*cdf0e10cSrcweir 			}
1002*cdf0e10cSrcweir 			else
1003*cdf0e10cSrcweir 				// ansonsten selber eine Default-Position ermitteln
1004*cdf0e10cSrcweir 				SetDefaultTabWinPosSize(pTabWin);
1005*cdf0e10cSrcweir 
1006*cdf0e10cSrcweir 			// Fenster zeigen und in Liste eintragen
1007*cdf0e10cSrcweir 			::rtl::OUString sName = static_cast< OQueryTableWindowData*>(pData.get())->GetAliasName();
1008*cdf0e10cSrcweir 			OSL_ENSURE(GetTabWinMap()->find(sName) == GetTabWinMap()->end(),"Alias name already in list!");
1009*cdf0e10cSrcweir 			GetTabWinMap()->insert(OTableWindowMap::value_type(sName,pTabWin));
1010*cdf0e10cSrcweir 
1011*cdf0e10cSrcweir 			pTabWin->Show();
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir 			pTabWin->Update();
1014*cdf0e10cSrcweir 				// Das Update ist notwendig, damit die Connections an dem Fenster richtig gezeichnet werden. Klingt absurd,
1015*cdf0e10cSrcweir 				// ich weiss. Aber die Listbox haelt sich intern ein Member, was bei ersten Zeichnen (nachdem die Listbox im Init
1016*cdf0e10cSrcweir 				// gerade neu gefuellt wurde) initialisiert wird, und genau dieses Member wird irgendwann benoetigt fuer
1017*cdf0e10cSrcweir 				// GetEntryPos, und dieses wiederum von der Connection, wenn sie ihren Ansatzpunkt am Fenster feststellen will.
1018*cdf0e10cSrcweir 
1019*cdf0e10cSrcweir 			// die Connections
1020*cdf0e10cSrcweir 			::std::vector<OTableConnection*>* pTableCon = pUndoAction->GetTabConnList();
1021*cdf0e10cSrcweir 			::std::vector<OTableConnection*>::iterator aIter = pTableCon->begin();
1022*cdf0e10cSrcweir             ::std::vector<OTableConnection*>::iterator aEnd = pTableCon->end();
1023*cdf0e10cSrcweir 
1024*cdf0e10cSrcweir 			for(;aIter != aEnd;++aIter)
1025*cdf0e10cSrcweir 				addConnection(*aIter); // add all connections from the undo action
1026*cdf0e10cSrcweir 
1027*cdf0e10cSrcweir 			// each connection should invalidated inside addConnection so we don't need this here any longer
1028*cdf0e10cSrcweir //			if ( !pOwnList->empty() )
1029*cdf0e10cSrcweir //				InvalidateConnections();
1030*cdf0e10cSrcweir 			pTableCon->clear();
1031*cdf0e10cSrcweir 
1032*cdf0e10cSrcweir 			// und die Daten des Fensters ebenfalls in Liste (des Docs)
1033*cdf0e10cSrcweir 			if(_bAppend)
1034*cdf0e10cSrcweir 				m_pView->getController().getTableWindowData()->push_back(pTabWin->GetData());
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir 			m_pView->getController().InvalidateFeature(ID_BROWSER_ADDTABLE);
1037*cdf0e10cSrcweir 
1038*cdf0e10cSrcweir 			// und der UndoAction sagen, dass das Fenster jetzt meine ist ...
1039*cdf0e10cSrcweir 			pUndoAction->SetOwnership(sal_False);
1040*cdf0e10cSrcweir 
1041*cdf0e10cSrcweir 			bSuccess = sal_True;
1042*cdf0e10cSrcweir 		}
1043*cdf0e10cSrcweir 		else
1044*cdf0e10cSrcweir 		{
1045*cdf0e10cSrcweir 			//////////////////////////////////////////////////////////////////
1046*cdf0e10cSrcweir 			// Initialisierung fehlgeschlagen
1047*cdf0e10cSrcweir 			// (z.B. wenn Verbindung zur Datenbank in diesem Augenblick unterbrochen worden ist)
1048*cdf0e10cSrcweir 			pTabWin->clearListBox();
1049*cdf0e10cSrcweir 			delete pTabWin;
1050*cdf0e10cSrcweir 		}
1051*cdf0e10cSrcweir 	}
1052*cdf0e10cSrcweir 
1053*cdf0e10cSrcweir 	// damit habe ich das Doc natuerlich modifiziert
1054*cdf0e10cSrcweir 	if(!m_pView->getController().isReadOnly())
1055*cdf0e10cSrcweir 		m_pView->getController().setModified( sal_True );
1056*cdf0e10cSrcweir 
1057*cdf0e10cSrcweir 	m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
1058*cdf0e10cSrcweir 
1059*cdf0e10cSrcweir 	return bSuccess;
1060*cdf0e10cSrcweir }
1061*cdf0e10cSrcweir //------------------------------------------------------------------------
1062*cdf0e10cSrcweir void OQueryTableView::InsertField(const OTableFieldDescRef& rInfo)
1063*cdf0e10cSrcweir {
1064*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
1065*cdf0e10cSrcweir 	DBG_ASSERT(getDesignView() != NULL, "OQueryTableView::InsertField : habe kein Parent !");
1066*cdf0e10cSrcweir 	static_cast<OQueryDesignView*>(getDesignView())->InsertField(rInfo);
1067*cdf0e10cSrcweir }
1068*cdf0e10cSrcweir //------------------------------------------------------------------------------
1069*cdf0e10cSrcweir sal_Bool OQueryTableView::ExistsAVisitedConn(const OQueryTableWindow* pFrom) const
1070*cdf0e10cSrcweir {
1071*cdf0e10cSrcweir 	DBG_CHKTHIS(OQueryTableView,NULL);
1072*cdf0e10cSrcweir 	const ::std::vector<OTableConnection*>* pList = getTableConnections();
1073*cdf0e10cSrcweir 	if (pList)
1074*cdf0e10cSrcweir 	{
1075*cdf0e10cSrcweir 		::std::vector<OTableConnection*>::const_iterator aIter = pList->begin();
1076*cdf0e10cSrcweir         ::std::vector<OTableConnection*>::const_iterator aEnd = pList->end();
1077*cdf0e10cSrcweir 		for(;aIter != aEnd;++aIter)
1078*cdf0e10cSrcweir 		{
1079*cdf0e10cSrcweir 			OQueryTableConnection* pTemp = static_cast<OQueryTableConnection*>(*aIter);
1080*cdf0e10cSrcweir 			if (pTemp->IsVisited() &&
1081*cdf0e10cSrcweir 				(pFrom == static_cast< OQueryTableWindow*>(pTemp->GetSourceWin()) || pFrom == static_cast< OQueryTableWindow*>(pTemp->GetDestWin())))
1082*cdf0e10cSrcweir 				return pTemp != NULL;
1083*cdf0e10cSrcweir 		}
1084*cdf0e10cSrcweir 	}
1085*cdf0e10cSrcweir 
1086*cdf0e10cSrcweir 	return sal_False;
1087*cdf0e10cSrcweir }
1088*cdf0e10cSrcweir // -----------------------------------------------------------------------------
1089*cdf0e10cSrcweir void OQueryTableView::onNoColumns_throw()
1090*cdf0e10cSrcweir {
1091*cdf0e10cSrcweir     String sError( ModuleRes( STR_STATEMENT_WITHOUT_RESULT_SET ) );
1092*cdf0e10cSrcweir     ::dbtools::throwSQLException( sError, ::dbtools::SQL_GENERAL_ERROR, NULL );
1093*cdf0e10cSrcweir }
1094*cdf0e10cSrcweir //------------------------------------------------------------------------------
1095*cdf0e10cSrcweir bool OQueryTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& _pData) const
1096*cdf0e10cSrcweir {
1097*cdf0e10cSrcweir     OQueryTableConnectionData* pQueryData = static_cast<OQueryTableConnectionData*>(_pData.get());
1098*cdf0e10cSrcweir     return pQueryData && (pQueryData->GetJoinType() == CROSS_JOIN);
1099*cdf0e10cSrcweir }
1100*cdf0e10cSrcweir // -----------------------------------------------------------------------------
1101