/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbui.hxx"

#ifndef DBAUI_QUERYTABLEVIEW_HXX
#include "QueryTableView.hxx"
#endif
#ifndef DBAUI_TABLEFIELDINFO_HXX
#include "TableFieldInfo.hxx"
#endif
#ifndef DBAUI_TABLEFIELDDESC_HXX
#include "TableFieldDescription.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef TOOLS_DIAGNOSE_EX_H
#include <tools/diagnose_ex.h>
#endif
#ifndef _DBA_DBACCESS_HELPID_HRC_
#include "dbaccess_helpid.hrc"
#endif
#ifndef DBAUI_QUERY_TABLEWINDOW_HXX
#include "QTableWindow.hxx"
#endif
#ifndef DBAUI_QUERYTABLECONNECTION_HXX
#include "QTableConnection.hxx"
#endif
#ifndef DBAUI_QTABLECONNECTIONDATA_HXX
#include "QTableConnectionData.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNVIEW_HXX
#include "QueryDesignView.hxx"
#endif
#ifndef DBAUI_QUERYCONTROLLER_HXX
#include "querycontroller.hxx"
#endif
#ifndef DBAUI_QUERYADDTABCONNUNDOACTION_HXX
#include "QueryAddTabConnUndoAction.hxx"
#endif
#ifndef DBAUI_QUERYTABWINSHOWUNDOACT_HXX
#include "QueryTabWinShowUndoAct.hxx"
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#endif
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#ifndef DBACCESS_JACCESS_HXX
#include "JAccess.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_
#include <com/sun/star/sdbcx/KeyType.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef DBAUI_QUERYDLG_HXX
#include "querydlg.hxx"
#endif
#ifndef DBAUI_JOINEXCHANGE_HXX
#include "JoinExchange.hxx"
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef DBAUI_QUERYDESIGNVIEW_HXX
#include "QueryDesignView.hxx"
#endif
#ifndef _DBU_QRY_HRC_
#include "dbu_qry.hrc"
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif

using namespace dbaui;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::accessibility;

//------------------------------------------------------------------------------
namespace
{
	// -----------------------------------------------------------------------------
	sal_Bool isColumnInKeyType(const Reference<XIndexAccess>& _rxKeys,const ::rtl::OUString& _rColumnName,sal_Int32 _nKeyType)
	{
		sal_Bool bReturn = sal_False;
		if(_rxKeys.is())
		{
			Reference<XColumnsSupplier> xColumnsSupplier;
			// search the one and only primary key
			const sal_Int32 nCount = _rxKeys->getCount();
			for(sal_Int32 i=0;i< nCount;++i)
			{
				Reference<XPropertySet> xProp(_rxKeys->getByIndex(i),UNO_QUERY);
				if(xProp.is())
				{
					sal_Int32 nKeyType = 0;
					xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
					if(_nKeyType == nKeyType)
					{
						xColumnsSupplier.set(xProp,UNO_QUERY);
						if(xColumnsSupplier.is())
						{
							Reference<XNameAccess> xColumns = xColumnsSupplier->getColumns();
							if(xColumns.is() && xColumns->hasByName(_rColumnName))
							{
								bReturn = sal_True;
								break;
							}
						}
					}
				}
			}
		}
		return bReturn;
	}
	// -----------------------------------------------------------------------------
	/** appends a new TabAdd Undo action at controller
		@param	_pView			the view which we use
		@param	_pUndoAction	the undo action which should be added
		@param	_pConnection	the connection for which the undo action should be appended
		@param	_bOwner			is the undo action the owner
	*/
	// -----------------------------------------------------------------------------
	void addUndoAction(	OQueryTableView* _pView,
						OQueryTabConnUndoAction* _pUndoAction,
						OQueryTableConnection* _pConnection,
						sal_Bool _bOwner = sal_False)
	{
		_pUndoAction->SetOwnership(_bOwner);
		_pUndoAction->SetConnection(_pConnection);
		_pView->getDesignView()->getController().addUndoActionAndInvalidate(_pUndoAction);
	}
	// -----------------------------------------------------------------------------
	/** openJoinDialog opens the join dialog with this connection data
		@param	_pView				the view which we use
		@param	_pConnectionData	the connection data

		@return	true when OK was pressed otherwise false
	*/
	sal_Bool openJoinDialog(OQueryTableView* _pView,const TTableConnectionData::value_type& _pConnectionData,sal_Bool _bSelectableTables)
	{
		OQueryTableConnectionData* pData = static_cast< OQueryTableConnectionData*>(_pConnectionData.get());

		DlgQryJoin aDlg(_pView,_pConnectionData,_pView->GetTabWinMap(),_pView->getDesignView()->getController().getConnection(),_bSelectableTables);
		sal_Bool bOk = aDlg.Execute() == RET_OK;
		if( bOk )
		{
			pData->SetJoinType(aDlg.GetJoinType());
			_pView->getDesignView()->getController().setModified(sal_True);
		}

		return bOk;
	}
	// -----------------------------------------------------------------------------
	/** connectionModified adds an undo action for the modified connection and forces an redraw
		@param	_pView				the view which we use
		@param	_pConnection	the connection which was modified
		@param	_bAddUndo		true when an undo action should be appended
	*/
	void connectionModified(OQueryTableView* _pView,
							OTableConnection* _pConnection,
							sal_Bool _bAddUndo)
	{
		OSL_ENSURE(_pConnection,"Invalid connection!");
		_pConnection->UpdateLineList();

		// add an undo action
		if ( _bAddUndo )
			addUndoAction(	_pView,
							new OQueryAddTabConnUndoAction(_pView),
							static_cast< OQueryTableConnection*>(_pConnection));
		// redraw
		_pConnection->RecalcLines();
		// force an invalidation of the bounding rectangle
		_pConnection->InvalidateConnection();

		_pView->Invalidate(INVALIDATE_NOCHILDREN);
	}
	// -----------------------------------------------------------------------------
	void addConnections(OQueryTableView* _pView,
						const OQueryTableWindow& _rSource,
						const OQueryTableWindow& _rDest,
						const Reference<XNameAccess>& _rxSourceForeignKeyColumns)
	{
        if ( _rSource.GetData()->isQuery() || _rDest.GetData()->isQuery() )
            // nothing to do if one of both denotes a query
            return;

		// we found a table in our view where we can insert some connections
		// the key columns have a property called RelatedColumn
		// OQueryTableConnectionData aufbauen
        OQueryTableConnectionData* pNewConnData = new OQueryTableConnectionData( _rSource.GetData(), _rDest.GetData() );
        TTableConnectionData::value_type aNewConnData(pNewConnData);

		Reference<XIndexAccess> xReferencedKeys( _rDest.GetData()->getKeys());
		::rtl::OUString sRelatedColumn;

		// iterate through all foreignkey columns to create the connections
		Sequence< ::rtl::OUString> aElements(_rxSourceForeignKeyColumns->getElementNames());
		const ::rtl::OUString* pIter = aElements.getConstArray();
		const ::rtl::OUString* pEnd   = pIter + aElements.getLength();
		for(sal_Int32 i=0;pIter != pEnd;++pIter,++i)
		{
			Reference<XPropertySet> xColumn;
            if ( !( _rxSourceForeignKeyColumns->getByName(*pIter) >>= xColumn ) )
            {
                OSL_ENSURE( false, "addConnections: invalid foreign key column!" );
                continue;
            }

			pNewConnData->SetFieldType(JTCS_FROM,TAB_NORMAL_FIELD);

			xColumn->getPropertyValue(PROPERTY_RELATEDCOLUMN) >>= sRelatedColumn;
			pNewConnData->SetFieldType(JTCS_TO,isColumnInKeyType(xReferencedKeys,sRelatedColumn,KeyType::PRIMARY) ? TAB_PRIMARY_FIELD : TAB_NORMAL_FIELD);

			{
				Sequence< sal_Int16> aFind(::comphelper::findValue(_rSource.GetOriginalColumns()->getElementNames(),*pIter,sal_True));
				if(aFind.getLength())
					pNewConnData->SetFieldIndex(JTCS_FROM,aFind[0]+1);
				else
					OSL_ENSURE(0,"Column not found!");
			}
			// get the position inside the table
			Reference<XNameAccess> xRefColumns = _rDest.GetOriginalColumns();
			if(xRefColumns.is())
			{
				Sequence< sal_Int16> aFind(::comphelper::findValue(xRefColumns->getElementNames(),sRelatedColumn,sal_True));
				if(aFind.getLength())
					pNewConnData->SetFieldIndex(JTCS_TO,aFind[0]+1);
				else
					OSL_ENSURE(0,"Column not found!");
			}
			pNewConnData->AppendConnLine(*pIter,sRelatedColumn);

			// dann die Conn selber dazu
			OQueryTableConnection aNewConn(_pView, aNewConnData);
				// der Verweis auf die lokale Variable ist unkritisch, da NotifyQueryTabConn eine neue Kopie anlegt
			// und mir hinzufuegen (wenn nicht schon existent)
			_pView->NotifyTabConnection(aNewConn, sal_False);
				// don't create an Undo-Action for the new connection : the connection is
				// covered by the Undo-Action for the tabwin, as the "Undo the insert" will
				// automatically remove all connections adjacent to the win.
				// (Because of this automatism we would have an ownership ambiguity for
				// the connection data if we would insert the conn-Undo-Action)
				// FS - 21.10.99 - 69183
		}
	}
}
//==================================================================
// class OQueryTableView
//==================================================================
DBG_NAME(OQueryTableView)
//------------------------------------------------------------------------
OQueryTableView::OQueryTableView( Window* pParent,OQueryDesignView* pView)
	: OJoinTableView( pParent,pView)
{
	DBG_CTOR(OQueryTableView,NULL);
	SetHelpId(HID_CTL_QRYDGNTAB);
}

//------------------------------------------------------------------------
OQueryTableView::~OQueryTableView()
{
	DBG_DTOR(OQueryTableView,NULL);
}

//------------------------------------------------------------------------
sal_Int32 OQueryTableView::CountTableAlias(const String& rName, sal_Int32& rMax)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	sal_Int32 nRet = 0;

	OTableWindowMapIterator aIter = GetTabWinMap()->find(rName);
	while(aIter != GetTabWinMap()->end())
	{
		String aNewName;
		aNewName = rName;
		aNewName += '_';
		aNewName += String::CreateFromInt32(++nRet);

		aIter = GetTabWinMap()->find(aNewName);
	}

	rMax = nRet;

	return nRet;
}
//------------------------------------------------------------------------
void OQueryTableView::ReSync()
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	TTableWindowData* pTabWinDataList = m_pView->getController().getTableWindowData();
	DBG_ASSERT((getTableConnections()->size()==0) && (GetTabWinMap()->size()==0),
		"vor OQueryTableView::ReSync() bitte ClearAll aufrufen !");

	// ich brauche eine Sammlung aller Fensternamen, deren Anlegen schief geht, damit ich die entsprechenden Connections
	// gar nicht erst anlege
	::std::vector<String> arrInvalidTables;

	TTableWindowData::reverse_iterator aIter = pTabWinDataList->rbegin();
	// Fenster kreieren und einfuegen

	for(;aIter != pTabWinDataList->rend();++aIter)
	{
		OQueryTableWindowData* pData = static_cast<OQueryTableWindowData*>(aIter->get());
		OTableWindow* pTabWin = createWindow(*aIter);

		// ich gehe jetzt NICHT ueber ShowTabWin, da dieses die Daten des Fensters in die Liste des Docs einfuegt, was
		// schlecht waere, denn genau von dort hole ich sie ja gerade
		// also Schritt fuer Schritt
		if (!pTabWin->Init())
		{
			// das Initialisieren ging schief, dass heisst, dieses TabWin steht nicht zur Verfuegung, also muss ich es inklusive
			// seiner Daten am Dokument aufraeumen
			pTabWin->clearListBox();
			delete pTabWin;
			arrInvalidTables.push_back(pData->GetAliasName());

			pTabWinDataList->erase( ::std::remove(pTabWinDataList->begin(),pTabWinDataList->end(),*aIter) ,pTabWinDataList->end());
			continue;
		}

		(*GetTabWinMap())[pData->GetAliasName()] = pTabWin;	// am Anfang einfuegen, da ich die DataList ja rueckwaerts durchlaufe
		// wenn in den Daten keine Position oder Groesse steht -> Default
		if (!pData->HasPosition() && !pData->HasSize())
			SetDefaultTabWinPosSize(pTabWin);

		pTabWin->Show();
	}

	// Verbindungen einfuegen
	TTableConnectionData* pTabConnDataList = m_pView->getController().getTableConnectionData();
	TTableConnectionData::reverse_iterator aConIter = pTabConnDataList->rbegin();

	for(;aConIter != pTabConnDataList->rend();++aConIter)
	{
		OQueryTableConnectionData* pTabConnData =  static_cast<OQueryTableConnectionData*>(aConIter->get());

		// gibt es die beiden Tabellen zur Connection ?
		String strTabExistenceTest = pTabConnData->getReferencingTable()->GetWinName();
		sal_Bool bInvalid = ::std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end();
		strTabExistenceTest = pTabConnData->getReferencedTable()->GetWinName();
		bInvalid = bInvalid && ::std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end();

		if (bInvalid)
		{	// nein -> Pech gehabt, die Connection faellt weg
			pTabConnDataList->erase( ::std::remove(pTabConnDataList->begin(),pTabConnDataList->end(),*aConIter) ,pTabConnDataList->end());
			continue;
		}

		// adds a new connection to join view and notifies our accessible and invalidates the controller
		addConnection(new OQueryTableConnection(this, *aConIter));
	}
}

//------------------------------------------------------------------------
void OQueryTableView::ClearAll()
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	OJoinTableView::ClearAll();

	SetUpdateMode(sal_True);
	m_pView->getController().setModified(sal_True);
}

// -----------------------------------------------------------------------------
OTableWindow* OQueryTableView::createWindow(const TTableWindowData::value_type& _pData)
{
	return new OQueryTableWindow(this,_pData);
}

//------------------------------------------------------------------------------
void OQueryTableView::NotifyTabConnection(const OQueryTableConnection& rNewConn, sal_Bool _bCreateUndoAction)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	// erst mal schauen, ob ich diese Connection schon habe
	OQueryTableConnection* pTabConn = NULL;
	const ::std::vector<OTableConnection*>*	pConnections = getTableConnections();
	::std::vector<OTableConnection*>::const_iterator aEnd = pConnections->end();
	::std::vector<OTableConnection*>::const_iterator aIter = ::std::find(	pConnections->begin(),
													aEnd,
													static_cast<const OTableConnection*>(&rNewConn)
													);
	if(aIter == aEnd )
	{
		aIter = pConnections->begin();
		for(;aIter != aEnd;++aIter)
		{
			if(*static_cast<OQueryTableConnection*>(*aIter) == rNewConn)
			{
				pTabConn = static_cast<OQueryTableConnection*>(*aIter);
				break;
			}
		}
	}
	else
		pTabConn = static_cast<OQueryTableConnection*>(*aIter);
	// nein -> einfuegen
	if (pTabConn == NULL)
	{
		// die neuen Daten ...
		OQueryTableConnectionData* pNewData = static_cast< OQueryTableConnectionData*>(rNewConn.GetData()->NewInstance());
		pNewData->CopyFrom(*rNewConn.GetData());
		TTableConnectionData::value_type aData(pNewData);
		OQueryTableConnection* pNewConn = new OQueryTableConnection(this, aData);
		GetConnection(pNewConn);

		connectionModified(this,pNewConn,_bCreateUndoAction);
	}
}
// -----------------------------------------------------------------------------
OTableWindowData* OQueryTableView::CreateImpl(const ::rtl::OUString& _rComposedName
                                             ,const ::rtl::OUString& _sTableName
											 ,const ::rtl::OUString& _rWinName)
{
	return new OQueryTableWindowData( _rComposedName, _sTableName,_rWinName );
}
//------------------------------------------------------------------------------
void OQueryTableView::AddTabWin(const ::rtl::OUString& _rTableName, const ::rtl::OUString& _rAliasName, sal_Bool bNewTable)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	// das ist die aus der Basisklasse geerbte Methode, die fuehre ich auf die an meinem Parent zurueck, die mir eventuell einen
	// Alias dazu bastelt und das an mein anderes AddTabWin weiterreicht

	// leider ist _rTableName voll qualifiziert, das OQueryDesignView erwartet aber einen String, der
	// nur aus Schema und Tabelle besteht und keinen Katalog enthaelt.
	Reference< XConnection> xConnection = m_pView->getController().getConnection();
	if(!xConnection.is())
		return;
	try
	{
		Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
		::rtl::OUString sCatalog, sSchema, sTable;
		::dbtools::qualifiedNameComponents(xMetaData,
									_rTableName,
									sCatalog,
									sSchema,
									sTable,
									::dbtools::eInDataManipulation);
		::rtl::OUString sRealName(sSchema);
		if (sRealName.getLength())
			sRealName+= ::rtl::OUString('.');
		sRealName += sTable;

		AddTabWin(_rTableName, sRealName, _rAliasName, bNewTable);
	}
	catch(SQLException&)
	{
		OSL_ASSERT(!"qualifiedNameComponents");
	}
}
// -----------------------------------------------------------------------------
// find the table which has a foreign key with this referencedTable name
Reference<XPropertySet> getKeyReferencedTo(const Reference<XIndexAccess>& _rxKeys,const ::rtl::OUString& _rReferencedTable)
{
	if(!_rxKeys.is())
		return Reference<XPropertySet>();

	if ( !_rxKeys.is() )
		return Reference<XPropertySet>();
	// search the one and only primary key
	const sal_Int32 nCount = _rxKeys->getCount();
	for(sal_Int32 i=0;i<nCount ;++i)
	{
		Reference<XPropertySet> xKey(_rxKeys->getByIndex(i),UNO_QUERY);
		if(xKey.is())
		{
			sal_Int32 nKeyType = 0;
			xKey->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
			if(KeyType::FOREIGN == nKeyType)
			{
				::rtl::OUString sReferencedTable;
				xKey->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= sReferencedTable;
				// TODO check case
				if(sReferencedTable == _rReferencedTable)
					return xKey;
			}
		}
	}
	return Reference<XPropertySet>();
}
//------------------------------------------------------------------------------
void OQueryTableView::AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& _rTableName, const ::rtl::OUString& strAlias, sal_Bool bNewTable)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	DBG_ASSERT(_rTableName.getLength() || strAlias.getLength(), "OQueryTableView::AddTabWin : kein Tabellen- und kein Aliasname !");
		// wenn der Tabellenname nicht gesetzt ist, steht das fuer ein Dummy-Fenster, das braucht aber wenigstens einen Alias-Namen

	// neue Datenstruktur erzeugen
	// first check if this already have its data
	sal_Bool bAppend = bNewTable;
	TTableWindowData::value_type pNewTabWinData;
	TTableWindowData* pWindowData = getDesignView()->getController().getTableWindowData();
	TTableWindowData::iterator aWinIter = pWindowData->begin();
	TTableWindowData::iterator aWinEnd = pWindowData->end();
	for(;aWinIter != aWinEnd;++aWinIter)
	{
		pNewTabWinData = *aWinIter;
		if (pNewTabWinData && pNewTabWinData->GetWinName() == strAlias && pNewTabWinData->GetComposedName() == _rComposedName && pNewTabWinData->GetTableName() == _rTableName)
			break;
	}
	if ( !bAppend )
		bAppend = ( aWinIter == aWinEnd );
	if ( bAppend )
		pNewTabWinData = createTableWindowData(_rComposedName, _rTableName, strAlias);
		// die TabWinData brauche ich nicht in die entsprechende Liste der DocShell eintragen, das macht ShowTabWin

	// neues Fenster erzeugen
	OQueryTableWindow* pNewTabWin = static_cast<OQueryTableWindow*>(createWindow(pNewTabWinData));
	// das Init kann ich hier weglassen, da das in ShowTabWin passiert

	// Neue UndoAction
	OQueryTabWinShowUndoAct* pUndoAction = new OQueryTabWinShowUndoAct(this);
	pUndoAction->SetTabWin(pNewTabWin);	// Fenster
	sal_Bool bSuccess = ShowTabWin(pNewTabWin, pUndoAction,bAppend);
	if(!bSuccess)
	{
		// reset table window
		pUndoAction->SetTabWin(NULL);
		pUndoAction->SetOwnership(sal_False);

		delete pUndoAction;
		return;
	}

	// Relationen zwischen den einzelnen Tabellen anzeigen
	OTableWindowMap* pTabWins = GetTabWinMap();
	if(bNewTable && !pTabWins->empty() && _rTableName.getLength())
	{
		modified();
		if ( m_pAccessible )
			m_pAccessible->notifyAccessibleEvent(	AccessibleEventId::CHILD,
													Any(),
													makeAny(pNewTabWin->GetAccessible())
													);

        do {

        if ( pNewTabWin->GetData()->isQuery() )
            break;

        try
        {
            //////////////////////////////////////////////////////////////////////
			// find relations between the table an the tables already inserted
			Reference< XIndexAccess> xKeyIndex = pNewTabWin->GetData()->getKeys();
			if ( !xKeyIndex.is() )
                break;

            Reference<XNameAccess> xFKeyColumns;
			::rtl::OUString aReferencedTable;
			Reference<XColumnsSupplier> xColumnsSupplier;

            const sal_Int32 nKeyCount = xKeyIndex->getCount();
            for ( sal_Int32 i=0; i<nKeyCount ; ++i )
			{
                Reference< XPropertySet > xProp( xKeyIndex->getByIndex(i), UNO_QUERY_THROW );
                xColumnsSupplier.set( xProp, UNO_QUERY_THROW );
				xFKeyColumns.set( xColumnsSupplier->getColumns(), UNO_QUERY_THROW );

                sal_Int32 nKeyType = 0;
				xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;

                switch ( nKeyType )
                {
                case KeyType::FOREIGN:
				{	// our new table has a foreign key
					// so look if the referenced table is already in our list
					xProp->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= aReferencedTable;
					OSL_ENSURE(aReferencedTable.getLength(),"Foreign key without referencedTableName");

					OTableWindowMap::const_iterator aIter = pTabWins->find(aReferencedTable);
                    OTableWindowMap::const_iterator aEnd  = pTabWins->end();
					if(aIter == aEnd)
					{
						for(aIter = pTabWins->begin();aIter != aEnd;++aIter)
						{
							OQueryTableWindow* pTabWinTmp = static_cast<OQueryTableWindow*>(aIter->second);
							OSL_ENSURE( pTabWinTmp,"TableWindow is null!" );
							if ( pTabWinTmp != pNewTabWin && pTabWinTmp->GetComposedName() == aReferencedTable )
								break;
						}
					}
					if ( aIter != aEnd && pNewTabWin != aIter->second )
						addConnections( this, *pNewTabWin, *static_cast<OQueryTableWindow*>(aIter->second), xFKeyColumns );
				}
                break;

                case KeyType::PRIMARY:
				{
					// we have a primary key so look in our list if there exists a key which this is referred to
					OTableWindowMap::const_iterator aIter = pTabWins->begin();
                    OTableWindowMap::const_iterator aEnd  = pTabWins->end();
					for(;aIter != aEnd;++aIter)
					{
						OQueryTableWindow* pTabWinTmp = static_cast<OQueryTableWindow*>(aIter->second);
						if ( pTabWinTmp == pNewTabWin )
                            continue;

                        if ( pTabWinTmp->GetData()->isQuery() )
                            continue;

                        OSL_ENSURE(pTabWinTmp,"TableWindow is null!");
						Reference< XPropertySet > xFKKey = getKeyReferencedTo( pTabWinTmp->GetData()->getKeys(), pNewTabWin->GetComposedName() );
                        if ( !xFKKey.is() )
                            continue;

                        Reference<XColumnsSupplier> xFKColumnsSupplier( xFKKey, UNO_QUERY_THROW );
						Reference< XNameAccess > xTColumns( xFKColumnsSupplier->getColumns(), UNO_QUERY_THROW );
						addConnections( this, *pTabWinTmp, *pNewTabWin, xTColumns );
					}
				}
                break;
                }
            }
		}
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

        } while ( false );
	}

	// mein Parent brauche ich, da es vom Loeschen erfahren soll
	m_pView->getController().addUndoActionAndInvalidate( pUndoAction );

	if (bSuccess && m_lnkTabWinsChangeHandler.IsSet())
	{
		TabWinsChangeNotification aHint(TabWinsChangeNotification::AT_ADDED_WIN, pNewTabWin->GetAliasName());
		m_lnkTabWinsChangeHandler.Call(&aHint);
	}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void OQueryTableView::AddConnection(const OJoinExchangeData& jxdSource, const OJoinExchangeData& jxdDest)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	OQueryTableWindow* pSourceWin = static_cast< OQueryTableWindow*>(jxdSource.pListBox->GetTabWin());
	OQueryTableWindow* pDestWin = static_cast< OQueryTableWindow*>(jxdDest.pListBox->GetTabWin());

	String aSourceFieldName, aDestFieldName;
	aSourceFieldName	= jxdSource.pListBox->GetEntryText(jxdSource.pEntry);
	aDestFieldName		= jxdDest.pListBox->GetEntryText(jxdDest.pEntry);

	OTableConnection* pConn = GetTabConn(pSourceWin,pDestWin,true);
	if ( !pConn )
	{
		// neues Daten-Objekt
		OQueryTableConnectionData* pNewConnectionData = new OQueryTableConnectionData(pSourceWin->GetData(), pDestWin->GetData());
        TTableConnectionData::value_type aNewConnectionData(pNewConnectionData);

		sal_uInt32			nSourceFieldIndex, nDestFieldIndex;
		ETableFieldType	eSourceFieldType, eDestFieldType;

		// Namen/Position/Typ der beiden betroffenen Felder besorgen ...
		// Source

		nSourceFieldIndex = jxdSource.pListBox->GetModel()->GetAbsPos(jxdSource.pEntry);
		eSourceFieldType = static_cast< OTableFieldInfo*>(jxdSource.pEntry->GetUserData())->GetKeyType();

		// Dest

		nDestFieldIndex = jxdDest.pListBox->GetModel()->GetAbsPos(jxdDest.pEntry);
		eDestFieldType = static_cast< OTableFieldInfo*>(jxdDest.pEntry->GetUserData())->GetKeyType();

		// ... und setzen

		pNewConnectionData->SetFieldIndex(JTCS_FROM, nSourceFieldIndex);
		pNewConnectionData->SetFieldIndex(JTCS_TO, nDestFieldIndex);

		pNewConnectionData->SetFieldType(JTCS_FROM, eSourceFieldType);
		pNewConnectionData->SetFieldType(JTCS_TO, eDestFieldType);

		pNewConnectionData->AppendConnLine( aSourceFieldName,aDestFieldName );

		OQueryTableConnection aNewConnection(this, aNewConnectionData);
		NotifyTabConnection(aNewConnection);
			// wie immer bei NotifyTabConnection ist das Verwenden lokaler Variablen unkritisch, da sowieso eine Kopie erzeugt wird
	}
	else
	{
		// the connection could point on the other side
		if(pConn->GetSourceWin() == pDestWin)
		{
			String aTmp(aSourceFieldName);
			aSourceFieldName = aDestFieldName;
			aDestFieldName = aTmp;
		}

		pConn->GetData()->AppendConnLine( aSourceFieldName,aDestFieldName );

		connectionModified(this,pConn,sal_False);
	}
}
// -----------------------------------------------------------------------------
void OQueryTableView::ConnDoubleClicked(OTableConnection* pConnection)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	if( openJoinDialog(this,pConnection->GetData(),sal_False) )
	{
		connectionModified(this,pConnection,sal_False);
		SelectConn( pConnection );
	}
}
// -----------------------------------------------------------------------------
void OQueryTableView::createNewConnection()
{
	TTableConnectionData::value_type pData(new OQueryTableConnectionData());
	if( openJoinDialog(this,pData,sal_True) )
	{
		OTableWindowMap* pMap = GetTabWinMap();
		OQueryTableWindow* pSourceWin	= static_cast< OQueryTableWindow*>((*pMap)[pData->getReferencingTable()->GetWinName()]);
		OQueryTableWindow* pDestWin		= static_cast< OQueryTableWindow*>((*pMap)[pData->getReferencedTable()->GetWinName()]);
		// first we have to look if the this connection already exists
		OTableConnection* pConn = GetTabConn(pSourceWin,pDestWin,true);
		sal_Bool bNew = sal_True;
		if ( pConn )
		{
			pConn->GetData()->CopyFrom( *pData );
			bNew = sal_False;
		}
		else
		{
			// create a new connection and append it
			OQueryTableConnection* pQConn = new OQueryTableConnection(this, pData);
			GetConnection(pQConn);
			pConn = pQConn;
		}
		connectionModified(this,pConn,bNew);
		if ( !bNew && pConn == GetSelectedConn() ) // our connection was selected before so we have to reselect it
			SelectConn( pConn );
	}
}
//------------------------------------------------------------------------------
bool OQueryTableView::RemoveConnection( OTableConnection* _pConnection,sal_Bool /*_bDelete*/ )
{
	DBG_CHKTHIS(OQueryTableView,NULL);

	// we don't want that our connection will be deleted, we put it in the undo manager
	bool bRet = OJoinTableView::RemoveConnection( _pConnection,sal_False);

	// add undo action
	addUndoAction(	this,
					new OQueryDelTabConnUndoAction(this),
					static_cast< OQueryTableConnection*>(_pConnection),
					sal_True);
	return bRet;
}

//------------------------------------------------------------------------------
void OQueryTableView::KeyInput( const KeyEvent& rEvt )
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	OJoinTableView::KeyInput( rEvt );
}

//------------------------------------------------------------------------------
OQueryTableWindow* OQueryTableView::FindTable(const String& rAliasName)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	DBG_ASSERT(rAliasName.Len(), "OQueryTableView::FindTable : der AliasName sollte nicht leer sein !");
		// (nicht dass es schadet, aber es ist sinnlos und weist vielleicht auf Fehler beim Aufrufer hin)
	OTableWindowMap::const_iterator aIter = GetTabWinMap()->find(rAliasName);
	if(aIter != GetTabWinMap()->end())
		return static_cast<OQueryTableWindow*>(aIter->second);
	return NULL;
}

//------------------------------------------------------------------------------
sal_Bool OQueryTableView::FindTableFromField(const String& rFieldName, OTableFieldDescRef& rInfo, sal_uInt16& rCnt)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	rCnt = 0;
	OTableWindowMap::const_iterator aIter = GetTabWinMap()->begin();
	OTableWindowMap::const_iterator aEnd  = GetTabWinMap()->end();
	for(;aIter != aEnd;++aIter)
	{
		if(static_cast<OQueryTableWindow*>(aIter->second)->ExistsField(rFieldName, rInfo))
			++rCnt;
	}

	return rCnt == 1;
}

//------------------------------------------------------------------------------
bool OQueryTableView::ContainsTabWin(const OTableWindow& rTabWin)
{
    OTableWindowMap* pTabWins = GetTabWinMap();
    DBG_ASSERT(pTabWins != NULL, "OQueryTableView::HideTabWin : habe keine TabWins !");

    OTableWindowMap::iterator aIter = pTabWins->begin();
    OTableWindowMap::iterator aEnd  = pTabWins->end();

    for ( ;aIter != aEnd ; ++aIter )
    {
        if ( aIter->second == &rTabWin )
        {
            return true;
        }
    }

    return false;
}

//------------------------------------------------------------------------------
void OQueryTableView::RemoveTabWin(OTableWindow* pTabWin)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	DBG_ASSERT(pTabWin != NULL, "OQueryTableView::RemoveTabWin : Fenster sollte ungleich NULL sein !");

    if(pTabWin && ContainsTabWin(*pTabWin)) // #122589# check if registered before deleting
    {
	    // mein Parent brauche ich, da es vom Loeschen erfahren soll
	    OQueryDesignView* pParent = static_cast<OQueryDesignView*>(getDesignView());

	    SfxUndoManager& rUndoMgr = m_pView->getController().GetUndoManager();
	    rUndoMgr.EnterListAction( String( ModuleRes(STR_QUERY_UNDO_TABWINDELETE) ), String() );

	    // Undo-Action anlegen
	    OQueryTabWinDelUndoAct* pUndoAction = new OQueryTabWinDelUndoAct(this);
	    pUndoAction->SetTabWin(static_cast< OQueryTableWindow*>(pTabWin));

	    // und Fenster verstecken
	    HideTabWin(static_cast< OQueryTableWindow*>(pTabWin), pUndoAction);

	    // Undo Actions und Loeschen der Felder in SelectionBrowseBox
	    pParent->TableDeleted( static_cast< OQueryTableWindowData*>(pTabWin->GetData().get())->GetAliasName() );

	    m_pView->getController().addUndoActionAndInvalidate( pUndoAction );
	    rUndoMgr.LeaveListAction();

	    if (m_lnkTabWinsChangeHandler.IsSet())
	    {
		    TabWinsChangeNotification aHint(TabWinsChangeNotification::AT_REMOVED_WIN, static_cast< OQueryTableWindow*>(pTabWin)->GetAliasName());
		    m_lnkTabWinsChangeHandler.Call(&aHint);
	    }

	    modified();
	    if ( m_pAccessible )
		    m_pAccessible->notifyAccessibleEvent(	AccessibleEventId::CHILD,
												    makeAny(pTabWin->GetAccessible()),
												    Any()
												    );
	}
}

//------------------------------------------------------------------------
void OQueryTableView::EnsureVisible(const OTableWindow* pWin)
{
	DBG_CHKTHIS(OQueryTableView,NULL);

	Invalidate(INVALIDATE_NOCHILDREN);
	OJoinTableView::EnsureVisible(pWin);
}

//------------------------------------------------------------------------
void OQueryTableView::GetConnection(OQueryTableConnection* pConn)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	// bei mir und dem Dokument einfuegen

	addConnection( pConn );
	// invalidieren (damit es neu gezeichnet wird)
	//	pConn->Invalidate();
}

//------------------------------------------------------------------------
void OQueryTableView::DropConnection(OQueryTableConnection* pConn)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	// Selektion beachten
	// bei mir und dem Dokument rausnehmen
	RemoveConnection( pConn ,sal_False);
}

//------------------------------------------------------------------------
void OQueryTableView::HideTabWin( OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction )
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	OTableWindowMap* pTabWins = GetTabWinMap();
	DBG_ASSERT(pTabWins != NULL, "OQueryTableView::HideTabWin : habe keine TabWins !");

	if (pTabWin)
	{
		// Fenster
		// die Position in seinen Daten speichern
		getDesignView()->SaveTabWinUIConfig(pTabWin);
			// (ich muss ueber das Parent gehen, da nur das die Position der Scrollbars kennt)
		// dann aus der Liste der TabWins raus und verstecken
        OTableWindowMap::iterator aIter = pTabWins->begin();
        OTableWindowMap::iterator aEnd  = pTabWins->end();
        for ( ;aIter != aEnd ; ++aIter )
            if ( aIter->second == pTabWin )
            {
                pTabWins->erase( aIter );
                break;
            }

		pTabWin->Hide();	// nicht zerstoeren, steht im Undo!!

		// die Daten zum TabWin muessen auch aus meiner Verantwortung entlassen werden
		TTableWindowData* pTabWinDataList = m_pView->getController().getTableWindowData();
		pTabWinDataList->erase( ::std::remove(pTabWinDataList->begin(),pTabWinDataList->end(),pTabWin->GetData()),pTabWinDataList->end());
			// NICHT loeschen, da ja das TabWin selber - das noch lebt - sie auch noch braucht
			// Entweder geht es irgendwann wieder in meine Verantwortung ueber, (ueber ShowTabWin), dann fuege ich
			// auch die Daten wieder ein, oder die Undo-Action, die im Augenblick die alleinige Verantwortung fuer das Fenster
			// und dessen Daten hat, wird zestoert, dann loescht es beides

		if (m_pLastFocusTabWin == pTabWin)
			m_pLastFocusTabWin = NULL;

		// Verbindungen, die zum Fenster gehoeren, einsammeln und der UndoAction uebergeben
		sal_Int16 nCnt = 0;
		const ::std::vector<OTableConnection*>* pTabConList = getTableConnections();
		::std::vector<OTableConnection*>::const_iterator aIter2 = pTabConList->begin();
		for(;aIter2 != pTabConList->end();)// the end may change
		{
			OQueryTableConnection* pTmpEntry = static_cast<OQueryTableConnection*>(*aIter2);
			OSL_ENSURE(pTmpEntry,"OQueryTableConnection is null!");
			if( pTmpEntry->GetAliasName(JTCS_FROM) == pTabWin->GetAliasName() ||
				pTmpEntry->GetAliasName(JTCS_TO) == pTabWin->GetAliasName() )
			{
				// add to undo list
				pUndoAction->InsertConnection(pTmpEntry);

				// call base class because we append an undo action
				// but this time we are in a undo action list
				OJoinTableView::RemoveConnection(pTmpEntry,sal_False);
                aIter2 = pTabConList->begin();
				++nCnt;
			}
			else
				++aIter2;
		}

		if (nCnt)
			InvalidateConnections();

		m_pView->getController().InvalidateFeature(ID_BROWSER_ADDTABLE);

		// der UndoAction sagen, dass das Fenster (inklusive der Connections) jetzt in seinem Besitzt ist
		pUndoAction->SetOwnership(sal_True);

		// damit habe ich das Doc natuerlich modifiziert
		m_pView->getController().setModified( sal_True );
		m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
	}
}

//------------------------------------------------------------------------
sal_Bool OQueryTableView::ShowTabWin( OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction,sal_Bool _bAppend )
{
	DBG_CHKTHIS(OQueryTableView,NULL);

	sal_Bool bSuccess = sal_False;

	if (pTabWin)
	{
		if (pTabWin->Init())
		{
			TTableWindowData::value_type pData = pTabWin->GetData();
			DBG_ASSERT( bool(pData), "OQueryTableView::ShowTabWin : TabWin hat keine Daten !");
			// Wenn die Daten schon PosSize haben, diese benutzen
			if (pData->HasPosition() && pData->HasSize())
			{
				Size aSize(CalcZoom(pData->GetSize().Width()),CalcZoom(pData->GetSize().Height()));
				pTabWin->SetPosSizePixel(pData->GetPosition(), aSize);
			}
			else
				// ansonsten selber eine Default-Position ermitteln
				SetDefaultTabWinPosSize(pTabWin);

			// Fenster zeigen und in Liste eintragen
			::rtl::OUString sName = static_cast< OQueryTableWindowData*>(pData.get())->GetAliasName();
			OSL_ENSURE(GetTabWinMap()->find(sName) == GetTabWinMap()->end(),"Alias name already in list!");
			GetTabWinMap()->insert(OTableWindowMap::value_type(sName,pTabWin));

			pTabWin->Show();

			pTabWin->Update();
				// Das Update ist notwendig, damit die Connections an dem Fenster richtig gezeichnet werden. Klingt absurd,
				// ich weiss. Aber die Listbox haelt sich intern ein Member, was bei ersten Zeichnen (nachdem die Listbox im Init
				// gerade neu gefuellt wurde) initialisiert wird, und genau dieses Member wird irgendwann benoetigt fuer
				// GetEntryPos, und dieses wiederum von der Connection, wenn sie ihren Ansatzpunkt am Fenster feststellen will.

			// die Connections
			::std::vector<OTableConnection*>* pTableCon = pUndoAction->GetTabConnList();
			::std::vector<OTableConnection*>::iterator aIter = pTableCon->begin();
			::std::vector<OTableConnection*>::iterator aEnd = pTableCon->end();

			for(;aIter != aEnd;++aIter)
				addConnection(*aIter); // add all connections from the undo action

			// each connection should invalidated inside addConnection so we don't need this here any longer
//			if ( !pOwnList->empty() )
//				InvalidateConnections();
			pTableCon->clear();

			// und die Daten des Fensters ebenfalls in Liste (des Docs)
			if(_bAppend)
				m_pView->getController().getTableWindowData()->push_back(pTabWin->GetData());

			m_pView->getController().InvalidateFeature(ID_BROWSER_ADDTABLE);

			// und der UndoAction sagen, dass das Fenster jetzt meine ist ...
			pUndoAction->SetOwnership(sal_False);

			bSuccess = sal_True;
		}
		else
		{
			//////////////////////////////////////////////////////////////////
			// Initialisierung fehlgeschlagen
			// (z.B. wenn Verbindung zur Datenbank in diesem Augenblick unterbrochen worden ist)
			pTabWin->clearListBox();
			delete pTabWin;
		}
	}

	// damit habe ich das Doc natuerlich modifiziert
	if(!m_pView->getController().isReadOnly())
		m_pView->getController().setModified( sal_True );

	m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY);

	return bSuccess;
}
//------------------------------------------------------------------------
void OQueryTableView::InsertField(const OTableFieldDescRef& rInfo)
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	DBG_ASSERT(getDesignView() != NULL, "OQueryTableView::InsertField : habe kein Parent !");
	static_cast<OQueryDesignView*>(getDesignView())->InsertField(rInfo);
}
//------------------------------------------------------------------------------
sal_Bool OQueryTableView::ExistsAVisitedConn(const OQueryTableWindow* pFrom) const
{
	DBG_CHKTHIS(OQueryTableView,NULL);
	const ::std::vector<OTableConnection*>* pList = getTableConnections();
	if (pList)
	{
		::std::vector<OTableConnection*>::const_iterator aIter = pList->begin();
		::std::vector<OTableConnection*>::const_iterator aEnd = pList->end();
		for(;aIter != aEnd;++aIter)
		{
			OQueryTableConnection* pTemp = static_cast<OQueryTableConnection*>(*aIter);
			if (pTemp->IsVisited() &&
				(pFrom == static_cast< OQueryTableWindow*>(pTemp->GetSourceWin()) || pFrom == static_cast< OQueryTableWindow*>(pTemp->GetDestWin())))
				return pTemp != NULL;
		}
	}

	return sal_False;
}
// -----------------------------------------------------------------------------
void OQueryTableView::onNoColumns_throw()
{
	String sError( ModuleRes( STR_STATEMENT_WITHOUT_RESULT_SET ) );
	::dbtools::throwSQLException( sError, ::dbtools::SQL_GENERAL_ERROR, NULL );
}
//------------------------------------------------------------------------------
bool OQueryTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& _pData) const
{
	OQueryTableConnectionData* pQueryData = static_cast<OQueryTableConnectionData*>(_pData.get());
	return pQueryData && (pQueryData->GetJoinType() == CROSS_JOIN);
}
// -----------------------------------------------------------------------------

/* vim: set noet sw=4 ts=4: */
