LCOV - code coverage report
Current view: top level - dbaccess/source/ui/querydesign - QueryTableView.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 445 0.0 %
Date: 2012-08-25 Functions: 0 34 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 973 0.0 %

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

Generated by: LCOV version 1.10