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