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