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: */
|