| /************************************************************** |
| * |
| * 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_dbaccess.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 tabe |
| 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 ownerhsip 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 invaldates 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 hav it's 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 exsits a key which this is refered 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 conenction 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); |
| } |
| // ----------------------------------------------------------------------------- |