1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26
27 #include "browserids.hxx"
28 #include "dbaccess_helpid.hrc"
29 #include "dbexchange.hxx"
30 #include "dbtreelistbox.hxx"
31 #include "dbtreemodel.hxx"
32 #include "dbtreeview.hxx"
33 #include "dbu_brw.hrc"
34 #include "dbu_reghelper.hxx"
35 #include "dbustrings.hrc"
36 #include "dlgsave.hxx"
37 #include "HtmlReader.hxx"
38 #include "imageprovider.hxx"
39 #include "listviewitems.hxx"
40 #include "QEnumTypes.hxx"
41 #include "RtfReader.hxx"
42 #include "sbagrid.hrc"
43 #include "sbagrid.hxx"
44 #include "sqlmessage.hxx"
45 #include "TokenWriter.hxx"
46 #include "UITools.hxx"
47 #include "unodatbr.hxx"
48 #include "WColumnSelect.hxx"
49 #include "WCopyTable.hxx"
50 #include "WCPage.hxx"
51 #include "WExtendPages.hxx"
52 #include "WNameMatch.hxx"
53
54 /** === begin UNO includes === **/
55 #include <com/sun/star/awt/LineEndFormat.hpp>
56 #include <com/sun/star/awt/LineEndFormat.hpp>
57 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
58 #include <com/sun/star/awt/TextAlign.hpp>
59 #include <com/sun/star/awt/VisualEffect.hpp>
60 #include <com/sun/star/beans/NamedValue.hpp>
61 #include <com/sun/star/beans/PropertyValue.hpp>
62 #include <com/sun/star/container/XNameContainer.hpp>
63 #include <com/sun/star/form/XForm.hpp>
64 #include <com/sun/star/form/XGridColumnFactory.hpp>
65 #include <com/sun/star/form/XLoadable.hpp>
66 #include <com/sun/star/form/XReset.hpp>
67 #include <com/sun/star/frame/FrameSearchFlag.hpp>
68 #include <com/sun/star/frame/XLayoutManager.hpp>
69 #include <com/sun/star/lang/DisposedException.hpp>
70 #include <com/sun/star/sdb/CommandType.hpp>
71 #include <com/sun/star/sdb/SQLContext.hpp>
72 #include <com/sun/star/sdb/XBookmarksSupplier.hpp>
73 #include <com/sun/star/sdb/XCompletedConnection.hpp>
74 #include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
75 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
76 #include <com/sun/star/sdb/XParametersSupplier.hpp>
77 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
78 #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
79 #include <com/sun/star/sdb/XResultSetAccess.hpp>
80 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
81 #include <com/sun/star/sdb/application/NamedDatabaseObject.hpp>
82 #include <com/sun/star/sdbc/ColumnValue.hpp>
83 #include <com/sun/star/sdbc/DataType.hpp>
84 #include <com/sun/star/sdbc/FetchDirection.hpp>
85 #include <com/sun/star/sdbc/SQLWarning.hpp>
86 #include <com/sun/star/sdbc/XDataSource.hpp>
87 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
88 #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
89 #include <com/sun/star/sdbcx/Privilege.hpp>
90 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
91 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
92 #include <com/sun/star/sdbcx/XDrop.hpp>
93 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
94 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
95 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
96 #include <com/sun/star/util/XFlushable.hpp>
97 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
98 #include <com/sun/star/document/MacroExecMode.hpp>
99 #include <com/sun/star/frame/XComponentLoader.hpp>
100 #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
101 /** === end UNO includes === **/
102
103 #include <comphelper/extract.hxx>
104 #include <comphelper/sequence.hxx>
105 #include <comphelper/types.hxx>
106 #include <connectivity/dbexception.hxx>
107 #include <cppuhelper/exc_hlp.hxx>
108 #include <cppuhelper/implbase2.hxx>
109 #include <cppuhelper/typeprovider.hxx>
110 #include <sfx2/app.hxx>
111 #include <sfx2/dispatch.hxx>
112 #include <sot/storage.hxx>
113 #include <svl/filenotation.hxx>
114 #include <svl/intitem.hxx>
115 #include <unotools/moduleoptions.hxx>
116 #include <svtools/svlbitm.hxx>
117 #include <svtools/svtreebx.hxx>
118 #include <svx/algitem.hxx>
119 #include <svx/dataaccessdescriptor.hxx>
120 #include <svx/databaseregistrationui.hxx>
121 #include <svx/gridctrl.hxx>
122 #include <toolkit/unohlp.hxx>
123 #include <tools/diagnose_ex.h>
124 #include <tools/multisel.hxx>
125 #include <tools/urlobj.hxx>
126 #include <unotools/confignode.hxx>
127 #include <vcl/msgbox.hxx>
128 #include <vcl/split.hxx>
129 #include <vcl/stdtext.hxx>
130 #include <vcl/svapp.hxx>
131 #include <vcl/toolbox.hxx>
132 #include <vcl/waitobj.hxx>
133 #include <vcl/wrkwin.hxx>
134 #include <rtl/logfile.hxx>
135
136 #include <memory>
137
138 using namespace ::com::sun::star::uno;
139 using namespace ::com::sun::star::awt;
140 using namespace ::com::sun::star::sdb;
141 using namespace ::com::sun::star::sdb::application;
142 using namespace ::com::sun::star::sdbc;
143 using namespace ::com::sun::star::sdbcx;
144 using namespace ::com::sun::star::beans;
145 using namespace ::com::sun::star::util;
146 using namespace ::com::sun::star::frame;
147 using namespace ::com::sun::star::container;
148 using namespace ::com::sun::star::lang;
149 using namespace ::com::sun::star::ui::dialogs;
150 using namespace ::com::sun::star::task;
151 using namespace ::com::sun::star::form;
152 using namespace ::com::sun::star::io;
153 using namespace ::com::sun::star::i18n;
154 using namespace ::com::sun::star::view;
155 using namespace ::com::sun::star::datatransfer;
156 using namespace ::com::sun::star::document;
157 using namespace ::com::sun::star::ui;
158 using namespace ::dbtools;
159 using namespace ::comphelper;
160 using namespace ::svx;
161
162 // .........................................................................
163 namespace dbaui
164 {
165 // .........................................................................
166
167 namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
168 namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer;
169
170 //==================================================================
171 //= SbaTableQueryBrowser
172 //==================================================================
173 // -------------------------------------------------------------------------
createRegistryInfo_OBrowser()174 extern "C" void SAL_CALL createRegistryInfo_OBrowser()
175 {
176 static OMultiInstanceAutoRegistration< SbaTableQueryBrowser > aAutoRegistration;
177 }
178 // -------------------------------------------------------------------------
SafeAddPropertyListener(const Reference<XPropertySet> & xSet,const::rtl::OUString & rPropName,XPropertyChangeListener * pListener)179 void SafeAddPropertyListener(const Reference< XPropertySet > & xSet, const ::rtl::OUString& rPropName, XPropertyChangeListener* pListener)
180 {
181 Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
182 if (xInfo->hasPropertyByName(rPropName))
183 xSet->addPropertyChangeListener(rPropName, pListener);
184 }
185
186 // -------------------------------------------------------------------------
SafeRemovePropertyListener(const Reference<XPropertySet> & xSet,const::rtl::OUString & rPropName,XPropertyChangeListener * pListener)187 void SafeRemovePropertyListener(const Reference< XPropertySet > & xSet, const ::rtl::OUString& rPropName, XPropertyChangeListener* pListener)
188 {
189 Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
190 if (xInfo->hasPropertyByName(rPropName))
191 xSet->removePropertyChangeListener(rPropName, pListener);
192 }
193 //-------------------------------------------------------------------------
getImplementationName()194 ::rtl::OUString SAL_CALL SbaTableQueryBrowser::getImplementationName() throw(RuntimeException)
195 {
196 return getImplementationName_Static();
197 }
198 //-------------------------------------------------------------------------
getSupportedServiceNames()199 ::comphelper::StringSequence SAL_CALL SbaTableQueryBrowser::getSupportedServiceNames() throw(RuntimeException)
200 {
201 return getSupportedServiceNames_Static();
202 }
203 // -------------------------------------------------------------------------
getImplementationName_Static()204 ::rtl::OUString SbaTableQueryBrowser::getImplementationName_Static() throw(RuntimeException)
205 {
206 return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.ODatasourceBrowser");
207 }
208 //-------------------------------------------------------------------------
getSupportedServiceNames_Static()209 ::comphelper::StringSequence SbaTableQueryBrowser::getSupportedServiceNames_Static() throw(RuntimeException)
210 {
211 ::comphelper::StringSequence aSupported(1);
212 aSupported.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.DataSourceBrowser");
213 return aSupported;
214 }
215 //-------------------------------------------------------------------------
Create(const Reference<XMultiServiceFactory> & _rxFactory)216 Reference< XInterface > SAL_CALL SbaTableQueryBrowser::Create(const Reference<XMultiServiceFactory >& _rxFactory)
217 {
218 ::vos::OGuard aGuard(Application::GetSolarMutex());
219 return *(new SbaTableQueryBrowser(_rxFactory));
220 }
221
222 DBG_NAME(SbaTableQueryBrowser);
223 //------------------------------------------------------------------------------
SbaTableQueryBrowser(const Reference<XMultiServiceFactory> & _rM)224 SbaTableQueryBrowser::SbaTableQueryBrowser(const Reference< XMultiServiceFactory >& _rM)
225 :SbaXDataBrowserController(_rM)
226 ,m_aSelectionListeners( getMutex() )
227 ,m_aContextMenuInterceptors( getMutex() )
228 ,m_aTableCopyHelper(this)
229 ,m_pTreeView(NULL)
230 ,m_pSplitter(NULL)
231 ,m_pTreeModel(NULL)
232 ,m_pCurrentlyDisplayed(NULL)
233 ,m_nAsyncDrop(0)
234 ,m_nBorder(1)
235 ,m_bQueryEscapeProcessing( sal_False )
236 ,m_bShowMenu(sal_False)
237 ,m_bInSuspend(sal_False)
238 ,m_bEnableBrowser(sal_True)
239 {
240 DBG_CTOR(SbaTableQueryBrowser,NULL);
241 }
242
243 //------------------------------------------------------------------------------
~SbaTableQueryBrowser()244 SbaTableQueryBrowser::~SbaTableQueryBrowser()
245 {
246 DBG_DTOR(SbaTableQueryBrowser,NULL);
247 if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
248 {
249 OSL_ENSURE(0,"Please check who doesn't dispose this component!");
250 // increment ref count to prevent double call of Dtor
251 osl_incrementInterlockedCount( &m_refCount );
252 dispose();
253 }
254 }
255
256 //------------------------------------------------------------------------------
queryInterface(const Type & _rType)257 Any SAL_CALL SbaTableQueryBrowser::queryInterface(const Type& _rType) throw (RuntimeException)
258 {
259 if ( _rType.equals( XScriptInvocationContext::static_type() ) )
260 {
261 OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::queryInterface: did not initialize this, yet!" );
262 if ( !!m_aDocScriptSupport && *m_aDocScriptSupport )
263 return makeAny( Reference< XScriptInvocationContext >( this ) );
264 return Any();
265 }
266
267 Any aReturn = SbaXDataBrowserController::queryInterface(_rType);
268 if (!aReturn.hasValue())
269 aReturn = SbaTableQueryBrowser_Base::queryInterface(_rType);
270 return aReturn;
271 }
272
273 //------------------------------------------------------------------------------
getTypes()274 Sequence< Type > SAL_CALL SbaTableQueryBrowser::getTypes( ) throw (RuntimeException)
275 {
276 Sequence< Type > aTypes( ::comphelper::concatSequences(
277 SbaXDataBrowserController::getTypes(),
278 SbaTableQueryBrowser_Base::getTypes()
279 ) );
280
281 OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::getTypes: did not initialize this, yet!" );
282 if ( !m_aDocScriptSupport || !*m_aDocScriptSupport )
283 {
284 Sequence< Type > aStrippedTypes( aTypes.getLength() - 1 );
285 ::std::remove_copy_if(
286 aTypes.getConstArray(),
287 aTypes.getConstArray() + aTypes.getLength(),
288 aStrippedTypes.getArray(),
289 ::std::bind2nd( ::std::equal_to< Type >(), XScriptInvocationContext::static_type() )
290 );
291 aTypes = aStrippedTypes;
292 }
293 return aTypes;
294 }
295
296 //------------------------------------------------------------------------------
getImplementationId()297 Sequence< sal_Int8 > SAL_CALL SbaTableQueryBrowser::getImplementationId( ) throw (RuntimeException)
298 {
299 static ::cppu::OImplementationId * pId = 0;
300 if (! pId)
301 {
302 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
303 if (! pId)
304 {
305 static ::cppu::OImplementationId aId;
306 pId = &aId;
307 }
308 }
309 return pId->getImplementationId();
310 }
311
312 //------------------------------------------------------------------------------
disposing()313 void SAL_CALL SbaTableQueryBrowser::disposing()
314 {
315 ::vos::OGuard aGuard(Application::GetSolarMutex());
316 // doin' a lot of VCL stuff here -> lock the SolarMutex
317
318 // kiss our listeners goodbye
319 EventObject aEvt(*this);
320 m_aSelectionListeners.disposeAndClear(aEvt);
321 m_aContextMenuInterceptors.disposeAndClear(aEvt);
322
323 // reset the content's tree view: it holds a reference to our model which is to be deleted immediately,
324 // and it will live longer than we do.
325 if (getBrowserView())
326 getBrowserView()->setTreeView(NULL);
327
328 clearTreeModel();
329 // clear the tree model
330 {
331 ::std::auto_ptr<SvLBoxTreeList> aTemp(m_pTreeModel);
332 m_pTreeModel = NULL;
333 }
334
335 // remove ourself as status listener
336 implRemoveStatusListeners();
337
338 // remove the container listener from the database context
339 try
340 {
341 Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
342 xDatabaseRegistrations->removeDatabaseRegistrationsListener( this );
343 }
344 catch( const Exception& )
345 {
346 DBG_UNHANDLED_EXCEPTION();
347 }
348
349 // check out from all the objects we are listening
350 // the frame
351 if (m_xCurrentFrameParent.is())
352 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
353 SbaXDataBrowserController::disposing();
354 }
355
356 //------------------------------------------------------------------------------
Construct(Window * pParent)357 sal_Bool SbaTableQueryBrowser::Construct(Window* pParent)
358 {
359 if ( !SbaXDataBrowserController::Construct( pParent ) )
360 return sal_False;
361
362 try
363 {
364 Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
365 xDatabaseRegistrations->addDatabaseRegistrationsListener( this );
366
367 // the collator for the string compares
368 m_xCollator = Reference< XCollator >( getORB()->createInstance(::rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ) ), UNO_QUERY_THROW );
369 m_xCollator->loadDefaultCollator( Application::GetSettings().GetLocale(), 0 );
370 }
371 catch(Exception&)
372 {
373 DBG_ERROR("SbaTableQueryBrowser::Construct: could not create (or start listening at) the database context!");
374 }
375 // some help ids
376 if (getBrowserView() && getBrowserView()->getVclControl())
377 {
378
379 // create controls and set sizes
380 const long nFrameWidth = getBrowserView()->LogicToPixel( ::Size( 3, 0 ), MAP_APPFONT ).Width();
381
382 m_pSplitter = new Splitter(getBrowserView(),WB_HSCROLL);
383 m_pSplitter->SetPosSizePixel( ::Point(0,0), ::Size(nFrameWidth,0) );
384 m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) );
385
386 m_pTreeView = new DBTreeView(getBrowserView(),getORB(), WB_TABSTOP | WB_BORDER);
387 m_pTreeView->SetPreExpandHandler(LINK(this, SbaTableQueryBrowser, OnExpandEntry));
388
389 m_pTreeView->setCopyHandler(LINK(this, SbaTableQueryBrowser, OnCopyEntry));
390
391 m_pTreeView->getListBox().setContextMenuProvider( this );
392 m_pTreeView->getListBox().setControlActionListener( this );
393 m_pTreeView->SetHelpId(HID_CTL_TREEVIEW);
394
395 // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide
396 m_pSplitter->SetSplitPosPixel( getBrowserView()->LogicToPixel( ::Size( 80, 0 ), MAP_APPFONT ).Width() );
397
398 getBrowserView()->setSplitter(m_pSplitter);
399 getBrowserView()->setTreeView(m_pTreeView);
400
401 // fill view with data
402 m_pTreeModel = new SvLBoxTreeList;
403 m_pTreeModel->SetSortMode(SortAscending);
404 m_pTreeModel->SetCompareHdl(LINK(this, SbaTableQueryBrowser, OnTreeEntryCompare));
405 m_pTreeView->setModel(m_pTreeModel);
406 m_pTreeView->setSelChangeHdl( LINK( this, SbaTableQueryBrowser, OnSelectionChange ) );
407
408 // TODO
409 getBrowserView()->getVclControl()->GetDataWindow().SetUniqueId(UID_DATABROWSE_DATAWINDOW);
410 getBrowserView()->getVclControl()->SetHelpId(HID_CTL_TABBROWSER);
411 getBrowserView()->SetUniqueId(UID_CTL_CONTENT);
412 if (getBrowserView()->getVclControl()->GetHeaderBar())
413 getBrowserView()->getVclControl()->GetHeaderBar()->SetHelpId(HID_DATABROWSE_HEADER);
414 InvalidateFeature(ID_BROWSER_EXPLORER);
415 }
416
417 return sal_True;
418 }
419 // ---------------------------------------------------------------------------------------------------------------------
420 namespace
421 {
422 // -----------------------------------------------------------------------------------------------------------------
423 struct SelectValueByName : public ::std::unary_function< ::rtl::OUString, Any >
424 {
operator ()dbaui::__anon6c5776a60111::SelectValueByName425 const Any& operator()( ::rtl::OUString const& i_name ) const
426 {
427 return m_rCollection.get( i_name );
428 }
429
SelectValueByNamedbaui::__anon6c5776a60111::SelectValueByName430 SelectValueByName( ::comphelper::NamedValueCollection const& i_collection )
431 :m_rCollection( i_collection )
432 {
433 }
434
435 ::comphelper::NamedValueCollection const& m_rCollection;
436 };
437 }
438
439 // ---------------------------------------------------------------------------------------------------------------------
impl_sanitizeRowSetClauses_nothrow()440 void SbaTableQueryBrowser::impl_sanitizeRowSetClauses_nothrow()
441 {
442 try
443 {
444 Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
445 sal_Bool bEscapeProcessing = sal_False;
446 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
447 if ( !bEscapeProcessing )
448 // don't touch or interpret anything if escape processing is disabled
449 return;
450
451 Reference< XSingleSelectQueryComposer > xComposer( createParser_nothrow() );
452 if ( !xComposer.is() )
453 // can't do anything. Already reported via assertion in createParser_nothrow.
454 return;
455
456 // the tables participating in the statement
457 const Reference< XTablesSupplier > xSuppTables( xComposer, UNO_QUERY_THROW );
458 const Reference< XNameAccess > xTableNames( xSuppTables->getTables(), UNO_QUERY_THROW );
459
460 // the columns participating in the statement
461 const Reference< XColumnsSupplier > xSuppColumns( xComposer, UNO_QUERY_THROW );
462 const Reference< XNameAccess > xColumnNames( xSuppColumns->getColumns(), UNO_QUERY_THROW );
463
464 // .............................................................................................................
465 // check if the order columns apply to tables which really exist in the statement
466 const Reference< XIndexAccess > xOrderColumns( xComposer->getOrderColumns(), UNO_SET_THROW );
467 const sal_Int32 nOrderColumns( xOrderColumns->getCount() );
468 bool invalidColumn = nOrderColumns == 0;
469 for ( sal_Int32 c=0; ( c < nOrderColumns ) && !invalidColumn; ++c )
470 {
471 const Reference< XPropertySet > xOrderColumn( xOrderColumns->getByIndex(c), UNO_QUERY_THROW );
472 ::rtl::OUString sTableName;
473 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName );
474 ::rtl::OUString sColumnName;
475 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName );
476
477 if ( sTableName.getLength() == 0 )
478 {
479 if ( !xColumnNames->hasByName( sColumnName ) )
480 {
481 invalidColumn = true;
482 break;
483 }
484 }
485 else
486 {
487 if ( !xTableNames->hasByName( sTableName ) )
488 {
489 invalidColumn = true;
490 break;
491 }
492
493 const Reference< XColumnsSupplier > xSuppTableColumns( xTableNames->getByName( sTableName ), UNO_QUERY_THROW );
494 const Reference< XNameAccess > xTableColumnNames( xSuppTableColumns->getColumns(), UNO_QUERY_THROW );
495 if ( !xTableColumnNames->hasByName( sColumnName ) )
496 {
497 invalidColumn = true;
498 break;
499 }
500 }
501 }
502
503 if ( invalidColumn )
504 {
505 // reset the complete order statement at both the row set and the parser
506 const ::rtl::OUString sEmptyOrder;
507 xRowSetProps->setPropertyValue( PROPERTY_ORDER, makeAny( sEmptyOrder ) );
508 xComposer->setOrder( sEmptyOrder );
509 }
510
511 // .............................................................................................................
512 // check if the columns participating in the filter refer to existing tables
513 // TODO: there's no API at all for this. The method which comes nearest to what we need is
514 // "getStructuredFilter", but it returns pure column names only. That is, for a statement like
515 // "SELECT * FROM <table> WHERE <other_table>.<column> = <value>", it will return "<column>". But
516 // there's no API at all to retrieve the information about "<other_table>" - which is what would
517 // be needed here.
518 // That'd be a chance to replace getStructuredFilter with something more reasonable. This method
519 // has at least one other problem: For a clause like "<column> != <value>", it will return "<column>"
520 // as column name, "NOT_EQUAL" as operator, and "!= <value>" as value, effectively duplicating the
521 // information about the operator, and beding all clients to manually remove the "!=" from the value
522 // string.
523 // So, what really would be handy, is some
524 // XNormalizedFilter getNormalizedFilter();
525 // with
526 // interface XDisjunctiveFilterExpression
527 // {
528 // XConjunctiveFilterTerm getTerm( int index );
529 // }
530 // interface XConjunctiveFilterTerm
531 // {
532 // ComparisonPredicate getPredicate( int index );
533 // }
534 // struct ComparisonPredicate
535 // {
536 // XComparisonOperand Lhs;
537 // SQLFilterOperator Operator;
538 // XComparisonOperand Rhs;
539 // }
540 // interface XComparisonOperand
541 // {
542 // SQLFilterOperand Type;
543 // XPropertySet getColumn();
544 // string getLiteral();
545 // ...
546 // }
547 // enum SQLFilterOperand { Column, Literal, ... }
548 //
549 // ... or something like this ....
550 }
551 catch( const Exception& )
552 {
553 DBG_UNHANDLED_EXCEPTION();
554 }
555 }
556
557 // ---------------------------------------------------------------------------------------------------------------------
InitializeForm(const Reference<XPropertySet> & i_formProperties)558 sal_Bool SbaTableQueryBrowser::InitializeForm( const Reference< XPropertySet > & i_formProperties )
559 {
560 if(!m_pCurrentlyDisplayed)
561 return sal_True;
562
563 // this method set all format settings from the orignal table or query
564 try
565 {
566 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
567 ENSURE_OR_RETURN_FALSE( pData, "SbaTableQueryBrowser::InitializeForm: No user data set at the currently displayed entry!" );
568 ENSURE_OR_RETURN_FALSE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeForm: No table available!" );
569
570 Reference< XPropertySetInfo > xPSI( pData->xObjectProperties->getPropertySetInfo(), UNO_SET_THROW );
571
572 ::comphelper::NamedValueCollection aPropertyValues;
573
574 const ::rtl::OUString aTransferProperties[] =
575 {
576 PROPERTY_APPLYFILTER,
577 PROPERTY_FILTER,
578 PROPERTY_HAVING_CLAUSE,
579 PROPERTY_ORDER
580 };
581 for ( size_t i=0; i < sizeof( aTransferProperties ) / sizeof( aTransferProperties[0] ); ++i )
582 {
583 if ( !xPSI->hasPropertyByName( aTransferProperties[i] ) )
584 continue;
585 aPropertyValues.put( aTransferProperties[i], pData->xObjectProperties->getPropertyValue( aTransferProperties[i] ) );
586 }
587
588 const ::std::vector< ::rtl::OUString > aNames( aPropertyValues.getNames() );
589 Sequence< ::rtl::OUString > aPropNames( aNames.size() );
590 ::std::copy( aNames.begin(), aNames.end(), aPropNames.getArray() );
591
592 Sequence< Any > aPropValues( aNames.size() );
593 ::std::transform( aNames.begin(), aNames.end(), aPropValues.getArray(), SelectValueByName( aPropertyValues ) );
594
595 Reference< XMultiPropertySet > xFormMultiSet( i_formProperties, UNO_QUERY_THROW );
596 xFormMultiSet->setPropertyValues( aPropNames, aPropValues );
597
598 impl_sanitizeRowSetClauses_nothrow();
599 }
600 catch ( const Exception& )
601 {
602 DBG_UNHANDLED_EXCEPTION();
603 return sal_False;
604 }
605
606 return sal_True;
607 }
608
609 //------------------------------------------------------------------------------
initializePreviewMode()610 void SbaTableQueryBrowser::initializePreviewMode()
611 {
612 if ( getBrowserView() && getBrowserView()->getVclControl() )
613 {
614 getBrowserView()->getVclControl()->AlwaysEnableInput( sal_False );
615 getBrowserView()->getVclControl()->EnableInput( sal_False );
616 getBrowserView()->getVclControl()->ForceHideScrollbars( sal_True );
617 }
618 Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY);
619 if ( xDataSourceSet.is() )
620 {
621 xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowInserts")),makeAny(sal_False));
622 xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowUpdates")),makeAny(sal_False));
623 xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowDeletes")),makeAny(sal_False));
624 }
625 }
626
627 //------------------------------------------------------------------------------
InitializeGridModel(const Reference<::com::sun::star::form::XFormComponent> & xGrid)628 sal_Bool SbaTableQueryBrowser::InitializeGridModel(const Reference< ::com::sun::star::form::XFormComponent > & xGrid)
629 {
630 try
631 {
632 Reference< ::com::sun::star::form::XGridColumnFactory > xColFactory(xGrid, UNO_QUERY);
633 Reference< XNameContainer > xColContainer(xGrid, UNO_QUERY);
634 clearGridColumns( xColContainer );
635
636 Reference< XChild > xGridAsChild(xGrid, UNO_QUERY);
637 Reference< XLoadable > xFormAsLoadable;
638 if (xGridAsChild.is())
639 xFormAsLoadable = xFormAsLoadable.query(xGridAsChild->getParent());
640 if (xFormAsLoadable.is() && xFormAsLoadable->isLoaded())
641 {
642 // set the formats from the table
643 if(m_pCurrentlyDisplayed)
644 {
645 Sequence< ::rtl::OUString> aProperties(6 + ( m_bPreview ? 5 : 0 ));
646 Sequence< Any> aValues(7 + ( m_bPreview ? 5 : 0 ));
647
648 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
649 OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeGridModel: No table available!" );
650 if ( !pData->xObjectProperties.is() )
651 return sal_False;
652
653 ::rtl::OUString* pStringIter = aProperties.getArray();
654 Any* pValueIter = aValues.getArray();
655 if ( m_bPreview )
656 {
657 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlwaysShowCursor"));
658 *pValueIter++ <<= sal_False;
659 *pStringIter++ = PROPERTY_BORDER;
660 *pValueIter++ <<= sal_Int16(0);
661 }
662
663 *pStringIter++ = PROPERTY_FONT;
664 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_FONT);
665 *pStringIter++ = PROPERTY_TEXTEMPHASIS;
666 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTEMPHASIS);
667 *pStringIter++ = PROPERTY_TEXTRELIEF;
668 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTRELIEF);
669 if ( m_bPreview )
670 {
671 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasNavigationBar"));
672 *pValueIter++ <<= sal_False;
673 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasRecordMarker"));
674 *pValueIter++ <<= sal_False;
675 }
676 *pStringIter++ = PROPERTY_ROW_HEIGHT;
677 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_ROW_HEIGHT);
678 if ( m_bPreview )
679 {
680 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tabstop"));
681 *pValueIter++ <<= sal_False;
682 }
683 *pStringIter++ = PROPERTY_TEXTCOLOR;
684 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTCOLOR);
685 *pStringIter++ = PROPERTY_TEXTLINECOLOR;
686 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTLINECOLOR);
687
688 Reference< XMultiPropertySet > xFormMultiSet(xGrid, UNO_QUERY);
689 xFormMultiSet->setPropertyValues(aProperties, aValues);
690 }
691
692
693 // get the formats supplier of the database we're working with
694 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier = getNumberFormatter()->getNumberFormatsSupplier();
695
696 Reference<XConnection> xConnection;
697 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
698 xRowSetProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
699 OSL_ENSURE(xConnection.is(),"A ActiveConnection should normaly exists!");
700
701 Reference<XChild> xChild(xConnection,UNO_QUERY);
702 Reference<XPropertySet> xDataSourceProp(xChild->getParent(),UNO_QUERY);
703 sal_Bool bSuppressVersionCol = sal_False;
704 OSL_VERIFY( xDataSourceProp->getPropertyValue( PROPERTY_SUPPRESSVERSIONCL ) >>= bSuppressVersionCol );
705
706 // insert the column into the gridcontrol so that we see something :-)
707 ::rtl::OUString aCurrentModelType;
708 Reference<XColumnsSupplier> xSupCols(getRowSet(),UNO_QUERY);
709 Reference<XNameAccess> xColumns = xSupCols->getColumns();
710 Sequence< ::rtl::OUString> aNames = xColumns->getElementNames();
711 const ::rtl::OUString* pIter = aNames.getConstArray();
712 const ::rtl::OUString* pEnd = pIter + aNames.getLength();
713
714 ::rtl::OUString sDefaultProperty;
715 Reference< XPropertySet > xColumn;
716 Reference< XPropertySetInfo > xColPSI;
717 for (sal_uInt16 i=0; pIter != pEnd; ++i,++pIter)
718 {
719 xColumn.set( xColumns->getByName( *pIter ), UNO_QUERY_THROW );
720 xColPSI.set( xColumn->getPropertySetInfo(), UNO_SET_THROW );
721
722 // ignore the column when it is a rowversion one
723 if ( bSuppressVersionCol
724 && xColPSI->hasPropertyByName( PROPERTY_ISROWVERSION )
725 && ::cppu::any2bool( xColumn->getPropertyValue( PROPERTY_ISROWVERSION ) )
726 )
727 continue;
728
729 // use the result set column's type to determine the type of grid column to create
730 sal_Bool bFormattedIsNumeric = sal_True;
731 sal_Int32 nType = ::comphelper::getINT32( xColumn->getPropertyValue( PROPERTY_TYPE ) );
732
733 ::std::vector< NamedValue > aInitialValues;
734 ::std::vector< ::rtl::OUString > aCopyProperties;
735 Any aDefault;
736
737 switch(nType)
738 {
739 case DataType::BIT:
740 case DataType::BOOLEAN:
741 {
742 aCurrentModelType = ::rtl::OUString::createFromAscii("CheckBox");
743 aInitialValues.push_back( NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualEffect" ) ), makeAny( VisualEffect::FLAT ) ) );
744 sDefaultProperty = PROPERTY_DEFAULTSTATE;
745
746 sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
747 OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable );
748 aInitialValues.push_back( NamedValue(
749 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TriState" ) ),
750 makeAny( sal_Bool( ColumnValue::NO_NULLS != nNullable ) )
751 ) );
752 if ( ColumnValue::NO_NULLS == nNullable )
753 aDefault <<= (sal_Int16)STATE_NOCHECK;
754 }
755 break;
756
757 case DataType::LONGVARCHAR:
758 case DataType::CLOB:
759 aInitialValues.push_back( NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiLine" ) ), makeAny( (sal_Bool)sal_True ) ) );
760 // NO break!
761 case DataType::BINARY:
762 case DataType::VARBINARY:
763 case DataType::LONGVARBINARY:
764 aCurrentModelType = ::rtl::OUString::createFromAscii("TextField");
765 sDefaultProperty = PROPERTY_DEFAULTTEXT;
766 break;
767
768 case DataType::VARCHAR:
769 case DataType::CHAR:
770 bFormattedIsNumeric = sal_False;
771 // NO break!
772 default:
773 aCurrentModelType = ::rtl::OUString::createFromAscii("FormattedField");
774 sDefaultProperty = PROPERTY_EFFECTIVEDEFAULT;
775
776 if ( xSupplier.is() )
777 aInitialValues.push_back( NamedValue( ::rtl::OUString::createFromAscii( "FormatsSupplier" ), makeAny( xSupplier ) ) );
778 aInitialValues.push_back( NamedValue( ::rtl::OUString::createFromAscii( "TreatAsNumber" ), makeAny( (sal_Bool)bFormattedIsNumeric ) ) );
779 aCopyProperties.push_back( PROPERTY_FORMATKEY );
780 break;
781 }
782
783 aInitialValues.push_back( NamedValue( PROPERTY_CONTROLSOURCE, makeAny( *pIter ) ) );
784 ::rtl::OUString sLabel;
785 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
786 if ( sLabel.getLength() )
787 aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( sLabel ) ) );
788 else
789 aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( *pIter ) ) );
790
791 Reference< XPropertySet > xGridCol( xColFactory->createColumn( aCurrentModelType ), UNO_SET_THROW );
792 Reference< XPropertySetInfo > xGridColPSI( xGridCol->getPropertySetInfo(), UNO_SET_THROW );
793
794 // calculate the default
795 if ( xGridColPSI->hasPropertyByName( PROPERTY_CONTROLDEFAULT ) )
796 {
797 aDefault = xColumn->getPropertyValue( PROPERTY_CONTROLDEFAULT );
798 // default value
799 if ( nType == DataType::BIT || nType == DataType::BOOLEAN )
800 {
801 if ( aDefault.hasValue() )
802 aDefault <<= (comphelper::getString(aDefault).toInt32() == 0) ? (sal_Int16)STATE_NOCHECK : (sal_Int16)STATE_CHECK;
803 else
804 aDefault <<= ((sal_Int16)STATE_DONTKNOW);
805 }
806 }
807
808 if ( aDefault.hasValue() )
809 aInitialValues.push_back( NamedValue( sDefaultProperty, aDefault ) );
810
811 // transfer properties from the definition to the UNO-model :
812 aCopyProperties.push_back( PROPERTY_HIDDEN );
813 aCopyProperties.push_back( PROPERTY_WIDTH );
814
815 // help text to display for the column
816 Any aDescription;
817 if ( xColPSI->hasPropertyByName( PROPERTY_HELPTEXT ) )
818 aDescription = xColumn->getPropertyValue( PROPERTY_HELPTEXT );
819 ::rtl::OUString sTemp;
820 aDescription >>= sTemp;
821 if ( !sTemp.getLength() )
822 xColumn->getPropertyValue( PROPERTY_DESCRIPTION ) >>= sTemp;
823
824 aDescription <<= sTemp;
825 aInitialValues.push_back( NamedValue( PROPERTY_HELPTEXT, aDescription ) );
826
827 // ... horizontal justify
828 Any aAlign; aAlign <<= sal_Int16( 0 );
829 Any aColAlign( xColumn->getPropertyValue( PROPERTY_ALIGN ) );
830 if ( aColAlign.hasValue() )
831 aAlign <<= sal_Int16( ::comphelper::getINT32( aColAlign ) );
832 aInitialValues.push_back( NamedValue( PROPERTY_ALIGN, aAlign ) );
833
834 // don't allow the mouse to scroll in the cells
835 if ( xGridColPSI->hasPropertyByName( PROPERTY_MOUSE_WHEEL_BEHAVIOR ) )
836 aInitialValues.push_back( NamedValue( PROPERTY_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) ) );
837
838 // now set all those values
839 for ( ::std::vector< NamedValue >::const_iterator property = aInitialValues.begin();
840 property != aInitialValues.end();
841 ++property
842 )
843 {
844 xGridCol->setPropertyValue( property->Name, property->Value );
845 }
846 for ( ::std::vector< ::rtl::OUString >::const_iterator copyPropertyName = aCopyProperties.begin();
847 copyPropertyName != aCopyProperties.end();
848 ++copyPropertyName
849 )
850 xGridCol->setPropertyValue( *copyPropertyName, xColumn->getPropertyValue( *copyPropertyName ) );
851
852 xColContainer->insertByName(*pIter, makeAny(xGridCol));
853 }
854 }
855 }
856 catch(Exception&)
857 {
858 DBG_UNHANDLED_EXCEPTION();
859 return sal_False;
860 }
861
862 return sal_True;
863 }
864 // -----------------------------------------------------------------------------
getColumnHelper(SvLBoxEntry * _pCurrentlyDisplayed,const Reference<XPropertySet> & _rxSource)865 Reference<XPropertySet> getColumnHelper(SvLBoxEntry* _pCurrentlyDisplayed,const Reference<XPropertySet>& _rxSource)
866 {
867 Reference<XPropertySet> xRet;
868 if(_pCurrentlyDisplayed)
869 {
870 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pCurrentlyDisplayed->GetUserData());
871 Reference<XColumnsSupplier> xColumnsSup(pData->xObjectProperties,UNO_QUERY);
872 Reference<XNameAccess> xNames = xColumnsSup->getColumns();
873 ::rtl::OUString aName;
874 _rxSource->getPropertyValue(PROPERTY_NAME) >>= aName;
875 if(xNames.is() && xNames->hasByName(aName))
876 xRet.set(xNames->getByName(aName),UNO_QUERY);
877 }
878 return xRet;
879 }
880
881 // -----------------------------------------------------------------------
transferChangedControlProperty(const::rtl::OUString & _rProperty,const Any & _rNewValue)882 void SbaTableQueryBrowser::transferChangedControlProperty(const ::rtl::OUString& _rProperty, const Any& _rNewValue)
883 {
884 if(m_pCurrentlyDisplayed)
885 {
886 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
887 Reference< XPropertySet > xObjectProps(pData->xObjectProperties, UNO_QUERY);
888 OSL_ENSURE(xObjectProps.is(),"SbaTableQueryBrowser::transferChangedControlProperty: no table/query object!");
889 if (xObjectProps.is())
890 xObjectProps->setPropertyValue(_rProperty, _rNewValue);
891 }
892 }
893
894 // -----------------------------------------------------------------------
propertyChange(const PropertyChangeEvent & evt)895 void SbaTableQueryBrowser::propertyChange(const PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException)
896 {
897 SbaXDataBrowserController::propertyChange(evt);
898
899 try
900 {
901 Reference< XPropertySet > xSource(evt.Source, UNO_QUERY);
902 if (!xSource.is())
903 return;
904
905 // one of the many properties which require us to update the definition ?
906 // a column's width ?
907 else if (evt.PropertyName.equals(PROPERTY_WIDTH))
908 { // a column width has changed -> update the model
909 // (the update of the view is done elsewhere)
910 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
911 if(xProp.is())
912 {
913 if(!evt.NewValue.hasValue())
914 xProp->setPropertyValue(PROPERTY_WIDTH,makeAny((sal_Int32)227));
915 else
916 xProp->setPropertyValue(PROPERTY_WIDTH,evt.NewValue);
917 }
918 }
919
920 // a column's 'visible' state ?
921 else if (evt.PropertyName.equals(PROPERTY_HIDDEN))
922 {
923 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
924 if(xProp.is())
925 xProp->setPropertyValue(PROPERTY_HIDDEN,evt.NewValue);
926 }
927
928 // a columns alignment ?
929 else if (evt.PropertyName.equals(PROPERTY_ALIGN))
930 {
931 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
932 try
933 {
934 if(xProp.is())
935 {
936 if(evt.NewValue.hasValue())
937 {
938 sal_Int16 nAlign = 0;
939 if(evt.NewValue >>= nAlign)
940 xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(sal_Int32(nAlign)));
941 else
942 xProp->setPropertyValue(PROPERTY_ALIGN,evt.NewValue);
943 }
944 else
945 xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(::com::sun::star::awt::TextAlign::LEFT));
946 }
947 }
948 catch( const Exception& )
949 {
950 DBG_UNHANDLED_EXCEPTION();
951 }
952 }
953
954 // a column's format ?
955 else if ( (evt.PropertyName.equals(PROPERTY_FORMATKEY))
956 && (TypeClass_LONG == evt.NewValue.getValueTypeClass())
957 )
958 {
959 // update the model (means the definition object)
960 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
961 if(xProp.is())
962 xProp->setPropertyValue(PROPERTY_FORMATKEY,evt.NewValue);
963 }
964
965 // some table definition properties ?
966 // the height of the rows in the grid ?
967 else if (evt.PropertyName.equals(PROPERTY_ROW_HEIGHT))
968 {
969 if(m_pCurrentlyDisplayed)
970 {
971 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
972 OSL_ENSURE( pData->xObjectProperties.is(), "No table available!" );
973
974 sal_Bool bDefault = !evt.NewValue.hasValue();
975 if (bDefault)
976 pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,makeAny((sal_Int32)45));
977 else
978 pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,evt.NewValue);
979 }
980 }
981
982 else if ( evt.PropertyName.equals(PROPERTY_FONT) // the font ?
983 || evt.PropertyName.equals(PROPERTY_TEXTCOLOR) // the text color ?
984 || evt.PropertyName.equals(PROPERTY_FILTER) // the filter ?
985 || evt.PropertyName.equals(PROPERTY_HAVING_CLAUSE) // the having clause ?
986 || evt.PropertyName.equals(PROPERTY_ORDER) // the sort ?
987 || evt.PropertyName.equals(PROPERTY_APPLYFILTER) // the appliance of the filter ?
988 || evt.PropertyName.equals(PROPERTY_TEXTLINECOLOR) // the text line color ?
989 || evt.PropertyName.equals(PROPERTY_TEXTEMPHASIS) // the text emphasis ?
990 || evt.PropertyName.equals(PROPERTY_TEXTRELIEF) // the text relief ?
991 )
992 {
993 transferChangedControlProperty(evt.PropertyName, evt.NewValue);
994 }
995 }
996 catch( const Exception& )
997 {
998 DBG_UNHANDLED_EXCEPTION();
999 }
1000 }
1001
1002 // -----------------------------------------------------------------------
suspend(sal_Bool bSuspend)1003 sal_Bool SbaTableQueryBrowser::suspend(sal_Bool bSuspend) throw( RuntimeException )
1004 {
1005 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1006 ::osl::MutexGuard aGuard( getMutex() );
1007 if ( getView() && getView()->IsInModalMode() )
1008 return sal_False;
1009 sal_Bool bRet = sal_False;
1010 if ( !m_bInSuspend )
1011 {
1012 m_bInSuspend = sal_True;
1013 if ( rBHelper.bDisposed )
1014 throw DisposedException( ::rtl::OUString(), *this );
1015
1016 bRet = SbaXDataBrowserController::suspend(bSuspend);
1017 if ( bRet && getView() )
1018 getView()->Hide();
1019
1020 m_bInSuspend = sal_False;
1021 }
1022
1023 return bRet;
1024 }
1025
1026 // -------------------------------------------------------------------------
statusChanged(const FeatureStateEvent & _rEvent)1027 void SAL_CALL SbaTableQueryBrowser::statusChanged( const FeatureStateEvent& _rEvent ) throw(RuntimeException)
1028 {
1029 // search the external dispatcher causing this call
1030 Reference< XDispatch > xSource(_rEvent.Source, UNO_QUERY);
1031 ExternalFeaturesMap::iterator aLoop;
1032 for ( aLoop = m_aExternalFeatures.begin();
1033 aLoop != m_aExternalFeatures.end();
1034 ++aLoop
1035 )
1036 {
1037 if ( _rEvent.FeatureURL.Complete == aLoop->second.aURL.Complete)
1038 {
1039 DBG_ASSERT( xSource.get() == aLoop->second.xDispatcher.get(), "SbaTableQueryBrowser::statusChanged: inconsistent!" );
1040 // update the enabled state
1041 aLoop->second.bEnabled = _rEvent.IsEnabled;
1042
1043 switch ( aLoop->first )
1044 {
1045 case ID_BROWSER_DOCUMENT_DATASOURCE:
1046 {
1047 // if it's the slot for the document data source, remember the state
1048 Sequence< PropertyValue > aDescriptor;
1049 #if OSL_DEBUG_LEVEL > 0
1050 sal_Bool bProperFormat =
1051 #endif
1052 _rEvent.State >>= aDescriptor;
1053 OSL_ENSURE(bProperFormat, "SbaTableQueryBrowser::statusChanged: need a data access descriptor here!");
1054 m_aDocumentDataSource.initializeFrom(aDescriptor);
1055
1056 OSL_ENSURE( ( m_aDocumentDataSource.has(daDataSource)
1057 || m_aDocumentDataSource.has(daDatabaseLocation)
1058 )
1059 && m_aDocumentDataSource.has(daCommand)
1060 && m_aDocumentDataSource.has(daCommandType),
1061 "SbaTableQueryBrowser::statusChanged: incomplete descriptor!");
1062
1063 // check if we know the object which is set as document data source
1064 checkDocumentDataSource();
1065 }
1066 break;
1067
1068 default:
1069 // update the toolbox
1070 implCheckExternalSlot( aLoop->first );
1071 break;
1072 }
1073 break;
1074 }
1075 }
1076
1077 DBG_ASSERT(aLoop != m_aExternalFeatures.end(), "SbaTableQueryBrowser::statusChanged: don't know who sent this!");
1078 }
1079
1080 // -------------------------------------------------------------------------
checkDocumentDataSource()1081 void SbaTableQueryBrowser::checkDocumentDataSource()
1082 {
1083 SvLBoxEntry* pDataSourceEntry = NULL;
1084 SvLBoxEntry* pContainerEntry = NULL;
1085 SvLBoxEntry* pObjectEntry = getObjectEntry( m_aDocumentDataSource, &pDataSourceEntry, &pContainerEntry, sal_False );
1086 sal_Bool bKnownDocDataSource = (NULL != pObjectEntry);
1087 if (!bKnownDocDataSource)
1088 {
1089 if (NULL != pDataSourceEntry)
1090 { // at least the data source is know
1091 if (NULL != pContainerEntry)
1092 bKnownDocDataSource = sal_True; // assume we know it.
1093 // TODO: should we expand the object container? This may be too expensive just for checking ....
1094 else
1095 {
1096 if ((NULL == pObjectEntry) && m_aDocumentDataSource.has(daCommandType) && m_aDocumentDataSource.has(daCommand))
1097 { // maybe we have a command to be displayed ?
1098 sal_Int32 nCommandType = CommandType::TABLE;
1099 m_aDocumentDataSource[daCommandType] >>= nCommandType;
1100
1101 ::rtl::OUString sCommand;
1102 m_aDocumentDataSource[daCommand] >>= sCommand;
1103
1104 bKnownDocDataSource = (CommandType::COMMAND == nCommandType) && (0 != sCommand.getLength());
1105 }
1106 }
1107 }
1108 }
1109
1110 if ( !bKnownDocDataSource )
1111 m_aExternalFeatures[ ID_BROWSER_DOCUMENT_DATASOURCE ].bEnabled = sal_False;
1112
1113 // update the toolbox
1114 implCheckExternalSlot(ID_BROWSER_DOCUMENT_DATASOURCE);
1115 }
1116
1117 // -------------------------------------------------------------------------
extractDescriptorProps(const::svx::ODataAccessDescriptor & _rDescriptor,::rtl::OUString & _rDataSource,::rtl::OUString & _rCommand,sal_Int32 & _rCommandType,sal_Bool & _rEscapeProcessing)1118 void SbaTableQueryBrowser::extractDescriptorProps(const ::svx::ODataAccessDescriptor& _rDescriptor, ::rtl::OUString& _rDataSource, ::rtl::OUString& _rCommand, sal_Int32& _rCommandType, sal_Bool& _rEscapeProcessing)
1119 {
1120 _rDataSource = _rDescriptor.getDataSource();
1121 if ( _rDescriptor.has(daCommand) )
1122 _rDescriptor[daCommand] >>= _rCommand;
1123 if ( _rDescriptor.has(daCommandType) )
1124 _rDescriptor[daCommandType] >>= _rCommandType;
1125
1126 // escape processing is the only one allowed not to be present
1127 _rEscapeProcessing = sal_True;
1128 if (_rDescriptor.has(daEscapeProcessing))
1129 _rEscapeProcessing = ::cppu::any2bool(_rDescriptor[daEscapeProcessing]);
1130 }
1131
1132 // -------------------------------------------------------------------------
1133 namespace
1134 {
getDataSourceDisplayName_isURL(const String & _rDS,String & _rDisplayName,String & _rUniqueId)1135 bool getDataSourceDisplayName_isURL( const String& _rDS, String& _rDisplayName, String& _rUniqueId )
1136 {
1137 INetURLObject aURL( _rDS );
1138 if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )
1139 {
1140 _rDisplayName = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET);
1141 // _rDisplayName = aURL.getName(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET);
1142 _rUniqueId = aURL.GetMainURL( INetURLObject::NO_DECODE );
1143 return true;
1144 }
1145 _rDisplayName = _rDS;
1146 _rUniqueId = String();
1147 return false;
1148 }
1149
1150 // .....................................................................
1151 struct FilterByEntryDataId : public IEntryFilter
1152 {
1153 String sId;
FilterByEntryDataIddbaui::__anon6c5776a60211::FilterByEntryDataId1154 FilterByEntryDataId( const String& _rId ) : sId( _rId ) { }
1155
~FilterByEntryDataIddbaui::__anon6c5776a60211::FilterByEntryDataId1156 virtual ~FilterByEntryDataId() {}
1157
1158 virtual bool includeEntry( SvLBoxEntry* _pEntry ) const;
1159 };
1160
includeEntry(SvLBoxEntry * _pEntry) const1161 bool FilterByEntryDataId::includeEntry( SvLBoxEntry* _pEntry ) const
1162 {
1163 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() );
1164 return ( !pData || ( pData->sAccessor == sId ) );
1165 }
1166 }
1167
1168 // -------------------------------------------------------------------------
getDataSourceAcessor(SvLBoxEntry * _pDataSourceEntry) const1169 String SbaTableQueryBrowser::getDataSourceAcessor( SvLBoxEntry* _pDataSourceEntry ) const
1170 {
1171 DBG_ASSERT( _pDataSourceEntry, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry!" );
1172
1173 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pDataSourceEntry->GetUserData() );
1174 DBG_ASSERT( pData, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry data!" );
1175 DBG_ASSERT( pData->eType == etDatasource, "SbaTableQueryBrowser::getDataSourceAcessor: entry does not denote a data source!" );
1176 return pData->sAccessor.Len() ? pData->sAccessor : GetEntryText( _pDataSourceEntry );
1177 }
1178
1179 // -------------------------------------------------------------------------
getObjectEntry(const::rtl::OUString & _rDataSource,const::rtl::OUString & _rCommand,sal_Int32 _nCommandType,SvLBoxEntry ** _ppDataSourceEntry,SvLBoxEntry ** _ppContainerEntry,sal_Bool _bExpandAncestors,const SharedConnection & _rxConnection)1180 SvLBoxEntry* SbaTableQueryBrowser::getObjectEntry(const ::rtl::OUString& _rDataSource, const ::rtl::OUString& _rCommand, sal_Int32 _nCommandType,
1181 SvLBoxEntry** _ppDataSourceEntry, SvLBoxEntry** _ppContainerEntry, sal_Bool _bExpandAncestors,
1182 const SharedConnection& _rxConnection )
1183 {
1184 if (_ppDataSourceEntry)
1185 *_ppDataSourceEntry = NULL;
1186 if (_ppContainerEntry)
1187 *_ppContainerEntry = NULL;
1188
1189 SvLBoxEntry* pObject = NULL;
1190 if ( m_pTreeView )
1191 {
1192 // look for the data source entry
1193 String sDisplayName, sDataSourceId;
1194 bool bIsDataSourceURL = getDataSourceDisplayName_isURL( _rDataSource, sDisplayName, sDataSourceId );
1195 // the display name may differ from the URL for readability reasons
1196 // #i33699# - 2004-09-24 - fs@openoffice.org
1197
1198 FilterByEntryDataId aFilter( sDataSourceId );
1199 SvLBoxEntry* pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter );
1200 if ( !pDataSource ) // check if the data source name is a file location
1201 {
1202 if ( bIsDataSourceURL )
1203 {
1204 // special case, the data source is a URL
1205 // add new entries to the list box model
1206 implAddDatasource( _rDataSource, _rxConnection );
1207 pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter );
1208 DBG_ASSERT( pDataSource, "SbaTableQueryBrowser::getObjectEntry: hmm - did not find it again!" );
1209 }
1210 }
1211 if (_ppDataSourceEntry)
1212 // (caller wants to have it ...)
1213 *_ppDataSourceEntry = pDataSource;
1214
1215 if (pDataSource)
1216 {
1217 // expand if required so
1218 if (_bExpandAncestors)
1219 m_pTreeView->getListBox().Expand(pDataSource);
1220
1221 // look for the object container
1222 SvLBoxEntry* pCommandType = NULL;
1223 switch (_nCommandType)
1224 {
1225 case CommandType::TABLE:
1226 pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_TABLES);
1227 break;
1228
1229 case CommandType::QUERY:
1230 pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_QUERIES);
1231 break;
1232 }
1233
1234 if (_ppContainerEntry)
1235 *_ppContainerEntry = pCommandType;
1236
1237 if (pCommandType)
1238 {
1239 // expand if required so
1240 if (_bExpandAncestors)
1241 {
1242 m_pTreeView->getListBox().Expand(pCommandType);
1243 }
1244
1245 // look for the object
1246 ::rtl::OUString sCommand = _rCommand;
1247 sal_Int32 nIndex = 0;
1248 do
1249 {
1250 ::rtl::OUString sPath = sCommand.getToken( 0, '/', nIndex );
1251 pObject = m_pTreeView->getListBox().GetEntryPosByName(sPath, pCommandType);
1252 pCommandType = pObject;
1253 if ( nIndex >= 0 )
1254 {
1255 if (ensureEntryObject(pObject))
1256 {
1257 DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( pObject->GetUserData() );
1258 Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
1259 sal_Int32 nIndex2 = nIndex;
1260 sPath = sCommand.getToken( 0, '/', nIndex2 );
1261 try
1262 {
1263 if ( xCollection->hasByName(sPath) )
1264 {
1265 if(!m_pTreeView->getListBox().GetEntryPosByName(sPath,pObject))
1266 {
1267 Reference<XNameAccess> xChild(xCollection->getByName(sPath),UNO_QUERY);
1268 DBTreeListUserData* pEntryData = new DBTreeListUserData;
1269 pEntryData->eType = etQuery;
1270 if ( xChild.is() )
1271 {
1272 pEntryData->eType = etQueryContainer;
1273 }
1274 implAppendEntry( pObject, sPath, pEntryData, pEntryData->eType );
1275 }
1276 }
1277 }
1278 catch(Exception&)
1279 {
1280 DBG_ERROR("SbaTableQueryBrowser::populateTree: could not fill the tree");
1281 }
1282 }
1283 }
1284 // m_pTreeView->getListBox().Expand(pCommandType);
1285 }
1286 while ( nIndex >= 0 );
1287 }
1288 }
1289 }
1290 return pObject;
1291 }
1292
1293 // -------------------------------------------------------------------------
getObjectEntry(const::svx::ODataAccessDescriptor & _rDescriptor,SvLBoxEntry ** _ppDataSourceEntry,SvLBoxEntry ** _ppContainerEntry,sal_Bool _bExpandAncestors)1294 SvLBoxEntry* SbaTableQueryBrowser::getObjectEntry(const ::svx::ODataAccessDescriptor& _rDescriptor,
1295 SvLBoxEntry** _ppDataSourceEntry, SvLBoxEntry** _ppContainerEntry,
1296 sal_Bool _bExpandAncestors)
1297 {
1298 // extract the props from the descriptor
1299 ::rtl::OUString sDataSource;
1300 ::rtl::OUString sCommand;
1301 sal_Int32 nCommandType = CommandType::COMMAND;
1302 sal_Bool bEscapeProcessing = sal_True;
1303 extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
1304
1305 return getObjectEntry( sDataSource, sCommand, nCommandType, _ppDataSourceEntry, _ppContainerEntry, _bExpandAncestors, SharedConnection() );
1306 }
1307
1308 // -------------------------------------------------------------------------
connectExternalDispatches()1309 void SbaTableQueryBrowser::connectExternalDispatches()
1310 {
1311 Reference< XDispatchProvider > xProvider( getFrame(), UNO_QUERY );
1312 DBG_ASSERT(xProvider.is(), "SbaTableQueryBrowser::connectExternalDispatches: no DispatchProvider !");
1313 if (xProvider.is())
1314 {
1315 if ( m_aExternalFeatures.empty() )
1316 {
1317 const sal_Char* pURLs[] = {
1318 ".uno:DataSourceBrowser/DocumentDataSource",
1319 ".uno:DataSourceBrowser/FormLetter",
1320 ".uno:DataSourceBrowser/InsertColumns",
1321 ".uno:DataSourceBrowser/InsertContent",
1322 };
1323 const sal_uInt16 nIds[] = {
1324 ID_BROWSER_DOCUMENT_DATASOURCE,
1325 ID_BROWSER_FORMLETTER,
1326 ID_BROWSER_INSERTCOLUMNS,
1327 ID_BROWSER_INSERTCONTENT
1328 };
1329
1330 for ( size_t i=0; i < sizeof( pURLs ) / sizeof( pURLs[0] ); ++i )
1331 {
1332 URL aURL;
1333 aURL.Complete = ::rtl::OUString::createFromAscii( pURLs[i] );
1334 if ( m_xUrlTransformer.is() )
1335 m_xUrlTransformer->parseStrict( aURL );
1336 m_aExternalFeatures[ nIds[ i ] ] = ExternalFeature( aURL );
1337 }
1338 }
1339
1340 for ( ExternalFeaturesMap::iterator feature = m_aExternalFeatures.begin();
1341 feature != m_aExternalFeatures.end();
1342 ++feature
1343 )
1344 {
1345 feature->second.xDispatcher = xProvider->queryDispatch(
1346 feature->second.aURL, ::rtl::OUString::createFromAscii("_parent"), FrameSearchFlag::PARENT
1347 );
1348
1349 if ( feature->second.xDispatcher.get() == static_cast< XDispatch* >( this ) )
1350 {
1351 OSL_ENSURE( sal_False, "SbaTableQueryBrowser::connectExternalDispatches: this should not happen anymore!" );
1352 // (nowadays, the URLs aren't in our SupportedFeatures list anymore, so we should
1353 // not supply a dispatcher for this)
1354 feature->second.xDispatcher.clear();
1355 }
1356
1357 if ( feature->second.xDispatcher.is() )
1358 {
1359 try
1360 {
1361 feature->second.xDispatcher->addStatusListener( this, feature->second.aURL );
1362 }
1363 catch( const Exception& )
1364 {
1365 DBG_UNHANDLED_EXCEPTION();
1366 }
1367 }
1368
1369 implCheckExternalSlot( feature->first );
1370 }
1371 }
1372 }
1373
1374 // -------------------------------------------------------------------------
implCheckExternalSlot(sal_uInt16 _nId)1375 void SbaTableQueryBrowser::implCheckExternalSlot( sal_uInt16 _nId )
1376 {
1377 if ( !m_xMainToolbar.is() )
1378 return;
1379
1380 Window* pToolboxWindow = VCLUnoHelper::GetWindow( m_xMainToolbar );
1381 ToolBox* pToolbox = dynamic_cast< ToolBox* >( pToolboxWindow );
1382 OSL_ENSURE( pToolbox, "SbaTableQueryBrowser::implCheckExternalSlot: cannot obtain the toolbox window!" );
1383
1384 // check if we have to hide this item from the toolbox
1385 if ( pToolbox )
1386 {
1387 sal_Bool bHaveDispatcher = m_aExternalFeatures[ _nId ].xDispatcher.is();
1388 if ( bHaveDispatcher != pToolbox->IsItemVisible( _nId ) )
1389 bHaveDispatcher ? pToolbox->ShowItem( _nId ) : pToolbox->HideItem( _nId );
1390 }
1391
1392 // and invalidate this feature in general
1393 InvalidateFeature( _nId );
1394 }
1395
1396 // -------------------------------------------------------------------------
disposing(const EventObject & _rSource)1397 void SAL_CALL SbaTableQueryBrowser::disposing( const EventObject& _rSource ) throw(RuntimeException)
1398 {
1399 // our frame ?
1400 Reference< ::com::sun::star::frame::XFrame > xSourceFrame(_rSource.Source, UNO_QUERY);
1401 if (m_xCurrentFrameParent.is() && (xSourceFrame == m_xCurrentFrameParent))
1402 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
1403 else
1404 {
1405 // search the external dispatcher causing this call in our map
1406 Reference< XDispatch > xSource(_rSource.Source, UNO_QUERY);
1407 if(xSource.is())
1408 {
1409 for ( ExternalFeaturesMap::iterator aLoop = m_aExternalFeatures.begin();
1410 aLoop != m_aExternalFeatures.end();
1411 )
1412 {
1413 if ( aLoop->second.xDispatcher.get() != xSource.get() ) {
1414 ++aLoop;
1415 continue;
1416 }
1417
1418 // prepare to erase the aLoop iterator
1419 const sal_uInt16 nSlotId = aLoop->first;
1420 ExternalFeaturesMap::iterator aNext = aLoop;
1421 ++aNext;
1422
1423 // remove it
1424 m_aExternalFeatures.erase( aLoop );
1425
1426 // maybe update the UI
1427 implCheckExternalSlot( nSlotId );
1428
1429 // continue, the same XDispatch may be resposible for more than one URL
1430 aLoop = aNext;
1431 }
1432 }
1433 else
1434 {
1435 Reference<XConnection> xCon(_rSource.Source, UNO_QUERY);
1436 if ( xCon.is() && m_pTreeView )
1437 { // our connection is in dispose so we have to find the entry equal with this connection
1438 // and close it what means to collapse the entry
1439 // get the top-level representing the removed data source
1440 SvLBoxEntry* pDSLoop = m_pTreeView->getListBox().FirstChild(NULL);
1441 while (pDSLoop)
1442 {
1443 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pDSLoop->GetUserData());
1444 if ( pData && pData->xConnection == xCon )
1445 {
1446 // we set the conenction to null to avoid a second disposing of the connection
1447 pData->xConnection.clear();
1448 closeConnection(pDSLoop,sal_False);
1449 break;
1450 }
1451
1452 pDSLoop = m_pTreeView->getListBox().NextSibling(pDSLoop);
1453 }
1454 }
1455 else
1456 SbaXDataBrowserController::disposing(_rSource);
1457 }
1458 }
1459 }
1460
1461 // -------------------------------------------------------------------------
implRemoveStatusListeners()1462 void SbaTableQueryBrowser::implRemoveStatusListeners()
1463 {
1464 // clear all old dispatches
1465 for ( ExternalFeaturesMap::const_iterator aLoop = m_aExternalFeatures.begin();
1466 aLoop != m_aExternalFeatures.end();
1467 ++aLoop
1468 )
1469 {
1470 if ( aLoop->second.xDispatcher.is() )
1471 {
1472 try
1473 {
1474 aLoop->second.xDispatcher->removeStatusListener( this, aLoop->second.aURL );
1475 }
1476 catch (Exception&)
1477 {
1478 DBG_ERROR("SbaTableQueryBrowser::implRemoveStatusListeners: could not remove a status listener!");
1479 }
1480 }
1481 }
1482 m_aExternalFeatures.clear();
1483 }
1484
1485 // -------------------------------------------------------------------------
select(const Any & _rSelection)1486 sal_Bool SAL_CALL SbaTableQueryBrowser::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException)
1487 {
1488 ::vos::OGuard aGuard(Application::GetSolarMutex());
1489 // doin' a lot of VCL stuff here -> lock the SolarMutex
1490
1491 Sequence< PropertyValue > aDescriptorSequence;
1492 if (!(_rSelection >>= aDescriptorSequence))
1493 throw IllegalArgumentException(::rtl::OUString(), *this, 1);
1494 // TODO: error message
1495
1496 ODataAccessDescriptor aDescriptor;
1497 try
1498 {
1499 aDescriptor = ODataAccessDescriptor(aDescriptorSequence);
1500 }
1501 catch(const Exception&)
1502 {
1503 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::select: could not extract the descriptor!");
1504 }
1505
1506 // check the precense of the props we need
1507 if ( !(aDescriptor.has(daDataSource) || aDescriptor.has(daDatabaseLocation)) || !aDescriptor.has(daCommand) || !aDescriptor.has(daCommandType))
1508 throw IllegalArgumentException(::rtl::OUString(), *this, 1);
1509 // TODO: error message
1510
1511 return implSelect(aDescriptor,sal_True);
1512 }
1513
1514 // -------------------------------------------------------------------------
getSelection()1515 Any SAL_CALL SbaTableQueryBrowser::getSelection( ) throw (RuntimeException)
1516 {
1517 Any aReturn;
1518
1519 try
1520 {
1521 Reference< XLoadable > xLoadable(getRowSet(), UNO_QUERY);
1522 if (xLoadable.is() && xLoadable->isLoaded())
1523 {
1524 Reference< XPropertySet > aFormProps(getRowSet(), UNO_QUERY);
1525 ODataAccessDescriptor aDescriptor(aFormProps);
1526 // remove properties which are not part of our "selection"
1527 aDescriptor.erase(daConnection);
1528 aDescriptor.erase(daCursor);
1529
1530 aReturn <<= aDescriptor.createPropertyValueSequence();
1531 }
1532 }
1533 catch( const Exception& )
1534 {
1535 DBG_UNHANDLED_EXCEPTION();
1536 }
1537
1538 return aReturn;
1539 }
1540
1541 // -------------------------------------------------------------------------
addSelectionChangeListener(const Reference<XSelectionChangeListener> & _rxListener)1542 void SAL_CALL SbaTableQueryBrowser::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException)
1543 {
1544 m_aSelectionListeners.addInterface(_rxListener);
1545 }
1546
1547 // -------------------------------------------------------------------------
removeSelectionChangeListener(const Reference<XSelectionChangeListener> & _rxListener)1548 void SAL_CALL SbaTableQueryBrowser::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException)
1549 {
1550 m_aSelectionListeners.removeInterface(_rxListener);
1551 }
1552
1553 // -------------------------------------------------------------------------
attachFrame(const Reference<::com::sun::star::frame::XFrame> & _xFrame)1554 void SbaTableQueryBrowser::attachFrame(const Reference< ::com::sun::star::frame::XFrame > & _xFrame) throw( RuntimeException )
1555 {
1556 implRemoveStatusListeners();
1557
1558 if (m_xCurrentFrameParent.is())
1559 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
1560
1561 SbaXDataBrowserController::attachFrame(_xFrame);
1562
1563 Reference< XFrame > xCurrentFrame( getFrame() );
1564 if ( xCurrentFrame.is() )
1565 {
1566 m_xCurrentFrameParent = xCurrentFrame->findFrame(::rtl::OUString::createFromAscii("_parent"),FrameSearchFlag::PARENT);
1567 if ( m_xCurrentFrameParent.is() )
1568 m_xCurrentFrameParent->addFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
1569
1570 // obtain our toolbox
1571 try
1572 {
1573 Reference< XPropertySet > xFrameProps( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW );
1574 Reference< XLayoutManager > xLayouter(
1575 xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ),
1576 UNO_QUERY );
1577
1578 if ( xLayouter.is() )
1579 {
1580 Reference< XUIElement > xUI(
1581 xLayouter->getElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ) ) ),
1582 UNO_SET_THROW );
1583 m_xMainToolbar = m_xMainToolbar.query( xUI->getRealInterface() );
1584 OSL_ENSURE( m_xMainToolbar.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" );
1585 }
1586 }
1587 catch( const Exception& )
1588 {
1589 DBG_UNHANDLED_EXCEPTION();
1590 }
1591 }
1592
1593 // get the dispatchers for the external slots
1594 connectExternalDispatches();
1595 }
1596
1597 // -------------------------------------------------------------------------
addModelListeners(const Reference<::com::sun::star::awt::XControlModel> & _xGridControlModel)1598 void SbaTableQueryBrowser::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
1599 {
1600 SbaXDataBrowserController::addModelListeners(_xGridControlModel);
1601 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1602 if (xSourceSet.is())
1603 {
1604 xSourceSet->addPropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1605 xSourceSet->addPropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1606 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1607 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1608 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1609 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1610 }
1611
1612 }
1613
1614 // -------------------------------------------------------------------------
removeModelListeners(const Reference<::com::sun::star::awt::XControlModel> & _xGridControlModel)1615 void SbaTableQueryBrowser::removeModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
1616 {
1617 SbaXDataBrowserController::removeModelListeners(_xGridControlModel);
1618 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1619 if (xSourceSet.is())
1620 {
1621 xSourceSet->removePropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1622 xSourceSet->removePropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1623 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1624 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1625 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1626 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1627 }
1628 }
1629 // -------------------------------------------------------------------------
RowChanged()1630 void SbaTableQueryBrowser::RowChanged()
1631 {
1632 if(getBrowserView())
1633 {
1634 SbaGridControl* pControl = getBrowserView()->getVclControl();
1635 if (!pControl->IsEditing())
1636 InvalidateFeature(ID_BROWSER_COPY);
1637 }
1638 SbaXDataBrowserController::RowChanged();
1639 }
1640
1641 // -------------------------------------------------------------------------
ColumnChanged()1642 void SbaTableQueryBrowser::ColumnChanged()
1643 {
1644 if(getBrowserView())
1645 {
1646 SbaGridControl* pControl = getBrowserView()->getVclControl();
1647 if (!pControl->IsEditing())
1648 InvalidateFeature(ID_BROWSER_COPY);
1649 }
1650 SbaXDataBrowserController::ColumnChanged();
1651 }
1652 //------------------------------------------------------------------------------
AddColumnListener(const Reference<XPropertySet> & xCol)1653 void SbaTableQueryBrowser::AddColumnListener(const Reference< XPropertySet > & xCol)
1654 {
1655 SbaXDataBrowserController::AddColumnListener(xCol);
1656 SafeAddPropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1657 SafeAddPropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1658 SafeAddPropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1659 SafeAddPropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1660 }
1661
1662 //------------------------------------------------------------------------------
RemoveColumnListener(const Reference<XPropertySet> & xCol)1663 void SbaTableQueryBrowser::RemoveColumnListener(const Reference< XPropertySet > & xCol)
1664 {
1665 SbaXDataBrowserController::RemoveColumnListener(xCol);
1666 SafeRemovePropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1667 SafeRemovePropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1668 SafeRemovePropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1669 SafeRemovePropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1670 }
1671
1672 //------------------------------------------------------------------------------
criticalFail()1673 void SbaTableQueryBrowser::criticalFail()
1674 {
1675 SbaXDataBrowserController::criticalFail();
1676 unloadAndCleanup( sal_False );
1677 }
1678
1679 //------------------------------------------------------------------------------
LoadFinished(sal_Bool _bWasSynch)1680 void SbaTableQueryBrowser::LoadFinished(sal_Bool _bWasSynch)
1681 {
1682 SbaXDataBrowserController::LoadFinished(_bWasSynch);
1683
1684 m_sQueryCommand = ::rtl::OUString();
1685 m_bQueryEscapeProcessing = sal_False;
1686
1687 if (isValid() && !loadingCancelled())
1688 {
1689 // did we load a query?
1690 sal_Bool bTemporary; // needed because we m_bQueryEscapeProcessing is only one bit wide (and we want to pass it by reference)
1691 if ( implGetQuerySignature( m_sQueryCommand, bTemporary ) )
1692 m_bQueryEscapeProcessing = bTemporary;
1693 }
1694
1695 // if the form has been loaded, this means that our "selection" has changed
1696 EventObject aEvent( *this );
1697 m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent );
1698 }
1699
1700 //------------------------------------------------------------------------------
getExternalSlotState(sal_uInt16 _nId) const1701 sal_Bool SbaTableQueryBrowser::getExternalSlotState( sal_uInt16 _nId ) const
1702 {
1703 sal_Bool bEnabled = sal_False;
1704 ExternalFeaturesMap::const_iterator aPos = m_aExternalFeatures.find( _nId );
1705 if ( ( m_aExternalFeatures.end() != aPos ) && aPos->second.xDispatcher.is() )
1706 bEnabled = aPos->second.bEnabled;
1707 return bEnabled;
1708 }
1709
1710 //------------------------------------------------------------------------------
GetState(sal_uInt16 nId) const1711 FeatureState SbaTableQueryBrowser::GetState(sal_uInt16 nId) const
1712 {
1713 FeatureState aReturn;
1714 // (disabled automatically)
1715
1716 // no chance without a view
1717 if (!getBrowserView() || !getBrowserView()->getVclControl())
1718 return aReturn;
1719
1720 switch ( nId )
1721 {
1722 case ID_TREE_ADMINISTRATE:
1723 aReturn.bEnabled = true;
1724 return aReturn;
1725
1726 case ID_BROWSER_CLOSE:
1727 // the close button should always be enabled
1728 aReturn.bEnabled = !m_bEnableBrowser;
1729 return aReturn;
1730
1731 // "toggle explorer" is always enabled (if we have a explorer)
1732 case ID_BROWSER_EXPLORER:
1733 aReturn.bEnabled = m_bEnableBrowser;
1734 aReturn.bChecked = haveExplorer();
1735 return aReturn;
1736
1737 case ID_BROWSER_REMOVEFILTER:
1738 return SbaXDataBrowserController::GetState( nId );
1739
1740 case ID_BROWSER_COPY:
1741 if ( !m_pTreeView->HasChildPathFocus() )
1742 // handled below
1743 break;
1744 // NO break!
1745 case ID_TREE_CLOSE_CONN:
1746 case ID_TREE_EDIT_DATABASE:
1747 {
1748 SvLBoxEntry* pCurrentEntry( m_pTreeView->getListBox().GetCurEntry() );
1749 EntryType eType = getEntryType( pCurrentEntry );
1750 if ( eType == etUnknown )
1751 return aReturn;
1752
1753 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent( pCurrentEntry );
1754 DBTreeListUserData* pDSData
1755 = pDataSourceEntry
1756 ? static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() )
1757 : NULL;
1758
1759 if ( nId == ID_TREE_CLOSE_CONN )
1760 {
1761 aReturn.bEnabled = ( pDSData != NULL ) && pDSData->xConnection.is();
1762 }
1763 else if ( nId == ID_TREE_EDIT_DATABASE )
1764 {
1765 ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithServiceFactory( getORB(),
1766 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.DataAccess/Policies/Features/Common" ) ) ) );
1767 sal_Bool bHaveEditDatabase( sal_True );
1768 OSL_VERIFY( aConfig.getNodeValue( "EditDatabaseFromDataSourceView" ) >>= bHaveEditDatabase );
1769 aReturn.bEnabled = getORB().is() && ( pDataSourceEntry != NULL ) && bHaveEditDatabase;
1770 }
1771 else if ( nId == ID_BROWSER_COPY )
1772 {
1773 aReturn.bEnabled = isEntryCopyAllowed( pCurrentEntry );
1774 }
1775
1776 return aReturn;
1777 }
1778 }
1779
1780 // all slots not handled above are not available if no form is loaded
1781 if (!isLoaded())
1782 return aReturn;
1783
1784 try
1785 {
1786 sal_Bool bHandled = sal_False;
1787 switch (nId)
1788 {
1789 case ID_BROWSER_DOCUMENT_DATASOURCE:
1790 // the slot is enabled if we have an external dispatcher able to handle it,
1791 // and the dispatcher must have enabled the slot in general
1792 aReturn.bEnabled = getExternalSlotState( ID_BROWSER_DOCUMENT_DATASOURCE );
1793 bHandled = sal_True;
1794 break;
1795 case ID_BROWSER_REFRESH:
1796 aReturn.bEnabled = sal_True;
1797 bHandled = sal_True;
1798 break;
1799 }
1800
1801 if (bHandled)
1802 return aReturn;
1803
1804 // no chance without valid models
1805 if (isValid() && !isValidCursor() && nId != ID_BROWSER_CLOSE)
1806 return aReturn;
1807
1808 switch (nId)
1809 {
1810 case ID_BROWSER_INSERTCOLUMNS:
1811 case ID_BROWSER_INSERTCONTENT:
1812 case ID_BROWSER_FORMLETTER:
1813 {
1814 // the slot is enabled if we have an external dispatcher able to handle it,
1815 // and the dispatcher must have enabled the slot in general
1816 aReturn.bEnabled = getExternalSlotState( nId );
1817
1818 // for the Insert* slots, we need at least one selected row
1819 if (ID_BROWSER_FORMLETTER != nId)
1820 aReturn.bEnabled = aReturn.bEnabled && getBrowserView()->getVclControl()->GetSelectRowCount();
1821
1822 // disabled for native queries which are not saved within the database
1823 // 67706 - 23.08.99 - FS
1824 Reference< XPropertySet > xDataSource(getRowSet(), UNO_QUERY);
1825 try
1826 {
1827 aReturn.bEnabled = aReturn.bEnabled && xDataSource.is();
1828
1829 if (xDataSource.is())
1830 {
1831 sal_Int32 nType = ::comphelper::getINT32(xDataSource->getPropertyValue(PROPERTY_COMMAND_TYPE));
1832 aReturn.bEnabled = aReturn.bEnabled && ((::comphelper::getBOOL(xDataSource->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || (nType == ::com::sun::star::sdb::CommandType::QUERY)));
1833 }
1834 }
1835 catch(DisposedException&)
1836 {
1837 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::GetState: object already disposed!");
1838 }
1839 catch( const Exception& )
1840 {
1841 DBG_UNHANDLED_EXCEPTION();
1842 }
1843 }
1844 break;
1845
1846 case ID_BROWSER_TITLE:
1847 {
1848 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1849 sal_Int32 nCommandType = CommandType::TABLE;
1850 xProp->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nCommandType;
1851 String sTitle;
1852 switch (nCommandType)
1853 {
1854 case CommandType::TABLE:
1855 sTitle = String(ModuleRes(STR_TBL_TITLE)); break;
1856 case CommandType::QUERY:
1857 case CommandType::COMMAND:
1858 sTitle = String(ModuleRes(STR_QRY_TITLE)); break;
1859 default:
1860 DBG_ASSERT(sal_False, "SbaTableQueryBrowser::GetState: unknown command type!");
1861 }
1862 ::rtl::OUString aName;
1863 xProp->getPropertyValue(PROPERTY_COMMAND) >>= aName;
1864 String sObject(aName.getStr());
1865
1866 sTitle.SearchAndReplace('#',sObject);
1867 aReturn.sTitle = sTitle;
1868 aReturn.bEnabled = sal_True;
1869 }
1870 break;
1871 case ID_BROWSER_TABLEATTR:
1872 case ID_BROWSER_ROWHEIGHT:
1873 case ID_BROWSER_COLATTRSET:
1874 case ID_BROWSER_COLWIDTH:
1875 aReturn.bEnabled = getBrowserView() && getBrowserView()->getVclControl() && isValid() && isValidCursor();
1876 // aReturn.bEnabled &= getDefinition() && !getDefinition()->GetDatabase()->IsReadOnly();
1877 break;
1878
1879 case ID_BROWSER_COPY:
1880 OSL_ENSURE( !m_pTreeView->HasChildPathFocus(), "SbaTableQueryBrowser::GetState( ID_BROWSER_COPY ): this should have been handled above!" );
1881 if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing())
1882 {
1883 SbaGridControl* pControl = getBrowserView()->getVclControl();
1884 if ( pControl->GetSelectRowCount() )
1885 {
1886 aReturn.bEnabled = m_aCurrentFrame.isActive();
1887 break;
1888 } // if ( getBrowserView()->getVclControl()->GetSelectRowCount() )
1889 else
1890 aReturn.bEnabled = pControl->canCopyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
1891 break;
1892 }
1893 // NO break here
1894 default:
1895 return SbaXDataBrowserController::GetState(nId);
1896 }
1897 }
1898 catch(const Exception&)
1899 {
1900 DBG_UNHANDLED_EXCEPTION();
1901 }
1902
1903 return aReturn;
1904
1905 }
1906
1907 //------------------------------------------------------------------------------
Execute(sal_uInt16 nId,const Sequence<PropertyValue> & aArgs)1908 void SbaTableQueryBrowser::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& aArgs)
1909 {
1910 switch (nId)
1911 {
1912 default:
1913 SbaXDataBrowserController::Execute(nId,aArgs);
1914 break;
1915
1916 case ID_TREE_EDIT_DATABASE:
1917 implAdministrate( m_pTreeView->getListBox().GetCurEntry() );
1918 break;
1919
1920 case ID_TREE_CLOSE_CONN:
1921 openHelpAgent( HID_DSBROWSER_DISCONNECTING );
1922 closeConnection( m_pTreeView->getListBox().GetRootLevelParent( m_pTreeView->getListBox().GetCurEntry() ) );
1923 break;
1924
1925 case ID_TREE_ADMINISTRATE:
1926 ::svx::administrateDatabaseRegistration( getView() );
1927 break;
1928
1929 case ID_BROWSER_REFRESH:
1930 {
1931 if ( !SaveModified( ) )
1932 // nothing to do
1933 break;
1934
1935 sal_Bool bFullReinit = sal_False;
1936 // check if the query signature (if the form is based on a query) has changed
1937 if ( m_sQueryCommand.getLength() )
1938 {
1939 ::rtl::OUString sNewQueryCommand;
1940 sal_Bool bNewQueryEP;
1941
1942 #if OSL_DEBUG_LEVEL > 0
1943 sal_Bool bIsQuery =
1944 #endif
1945 implGetQuerySignature( sNewQueryCommand, bNewQueryEP );
1946 OSL_ENSURE( bIsQuery, "SbaTableQueryBrowser::Execute: was a query before, but is not anymore?" );
1947
1948 bFullReinit = ( sNewQueryCommand != m_sQueryCommand ) || ( m_bQueryEscapeProcessing != bNewQueryEP );
1949 }
1950 if ( !bFullReinit )
1951 {
1952 // let the base class do a simple reload
1953 SbaXDataBrowserController::Execute(nId,aArgs);
1954 break;
1955 }
1956 // NO break here!
1957 }
1958
1959 case ID_BROWSER_REFRESH_REBUILD:
1960 {
1961 if ( !SaveModified() )
1962 // nothing to do
1963 break;
1964
1965 SvLBoxEntry* pSelected = m_pCurrentlyDisplayed;
1966 // unload
1967 unloadAndCleanup( sal_False );
1968
1969 // reselect the entry
1970 if ( pSelected )
1971 {
1972 implSelect( pSelected );
1973 }
1974 else
1975 {
1976 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1977 implSelect(::svx::ODataAccessDescriptor(xProp));
1978 }
1979 }
1980 break;
1981
1982 case ID_BROWSER_EXPLORER:
1983 toggleExplorer();
1984 break;
1985
1986 case ID_BROWSER_DOCUMENT_DATASOURCE:
1987 implSelect(m_aDocumentDataSource);
1988 break;
1989
1990 case ID_BROWSER_INSERTCOLUMNS:
1991 case ID_BROWSER_INSERTCONTENT:
1992 case ID_BROWSER_FORMLETTER:
1993 if (getBrowserView() && isValidCursor())
1994 {
1995 // the URL the slot id is assigned to
1996 OSL_ENSURE( m_aExternalFeatures.find( nId ) != m_aExternalFeatures.end(),
1997 "SbaTableQueryBrowser::Execute( ID_BROWSER_?): how could this ever be enabled?" );
1998 URL aParentUrl = m_aExternalFeatures[ nId ].aURL;
1999
2000 // let the dispatcher execute the slot
2001 Reference< XDispatch > xDispatch( m_aExternalFeatures[ nId ].xDispatcher );
2002 if (xDispatch.is())
2003 {
2004 // set the properties for the dispatch
2005
2006 // first fill the selection
2007 SbaGridControl* pGrid = getBrowserView()->getVclControl();
2008 MultiSelection* pSelection = (MultiSelection*)pGrid->GetSelection();
2009 Sequence< Any > aSelection;
2010 if ( !pGrid->IsAllSelected() )
2011 { // transfer the selected rows only if not all rows are selected
2012 // (all rows means the whole table)
2013 // i3832 - 03.04.2002 - fs@openoffice.org
2014 if (pSelection != NULL)
2015 {
2016 aSelection.realloc(pSelection->GetSelectCount());
2017 long nIdx = pSelection->FirstSelected();
2018 Any* pSelectionNos = aSelection.getArray();
2019 while (nIdx >= 0)
2020 {
2021 *pSelectionNos++ <<= (sal_Int32)(nIdx + 1);
2022 nIdx = pSelection->NextSelected();
2023 }
2024 }
2025 }
2026
2027 Reference< XResultSet > xCursorClone;
2028 try
2029 {
2030 Reference< XResultSetAccess > xResultSetAccess(getRowSet(),UNO_QUERY);
2031 if (xResultSetAccess.is())
2032 xCursorClone = xResultSetAccess->createResultSet();
2033 }
2034 catch(DisposedException&)
2035 {
2036 OSL_ENSURE(0,"Object already disposed!");
2037 }
2038 catch(Exception&)
2039 {
2040 DBG_ERROR("SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not clone the cursor!");
2041 }
2042
2043 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
2044
2045 try
2046 {
2047 ODataAccessDescriptor aDescriptor;
2048 ::rtl::OUString sDataSourceName;
2049 xProp->getPropertyValue(PROPERTY_DATASOURCENAME) >>= sDataSourceName;
2050
2051 aDescriptor.setDataSource(sDataSourceName);
2052 aDescriptor[daCommand] = xProp->getPropertyValue(PROPERTY_COMMAND);
2053 aDescriptor[daCommandType] = xProp->getPropertyValue(PROPERTY_COMMAND_TYPE);
2054 aDescriptor[daConnection] = xProp->getPropertyValue(PROPERTY_ACTIVE_CONNECTION);
2055 aDescriptor[daCursor] <<= xCursorClone;
2056 if ( aSelection.getLength() )
2057 {
2058 aDescriptor[daSelection] <<= aSelection;
2059 aDescriptor[daBookmarkSelection] <<= sal_False;
2060 // these are selection indicies
2061 // before we change this, all clients have to be adjusted
2062 // so that they recognize the new BookmarkSelection property!
2063 }
2064
2065 xDispatch->dispatch(aParentUrl, aDescriptor.createPropertyValueSequence());
2066 }
2067 catch( const Exception& )
2068 {
2069 DBG_UNHANDLED_EXCEPTION();
2070 }
2071 }
2072 }
2073 break;
2074
2075 case ID_BROWSER_CLOSE:
2076 closeTask();
2077 // if it's not 0, such a async close is already pending
2078 break;
2079
2080 case ID_BROWSER_COPY:
2081 if(m_pTreeView->HasChildPathFocus())
2082 {
2083 copyEntry(m_pTreeView->getListBox().GetCurEntry());
2084 }
2085 else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing() && getBrowserView()->getVclControl()->GetSelectRowCount() < 1)
2086 {
2087 SbaGridControl* pControl = getBrowserView()->getVclControl();
2088 pControl->copyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
2089 }
2090 else
2091 SbaXDataBrowserController::Execute(nId,aArgs);
2092 break;
2093 }
2094 }
2095
2096 // -------------------------------------------------------------------------
implAddDatasource(const String & _rDataSourceName,const SharedConnection & _rxConnection)2097 void SbaTableQueryBrowser::implAddDatasource( const String& _rDataSourceName, const SharedConnection& _rxConnection )
2098 {
2099 Image a, b, c;
2100 String d, e;
2101 implAddDatasource( _rDataSourceName, a, d, b, e, c, _rxConnection );
2102 }
2103
2104 // -------------------------------------------------------------------------
implAddDatasource(const String & _rDbName,Image & _rDbImage,String & _rQueryName,Image & _rQueryImage,String & _rTableName,Image & _rTableImage,const SharedConnection & _rxConnection)2105 void SbaTableQueryBrowser::implAddDatasource(const String& _rDbName, Image& _rDbImage,
2106 String& _rQueryName, Image& _rQueryImage, String& _rTableName, Image& _rTableImage,
2107 const SharedConnection& _rxConnection)
2108 {
2109 vos::OGuard aGuard( Application::GetSolarMutex() );
2110 // initialize the names/images if necessary
2111 if (!_rQueryName.Len())
2112 _rQueryName = String(ModuleRes(RID_STR_QUERIES_CONTAINER));
2113 if (!_rTableName.Len())
2114 _rTableName = String(ModuleRes(RID_STR_TABLES_CONTAINER));
2115
2116 ImageProvider aImageProvider;
2117 if (!_rQueryImage)
2118 _rQueryImage = aImageProvider.getFolderImage( DatabaseObject::QUERY, isHiContrast() );
2119 if (!_rTableImage)
2120 _rTableImage = aImageProvider.getFolderImage( DatabaseObject::TABLE, isHiContrast() );
2121
2122 if (!_rDbImage)
2123 _rDbImage = aImageProvider.getDatabaseImage( isHiContrast() );
2124
2125 // add the entry for the data source
2126 // special handling for data sources denoted by URLs - we do not want to display this ugly URL, do we?
2127 // #i33699# - 2004-09-24 - fs@openoffice.org
2128 String sDSDisplayName, sDataSourceId;
2129 getDataSourceDisplayName_isURL( _rDbName, sDSDisplayName, sDataSourceId );
2130
2131 SvLBoxEntry* pDatasourceEntry = m_pTreeView->getListBox().InsertEntry( sDSDisplayName, _rDbImage, _rDbImage, NULL, sal_False );
2132 DBTreeListUserData* pDSData = new DBTreeListUserData;
2133 pDSData->eType = etDatasource;
2134 pDSData->sAccessor = sDataSourceId;
2135 pDSData->xConnection = _rxConnection;
2136 pDatasourceEntry->SetUserData(pDSData);
2137
2138 // the child for the queries container
2139 {
2140 DBTreeListUserData* pQueriesData = new DBTreeListUserData;
2141 pQueriesData->eType = etQueryContainer;
2142
2143 m_pTreeView->getListBox().InsertEntry(
2144 _rQueryName, _rQueryImage, _rQueryImage, pDatasourceEntry,
2145 sal_True /*ChildsOnDemand*/, LIST_APPEND, pQueriesData );
2146 }
2147
2148 // the child for the tables container
2149 {
2150 DBTreeListUserData* pTablesData = new DBTreeListUserData;
2151 pTablesData->eType = etTableContainer;
2152
2153 m_pTreeView->getListBox().InsertEntry(
2154 _rTableName, _rTableImage, _rTableImage, pDatasourceEntry,
2155 sal_True /*ChildsOnDemand*/, LIST_APPEND, pTablesData );
2156 }
2157
2158 }
2159 // -------------------------------------------------------------------------
initializeTreeModel()2160 void SbaTableQueryBrowser::initializeTreeModel()
2161 {
2162 if (m_xDatabaseContext.is())
2163 {
2164 Image aDBImage, aQueriesImage, aTablesImage;
2165 String sQueriesName, sTablesName;
2166
2167 // fill the model with the names of the registered datasources
2168 Sequence< ::rtl::OUString > aDatasources = m_xDatabaseContext->getElementNames();
2169 const ::rtl::OUString* pIter = aDatasources.getConstArray();
2170 const ::rtl::OUString* pEnd = pIter + aDatasources.getLength();
2171 for (; pIter != pEnd; ++pIter)
2172 implAddDatasource( *pIter, aDBImage, sQueriesName, aQueriesImage, sTablesName, aTablesImage, SharedConnection() );
2173 }
2174 }
2175 // -------------------------------------------------------------------------
populateTree(const Reference<XNameAccess> & _xNameAccess,SvLBoxEntry * _pParent,EntryType _eEntryType)2176 void SbaTableQueryBrowser::populateTree(const Reference<XNameAccess>& _xNameAccess,
2177 SvLBoxEntry* _pParent,
2178 EntryType _eEntryType)
2179 {
2180 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pParent->GetUserData());
2181 if(pData) // don't ask if the nameaccess is already set see OnExpandEntry views and tables
2182 pData->xContainer = _xNameAccess;
2183
2184 try
2185 {
2186 Sequence< ::rtl::OUString > aNames = _xNameAccess->getElementNames();
2187 const ::rtl::OUString* pIter = aNames.getConstArray();
2188 const ::rtl::OUString* pEnd = pIter + aNames.getLength();
2189 for (; pIter != pEnd; ++pIter)
2190 {
2191 if( !m_pTreeView->getListBox().GetEntryPosByName(*pIter,_pParent))
2192 {
2193 DBTreeListUserData* pEntryData = new DBTreeListUserData;
2194 pEntryData->eType = _eEntryType;
2195 if ( _eEntryType == etQuery )
2196 {
2197 Reference<XNameAccess> xChild(_xNameAccess->getByName(*pIter),UNO_QUERY);
2198 if ( xChild.is() )
2199 pEntryData->eType = etQueryContainer;
2200 }
2201 implAppendEntry( _pParent, *pIter, pEntryData, pEntryData->eType );
2202 }
2203 }
2204 }
2205 catch(Exception&)
2206 {
2207 DBG_ERROR("SbaTableQueryBrowser::populateTree: could not fill the tree");
2208 }
2209 }
2210
2211 //------------------------------------------------------------------------------
implAppendEntry(SvLBoxEntry * _pParent,const String & _rName,void * _pUserData,EntryType _eEntryType)2212 SvLBoxEntry* SbaTableQueryBrowser::implAppendEntry( SvLBoxEntry* _pParent, const String& _rName, void* _pUserData, EntryType _eEntryType )
2213 {
2214 ::std::auto_ptr< ImageProvider > pImageProvider( getImageProviderFor( _pParent ) );
2215
2216 Image aImage, aImageHC;
2217 pImageProvider->getImages( _rName, getDatabaseObjectType( _eEntryType ), aImage, aImageHC );
2218
2219 SvLBoxEntry* pNewEntry = m_pTreeView->getListBox().InsertEntry( _rName, _pParent, _eEntryType == etQueryContainer , LIST_APPEND, _pUserData );
2220
2221 m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL );
2222 m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL );
2223 m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImageHC, BMP_COLOR_HIGHCONTRAST );
2224 m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImageHC, BMP_COLOR_HIGHCONTRAST );
2225
2226 return pNewEntry;
2227 }
2228
2229 //------------------------------------------------------------------------------
IMPL_LINK(SbaTableQueryBrowser,OnExpandEntry,SvLBoxEntry *,_pParent)2230 IMPL_LINK(SbaTableQueryBrowser, OnExpandEntry, SvLBoxEntry*, _pParent)
2231 {
2232 if (_pParent->HasChilds())
2233 // nothing to to ...
2234 return 1L;
2235
2236 SvLBoxEntry* pFirstParent = m_pTreeView->getListBox().GetRootLevelParent(_pParent);
2237 OSL_ENSURE(pFirstParent,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!");
2238
2239 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >(_pParent->GetUserData());
2240 OSL_ENSURE(pData,"SbaTableQueryBrowser::OnExpandEntry: No user data!");
2241 #if OSL_DEBUG_LEVEL > 0
2242 SvLBoxString* pString = static_cast<SvLBoxString*>(pFirstParent->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2243 OSL_ENSURE(pString,"SbaTableQueryBrowser::OnExpandEntry: No string item!");
2244 #endif
2245
2246 if (etTableContainer == pData->eType)
2247 {
2248 WaitObject aWaitCursor(getBrowserView());
2249
2250 // it could be that we already have a connection
2251 SharedConnection xConnection;
2252 ensureConnection( pFirstParent, xConnection );
2253
2254 if ( xConnection.is() )
2255 {
2256 SQLExceptionInfo aInfo;
2257 try
2258 {
2259 Reference< XWarningsSupplier > xWarnings(xConnection, UNO_QUERY);
2260 if (xWarnings.is())
2261 xWarnings->clearWarnings();
2262
2263 // first insert the views because the tables can also include
2264 // views but that time the bitmap is the wrong one
2265 // the nameaccess will be overwriten in populateTree
2266 Reference<XViewsSupplier> xViewSup(xConnection,UNO_QUERY);
2267 if(xViewSup.is())
2268 populateTree( xViewSup->getViews(), _pParent, etTableOrView );
2269
2270 Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY);
2271 if(xTabSup.is())
2272 {
2273 populateTree( xTabSup->getTables(), _pParent, etTableOrView );
2274 Reference<XContainer> xCont(xTabSup->getTables(),UNO_QUERY);
2275 if(xCont.is())
2276 // add as listener to know when elements are inserted or removed
2277 xCont->addContainerListener(this);
2278 }
2279
2280 if (xWarnings.is())
2281 {
2282 SQLExceptionInfo aWarnings(xWarnings->getWarnings());
2283 if (aWarnings.isValid() && sal_False)
2284 {
2285 SQLContext aContext;
2286 aContext.Message = String(ModuleRes(STR_OPENTABLES_WARNINGS));
2287 aContext.Details = String(ModuleRes(STR_OPENTABLES_WARNINGS_DETAILS));
2288 aContext.NextException = aWarnings.get();
2289 aWarnings = aContext;
2290 showError(aWarnings);
2291 }
2292 // TODO: we need a better concept for these warnings:
2293 // something like "don't show any warnings for this datasource, again" would be nice
2294 // But this requires an extension of the InteractionHandler and an additional property on the data source
2295 }
2296 }
2297 catch(const SQLContext& e) { aInfo = e; }
2298 catch(const SQLWarning& e) { aInfo = e; }
2299 catch(const SQLException& e) { aInfo = e; }
2300 catch(const WrappedTargetException& e)
2301 {
2302 SQLException aSql;
2303 if(e.TargetException >>= aSql)
2304 aInfo = aSql;
2305 else
2306 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::OnExpandEntry: something strange happended!");
2307 }
2308 catch( const Exception& )
2309 {
2310 DBG_UNHANDLED_EXCEPTION();
2311 }
2312 if (aInfo.isValid())
2313 showError(aInfo);
2314 }
2315 else
2316 return 0L;
2317 // 0 indicates that an error occured
2318 }
2319 else
2320 { // we have to expand the queries or bookmarks
2321 if (ensureEntryObject(_pParent))
2322 {
2323 DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( _pParent->GetUserData() );
2324 Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
2325 populateTree( xCollection, _pParent, etQuery );
2326 }
2327 }
2328 return 1L;
2329 }
2330
2331 //------------------------------------------------------------------------------
ensureEntryObject(SvLBoxEntry * _pEntry)2332 sal_Bool SbaTableQueryBrowser::ensureEntryObject( SvLBoxEntry* _pEntry )
2333 {
2334 DBG_ASSERT(_pEntry, "SbaTableQueryBrowser::ensureEntryObject: invalid argument!");
2335 if (!_pEntry)
2336 return sal_False;
2337
2338 EntryType eType = getEntryType( _pEntry );
2339
2340 // the user data of the entry
2341 DBTreeListUserData* pEntryData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData());
2342 OSL_ENSURE(pEntryData,"ensureEntryObject: user data should already be set!");
2343
2344 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(_pEntry);
2345
2346 sal_Bool bSuccess = sal_False;
2347 switch (eType)
2348 {
2349 case etQueryContainer:
2350 if ( pEntryData->xContainer.is() )
2351 {
2352 // nothing to do
2353 bSuccess = sal_True;
2354 break;
2355 }
2356
2357 {
2358 SvLBoxEntry* pParent = m_pTreeView->getListBox().GetParent(_pEntry);
2359 if ( pParent != pDataSourceEntry )
2360 {
2361 SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING);
2362 OSL_ENSURE(pString,"There must be a string item!");
2363 ::rtl::OUString aName(pString->GetText());
2364 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pParent->GetUserData());
2365 try
2366 {
2367 Reference< XNameAccess > xNameAccess(pData->xContainer,UNO_QUERY);
2368 if ( xNameAccess.is() )
2369 pEntryData->xContainer.set(xNameAccess->getByName(aName),UNO_QUERY);
2370 }
2371 catch(const Exception& )
2372 {
2373 DBG_UNHANDLED_EXCEPTION();
2374 }
2375
2376 bSuccess = pEntryData->xContainer.is();
2377 }
2378 else
2379 {
2380 try
2381 {
2382 Reference< XQueryDefinitionsSupplier > xQuerySup;
2383 m_xDatabaseContext->getByName( getDataSourceAcessor( pDataSourceEntry ) ) >>= xQuerySup;
2384 if (xQuerySup.is())
2385 {
2386 Reference< XNameAccess > xQueryDefs = xQuerySup->getQueryDefinitions();
2387 Reference< XContainer > xCont(xQueryDefs, UNO_QUERY);
2388 if (xCont.is())
2389 // add as listener to get notified if elements are inserted or removed
2390 xCont->addContainerListener(this);
2391
2392 pEntryData->xContainer = xQueryDefs;
2393 bSuccess = pEntryData->xContainer.is();
2394 }
2395 else {
2396 DBG_ERROR("SbaTableQueryBrowser::ensureEntryObject: no XQueryDefinitionsSupplier interface!");
2397 }
2398 }
2399 catch( const Exception& )
2400 {
2401 DBG_UNHANDLED_EXCEPTION();
2402 }
2403 }
2404 }
2405 break;
2406
2407 default:
2408 DBG_ERROR("SbaTableQueryBrowser::ensureEntryObject: ooops ... missing some implementation here!");
2409 // TODO ...
2410 break;
2411 }
2412
2413 return bSuccess;
2414 }
2415 //------------------------------------------------------------------------------
implSelect(const::svx::ODataAccessDescriptor & _rDescriptor,sal_Bool _bSelectDirect)2416 sal_Bool SbaTableQueryBrowser::implSelect(const ::svx::ODataAccessDescriptor& _rDescriptor,sal_Bool _bSelectDirect)
2417 {
2418 // extract the props
2419 ::rtl::OUString sDataSource;
2420 ::rtl::OUString sCommand;
2421 sal_Int32 nCommandType = CommandType::COMMAND;
2422 sal_Bool bEscapeProcessing = sal_True;
2423 extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
2424
2425 // select it
2426 return implSelect( sDataSource, sCommand, nCommandType, bEscapeProcessing, SharedConnection(), _bSelectDirect );
2427 }
2428
2429 //------------------------------------------------------------------------------
implLoadAnything(const::rtl::OUString & _rDataSourceName,const::rtl::OUString & _rCommand,const sal_Int32 _nCommandType,const sal_Bool _bEscapeProcessing,const SharedConnection & _rxConnection)2430 sal_Bool SbaTableQueryBrowser::implLoadAnything(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand,
2431 const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing, const SharedConnection& _rxConnection)
2432 {
2433 try
2434 {
2435 Reference<XPropertySet> xProp( getRowSet(), UNO_QUERY_THROW );
2436 Reference< XLoadable > xLoadable( xProp, UNO_QUERY_THROW );
2437 // the values allowing the RowSet to re-execute
2438 xProp->setPropertyValue(PROPERTY_DATASOURCENAME, makeAny(_rDataSourceName));
2439 if(_rxConnection.is())
2440 xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( _rxConnection.getTyped() ) );
2441
2442 // set this _before_ setting the connection, else the rowset would rebuild it ...
2443 xProp->setPropertyValue(PROPERTY_COMMAND_TYPE, makeAny(_nCommandType));
2444 xProp->setPropertyValue(PROPERTY_COMMAND, makeAny(_rCommand));
2445 xProp->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, ::cppu::bool2any(_bEscapeProcessing));
2446 if ( m_bPreview )
2447 {
2448 xProp->setPropertyValue(PROPERTY_FETCHDIRECTION, makeAny(FetchDirection::FORWARD));
2449 }
2450
2451 // the formatter depends on the data source we're working on, so rebuild it here ...
2452 initFormatter();
2453
2454 // switch the grid to design mode while loading
2455 getBrowserView()->getGridControl()->setDesignMode(sal_True);
2456 InitializeForm( xProp );
2457
2458 sal_Bool bSuccess = sal_True;
2459
2460 {
2461 {
2462 Reference< XNameContainer > xColContainer(getFormComponent(), UNO_QUERY);
2463 // first we have to clear the grid
2464 clearGridColumns(xColContainer);
2465 }
2466 FormErrorHelper aHelper(this);
2467 // load the form
2468 bSuccess = reloadForm(xLoadable);
2469
2470 // initialize the model
2471 InitializeGridModel(getFormComponent());
2472
2473 Any aVal = xProp->getPropertyValue(PROPERTY_ISNEW);
2474 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2475 {
2476 // then set the default values and the parameters given from the parent
2477 Reference< XReset> xReset(xProp, UNO_QUERY);
2478 xReset->reset();
2479 }
2480
2481 if ( m_bPreview )
2482 initializePreviewMode();
2483
2484 LoadFinished(sal_True);
2485 }
2486
2487 InvalidateAll();
2488 return bSuccess;
2489 }
2490 catch( const SQLException& e )
2491 {
2492 Any aException( ::cppu::getCaughtException() );
2493 showError( SQLExceptionInfo( aException ) );
2494 }
2495 catch( const WrappedTargetException& e )
2496 {
2497 SQLException aSql;
2498 if ( e.TargetException.isExtractableTo( ::cppu::UnoType< SQLException >::get() ) )
2499 showError( SQLExceptionInfo( e.TargetException ) );
2500 else
2501 {
2502 DBG_UNHANDLED_EXCEPTION();
2503 }
2504 }
2505 catch(Exception&)
2506 {
2507 DBG_UNHANDLED_EXCEPTION();
2508 }
2509
2510 InvalidateAll();
2511 return sal_False;
2512 }
2513
2514 //------------------------------------------------------------------------------
implSelect(const::rtl::OUString & _rDataSourceName,const::rtl::OUString & _rCommand,const sal_Int32 _nCommandType,const sal_Bool _bEscapeProcessing,const SharedConnection & _rxConnection,sal_Bool _bSelectDirect)2515 sal_Bool SbaTableQueryBrowser::implSelect(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand,
2516 const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing,
2517 const SharedConnection& _rxConnection
2518 ,sal_Bool _bSelectDirect)
2519 {
2520 if (_rDataSourceName.getLength() && _rCommand.getLength() && (-1 != _nCommandType))
2521 {
2522 SvLBoxEntry* pDataSource = NULL;
2523 SvLBoxEntry* pCommandType = NULL;
2524 SvLBoxEntry* pCommand = getObjectEntry( _rDataSourceName, _rCommand, _nCommandType, &pDataSource, &pCommandType, sal_True, _rxConnection );
2525
2526 if (pCommand)
2527 {
2528 bool bSuccess = true;
2529 if ( _bSelectDirect )
2530 {
2531 bSuccess = implSelect( pCommand );
2532 }
2533 else
2534 {
2535 m_pTreeView->getListBox().Select( pCommand );
2536 }
2537
2538 if ( bSuccess )
2539 {
2540 m_pTreeView->getListBox().MakeVisible(pCommand);
2541 m_pTreeView->getListBox().SetCursor(pCommand);
2542 }
2543 }
2544 else if (!pCommandType)
2545 {
2546 if ( m_pCurrentlyDisplayed )
2547 { // tell the old entry (if any) it has been deselected
2548 selectPath(m_pCurrentlyDisplayed, sal_False);
2549 m_pCurrentlyDisplayed = NULL;
2550 }
2551
2552 // we have a command and need to display this in the rowset
2553 return implLoadAnything(_rDataSourceName, _rCommand, _nCommandType, _bEscapeProcessing, _rxConnection);
2554 }
2555 }
2556 return sal_False;
2557 }
2558
2559 //------------------------------------------------------------------------------
2560 IMPL_LINK(SbaTableQueryBrowser, OnSelectionChange, void*, /*NOINTERESTEDIN*/)
2561 {
2562 return implSelect( m_pTreeView->getListBox().FirstSelected() ) ? 1L : 0L;
2563 }
2564 //------------------------------------------------------------------------------
implGetConnectionEntry(SvLBoxEntry * _pEntry) const2565 SvLBoxEntry* SbaTableQueryBrowser::implGetConnectionEntry(SvLBoxEntry* _pEntry) const
2566 {
2567 SvLBoxEntry* pCurrentEntry = _pEntry;
2568 DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() );
2569 while(pEntryData->eType != etDatasource )
2570 {
2571 pCurrentEntry = m_pTreeModel->GetParent(pCurrentEntry);
2572 pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() );
2573 }
2574 return pCurrentEntry;
2575 }
2576 //------------------------------------------------------------------------------
implSelect(SvLBoxEntry * _pEntry)2577 bool SbaTableQueryBrowser::implSelect( SvLBoxEntry* _pEntry )
2578 {
2579 if ( !_pEntry )
2580 return false;
2581
2582 DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() );
2583 switch (pEntryData->eType)
2584 {
2585 case etTableOrView:
2586 case etQuery:
2587 break;
2588 default:
2589 // nothing to do
2590 return false;
2591 }
2592
2593 OSL_ENSURE(m_pTreeModel->HasParent(_pEntry), "SbaTableQueryBrowser::implSelect: invalid entry (1)!");
2594 OSL_ENSURE(m_pTreeModel->HasParent(m_pTreeModel->GetParent(_pEntry)), "SbaTableQueryBrowser::implSelect: invalid entry (2)!");
2595
2596 // get the entry for the tables or queries
2597 SvLBoxEntry* pContainer = m_pTreeModel->GetParent(_pEntry);
2598 DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2599
2600 // get the entry for the datasource
2601 SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer);
2602 DBTreeListUserData* pConData = static_cast<DBTreeListUserData*>(pConnection->GetUserData());
2603
2604 // reinitialize the rowset
2605 // but first check if it is necessary
2606 // get all old properties
2607 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
2608 ::rtl::OUString aOldName;
2609 xRowSetProps->getPropertyValue(PROPERTY_COMMAND) >>= aOldName;
2610 sal_Int32 nOldType = 0;
2611 xRowSetProps->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nOldType;
2612 Reference<XConnection> xOldConnection(xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
2613
2614 // the name of the table or query
2615 SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING);
2616 OSL_ENSURE(pString,"There must be a string item!");
2617 const ::rtl::OUString sSimpleName = pString->GetText();
2618 ::rtl::OUStringBuffer sNameBuffer(sSimpleName);
2619 if ( etQueryContainer == pContainerData->eType )
2620 {
2621 SvLBoxEntry* pTemp = pContainer;
2622 while( m_pTreeModel->GetParent(pTemp) != pConnection )
2623 {
2624 sNameBuffer.insert(0,sal_Unicode('/'));
2625 pString = (SvLBoxString*)pTemp->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING);
2626 OSL_ENSURE(pString,"There must be a string item!");
2627 sNameBuffer.insert(0,pString->GetText());
2628 pTemp = m_pTreeModel->GetParent(pTemp);
2629 }
2630 }
2631 ::rtl::OUString aName = sNameBuffer.makeStringAndClear();
2632
2633 sal_Int32 nCommandType = ( etTableContainer == pContainerData->eType)
2634 ? CommandType::TABLE
2635 : CommandType::QUERY;
2636
2637 // check if need to rebuild the rowset
2638 sal_Bool bRebuild = ( xOldConnection != pConData->xConnection )
2639 || ( nOldType != nCommandType )
2640 || ( aName != aOldName );
2641
2642 Reference< ::com::sun::star::form::XLoadable > xLoadable = getLoadable();
2643 bRebuild |= !xLoadable->isLoaded();
2644 bool bSuccess = true;
2645 if ( bRebuild )
2646 {
2647 try
2648 {
2649 WaitObject aWaitCursor(getBrowserView());
2650
2651 // tell the old entry it has been deselected
2652 selectPath(m_pCurrentlyDisplayed, sal_False);
2653 m_pCurrentlyDisplayed = NULL;
2654
2655 // not really loaded
2656 m_pCurrentlyDisplayed = _pEntry;
2657 // tell the new entry it has been selected
2658 selectPath(m_pCurrentlyDisplayed, sal_True);
2659
2660 // get the name of the data source currently selected
2661 ensureConnection( m_pCurrentlyDisplayed, pConData->xConnection );
2662
2663 if ( !pConData->xConnection.is() )
2664 {
2665 unloadAndCleanup( sal_False );
2666 return false;
2667 }
2668
2669 Reference<XNameAccess> xNameAccess;
2670 switch(nCommandType)
2671 {
2672 case CommandType::TABLE:
2673 {
2674 // only for tables
2675 if ( !pContainerData->xContainer.is() )
2676 {
2677 Reference<XTablesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2678 if(xSup.is())
2679 xNameAccess = xSup->getTables();
2680
2681 pContainerData->xContainer = xNameAccess;
2682 }
2683 else
2684 xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2685 }
2686 break;
2687 case CommandType::QUERY:
2688 {
2689 if ( pContainerData->xContainer.is() )
2690 xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2691 else
2692 {
2693 Reference<XQueriesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2694 if(xSup.is())
2695 xNameAccess = xSup->getQueries();
2696 }
2697 }
2698 break;
2699 }
2700 String sStatus(ModuleRes( CommandType::TABLE == nCommandType ? STR_LOADING_TABLE : STR_LOADING_QUERY ));
2701 sStatus.SearchAndReplaceAscii("$name$", aName);
2702 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sStatus);
2703
2704
2705 sal_Bool bEscapeProcessing = sal_True;
2706 if(xNameAccess.is() && xNameAccess->hasByName(sSimpleName))
2707 {
2708 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData());
2709 if ( !pData->xObjectProperties.is() )
2710 {
2711 Reference<XInterface> xObject;
2712 if(xNameAccess->getByName(sSimpleName) >>= xObject) // remember the table or query object
2713 {
2714 pData->xObjectProperties = pData->xObjectProperties.query( xObject );
2715 // if the query contains a parameterized statement and preview is enabled we won't get any data.
2716 if ( nCommandType == CommandType::QUERY && xObject.is() )
2717 {
2718 Reference<XPropertySet> xObjectProps(xObject,UNO_QUERY);
2719 xObjectProps->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bEscapeProcessing;
2720 if ( m_bPreview )
2721 {
2722 ::rtl::OUString sSql;
2723 xObjectProps->getPropertyValue(PROPERTY_COMMAND) >>= sSql;
2724 Reference< XMultiServiceFactory > xFactory( pConData->xConnection, UNO_QUERY );
2725 if (xFactory.is())
2726 {
2727 try
2728 {
2729 Reference<XSingleSelectQueryAnalyzer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
2730 if ( xAnalyzer.is() )
2731 {
2732 xAnalyzer->setQuery(sSql);
2733 Reference<XParametersSupplier> xParSup(xAnalyzer,UNO_QUERY);
2734 if ( xParSup->getParameters()->getCount() > 0 )
2735 {
2736 String sFilter = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE "));
2737 sFilter = sFilter + xAnalyzer->getFilter();
2738 String sReplace(sSql);
2739 sReplace.SearchAndReplace(sFilter,String());
2740 xAnalyzer->setQuery(sReplace);
2741 Reference<XSingleSelectQueryComposer> xComposer(xAnalyzer,UNO_QUERY);
2742 xComposer->setFilter(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0=1")));
2743 aName = xAnalyzer->getQuery();
2744 nCommandType = CommandType::COMMAND;
2745 }
2746 }
2747 }
2748 catch (Exception&)
2749 {
2750 DBG_UNHANDLED_EXCEPTION();
2751 }
2752 }
2753 }
2754 }
2755 }
2756 }
2757 }
2758
2759 String sDataSourceName( getDataSourceAcessor( pConnection ) );
2760 bSuccess = implLoadAnything( sDataSourceName, aName, nCommandType, bEscapeProcessing, pConData->xConnection );
2761 if ( !bSuccess )
2762 { // clean up
2763 criticalFail();
2764 }
2765 }
2766 catch(const SQLException& e)
2767 {
2768 showError(SQLExceptionInfo(e));
2769 // reset the values
2770 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2771 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2772 }
2773 catch(WrappedTargetException& e)
2774 {
2775 SQLException aSql;
2776 if(e.TargetException >>= aSql)
2777 showError(SQLExceptionInfo(aSql));
2778 else
2779 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::implSelect: something strange happended!");
2780 // reset the values
2781 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2782 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2783 }
2784 catch(Exception&)
2785 {
2786 // reset the values
2787 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2788 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2789 }
2790 }
2791 return bSuccess;
2792 }
2793
2794 // -----------------------------------------------------------------------------
getEntryFromContainer(const Reference<XNameAccess> & _rxNameAccess)2795 SvLBoxEntry* SbaTableQueryBrowser::getEntryFromContainer(const Reference<XNameAccess>& _rxNameAccess)
2796 {
2797 DBTreeListBox& rListBox = m_pTreeView->getListBox();
2798 SvLBoxEntry* pContainer = NULL;
2799 SvLBoxEntry* pDSLoop = rListBox.FirstChild(NULL);
2800 while (pDSLoop)
2801 {
2802 pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_QUERIES);
2803 DBTreeListUserData* pQueriesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2804 if ( pQueriesData && pQueriesData->xContainer == _rxNameAccess )
2805 break;
2806
2807 pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_TABLES);
2808 DBTreeListUserData* pTablesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2809 if ( pTablesData && pTablesData->xContainer == _rxNameAccess )
2810 break;
2811
2812 pDSLoop = rListBox.NextSibling(pDSLoop);
2813 pContainer = NULL;
2814 }
2815 return pContainer;
2816 }
2817
2818 // -------------------------------------------------------------------------
elementInserted(const ContainerEvent & _rEvent)2819 void SAL_CALL SbaTableQueryBrowser::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException)
2820 {
2821 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2822
2823 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2824 // first search for a definition container where we can insert this element
2825
2826 SvLBoxEntry* pEntry = getEntryFromContainer(xNames);
2827 if(pEntry) // found one
2828 {
2829 // insert the new entry into the tree
2830 DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pEntry->GetUserData());
2831 OSL_ENSURE(pContainerData, "elementInserted: There must be user data for this type!");
2832
2833 DBTreeListUserData* pNewData = new DBTreeListUserData;
2834 sal_Bool bIsTable = etTableContainer == pContainerData->eType;
2835 if ( bIsTable )
2836 {
2837 _rEvent.Element >>= pNewData->xObjectProperties;// remember the new element
2838 pNewData->eType = etTableOrView;
2839 }
2840 else
2841 {
2842 if ((sal_Int32)m_pTreeView->getListBox().GetChildCount(pEntry) < ( xNames->getElementNames().getLength() - 1 ) )
2843 {
2844 // the item inserts its children on demand, but it has not been expanded yet. So ensure here and
2845 // now that it has all items
2846 populateTree(xNames, pEntry, etQuery );
2847 }
2848 pNewData->eType = etQuery;
2849 }
2850 implAppendEntry( pEntry, ::comphelper::getString( _rEvent.Accessor ), pNewData, pNewData->eType );
2851 }
2852 else
2853 SbaXDataBrowserController::elementInserted(_rEvent);
2854 }
2855 // -------------------------------------------------------------------------
isCurrentlyDisplayedChanged(const String & _sName,SvLBoxEntry * _pContainer)2856 sal_Bool SbaTableQueryBrowser::isCurrentlyDisplayedChanged(const String& _sName,SvLBoxEntry* _pContainer)
2857 {
2858 return m_pCurrentlyDisplayed
2859 && getEntryType(m_pCurrentlyDisplayed) == getChildType(_pContainer)
2860 && m_pTreeView->getListBox().GetParent(m_pCurrentlyDisplayed) == _pContainer
2861 && m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed) == _sName;
2862 }
2863 // -------------------------------------------------------------------------
elementRemoved(const ContainerEvent & _rEvent)2864 void SAL_CALL SbaTableQueryBrowser::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException)
2865 {
2866 ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
2867
2868 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2869 // get the top-level representing the removed data source
2870 // and search for the queries and tables
2871 SvLBoxEntry* pContainer = getEntryFromContainer(xNames);
2872 if ( pContainer )
2873 { // a query or table has been removed
2874 String aName = ::comphelper::getString(_rEvent.Accessor).getStr();
2875
2876 if ( isCurrentlyDisplayedChanged( aName, pContainer) )
2877 { // the element displayed currently has been replaced
2878
2879 // we need to remember the old value
2880 SvLBoxEntry* pTemp = m_pCurrentlyDisplayed;
2881
2882 // unload
2883 unloadAndCleanup( sal_False ); // don't dispose the connection
2884
2885 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData());
2886 pTemp->SetUserData(NULL);
2887 delete pData;
2888 // the data could be null because we have a table which isn't correct
2889 m_pTreeModel->Remove(pTemp);
2890 }
2891 else
2892 {
2893 // remove the entry from the model
2894 SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer);
2895 while(pChild)
2896 {
2897 if (m_pTreeView->getListBox().GetEntryText(pChild) == aName)
2898 {
2899 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData());
2900 pChild->SetUserData(NULL);
2901 delete pData;
2902 m_pTreeModel->Remove(pChild);
2903 break;
2904 }
2905 pChild = m_pTreeModel->NextSibling(pChild);
2906 }
2907 }
2908
2909 // maybe the object which is part of the document data source has been removed
2910 checkDocumentDataSource();
2911 }
2912 else
2913 SbaXDataBrowserController::elementRemoved(_rEvent);
2914 }
2915
2916 // -------------------------------------------------------------------------
elementReplaced(const ContainerEvent & _rEvent)2917 void SAL_CALL SbaTableQueryBrowser::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException)
2918 {
2919 ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
2920
2921 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2922 SvLBoxEntry* pContainer = getEntryFromContainer(xNames);
2923 if ( pContainer )
2924 { // a table or query as been replaced
2925 String aName = ::comphelper::getString(_rEvent.Accessor).getStr();
2926
2927 if ( isCurrentlyDisplayedChanged( aName, pContainer) )
2928 { // the element displayed currently has been replaced
2929
2930 // we need to remember the old value
2931 SvLBoxEntry* pTemp = m_pCurrentlyDisplayed;
2932 unloadAndCleanup( sal_False ); // don't dispose the connection
2933
2934 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData());
2935 if (pData)
2936 {
2937 if ( etTableOrView == pData->eType )
2938 { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2939 _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2940 }
2941 else
2942 {
2943 pTemp->SetUserData(NULL);
2944 delete pData;
2945 }
2946 }
2947 }
2948 else
2949 {
2950 // find the entry for this name
2951 SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer);
2952 while(pChild)
2953 {
2954 if (m_pTreeView->getListBox().GetEntryText(pChild) == aName)
2955 {
2956 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData());
2957 if (pData)
2958 {
2959 if ( etTableOrView == pData->eType )
2960 { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2961 _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2962 }
2963 else
2964 {
2965 pChild->SetUserData(NULL);
2966 delete pData;
2967 }
2968 }
2969 break;
2970 }
2971 pChild = m_pTreeModel->NextSibling(pChild);
2972 }
2973 }
2974
2975 // maybe the object which is part of the document data source has been removed
2976 checkDocumentDataSource();
2977 }
2978 else if (xNames.get() == m_xDatabaseContext.get())
2979 { // a datasource has been replaced in the context
2980 DBG_ERROR("SbaTableQueryBrowser::elementReplaced: no support for replaced data sources!");
2981 // very suspicious: the database context should not allow to replace data source, only to register
2982 // and revoke them
2983 }
2984 else
2985 SbaXDataBrowserController::elementReplaced(_rEvent);
2986 }
2987
2988 // -------------------------------------------------------------------------
impl_releaseConnection(SharedConnection & _rxConnection)2989 void SbaTableQueryBrowser::impl_releaseConnection( SharedConnection& _rxConnection )
2990 {
2991 // remove as event listener
2992 Reference< XComponent > xComponent( _rxConnection, UNO_QUERY );
2993 if ( xComponent.is() )
2994 {
2995 Reference< XEventListener > xListener( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY );
2996 xComponent->removeEventListener( xListener );
2997 }
2998
2999 try
3000 {
3001 // temporary (hopefully!) hack for #i55274#
3002 Reference< XFlushable > xFlush( _rxConnection, UNO_QUERY );
3003 if ( xFlush.is() )
3004 xFlush->flush();
3005 }
3006 catch( const Exception& )
3007 {
3008 DBG_UNHANDLED_EXCEPTION();
3009 }
3010
3011 // clear
3012 _rxConnection.clear();
3013 // will implicitly dispose if we have the ownership, since xConnection is a SharedConnection
3014 }
3015
3016 // -------------------------------------------------------------------------
disposeConnection(SvLBoxEntry * _pDSEntry)3017 void SbaTableQueryBrowser::disposeConnection( SvLBoxEntry* _pDSEntry )
3018 {
3019 DBG_ASSERT( _pDSEntry, "SbaTableQueryBrowser::disposeConnection: invalid entry (NULL)!" );
3020 DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::disposeConnection: invalid entry (not top-level)!" );
3021
3022 if ( _pDSEntry )
3023 {
3024 DBTreeListUserData* pTreeListData = static_cast< DBTreeListUserData* >( _pDSEntry->GetUserData() );
3025 if ( pTreeListData )
3026 impl_releaseConnection( pTreeListData->xConnection );
3027 }
3028 }
3029
3030 // -------------------------------------------------------------------------
closeConnection(SvLBoxEntry * _pDSEntry,sal_Bool _bDisposeConnection)3031 void SbaTableQueryBrowser::closeConnection(SvLBoxEntry* _pDSEntry,sal_Bool _bDisposeConnection)
3032 {
3033 DBG_ASSERT(_pDSEntry, "SbaTableQueryBrowser::closeConnection: invalid entry (NULL)!");
3034 DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::closeConnection: invalid entry (not top-level)!");
3035
3036 // if one of the entries of the given DS is displayed currently, unload the form
3037 if (m_pCurrentlyDisplayed && (m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed) == _pDSEntry))
3038 unloadAndCleanup(_bDisposeConnection);
3039
3040 // collapse the query/table container
3041 for (SvLBoxEntry* pContainers = m_pTreeModel->FirstChild(_pDSEntry); pContainers; pContainers= m_pTreeModel->NextSibling(pContainers))
3042 {
3043 SvLBoxEntry* pElements = m_pTreeModel->FirstChild(pContainers);
3044 if ( pElements )
3045 m_pTreeView->getListBox().Collapse(pContainers);
3046 m_pTreeView->getListBox().EnableExpandHandler(pContainers);
3047 // and delete their children (they are connection-relative)
3048 for (; pElements; )
3049 {
3050 SvLBoxEntry* pRemove = pElements;
3051 pElements= m_pTreeModel->NextSibling(pElements);
3052 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pRemove->GetUserData());
3053 pRemove->SetUserData(NULL);
3054 delete pData;
3055 m_pTreeModel->Remove(pRemove);
3056 }
3057 }
3058 // collapse the entry itself
3059 m_pTreeView->getListBox().Collapse(_pDSEntry);
3060
3061 // dispose/reset the connection
3062 if ( _bDisposeConnection )
3063 disposeConnection( _pDSEntry );
3064 }
3065
3066 // -------------------------------------------------------------------------
unloadAndCleanup(sal_Bool _bDisposeConnection)3067 void SbaTableQueryBrowser::unloadAndCleanup( sal_Bool _bDisposeConnection )
3068 {
3069 if (!m_pCurrentlyDisplayed)
3070 // nothing to do
3071 return;
3072
3073 SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed);
3074
3075 // de-select the path for the currently displayed table/query
3076 if (m_pCurrentlyDisplayed)
3077 {
3078 selectPath(m_pCurrentlyDisplayed, sal_False);
3079 }
3080 m_pCurrentlyDisplayed = NULL;
3081
3082 try
3083 {
3084 // get the active connection. We need to dispose it.
3085 Reference< XPropertySet > xRowSetProps(getRowSet(),UNO_QUERY);
3086 Reference< XConnection > xConn;
3087 xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION) >>= xConn;
3088 #if OSL_DEBUG_LEVEL > 1
3089 {
3090 Reference< XComponent > xComp;
3091 ::cppu::extractInterface(xComp, xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION));
3092 }
3093 #endif
3094
3095 // unload the form
3096 Reference< XLoadable > xLoadable = getLoadable();
3097 if (xLoadable->isLoaded())
3098 xLoadable->unload();
3099
3100 // clear the grid control
3101 Reference< XNameContainer > xConta(getControlModel(),UNO_QUERY);
3102 clearGridColumns(xConta);
3103
3104 // dispose the connection
3105 if(_bDisposeConnection)
3106 disposeConnection( pDSEntry );
3107 }
3108 catch(SQLException& e)
3109 {
3110 showError(SQLExceptionInfo(e));
3111 }
3112 catch(WrappedTargetException& e)
3113 {
3114 SQLException aSql;
3115 if(e.TargetException >>= aSql)
3116 showError(SQLExceptionInfo(aSql));
3117 else
3118 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::unloadAndCleanup: something strange happended!");
3119 }
3120 catch(Exception&)
3121 {
3122 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::unloadAndCleanup: could not reset the form");
3123 }
3124 }
3125
3126 // -------------------------------------------------------------------------
3127 namespace
3128 {
lcl_getDataSource(const Reference<XNameAccess> & _rxDatabaseContext,const::rtl::OUString & _rDataSourceName,const Reference<XConnection> & _rxConnection)3129 Reference< XInterface > lcl_getDataSource( const Reference< XNameAccess >& _rxDatabaseContext,
3130 const ::rtl::OUString& _rDataSourceName, const Reference< XConnection >& _rxConnection )
3131 {
3132 Reference< XDataSource > xDataSource;
3133 try
3134 {
3135 if ( _rDataSourceName.getLength() && _rxDatabaseContext->hasByName( _rDataSourceName ) )
3136 xDataSource.set( _rxDatabaseContext->getByName( _rDataSourceName ), UNO_QUERY_THROW );
3137
3138 if ( !xDataSource.is() )
3139 {
3140 Reference< XChild > xConnAsChild( _rxConnection, UNO_QUERY );
3141 if ( xConnAsChild.is() )
3142 xDataSource.set( xConnAsChild->getParent(), UNO_QUERY_THROW );
3143 }
3144 }
3145 catch( const Exception& )
3146 {
3147 DBG_UNHANDLED_EXCEPTION();
3148 }
3149 return xDataSource.get();
3150 }
3151 }
3152
3153 // -------------------------------------------------------------------------
impl_initialize()3154 void SbaTableQueryBrowser::impl_initialize()
3155 {
3156 ::vos::OGuard aGuard(Application::GetSolarMutex());
3157 // doin' a lot of VCL stuff here -> lock the SolarMutex
3158
3159 // first initialize the parent
3160 SbaXDataBrowserController::impl_initialize();
3161
3162 Reference<XConnection> xForeignConnection;
3163 Reference< XFrame > xFrame;
3164
3165 ::rtl::OUString aTableName, aCatalogName, aSchemaName;
3166
3167 sal_Bool bEsacpeProcessing = sal_True;
3168 sal_Int32 nInitialDisplayCommandType = CommandType::COMMAND;
3169 ::rtl::OUString sInitialDataSourceName;
3170 ::rtl::OUString sInitialCommand;
3171
3172 const NamedValueCollection& rArguments( getInitParams() );
3173
3174 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_DATASOURCENAME, sInitialDataSourceName );
3175 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND_TYPE, nInitialDisplayCommandType );
3176 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND, sInitialCommand );
3177 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, xForeignConnection );
3178 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_CATALOGNAME, aCatalogName );
3179 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_SCHEMANAME, aSchemaName );
3180 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_TABLENAME, aTableName );
3181 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, bEsacpeProcessing );
3182 rArguments.get_ensureType( "Frame", xFrame );
3183 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_SHOWMENU, m_bShowMenu );
3184
3185 // disable the browser if either of ShowTreeViewButton (compatibility name) or EnableBrowser
3186 // is present and set to FALSE
3187 sal_Bool bDisableBrowser = ( sal_False == rArguments.getOrDefault( "ShowTreeViewButton", sal_True ) ) // compatibility name
3188 || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_True ) );
3189 OSL_ENSURE( !rArguments.has( "ShowTreeViewButton" ),
3190 "SbaTableQueryBrowser::impl_initialize: ShowTreeViewButton is superseded by EnableBrowser!" );
3191 m_bEnableBrowser = !bDisableBrowser;
3192
3193 // hide the tree view it is disabled in general, or if the settings tell to hide it initially
3194 sal_Bool bHideTreeView = ( !m_bEnableBrowser )
3195 || ( sal_False == rArguments.getOrDefault( "ShowTreeView", sal_True ) ) // compatibility name
3196 || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_SHOW_BROWSER, sal_True ) );
3197 OSL_ENSURE( !rArguments.has( "ShowTreeView" ),
3198 "SbaTableQueryBrowser::impl_initialize: ShowTreeView is superseded by ShowBrowser!" );
3199
3200 if ( bHideTreeView )
3201 hideExplorer();
3202 else
3203 showExplorer();
3204
3205 if ( m_bPreview )
3206 {
3207 try
3208 {
3209 Sequence< ::rtl::OUString> aProperties(5);
3210 Sequence< Any> aValues(5);
3211
3212 ::rtl::OUString* pStringIter = aProperties.getArray();
3213 Any* pValueIter = aValues.getArray();
3214 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlwaysShowCursor"));
3215 *pValueIter++ <<= sal_False;
3216 *pStringIter++ = PROPERTY_BORDER;
3217 *pValueIter++ <<= sal_Int16(0);
3218
3219 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasNavigationBar"));
3220 *pValueIter++ <<= sal_False;
3221 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasRecordMarker"));
3222 *pValueIter++ <<= sal_False;
3223
3224 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tabstop"));
3225 *pValueIter++ <<= sal_False;
3226
3227 Reference< XMultiPropertySet > xFormMultiSet(getFormComponent(), UNO_QUERY);
3228 if ( xFormMultiSet.is() )
3229 xFormMultiSet->setPropertyValues(aProperties, aValues);
3230 }
3231 catch(Exception)
3232 {
3233 DBG_UNHANDLED_EXCEPTION();
3234 }
3235 }
3236
3237 // are we loaded into a (sub)frame of an embedded document (i.e. a form belonging to a database
3238 // document)?
3239 sal_Bool bSubFrameOfEmbeddedDocument = sal_False;
3240 if ( xFrame.is() )
3241 {
3242 Reference<XFramesSupplier> xSup = xFrame->getCreator();
3243 Reference<XController> xCont = xSup.is() ? xSup->getController() : Reference<XController>();
3244
3245 bSubFrameOfEmbeddedDocument = xCont.is() && ::dbtools::isEmbeddedInDatabase( xCont->getModel(), xForeignConnection );
3246 }
3247
3248 // if we have a connection at this point, it was either passed from outside, our
3249 // determined from a outer DB document. In both cases, do not dispose it later on.
3250 SharedConnection xConnection( xForeignConnection, SharedConnection::NoTakeOwnership );
3251
3252 // should we display all registered databases in the left hand side tree?
3253 // or only *one* special?
3254 sal_Bool bLimitedTreeEntries = sal_False;
3255 // if we're part of a frame which is a secondary frame of a database document, then only
3256 // display the database for this document, not all registered ones
3257 bLimitedTreeEntries |= bSubFrameOfEmbeddedDocument;
3258 // if the tree view is not to be displayed at all, then only display the data source
3259 // which was given as initial selection
3260 bLimitedTreeEntries |= ( m_bEnableBrowser != sal_True );
3261
3262 if ( bLimitedTreeEntries )
3263 {
3264 if ( xConnection.is() )
3265 {
3266 startConnectionListening( xConnection );
3267
3268 // if no initial name was given, try to obtain one from the data source
3269 if ( !sInitialDataSourceName.getLength() )
3270 {
3271 Reference< XChild > xChild( xConnection, UNO_QUERY );
3272 Reference< XPropertySet > xDataSourceProperties;
3273 if ( xChild.is() )
3274 xDataSourceProperties = xDataSourceProperties.query( xChild->getParent() );
3275 if ( xDataSourceProperties.is() )
3276 {
3277 try
3278 {
3279 OSL_VERIFY( xDataSourceProperties->getPropertyValue( PROPERTY_NAME ) >>= sInitialDataSourceName );
3280 }
3281 catch( const Exception& )
3282 {
3283 OSL_ENSURE( sal_False, "SbaTableQueryBrowser::impl_initialize: a connection parent which does not have a 'Name'!??" );
3284 }
3285 }
3286 }
3287 }
3288
3289 implAddDatasource( sInitialDataSourceName, xConnection );
3290 m_pTreeView->getListBox().Expand( m_pTreeView->getListBox().First() );
3291 }
3292 else
3293 initializeTreeModel();
3294
3295 if ( m_bEnableBrowser )
3296 {
3297 m_aDocScriptSupport = ::boost::optional< bool >( false );
3298 }
3299 else
3300 {
3301 // we are not used as "browser", but as mere view for a single table/query/command. In particular,
3302 // there is a specific database document which we belong to.
3303 Reference< XOfficeDatabaseDocument > xDocument( getDataSourceOrModel(
3304 lcl_getDataSource( m_xDatabaseContext, sInitialDataSourceName, xConnection ) ), UNO_QUERY );
3305 m_aDocScriptSupport = ::boost::optional< bool >( Reference< XEmbeddedScripts >( xDocument, UNO_QUERY ).is() );
3306 }
3307
3308 if ( implSelect( sInitialDataSourceName, sInitialCommand, nInitialDisplayCommandType, bEsacpeProcessing, xConnection, sal_True ) )
3309 {
3310 try
3311 {
3312 Reference< XPropertySet > xRowSetProps(getRowSet(), UNO_QUERY);
3313 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_CATALOGNAME,makeAny(aCatalogName));
3314 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_SCHEMANAME,makeAny(aSchemaName));
3315 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_TABLENAME,makeAny(aTableName));
3316
3317 }
3318 catch(const Exception&)
3319 {
3320 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::impl_initialize: could not set the update related names!");
3321 }
3322 }
3323
3324 InvalidateAll();
3325 }
3326
3327 // -------------------------------------------------------------------------
haveExplorer() const3328 sal_Bool SbaTableQueryBrowser::haveExplorer() const
3329 {
3330 return m_pTreeView && m_pTreeView->IsVisible();
3331 }
3332
3333 // -------------------------------------------------------------------------
hideExplorer()3334 void SbaTableQueryBrowser::hideExplorer()
3335 {
3336 if (!haveExplorer())
3337 return;
3338 if (!getBrowserView())
3339 return;
3340
3341 m_pTreeView->Hide();
3342 m_pSplitter->Hide();
3343 getBrowserView()->Resize();
3344
3345 InvalidateFeature(ID_BROWSER_EXPLORER);
3346 }
3347
3348 // -------------------------------------------------------------------------
showExplorer()3349 void SbaTableQueryBrowser::showExplorer()
3350 {
3351 if (haveExplorer())
3352 return;
3353
3354 if (!getBrowserView())
3355 return;
3356
3357 m_pTreeView->Show();
3358 m_pSplitter->Show();
3359 getBrowserView()->Resize();
3360
3361 InvalidateFeature(ID_BROWSER_EXPLORER);
3362 }
3363
3364 // -----------------------------------------------------------------------------
ensureConnection(SvLBoxEntry * _pAnyEntry,SharedConnection & _rConnection)3365 sal_Bool SbaTableQueryBrowser::ensureConnection(SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection)
3366 {
3367 SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(_pAnyEntry);
3368 DBTreeListUserData* pDSData =
3369 pDSEntry
3370 ? static_cast<DBTreeListUserData*>(pDSEntry->GetUserData())
3371 : NULL;
3372
3373 return ensureConnection( pDSEntry, pDSData, _rConnection );
3374 }
3375
3376 // -----------------------------------------------------------------------------
getImageProviderFor(SvLBoxEntry * _pAnyEntry)3377 ::std::auto_ptr< ImageProvider > SbaTableQueryBrowser::getImageProviderFor( SvLBoxEntry* _pAnyEntry )
3378 {
3379 ::std::auto_ptr< ImageProvider > pImageProvider( new ImageProvider );
3380 SharedConnection xConnection;
3381 if ( getExistentConnectionFor( _pAnyEntry, xConnection ) )
3382 pImageProvider.reset( new ImageProvider( xConnection ) );
3383 return pImageProvider;
3384 }
3385
3386 // -----------------------------------------------------------------------------
getExistentConnectionFor(SvLBoxEntry * _pAnyEntry,SharedConnection & _rConnection)3387 sal_Bool SbaTableQueryBrowser::getExistentConnectionFor( SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection )
3388 {
3389 SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent( _pAnyEntry );
3390 DBTreeListUserData* pDSData =
3391 pDSEntry
3392 ? static_cast< DBTreeListUserData* >( pDSEntry->GetUserData() )
3393 : NULL;
3394 if ( pDSData )
3395 _rConnection = pDSData->xConnection;
3396 return _rConnection.is();
3397 }
3398
3399 #ifdef DBG_UTIL
3400 // -----------------------------------------------------------------------------
impl_isDataSourceEntry(SvLBoxEntry * _pEntry) const3401 bool SbaTableQueryBrowser::impl_isDataSourceEntry( SvLBoxEntry* _pEntry ) const
3402 {
3403 return m_pTreeModel->GetRootLevelParent( _pEntry ) == _pEntry;
3404 }
3405 #endif
3406
3407 // -----------------------------------------------------------------------------
ensureConnection(SvLBoxEntry * _pDSEntry,void * pDSData,SharedConnection & _rConnection)3408 sal_Bool SbaTableQueryBrowser::ensureConnection( SvLBoxEntry* _pDSEntry, void* pDSData, SharedConnection& _rConnection )
3409 {
3410 DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::ensureConnection: this entry does not denote a data source!" );
3411 if(_pDSEntry)
3412 {
3413 DBTreeListUserData* pTreeListData = static_cast<DBTreeListUserData*>(pDSData);
3414 ::rtl::OUString aDSName = GetEntryText(_pDSEntry);
3415
3416 if ( pTreeListData )
3417 _rConnection = pTreeListData->xConnection;
3418
3419 if ( !_rConnection.is() && pTreeListData )
3420 {
3421 // show the "connecting to ..." status
3422 String sConnecting(ModuleRes(STR_CONNECTING_DATASOURCE));
3423 sConnecting.SearchAndReplaceAscii("$name$", aDSName);
3424 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sConnecting);
3425
3426 // build a string showing context information in case of error
3427 String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) );
3428 sConnectingContext.SearchAndReplaceAscii("$name$", aDSName);
3429
3430 // connect
3431 _rConnection.reset(
3432 connect( getDataSourceAcessor( _pDSEntry ), sConnectingContext, NULL ),
3433 SharedConnection::TakeOwnership
3434 );
3435
3436 // remember the connection
3437 pTreeListData->xConnection = _rConnection;
3438 }
3439 }
3440
3441 return _rConnection.is();
3442 }
3443
3444 // -----------------------------------------------------------------------------
IMPL_LINK(SbaTableQueryBrowser,OnTreeEntryCompare,const SvSortData *,_pSortData)3445 IMPL_LINK( SbaTableQueryBrowser, OnTreeEntryCompare, const SvSortData*, _pSortData )
3446 {
3447 SvLBoxEntry* pLHS = static_cast<SvLBoxEntry*>(_pSortData->pLeft);
3448 SvLBoxEntry* pRHS = static_cast<SvLBoxEntry*>(_pSortData->pRight);
3449 DBG_ASSERT(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!");
3450 // we want the table entry and the end so we have to do a check
3451
3452 if (isContainer(pRHS))
3453 {
3454 // don't use getEntryType (directly or indirecly) for the LHS:
3455 // LHS is currently beeing inserted, so it is not "completely valid" at the moment
3456
3457 const EntryType eRight = getEntryType(pRHS);
3458 if (etTableContainer == eRight)
3459 // every other container should be placed _before_ the bookmark container
3460 return -1;
3461
3462 const String sLeft = m_pTreeView->getListBox().GetEntryText(pLHS);
3463
3464 EntryType eLeft = etTableContainer;
3465 if (String(ModuleRes(RID_STR_TABLES_CONTAINER)) == sLeft)
3466 eLeft = etTableContainer;
3467 else if (String(ModuleRes(RID_STR_QUERIES_CONTAINER)) == sLeft)
3468 eLeft = etQueryContainer;
3469
3470 if ( eLeft == eRight )
3471 return COMPARE_EQUAL;
3472
3473 if ( ( eLeft == etTableContainer ) && ( eRight == etQueryContainer ) )
3474 return COMPARE_GREATER;
3475
3476 if ( ( eLeft == etQueryContainer ) && ( eRight == etTableContainer ) )
3477 return COMPARE_LESS;
3478
3479 OSL_ENSURE( false, "SbaTableQueryBrowser::OnTreeEntryCompare: unexpected case!" );
3480 return COMPARE_EQUAL;
3481 }
3482
3483 SvLBoxString* pLeftTextItem = static_cast<SvLBoxString*>(pLHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
3484 SvLBoxString* pRightTextItem = static_cast<SvLBoxString*>(pRHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
3485 DBG_ASSERT(pLeftTextItem && pRightTextItem, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid text items!");
3486
3487 String sLeftText = pLeftTextItem->GetText();
3488 String sRightText = pRightTextItem->GetText();
3489
3490 sal_Int32 nCompareResult = 0; // equal by default
3491
3492 if (m_xCollator.is())
3493 {
3494 try
3495 {
3496 nCompareResult = m_xCollator->compareString(sLeftText, sRightText);
3497 }
3498 catch(Exception&)
3499 {
3500 }
3501 }
3502 else
3503 // default behaviour if we do not have a collator -> do the simple string compare
3504 nCompareResult = sLeftText.CompareTo(sRightText);
3505
3506 return nCompareResult;
3507 }
3508
3509 // -----------------------------------------------------------------------------
implAdministrate(SvLBoxEntry * _pApplyTo)3510 void SbaTableQueryBrowser::implAdministrate( SvLBoxEntry* _pApplyTo )
3511 {
3512 OSL_PRECOND( _pApplyTo, "SbaTableQueryBrowser::implAdministrate: illegal entry!" );
3513 if ( !_pApplyTo )
3514 return;
3515
3516 try
3517 {
3518 // get the desktop object
3519 sal_Int32 nFrameSearchFlag = FrameSearchFlag::ALL | FrameSearchFlag::GLOBAL ;
3520 Reference< XComponentLoader > xFrameLoader(getORB()->createInstance(SERVICE_FRAME_DESKTOP),UNO_QUERY);
3521
3522 if ( xFrameLoader.is() )
3523 {
3524 // the initial selection
3525 SvLBoxEntry* pTopLevelSelected = _pApplyTo;
3526 while (pTopLevelSelected && m_pTreeView->getListBox().GetParent(pTopLevelSelected))
3527 pTopLevelSelected = m_pTreeView->getListBox().GetParent(pTopLevelSelected);
3528 ::rtl::OUString sInitialSelection;
3529 if (pTopLevelSelected)
3530 sInitialSelection = getDataSourceAcessor( pTopLevelSelected );
3531
3532 Reference< XDataSource > xDataSource( getDataSourceByName( sInitialSelection, getView(), getORB(), NULL ) );
3533 Reference< XModel > xDocumentModel( getDataSourceOrModel( xDataSource ), UNO_QUERY );
3534
3535 if ( xDocumentModel.is() )
3536 {
3537 Reference< XInteractionHandler > xInteractionHandler(
3538 getORB()->createInstance(
3539 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ),
3540 UNO_QUERY );
3541 OSL_ENSURE( xInteractionHandler.is(), "SbaTableQueryBrowser::implAdministrate: no interaction handler available!" );
3542
3543 ::comphelper::NamedValueCollection aLoadArgs;
3544 aLoadArgs.put( "Model", xDocumentModel );
3545 aLoadArgs.put( "InteractionHandler", xInteractionHandler );
3546 aLoadArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
3547
3548 Sequence< PropertyValue > aLoadArgPV;
3549 aLoadArgs >>= aLoadArgPV;
3550
3551 xFrameLoader->loadComponentFromURL(
3552 xDocumentModel->getURL(),
3553 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_default")),
3554 nFrameSearchFlag,
3555 aLoadArgPV
3556 );
3557 }
3558 }
3559 }
3560 catch( const Exception& )
3561 {
3562 DBG_UNHANDLED_EXCEPTION();
3563 }
3564 }
3565
3566 // -----------------------------------------------------------------------------
requestQuickHelp(const SvLBoxEntry * _pEntry,String & _rText) const3567 sal_Bool SbaTableQueryBrowser::requestQuickHelp( const SvLBoxEntry* _pEntry, String& _rText ) const
3568 {
3569 const DBTreeListUserData* pData = static_cast< const DBTreeListUserData* >( _pEntry->GetUserData() );
3570 if ( ( pData->eType == etDatasource ) && pData->sAccessor.Len() )
3571 {
3572 _rText = ::svt::OFileNotation( pData->sAccessor ).get( ::svt::OFileNotation::N_SYSTEM );
3573 return sal_True;
3574 }
3575 return sal_False;
3576 }
3577
3578 // -----------------------------------------------------------------------------
getContextMenu(Control & _rControl) const3579 PopupMenu* SbaTableQueryBrowser::getContextMenu( Control& _rControl ) const
3580 {
3581 OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl,
3582 "SbaTableQueryBrowser::getContextMenu: where does this come from?" );
3583 if ( &m_pTreeView->getListBox() != &_rControl )
3584 return NULL;
3585
3586 return new PopupMenu( ModuleRes( MENU_BROWSER_DEFAULTCONTEXT ) );
3587 }
3588
3589 // -----------------------------------------------------------------------------
getCommandController()3590 IController& SbaTableQueryBrowser::getCommandController()
3591 {
3592 return *this;
3593 }
3594
3595 // -----------------------------------------------------------------------------
getContextMenuInterceptors()3596 ::cppu::OInterfaceContainerHelper* SbaTableQueryBrowser::getContextMenuInterceptors()
3597 {
3598 return &m_aContextMenuInterceptors;
3599 }
3600
3601 // -----------------------------------------------------------------------------
getCurrentSelection(Control & _rControl) const3602 Any SbaTableQueryBrowser::getCurrentSelection( Control& _rControl ) const
3603 {
3604 OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl,
3605 "SbaTableQueryBrowser::getCurrentSelection: where does this come from?" );
3606
3607 if ( &m_pTreeView->getListBox() != &_rControl )
3608 return Any();
3609
3610 SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected();
3611 if ( !pSelected )
3612 return Any();
3613
3614 OSL_ENSURE( m_pTreeView->getListBox().NextSelected( pSelected ) == NULL,
3615 "SbaTableQueryBrowser::getCurrentSelection: single-selection is expected here!" );
3616
3617 NamedDatabaseObject aSelectedObject;
3618 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pSelected->GetUserData() );
3619 aSelectedObject.Type = static_cast< sal_Int32 >( pData->eType );
3620
3621 switch ( aSelectedObject.Type )
3622 {
3623 case DatabaseObject::QUERY:
3624 case DatabaseObject::TABLE:
3625 aSelectedObject.Name = m_pTreeView->getListBox().GetEntryText( pSelected );
3626 break;
3627
3628 case DatabaseObjectContainer::DATA_SOURCE:
3629 case DatabaseObjectContainer::QUERIES:
3630 case DatabaseObjectContainer::TABLES:
3631 aSelectedObject.Name = getDataSourceAcessor( pSelected );
3632 break;
3633
3634 default:
3635 OSL_ENSURE( false, "SbaTableQueryBrowser::getCurrentSelection: invalid (unexpected) object type!" );
3636 break;
3637 }
3638
3639 return makeAny( aSelectedObject );
3640 }
3641
3642 // -----------------------------------------------------------------------------
implGetQuerySignature(::rtl::OUString & _rCommand,sal_Bool & _bEscapeProcessing)3643 sal_Bool SbaTableQueryBrowser::implGetQuerySignature( ::rtl::OUString& _rCommand, sal_Bool& _bEscapeProcessing )
3644 {
3645 _rCommand = ::rtl::OUString();
3646 _bEscapeProcessing = sal_False;
3647
3648 try
3649 {
3650 // ontain the dss (data source signature) of the form
3651 ::rtl::OUString sDataSourceName;
3652 ::rtl::OUString sCommand;
3653 sal_Int32 nCommandType = CommandType::COMMAND;
3654 Reference< XPropertySet > xRowsetProps( getRowSet(), UNO_QUERY );
3655 ODataAccessDescriptor aDesc( xRowsetProps );
3656 sDataSourceName = aDesc.getDataSource();
3657 aDesc[ daCommand ] >>= sCommand;
3658 aDesc[ daCommandType ] >>= nCommandType;
3659
3660 // do we need to do anything?
3661 if ( CommandType::QUERY != nCommandType )
3662 return sal_False;
3663
3664 // get the query object
3665 Reference< XQueryDefinitionsSupplier > xSuppQueries;
3666 Reference< XNameAccess > xQueries;
3667 Reference< XPropertySet > xQuery;
3668 m_xDatabaseContext->getByName( sDataSourceName ) >>= xSuppQueries;
3669 if ( xSuppQueries.is() )
3670 xQueries = xSuppQueries->getQueryDefinitions();
3671 if ( xQueries.is() )
3672 xQueries->getByName( sCommand ) >>= xQuery;
3673 OSL_ENSURE( xQuery.is(), "SbaTableQueryBrowser::implGetQuerySignature: could not retrieve the query object!" );
3674
3675 // get the two properties we need
3676 if ( xQuery.is() )
3677 {
3678 xQuery->getPropertyValue( PROPERTY_COMMAND ) >>= _rCommand;
3679 _bEscapeProcessing = ::cppu::any2bool( xQuery->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) );
3680 return sal_True;
3681 }
3682 }
3683 catch( const Exception& )
3684 {
3685 DBG_UNHANDLED_EXCEPTION();
3686 }
3687
3688 return sal_False;
3689 }
3690 //------------------------------------------------------------------------------
frameAction(const::com::sun::star::frame::FrameActionEvent & aEvent)3691 void SbaTableQueryBrowser::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException )
3692 {
3693 if (aEvent.Frame == m_xCurrentFrameParent)
3694 {
3695 if(aEvent.Action == FrameAction_COMPONENT_DETACHING)
3696 implRemoveStatusListeners();
3697 else if (aEvent.Action == FrameAction_COMPONENT_REATTACHED)
3698 connectExternalDispatches();
3699 }
3700 else
3701 SbaXDataBrowserController::frameAction(aEvent);
3702
3703 }
3704 // -----------------------------------------------------------------------------
clearGridColumns(const Reference<XNameContainer> & _xColContainer)3705 void SbaTableQueryBrowser::clearGridColumns(const Reference< XNameContainer >& _xColContainer)
3706 {
3707 // first we have to clear the grid
3708 Sequence< ::rtl::OUString > aNames = _xColContainer->getElementNames();
3709 const ::rtl::OUString* pIter = aNames.getConstArray();
3710 const ::rtl::OUString* pEnd = pIter + aNames.getLength();
3711 Reference< XInterface > xColumn;
3712 for (; pIter != pEnd;++pIter)
3713 {
3714 _xColContainer->getByName(*pIter) >>= xColumn;
3715 _xColContainer->removeByName(*pIter);
3716 ::comphelper::disposeComponent(xColumn);
3717 }
3718 }
3719 // -----------------------------------------------------------------------------
isHiContrast() const3720 sal_Bool SbaTableQueryBrowser::isHiContrast() const
3721 {
3722 sal_Bool bRet = sal_False;
3723 if ( m_pTreeView )
3724 bRet = m_pTreeView->getListBox().GetSettings().GetStyleSettings().GetHighContrastMode();
3725 return bRet;
3726 }
3727 // -----------------------------------------------------------------------------
loadMenu(const Reference<XFrame> & _xFrame)3728 void SbaTableQueryBrowser::loadMenu(const Reference< XFrame >& _xFrame)
3729 {
3730 if ( m_bShowMenu )
3731 {
3732 OGenericUnoController::loadMenu(_xFrame);
3733 }
3734 else if ( !m_bPreview )
3735 {
3736 Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager = getLayoutManager(_xFrame);
3737
3738 if ( xLayoutManager.is() )
3739 {
3740 xLayoutManager->lock();
3741 xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" )));
3742 xLayoutManager->unlock();
3743 xLayoutManager->doLayout();
3744 }
3745 onLoadedMenu( xLayoutManager );
3746 }
3747 }
3748 // -----------------------------------------------------------------------------
getPrivateTitle() const3749 ::rtl::OUString SbaTableQueryBrowser::getPrivateTitle() const
3750 {
3751 ::rtl::OUString sTitle;
3752 if ( m_pCurrentlyDisplayed )
3753 {
3754 SvLBoxEntry* pContainer = m_pTreeModel->GetParent(m_pCurrentlyDisplayed);
3755 // get the entry for the datasource
3756 SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer);
3757 ::rtl::OUString sName = m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed);
3758 sTitle = GetEntryText( pConnection );
3759 INetURLObject aURL(sTitle);
3760 if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )
3761 sTitle = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET);
3762 if ( sName.getLength() )
3763 {
3764 sName += ::rtl::OUString::createFromAscii(" - ");
3765 sName += sTitle;
3766 sTitle = sName;
3767 }
3768 }
3769
3770 return sTitle;
3771 }
3772 // -----------------------------------------------------------------------------
preReloadForm()3773 sal_Bool SbaTableQueryBrowser::preReloadForm()
3774 {
3775 sal_Bool bIni = sal_False;
3776 if ( !m_pCurrentlyDisplayed )
3777 {
3778 // switch the grid to design mode while loading
3779 getBrowserView()->getGridControl()->setDesignMode(sal_True);
3780 // we had an invalid statement so we need to connect the column models
3781 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
3782 ::svx::ODataAccessDescriptor aDesc(xRowSetProps);
3783 // extract the props
3784 ::rtl::OUString sDataSource;
3785 ::rtl::OUString sCommand;
3786 sal_Int32 nCommandType = CommandType::COMMAND;
3787 sal_Bool bEscapeProcessing = sal_True;
3788 extractDescriptorProps(aDesc, sDataSource, sCommand, nCommandType, bEscapeProcessing);
3789 if ( sDataSource.getLength() && sCommand.getLength() && (-1 != nCommandType) )
3790 {
3791 SvLBoxEntry* pDataSource = NULL;
3792 SvLBoxEntry* pCommandType = NULL;
3793 m_pCurrentlyDisplayed = getObjectEntry( sDataSource, sCommand, nCommandType, &pDataSource, &pCommandType, sal_True, SharedConnection() );
3794 bIni = sal_True;
3795 }
3796 }
3797 return bIni;
3798 }
3799
3800 // -----------------------------------------------------------------------------
postReloadForm()3801 void SbaTableQueryBrowser::postReloadForm()
3802 {
3803 InitializeGridModel(getFormComponent());
3804 LoadFinished(sal_True);
3805 //updateTitle();
3806 }
3807
3808 //------------------------------------------------------------------------------
getScriptContainer()3809 Reference< XEmbeddedScripts > SAL_CALL SbaTableQueryBrowser::getScriptContainer() throw (RuntimeException)
3810 {
3811 // update our database document
3812 Reference< XModel > xDocument;
3813 try
3814 {
3815 Reference< XPropertySet > xCursorProps( getRowSet(), UNO_QUERY_THROW );
3816 Reference< XConnection > xConnection( xCursorProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY );
3817 if ( xConnection.is() )
3818 {
3819 Reference< XChild > xChild( xConnection, UNO_QUERY_THROW );
3820 Reference< XDocumentDataSource > xDataSource( xChild->getParent(), UNO_QUERY_THROW );
3821 xDocument.set( xDataSource->getDatabaseDocument(), UNO_QUERY_THROW );
3822 }
3823 }
3824 catch( const Exception& )
3825 {
3826 DBG_UNHANDLED_EXCEPTION();
3827 }
3828 Reference< XEmbeddedScripts > xScripts( xDocument, UNO_QUERY );
3829 OSL_ENSURE( xScripts.is() || !xDocument.is(),
3830 "SbaTableQueryBrowser::getScriptContainer: invalid database document!" );
3831 return xScripts;
3832 }
3833
3834 //------------------------------------------------------------------------------
registerContextMenuInterceptor(const Reference<XContextMenuInterceptor> & _Interceptor)3835 void SAL_CALL SbaTableQueryBrowser::registerContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException)
3836 {
3837 if ( _Interceptor.is() )
3838 m_aContextMenuInterceptors.addInterface( _Interceptor );
3839 }
3840
3841 //------------------------------------------------------------------------------
releaseContextMenuInterceptor(const Reference<XContextMenuInterceptor> & _Interceptor)3842 void SAL_CALL SbaTableQueryBrowser::releaseContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException)
3843 {
3844 if ( _Interceptor.is() )
3845 m_aContextMenuInterceptors.removeInterface( _Interceptor );
3846 }
3847
3848 //------------------------------------------------------------------------------
registeredDatabaseLocation(const DatabaseRegistrationEvent & _Event)3849 void SAL_CALL SbaTableQueryBrowser::registeredDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException)
3850 {
3851 ::vos::OGuard aGuard( Application::GetSolarMutex() );
3852 implAddDatasource( _Event.Name, SharedConnection() );
3853 }
3854
3855 //------------------------------------------------------------------------------
impl_cleanupDataSourceEntry(const String & _rDataSourceName)3856 void SbaTableQueryBrowser::impl_cleanupDataSourceEntry( const String& _rDataSourceName )
3857 {
3858 // get the top-level representing the removed data source
3859 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().FirstChild( NULL );
3860 while ( pDataSourceEntry )
3861 {
3862 if ( m_pTreeView->getListBox().GetEntryText( pDataSourceEntry ) == _rDataSourceName )
3863 break;
3864
3865 pDataSourceEntry = m_pTreeView->getListBox().NextSibling( pDataSourceEntry );
3866 }
3867
3868 OSL_ENSURE( pDataSourceEntry, "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: do not know this data source!" );
3869 if ( !pDataSourceEntry )
3870 return;
3871
3872 if ( isSelected( pDataSourceEntry ) )
3873 { // a table or query belonging to the deleted data source is currently beeing displayed.
3874 OSL_ENSURE( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) == pDataSourceEntry,
3875 "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (1)!" );
3876 unloadAndCleanup( sal_True );
3877 }
3878 else
3879 OSL_ENSURE(
3880 ( NULL == m_pCurrentlyDisplayed )
3881 || ( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) != pDataSourceEntry ),
3882 "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (2)!");
3883
3884 // delete any user data of the child entries of the to-be-removed entry
3885 SvTreeEntryList* pList = m_pTreeModel->GetChildList( pDataSourceEntry );
3886 if ( pList )
3887 {
3888 SvLBoxEntry* pEntryLoop = static_cast<SvLBoxEntry*>( pList->First() );
3889 while ( pEntryLoop )
3890 {
3891 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pEntryLoop->GetUserData() );
3892 pEntryLoop->SetUserData( NULL );
3893 delete pData;
3894 pEntryLoop = static_cast< SvLBoxEntry* >( pList->Next() );
3895 }
3896 }
3897
3898 // remove the entry
3899 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() );
3900 pDataSourceEntry->SetUserData( NULL );
3901 delete pData;
3902 m_pTreeModel->Remove( pDataSourceEntry );
3903 }
3904
3905 //------------------------------------------------------------------------------
revokedDatabaseLocation(const DatabaseRegistrationEvent & _Event)3906 void SAL_CALL SbaTableQueryBrowser::revokedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException)
3907 {
3908 ::vos::OGuard aGuard( Application::GetSolarMutex() );
3909
3910 impl_cleanupDataSourceEntry( _Event.Name );
3911
3912 // maybe the object which is part of the document data source has been removed
3913 checkDocumentDataSource();
3914 }
3915
3916 //------------------------------------------------------------------------------
changedDatabaseLocation(const DatabaseRegistrationEvent & _Event)3917 void SAL_CALL SbaTableQueryBrowser::changedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException)
3918 {
3919 ::vos::OGuard aGuard( Application::GetSolarMutex() );
3920
3921 // in case the data source was expanded, and connected, we need to clean it up
3922 // for simplicity, just do as if the data source were completely removed and re-added
3923 impl_cleanupDataSourceEntry( _Event.Name );
3924 implAddDatasource( _Event.Name, SharedConnection() );
3925 }
3926
3927
3928 // .........................................................................
3929 } // namespace dbaui
3930 // .........................................................................
3931
3932
3933