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 // ------------------------------------------------------------------------- 174 extern "C" void SAL_CALL createRegistryInfo_OBrowser() 175 { 176 static OMultiInstanceAutoRegistration< SbaTableQueryBrowser > aAutoRegistration; 177 } 178 // ------------------------------------------------------------------------- 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 // ------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 194 ::rtl::OUString SAL_CALL SbaTableQueryBrowser::getImplementationName() throw(RuntimeException) 195 { 196 return getImplementationName_Static(); 197 } 198 //------------------------------------------------------------------------- 199 ::comphelper::StringSequence SAL_CALL SbaTableQueryBrowser::getSupportedServiceNames() throw(RuntimeException) 200 { 201 return getSupportedServiceNames_Static(); 202 } 203 // ------------------------------------------------------------------------- 204 ::rtl::OUString SbaTableQueryBrowser::getImplementationName_Static() throw(RuntimeException) 205 { 206 return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.ODatasourceBrowser"); 207 } 208 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 { 425 const Any& operator()( ::rtl::OUString const& i_name ) const 426 { 427 return m_rCollection.get( i_name ); 428 } 429 430 SelectValueByName( ::comphelper::NamedValueCollection const& i_collection ) 431 :m_rCollection( i_collection ) 432 { 433 } 434 435 ::comphelper::NamedValueCollection const& m_rCollection; 436 }; 437 } 438 439 // --------------------------------------------------------------------------------------------------------------------- 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 // --------------------------------------------------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------- 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 // ----------------------------------------------------------------------- 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 // ----------------------------------------------------------------------- 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 // ------------------------------------------------------------------------- 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 // ------------------------------------------------------------------------- 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 // ------------------------------------------------------------------------- 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 { 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; 1154 FilterByEntryDataId( const String& _rId ) : sId( _rId ) { } 1155 1156 virtual ~FilterByEntryDataId() {} 1157 1158 virtual bool includeEntry( SvLBoxEntry* _pEntry ) const; 1159 }; 1160 1161 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 // ------------------------------------------------------------------------- 1169 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 // ------------------------------------------------------------------------- 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 // ------------------------------------------------------------------------- 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 // ------------------------------------------------------------------------- 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 // ------------------------------------------------------------------------- 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 // ------------------------------------------------------------------------- 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 ++aLoop 1412 ) 1413 { 1414 if ( aLoop->second.xDispatcher.get() == xSource.get() ) 1415 { 1416 ExternalFeaturesMap::iterator aPrevious = aLoop; 1417 --aPrevious; 1418 1419 // remove it 1420 m_aExternalFeatures.erase( aLoop ); 1421 1422 // maybe update the UI 1423 implCheckExternalSlot(aLoop->first); 1424 1425 // continue, the same XDispatch may be resposible for more than one URL 1426 aLoop = aPrevious; 1427 } 1428 } 1429 } 1430 else 1431 { 1432 Reference<XConnection> xCon(_rSource.Source, UNO_QUERY); 1433 if ( xCon.is() && m_pTreeView ) 1434 { // our connection is in dispose so we have to find the entry equal with this connection 1435 // and close it what means to collapse the entry 1436 // get the top-level representing the removed data source 1437 SvLBoxEntry* pDSLoop = m_pTreeView->getListBox().FirstChild(NULL); 1438 while (pDSLoop) 1439 { 1440 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pDSLoop->GetUserData()); 1441 if ( pData && pData->xConnection == xCon ) 1442 { 1443 // we set the conenction to null to avoid a second disposing of the connection 1444 pData->xConnection.clear(); 1445 closeConnection(pDSLoop,sal_False); 1446 break; 1447 } 1448 1449 pDSLoop = m_pTreeView->getListBox().NextSibling(pDSLoop); 1450 } 1451 } 1452 else 1453 SbaXDataBrowserController::disposing(_rSource); 1454 } 1455 } 1456 } 1457 1458 // ------------------------------------------------------------------------- 1459 void SbaTableQueryBrowser::implRemoveStatusListeners() 1460 { 1461 // clear all old dispatches 1462 for ( ExternalFeaturesMap::const_iterator aLoop = m_aExternalFeatures.begin(); 1463 aLoop != m_aExternalFeatures.end(); 1464 ++aLoop 1465 ) 1466 { 1467 if ( aLoop->second.xDispatcher.is() ) 1468 { 1469 try 1470 { 1471 aLoop->second.xDispatcher->removeStatusListener( this, aLoop->second.aURL ); 1472 } 1473 catch (Exception&) 1474 { 1475 DBG_ERROR("SbaTableQueryBrowser::implRemoveStatusListeners: could not remove a status listener!"); 1476 } 1477 } 1478 } 1479 m_aExternalFeatures.clear(); 1480 } 1481 1482 // ------------------------------------------------------------------------- 1483 sal_Bool SAL_CALL SbaTableQueryBrowser::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException) 1484 { 1485 ::vos::OGuard aGuard(Application::GetSolarMutex()); 1486 // doin' a lot of VCL stuff here -> lock the SolarMutex 1487 1488 Sequence< PropertyValue > aDescriptorSequence; 1489 if (!(_rSelection >>= aDescriptorSequence)) 1490 throw IllegalArgumentException(::rtl::OUString(), *this, 1); 1491 // TODO: error message 1492 1493 ODataAccessDescriptor aDescriptor; 1494 try 1495 { 1496 aDescriptor = ODataAccessDescriptor(aDescriptorSequence); 1497 } 1498 catch(const Exception&) 1499 { 1500 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::select: could not extract the descriptor!"); 1501 } 1502 1503 // check the precense of the props we need 1504 if ( !(aDescriptor.has(daDataSource) || aDescriptor.has(daDatabaseLocation)) || !aDescriptor.has(daCommand) || !aDescriptor.has(daCommandType)) 1505 throw IllegalArgumentException(::rtl::OUString(), *this, 1); 1506 // TODO: error message 1507 1508 return implSelect(aDescriptor,sal_True); 1509 } 1510 1511 // ------------------------------------------------------------------------- 1512 Any SAL_CALL SbaTableQueryBrowser::getSelection( ) throw (RuntimeException) 1513 { 1514 Any aReturn; 1515 1516 try 1517 { 1518 Reference< XLoadable > xLoadable(getRowSet(), UNO_QUERY); 1519 if (xLoadable.is() && xLoadable->isLoaded()) 1520 { 1521 Reference< XPropertySet > aFormProps(getRowSet(), UNO_QUERY); 1522 ODataAccessDescriptor aDescriptor(aFormProps); 1523 // remove properties which are not part of our "selection" 1524 aDescriptor.erase(daConnection); 1525 aDescriptor.erase(daCursor); 1526 1527 aReturn <<= aDescriptor.createPropertyValueSequence(); 1528 } 1529 } 1530 catch( const Exception& ) 1531 { 1532 DBG_UNHANDLED_EXCEPTION(); 1533 } 1534 1535 return aReturn; 1536 } 1537 1538 // ------------------------------------------------------------------------- 1539 void SAL_CALL SbaTableQueryBrowser::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) 1540 { 1541 m_aSelectionListeners.addInterface(_rxListener); 1542 } 1543 1544 // ------------------------------------------------------------------------- 1545 void SAL_CALL SbaTableQueryBrowser::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) 1546 { 1547 m_aSelectionListeners.removeInterface(_rxListener); 1548 } 1549 1550 // ------------------------------------------------------------------------- 1551 void SbaTableQueryBrowser::attachFrame(const Reference< ::com::sun::star::frame::XFrame > & _xFrame) throw( RuntimeException ) 1552 { 1553 implRemoveStatusListeners(); 1554 1555 if (m_xCurrentFrameParent.is()) 1556 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); 1557 1558 SbaXDataBrowserController::attachFrame(_xFrame); 1559 1560 Reference< XFrame > xCurrentFrame( getFrame() ); 1561 if ( xCurrentFrame.is() ) 1562 { 1563 m_xCurrentFrameParent = xCurrentFrame->findFrame(::rtl::OUString::createFromAscii("_parent"),FrameSearchFlag::PARENT); 1564 if ( m_xCurrentFrameParent.is() ) 1565 m_xCurrentFrameParent->addFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); 1566 1567 // obtain our toolbox 1568 try 1569 { 1570 Reference< XPropertySet > xFrameProps( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW ); 1571 Reference< XLayoutManager > xLayouter( 1572 xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ), 1573 UNO_QUERY ); 1574 1575 if ( xLayouter.is() ) 1576 { 1577 Reference< XUIElement > xUI( 1578 xLayouter->getElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ) ) ), 1579 UNO_SET_THROW ); 1580 m_xMainToolbar = m_xMainToolbar.query( xUI->getRealInterface() ); 1581 OSL_ENSURE( m_xMainToolbar.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" ); 1582 } 1583 } 1584 catch( const Exception& ) 1585 { 1586 DBG_UNHANDLED_EXCEPTION(); 1587 } 1588 } 1589 1590 // get the dispatchers for the external slots 1591 connectExternalDispatches(); 1592 } 1593 1594 // ------------------------------------------------------------------------- 1595 void SbaTableQueryBrowser::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel) 1596 { 1597 SbaXDataBrowserController::addModelListeners(_xGridControlModel); 1598 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY); 1599 if (xSourceSet.is()) 1600 { 1601 xSourceSet->addPropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this)); 1602 xSourceSet->addPropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this)); 1603 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this)); 1604 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this)); 1605 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this)); 1606 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this)); 1607 } 1608 1609 } 1610 1611 // ------------------------------------------------------------------------- 1612 void SbaTableQueryBrowser::removeModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel) 1613 { 1614 SbaXDataBrowserController::removeModelListeners(_xGridControlModel); 1615 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY); 1616 if (xSourceSet.is()) 1617 { 1618 xSourceSet->removePropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this)); 1619 xSourceSet->removePropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this)); 1620 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this)); 1621 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this)); 1622 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this)); 1623 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this)); 1624 } 1625 } 1626 // ------------------------------------------------------------------------- 1627 void SbaTableQueryBrowser::RowChanged() 1628 { 1629 if(getBrowserView()) 1630 { 1631 SbaGridControl* pControl = getBrowserView()->getVclControl(); 1632 if (!pControl->IsEditing()) 1633 InvalidateFeature(ID_BROWSER_COPY); 1634 } 1635 SbaXDataBrowserController::RowChanged(); 1636 } 1637 1638 // ------------------------------------------------------------------------- 1639 void SbaTableQueryBrowser::ColumnChanged() 1640 { 1641 if(getBrowserView()) 1642 { 1643 SbaGridControl* pControl = getBrowserView()->getVclControl(); 1644 if (!pControl->IsEditing()) 1645 InvalidateFeature(ID_BROWSER_COPY); 1646 } 1647 SbaXDataBrowserController::ColumnChanged(); 1648 } 1649 //------------------------------------------------------------------------------ 1650 void SbaTableQueryBrowser::AddColumnListener(const Reference< XPropertySet > & xCol) 1651 { 1652 SbaXDataBrowserController::AddColumnListener(xCol); 1653 SafeAddPropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this)); 1654 SafeAddPropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this)); 1655 SafeAddPropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this)); 1656 SafeAddPropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this)); 1657 } 1658 1659 //------------------------------------------------------------------------------ 1660 void SbaTableQueryBrowser::RemoveColumnListener(const Reference< XPropertySet > & xCol) 1661 { 1662 SbaXDataBrowserController::RemoveColumnListener(xCol); 1663 SafeRemovePropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this)); 1664 SafeRemovePropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this)); 1665 SafeRemovePropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this)); 1666 SafeRemovePropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this)); 1667 } 1668 1669 //------------------------------------------------------------------------------ 1670 void SbaTableQueryBrowser::criticalFail() 1671 { 1672 SbaXDataBrowserController::criticalFail(); 1673 unloadAndCleanup( sal_False ); 1674 } 1675 1676 //------------------------------------------------------------------------------ 1677 void SbaTableQueryBrowser::LoadFinished(sal_Bool _bWasSynch) 1678 { 1679 SbaXDataBrowserController::LoadFinished(_bWasSynch); 1680 1681 m_sQueryCommand = ::rtl::OUString(); 1682 m_bQueryEscapeProcessing = sal_False; 1683 1684 if (isValid() && !loadingCancelled()) 1685 { 1686 // did we load a query? 1687 sal_Bool bTemporary; // needed because we m_bQueryEscapeProcessing is only one bit wide (and we want to pass it by reference) 1688 if ( implGetQuerySignature( m_sQueryCommand, bTemporary ) ) 1689 m_bQueryEscapeProcessing = bTemporary; 1690 } 1691 1692 // if the form has been loaded, this means that our "selection" has changed 1693 EventObject aEvent( *this ); 1694 m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent ); 1695 } 1696 1697 //------------------------------------------------------------------------------ 1698 sal_Bool SbaTableQueryBrowser::getExternalSlotState( sal_uInt16 _nId ) const 1699 { 1700 sal_Bool bEnabled = sal_False; 1701 ExternalFeaturesMap::const_iterator aPos = m_aExternalFeatures.find( _nId ); 1702 if ( ( m_aExternalFeatures.end() != aPos ) && aPos->second.xDispatcher.is() ) 1703 bEnabled = aPos->second.bEnabled; 1704 return bEnabled; 1705 } 1706 1707 //------------------------------------------------------------------------------ 1708 FeatureState SbaTableQueryBrowser::GetState(sal_uInt16 nId) const 1709 { 1710 FeatureState aReturn; 1711 // (disabled automatically) 1712 1713 // no chance without a view 1714 if (!getBrowserView() || !getBrowserView()->getVclControl()) 1715 return aReturn; 1716 1717 switch ( nId ) 1718 { 1719 case ID_TREE_ADMINISTRATE: 1720 aReturn.bEnabled = true; 1721 return aReturn; 1722 1723 case ID_BROWSER_CLOSE: 1724 // the close button should always be enabled 1725 aReturn.bEnabled = !m_bEnableBrowser; 1726 return aReturn; 1727 1728 // "toggle explorer" is always enabled (if we have a explorer) 1729 case ID_BROWSER_EXPLORER: 1730 aReturn.bEnabled = m_bEnableBrowser; 1731 aReturn.bChecked = haveExplorer(); 1732 return aReturn; 1733 1734 case ID_BROWSER_REMOVEFILTER: 1735 return SbaXDataBrowserController::GetState( nId ); 1736 1737 case ID_BROWSER_COPY: 1738 if ( !m_pTreeView->HasChildPathFocus() ) 1739 // handled below 1740 break; 1741 // NO break! 1742 case ID_TREE_CLOSE_CONN: 1743 case ID_TREE_EDIT_DATABASE: 1744 { 1745 SvLBoxEntry* pCurrentEntry( m_pTreeView->getListBox().GetCurEntry() ); 1746 EntryType eType = getEntryType( pCurrentEntry ); 1747 if ( eType == etUnknown ) 1748 return aReturn; 1749 1750 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent( pCurrentEntry ); 1751 DBTreeListUserData* pDSData 1752 = pDataSourceEntry 1753 ? static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() ) 1754 : NULL; 1755 1756 if ( nId == ID_TREE_CLOSE_CONN ) 1757 { 1758 aReturn.bEnabled = ( pDSData != NULL ) && pDSData->xConnection.is(); 1759 } 1760 else if ( nId == ID_TREE_EDIT_DATABASE ) 1761 { 1762 ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithServiceFactory( getORB(), 1763 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.DataAccess/Policies/Features/Common" ) ) ) ); 1764 sal_Bool bHaveEditDatabase( sal_True ); 1765 OSL_VERIFY( aConfig.getNodeValue( "EditDatabaseFromDataSourceView" ) >>= bHaveEditDatabase ); 1766 aReturn.bEnabled = getORB().is() && ( pDataSourceEntry != NULL ) && bHaveEditDatabase; 1767 } 1768 else if ( nId == ID_BROWSER_COPY ) 1769 { 1770 aReturn.bEnabled = isEntryCopyAllowed( pCurrentEntry ); 1771 } 1772 1773 return aReturn; 1774 } 1775 } 1776 1777 // all slots not handled above are not available if no form is loaded 1778 if (!isLoaded()) 1779 return aReturn; 1780 1781 try 1782 { 1783 sal_Bool bHandled = sal_False; 1784 switch (nId) 1785 { 1786 case ID_BROWSER_DOCUMENT_DATASOURCE: 1787 // the slot is enabled if we have an external dispatcher able to handle it, 1788 // and the dispatcher must have enabled the slot in general 1789 aReturn.bEnabled = getExternalSlotState( ID_BROWSER_DOCUMENT_DATASOURCE ); 1790 bHandled = sal_True; 1791 break; 1792 case ID_BROWSER_REFRESH: 1793 aReturn.bEnabled = sal_True; 1794 bHandled = sal_True; 1795 break; 1796 } 1797 1798 if (bHandled) 1799 return aReturn; 1800 1801 // no chance without valid models 1802 if (isValid() && !isValidCursor() && nId != ID_BROWSER_CLOSE) 1803 return aReturn; 1804 1805 switch (nId) 1806 { 1807 case ID_BROWSER_INSERTCOLUMNS: 1808 case ID_BROWSER_INSERTCONTENT: 1809 case ID_BROWSER_FORMLETTER: 1810 { 1811 // the slot is enabled if we have an external dispatcher able to handle it, 1812 // and the dispatcher must have enabled the slot in general 1813 aReturn.bEnabled = getExternalSlotState( nId ); 1814 1815 // for the Insert* slots, we need at least one selected row 1816 if (ID_BROWSER_FORMLETTER != nId) 1817 aReturn.bEnabled = aReturn.bEnabled && getBrowserView()->getVclControl()->GetSelectRowCount(); 1818 1819 // disabled for native queries which are not saved within the database 1820 // 67706 - 23.08.99 - FS 1821 Reference< XPropertySet > xDataSource(getRowSet(), UNO_QUERY); 1822 try 1823 { 1824 aReturn.bEnabled = aReturn.bEnabled && xDataSource.is(); 1825 1826 if (xDataSource.is()) 1827 { 1828 sal_Int32 nType = ::comphelper::getINT32(xDataSource->getPropertyValue(PROPERTY_COMMAND_TYPE)); 1829 aReturn.bEnabled = aReturn.bEnabled && ((::comphelper::getBOOL(xDataSource->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || (nType == ::com::sun::star::sdb::CommandType::QUERY))); 1830 } 1831 } 1832 catch(DisposedException&) 1833 { 1834 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::GetState: object already disposed!"); 1835 } 1836 catch( const Exception& ) 1837 { 1838 DBG_UNHANDLED_EXCEPTION(); 1839 } 1840 } 1841 break; 1842 1843 case ID_BROWSER_TITLE: 1844 { 1845 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); 1846 sal_Int32 nCommandType = CommandType::TABLE; 1847 xProp->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nCommandType; 1848 String sTitle; 1849 switch (nCommandType) 1850 { 1851 case CommandType::TABLE: 1852 sTitle = String(ModuleRes(STR_TBL_TITLE)); break; 1853 case CommandType::QUERY: 1854 case CommandType::COMMAND: 1855 sTitle = String(ModuleRes(STR_QRY_TITLE)); break; 1856 default: 1857 DBG_ASSERT(sal_False, "SbaTableQueryBrowser::GetState: unknown command type!"); 1858 } 1859 ::rtl::OUString aName; 1860 xProp->getPropertyValue(PROPERTY_COMMAND) >>= aName; 1861 String sObject(aName.getStr()); 1862 1863 sTitle.SearchAndReplace('#',sObject); 1864 aReturn.sTitle = sTitle; 1865 aReturn.bEnabled = sal_True; 1866 } 1867 break; 1868 case ID_BROWSER_TABLEATTR: 1869 case ID_BROWSER_ROWHEIGHT: 1870 case ID_BROWSER_COLATTRSET: 1871 case ID_BROWSER_COLWIDTH: 1872 aReturn.bEnabled = getBrowserView() && getBrowserView()->getVclControl() && isValid() && isValidCursor(); 1873 // aReturn.bEnabled &= getDefinition() && !getDefinition()->GetDatabase()->IsReadOnly(); 1874 break; 1875 1876 case ID_BROWSER_COPY: 1877 OSL_ENSURE( !m_pTreeView->HasChildPathFocus(), "SbaTableQueryBrowser::GetState( ID_BROWSER_COPY ): this should have been handled above!" ); 1878 if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing()) 1879 { 1880 SbaGridControl* pControl = getBrowserView()->getVclControl(); 1881 if ( pControl->GetSelectRowCount() ) 1882 { 1883 aReturn.bEnabled = m_aCurrentFrame.isActive(); 1884 break; 1885 } // if ( getBrowserView()->getVclControl()->GetSelectRowCount() ) 1886 else 1887 aReturn.bEnabled = pControl->canCopyCellText(pControl->GetCurRow(), pControl->GetCurColumnId()); 1888 break; 1889 } 1890 // NO break here 1891 default: 1892 return SbaXDataBrowserController::GetState(nId); 1893 } 1894 } 1895 catch(const Exception&) 1896 { 1897 DBG_UNHANDLED_EXCEPTION(); 1898 } 1899 1900 return aReturn; 1901 1902 } 1903 1904 //------------------------------------------------------------------------------ 1905 void SbaTableQueryBrowser::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& aArgs) 1906 { 1907 switch (nId) 1908 { 1909 default: 1910 SbaXDataBrowserController::Execute(nId,aArgs); 1911 break; 1912 1913 case ID_TREE_EDIT_DATABASE: 1914 implAdministrate( m_pTreeView->getListBox().GetCurEntry() ); 1915 break; 1916 1917 case ID_TREE_CLOSE_CONN: 1918 openHelpAgent( HID_DSBROWSER_DISCONNECTING ); 1919 closeConnection( m_pTreeView->getListBox().GetRootLevelParent( m_pTreeView->getListBox().GetCurEntry() ) ); 1920 break; 1921 1922 case ID_TREE_ADMINISTRATE: 1923 ::svx::administrateDatabaseRegistration( getView() ); 1924 break; 1925 1926 case ID_BROWSER_REFRESH: 1927 { 1928 if ( !SaveModified( ) ) 1929 // nothing to do 1930 break; 1931 1932 sal_Bool bFullReinit = sal_False; 1933 // check if the query signature (if the form is based on a query) has changed 1934 if ( m_sQueryCommand.getLength() ) 1935 { 1936 ::rtl::OUString sNewQueryCommand; 1937 sal_Bool bNewQueryEP; 1938 1939 #if OSL_DEBUG_LEVEL > 0 1940 sal_Bool bIsQuery = 1941 #endif 1942 implGetQuerySignature( sNewQueryCommand, bNewQueryEP ); 1943 OSL_ENSURE( bIsQuery, "SbaTableQueryBrowser::Execute: was a query before, but is not anymore?" ); 1944 1945 bFullReinit = ( sNewQueryCommand != m_sQueryCommand ) || ( m_bQueryEscapeProcessing != bNewQueryEP ); 1946 } 1947 if ( !bFullReinit ) 1948 { 1949 // let the base class do a simple reload 1950 SbaXDataBrowserController::Execute(nId,aArgs); 1951 break; 1952 } 1953 // NO break here! 1954 } 1955 1956 case ID_BROWSER_REFRESH_REBUILD: 1957 { 1958 if ( !SaveModified() ) 1959 // nothing to do 1960 break; 1961 1962 SvLBoxEntry* pSelected = m_pCurrentlyDisplayed; 1963 // unload 1964 unloadAndCleanup( sal_False ); 1965 1966 // reselect the entry 1967 if ( pSelected ) 1968 { 1969 implSelect( pSelected ); 1970 } 1971 else 1972 { 1973 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); 1974 implSelect(::svx::ODataAccessDescriptor(xProp)); 1975 } 1976 } 1977 break; 1978 1979 case ID_BROWSER_EXPLORER: 1980 toggleExplorer(); 1981 break; 1982 1983 case ID_BROWSER_DOCUMENT_DATASOURCE: 1984 implSelect(m_aDocumentDataSource); 1985 break; 1986 1987 case ID_BROWSER_INSERTCOLUMNS: 1988 case ID_BROWSER_INSERTCONTENT: 1989 case ID_BROWSER_FORMLETTER: 1990 if (getBrowserView() && isValidCursor()) 1991 { 1992 // the URL the slot id is assigned to 1993 OSL_ENSURE( m_aExternalFeatures.find( nId ) != m_aExternalFeatures.end(), 1994 "SbaTableQueryBrowser::Execute( ID_BROWSER_?): how could this ever be enabled?" ); 1995 URL aParentUrl = m_aExternalFeatures[ nId ].aURL; 1996 1997 // let the dispatcher execute the slot 1998 Reference< XDispatch > xDispatch( m_aExternalFeatures[ nId ].xDispatcher ); 1999 if (xDispatch.is()) 2000 { 2001 // set the properties for the dispatch 2002 2003 // first fill the selection 2004 SbaGridControl* pGrid = getBrowserView()->getVclControl(); 2005 MultiSelection* pSelection = (MultiSelection*)pGrid->GetSelection(); 2006 Sequence< Any > aSelection; 2007 if ( !pGrid->IsAllSelected() ) 2008 { // transfer the selected rows only if not all rows are selected 2009 // (all rows means the whole table) 2010 // i3832 - 03.04.2002 - fs@openoffice.org 2011 if (pSelection != NULL) 2012 { 2013 aSelection.realloc(pSelection->GetSelectCount()); 2014 long nIdx = pSelection->FirstSelected(); 2015 Any* pSelectionNos = aSelection.getArray(); 2016 while (nIdx >= 0) 2017 { 2018 *pSelectionNos++ <<= (sal_Int32)(nIdx + 1); 2019 nIdx = pSelection->NextSelected(); 2020 } 2021 } 2022 } 2023 2024 Reference< XResultSet > xCursorClone; 2025 try 2026 { 2027 Reference< XResultSetAccess > xResultSetAccess(getRowSet(),UNO_QUERY); 2028 if (xResultSetAccess.is()) 2029 xCursorClone = xResultSetAccess->createResultSet(); 2030 } 2031 catch(DisposedException&) 2032 { 2033 OSL_ENSURE(0,"Object already disposed!"); 2034 } 2035 catch(Exception&) 2036 { 2037 DBG_ERROR("SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not clone the cursor!"); 2038 } 2039 2040 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); 2041 2042 try 2043 { 2044 ODataAccessDescriptor aDescriptor; 2045 ::rtl::OUString sDataSourceName; 2046 xProp->getPropertyValue(PROPERTY_DATASOURCENAME) >>= sDataSourceName; 2047 2048 aDescriptor.setDataSource(sDataSourceName); 2049 aDescriptor[daCommand] = xProp->getPropertyValue(PROPERTY_COMMAND); 2050 aDescriptor[daCommandType] = xProp->getPropertyValue(PROPERTY_COMMAND_TYPE); 2051 aDescriptor[daConnection] = xProp->getPropertyValue(PROPERTY_ACTIVE_CONNECTION); 2052 aDescriptor[daCursor] <<= xCursorClone; 2053 if ( aSelection.getLength() ) 2054 { 2055 aDescriptor[daSelection] <<= aSelection; 2056 aDescriptor[daBookmarkSelection] <<= sal_False; 2057 // these are selection indicies 2058 // before we change this, all clients have to be adjusted 2059 // so that they recognize the new BookmarkSelection property! 2060 } 2061 2062 xDispatch->dispatch(aParentUrl, aDescriptor.createPropertyValueSequence()); 2063 } 2064 catch( const Exception& ) 2065 { 2066 DBG_UNHANDLED_EXCEPTION(); 2067 } 2068 } 2069 } 2070 break; 2071 2072 case ID_BROWSER_CLOSE: 2073 closeTask(); 2074 // if it's not 0, such a async close is already pending 2075 break; 2076 2077 case ID_BROWSER_COPY: 2078 if(m_pTreeView->HasChildPathFocus()) 2079 { 2080 copyEntry(m_pTreeView->getListBox().GetCurEntry()); 2081 } 2082 else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing() && getBrowserView()->getVclControl()->GetSelectRowCount() < 1) 2083 { 2084 SbaGridControl* pControl = getBrowserView()->getVclControl(); 2085 pControl->copyCellText(pControl->GetCurRow(), pControl->GetCurColumnId()); 2086 } 2087 else 2088 SbaXDataBrowserController::Execute(nId,aArgs); 2089 break; 2090 } 2091 } 2092 2093 // ------------------------------------------------------------------------- 2094 void SbaTableQueryBrowser::implAddDatasource( const String& _rDataSourceName, const SharedConnection& _rxConnection ) 2095 { 2096 Image a, b, c; 2097 String d, e; 2098 implAddDatasource( _rDataSourceName, a, d, b, e, c, _rxConnection ); 2099 } 2100 2101 // ------------------------------------------------------------------------- 2102 void SbaTableQueryBrowser::implAddDatasource(const String& _rDbName, Image& _rDbImage, 2103 String& _rQueryName, Image& _rQueryImage, String& _rTableName, Image& _rTableImage, 2104 const SharedConnection& _rxConnection) 2105 { 2106 vos::OGuard aGuard( Application::GetSolarMutex() ); 2107 // initialize the names/images if necessary 2108 if (!_rQueryName.Len()) 2109 _rQueryName = String(ModuleRes(RID_STR_QUERIES_CONTAINER)); 2110 if (!_rTableName.Len()) 2111 _rTableName = String(ModuleRes(RID_STR_TABLES_CONTAINER)); 2112 2113 ImageProvider aImageProvider; 2114 if (!_rQueryImage) 2115 _rQueryImage = aImageProvider.getFolderImage( DatabaseObject::QUERY, isHiContrast() ); 2116 if (!_rTableImage) 2117 _rTableImage = aImageProvider.getFolderImage( DatabaseObject::TABLE, isHiContrast() ); 2118 2119 if (!_rDbImage) 2120 _rDbImage = aImageProvider.getDatabaseImage( isHiContrast() ); 2121 2122 // add the entry for the data source 2123 // special handling for data sources denoted by URLs - we do not want to display this ugly URL, do we? 2124 // #i33699# - 2004-09-24 - fs@openoffice.org 2125 String sDSDisplayName, sDataSourceId; 2126 getDataSourceDisplayName_isURL( _rDbName, sDSDisplayName, sDataSourceId ); 2127 2128 SvLBoxEntry* pDatasourceEntry = m_pTreeView->getListBox().InsertEntry( sDSDisplayName, _rDbImage, _rDbImage, NULL, sal_False ); 2129 DBTreeListUserData* pDSData = new DBTreeListUserData; 2130 pDSData->eType = etDatasource; 2131 pDSData->sAccessor = sDataSourceId; 2132 pDSData->xConnection = _rxConnection; 2133 pDatasourceEntry->SetUserData(pDSData); 2134 2135 // the child for the queries container 2136 { 2137 DBTreeListUserData* pQueriesData = new DBTreeListUserData; 2138 pQueriesData->eType = etQueryContainer; 2139 2140 m_pTreeView->getListBox().InsertEntry( 2141 _rQueryName, _rQueryImage, _rQueryImage, pDatasourceEntry, 2142 sal_True /*ChildsOnDemand*/, LIST_APPEND, pQueriesData ); 2143 } 2144 2145 // the child for the tables container 2146 { 2147 DBTreeListUserData* pTablesData = new DBTreeListUserData; 2148 pTablesData->eType = etTableContainer; 2149 2150 m_pTreeView->getListBox().InsertEntry( 2151 _rTableName, _rTableImage, _rTableImage, pDatasourceEntry, 2152 sal_True /*ChildsOnDemand*/, LIST_APPEND, pTablesData ); 2153 } 2154 2155 } 2156 // ------------------------------------------------------------------------- 2157 void SbaTableQueryBrowser::initializeTreeModel() 2158 { 2159 if (m_xDatabaseContext.is()) 2160 { 2161 Image aDBImage, aQueriesImage, aTablesImage; 2162 String sQueriesName, sTablesName; 2163 2164 // fill the model with the names of the registered datasources 2165 Sequence< ::rtl::OUString > aDatasources = m_xDatabaseContext->getElementNames(); 2166 const ::rtl::OUString* pIter = aDatasources.getConstArray(); 2167 const ::rtl::OUString* pEnd = pIter + aDatasources.getLength(); 2168 for (; pIter != pEnd; ++pIter) 2169 implAddDatasource( *pIter, aDBImage, sQueriesName, aQueriesImage, sTablesName, aTablesImage, SharedConnection() ); 2170 } 2171 } 2172 // ------------------------------------------------------------------------- 2173 void SbaTableQueryBrowser::populateTree(const Reference<XNameAccess>& _xNameAccess, 2174 SvLBoxEntry* _pParent, 2175 EntryType _eEntryType) 2176 { 2177 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pParent->GetUserData()); 2178 if(pData) // don't ask if the nameaccess is already set see OnExpandEntry views and tables 2179 pData->xContainer = _xNameAccess; 2180 2181 try 2182 { 2183 Sequence< ::rtl::OUString > aNames = _xNameAccess->getElementNames(); 2184 const ::rtl::OUString* pIter = aNames.getConstArray(); 2185 const ::rtl::OUString* pEnd = pIter + aNames.getLength(); 2186 for (; pIter != pEnd; ++pIter) 2187 { 2188 if( !m_pTreeView->getListBox().GetEntryPosByName(*pIter,_pParent)) 2189 { 2190 DBTreeListUserData* pEntryData = new DBTreeListUserData; 2191 pEntryData->eType = _eEntryType; 2192 if ( _eEntryType == etQuery ) 2193 { 2194 Reference<XNameAccess> xChild(_xNameAccess->getByName(*pIter),UNO_QUERY); 2195 if ( xChild.is() ) 2196 pEntryData->eType = etQueryContainer; 2197 } 2198 implAppendEntry( _pParent, *pIter, pEntryData, pEntryData->eType ); 2199 } 2200 } 2201 } 2202 catch(Exception&) 2203 { 2204 DBG_ERROR("SbaTableQueryBrowser::populateTree: could not fill the tree"); 2205 } 2206 } 2207 2208 //------------------------------------------------------------------------------ 2209 SvLBoxEntry* SbaTableQueryBrowser::implAppendEntry( SvLBoxEntry* _pParent, const String& _rName, void* _pUserData, EntryType _eEntryType ) 2210 { 2211 ::std::auto_ptr< ImageProvider > pImageProvider( getImageProviderFor( _pParent ) ); 2212 2213 Image aImage, aImageHC; 2214 pImageProvider->getImages( _rName, getDatabaseObjectType( _eEntryType ), aImage, aImageHC ); 2215 2216 SvLBoxEntry* pNewEntry = m_pTreeView->getListBox().InsertEntry( _rName, _pParent, _eEntryType == etQueryContainer , LIST_APPEND, _pUserData ); 2217 2218 m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL ); 2219 m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL ); 2220 m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImageHC, BMP_COLOR_HIGHCONTRAST ); 2221 m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImageHC, BMP_COLOR_HIGHCONTRAST ); 2222 2223 return pNewEntry; 2224 } 2225 2226 //------------------------------------------------------------------------------ 2227 IMPL_LINK(SbaTableQueryBrowser, OnExpandEntry, SvLBoxEntry*, _pParent) 2228 { 2229 if (_pParent->HasChilds()) 2230 // nothing to to ... 2231 return 1L; 2232 2233 SvLBoxEntry* pFirstParent = m_pTreeView->getListBox().GetRootLevelParent(_pParent); 2234 OSL_ENSURE(pFirstParent,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!"); 2235 2236 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >(_pParent->GetUserData()); 2237 OSL_ENSURE(pData,"SbaTableQueryBrowser::OnExpandEntry: No user data!"); 2238 #if OSL_DEBUG_LEVEL > 0 2239 SvLBoxString* pString = static_cast<SvLBoxString*>(pFirstParent->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING)); 2240 OSL_ENSURE(pString,"SbaTableQueryBrowser::OnExpandEntry: No string item!"); 2241 #endif 2242 2243 if (etTableContainer == pData->eType) 2244 { 2245 WaitObject aWaitCursor(getBrowserView()); 2246 2247 // it could be that we already have a connection 2248 SharedConnection xConnection; 2249 ensureConnection( pFirstParent, xConnection ); 2250 2251 if ( xConnection.is() ) 2252 { 2253 SQLExceptionInfo aInfo; 2254 try 2255 { 2256 Reference< XWarningsSupplier > xWarnings(xConnection, UNO_QUERY); 2257 if (xWarnings.is()) 2258 xWarnings->clearWarnings(); 2259 2260 // first insert the views because the tables can also include 2261 // views but that time the bitmap is the wrong one 2262 // the nameaccess will be overwriten in populateTree 2263 Reference<XViewsSupplier> xViewSup(xConnection,UNO_QUERY); 2264 if(xViewSup.is()) 2265 populateTree( xViewSup->getViews(), _pParent, etTableOrView ); 2266 2267 Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY); 2268 if(xTabSup.is()) 2269 { 2270 populateTree( xTabSup->getTables(), _pParent, etTableOrView ); 2271 Reference<XContainer> xCont(xTabSup->getTables(),UNO_QUERY); 2272 if(xCont.is()) 2273 // add as listener to know when elements are inserted or removed 2274 xCont->addContainerListener(this); 2275 } 2276 2277 if (xWarnings.is()) 2278 { 2279 SQLExceptionInfo aWarnings(xWarnings->getWarnings()); 2280 if (aWarnings.isValid() && sal_False) 2281 { 2282 SQLContext aContext; 2283 aContext.Message = String(ModuleRes(STR_OPENTABLES_WARNINGS)); 2284 aContext.Details = String(ModuleRes(STR_OPENTABLES_WARNINGS_DETAILS)); 2285 aContext.NextException = aWarnings.get(); 2286 aWarnings = aContext; 2287 showError(aWarnings); 2288 } 2289 // TODO: we need a better concept for these warnings: 2290 // something like "don't show any warnings for this datasource, again" would be nice 2291 // But this requires an extension of the InteractionHandler and an additional property on the data source 2292 } 2293 } 2294 catch(const SQLContext& e) { aInfo = e; } 2295 catch(const SQLWarning& e) { aInfo = e; } 2296 catch(const SQLException& e) { aInfo = e; } 2297 catch(const WrappedTargetException& e) 2298 { 2299 SQLException aSql; 2300 if(e.TargetException >>= aSql) 2301 aInfo = aSql; 2302 else 2303 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::OnExpandEntry: something strange happended!"); 2304 } 2305 catch( const Exception& ) 2306 { 2307 DBG_UNHANDLED_EXCEPTION(); 2308 } 2309 if (aInfo.isValid()) 2310 showError(aInfo); 2311 } 2312 else 2313 return 0L; 2314 // 0 indicates that an error occured 2315 } 2316 else 2317 { // we have to expand the queries or bookmarks 2318 if (ensureEntryObject(_pParent)) 2319 { 2320 DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( _pParent->GetUserData() ); 2321 Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY ); 2322 populateTree( xCollection, _pParent, etQuery ); 2323 } 2324 } 2325 return 1L; 2326 } 2327 2328 //------------------------------------------------------------------------------ 2329 sal_Bool SbaTableQueryBrowser::ensureEntryObject( SvLBoxEntry* _pEntry ) 2330 { 2331 DBG_ASSERT(_pEntry, "SbaTableQueryBrowser::ensureEntryObject: invalid argument!"); 2332 if (!_pEntry) 2333 return sal_False; 2334 2335 EntryType eType = getEntryType( _pEntry ); 2336 2337 // the user data of the entry 2338 DBTreeListUserData* pEntryData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData()); 2339 OSL_ENSURE(pEntryData,"ensureEntryObject: user data should already be set!"); 2340 2341 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(_pEntry); 2342 2343 sal_Bool bSuccess = sal_False; 2344 switch (eType) 2345 { 2346 case etQueryContainer: 2347 if ( pEntryData->xContainer.is() ) 2348 { 2349 // nothing to do 2350 bSuccess = sal_True; 2351 break; 2352 } 2353 2354 { 2355 SvLBoxEntry* pParent = m_pTreeView->getListBox().GetParent(_pEntry); 2356 if ( pParent != pDataSourceEntry ) 2357 { 2358 SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING); 2359 OSL_ENSURE(pString,"There must be a string item!"); 2360 ::rtl::OUString aName(pString->GetText()); 2361 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pParent->GetUserData()); 2362 try 2363 { 2364 Reference< XNameAccess > xNameAccess(pData->xContainer,UNO_QUERY); 2365 if ( xNameAccess.is() ) 2366 pEntryData->xContainer.set(xNameAccess->getByName(aName),UNO_QUERY); 2367 } 2368 catch(const Exception& ) 2369 { 2370 DBG_UNHANDLED_EXCEPTION(); 2371 } 2372 2373 bSuccess = pEntryData->xContainer.is(); 2374 } 2375 else 2376 { 2377 try 2378 { 2379 Reference< XQueryDefinitionsSupplier > xQuerySup; 2380 m_xDatabaseContext->getByName( getDataSourceAcessor( pDataSourceEntry ) ) >>= xQuerySup; 2381 if (xQuerySup.is()) 2382 { 2383 Reference< XNameAccess > xQueryDefs = xQuerySup->getQueryDefinitions(); 2384 Reference< XContainer > xCont(xQueryDefs, UNO_QUERY); 2385 if (xCont.is()) 2386 // add as listener to get notified if elements are inserted or removed 2387 xCont->addContainerListener(this); 2388 2389 pEntryData->xContainer = xQueryDefs; 2390 bSuccess = pEntryData->xContainer.is(); 2391 } 2392 else { 2393 DBG_ERROR("SbaTableQueryBrowser::ensureEntryObject: no XQueryDefinitionsSupplier interface!"); 2394 } 2395 } 2396 catch( const Exception& ) 2397 { 2398 DBG_UNHANDLED_EXCEPTION(); 2399 } 2400 } 2401 } 2402 break; 2403 2404 default: 2405 DBG_ERROR("SbaTableQueryBrowser::ensureEntryObject: ooops ... missing some implementation here!"); 2406 // TODO ... 2407 break; 2408 } 2409 2410 return bSuccess; 2411 } 2412 //------------------------------------------------------------------------------ 2413 sal_Bool SbaTableQueryBrowser::implSelect(const ::svx::ODataAccessDescriptor& _rDescriptor,sal_Bool _bSelectDirect) 2414 { 2415 // extract the props 2416 ::rtl::OUString sDataSource; 2417 ::rtl::OUString sCommand; 2418 sal_Int32 nCommandType = CommandType::COMMAND; 2419 sal_Bool bEscapeProcessing = sal_True; 2420 extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing); 2421 2422 // select it 2423 return implSelect( sDataSource, sCommand, nCommandType, bEscapeProcessing, SharedConnection(), _bSelectDirect ); 2424 } 2425 2426 //------------------------------------------------------------------------------ 2427 sal_Bool SbaTableQueryBrowser::implLoadAnything(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand, 2428 const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing, const SharedConnection& _rxConnection) 2429 { 2430 try 2431 { 2432 Reference<XPropertySet> xProp( getRowSet(), UNO_QUERY_THROW ); 2433 Reference< XLoadable > xLoadable( xProp, UNO_QUERY_THROW ); 2434 // the values allowing the RowSet to re-execute 2435 xProp->setPropertyValue(PROPERTY_DATASOURCENAME, makeAny(_rDataSourceName)); 2436 if(_rxConnection.is()) 2437 xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( _rxConnection.getTyped() ) ); 2438 2439 // set this _before_ setting the connection, else the rowset would rebuild it ... 2440 xProp->setPropertyValue(PROPERTY_COMMAND_TYPE, makeAny(_nCommandType)); 2441 xProp->setPropertyValue(PROPERTY_COMMAND, makeAny(_rCommand)); 2442 xProp->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, ::cppu::bool2any(_bEscapeProcessing)); 2443 if ( m_bPreview ) 2444 { 2445 xProp->setPropertyValue(PROPERTY_FETCHDIRECTION, makeAny(FetchDirection::FORWARD)); 2446 } 2447 2448 // the formatter depends on the data source we're working on, so rebuild it here ... 2449 initFormatter(); 2450 2451 // switch the grid to design mode while loading 2452 getBrowserView()->getGridControl()->setDesignMode(sal_True); 2453 InitializeForm( xProp ); 2454 2455 sal_Bool bSuccess = sal_True; 2456 2457 { 2458 { 2459 Reference< XNameContainer > xColContainer(getFormComponent(), UNO_QUERY); 2460 // first we have to clear the grid 2461 clearGridColumns(xColContainer); 2462 } 2463 FormErrorHelper aHelper(this); 2464 // load the form 2465 bSuccess = reloadForm(xLoadable); 2466 2467 // initialize the model 2468 InitializeGridModel(getFormComponent()); 2469 2470 Any aVal = xProp->getPropertyValue(PROPERTY_ISNEW); 2471 if (aVal.hasValue() && ::comphelper::getBOOL(aVal)) 2472 { 2473 // then set the default values and the parameters given from the parent 2474 Reference< XReset> xReset(xProp, UNO_QUERY); 2475 xReset->reset(); 2476 } 2477 2478 if ( m_bPreview ) 2479 initializePreviewMode(); 2480 2481 LoadFinished(sal_True); 2482 } 2483 2484 InvalidateAll(); 2485 return bSuccess; 2486 } 2487 catch( const SQLException& e ) 2488 { 2489 Any aException( ::cppu::getCaughtException() ); 2490 showError( SQLExceptionInfo( aException ) ); 2491 } 2492 catch( const WrappedTargetException& e ) 2493 { 2494 SQLException aSql; 2495 if ( e.TargetException.isExtractableTo( ::cppu::UnoType< SQLException >::get() ) ) 2496 showError( SQLExceptionInfo( e.TargetException ) ); 2497 else 2498 { 2499 DBG_UNHANDLED_EXCEPTION(); 2500 } 2501 } 2502 catch(Exception&) 2503 { 2504 DBG_UNHANDLED_EXCEPTION(); 2505 } 2506 2507 InvalidateAll(); 2508 return sal_False; 2509 } 2510 2511 //------------------------------------------------------------------------------ 2512 sal_Bool SbaTableQueryBrowser::implSelect(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand, 2513 const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing, 2514 const SharedConnection& _rxConnection 2515 ,sal_Bool _bSelectDirect) 2516 { 2517 if (_rDataSourceName.getLength() && _rCommand.getLength() && (-1 != _nCommandType)) 2518 { 2519 SvLBoxEntry* pDataSource = NULL; 2520 SvLBoxEntry* pCommandType = NULL; 2521 SvLBoxEntry* pCommand = getObjectEntry( _rDataSourceName, _rCommand, _nCommandType, &pDataSource, &pCommandType, sal_True, _rxConnection ); 2522 2523 if (pCommand) 2524 { 2525 bool bSuccess = true; 2526 if ( _bSelectDirect ) 2527 { 2528 bSuccess = implSelect( pCommand ); 2529 } 2530 else 2531 { 2532 m_pTreeView->getListBox().Select( pCommand ); 2533 } 2534 2535 if ( bSuccess ) 2536 { 2537 m_pTreeView->getListBox().MakeVisible(pCommand); 2538 m_pTreeView->getListBox().SetCursor(pCommand); 2539 } 2540 } 2541 else if (!pCommandType) 2542 { 2543 if ( m_pCurrentlyDisplayed ) 2544 { // tell the old entry (if any) it has been deselected 2545 selectPath(m_pCurrentlyDisplayed, sal_False); 2546 m_pCurrentlyDisplayed = NULL; 2547 } 2548 2549 // we have a command and need to display this in the rowset 2550 return implLoadAnything(_rDataSourceName, _rCommand, _nCommandType, _bEscapeProcessing, _rxConnection); 2551 } 2552 } 2553 return sal_False; 2554 } 2555 2556 //------------------------------------------------------------------------------ 2557 IMPL_LINK(SbaTableQueryBrowser, OnSelectionChange, void*, /*NOINTERESTEDIN*/) 2558 { 2559 return implSelect( m_pTreeView->getListBox().FirstSelected() ) ? 1L : 0L; 2560 } 2561 //------------------------------------------------------------------------------ 2562 SvLBoxEntry* SbaTableQueryBrowser::implGetConnectionEntry(SvLBoxEntry* _pEntry) const 2563 { 2564 SvLBoxEntry* pCurrentEntry = _pEntry; 2565 DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() ); 2566 while(pEntryData->eType != etDatasource ) 2567 { 2568 pCurrentEntry = m_pTreeModel->GetParent(pCurrentEntry); 2569 pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() ); 2570 } 2571 return pCurrentEntry; 2572 } 2573 //------------------------------------------------------------------------------ 2574 bool SbaTableQueryBrowser::implSelect( SvLBoxEntry* _pEntry ) 2575 { 2576 if ( !_pEntry ) 2577 return false; 2578 2579 DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() ); 2580 switch (pEntryData->eType) 2581 { 2582 case etTableOrView: 2583 case etQuery: 2584 break; 2585 default: 2586 // nothing to do 2587 return false; 2588 } 2589 2590 OSL_ENSURE(m_pTreeModel->HasParent(_pEntry), "SbaTableQueryBrowser::implSelect: invalid entry (1)!"); 2591 OSL_ENSURE(m_pTreeModel->HasParent(m_pTreeModel->GetParent(_pEntry)), "SbaTableQueryBrowser::implSelect: invalid entry (2)!"); 2592 2593 // get the entry for the tables or queries 2594 SvLBoxEntry* pContainer = m_pTreeModel->GetParent(_pEntry); 2595 DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pContainer->GetUserData()); 2596 2597 // get the entry for the datasource 2598 SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer); 2599 DBTreeListUserData* pConData = static_cast<DBTreeListUserData*>(pConnection->GetUserData()); 2600 2601 // reinitialize the rowset 2602 // but first check if it is necessary 2603 // get all old properties 2604 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY); 2605 ::rtl::OUString aOldName; 2606 xRowSetProps->getPropertyValue(PROPERTY_COMMAND) >>= aOldName; 2607 sal_Int32 nOldType = 0; 2608 xRowSetProps->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nOldType; 2609 Reference<XConnection> xOldConnection(xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY); 2610 2611 // the name of the table or query 2612 SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING); 2613 OSL_ENSURE(pString,"There must be a string item!"); 2614 const ::rtl::OUString sSimpleName = pString->GetText(); 2615 ::rtl::OUStringBuffer sNameBuffer(sSimpleName); 2616 if ( etQueryContainer == pContainerData->eType ) 2617 { 2618 SvLBoxEntry* pTemp = pContainer; 2619 while( m_pTreeModel->GetParent(pTemp) != pConnection ) 2620 { 2621 sNameBuffer.insert(0,sal_Unicode('/')); 2622 pString = (SvLBoxString*)pTemp->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING); 2623 OSL_ENSURE(pString,"There must be a string item!"); 2624 sNameBuffer.insert(0,pString->GetText()); 2625 pTemp = m_pTreeModel->GetParent(pTemp); 2626 } 2627 } 2628 ::rtl::OUString aName = sNameBuffer.makeStringAndClear(); 2629 2630 sal_Int32 nCommandType = ( etTableContainer == pContainerData->eType) 2631 ? CommandType::TABLE 2632 : CommandType::QUERY; 2633 2634 // check if need to rebuild the rowset 2635 sal_Bool bRebuild = ( xOldConnection != pConData->xConnection ) 2636 || ( nOldType != nCommandType ) 2637 || ( aName != aOldName ); 2638 2639 Reference< ::com::sun::star::form::XLoadable > xLoadable = getLoadable(); 2640 bRebuild |= !xLoadable->isLoaded(); 2641 bool bSuccess = true; 2642 if ( bRebuild ) 2643 { 2644 try 2645 { 2646 WaitObject aWaitCursor(getBrowserView()); 2647 2648 // tell the old entry it has been deselected 2649 selectPath(m_pCurrentlyDisplayed, sal_False); 2650 m_pCurrentlyDisplayed = NULL; 2651 2652 // not really loaded 2653 m_pCurrentlyDisplayed = _pEntry; 2654 // tell the new entry it has been selected 2655 selectPath(m_pCurrentlyDisplayed, sal_True); 2656 2657 // get the name of the data source currently selected 2658 ensureConnection( m_pCurrentlyDisplayed, pConData->xConnection ); 2659 2660 if ( !pConData->xConnection.is() ) 2661 { 2662 unloadAndCleanup( sal_False ); 2663 return false; 2664 } 2665 2666 Reference<XNameAccess> xNameAccess; 2667 switch(nCommandType) 2668 { 2669 case CommandType::TABLE: 2670 { 2671 // only for tables 2672 if ( !pContainerData->xContainer.is() ) 2673 { 2674 Reference<XTablesSupplier> xSup( pConData->xConnection, UNO_QUERY ); 2675 if(xSup.is()) 2676 xNameAccess = xSup->getTables(); 2677 2678 pContainerData->xContainer = xNameAccess; 2679 } 2680 else 2681 xNameAccess.set( pContainerData->xContainer, UNO_QUERY ); 2682 } 2683 break; 2684 case CommandType::QUERY: 2685 { 2686 if ( pContainerData->xContainer.is() ) 2687 xNameAccess.set( pContainerData->xContainer, UNO_QUERY ); 2688 else 2689 { 2690 Reference<XQueriesSupplier> xSup( pConData->xConnection, UNO_QUERY ); 2691 if(xSup.is()) 2692 xNameAccess = xSup->getQueries(); 2693 } 2694 } 2695 break; 2696 } 2697 String sStatus(ModuleRes( CommandType::TABLE == nCommandType ? STR_LOADING_TABLE : STR_LOADING_QUERY )); 2698 sStatus.SearchAndReplaceAscii("$name$", aName); 2699 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sStatus); 2700 2701 2702 sal_Bool bEscapeProcessing = sal_True; 2703 if(xNameAccess.is() && xNameAccess->hasByName(sSimpleName)) 2704 { 2705 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData()); 2706 if ( !pData->xObjectProperties.is() ) 2707 { 2708 Reference<XInterface> xObject; 2709 if(xNameAccess->getByName(sSimpleName) >>= xObject) // remember the table or query object 2710 { 2711 pData->xObjectProperties = pData->xObjectProperties.query( xObject ); 2712 // if the query contains a parameterized statement and preview is enabled we won't get any data. 2713 if ( nCommandType == CommandType::QUERY && xObject.is() ) 2714 { 2715 Reference<XPropertySet> xObjectProps(xObject,UNO_QUERY); 2716 xObjectProps->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bEscapeProcessing; 2717 if ( m_bPreview ) 2718 { 2719 ::rtl::OUString sSql; 2720 xObjectProps->getPropertyValue(PROPERTY_COMMAND) >>= sSql; 2721 Reference< XMultiServiceFactory > xFactory( pConData->xConnection, UNO_QUERY ); 2722 if (xFactory.is()) 2723 { 2724 try 2725 { 2726 Reference<XSingleSelectQueryAnalyzer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY); 2727 if ( xAnalyzer.is() ) 2728 { 2729 xAnalyzer->setQuery(sSql); 2730 Reference<XParametersSupplier> xParSup(xAnalyzer,UNO_QUERY); 2731 if ( xParSup->getParameters()->getCount() > 0 ) 2732 { 2733 String sFilter = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE ")); 2734 sFilter = sFilter + xAnalyzer->getFilter(); 2735 String sReplace(sSql); 2736 sReplace.SearchAndReplace(sFilter,String()); 2737 xAnalyzer->setQuery(sReplace); 2738 Reference<XSingleSelectQueryComposer> xComposer(xAnalyzer,UNO_QUERY); 2739 xComposer->setFilter(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0=1"))); 2740 aName = xAnalyzer->getQuery(); 2741 nCommandType = CommandType::COMMAND; 2742 } 2743 } 2744 } 2745 catch (Exception&) 2746 { 2747 DBG_UNHANDLED_EXCEPTION(); 2748 } 2749 } 2750 } 2751 } 2752 } 2753 } 2754 } 2755 2756 String sDataSourceName( getDataSourceAcessor( pConnection ) ); 2757 bSuccess = implLoadAnything( sDataSourceName, aName, nCommandType, bEscapeProcessing, pConData->xConnection ); 2758 if ( !bSuccess ) 2759 { // clean up 2760 criticalFail(); 2761 } 2762 } 2763 catch(const SQLException& e) 2764 { 2765 showError(SQLExceptionInfo(e)); 2766 // reset the values 2767 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any()); 2768 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any()); 2769 } 2770 catch(WrappedTargetException& e) 2771 { 2772 SQLException aSql; 2773 if(e.TargetException >>= aSql) 2774 showError(SQLExceptionInfo(aSql)); 2775 else 2776 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::implSelect: something strange happended!"); 2777 // reset the values 2778 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any()); 2779 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any()); 2780 } 2781 catch(Exception&) 2782 { 2783 // reset the values 2784 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any()); 2785 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any()); 2786 } 2787 } 2788 return bSuccess; 2789 } 2790 2791 // ----------------------------------------------------------------------------- 2792 SvLBoxEntry* SbaTableQueryBrowser::getEntryFromContainer(const Reference<XNameAccess>& _rxNameAccess) 2793 { 2794 DBTreeListBox& rListBox = m_pTreeView->getListBox(); 2795 SvLBoxEntry* pContainer = NULL; 2796 SvLBoxEntry* pDSLoop = rListBox.FirstChild(NULL); 2797 while (pDSLoop) 2798 { 2799 pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_QUERIES); 2800 DBTreeListUserData* pQueriesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData()); 2801 if ( pQueriesData && pQueriesData->xContainer == _rxNameAccess ) 2802 break; 2803 2804 pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_TABLES); 2805 DBTreeListUserData* pTablesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData()); 2806 if ( pTablesData && pTablesData->xContainer == _rxNameAccess ) 2807 break; 2808 2809 pDSLoop = rListBox.NextSibling(pDSLoop); 2810 pContainer = NULL; 2811 } 2812 return pContainer; 2813 } 2814 2815 // ------------------------------------------------------------------------- 2816 void SAL_CALL SbaTableQueryBrowser::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException) 2817 { 2818 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 2819 2820 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY); 2821 // first search for a definition container where we can insert this element 2822 2823 SvLBoxEntry* pEntry = getEntryFromContainer(xNames); 2824 if(pEntry) // found one 2825 { 2826 // insert the new entry into the tree 2827 DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pEntry->GetUserData()); 2828 OSL_ENSURE(pContainerData, "elementInserted: There must be user data for this type!"); 2829 2830 DBTreeListUserData* pNewData = new DBTreeListUserData; 2831 sal_Bool bIsTable = etTableContainer == pContainerData->eType; 2832 if ( bIsTable ) 2833 { 2834 _rEvent.Element >>= pNewData->xObjectProperties;// remember the new element 2835 pNewData->eType = etTableOrView; 2836 } 2837 else 2838 { 2839 if ((sal_Int32)m_pTreeView->getListBox().GetChildCount(pEntry) < ( xNames->getElementNames().getLength() - 1 ) ) 2840 { 2841 // the item inserts its children on demand, but it has not been expanded yet. So ensure here and 2842 // now that it has all items 2843 populateTree(xNames, pEntry, etQuery ); 2844 } 2845 pNewData->eType = etQuery; 2846 } 2847 implAppendEntry( pEntry, ::comphelper::getString( _rEvent.Accessor ), pNewData, pNewData->eType ); 2848 } 2849 else 2850 SbaXDataBrowserController::elementInserted(_rEvent); 2851 } 2852 // ------------------------------------------------------------------------- 2853 sal_Bool SbaTableQueryBrowser::isCurrentlyDisplayedChanged(const String& _sName,SvLBoxEntry* _pContainer) 2854 { 2855 return m_pCurrentlyDisplayed 2856 && getEntryType(m_pCurrentlyDisplayed) == getChildType(_pContainer) 2857 && m_pTreeView->getListBox().GetParent(m_pCurrentlyDisplayed) == _pContainer 2858 && m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed) == _sName; 2859 } 2860 // ------------------------------------------------------------------------- 2861 void SAL_CALL SbaTableQueryBrowser::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException) 2862 { 2863 ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); 2864 2865 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY); 2866 // get the top-level representing the removed data source 2867 // and search for the queries and tables 2868 SvLBoxEntry* pContainer = getEntryFromContainer(xNames); 2869 if ( pContainer ) 2870 { // a query or table has been removed 2871 String aName = ::comphelper::getString(_rEvent.Accessor).getStr(); 2872 2873 if ( isCurrentlyDisplayedChanged( aName, pContainer) ) 2874 { // the element displayed currently has been replaced 2875 2876 // we need to remember the old value 2877 SvLBoxEntry* pTemp = m_pCurrentlyDisplayed; 2878 2879 // unload 2880 unloadAndCleanup( sal_False ); // don't dispose the connection 2881 2882 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData()); 2883 pTemp->SetUserData(NULL); 2884 delete pData; 2885 // the data could be null because we have a table which isn't correct 2886 m_pTreeModel->Remove(pTemp); 2887 } 2888 else 2889 { 2890 // remove the entry from the model 2891 SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer); 2892 while(pChild) 2893 { 2894 if (m_pTreeView->getListBox().GetEntryText(pChild) == aName) 2895 { 2896 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData()); 2897 pChild->SetUserData(NULL); 2898 delete pData; 2899 m_pTreeModel->Remove(pChild); 2900 break; 2901 } 2902 pChild = m_pTreeModel->NextSibling(pChild); 2903 } 2904 } 2905 2906 // maybe the object which is part of the document data source has been removed 2907 checkDocumentDataSource(); 2908 } 2909 else 2910 SbaXDataBrowserController::elementRemoved(_rEvent); 2911 } 2912 2913 // ------------------------------------------------------------------------- 2914 void SAL_CALL SbaTableQueryBrowser::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException) 2915 { 2916 ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); 2917 2918 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY); 2919 SvLBoxEntry* pContainer = getEntryFromContainer(xNames); 2920 if ( pContainer ) 2921 { // a table or query as been replaced 2922 String aName = ::comphelper::getString(_rEvent.Accessor).getStr(); 2923 2924 if ( isCurrentlyDisplayedChanged( aName, pContainer) ) 2925 { // the element displayed currently has been replaced 2926 2927 // we need to remember the old value 2928 SvLBoxEntry* pTemp = m_pCurrentlyDisplayed; 2929 unloadAndCleanup( sal_False ); // don't dispose the connection 2930 2931 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData()); 2932 if (pData) 2933 { 2934 if ( etTableOrView == pData->eType ) 2935 { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query 2936 _rEvent.Element >>= pData->xObjectProperties; // remember the new element 2937 } 2938 else 2939 { 2940 pTemp->SetUserData(NULL); 2941 delete pData; 2942 } 2943 } 2944 } 2945 else 2946 { 2947 // find the entry for this name 2948 SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer); 2949 while(pChild) 2950 { 2951 if (m_pTreeView->getListBox().GetEntryText(pChild) == aName) 2952 { 2953 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData()); 2954 if (pData) 2955 { 2956 if ( etTableOrView == pData->eType ) 2957 { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query 2958 _rEvent.Element >>= pData->xObjectProperties; // remember the new element 2959 } 2960 else 2961 { 2962 pChild->SetUserData(NULL); 2963 delete pData; 2964 } 2965 } 2966 break; 2967 } 2968 pChild = m_pTreeModel->NextSibling(pChild); 2969 } 2970 } 2971 2972 // maybe the object which is part of the document data source has been removed 2973 checkDocumentDataSource(); 2974 } 2975 else if (xNames.get() == m_xDatabaseContext.get()) 2976 { // a datasource has been replaced in the context 2977 DBG_ERROR("SbaTableQueryBrowser::elementReplaced: no support for replaced data sources!"); 2978 // very suspicious: the database context should not allow to replace data source, only to register 2979 // and revoke them 2980 } 2981 else 2982 SbaXDataBrowserController::elementReplaced(_rEvent); 2983 } 2984 2985 // ------------------------------------------------------------------------- 2986 void SbaTableQueryBrowser::impl_releaseConnection( SharedConnection& _rxConnection ) 2987 { 2988 // remove as event listener 2989 Reference< XComponent > xComponent( _rxConnection, UNO_QUERY ); 2990 if ( xComponent.is() ) 2991 { 2992 Reference< XEventListener > xListener( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY ); 2993 xComponent->removeEventListener( xListener ); 2994 } 2995 2996 try 2997 { 2998 // temporary (hopefully!) hack for #i55274# 2999 Reference< XFlushable > xFlush( _rxConnection, UNO_QUERY ); 3000 if ( xFlush.is() ) 3001 xFlush->flush(); 3002 } 3003 catch( const Exception& ) 3004 { 3005 DBG_UNHANDLED_EXCEPTION(); 3006 } 3007 3008 // clear 3009 _rxConnection.clear(); 3010 // will implicitly dispose if we have the ownership, since xConnection is a SharedConnection 3011 } 3012 3013 // ------------------------------------------------------------------------- 3014 void SbaTableQueryBrowser::disposeConnection( SvLBoxEntry* _pDSEntry ) 3015 { 3016 DBG_ASSERT( _pDSEntry, "SbaTableQueryBrowser::disposeConnection: invalid entry (NULL)!" ); 3017 DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::disposeConnection: invalid entry (not top-level)!" ); 3018 3019 if ( _pDSEntry ) 3020 { 3021 DBTreeListUserData* pTreeListData = static_cast< DBTreeListUserData* >( _pDSEntry->GetUserData() ); 3022 if ( pTreeListData ) 3023 impl_releaseConnection( pTreeListData->xConnection ); 3024 } 3025 } 3026 3027 // ------------------------------------------------------------------------- 3028 void SbaTableQueryBrowser::closeConnection(SvLBoxEntry* _pDSEntry,sal_Bool _bDisposeConnection) 3029 { 3030 DBG_ASSERT(_pDSEntry, "SbaTableQueryBrowser::closeConnection: invalid entry (NULL)!"); 3031 DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::closeConnection: invalid entry (not top-level)!"); 3032 3033 // if one of the entries of the given DS is displayed currently, unload the form 3034 if (m_pCurrentlyDisplayed && (m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed) == _pDSEntry)) 3035 unloadAndCleanup(_bDisposeConnection); 3036 3037 // collapse the query/table container 3038 for (SvLBoxEntry* pContainers = m_pTreeModel->FirstChild(_pDSEntry); pContainers; pContainers= m_pTreeModel->NextSibling(pContainers)) 3039 { 3040 SvLBoxEntry* pElements = m_pTreeModel->FirstChild(pContainers); 3041 if ( pElements ) 3042 m_pTreeView->getListBox().Collapse(pContainers); 3043 m_pTreeView->getListBox().EnableExpandHandler(pContainers); 3044 // and delete their children (they are connection-relative) 3045 for (; pElements; ) 3046 { 3047 SvLBoxEntry* pRemove = pElements; 3048 pElements= m_pTreeModel->NextSibling(pElements); 3049 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pRemove->GetUserData()); 3050 pRemove->SetUserData(NULL); 3051 delete pData; 3052 m_pTreeModel->Remove(pRemove); 3053 } 3054 } 3055 // collapse the entry itself 3056 m_pTreeView->getListBox().Collapse(_pDSEntry); 3057 3058 // dispose/reset the connection 3059 if ( _bDisposeConnection ) 3060 disposeConnection( _pDSEntry ); 3061 } 3062 3063 // ------------------------------------------------------------------------- 3064 void SbaTableQueryBrowser::unloadAndCleanup( sal_Bool _bDisposeConnection ) 3065 { 3066 if (!m_pCurrentlyDisplayed) 3067 // nothing to do 3068 return; 3069 3070 SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed); 3071 3072 // de-select the path for the currently displayed table/query 3073 if (m_pCurrentlyDisplayed) 3074 { 3075 selectPath(m_pCurrentlyDisplayed, sal_False); 3076 } 3077 m_pCurrentlyDisplayed = NULL; 3078 3079 try 3080 { 3081 // get the active connection. We need to dispose it. 3082 Reference< XPropertySet > xRowSetProps(getRowSet(),UNO_QUERY); 3083 Reference< XConnection > xConn; 3084 xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION) >>= xConn; 3085 #if OSL_DEBUG_LEVEL > 1 3086 { 3087 Reference< XComponent > xComp; 3088 ::cppu::extractInterface(xComp, xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION)); 3089 } 3090 #endif 3091 3092 // unload the form 3093 Reference< XLoadable > xLoadable = getLoadable(); 3094 if (xLoadable->isLoaded()) 3095 xLoadable->unload(); 3096 3097 // clear the grid control 3098 Reference< XNameContainer > xConta(getControlModel(),UNO_QUERY); 3099 clearGridColumns(xConta); 3100 3101 // dispose the connection 3102 if(_bDisposeConnection) 3103 disposeConnection( pDSEntry ); 3104 } 3105 catch(SQLException& e) 3106 { 3107 showError(SQLExceptionInfo(e)); 3108 } 3109 catch(WrappedTargetException& e) 3110 { 3111 SQLException aSql; 3112 if(e.TargetException >>= aSql) 3113 showError(SQLExceptionInfo(aSql)); 3114 else 3115 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::unloadAndCleanup: something strange happended!"); 3116 } 3117 catch(Exception&) 3118 { 3119 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::unloadAndCleanup: could not reset the form"); 3120 } 3121 } 3122 3123 // ------------------------------------------------------------------------- 3124 namespace 3125 { 3126 Reference< XInterface > lcl_getDataSource( const Reference< XNameAccess >& _rxDatabaseContext, 3127 const ::rtl::OUString& _rDataSourceName, const Reference< XConnection >& _rxConnection ) 3128 { 3129 Reference< XDataSource > xDataSource; 3130 try 3131 { 3132 if ( _rDataSourceName.getLength() && _rxDatabaseContext->hasByName( _rDataSourceName ) ) 3133 xDataSource.set( _rxDatabaseContext->getByName( _rDataSourceName ), UNO_QUERY_THROW ); 3134 3135 if ( !xDataSource.is() ) 3136 { 3137 Reference< XChild > xConnAsChild( _rxConnection, UNO_QUERY ); 3138 if ( xConnAsChild.is() ) 3139 xDataSource.set( xConnAsChild->getParent(), UNO_QUERY_THROW ); 3140 } 3141 } 3142 catch( const Exception& ) 3143 { 3144 DBG_UNHANDLED_EXCEPTION(); 3145 } 3146 return xDataSource.get(); 3147 } 3148 } 3149 3150 // ------------------------------------------------------------------------- 3151 void SbaTableQueryBrowser::impl_initialize() 3152 { 3153 ::vos::OGuard aGuard(Application::GetSolarMutex()); 3154 // doin' a lot of VCL stuff here -> lock the SolarMutex 3155 3156 // first initialize the parent 3157 SbaXDataBrowserController::impl_initialize(); 3158 3159 Reference<XConnection> xForeignConnection; 3160 Reference< XFrame > xFrame; 3161 3162 ::rtl::OUString aTableName, aCatalogName, aSchemaName; 3163 3164 sal_Bool bEsacpeProcessing = sal_True; 3165 sal_Int32 nInitialDisplayCommandType = CommandType::COMMAND; 3166 ::rtl::OUString sInitialDataSourceName; 3167 ::rtl::OUString sInitialCommand; 3168 3169 const NamedValueCollection& rArguments( getInitParams() ); 3170 3171 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_DATASOURCENAME, sInitialDataSourceName ); 3172 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND_TYPE, nInitialDisplayCommandType ); 3173 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND, sInitialCommand ); 3174 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, xForeignConnection ); 3175 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_CATALOGNAME, aCatalogName ); 3176 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_SCHEMANAME, aSchemaName ); 3177 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_TABLENAME, aTableName ); 3178 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, bEsacpeProcessing ); 3179 rArguments.get_ensureType( "Frame", xFrame ); 3180 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_SHOWMENU, m_bShowMenu ); 3181 3182 // disable the browser if either of ShowTreeViewButton (compatibility name) or EnableBrowser 3183 // is present and set to FALSE 3184 sal_Bool bDisableBrowser = ( sal_False == rArguments.getOrDefault( "ShowTreeViewButton", sal_True ) ) // compatibility name 3185 || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_True ) ); 3186 OSL_ENSURE( !rArguments.has( "ShowTreeViewButton" ), 3187 "SbaTableQueryBrowser::impl_initialize: ShowTreeViewButton is superseded by EnableBrowser!" ); 3188 m_bEnableBrowser = !bDisableBrowser; 3189 3190 // hide the tree view it is disabled in general, or if the settings tell to hide it initially 3191 sal_Bool bHideTreeView = ( !m_bEnableBrowser ) 3192 || ( sal_False == rArguments.getOrDefault( "ShowTreeView", sal_True ) ) // compatibility name 3193 || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_SHOW_BROWSER, sal_True ) ); 3194 OSL_ENSURE( !rArguments.has( "ShowTreeView" ), 3195 "SbaTableQueryBrowser::impl_initialize: ShowTreeView is superseded by ShowBrowser!" ); 3196 3197 if ( bHideTreeView ) 3198 hideExplorer(); 3199 else 3200 showExplorer(); 3201 3202 if ( m_bPreview ) 3203 { 3204 try 3205 { 3206 Sequence< ::rtl::OUString> aProperties(5); 3207 Sequence< Any> aValues(5); 3208 3209 ::rtl::OUString* pStringIter = aProperties.getArray(); 3210 Any* pValueIter = aValues.getArray(); 3211 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlwaysShowCursor")); 3212 *pValueIter++ <<= sal_False; 3213 *pStringIter++ = PROPERTY_BORDER; 3214 *pValueIter++ <<= sal_Int16(0); 3215 3216 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasNavigationBar")); 3217 *pValueIter++ <<= sal_False; 3218 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasRecordMarker")); 3219 *pValueIter++ <<= sal_False; 3220 3221 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tabstop")); 3222 *pValueIter++ <<= sal_False; 3223 3224 Reference< XMultiPropertySet > xFormMultiSet(getFormComponent(), UNO_QUERY); 3225 if ( xFormMultiSet.is() ) 3226 xFormMultiSet->setPropertyValues(aProperties, aValues); 3227 } 3228 catch(Exception) 3229 { 3230 DBG_UNHANDLED_EXCEPTION(); 3231 } 3232 } 3233 3234 // are we loaded into a (sub)frame of an embedded document (i.e. a form belonging to a database 3235 // document)? 3236 sal_Bool bSubFrameOfEmbeddedDocument = sal_False; 3237 if ( xFrame.is() ) 3238 { 3239 Reference<XFramesSupplier> xSup = xFrame->getCreator(); 3240 Reference<XController> xCont = xSup.is() ? xSup->getController() : Reference<XController>(); 3241 3242 bSubFrameOfEmbeddedDocument = xCont.is() && ::dbtools::isEmbeddedInDatabase( xCont->getModel(), xForeignConnection ); 3243 } 3244 3245 // if we have a connection at this point, it was either passed from outside, our 3246 // determined from a outer DB document. In both cases, do not dispose it later on. 3247 SharedConnection xConnection( xForeignConnection, SharedConnection::NoTakeOwnership ); 3248 3249 // should we display all registered databases in the left hand side tree? 3250 // or only *one* special? 3251 sal_Bool bLimitedTreeEntries = sal_False; 3252 // if we're part of a frame which is a secondary frame of a database document, then only 3253 // display the database for this document, not all registered ones 3254 bLimitedTreeEntries |= bSubFrameOfEmbeddedDocument; 3255 // if the tree view is not to be displayed at all, then only display the data source 3256 // which was given as initial selection 3257 bLimitedTreeEntries |= ( m_bEnableBrowser != sal_True ); 3258 3259 if ( bLimitedTreeEntries ) 3260 { 3261 if ( xConnection.is() ) 3262 { 3263 startConnectionListening( xConnection ); 3264 3265 // if no initial name was given, try to obtain one from the data source 3266 if ( !sInitialDataSourceName.getLength() ) 3267 { 3268 Reference< XChild > xChild( xConnection, UNO_QUERY ); 3269 Reference< XPropertySet > xDataSourceProperties; 3270 if ( xChild.is() ) 3271 xDataSourceProperties = xDataSourceProperties.query( xChild->getParent() ); 3272 if ( xDataSourceProperties.is() ) 3273 { 3274 try 3275 { 3276 OSL_VERIFY( xDataSourceProperties->getPropertyValue( PROPERTY_NAME ) >>= sInitialDataSourceName ); 3277 } 3278 catch( const Exception& ) 3279 { 3280 OSL_ENSURE( sal_False, "SbaTableQueryBrowser::impl_initialize: a connection parent which does not have a 'Name'!??" ); 3281 } 3282 } 3283 } 3284 } 3285 3286 implAddDatasource( sInitialDataSourceName, xConnection ); 3287 m_pTreeView->getListBox().Expand( m_pTreeView->getListBox().First() ); 3288 } 3289 else 3290 initializeTreeModel(); 3291 3292 if ( m_bEnableBrowser ) 3293 { 3294 m_aDocScriptSupport = ::boost::optional< bool >( false ); 3295 } 3296 else 3297 { 3298 // we are not used as "browser", but as mere view for a single table/query/command. In particular, 3299 // there is a specific database document which we belong to. 3300 Reference< XOfficeDatabaseDocument > xDocument( getDataSourceOrModel( 3301 lcl_getDataSource( m_xDatabaseContext, sInitialDataSourceName, xConnection ) ), UNO_QUERY ); 3302 m_aDocScriptSupport = ::boost::optional< bool >( Reference< XEmbeddedScripts >( xDocument, UNO_QUERY ).is() ); 3303 } 3304 3305 if ( implSelect( sInitialDataSourceName, sInitialCommand, nInitialDisplayCommandType, bEsacpeProcessing, xConnection, sal_True ) ) 3306 { 3307 try 3308 { 3309 Reference< XPropertySet > xRowSetProps(getRowSet(), UNO_QUERY); 3310 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_CATALOGNAME,makeAny(aCatalogName)); 3311 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_SCHEMANAME,makeAny(aSchemaName)); 3312 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_TABLENAME,makeAny(aTableName)); 3313 3314 } 3315 catch(const Exception&) 3316 { 3317 OSL_ENSURE(sal_False, "SbaTableQueryBrowser::impl_initialize: could not set the update related names!"); 3318 } 3319 } 3320 3321 InvalidateAll(); 3322 } 3323 3324 // ------------------------------------------------------------------------- 3325 sal_Bool SbaTableQueryBrowser::haveExplorer() const 3326 { 3327 return m_pTreeView && m_pTreeView->IsVisible(); 3328 } 3329 3330 // ------------------------------------------------------------------------- 3331 void SbaTableQueryBrowser::hideExplorer() 3332 { 3333 if (!haveExplorer()) 3334 return; 3335 if (!getBrowserView()) 3336 return; 3337 3338 m_pTreeView->Hide(); 3339 m_pSplitter->Hide(); 3340 getBrowserView()->Resize(); 3341 3342 InvalidateFeature(ID_BROWSER_EXPLORER); 3343 } 3344 3345 // ------------------------------------------------------------------------- 3346 void SbaTableQueryBrowser::showExplorer() 3347 { 3348 if (haveExplorer()) 3349 return; 3350 3351 if (!getBrowserView()) 3352 return; 3353 3354 m_pTreeView->Show(); 3355 m_pSplitter->Show(); 3356 getBrowserView()->Resize(); 3357 3358 InvalidateFeature(ID_BROWSER_EXPLORER); 3359 } 3360 3361 // ----------------------------------------------------------------------------- 3362 sal_Bool SbaTableQueryBrowser::ensureConnection(SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection) 3363 { 3364 SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(_pAnyEntry); 3365 DBTreeListUserData* pDSData = 3366 pDSEntry 3367 ? static_cast<DBTreeListUserData*>(pDSEntry->GetUserData()) 3368 : NULL; 3369 3370 return ensureConnection( pDSEntry, pDSData, _rConnection ); 3371 } 3372 3373 // ----------------------------------------------------------------------------- 3374 ::std::auto_ptr< ImageProvider > SbaTableQueryBrowser::getImageProviderFor( SvLBoxEntry* _pAnyEntry ) 3375 { 3376 ::std::auto_ptr< ImageProvider > pImageProvider( new ImageProvider ); 3377 SharedConnection xConnection; 3378 if ( getExistentConnectionFor( _pAnyEntry, xConnection ) ) 3379 pImageProvider.reset( new ImageProvider( xConnection ) ); 3380 return pImageProvider; 3381 } 3382 3383 // ----------------------------------------------------------------------------- 3384 sal_Bool SbaTableQueryBrowser::getExistentConnectionFor( SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection ) 3385 { 3386 SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent( _pAnyEntry ); 3387 DBTreeListUserData* pDSData = 3388 pDSEntry 3389 ? static_cast< DBTreeListUserData* >( pDSEntry->GetUserData() ) 3390 : NULL; 3391 if ( pDSData ) 3392 _rConnection = pDSData->xConnection; 3393 return _rConnection.is(); 3394 } 3395 3396 #ifdef DBG_UTIL 3397 // ----------------------------------------------------------------------------- 3398 bool SbaTableQueryBrowser::impl_isDataSourceEntry( SvLBoxEntry* _pEntry ) const 3399 { 3400 return m_pTreeModel->GetRootLevelParent( _pEntry ) == _pEntry; 3401 } 3402 #endif 3403 3404 // ----------------------------------------------------------------------------- 3405 sal_Bool SbaTableQueryBrowser::ensureConnection( SvLBoxEntry* _pDSEntry, void* pDSData, SharedConnection& _rConnection ) 3406 { 3407 DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::ensureConnection: this entry does not denote a data source!" ); 3408 if(_pDSEntry) 3409 { 3410 DBTreeListUserData* pTreeListData = static_cast<DBTreeListUserData*>(pDSData); 3411 ::rtl::OUString aDSName = GetEntryText(_pDSEntry); 3412 3413 if ( pTreeListData ) 3414 _rConnection = pTreeListData->xConnection; 3415 3416 if ( !_rConnection.is() && pTreeListData ) 3417 { 3418 // show the "connecting to ..." status 3419 String sConnecting(ModuleRes(STR_CONNECTING_DATASOURCE)); 3420 sConnecting.SearchAndReplaceAscii("$name$", aDSName); 3421 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sConnecting); 3422 3423 // build a string showing context information in case of error 3424 String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) ); 3425 sConnectingContext.SearchAndReplaceAscii("$name$", aDSName); 3426 3427 // connect 3428 _rConnection.reset( 3429 connect( getDataSourceAcessor( _pDSEntry ), sConnectingContext, NULL ), 3430 SharedConnection::TakeOwnership 3431 ); 3432 3433 // remember the connection 3434 pTreeListData->xConnection = _rConnection; 3435 } 3436 } 3437 3438 return _rConnection.is(); 3439 } 3440 3441 // ----------------------------------------------------------------------------- 3442 IMPL_LINK( SbaTableQueryBrowser, OnTreeEntryCompare, const SvSortData*, _pSortData ) 3443 { 3444 SvLBoxEntry* pLHS = static_cast<SvLBoxEntry*>(_pSortData->pLeft); 3445 SvLBoxEntry* pRHS = static_cast<SvLBoxEntry*>(_pSortData->pRight); 3446 DBG_ASSERT(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!"); 3447 // we want the table entry and the end so we have to do a check 3448 3449 if (isContainer(pRHS)) 3450 { 3451 // don't use getEntryType (directly or indirecly) for the LHS: 3452 // LHS is currently beeing inserted, so it is not "completely valid" at the moment 3453 3454 const EntryType eRight = getEntryType(pRHS); 3455 if (etTableContainer == eRight) 3456 // every other container should be placed _before_ the bookmark container 3457 return -1; 3458 3459 const String sLeft = m_pTreeView->getListBox().GetEntryText(pLHS); 3460 3461 EntryType eLeft = etTableContainer; 3462 if (String(ModuleRes(RID_STR_TABLES_CONTAINER)) == sLeft) 3463 eLeft = etTableContainer; 3464 else if (String(ModuleRes(RID_STR_QUERIES_CONTAINER)) == sLeft) 3465 eLeft = etQueryContainer; 3466 3467 if ( eLeft == eRight ) 3468 return COMPARE_EQUAL; 3469 3470 if ( ( eLeft == etTableContainer ) && ( eRight == etQueryContainer ) ) 3471 return COMPARE_GREATER; 3472 3473 if ( ( eLeft == etQueryContainer ) && ( eRight == etTableContainer ) ) 3474 return COMPARE_LESS; 3475 3476 OSL_ENSURE( false, "SbaTableQueryBrowser::OnTreeEntryCompare: unexpected case!" ); 3477 return COMPARE_EQUAL; 3478 } 3479 3480 SvLBoxString* pLeftTextItem = static_cast<SvLBoxString*>(pLHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); 3481 SvLBoxString* pRightTextItem = static_cast<SvLBoxString*>(pRHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); 3482 DBG_ASSERT(pLeftTextItem && pRightTextItem, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid text items!"); 3483 3484 String sLeftText = pLeftTextItem->GetText(); 3485 String sRightText = pRightTextItem->GetText(); 3486 3487 sal_Int32 nCompareResult = 0; // equal by default 3488 3489 if (m_xCollator.is()) 3490 { 3491 try 3492 { 3493 nCompareResult = m_xCollator->compareString(sLeftText, sRightText); 3494 } 3495 catch(Exception&) 3496 { 3497 } 3498 } 3499 else 3500 // default behaviour if we do not have a collator -> do the simple string compare 3501 nCompareResult = sLeftText.CompareTo(sRightText); 3502 3503 return nCompareResult; 3504 } 3505 3506 // ----------------------------------------------------------------------------- 3507 void SbaTableQueryBrowser::implAdministrate( SvLBoxEntry* _pApplyTo ) 3508 { 3509 OSL_PRECOND( _pApplyTo, "SbaTableQueryBrowser::implAdministrate: illegal entry!" ); 3510 if ( !_pApplyTo ) 3511 return; 3512 3513 try 3514 { 3515 // get the desktop object 3516 sal_Int32 nFrameSearchFlag = FrameSearchFlag::ALL | FrameSearchFlag::GLOBAL ; 3517 Reference< XComponentLoader > xFrameLoader(getORB()->createInstance(SERVICE_FRAME_DESKTOP),UNO_QUERY); 3518 3519 if ( xFrameLoader.is() ) 3520 { 3521 // the initial selection 3522 SvLBoxEntry* pTopLevelSelected = _pApplyTo; 3523 while (pTopLevelSelected && m_pTreeView->getListBox().GetParent(pTopLevelSelected)) 3524 pTopLevelSelected = m_pTreeView->getListBox().GetParent(pTopLevelSelected); 3525 ::rtl::OUString sInitialSelection; 3526 if (pTopLevelSelected) 3527 sInitialSelection = getDataSourceAcessor( pTopLevelSelected ); 3528 3529 Reference< XDataSource > xDataSource( getDataSourceByName( sInitialSelection, getView(), getORB(), NULL ) ); 3530 Reference< XModel > xDocumentModel( getDataSourceOrModel( xDataSource ), UNO_QUERY ); 3531 3532 if ( xDocumentModel.is() ) 3533 { 3534 Reference< XInteractionHandler > xInteractionHandler( 3535 getORB()->createInstance( 3536 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), 3537 UNO_QUERY ); 3538 OSL_ENSURE( xInteractionHandler.is(), "SbaTableQueryBrowser::implAdministrate: no interaction handler available!" ); 3539 3540 ::comphelper::NamedValueCollection aLoadArgs; 3541 aLoadArgs.put( "Model", xDocumentModel ); 3542 aLoadArgs.put( "InteractionHandler", xInteractionHandler ); 3543 aLoadArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG ); 3544 3545 Sequence< PropertyValue > aLoadArgPV; 3546 aLoadArgs >>= aLoadArgPV; 3547 3548 xFrameLoader->loadComponentFromURL( 3549 xDocumentModel->getURL(), 3550 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_default")), 3551 nFrameSearchFlag, 3552 aLoadArgPV 3553 ); 3554 } 3555 } 3556 } 3557 catch( const Exception& ) 3558 { 3559 DBG_UNHANDLED_EXCEPTION(); 3560 } 3561 } 3562 3563 // ----------------------------------------------------------------------------- 3564 sal_Bool SbaTableQueryBrowser::requestQuickHelp( const SvLBoxEntry* _pEntry, String& _rText ) const 3565 { 3566 const DBTreeListUserData* pData = static_cast< const DBTreeListUserData* >( _pEntry->GetUserData() ); 3567 if ( ( pData->eType == etDatasource ) && pData->sAccessor.Len() ) 3568 { 3569 _rText = ::svt::OFileNotation( pData->sAccessor ).get( ::svt::OFileNotation::N_SYSTEM ); 3570 return sal_True; 3571 } 3572 return sal_False; 3573 } 3574 3575 // ----------------------------------------------------------------------------- 3576 PopupMenu* SbaTableQueryBrowser::getContextMenu( Control& _rControl ) const 3577 { 3578 OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl, 3579 "SbaTableQueryBrowser::getContextMenu: where does this come from?" ); 3580 if ( &m_pTreeView->getListBox() != &_rControl ) 3581 return NULL; 3582 3583 return new PopupMenu( ModuleRes( MENU_BROWSER_DEFAULTCONTEXT ) ); 3584 } 3585 3586 // ----------------------------------------------------------------------------- 3587 IController& SbaTableQueryBrowser::getCommandController() 3588 { 3589 return *this; 3590 } 3591 3592 // ----------------------------------------------------------------------------- 3593 ::cppu::OInterfaceContainerHelper* SbaTableQueryBrowser::getContextMenuInterceptors() 3594 { 3595 return &m_aContextMenuInterceptors; 3596 } 3597 3598 // ----------------------------------------------------------------------------- 3599 Any SbaTableQueryBrowser::getCurrentSelection( Control& _rControl ) const 3600 { 3601 OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl, 3602 "SbaTableQueryBrowser::getCurrentSelection: where does this come from?" ); 3603 3604 if ( &m_pTreeView->getListBox() != &_rControl ) 3605 return Any(); 3606 3607 SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected(); 3608 if ( !pSelected ) 3609 return Any(); 3610 3611 OSL_ENSURE( m_pTreeView->getListBox().NextSelected( pSelected ) == NULL, 3612 "SbaTableQueryBrowser::getCurrentSelection: single-selection is expected here!" ); 3613 3614 NamedDatabaseObject aSelectedObject; 3615 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pSelected->GetUserData() ); 3616 aSelectedObject.Type = static_cast< sal_Int32 >( pData->eType ); 3617 3618 switch ( aSelectedObject.Type ) 3619 { 3620 case DatabaseObject::QUERY: 3621 case DatabaseObject::TABLE: 3622 aSelectedObject.Name = m_pTreeView->getListBox().GetEntryText( pSelected ); 3623 break; 3624 3625 case DatabaseObjectContainer::DATA_SOURCE: 3626 case DatabaseObjectContainer::QUERIES: 3627 case DatabaseObjectContainer::TABLES: 3628 aSelectedObject.Name = getDataSourceAcessor( pSelected ); 3629 break; 3630 3631 default: 3632 OSL_ENSURE( false, "SbaTableQueryBrowser::getCurrentSelection: invalid (unexpected) object type!" ); 3633 break; 3634 } 3635 3636 return makeAny( aSelectedObject ); 3637 } 3638 3639 // ----------------------------------------------------------------------------- 3640 sal_Bool SbaTableQueryBrowser::implGetQuerySignature( ::rtl::OUString& _rCommand, sal_Bool& _bEscapeProcessing ) 3641 { 3642 _rCommand = ::rtl::OUString(); 3643 _bEscapeProcessing = sal_False; 3644 3645 try 3646 { 3647 // ontain the dss (data source signature) of the form 3648 ::rtl::OUString sDataSourceName; 3649 ::rtl::OUString sCommand; 3650 sal_Int32 nCommandType = CommandType::COMMAND; 3651 Reference< XPropertySet > xRowsetProps( getRowSet(), UNO_QUERY ); 3652 ODataAccessDescriptor aDesc( xRowsetProps ); 3653 sDataSourceName = aDesc.getDataSource(); 3654 aDesc[ daCommand ] >>= sCommand; 3655 aDesc[ daCommandType ] >>= nCommandType; 3656 3657 // do we need to do anything? 3658 if ( CommandType::QUERY != nCommandType ) 3659 return sal_False; 3660 3661 // get the query object 3662 Reference< XQueryDefinitionsSupplier > xSuppQueries; 3663 Reference< XNameAccess > xQueries; 3664 Reference< XPropertySet > xQuery; 3665 m_xDatabaseContext->getByName( sDataSourceName ) >>= xSuppQueries; 3666 if ( xSuppQueries.is() ) 3667 xQueries = xSuppQueries->getQueryDefinitions(); 3668 if ( xQueries.is() ) 3669 xQueries->getByName( sCommand ) >>= xQuery; 3670 OSL_ENSURE( xQuery.is(), "SbaTableQueryBrowser::implGetQuerySignature: could not retrieve the query object!" ); 3671 3672 // get the two properties we need 3673 if ( xQuery.is() ) 3674 { 3675 xQuery->getPropertyValue( PROPERTY_COMMAND ) >>= _rCommand; 3676 _bEscapeProcessing = ::cppu::any2bool( xQuery->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) ); 3677 return sal_True; 3678 } 3679 } 3680 catch( const Exception& ) 3681 { 3682 DBG_UNHANDLED_EXCEPTION(); 3683 } 3684 3685 return sal_False; 3686 } 3687 //------------------------------------------------------------------------------ 3688 void SbaTableQueryBrowser::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException ) 3689 { 3690 if (aEvent.Frame == m_xCurrentFrameParent) 3691 { 3692 if(aEvent.Action == FrameAction_COMPONENT_DETACHING) 3693 implRemoveStatusListeners(); 3694 else if (aEvent.Action == FrameAction_COMPONENT_REATTACHED) 3695 connectExternalDispatches(); 3696 } 3697 else 3698 SbaXDataBrowserController::frameAction(aEvent); 3699 3700 } 3701 // ----------------------------------------------------------------------------- 3702 void SbaTableQueryBrowser::clearGridColumns(const Reference< XNameContainer >& _xColContainer) 3703 { 3704 // first we have to clear the grid 3705 Sequence< ::rtl::OUString > aNames = _xColContainer->getElementNames(); 3706 const ::rtl::OUString* pIter = aNames.getConstArray(); 3707 const ::rtl::OUString* pEnd = pIter + aNames.getLength(); 3708 Reference< XInterface > xColumn; 3709 for (; pIter != pEnd;++pIter) 3710 { 3711 _xColContainer->getByName(*pIter) >>= xColumn; 3712 _xColContainer->removeByName(*pIter); 3713 ::comphelper::disposeComponent(xColumn); 3714 } 3715 } 3716 // ----------------------------------------------------------------------------- 3717 sal_Bool SbaTableQueryBrowser::isHiContrast() const 3718 { 3719 sal_Bool bRet = sal_False; 3720 if ( m_pTreeView ) 3721 bRet = m_pTreeView->getListBox().GetSettings().GetStyleSettings().GetHighContrastMode(); 3722 return bRet; 3723 } 3724 // ----------------------------------------------------------------------------- 3725 void SbaTableQueryBrowser::loadMenu(const Reference< XFrame >& _xFrame) 3726 { 3727 if ( m_bShowMenu ) 3728 { 3729 OGenericUnoController::loadMenu(_xFrame); 3730 } 3731 else if ( !m_bPreview ) 3732 { 3733 Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager = getLayoutManager(_xFrame); 3734 3735 if ( xLayoutManager.is() ) 3736 { 3737 xLayoutManager->lock(); 3738 xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ))); 3739 xLayoutManager->unlock(); 3740 xLayoutManager->doLayout(); 3741 } 3742 onLoadedMenu( xLayoutManager ); 3743 } 3744 } 3745 // ----------------------------------------------------------------------------- 3746 ::rtl::OUString SbaTableQueryBrowser::getPrivateTitle() const 3747 { 3748 ::rtl::OUString sTitle; 3749 if ( m_pCurrentlyDisplayed ) 3750 { 3751 SvLBoxEntry* pContainer = m_pTreeModel->GetParent(m_pCurrentlyDisplayed); 3752 // get the entry for the datasource 3753 SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer); 3754 ::rtl::OUString sName = m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed); 3755 sTitle = GetEntryText( pConnection ); 3756 INetURLObject aURL(sTitle); 3757 if ( aURL.GetProtocol() != INET_PROT_NOT_VALID ) 3758 sTitle = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET); 3759 if ( sName.getLength() ) 3760 { 3761 sName += ::rtl::OUString::createFromAscii(" - "); 3762 sName += sTitle; 3763 sTitle = sName; 3764 } 3765 } 3766 3767 return sTitle; 3768 } 3769 // ----------------------------------------------------------------------------- 3770 sal_Bool SbaTableQueryBrowser::preReloadForm() 3771 { 3772 sal_Bool bIni = sal_False; 3773 if ( !m_pCurrentlyDisplayed ) 3774 { 3775 // switch the grid to design mode while loading 3776 getBrowserView()->getGridControl()->setDesignMode(sal_True); 3777 // we had an invalid statement so we need to connect the column models 3778 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY); 3779 ::svx::ODataAccessDescriptor aDesc(xRowSetProps); 3780 // extract the props 3781 ::rtl::OUString sDataSource; 3782 ::rtl::OUString sCommand; 3783 sal_Int32 nCommandType = CommandType::COMMAND; 3784 sal_Bool bEscapeProcessing = sal_True; 3785 extractDescriptorProps(aDesc, sDataSource, sCommand, nCommandType, bEscapeProcessing); 3786 if ( sDataSource.getLength() && sCommand.getLength() && (-1 != nCommandType) ) 3787 { 3788 SvLBoxEntry* pDataSource = NULL; 3789 SvLBoxEntry* pCommandType = NULL; 3790 m_pCurrentlyDisplayed = getObjectEntry( sDataSource, sCommand, nCommandType, &pDataSource, &pCommandType, sal_True, SharedConnection() ); 3791 bIni = sal_True; 3792 } 3793 } 3794 return bIni; 3795 } 3796 3797 // ----------------------------------------------------------------------------- 3798 void SbaTableQueryBrowser::postReloadForm() 3799 { 3800 InitializeGridModel(getFormComponent()); 3801 LoadFinished(sal_True); 3802 //updateTitle(); 3803 } 3804 3805 //------------------------------------------------------------------------------ 3806 Reference< XEmbeddedScripts > SAL_CALL SbaTableQueryBrowser::getScriptContainer() throw (RuntimeException) 3807 { 3808 // update our database document 3809 Reference< XModel > xDocument; 3810 try 3811 { 3812 Reference< XPropertySet > xCursorProps( getRowSet(), UNO_QUERY_THROW ); 3813 Reference< XConnection > xConnection( xCursorProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY ); 3814 if ( xConnection.is() ) 3815 { 3816 Reference< XChild > xChild( xConnection, UNO_QUERY_THROW ); 3817 Reference< XDocumentDataSource > xDataSource( xChild->getParent(), UNO_QUERY_THROW ); 3818 xDocument.set( xDataSource->getDatabaseDocument(), UNO_QUERY_THROW ); 3819 } 3820 } 3821 catch( const Exception& ) 3822 { 3823 DBG_UNHANDLED_EXCEPTION(); 3824 } 3825 Reference< XEmbeddedScripts > xScripts( xDocument, UNO_QUERY ); 3826 OSL_ENSURE( xScripts.is() || !xDocument.is(), 3827 "SbaTableQueryBrowser::getScriptContainer: invalid database document!" ); 3828 return xScripts; 3829 } 3830 3831 //------------------------------------------------------------------------------ 3832 void SAL_CALL SbaTableQueryBrowser::registerContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException) 3833 { 3834 if ( _Interceptor.is() ) 3835 m_aContextMenuInterceptors.addInterface( _Interceptor ); 3836 } 3837 3838 //------------------------------------------------------------------------------ 3839 void SAL_CALL SbaTableQueryBrowser::releaseContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException) 3840 { 3841 if ( _Interceptor.is() ) 3842 m_aContextMenuInterceptors.removeInterface( _Interceptor ); 3843 } 3844 3845 //------------------------------------------------------------------------------ 3846 void SAL_CALL SbaTableQueryBrowser::registeredDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException) 3847 { 3848 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 3849 implAddDatasource( _Event.Name, SharedConnection() ); 3850 } 3851 3852 //------------------------------------------------------------------------------ 3853 void SbaTableQueryBrowser::impl_cleanupDataSourceEntry( const String& _rDataSourceName ) 3854 { 3855 // get the top-level representing the removed data source 3856 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().FirstChild( NULL ); 3857 while ( pDataSourceEntry ) 3858 { 3859 if ( m_pTreeView->getListBox().GetEntryText( pDataSourceEntry ) == _rDataSourceName ) 3860 break; 3861 3862 pDataSourceEntry = m_pTreeView->getListBox().NextSibling( pDataSourceEntry ); 3863 } 3864 3865 OSL_ENSURE( pDataSourceEntry, "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: do not know this data source!" ); 3866 if ( !pDataSourceEntry ) 3867 return; 3868 3869 if ( isSelected( pDataSourceEntry ) ) 3870 { // a table or query belonging to the deleted data source is currently beeing displayed. 3871 OSL_ENSURE( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) == pDataSourceEntry, 3872 "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (1)!" ); 3873 unloadAndCleanup( sal_True ); 3874 } 3875 else 3876 OSL_ENSURE( 3877 ( NULL == m_pCurrentlyDisplayed ) 3878 || ( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) != pDataSourceEntry ), 3879 "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (2)!"); 3880 3881 // delete any user data of the child entries of the to-be-removed entry 3882 SvTreeEntryList* pList = m_pTreeModel->GetChildList( pDataSourceEntry ); 3883 if ( pList ) 3884 { 3885 SvLBoxEntry* pEntryLoop = static_cast<SvLBoxEntry*>( pList->First() ); 3886 while ( pEntryLoop ) 3887 { 3888 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pEntryLoop->GetUserData() ); 3889 pEntryLoop->SetUserData( NULL ); 3890 delete pData; 3891 pEntryLoop = static_cast< SvLBoxEntry* >( pList->Next() ); 3892 } 3893 } 3894 3895 // remove the entry 3896 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() ); 3897 pDataSourceEntry->SetUserData( NULL ); 3898 delete pData; 3899 m_pTreeModel->Remove( pDataSourceEntry ); 3900 } 3901 3902 //------------------------------------------------------------------------------ 3903 void SAL_CALL SbaTableQueryBrowser::revokedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException) 3904 { 3905 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 3906 3907 impl_cleanupDataSourceEntry( _Event.Name ); 3908 3909 // maybe the object which is part of the document data source has been removed 3910 checkDocumentDataSource(); 3911 } 3912 3913 //------------------------------------------------------------------------------ 3914 void SAL_CALL SbaTableQueryBrowser::changedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException) 3915 { 3916 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 3917 3918 // in case the data source was expanded, and connected, we need to clean it up 3919 // for simplicity, just do as if the data source were completely removed and re-added 3920 impl_cleanupDataSourceEntry( _Event.Name ); 3921 implAddDatasource( _Event.Name, SharedConnection() ); 3922 } 3923 3924 3925 // ......................................................................... 3926 } // namespace dbaui 3927 // ......................................................................... 3928 3929 3930