| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_dbaccess.hxx" |
| |
| #include "browserids.hxx" |
| #include "dbaccess_helpid.hrc" |
| #include "dbexchange.hxx" |
| #include "dbtreelistbox.hxx" |
| #include "dbtreemodel.hxx" |
| #include "dbtreeview.hxx" |
| #include "dbu_brw.hrc" |
| #include "dbu_reghelper.hxx" |
| #include "dbustrings.hrc" |
| #include "dlgsave.hxx" |
| #include "HtmlReader.hxx" |
| #include "imageprovider.hxx" |
| #include "listviewitems.hxx" |
| #include "QEnumTypes.hxx" |
| #include "RtfReader.hxx" |
| #include "sbagrid.hrc" |
| #include "sbagrid.hxx" |
| #include "sqlmessage.hxx" |
| #include "TokenWriter.hxx" |
| #include "UITools.hxx" |
| #include "unodatbr.hxx" |
| #include "WColumnSelect.hxx" |
| #include "WCopyTable.hxx" |
| #include "WCPage.hxx" |
| #include "WExtendPages.hxx" |
| #include "WNameMatch.hxx" |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/awt/LineEndFormat.hpp> |
| #include <com/sun/star/awt/LineEndFormat.hpp> |
| #include <com/sun/star/awt/MouseWheelBehavior.hpp> |
| #include <com/sun/star/awt/TextAlign.hpp> |
| #include <com/sun/star/awt/VisualEffect.hpp> |
| #include <com/sun/star/beans/NamedValue.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #include <com/sun/star/container/XNameContainer.hpp> |
| #include <com/sun/star/form/XForm.hpp> |
| #include <com/sun/star/form/XGridColumnFactory.hpp> |
| #include <com/sun/star/form/XLoadable.hpp> |
| #include <com/sun/star/form/XReset.hpp> |
| #include <com/sun/star/frame/FrameSearchFlag.hpp> |
| #include <com/sun/star/frame/XLayoutManager.hpp> |
| #include <com/sun/star/lang/DisposedException.hpp> |
| #include <com/sun/star/sdb/CommandType.hpp> |
| #include <com/sun/star/sdb/SQLContext.hpp> |
| #include <com/sun/star/sdb/XBookmarksSupplier.hpp> |
| #include <com/sun/star/sdb/XCompletedConnection.hpp> |
| #include <com/sun/star/sdb/XDatabaseRegistrations.hpp> |
| #include <com/sun/star/sdb/XDocumentDataSource.hpp> |
| #include <com/sun/star/sdb/XParametersSupplier.hpp> |
| #include <com/sun/star/sdb/XQueriesSupplier.hpp> |
| #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp> |
| #include <com/sun/star/sdb/XResultSetAccess.hpp> |
| #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> |
| #include <com/sun/star/sdb/application/NamedDatabaseObject.hpp> |
| #include <com/sun/star/sdbc/ColumnValue.hpp> |
| #include <com/sun/star/sdbc/DataType.hpp> |
| #include <com/sun/star/sdbc/FetchDirection.hpp> |
| #include <com/sun/star/sdbc/SQLWarning.hpp> |
| #include <com/sun/star/sdbc/XDataSource.hpp> |
| #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> |
| #include <com/sun/star/sdbc/XWarningsSupplier.hpp> |
| #include <com/sun/star/sdbcx/Privilege.hpp> |
| #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> |
| #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp> |
| #include <com/sun/star/sdbcx/XDrop.hpp> |
| #include <com/sun/star/sdbcx/XTablesSupplier.hpp> |
| #include <com/sun/star/sdbcx/XViewsSupplier.hpp> |
| #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> |
| #include <com/sun/star/util/XFlushable.hpp> |
| #include <com/sun/star/sdb/XDocumentDataSource.hpp> |
| #include <com/sun/star/document/MacroExecMode.hpp> |
| #include <com/sun/star/frame/XComponentLoader.hpp> |
| #include <com/sun/star/ui/XContextMenuInterceptor.hpp> |
| /** === end UNO includes === **/ |
| |
| #include <comphelper/extract.hxx> |
| #include <comphelper/sequence.hxx> |
| #include <comphelper/types.hxx> |
| #include <connectivity/dbexception.hxx> |
| #include <cppuhelper/exc_hlp.hxx> |
| #include <cppuhelper/implbase2.hxx> |
| #include <cppuhelper/typeprovider.hxx> |
| #include <sfx2/app.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include <sot/storage.hxx> |
| #include <svl/filenotation.hxx> |
| #include <svl/intitem.hxx> |
| #include <unotools/moduleoptions.hxx> |
| #include <svtools/svlbitm.hxx> |
| #include <svtools/svtreebx.hxx> |
| #include <svx/algitem.hxx> |
| #include <svx/dataaccessdescriptor.hxx> |
| #include <svx/databaseregistrationui.hxx> |
| #include <svx/gridctrl.hxx> |
| #include <toolkit/unohlp.hxx> |
| #include <tools/diagnose_ex.h> |
| #include <tools/multisel.hxx> |
| #include <tools/urlobj.hxx> |
| #include <unotools/confignode.hxx> |
| #include <vcl/msgbox.hxx> |
| #include <vcl/split.hxx> |
| #include <vcl/stdtext.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vcl/toolbox.hxx> |
| #include <vcl/waitobj.hxx> |
| #include <vcl/wrkwin.hxx> |
| #include <rtl/logfile.hxx> |
| |
| #include <memory> |
| |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::awt; |
| using namespace ::com::sun::star::sdb; |
| using namespace ::com::sun::star::sdb::application; |
| using namespace ::com::sun::star::sdbc; |
| using namespace ::com::sun::star::sdbcx; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::ui::dialogs; |
| using namespace ::com::sun::star::task; |
| using namespace ::com::sun::star::form; |
| using namespace ::com::sun::star::io; |
| using namespace ::com::sun::star::i18n; |
| using namespace ::com::sun::star::view; |
| using namespace ::com::sun::star::datatransfer; |
| using namespace ::com::sun::star::document; |
| using namespace ::com::sun::star::ui; |
| using namespace ::dbtools; |
| using namespace ::comphelper; |
| using namespace ::svx; |
| |
| // ......................................................................... |
| namespace dbaui |
| { |
| // ......................................................................... |
| |
| namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject; |
| namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer; |
| |
| //================================================================== |
| //= SbaTableQueryBrowser |
| //================================================================== |
| // ------------------------------------------------------------------------- |
| extern "C" void SAL_CALL createRegistryInfo_OBrowser() |
| { |
| static OMultiInstanceAutoRegistration< SbaTableQueryBrowser > aAutoRegistration; |
| } |
| // ------------------------------------------------------------------------- |
| void SafeAddPropertyListener(const Reference< XPropertySet > & xSet, const ::rtl::OUString& rPropName, XPropertyChangeListener* pListener) |
| { |
| Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo(); |
| if (xInfo->hasPropertyByName(rPropName)) |
| xSet->addPropertyChangeListener(rPropName, pListener); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SafeRemovePropertyListener(const Reference< XPropertySet > & xSet, const ::rtl::OUString& rPropName, XPropertyChangeListener* pListener) |
| { |
| Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo(); |
| if (xInfo->hasPropertyByName(rPropName)) |
| xSet->removePropertyChangeListener(rPropName, pListener); |
| } |
| //------------------------------------------------------------------------- |
| ::rtl::OUString SAL_CALL SbaTableQueryBrowser::getImplementationName() throw(RuntimeException) |
| { |
| return getImplementationName_Static(); |
| } |
| //------------------------------------------------------------------------- |
| ::comphelper::StringSequence SAL_CALL SbaTableQueryBrowser::getSupportedServiceNames() throw(RuntimeException) |
| { |
| return getSupportedServiceNames_Static(); |
| } |
| // ------------------------------------------------------------------------- |
| ::rtl::OUString SbaTableQueryBrowser::getImplementationName_Static() throw(RuntimeException) |
| { |
| return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.ODatasourceBrowser"); |
| } |
| //------------------------------------------------------------------------- |
| ::comphelper::StringSequence SbaTableQueryBrowser::getSupportedServiceNames_Static() throw(RuntimeException) |
| { |
| ::comphelper::StringSequence aSupported(1); |
| aSupported.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.DataSourceBrowser"); |
| return aSupported; |
| } |
| //------------------------------------------------------------------------- |
| Reference< XInterface > SAL_CALL SbaTableQueryBrowser::Create(const Reference<XMultiServiceFactory >& _rxFactory) |
| { |
| ::vos::OGuard aGuard(Application::GetSolarMutex()); |
| return *(new SbaTableQueryBrowser(_rxFactory)); |
| } |
| |
| DBG_NAME(SbaTableQueryBrowser); |
| //------------------------------------------------------------------------------ |
| SbaTableQueryBrowser::SbaTableQueryBrowser(const Reference< XMultiServiceFactory >& _rM) |
| :SbaXDataBrowserController(_rM) |
| ,m_aSelectionListeners( getMutex() ) |
| ,m_aContextMenuInterceptors( getMutex() ) |
| ,m_aTableCopyHelper(this) |
| ,m_pTreeView(NULL) |
| ,m_pSplitter(NULL) |
| ,m_pTreeModel(NULL) |
| ,m_pCurrentlyDisplayed(NULL) |
| ,m_nAsyncDrop(0) |
| ,m_nBorder(1) |
| ,m_bQueryEscapeProcessing( sal_False ) |
| ,m_bShowMenu(sal_False) |
| ,m_bInSuspend(sal_False) |
| ,m_bEnableBrowser(sal_True) |
| { |
| DBG_CTOR(SbaTableQueryBrowser,NULL); |
| } |
| |
| //------------------------------------------------------------------------------ |
| SbaTableQueryBrowser::~SbaTableQueryBrowser() |
| { |
| DBG_DTOR(SbaTableQueryBrowser,NULL); |
| if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) |
| { |
| OSL_ENSURE(0,"Please check who doesn't dispose this component!"); |
| // increment ref count to prevent double call of Dtor |
| osl_incrementInterlockedCount( &m_refCount ); |
| dispose(); |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| Any SAL_CALL SbaTableQueryBrowser::queryInterface(const Type& _rType) throw (RuntimeException) |
| { |
| if ( _rType.equals( XScriptInvocationContext::static_type() ) ) |
| { |
| OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::queryInterface: did not initialize this, yet!" ); |
| if ( !!m_aDocScriptSupport && *m_aDocScriptSupport ) |
| return makeAny( Reference< XScriptInvocationContext >( this ) ); |
| return Any(); |
| } |
| |
| Any aReturn = SbaXDataBrowserController::queryInterface(_rType); |
| if (!aReturn.hasValue()) |
| aReturn = SbaTableQueryBrowser_Base::queryInterface(_rType); |
| return aReturn; |
| } |
| |
| //------------------------------------------------------------------------------ |
| Sequence< Type > SAL_CALL SbaTableQueryBrowser::getTypes( ) throw (RuntimeException) |
| { |
| Sequence< Type > aTypes( ::comphelper::concatSequences( |
| SbaXDataBrowserController::getTypes(), |
| SbaTableQueryBrowser_Base::getTypes() |
| ) ); |
| |
| OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::getTypes: did not initialize this, yet!" ); |
| if ( !m_aDocScriptSupport || !*m_aDocScriptSupport ) |
| { |
| Sequence< Type > aStrippedTypes( aTypes.getLength() - 1 ); |
| ::std::remove_copy_if( |
| aTypes.getConstArray(), |
| aTypes.getConstArray() + aTypes.getLength(), |
| aStrippedTypes.getArray(), |
| ::std::bind2nd( ::std::equal_to< Type >(), XScriptInvocationContext::static_type() ) |
| ); |
| aTypes = aStrippedTypes; |
| } |
| return aTypes; |
| } |
| |
| //------------------------------------------------------------------------------ |
| Sequence< sal_Int8 > SAL_CALL SbaTableQueryBrowser::getImplementationId( ) throw (RuntimeException) |
| { |
| static ::cppu::OImplementationId * pId = 0; |
| if (! pId) |
| { |
| ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); |
| if (! pId) |
| { |
| static ::cppu::OImplementationId aId; |
| pId = &aId; |
| } |
| } |
| return pId->getImplementationId(); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL SbaTableQueryBrowser::disposing() |
| { |
| ::vos::OGuard aGuard(Application::GetSolarMutex()); |
| // doin' a lot of VCL stuff here -> lock the SolarMutex |
| |
| // kiss our listeners goodbye |
| EventObject aEvt(*this); |
| m_aSelectionListeners.disposeAndClear(aEvt); |
| m_aContextMenuInterceptors.disposeAndClear(aEvt); |
| |
| // reset the content's tree view: it holds a reference to our model which is to be deleted immediately, |
| // and it will live longer than we do. |
| if (getBrowserView()) |
| getBrowserView()->setTreeView(NULL); |
| |
| clearTreeModel(); |
| // clear the tree model |
| { |
| ::std::auto_ptr<SvLBoxTreeList> aTemp(m_pTreeModel); |
| m_pTreeModel = NULL; |
| } |
| |
| // remove ourself as status listener |
| implRemoveStatusListeners(); |
| |
| // remove the container listener from the database context |
| try |
| { |
| Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW ); |
| xDatabaseRegistrations->removeDatabaseRegistrationsListener( this ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| // check out from all the objects we are listening |
| // the frame |
| if (m_xCurrentFrameParent.is()) |
| m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); |
| SbaXDataBrowserController::disposing(); |
| } |
| |
| //------------------------------------------------------------------------------ |
| sal_Bool SbaTableQueryBrowser::Construct(Window* pParent) |
| { |
| if ( !SbaXDataBrowserController::Construct( pParent ) ) |
| return sal_False; |
| |
| try |
| { |
| Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW ); |
| xDatabaseRegistrations->addDatabaseRegistrationsListener( this ); |
| |
| // the collator for the string compares |
| m_xCollator = Reference< XCollator >( getORB()->createInstance(::rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ) ), UNO_QUERY_THROW ); |
| m_xCollator->loadDefaultCollator( Application::GetSettings().GetLocale(), 0 ); |
| } |
| catch(Exception&) |
| { |
| DBG_ERROR("SbaTableQueryBrowser::Construct: could not create (or start listening at) the database context!"); |
| } |
| // some help ids |
| if (getBrowserView() && getBrowserView()->getVclControl()) |
| { |
| |
| // create controls and set sizes |
| const long nFrameWidth = getBrowserView()->LogicToPixel( ::Size( 3, 0 ), MAP_APPFONT ).Width(); |
| |
| m_pSplitter = new Splitter(getBrowserView(),WB_HSCROLL); |
| m_pSplitter->SetPosSizePixel( ::Point(0,0), ::Size(nFrameWidth,0) ); |
| m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) ); |
| |
| m_pTreeView = new DBTreeView(getBrowserView(),getORB(), WB_TABSTOP | WB_BORDER); |
| m_pTreeView->SetPreExpandHandler(LINK(this, SbaTableQueryBrowser, OnExpandEntry)); |
| |
| m_pTreeView->setCopyHandler(LINK(this, SbaTableQueryBrowser, OnCopyEntry)); |
| |
| m_pTreeView->getListBox().setContextMenuProvider( this ); |
| m_pTreeView->getListBox().setControlActionListener( this ); |
| m_pTreeView->SetHelpId(HID_CTL_TREEVIEW); |
| |
| // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide |
| m_pSplitter->SetSplitPosPixel( getBrowserView()->LogicToPixel( ::Size( 80, 0 ), MAP_APPFONT ).Width() ); |
| |
| getBrowserView()->setSplitter(m_pSplitter); |
| getBrowserView()->setTreeView(m_pTreeView); |
| |
| // fill view with data |
| m_pTreeModel = new SvLBoxTreeList; |
| m_pTreeModel->SetSortMode(SortAscending); |
| m_pTreeModel->SetCompareHdl(LINK(this, SbaTableQueryBrowser, OnTreeEntryCompare)); |
| m_pTreeView->setModel(m_pTreeModel); |
| m_pTreeView->setSelChangeHdl( LINK( this, SbaTableQueryBrowser, OnSelectionChange ) ); |
| |
| // TODO |
| getBrowserView()->getVclControl()->GetDataWindow().SetUniqueId(UID_DATABROWSE_DATAWINDOW); |
| getBrowserView()->getVclControl()->SetHelpId(HID_CTL_TABBROWSER); |
| getBrowserView()->SetUniqueId(UID_CTL_CONTENT); |
| if (getBrowserView()->getVclControl()->GetHeaderBar()) |
| getBrowserView()->getVclControl()->GetHeaderBar()->SetHelpId(HID_DATABROWSE_HEADER); |
| InvalidateFeature(ID_BROWSER_EXPLORER); |
| } |
| |
| return sal_True; |
| } |
| // --------------------------------------------------------------------------------------------------------------------- |
| namespace |
| { |
| // ----------------------------------------------------------------------------------------------------------------- |
| struct SelectValueByName : public ::std::unary_function< ::rtl::OUString, Any > |
| { |
| const Any& operator()( ::rtl::OUString const& i_name ) const |
| { |
| return m_rCollection.get( i_name ); |
| } |
| |
| SelectValueByName( ::comphelper::NamedValueCollection const& i_collection ) |
| :m_rCollection( i_collection ) |
| { |
| } |
| |
| ::comphelper::NamedValueCollection const& m_rCollection; |
| }; |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::impl_sanitizeRowSetClauses_nothrow() |
| { |
| try |
| { |
| Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW ); |
| sal_Bool bEscapeProcessing = sal_False; |
| OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing ); |
| if ( !bEscapeProcessing ) |
| // don't touch or interpret anything if escape processing is disabled |
| return; |
| |
| Reference< XSingleSelectQueryComposer > xComposer( createParser_nothrow() ); |
| if ( !xComposer.is() ) |
| // can't do anything. Already reported via assertion in createParser_nothrow. |
| return; |
| |
| // the tables participating in the statement |
| const Reference< XTablesSupplier > xSuppTables( xComposer, UNO_QUERY_THROW ); |
| const Reference< XNameAccess > xTableNames( xSuppTables->getTables(), UNO_QUERY_THROW ); |
| |
| // the columns participating in the statement |
| const Reference< XColumnsSupplier > xSuppColumns( xComposer, UNO_QUERY_THROW ); |
| const Reference< XNameAccess > xColumnNames( xSuppColumns->getColumns(), UNO_QUERY_THROW ); |
| |
| // ............................................................................................................. |
| // check if the order columns apply to tables which really exist in the statement |
| const Reference< XIndexAccess > xOrderColumns( xComposer->getOrderColumns(), UNO_SET_THROW ); |
| const sal_Int32 nOrderColumns( xOrderColumns->getCount() ); |
| bool invalidColumn = nOrderColumns == 0; |
| for ( sal_Int32 c=0; ( c < nOrderColumns ) && !invalidColumn; ++c ) |
| { |
| const Reference< XPropertySet > xOrderColumn( xOrderColumns->getByIndex(c), UNO_QUERY_THROW ); |
| ::rtl::OUString sTableName; |
| OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName ); |
| ::rtl::OUString sColumnName; |
| OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName ); |
| |
| if ( sTableName.getLength() == 0 ) |
| { |
| if ( !xColumnNames->hasByName( sColumnName ) ) |
| { |
| invalidColumn = true; |
| break; |
| } |
| } |
| else |
| { |
| if ( !xTableNames->hasByName( sTableName ) ) |
| { |
| invalidColumn = true; |
| break; |
| } |
| |
| const Reference< XColumnsSupplier > xSuppTableColumns( xTableNames->getByName( sTableName ), UNO_QUERY_THROW ); |
| const Reference< XNameAccess > xTableColumnNames( xSuppTableColumns->getColumns(), UNO_QUERY_THROW ); |
| if ( !xTableColumnNames->hasByName( sColumnName ) ) |
| { |
| invalidColumn = true; |
| break; |
| } |
| } |
| } |
| |
| if ( invalidColumn ) |
| { |
| // reset the complete order statement at both the row set and the parser |
| const ::rtl::OUString sEmptyOrder; |
| xRowSetProps->setPropertyValue( PROPERTY_ORDER, makeAny( sEmptyOrder ) ); |
| xComposer->setOrder( sEmptyOrder ); |
| } |
| |
| // ............................................................................................................. |
| // check if the columns participating in the filter refer to existing tables |
| // TODO: there's no API at all for this. The method which comes nearest to what we need is |
| // "getStructuredFilter", but it returns pure column names only. That is, for a statement like |
| // "SELECT * FROM <table> WHERE <other_table>.<column> = <value>", it will return "<column>". But |
| // there's no API at all to retrieve the information about "<other_table>" - which is what would |
| // be needed here. |
| // That'd be a chance to replace getStructuredFilter with something more reasonable. This method |
| // has at least one other problem: For a clause like "<column> != <value>", it will return "<column>" |
| // as column name, "NOT_EQUAL" as operator, and "!= <value>" as value, effectively duplicating the |
| // information about the operator, and beding all clients to manually remove the "!=" from the value |
| // string. |
| // So, what really would be handy, is some |
| // XNormalizedFilter getNormalizedFilter(); |
| // with |
| // interface XDisjunctiveFilterExpression |
| // { |
| // XConjunctiveFilterTerm getTerm( int index ); |
| // } |
| // interface XConjunctiveFilterTerm |
| // { |
| // ComparisonPredicate getPredicate( int index ); |
| // } |
| // struct ComparisonPredicate |
| // { |
| // XComparisonOperand Lhs; |
| // SQLFilterOperator Operator; |
| // XComparisonOperand Rhs; |
| // } |
| // interface XComparisonOperand |
| // { |
| // SQLFilterOperand Type; |
| // XPropertySet getColumn(); |
| // string getLiteral(); |
| // ... |
| // } |
| // enum SQLFilterOperand { Column, Literal, ... } |
| // |
| // ... or something like this .... |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| // --------------------------------------------------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::InitializeForm( const Reference< XPropertySet > & i_formProperties ) |
| { |
| if(!m_pCurrentlyDisplayed) |
| return sal_True; |
| |
| // this method set all format settings from the orignal table or query |
| try |
| { |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData()); |
| ENSURE_OR_RETURN_FALSE( pData, "SbaTableQueryBrowser::InitializeForm: No user data set at the currently displayed entry!" ); |
| ENSURE_OR_RETURN_FALSE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeForm: No table available!" ); |
| |
| Reference< XPropertySetInfo > xPSI( pData->xObjectProperties->getPropertySetInfo(), UNO_SET_THROW ); |
| |
| ::comphelper::NamedValueCollection aPropertyValues; |
| |
| const ::rtl::OUString aTransferProperties[] = |
| { |
| PROPERTY_APPLYFILTER, |
| PROPERTY_FILTER, |
| PROPERTY_HAVING_CLAUSE, |
| PROPERTY_ORDER |
| }; |
| for ( size_t i=0; i < sizeof( aTransferProperties ) / sizeof( aTransferProperties[0] ); ++i ) |
| { |
| if ( !xPSI->hasPropertyByName( aTransferProperties[i] ) ) |
| continue; |
| aPropertyValues.put( aTransferProperties[i], pData->xObjectProperties->getPropertyValue( aTransferProperties[i] ) ); |
| } |
| |
| const ::std::vector< ::rtl::OUString > aNames( aPropertyValues.getNames() ); |
| Sequence< ::rtl::OUString > aPropNames( aNames.size() ); |
| ::std::copy( aNames.begin(), aNames.end(), aPropNames.getArray() ); |
| |
| Sequence< Any > aPropValues( aNames.size() ); |
| ::std::transform( aNames.begin(), aNames.end(), aPropValues.getArray(), SelectValueByName( aPropertyValues ) ); |
| |
| Reference< XMultiPropertySet > xFormMultiSet( i_formProperties, UNO_QUERY_THROW ); |
| xFormMultiSet->setPropertyValues( aPropNames, aPropValues ); |
| |
| impl_sanitizeRowSetClauses_nothrow(); |
| } |
| catch ( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| return sal_False; |
| } |
| |
| return sal_True; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SbaTableQueryBrowser::initializePreviewMode() |
| { |
| if ( getBrowserView() && getBrowserView()->getVclControl() ) |
| { |
| getBrowserView()->getVclControl()->AlwaysEnableInput( sal_False ); |
| getBrowserView()->getVclControl()->EnableInput( sal_False ); |
| getBrowserView()->getVclControl()->ForceHideScrollbars( sal_True ); |
| } |
| Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY); |
| if ( xDataSourceSet.is() ) |
| { |
| xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowInserts")),makeAny(sal_False)); |
| xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowUpdates")),makeAny(sal_False)); |
| xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowDeletes")),makeAny(sal_False)); |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| sal_Bool SbaTableQueryBrowser::InitializeGridModel(const Reference< ::com::sun::star::form::XFormComponent > & xGrid) |
| { |
| try |
| { |
| Reference< ::com::sun::star::form::XGridColumnFactory > xColFactory(xGrid, UNO_QUERY); |
| Reference< XNameContainer > xColContainer(xGrid, UNO_QUERY); |
| clearGridColumns( xColContainer ); |
| |
| Reference< XChild > xGridAsChild(xGrid, UNO_QUERY); |
| Reference< XLoadable > xFormAsLoadable; |
| if (xGridAsChild.is()) |
| xFormAsLoadable = xFormAsLoadable.query(xGridAsChild->getParent()); |
| if (xFormAsLoadable.is() && xFormAsLoadable->isLoaded()) |
| { |
| // set the formats from the table |
| if(m_pCurrentlyDisplayed) |
| { |
| Sequence< ::rtl::OUString> aProperties(6 + ( m_bPreview ? 5 : 0 )); |
| Sequence< Any> aValues(7 + ( m_bPreview ? 5 : 0 )); |
| |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData()); |
| OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeGridModel: No table available!" ); |
| if ( !pData->xObjectProperties.is() ) |
| return sal_False; |
| |
| ::rtl::OUString* pStringIter = aProperties.getArray(); |
| Any* pValueIter = aValues.getArray(); |
| if ( m_bPreview ) |
| { |
| *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlwaysShowCursor")); |
| *pValueIter++ <<= sal_False; |
| *pStringIter++ = PROPERTY_BORDER; |
| *pValueIter++ <<= sal_Int16(0); |
| } |
| |
| *pStringIter++ = PROPERTY_FONT; |
| *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_FONT); |
| *pStringIter++ = PROPERTY_TEXTEMPHASIS; |
| *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTEMPHASIS); |
| *pStringIter++ = PROPERTY_TEXTRELIEF; |
| *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTRELIEF); |
| if ( m_bPreview ) |
| { |
| *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasNavigationBar")); |
| *pValueIter++ <<= sal_False; |
| *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasRecordMarker")); |
| *pValueIter++ <<= sal_False; |
| } |
| *pStringIter++ = PROPERTY_ROW_HEIGHT; |
| *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_ROW_HEIGHT); |
| if ( m_bPreview ) |
| { |
| *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tabstop")); |
| *pValueIter++ <<= sal_False; |
| } |
| *pStringIter++ = PROPERTY_TEXTCOLOR; |
| *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTCOLOR); |
| *pStringIter++ = PROPERTY_TEXTLINECOLOR; |
| *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTLINECOLOR); |
| |
| Reference< XMultiPropertySet > xFormMultiSet(xGrid, UNO_QUERY); |
| xFormMultiSet->setPropertyValues(aProperties, aValues); |
| } |
| |
| |
| // get the formats supplier of the database we're working with |
| Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier = getNumberFormatter()->getNumberFormatsSupplier(); |
| |
| Reference<XConnection> xConnection; |
| Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY); |
| xRowSetProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection; |
| OSL_ENSURE(xConnection.is(),"A ActiveConnection should normaly exists!"); |
| |
| Reference<XChild> xChild(xConnection,UNO_QUERY); |
| Reference<XPropertySet> xDataSourceProp(xChild->getParent(),UNO_QUERY); |
| sal_Bool bSuppressVersionCol = sal_False; |
| OSL_VERIFY( xDataSourceProp->getPropertyValue( PROPERTY_SUPPRESSVERSIONCL ) >>= bSuppressVersionCol ); |
| |
| // insert the column into the gridcontrol so that we see something :-) |
| ::rtl::OUString aCurrentModelType; |
| Reference<XColumnsSupplier> xSupCols(getRowSet(),UNO_QUERY); |
| Reference<XNameAccess> xColumns = xSupCols->getColumns(); |
| Sequence< ::rtl::OUString> aNames = xColumns->getElementNames(); |
| const ::rtl::OUString* pIter = aNames.getConstArray(); |
| const ::rtl::OUString* pEnd = pIter + aNames.getLength(); |
| |
| ::rtl::OUString sDefaultProperty; |
| Reference< XPropertySet > xColumn; |
| Reference< XPropertySetInfo > xColPSI; |
| for (sal_uInt16 i=0; pIter != pEnd; ++i,++pIter) |
| { |
| xColumn.set( xColumns->getByName( *pIter ), UNO_QUERY_THROW ); |
| xColPSI.set( xColumn->getPropertySetInfo(), UNO_SET_THROW ); |
| |
| // ignore the column when it is a rowversion one |
| if ( bSuppressVersionCol |
| && xColPSI->hasPropertyByName( PROPERTY_ISROWVERSION ) |
| && ::cppu::any2bool( xColumn->getPropertyValue( PROPERTY_ISROWVERSION ) ) |
| ) |
| continue; |
| |
| // use the result set column's type to determine the type of grid column to create |
| sal_Bool bFormattedIsNumeric = sal_True; |
| sal_Int32 nType = ::comphelper::getINT32( xColumn->getPropertyValue( PROPERTY_TYPE ) ); |
| |
| ::std::vector< NamedValue > aInitialValues; |
| ::std::vector< ::rtl::OUString > aCopyProperties; |
| Any aDefault; |
| |
| switch(nType) |
| { |
| case DataType::BIT: |
| case DataType::BOOLEAN: |
| { |
| aCurrentModelType = ::rtl::OUString::createFromAscii("CheckBox"); |
| aInitialValues.push_back( NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualEffect" ) ), makeAny( VisualEffect::FLAT ) ) ); |
| sDefaultProperty = PROPERTY_DEFAULTSTATE; |
| |
| sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN; |
| OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable ); |
| aInitialValues.push_back( NamedValue( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TriState" ) ), |
| makeAny( sal_Bool( ColumnValue::NO_NULLS != nNullable ) ) |
| ) ); |
| if ( ColumnValue::NO_NULLS == nNullable ) |
| aDefault <<= (sal_Int16)STATE_NOCHECK; |
| } |
| break; |
| |
| case DataType::LONGVARCHAR: |
| case DataType::CLOB: |
| aInitialValues.push_back( NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiLine" ) ), makeAny( (sal_Bool)sal_True ) ) ); |
| // NO break! |
| case DataType::BINARY: |
| case DataType::VARBINARY: |
| case DataType::LONGVARBINARY: |
| aCurrentModelType = ::rtl::OUString::createFromAscii("TextField"); |
| sDefaultProperty = PROPERTY_DEFAULTTEXT; |
| break; |
| |
| case DataType::VARCHAR: |
| case DataType::CHAR: |
| bFormattedIsNumeric = sal_False; |
| // NO break! |
| default: |
| aCurrentModelType = ::rtl::OUString::createFromAscii("FormattedField"); |
| sDefaultProperty = PROPERTY_EFFECTIVEDEFAULT; |
| |
| if ( xSupplier.is() ) |
| aInitialValues.push_back( NamedValue( ::rtl::OUString::createFromAscii( "FormatsSupplier" ), makeAny( xSupplier ) ) ); |
| aInitialValues.push_back( NamedValue( ::rtl::OUString::createFromAscii( "TreatAsNumber" ), makeAny( (sal_Bool)bFormattedIsNumeric ) ) ); |
| aCopyProperties.push_back( PROPERTY_FORMATKEY ); |
| break; |
| } |
| |
| aInitialValues.push_back( NamedValue( PROPERTY_CONTROLSOURCE, makeAny( *pIter ) ) ); |
| ::rtl::OUString sLabel; |
| xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; |
| if ( sLabel.getLength() ) |
| aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( sLabel ) ) ); |
| else |
| aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( *pIter ) ) ); |
| |
| Reference< XPropertySet > xGridCol( xColFactory->createColumn( aCurrentModelType ), UNO_SET_THROW ); |
| Reference< XPropertySetInfo > xGridColPSI( xGridCol->getPropertySetInfo(), UNO_SET_THROW ); |
| |
| // calculate the default |
| if ( xGridColPSI->hasPropertyByName( PROPERTY_CONTROLDEFAULT ) ) |
| { |
| aDefault = xColumn->getPropertyValue( PROPERTY_CONTROLDEFAULT ); |
| // default value |
| if ( nType == DataType::BIT || nType == DataType::BOOLEAN ) |
| { |
| if ( aDefault.hasValue() ) |
| aDefault <<= (comphelper::getString(aDefault).toInt32() == 0) ? (sal_Int16)STATE_NOCHECK : (sal_Int16)STATE_CHECK; |
| else |
| aDefault <<= ((sal_Int16)STATE_DONTKNOW); |
| } |
| } |
| |
| if ( aDefault.hasValue() ) |
| aInitialValues.push_back( NamedValue( sDefaultProperty, aDefault ) ); |
| |
| // transfer properties from the definition to the UNO-model : |
| aCopyProperties.push_back( PROPERTY_HIDDEN ); |
| aCopyProperties.push_back( PROPERTY_WIDTH ); |
| |
| // help text to display for the column |
| Any aDescription; |
| if ( xColPSI->hasPropertyByName( PROPERTY_HELPTEXT ) ) |
| aDescription = xColumn->getPropertyValue( PROPERTY_HELPTEXT ); |
| ::rtl::OUString sTemp; |
| aDescription >>= sTemp; |
| if ( !sTemp.getLength() ) |
| xColumn->getPropertyValue( PROPERTY_DESCRIPTION ) >>= sTemp; |
| |
| aDescription <<= sTemp; |
| aInitialValues.push_back( NamedValue( PROPERTY_HELPTEXT, aDescription ) ); |
| |
| // ... horizontal justify |
| Any aAlign; aAlign <<= sal_Int16( 0 ); |
| Any aColAlign( xColumn->getPropertyValue( PROPERTY_ALIGN ) ); |
| if ( aColAlign.hasValue() ) |
| aAlign <<= sal_Int16( ::comphelper::getINT32( aColAlign ) ); |
| aInitialValues.push_back( NamedValue( PROPERTY_ALIGN, aAlign ) ); |
| |
| // don't allow the mouse to scroll in the cells |
| if ( xGridColPSI->hasPropertyByName( PROPERTY_MOUSE_WHEEL_BEHAVIOR ) ) |
| aInitialValues.push_back( NamedValue( PROPERTY_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) ) ); |
| |
| // now set all those values |
| for ( ::std::vector< NamedValue >::const_iterator property = aInitialValues.begin(); |
| property != aInitialValues.end(); |
| ++property |
| ) |
| { |
| xGridCol->setPropertyValue( property->Name, property->Value ); |
| } |
| for ( ::std::vector< ::rtl::OUString >::const_iterator copyPropertyName = aCopyProperties.begin(); |
| copyPropertyName != aCopyProperties.end(); |
| ++copyPropertyName |
| ) |
| xGridCol->setPropertyValue( *copyPropertyName, xColumn->getPropertyValue( *copyPropertyName ) ); |
| |
| xColContainer->insertByName(*pIter, makeAny(xGridCol)); |
| } |
| } |
| } |
| catch(Exception&) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| return sal_False; |
| } |
| |
| return sal_True; |
| } |
| // ----------------------------------------------------------------------------- |
| Reference<XPropertySet> getColumnHelper(SvLBoxEntry* _pCurrentlyDisplayed,const Reference<XPropertySet>& _rxSource) |
| { |
| Reference<XPropertySet> xRet; |
| if(_pCurrentlyDisplayed) |
| { |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pCurrentlyDisplayed->GetUserData()); |
| Reference<XColumnsSupplier> xColumnsSup(pData->xObjectProperties,UNO_QUERY); |
| Reference<XNameAccess> xNames = xColumnsSup->getColumns(); |
| ::rtl::OUString aName; |
| _rxSource->getPropertyValue(PROPERTY_NAME) >>= aName; |
| if(xNames.is() && xNames->hasByName(aName)) |
| xRet.set(xNames->getByName(aName),UNO_QUERY); |
| } |
| return xRet; |
| } |
| |
| // ----------------------------------------------------------------------- |
| void SbaTableQueryBrowser::transferChangedControlProperty(const ::rtl::OUString& _rProperty, const Any& _rNewValue) |
| { |
| if(m_pCurrentlyDisplayed) |
| { |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData()); |
| Reference< XPropertySet > xObjectProps(pData->xObjectProperties, UNO_QUERY); |
| OSL_ENSURE(xObjectProps.is(),"SbaTableQueryBrowser::transferChangedControlProperty: no table/query object!"); |
| if (xObjectProps.is()) |
| xObjectProps->setPropertyValue(_rProperty, _rNewValue); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| void SbaTableQueryBrowser::propertyChange(const PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException) |
| { |
| SbaXDataBrowserController::propertyChange(evt); |
| |
| try |
| { |
| Reference< XPropertySet > xSource(evt.Source, UNO_QUERY); |
| if (!xSource.is()) |
| return; |
| |
| // one of the many properties which require us to update the definition ? |
| // a column's width ? |
| else if (evt.PropertyName.equals(PROPERTY_WIDTH)) |
| { // a column width has changed -> update the model |
| // (the update of the view is done elsewhere) |
| Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource); |
| if(xProp.is()) |
| { |
| if(!evt.NewValue.hasValue()) |
| xProp->setPropertyValue(PROPERTY_WIDTH,makeAny((sal_Int32)227)); |
| else |
| xProp->setPropertyValue(PROPERTY_WIDTH,evt.NewValue); |
| } |
| } |
| |
| // a column's 'visible' state ? |
| else if (evt.PropertyName.equals(PROPERTY_HIDDEN)) |
| { |
| Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource); |
| if(xProp.is()) |
| xProp->setPropertyValue(PROPERTY_HIDDEN,evt.NewValue); |
| } |
| |
| // a columns alignment ? |
| else if (evt.PropertyName.equals(PROPERTY_ALIGN)) |
| { |
| Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource); |
| try |
| { |
| if(xProp.is()) |
| { |
| if(evt.NewValue.hasValue()) |
| { |
| sal_Int16 nAlign = 0; |
| if(evt.NewValue >>= nAlign) |
| xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(sal_Int32(nAlign))); |
| else |
| xProp->setPropertyValue(PROPERTY_ALIGN,evt.NewValue); |
| } |
| else |
| xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(::com::sun::star::awt::TextAlign::LEFT)); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| // a column's format ? |
| else if ( (evt.PropertyName.equals(PROPERTY_FORMATKEY)) |
| && (TypeClass_LONG == evt.NewValue.getValueTypeClass()) |
| ) |
| { |
| // update the model (means the definition object) |
| Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource); |
| if(xProp.is()) |
| xProp->setPropertyValue(PROPERTY_FORMATKEY,evt.NewValue); |
| } |
| |
| // some table definition properties ? |
| // the height of the rows in the grid ? |
| else if (evt.PropertyName.equals(PROPERTY_ROW_HEIGHT)) |
| { |
| if(m_pCurrentlyDisplayed) |
| { |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData()); |
| OSL_ENSURE( pData->xObjectProperties.is(), "No table available!" ); |
| |
| sal_Bool bDefault = !evt.NewValue.hasValue(); |
| if (bDefault) |
| pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,makeAny((sal_Int32)45)); |
| else |
| pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,evt.NewValue); |
| } |
| } |
| |
| else if ( evt.PropertyName.equals(PROPERTY_FONT) // the font ? |
| || evt.PropertyName.equals(PROPERTY_TEXTCOLOR) // the text color ? |
| || evt.PropertyName.equals(PROPERTY_FILTER) // the filter ? |
| || evt.PropertyName.equals(PROPERTY_HAVING_CLAUSE) // the having clause ? |
| || evt.PropertyName.equals(PROPERTY_ORDER) // the sort ? |
| || evt.PropertyName.equals(PROPERTY_APPLYFILTER) // the appliance of the filter ? |
| || evt.PropertyName.equals(PROPERTY_TEXTLINECOLOR) // the text line color ? |
| || evt.PropertyName.equals(PROPERTY_TEXTEMPHASIS) // the text emphasis ? |
| || evt.PropertyName.equals(PROPERTY_TEXTRELIEF) // the text relief ? |
| ) |
| { |
| transferChangedControlProperty(evt.PropertyName, evt.NewValue); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::suspend(sal_Bool bSuspend) throw( RuntimeException ) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| ::osl::MutexGuard aGuard( getMutex() ); |
| if ( getView() && getView()->IsInModalMode() ) |
| return sal_False; |
| sal_Bool bRet = sal_False; |
| if ( !m_bInSuspend ) |
| { |
| m_bInSuspend = sal_True; |
| if ( rBHelper.bDisposed ) |
| throw DisposedException( ::rtl::OUString(), *this ); |
| |
| bRet = SbaXDataBrowserController::suspend(bSuspend); |
| if ( bRet && getView() ) |
| getView()->Hide(); |
| |
| m_bInSuspend = sal_False; |
| } |
| |
| return bRet; |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SAL_CALL SbaTableQueryBrowser::statusChanged( const FeatureStateEvent& _rEvent ) throw(RuntimeException) |
| { |
| // search the external dispatcher causing this call |
| Reference< XDispatch > xSource(_rEvent.Source, UNO_QUERY); |
| ExternalFeaturesMap::iterator aLoop; |
| for ( aLoop = m_aExternalFeatures.begin(); |
| aLoop != m_aExternalFeatures.end(); |
| ++aLoop |
| ) |
| { |
| if ( _rEvent.FeatureURL.Complete == aLoop->second.aURL.Complete) |
| { |
| DBG_ASSERT( xSource.get() == aLoop->second.xDispatcher.get(), "SbaTableQueryBrowser::statusChanged: inconsistent!" ); |
| // update the enabled state |
| aLoop->second.bEnabled = _rEvent.IsEnabled; |
| |
| switch ( aLoop->first ) |
| { |
| case ID_BROWSER_DOCUMENT_DATASOURCE: |
| { |
| // if it's the slot for the document data source, remember the state |
| Sequence< PropertyValue > aDescriptor; |
| #if OSL_DEBUG_LEVEL > 0 |
| sal_Bool bProperFormat = |
| #endif |
| _rEvent.State >>= aDescriptor; |
| OSL_ENSURE(bProperFormat, "SbaTableQueryBrowser::statusChanged: need a data access descriptor here!"); |
| m_aDocumentDataSource.initializeFrom(aDescriptor); |
| |
| OSL_ENSURE( ( m_aDocumentDataSource.has(daDataSource) |
| || m_aDocumentDataSource.has(daDatabaseLocation) |
| ) |
| && m_aDocumentDataSource.has(daCommand) |
| && m_aDocumentDataSource.has(daCommandType), |
| "SbaTableQueryBrowser::statusChanged: incomplete descriptor!"); |
| |
| // check if we know the object which is set as document data source |
| checkDocumentDataSource(); |
| } |
| break; |
| |
| default: |
| // update the toolbox |
| implCheckExternalSlot( aLoop->first ); |
| break; |
| } |
| break; |
| } |
| } |
| |
| DBG_ASSERT(aLoop != m_aExternalFeatures.end(), "SbaTableQueryBrowser::statusChanged: don't know who sent this!"); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::checkDocumentDataSource() |
| { |
| SvLBoxEntry* pDataSourceEntry = NULL; |
| SvLBoxEntry* pContainerEntry = NULL; |
| SvLBoxEntry* pObjectEntry = getObjectEntry( m_aDocumentDataSource, &pDataSourceEntry, &pContainerEntry, sal_False ); |
| sal_Bool bKnownDocDataSource = (NULL != pObjectEntry); |
| if (!bKnownDocDataSource) |
| { |
| if (NULL != pDataSourceEntry) |
| { // at least the data source is know |
| if (NULL != pContainerEntry) |
| bKnownDocDataSource = sal_True; // assume we know it. |
| // TODO: should we expand the object container? This may be too expensive just for checking .... |
| else |
| { |
| if ((NULL == pObjectEntry) && m_aDocumentDataSource.has(daCommandType) && m_aDocumentDataSource.has(daCommand)) |
| { // maybe we have a command to be displayed ? |
| sal_Int32 nCommandType = CommandType::TABLE; |
| m_aDocumentDataSource[daCommandType] >>= nCommandType; |
| |
| ::rtl::OUString sCommand; |
| m_aDocumentDataSource[daCommand] >>= sCommand; |
| |
| bKnownDocDataSource = (CommandType::COMMAND == nCommandType) && (0 != sCommand.getLength()); |
| } |
| } |
| } |
| } |
| |
| if ( !bKnownDocDataSource ) |
| m_aExternalFeatures[ ID_BROWSER_DOCUMENT_DATASOURCE ].bEnabled = sal_False; |
| |
| // update the toolbox |
| implCheckExternalSlot(ID_BROWSER_DOCUMENT_DATASOURCE); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::extractDescriptorProps(const ::svx::ODataAccessDescriptor& _rDescriptor, ::rtl::OUString& _rDataSource, ::rtl::OUString& _rCommand, sal_Int32& _rCommandType, sal_Bool& _rEscapeProcessing) |
| { |
| _rDataSource = _rDescriptor.getDataSource(); |
| if ( _rDescriptor.has(daCommand) ) |
| _rDescriptor[daCommand] >>= _rCommand; |
| if ( _rDescriptor.has(daCommandType) ) |
| _rDescriptor[daCommandType] >>= _rCommandType; |
| |
| // escape processing is the only one allowed not to be present |
| _rEscapeProcessing = sal_True; |
| if (_rDescriptor.has(daEscapeProcessing)) |
| _rEscapeProcessing = ::cppu::any2bool(_rDescriptor[daEscapeProcessing]); |
| } |
| |
| // ------------------------------------------------------------------------- |
| namespace |
| { |
| bool getDataSourceDisplayName_isURL( const String& _rDS, String& _rDisplayName, String& _rUniqueId ) |
| { |
| INetURLObject aURL( _rDS ); |
| if ( aURL.GetProtocol() != INET_PROT_NOT_VALID ) |
| { |
| _rDisplayName = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET); |
| // _rDisplayName = aURL.getName(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET); |
| _rUniqueId = aURL.GetMainURL( INetURLObject::NO_DECODE ); |
| return true; |
| } |
| _rDisplayName = _rDS; |
| _rUniqueId = String(); |
| return false; |
| } |
| |
| // ..................................................................... |
| struct FilterByEntryDataId : public IEntryFilter |
| { |
| String sId; |
| FilterByEntryDataId( const String& _rId ) : sId( _rId ) { } |
| |
| virtual ~FilterByEntryDataId() {} |
| |
| virtual bool includeEntry( SvLBoxEntry* _pEntry ) const; |
| }; |
| |
| bool FilterByEntryDataId::includeEntry( SvLBoxEntry* _pEntry ) const |
| { |
| DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() ); |
| return ( !pData || ( pData->sAccessor == sId ) ); |
| } |
| } |
| |
| // ------------------------------------------------------------------------- |
| String SbaTableQueryBrowser::getDataSourceAcessor( SvLBoxEntry* _pDataSourceEntry ) const |
| { |
| DBG_ASSERT( _pDataSourceEntry, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry!" ); |
| |
| DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pDataSourceEntry->GetUserData() ); |
| DBG_ASSERT( pData, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry data!" ); |
| DBG_ASSERT( pData->eType == etDatasource, "SbaTableQueryBrowser::getDataSourceAcessor: entry does not denote a data source!" ); |
| return pData->sAccessor.Len() ? pData->sAccessor : GetEntryText( _pDataSourceEntry ); |
| } |
| |
| // ------------------------------------------------------------------------- |
| SvLBoxEntry* SbaTableQueryBrowser::getObjectEntry(const ::rtl::OUString& _rDataSource, const ::rtl::OUString& _rCommand, sal_Int32 _nCommandType, |
| SvLBoxEntry** _ppDataSourceEntry, SvLBoxEntry** _ppContainerEntry, sal_Bool _bExpandAncestors, |
| const SharedConnection& _rxConnection ) |
| { |
| if (_ppDataSourceEntry) |
| *_ppDataSourceEntry = NULL; |
| if (_ppContainerEntry) |
| *_ppContainerEntry = NULL; |
| |
| SvLBoxEntry* pObject = NULL; |
| if ( m_pTreeView ) |
| { |
| // look for the data source entry |
| String sDisplayName, sDataSourceId; |
| bool bIsDataSourceURL = getDataSourceDisplayName_isURL( _rDataSource, sDisplayName, sDataSourceId ); |
| // the display name may differ from the URL for readability reasons |
| // #i33699# - 2004-09-24 - fs@openoffice.org |
| |
| FilterByEntryDataId aFilter( sDataSourceId ); |
| SvLBoxEntry* pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter ); |
| if ( !pDataSource ) // check if the data source name is a file location |
| { |
| if ( bIsDataSourceURL ) |
| { |
| // special case, the data source is a URL |
| // add new entries to the list box model |
| implAddDatasource( _rDataSource, _rxConnection ); |
| pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter ); |
| DBG_ASSERT( pDataSource, "SbaTableQueryBrowser::getObjectEntry: hmm - did not find it again!" ); |
| } |
| } |
| if (_ppDataSourceEntry) |
| // (caller wants to have it ...) |
| *_ppDataSourceEntry = pDataSource; |
| |
| if (pDataSource) |
| { |
| // expand if required so |
| if (_bExpandAncestors) |
| m_pTreeView->getListBox().Expand(pDataSource); |
| |
| // look for the object container |
| SvLBoxEntry* pCommandType = NULL; |
| switch (_nCommandType) |
| { |
| case CommandType::TABLE: |
| pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_TABLES); |
| break; |
| |
| case CommandType::QUERY: |
| pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_QUERIES); |
| break; |
| } |
| |
| if (_ppContainerEntry) |
| *_ppContainerEntry = pCommandType; |
| |
| if (pCommandType) |
| { |
| // expand if required so |
| if (_bExpandAncestors) |
| { |
| m_pTreeView->getListBox().Expand(pCommandType); |
| } |
| |
| // look for the object |
| ::rtl::OUString sCommand = _rCommand; |
| sal_Int32 nIndex = 0; |
| do |
| { |
| ::rtl::OUString sPath = sCommand.getToken( 0, '/', nIndex ); |
| pObject = m_pTreeView->getListBox().GetEntryPosByName(sPath, pCommandType); |
| pCommandType = pObject; |
| if ( nIndex >= 0 ) |
| { |
| if (ensureEntryObject(pObject)) |
| { |
| DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( pObject->GetUserData() ); |
| Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY ); |
| sal_Int32 nIndex2 = nIndex; |
| sPath = sCommand.getToken( 0, '/', nIndex2 ); |
| try |
| { |
| if ( xCollection->hasByName(sPath) ) |
| { |
| if(!m_pTreeView->getListBox().GetEntryPosByName(sPath,pObject)) |
| { |
| Reference<XNameAccess> xChild(xCollection->getByName(sPath),UNO_QUERY); |
| DBTreeListUserData* pEntryData = new DBTreeListUserData; |
| pEntryData->eType = etQuery; |
| if ( xChild.is() ) |
| { |
| pEntryData->eType = etQueryContainer; |
| } |
| implAppendEntry( pObject, sPath, pEntryData, pEntryData->eType ); |
| } |
| } |
| } |
| catch(Exception&) |
| { |
| DBG_ERROR("SbaTableQueryBrowser::populateTree: could not fill the tree"); |
| } |
| } |
| } |
| // m_pTreeView->getListBox().Expand(pCommandType); |
| } |
| while ( nIndex >= 0 ); |
| } |
| } |
| } |
| return pObject; |
| } |
| |
| // ------------------------------------------------------------------------- |
| SvLBoxEntry* SbaTableQueryBrowser::getObjectEntry(const ::svx::ODataAccessDescriptor& _rDescriptor, |
| SvLBoxEntry** _ppDataSourceEntry, SvLBoxEntry** _ppContainerEntry, |
| sal_Bool _bExpandAncestors) |
| { |
| // extract the props from the descriptor |
| ::rtl::OUString sDataSource; |
| ::rtl::OUString sCommand; |
| sal_Int32 nCommandType = CommandType::COMMAND; |
| sal_Bool bEscapeProcessing = sal_True; |
| extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing); |
| |
| return getObjectEntry( sDataSource, sCommand, nCommandType, _ppDataSourceEntry, _ppContainerEntry, _bExpandAncestors, SharedConnection() ); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::connectExternalDispatches() |
| { |
| Reference< XDispatchProvider > xProvider( getFrame(), UNO_QUERY ); |
| DBG_ASSERT(xProvider.is(), "SbaTableQueryBrowser::connectExternalDispatches: no DispatchProvider !"); |
| if (xProvider.is()) |
| { |
| if ( m_aExternalFeatures.empty() ) |
| { |
| const sal_Char* pURLs[] = { |
| ".uno:DataSourceBrowser/DocumentDataSource", |
| ".uno:DataSourceBrowser/FormLetter", |
| ".uno:DataSourceBrowser/InsertColumns", |
| ".uno:DataSourceBrowser/InsertContent", |
| }; |
| const sal_uInt16 nIds[] = { |
| ID_BROWSER_DOCUMENT_DATASOURCE, |
| ID_BROWSER_FORMLETTER, |
| ID_BROWSER_INSERTCOLUMNS, |
| ID_BROWSER_INSERTCONTENT |
| }; |
| |
| for ( size_t i=0; i < sizeof( pURLs ) / sizeof( pURLs[0] ); ++i ) |
| { |
| URL aURL; |
| aURL.Complete = ::rtl::OUString::createFromAscii( pURLs[i] ); |
| if ( m_xUrlTransformer.is() ) |
| m_xUrlTransformer->parseStrict( aURL ); |
| m_aExternalFeatures[ nIds[ i ] ] = ExternalFeature( aURL ); |
| } |
| } |
| |
| for ( ExternalFeaturesMap::iterator feature = m_aExternalFeatures.begin(); |
| feature != m_aExternalFeatures.end(); |
| ++feature |
| ) |
| { |
| feature->second.xDispatcher = xProvider->queryDispatch( |
| feature->second.aURL, ::rtl::OUString::createFromAscii("_parent"), FrameSearchFlag::PARENT |
| ); |
| |
| if ( feature->second.xDispatcher.get() == static_cast< XDispatch* >( this ) ) |
| { |
| OSL_ENSURE( sal_False, "SbaTableQueryBrowser::connectExternalDispatches: this should not happen anymore!" ); |
| // (nowadays, the URLs aren't in our SupportedFeatures list anymore, so we should |
| // not supply a dispatcher for this) |
| feature->second.xDispatcher.clear(); |
| } |
| |
| if ( feature->second.xDispatcher.is() ) |
| { |
| try |
| { |
| feature->second.xDispatcher->addStatusListener( this, feature->second.aURL ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| implCheckExternalSlot( feature->first ); |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::implCheckExternalSlot( sal_uInt16 _nId ) |
| { |
| if ( !m_xMainToolbar.is() ) |
| return; |
| |
| Window* pToolboxWindow = VCLUnoHelper::GetWindow( m_xMainToolbar ); |
| ToolBox* pToolbox = dynamic_cast< ToolBox* >( pToolboxWindow ); |
| OSL_ENSURE( pToolbox, "SbaTableQueryBrowser::implCheckExternalSlot: cannot obtain the toolbox window!" ); |
| |
| // check if we have to hide this item from the toolbox |
| if ( pToolbox ) |
| { |
| sal_Bool bHaveDispatcher = m_aExternalFeatures[ _nId ].xDispatcher.is(); |
| if ( bHaveDispatcher != pToolbox->IsItemVisible( _nId ) ) |
| bHaveDispatcher ? pToolbox->ShowItem( _nId ) : pToolbox->HideItem( _nId ); |
| } |
| |
| // and invalidate this feature in general |
| InvalidateFeature( _nId ); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SAL_CALL SbaTableQueryBrowser::disposing( const EventObject& _rSource ) throw(RuntimeException) |
| { |
| // our frame ? |
| Reference< ::com::sun::star::frame::XFrame > xSourceFrame(_rSource.Source, UNO_QUERY); |
| if (m_xCurrentFrameParent.is() && (xSourceFrame == m_xCurrentFrameParent)) |
| m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); |
| else |
| { |
| // search the external dispatcher causing this call in our map |
| Reference< XDispatch > xSource(_rSource.Source, UNO_QUERY); |
| if(xSource.is()) |
| { |
| for ( ExternalFeaturesMap::iterator aLoop = m_aExternalFeatures.begin(); |
| aLoop != m_aExternalFeatures.end(); |
| ) |
| { |
| if ( aLoop->second.xDispatcher.get() != xSource.get() ) { |
| ++aLoop; |
| continue; |
| } |
| |
| // prepare to erase the aLoop iterator |
| const sal_uInt16 nSlotId = aLoop->first; |
| ExternalFeaturesMap::iterator aNext = aLoop; |
| ++aNext; |
| |
| // remove it |
| m_aExternalFeatures.erase( aLoop ); |
| |
| // maybe update the UI |
| implCheckExternalSlot( nSlotId ); |
| |
| // continue, the same XDispatch may be resposible for more than one URL |
| aLoop = aNext; |
| } |
| } |
| else |
| { |
| Reference<XConnection> xCon(_rSource.Source, UNO_QUERY); |
| if ( xCon.is() && m_pTreeView ) |
| { // our connection is in dispose so we have to find the entry equal with this connection |
| // and close it what means to collapse the entry |
| // get the top-level representing the removed data source |
| SvLBoxEntry* pDSLoop = m_pTreeView->getListBox().FirstChild(NULL); |
| while (pDSLoop) |
| { |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pDSLoop->GetUserData()); |
| if ( pData && pData->xConnection == xCon ) |
| { |
| // we set the conenction to null to avoid a second disposing of the connection |
| pData->xConnection.clear(); |
| closeConnection(pDSLoop,sal_False); |
| break; |
| } |
| |
| pDSLoop = m_pTreeView->getListBox().NextSibling(pDSLoop); |
| } |
| } |
| else |
| SbaXDataBrowserController::disposing(_rSource); |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::implRemoveStatusListeners() |
| { |
| // clear all old dispatches |
| for ( ExternalFeaturesMap::const_iterator aLoop = m_aExternalFeatures.begin(); |
| aLoop != m_aExternalFeatures.end(); |
| ++aLoop |
| ) |
| { |
| if ( aLoop->second.xDispatcher.is() ) |
| { |
| try |
| { |
| aLoop->second.xDispatcher->removeStatusListener( this, aLoop->second.aURL ); |
| } |
| catch (Exception&) |
| { |
| DBG_ERROR("SbaTableQueryBrowser::implRemoveStatusListeners: could not remove a status listener!"); |
| } |
| } |
| } |
| m_aExternalFeatures.clear(); |
| } |
| |
| // ------------------------------------------------------------------------- |
| sal_Bool SAL_CALL SbaTableQueryBrowser::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException) |
| { |
| ::vos::OGuard aGuard(Application::GetSolarMutex()); |
| // doin' a lot of VCL stuff here -> lock the SolarMutex |
| |
| Sequence< PropertyValue > aDescriptorSequence; |
| if (!(_rSelection >>= aDescriptorSequence)) |
| throw IllegalArgumentException(::rtl::OUString(), *this, 1); |
| // TODO: error message |
| |
| ODataAccessDescriptor aDescriptor; |
| try |
| { |
| aDescriptor = ODataAccessDescriptor(aDescriptorSequence); |
| } |
| catch(const Exception&) |
| { |
| OSL_ENSURE(sal_False, "SbaTableQueryBrowser::select: could not extract the descriptor!"); |
| } |
| |
| // check the precense of the props we need |
| if ( !(aDescriptor.has(daDataSource) || aDescriptor.has(daDatabaseLocation)) || !aDescriptor.has(daCommand) || !aDescriptor.has(daCommandType)) |
| throw IllegalArgumentException(::rtl::OUString(), *this, 1); |
| // TODO: error message |
| |
| return implSelect(aDescriptor,sal_True); |
| } |
| |
| // ------------------------------------------------------------------------- |
| Any SAL_CALL SbaTableQueryBrowser::getSelection( ) throw (RuntimeException) |
| { |
| Any aReturn; |
| |
| try |
| { |
| Reference< XLoadable > xLoadable(getRowSet(), UNO_QUERY); |
| if (xLoadable.is() && xLoadable->isLoaded()) |
| { |
| Reference< XPropertySet > aFormProps(getRowSet(), UNO_QUERY); |
| ODataAccessDescriptor aDescriptor(aFormProps); |
| // remove properties which are not part of our "selection" |
| aDescriptor.erase(daConnection); |
| aDescriptor.erase(daCursor); |
| |
| aReturn <<= aDescriptor.createPropertyValueSequence(); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| return aReturn; |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SAL_CALL SbaTableQueryBrowser::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) |
| { |
| m_aSelectionListeners.addInterface(_rxListener); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SAL_CALL SbaTableQueryBrowser::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) |
| { |
| m_aSelectionListeners.removeInterface(_rxListener); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::attachFrame(const Reference< ::com::sun::star::frame::XFrame > & _xFrame) throw( RuntimeException ) |
| { |
| implRemoveStatusListeners(); |
| |
| if (m_xCurrentFrameParent.is()) |
| m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); |
| |
| SbaXDataBrowserController::attachFrame(_xFrame); |
| |
| Reference< XFrame > xCurrentFrame( getFrame() ); |
| if ( xCurrentFrame.is() ) |
| { |
| m_xCurrentFrameParent = xCurrentFrame->findFrame(::rtl::OUString::createFromAscii("_parent"),FrameSearchFlag::PARENT); |
| if ( m_xCurrentFrameParent.is() ) |
| m_xCurrentFrameParent->addFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); |
| |
| // obtain our toolbox |
| try |
| { |
| Reference< XPropertySet > xFrameProps( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW ); |
| Reference< XLayoutManager > xLayouter( |
| xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ), |
| UNO_QUERY ); |
| |
| if ( xLayouter.is() ) |
| { |
| Reference< XUIElement > xUI( |
| xLayouter->getElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ) ) ), |
| UNO_SET_THROW ); |
| m_xMainToolbar = m_xMainToolbar.query( xUI->getRealInterface() ); |
| OSL_ENSURE( m_xMainToolbar.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| // get the dispatchers for the external slots |
| connectExternalDispatches(); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel) |
| { |
| SbaXDataBrowserController::addModelListeners(_xGridControlModel); |
| Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY); |
| if (xSourceSet.is()) |
| { |
| xSourceSet->addPropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->addPropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->addPropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->addPropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->addPropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->addPropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this)); |
| } |
| |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::removeModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel) |
| { |
| SbaXDataBrowserController::removeModelListeners(_xGridControlModel); |
| Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY); |
| if (xSourceSet.is()) |
| { |
| xSourceSet->removePropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->removePropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->removePropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->removePropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->removePropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this)); |
| xSourceSet->removePropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this)); |
| } |
| } |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::RowChanged() |
| { |
| if(getBrowserView()) |
| { |
| SbaGridControl* pControl = getBrowserView()->getVclControl(); |
| if (!pControl->IsEditing()) |
| InvalidateFeature(ID_BROWSER_COPY); |
| } |
| SbaXDataBrowserController::RowChanged(); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::ColumnChanged() |
| { |
| if(getBrowserView()) |
| { |
| SbaGridControl* pControl = getBrowserView()->getVclControl(); |
| if (!pControl->IsEditing()) |
| InvalidateFeature(ID_BROWSER_COPY); |
| } |
| SbaXDataBrowserController::ColumnChanged(); |
| } |
| //------------------------------------------------------------------------------ |
| void SbaTableQueryBrowser::AddColumnListener(const Reference< XPropertySet > & xCol) |
| { |
| SbaXDataBrowserController::AddColumnListener(xCol); |
| SafeAddPropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this)); |
| SafeAddPropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this)); |
| SafeAddPropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this)); |
| SafeAddPropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this)); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SbaTableQueryBrowser::RemoveColumnListener(const Reference< XPropertySet > & xCol) |
| { |
| SbaXDataBrowserController::RemoveColumnListener(xCol); |
| SafeRemovePropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this)); |
| SafeRemovePropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this)); |
| SafeRemovePropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this)); |
| SafeRemovePropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this)); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SbaTableQueryBrowser::criticalFail() |
| { |
| SbaXDataBrowserController::criticalFail(); |
| unloadAndCleanup( sal_False ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SbaTableQueryBrowser::LoadFinished(sal_Bool _bWasSynch) |
| { |
| SbaXDataBrowserController::LoadFinished(_bWasSynch); |
| |
| m_sQueryCommand = ::rtl::OUString(); |
| m_bQueryEscapeProcessing = sal_False; |
| |
| if (isValid() && !loadingCancelled()) |
| { |
| // did we load a query? |
| sal_Bool bTemporary; // needed because we m_bQueryEscapeProcessing is only one bit wide (and we want to pass it by reference) |
| if ( implGetQuerySignature( m_sQueryCommand, bTemporary ) ) |
| m_bQueryEscapeProcessing = bTemporary; |
| } |
| |
| // if the form has been loaded, this means that our "selection" has changed |
| EventObject aEvent( *this ); |
| m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| sal_Bool SbaTableQueryBrowser::getExternalSlotState( sal_uInt16 _nId ) const |
| { |
| sal_Bool bEnabled = sal_False; |
| ExternalFeaturesMap::const_iterator aPos = m_aExternalFeatures.find( _nId ); |
| if ( ( m_aExternalFeatures.end() != aPos ) && aPos->second.xDispatcher.is() ) |
| bEnabled = aPos->second.bEnabled; |
| return bEnabled; |
| } |
| |
| //------------------------------------------------------------------------------ |
| FeatureState SbaTableQueryBrowser::GetState(sal_uInt16 nId) const |
| { |
| FeatureState aReturn; |
| // (disabled automatically) |
| |
| // no chance without a view |
| if (!getBrowserView() || !getBrowserView()->getVclControl()) |
| return aReturn; |
| |
| switch ( nId ) |
| { |
| case ID_TREE_ADMINISTRATE: |
| aReturn.bEnabled = true; |
| return aReturn; |
| |
| case ID_BROWSER_CLOSE: |
| // the close button should always be enabled |
| aReturn.bEnabled = !m_bEnableBrowser; |
| return aReturn; |
| |
| // "toggle explorer" is always enabled (if we have a explorer) |
| case ID_BROWSER_EXPLORER: |
| aReturn.bEnabled = m_bEnableBrowser; |
| aReturn.bChecked = haveExplorer(); |
| return aReturn; |
| |
| case ID_BROWSER_REMOVEFILTER: |
| return SbaXDataBrowserController::GetState( nId ); |
| |
| case ID_BROWSER_COPY: |
| if ( !m_pTreeView->HasChildPathFocus() ) |
| // handled below |
| break; |
| // NO break! |
| case ID_TREE_CLOSE_CONN: |
| case ID_TREE_EDIT_DATABASE: |
| { |
| SvLBoxEntry* pCurrentEntry( m_pTreeView->getListBox().GetCurEntry() ); |
| EntryType eType = getEntryType( pCurrentEntry ); |
| if ( eType == etUnknown ) |
| return aReturn; |
| |
| SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent( pCurrentEntry ); |
| DBTreeListUserData* pDSData |
| = pDataSourceEntry |
| ? static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() ) |
| : NULL; |
| |
| if ( nId == ID_TREE_CLOSE_CONN ) |
| { |
| aReturn.bEnabled = ( pDSData != NULL ) && pDSData->xConnection.is(); |
| } |
| else if ( nId == ID_TREE_EDIT_DATABASE ) |
| { |
| ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithServiceFactory( getORB(), |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.DataAccess/Policies/Features/Common" ) ) ) ); |
| sal_Bool bHaveEditDatabase( sal_True ); |
| OSL_VERIFY( aConfig.getNodeValue( "EditDatabaseFromDataSourceView" ) >>= bHaveEditDatabase ); |
| aReturn.bEnabled = getORB().is() && ( pDataSourceEntry != NULL ) && bHaveEditDatabase; |
| } |
| else if ( nId == ID_BROWSER_COPY ) |
| { |
| aReturn.bEnabled = isEntryCopyAllowed( pCurrentEntry ); |
| } |
| |
| return aReturn; |
| } |
| } |
| |
| // all slots not handled above are not available if no form is loaded |
| if (!isLoaded()) |
| return aReturn; |
| |
| try |
| { |
| sal_Bool bHandled = sal_False; |
| switch (nId) |
| { |
| case ID_BROWSER_DOCUMENT_DATASOURCE: |
| // the slot is enabled if we have an external dispatcher able to handle it, |
| // and the dispatcher must have enabled the slot in general |
| aReturn.bEnabled = getExternalSlotState( ID_BROWSER_DOCUMENT_DATASOURCE ); |
| bHandled = sal_True; |
| break; |
| case ID_BROWSER_REFRESH: |
| aReturn.bEnabled = sal_True; |
| bHandled = sal_True; |
| break; |
| } |
| |
| if (bHandled) |
| return aReturn; |
| |
| // no chance without valid models |
| if (isValid() && !isValidCursor() && nId != ID_BROWSER_CLOSE) |
| return aReturn; |
| |
| switch (nId) |
| { |
| case ID_BROWSER_INSERTCOLUMNS: |
| case ID_BROWSER_INSERTCONTENT: |
| case ID_BROWSER_FORMLETTER: |
| { |
| // the slot is enabled if we have an external dispatcher able to handle it, |
| // and the dispatcher must have enabled the slot in general |
| aReturn.bEnabled = getExternalSlotState( nId ); |
| |
| // for the Insert* slots, we need at least one selected row |
| if (ID_BROWSER_FORMLETTER != nId) |
| aReturn.bEnabled = aReturn.bEnabled && getBrowserView()->getVclControl()->GetSelectRowCount(); |
| |
| // disabled for native queries which are not saved within the database |
| // 67706 - 23.08.99 - FS |
| Reference< XPropertySet > xDataSource(getRowSet(), UNO_QUERY); |
| try |
| { |
| aReturn.bEnabled = aReturn.bEnabled && xDataSource.is(); |
| |
| if (xDataSource.is()) |
| { |
| sal_Int32 nType = ::comphelper::getINT32(xDataSource->getPropertyValue(PROPERTY_COMMAND_TYPE)); |
| aReturn.bEnabled = aReturn.bEnabled && ((::comphelper::getBOOL(xDataSource->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || (nType == ::com::sun::star::sdb::CommandType::QUERY))); |
| } |
| } |
| catch(DisposedException&) |
| { |
| OSL_ENSURE(sal_False, "SbaTableQueryBrowser::GetState: object already disposed!"); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| break; |
| |
| case ID_BROWSER_TITLE: |
| { |
| Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); |
| sal_Int32 nCommandType = CommandType::TABLE; |
| xProp->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nCommandType; |
| String sTitle; |
| switch (nCommandType) |
| { |
| case CommandType::TABLE: |
| sTitle = String(ModuleRes(STR_TBL_TITLE)); break; |
| case CommandType::QUERY: |
| case CommandType::COMMAND: |
| sTitle = String(ModuleRes(STR_QRY_TITLE)); break; |
| default: |
| DBG_ASSERT(sal_False, "SbaTableQueryBrowser::GetState: unknown command type!"); |
| } |
| ::rtl::OUString aName; |
| xProp->getPropertyValue(PROPERTY_COMMAND) >>= aName; |
| String sObject(aName.getStr()); |
| |
| sTitle.SearchAndReplace('#',sObject); |
| aReturn.sTitle = sTitle; |
| aReturn.bEnabled = sal_True; |
| } |
| break; |
| case ID_BROWSER_TABLEATTR: |
| case ID_BROWSER_ROWHEIGHT: |
| case ID_BROWSER_COLATTRSET: |
| case ID_BROWSER_COLWIDTH: |
| aReturn.bEnabled = getBrowserView() && getBrowserView()->getVclControl() && isValid() && isValidCursor(); |
| // aReturn.bEnabled &= getDefinition() && !getDefinition()->GetDatabase()->IsReadOnly(); |
| break; |
| |
| case ID_BROWSER_COPY: |
| OSL_ENSURE( !m_pTreeView->HasChildPathFocus(), "SbaTableQueryBrowser::GetState( ID_BROWSER_COPY ): this should have been handled above!" ); |
| if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing()) |
| { |
| SbaGridControl* pControl = getBrowserView()->getVclControl(); |
| if ( pControl->GetSelectRowCount() ) |
| { |
| aReturn.bEnabled = m_aCurrentFrame.isActive(); |
| break; |
| } // if ( getBrowserView()->getVclControl()->GetSelectRowCount() ) |
| else |
| aReturn.bEnabled = pControl->canCopyCellText(pControl->GetCurRow(), pControl->GetCurColumnId()); |
| break; |
| } |
| // NO break here |
| default: |
| return SbaXDataBrowserController::GetState(nId); |
| } |
| } |
| catch(const Exception&) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| return aReturn; |
| |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SbaTableQueryBrowser::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& aArgs) |
| { |
| switch (nId) |
| { |
| default: |
| SbaXDataBrowserController::Execute(nId,aArgs); |
| break; |
| |
| case ID_TREE_EDIT_DATABASE: |
| implAdministrate( m_pTreeView->getListBox().GetCurEntry() ); |
| break; |
| |
| case ID_TREE_CLOSE_CONN: |
| openHelpAgent( HID_DSBROWSER_DISCONNECTING ); |
| closeConnection( m_pTreeView->getListBox().GetRootLevelParent( m_pTreeView->getListBox().GetCurEntry() ) ); |
| break; |
| |
| case ID_TREE_ADMINISTRATE: |
| ::svx::administrateDatabaseRegistration( getView() ); |
| break; |
| |
| case ID_BROWSER_REFRESH: |
| { |
| if ( !SaveModified( ) ) |
| // nothing to do |
| break; |
| |
| sal_Bool bFullReinit = sal_False; |
| // check if the query signature (if the form is based on a query) has changed |
| if ( m_sQueryCommand.getLength() ) |
| { |
| ::rtl::OUString sNewQueryCommand; |
| sal_Bool bNewQueryEP; |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| sal_Bool bIsQuery = |
| #endif |
| implGetQuerySignature( sNewQueryCommand, bNewQueryEP ); |
| OSL_ENSURE( bIsQuery, "SbaTableQueryBrowser::Execute: was a query before, but is not anymore?" ); |
| |
| bFullReinit = ( sNewQueryCommand != m_sQueryCommand ) || ( m_bQueryEscapeProcessing != bNewQueryEP ); |
| } |
| if ( !bFullReinit ) |
| { |
| // let the base class do a simple reload |
| SbaXDataBrowserController::Execute(nId,aArgs); |
| break; |
| } |
| // NO break here! |
| } |
| |
| case ID_BROWSER_REFRESH_REBUILD: |
| { |
| if ( !SaveModified() ) |
| // nothing to do |
| break; |
| |
| SvLBoxEntry* pSelected = m_pCurrentlyDisplayed; |
| // unload |
| unloadAndCleanup( sal_False ); |
| |
| // reselect the entry |
| if ( pSelected ) |
| { |
| implSelect( pSelected ); |
| } |
| else |
| { |
| Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); |
| implSelect(::svx::ODataAccessDescriptor(xProp)); |
| } |
| } |
| break; |
| |
| case ID_BROWSER_EXPLORER: |
| toggleExplorer(); |
| break; |
| |
| case ID_BROWSER_DOCUMENT_DATASOURCE: |
| implSelect(m_aDocumentDataSource); |
| break; |
| |
| case ID_BROWSER_INSERTCOLUMNS: |
| case ID_BROWSER_INSERTCONTENT: |
| case ID_BROWSER_FORMLETTER: |
| if (getBrowserView() && isValidCursor()) |
| { |
| // the URL the slot id is assigned to |
| OSL_ENSURE( m_aExternalFeatures.find( nId ) != m_aExternalFeatures.end(), |
| "SbaTableQueryBrowser::Execute( ID_BROWSER_?): how could this ever be enabled?" ); |
| URL aParentUrl = m_aExternalFeatures[ nId ].aURL; |
| |
| // let the dispatcher execute the slot |
| Reference< XDispatch > xDispatch( m_aExternalFeatures[ nId ].xDispatcher ); |
| if (xDispatch.is()) |
| { |
| // set the properties for the dispatch |
| |
| // first fill the selection |
| SbaGridControl* pGrid = getBrowserView()->getVclControl(); |
| MultiSelection* pSelection = (MultiSelection*)pGrid->GetSelection(); |
| Sequence< Any > aSelection; |
| if ( !pGrid->IsAllSelected() ) |
| { // transfer the selected rows only if not all rows are selected |
| // (all rows means the whole table) |
| // i3832 - 03.04.2002 - fs@openoffice.org |
| if (pSelection != NULL) |
| { |
| aSelection.realloc(pSelection->GetSelectCount()); |
| long nIdx = pSelection->FirstSelected(); |
| Any* pSelectionNos = aSelection.getArray(); |
| while (nIdx >= 0) |
| { |
| *pSelectionNos++ <<= (sal_Int32)(nIdx + 1); |
| nIdx = pSelection->NextSelected(); |
| } |
| } |
| } |
| |
| Reference< XResultSet > xCursorClone; |
| try |
| { |
| Reference< XResultSetAccess > xResultSetAccess(getRowSet(),UNO_QUERY); |
| if (xResultSetAccess.is()) |
| xCursorClone = xResultSetAccess->createResultSet(); |
| } |
| catch(DisposedException&) |
| { |
| OSL_ENSURE(0,"Object already disposed!"); |
| } |
| catch(Exception&) |
| { |
| DBG_ERROR("SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not clone the cursor!"); |
| } |
| |
| Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); |
| |
| try |
| { |
| ODataAccessDescriptor aDescriptor; |
| ::rtl::OUString sDataSourceName; |
| xProp->getPropertyValue(PROPERTY_DATASOURCENAME) >>= sDataSourceName; |
| |
| aDescriptor.setDataSource(sDataSourceName); |
| aDescriptor[daCommand] = xProp->getPropertyValue(PROPERTY_COMMAND); |
| aDescriptor[daCommandType] = xProp->getPropertyValue(PROPERTY_COMMAND_TYPE); |
| aDescriptor[daConnection] = xProp->getPropertyValue(PROPERTY_ACTIVE_CONNECTION); |
| aDescriptor[daCursor] <<= xCursorClone; |
| if ( aSelection.getLength() ) |
| { |
| aDescriptor[daSelection] <<= aSelection; |
| aDescriptor[daBookmarkSelection] <<= sal_False; |
| // these are selection indicies |
| // before we change this, all clients have to be adjusted |
| // so that they recognize the new BookmarkSelection property! |
| } |
| |
| xDispatch->dispatch(aParentUrl, aDescriptor.createPropertyValueSequence()); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| } |
| break; |
| |
| case ID_BROWSER_CLOSE: |
| closeTask(); |
| // if it's not 0, such a async close is already pending |
| break; |
| |
| case ID_BROWSER_COPY: |
| if(m_pTreeView->HasChildPathFocus()) |
| { |
| copyEntry(m_pTreeView->getListBox().GetCurEntry()); |
| } |
| else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing() && getBrowserView()->getVclControl()->GetSelectRowCount() < 1) |
| { |
| SbaGridControl* pControl = getBrowserView()->getVclControl(); |
| pControl->copyCellText(pControl->GetCurRow(), pControl->GetCurColumnId()); |
| } |
| else |
| SbaXDataBrowserController::Execute(nId,aArgs); |
| break; |
| } |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::implAddDatasource( const String& _rDataSourceName, const SharedConnection& _rxConnection ) |
| { |
| Image a, b, c; |
| String d, e; |
| implAddDatasource( _rDataSourceName, a, d, b, e, c, _rxConnection ); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::implAddDatasource(const String& _rDbName, Image& _rDbImage, |
| String& _rQueryName, Image& _rQueryImage, String& _rTableName, Image& _rTableImage, |
| const SharedConnection& _rxConnection) |
| { |
| vos::OGuard aGuard( Application::GetSolarMutex() ); |
| // initialize the names/images if necessary |
| if (!_rQueryName.Len()) |
| _rQueryName = String(ModuleRes(RID_STR_QUERIES_CONTAINER)); |
| if (!_rTableName.Len()) |
| _rTableName = String(ModuleRes(RID_STR_TABLES_CONTAINER)); |
| |
| ImageProvider aImageProvider; |
| if (!_rQueryImage) |
| _rQueryImage = aImageProvider.getFolderImage( DatabaseObject::QUERY, isHiContrast() ); |
| if (!_rTableImage) |
| _rTableImage = aImageProvider.getFolderImage( DatabaseObject::TABLE, isHiContrast() ); |
| |
| if (!_rDbImage) |
| _rDbImage = aImageProvider.getDatabaseImage( isHiContrast() ); |
| |
| // add the entry for the data source |
| // special handling for data sources denoted by URLs - we do not want to display this ugly URL, do we? |
| // #i33699# - 2004-09-24 - fs@openoffice.org |
| String sDSDisplayName, sDataSourceId; |
| getDataSourceDisplayName_isURL( _rDbName, sDSDisplayName, sDataSourceId ); |
| |
| SvLBoxEntry* pDatasourceEntry = m_pTreeView->getListBox().InsertEntry( sDSDisplayName, _rDbImage, _rDbImage, NULL, sal_False ); |
| DBTreeListUserData* pDSData = new DBTreeListUserData; |
| pDSData->eType = etDatasource; |
| pDSData->sAccessor = sDataSourceId; |
| pDSData->xConnection = _rxConnection; |
| pDatasourceEntry->SetUserData(pDSData); |
| |
| // the child for the queries container |
| { |
| DBTreeListUserData* pQueriesData = new DBTreeListUserData; |
| pQueriesData->eType = etQueryContainer; |
| |
| m_pTreeView->getListBox().InsertEntry( |
| _rQueryName, _rQueryImage, _rQueryImage, pDatasourceEntry, |
| sal_True /*ChildsOnDemand*/, LIST_APPEND, pQueriesData ); |
| } |
| |
| // the child for the tables container |
| { |
| DBTreeListUserData* pTablesData = new DBTreeListUserData; |
| pTablesData->eType = etTableContainer; |
| |
| m_pTreeView->getListBox().InsertEntry( |
| _rTableName, _rTableImage, _rTableImage, pDatasourceEntry, |
| sal_True /*ChildsOnDemand*/, LIST_APPEND, pTablesData ); |
| } |
| |
| } |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::initializeTreeModel() |
| { |
| if (m_xDatabaseContext.is()) |
| { |
| Image aDBImage, aQueriesImage, aTablesImage; |
| String sQueriesName, sTablesName; |
| |
| // fill the model with the names of the registered datasources |
| Sequence< ::rtl::OUString > aDatasources = m_xDatabaseContext->getElementNames(); |
| const ::rtl::OUString* pIter = aDatasources.getConstArray(); |
| const ::rtl::OUString* pEnd = pIter + aDatasources.getLength(); |
| for (; pIter != pEnd; ++pIter) |
| implAddDatasource( *pIter, aDBImage, sQueriesName, aQueriesImage, sTablesName, aTablesImage, SharedConnection() ); |
| } |
| } |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::populateTree(const Reference<XNameAccess>& _xNameAccess, |
| SvLBoxEntry* _pParent, |
| EntryType _eEntryType) |
| { |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pParent->GetUserData()); |
| if(pData) // don't ask if the nameaccess is already set see OnExpandEntry views and tables |
| pData->xContainer = _xNameAccess; |
| |
| try |
| { |
| Sequence< ::rtl::OUString > aNames = _xNameAccess->getElementNames(); |
| const ::rtl::OUString* pIter = aNames.getConstArray(); |
| const ::rtl::OUString* pEnd = pIter + aNames.getLength(); |
| for (; pIter != pEnd; ++pIter) |
| { |
| if( !m_pTreeView->getListBox().GetEntryPosByName(*pIter,_pParent)) |
| { |
| DBTreeListUserData* pEntryData = new DBTreeListUserData; |
| pEntryData->eType = _eEntryType; |
| if ( _eEntryType == etQuery ) |
| { |
| Reference<XNameAccess> xChild(_xNameAccess->getByName(*pIter),UNO_QUERY); |
| if ( xChild.is() ) |
| pEntryData->eType = etQueryContainer; |
| } |
| implAppendEntry( _pParent, *pIter, pEntryData, pEntryData->eType ); |
| } |
| } |
| } |
| catch(Exception&) |
| { |
| DBG_ERROR("SbaTableQueryBrowser::populateTree: could not fill the tree"); |
| } |
| } |
| |
| //------------------------------------------------------------------------------ |
| SvLBoxEntry* SbaTableQueryBrowser::implAppendEntry( SvLBoxEntry* _pParent, const String& _rName, void* _pUserData, EntryType _eEntryType ) |
| { |
| ::std::auto_ptr< ImageProvider > pImageProvider( getImageProviderFor( _pParent ) ); |
| |
| Image aImage, aImageHC; |
| pImageProvider->getImages( _rName, getDatabaseObjectType( _eEntryType ), aImage, aImageHC ); |
| |
| SvLBoxEntry* pNewEntry = m_pTreeView->getListBox().InsertEntry( _rName, _pParent, _eEntryType == etQueryContainer , LIST_APPEND, _pUserData ); |
| |
| m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL ); |
| m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL ); |
| m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImageHC, BMP_COLOR_HIGHCONTRAST ); |
| m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImageHC, BMP_COLOR_HIGHCONTRAST ); |
| |
| return pNewEntry; |
| } |
| |
| //------------------------------------------------------------------------------ |
| IMPL_LINK(SbaTableQueryBrowser, OnExpandEntry, SvLBoxEntry*, _pParent) |
| { |
| if (_pParent->HasChilds()) |
| // nothing to to ... |
| return 1L; |
| |
| SvLBoxEntry* pFirstParent = m_pTreeView->getListBox().GetRootLevelParent(_pParent); |
| OSL_ENSURE(pFirstParent,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!"); |
| |
| DBTreeListUserData* pData = static_cast< DBTreeListUserData* >(_pParent->GetUserData()); |
| OSL_ENSURE(pData,"SbaTableQueryBrowser::OnExpandEntry: No user data!"); |
| #if OSL_DEBUG_LEVEL > 0 |
| SvLBoxString* pString = static_cast<SvLBoxString*>(pFirstParent->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING)); |
| OSL_ENSURE(pString,"SbaTableQueryBrowser::OnExpandEntry: No string item!"); |
| #endif |
| |
| if (etTableContainer == pData->eType) |
| { |
| WaitObject aWaitCursor(getBrowserView()); |
| |
| // it could be that we already have a connection |
| SharedConnection xConnection; |
| ensureConnection( pFirstParent, xConnection ); |
| |
| if ( xConnection.is() ) |
| { |
| SQLExceptionInfo aInfo; |
| try |
| { |
| Reference< XWarningsSupplier > xWarnings(xConnection, UNO_QUERY); |
| if (xWarnings.is()) |
| xWarnings->clearWarnings(); |
| |
| // first insert the views because the tables can also include |
| // views but that time the bitmap is the wrong one |
| // the nameaccess will be overwriten in populateTree |
| Reference<XViewsSupplier> xViewSup(xConnection,UNO_QUERY); |
| if(xViewSup.is()) |
| populateTree( xViewSup->getViews(), _pParent, etTableOrView ); |
| |
| Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY); |
| if(xTabSup.is()) |
| { |
| populateTree( xTabSup->getTables(), _pParent, etTableOrView ); |
| Reference<XContainer> xCont(xTabSup->getTables(),UNO_QUERY); |
| if(xCont.is()) |
| // add as listener to know when elements are inserted or removed |
| xCont->addContainerListener(this); |
| } |
| |
| if (xWarnings.is()) |
| { |
| SQLExceptionInfo aWarnings(xWarnings->getWarnings()); |
| if (aWarnings.isValid() && sal_False) |
| { |
| SQLContext aContext; |
| aContext.Message = String(ModuleRes(STR_OPENTABLES_WARNINGS)); |
| aContext.Details = String(ModuleRes(STR_OPENTABLES_WARNINGS_DETAILS)); |
| aContext.NextException = aWarnings.get(); |
| aWarnings = aContext; |
| showError(aWarnings); |
| } |
| // TODO: we need a better concept for these warnings: |
| // something like "don't show any warnings for this datasource, again" would be nice |
| // But this requires an extension of the InteractionHandler and an additional property on the data source |
| } |
| } |
| catch(const SQLContext& e) { aInfo = e; } |
| catch(const SQLWarning& e) { aInfo = e; } |
| catch(const SQLException& e) { aInfo = e; } |
| catch(const WrappedTargetException& e) |
| { |
| SQLException aSql; |
| if(e.TargetException >>= aSql) |
| aInfo = aSql; |
| else |
| OSL_ENSURE(sal_False, "SbaTableQueryBrowser::OnExpandEntry: something strange happended!"); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| if (aInfo.isValid()) |
| showError(aInfo); |
| } |
| else |
| return 0L; |
| // 0 indicates that an error occured |
| } |
| else |
| { // we have to expand the queries or bookmarks |
| if (ensureEntryObject(_pParent)) |
| { |
| DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( _pParent->GetUserData() ); |
| Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY ); |
| populateTree( xCollection, _pParent, etQuery ); |
| } |
| } |
| return 1L; |
| } |
| |
| //------------------------------------------------------------------------------ |
| sal_Bool SbaTableQueryBrowser::ensureEntryObject( SvLBoxEntry* _pEntry ) |
| { |
| DBG_ASSERT(_pEntry, "SbaTableQueryBrowser::ensureEntryObject: invalid argument!"); |
| if (!_pEntry) |
| return sal_False; |
| |
| EntryType eType = getEntryType( _pEntry ); |
| |
| // the user data of the entry |
| DBTreeListUserData* pEntryData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData()); |
| OSL_ENSURE(pEntryData,"ensureEntryObject: user data should already be set!"); |
| |
| SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(_pEntry); |
| |
| sal_Bool bSuccess = sal_False; |
| switch (eType) |
| { |
| case etQueryContainer: |
| if ( pEntryData->xContainer.is() ) |
| { |
| // nothing to do |
| bSuccess = sal_True; |
| break; |
| } |
| |
| { |
| SvLBoxEntry* pParent = m_pTreeView->getListBox().GetParent(_pEntry); |
| if ( pParent != pDataSourceEntry ) |
| { |
| SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING); |
| OSL_ENSURE(pString,"There must be a string item!"); |
| ::rtl::OUString aName(pString->GetText()); |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pParent->GetUserData()); |
| try |
| { |
| Reference< XNameAccess > xNameAccess(pData->xContainer,UNO_QUERY); |
| if ( xNameAccess.is() ) |
| pEntryData->xContainer.set(xNameAccess->getByName(aName),UNO_QUERY); |
| } |
| catch(const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| bSuccess = pEntryData->xContainer.is(); |
| } |
| else |
| { |
| try |
| { |
| Reference< XQueryDefinitionsSupplier > xQuerySup; |
| m_xDatabaseContext->getByName( getDataSourceAcessor( pDataSourceEntry ) ) >>= xQuerySup; |
| if (xQuerySup.is()) |
| { |
| Reference< XNameAccess > xQueryDefs = xQuerySup->getQueryDefinitions(); |
| Reference< XContainer > xCont(xQueryDefs, UNO_QUERY); |
| if (xCont.is()) |
| // add as listener to get notified if elements are inserted or removed |
| xCont->addContainerListener(this); |
| |
| pEntryData->xContainer = xQueryDefs; |
| bSuccess = pEntryData->xContainer.is(); |
| } |
| else { |
| DBG_ERROR("SbaTableQueryBrowser::ensureEntryObject: no XQueryDefinitionsSupplier interface!"); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| } |
| break; |
| |
| default: |
| DBG_ERROR("SbaTableQueryBrowser::ensureEntryObject: ooops ... missing some implementation here!"); |
| // TODO ... |
| break; |
| } |
| |
| return bSuccess; |
| } |
| //------------------------------------------------------------------------------ |
| sal_Bool SbaTableQueryBrowser::implSelect(const ::svx::ODataAccessDescriptor& _rDescriptor,sal_Bool _bSelectDirect) |
| { |
| // extract the props |
| ::rtl::OUString sDataSource; |
| ::rtl::OUString sCommand; |
| sal_Int32 nCommandType = CommandType::COMMAND; |
| sal_Bool bEscapeProcessing = sal_True; |
| extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing); |
| |
| // select it |
| return implSelect( sDataSource, sCommand, nCommandType, bEscapeProcessing, SharedConnection(), _bSelectDirect ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| sal_Bool SbaTableQueryBrowser::implLoadAnything(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand, |
| const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing, const SharedConnection& _rxConnection) |
| { |
| try |
| { |
| Reference<XPropertySet> xProp( getRowSet(), UNO_QUERY_THROW ); |
| Reference< XLoadable > xLoadable( xProp, UNO_QUERY_THROW ); |
| // the values allowing the RowSet to re-execute |
| xProp->setPropertyValue(PROPERTY_DATASOURCENAME, makeAny(_rDataSourceName)); |
| if(_rxConnection.is()) |
| xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( _rxConnection.getTyped() ) ); |
| |
| // set this _before_ setting the connection, else the rowset would rebuild it ... |
| xProp->setPropertyValue(PROPERTY_COMMAND_TYPE, makeAny(_nCommandType)); |
| xProp->setPropertyValue(PROPERTY_COMMAND, makeAny(_rCommand)); |
| xProp->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, ::cppu::bool2any(_bEscapeProcessing)); |
| if ( m_bPreview ) |
| { |
| xProp->setPropertyValue(PROPERTY_FETCHDIRECTION, makeAny(FetchDirection::FORWARD)); |
| } |
| |
| // the formatter depends on the data source we're working on, so rebuild it here ... |
| initFormatter(); |
| |
| // switch the grid to design mode while loading |
| getBrowserView()->getGridControl()->setDesignMode(sal_True); |
| InitializeForm( xProp ); |
| |
| sal_Bool bSuccess = sal_True; |
| |
| { |
| { |
| Reference< XNameContainer > xColContainer(getFormComponent(), UNO_QUERY); |
| // first we have to clear the grid |
| clearGridColumns(xColContainer); |
| } |
| FormErrorHelper aHelper(this); |
| // load the form |
| bSuccess = reloadForm(xLoadable); |
| |
| // initialize the model |
| InitializeGridModel(getFormComponent()); |
| |
| Any aVal = xProp->getPropertyValue(PROPERTY_ISNEW); |
| if (aVal.hasValue() && ::comphelper::getBOOL(aVal)) |
| { |
| // then set the default values and the parameters given from the parent |
| Reference< XReset> xReset(xProp, UNO_QUERY); |
| xReset->reset(); |
| } |
| |
| if ( m_bPreview ) |
| initializePreviewMode(); |
| |
| LoadFinished(sal_True); |
| } |
| |
| InvalidateAll(); |
| return bSuccess; |
| } |
| catch( const SQLException& e ) |
| { |
| Any aException( ::cppu::getCaughtException() ); |
| showError( SQLExceptionInfo( aException ) ); |
| } |
| catch( const WrappedTargetException& e ) |
| { |
| SQLException aSql; |
| if ( e.TargetException.isExtractableTo( ::cppu::UnoType< SQLException >::get() ) ) |
| showError( SQLExceptionInfo( e.TargetException ) ); |
| else |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| catch(Exception&) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| InvalidateAll(); |
| return sal_False; |
| } |
| |
| //------------------------------------------------------------------------------ |
| sal_Bool SbaTableQueryBrowser::implSelect(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand, |
| const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing, |
| const SharedConnection& _rxConnection |
| ,sal_Bool _bSelectDirect) |
| { |
| if (_rDataSourceName.getLength() && _rCommand.getLength() && (-1 != _nCommandType)) |
| { |
| SvLBoxEntry* pDataSource = NULL; |
| SvLBoxEntry* pCommandType = NULL; |
| SvLBoxEntry* pCommand = getObjectEntry( _rDataSourceName, _rCommand, _nCommandType, &pDataSource, &pCommandType, sal_True, _rxConnection ); |
| |
| if (pCommand) |
| { |
| bool bSuccess = true; |
| if ( _bSelectDirect ) |
| { |
| bSuccess = implSelect( pCommand ); |
| } |
| else |
| { |
| m_pTreeView->getListBox().Select( pCommand ); |
| } |
| |
| if ( bSuccess ) |
| { |
| m_pTreeView->getListBox().MakeVisible(pCommand); |
| m_pTreeView->getListBox().SetCursor(pCommand); |
| } |
| } |
| else if (!pCommandType) |
| { |
| if ( m_pCurrentlyDisplayed ) |
| { // tell the old entry (if any) it has been deselected |
| selectPath(m_pCurrentlyDisplayed, sal_False); |
| m_pCurrentlyDisplayed = NULL; |
| } |
| |
| // we have a command and need to display this in the rowset |
| return implLoadAnything(_rDataSourceName, _rCommand, _nCommandType, _bEscapeProcessing, _rxConnection); |
| } |
| } |
| return sal_False; |
| } |
| |
| //------------------------------------------------------------------------------ |
| IMPL_LINK(SbaTableQueryBrowser, OnSelectionChange, void*, /*NOINTERESTEDIN*/) |
| { |
| return implSelect( m_pTreeView->getListBox().FirstSelected() ) ? 1L : 0L; |
| } |
| //------------------------------------------------------------------------------ |
| SvLBoxEntry* SbaTableQueryBrowser::implGetConnectionEntry(SvLBoxEntry* _pEntry) const |
| { |
| SvLBoxEntry* pCurrentEntry = _pEntry; |
| DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() ); |
| while(pEntryData->eType != etDatasource ) |
| { |
| pCurrentEntry = m_pTreeModel->GetParent(pCurrentEntry); |
| pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() ); |
| } |
| return pCurrentEntry; |
| } |
| //------------------------------------------------------------------------------ |
| bool SbaTableQueryBrowser::implSelect( SvLBoxEntry* _pEntry ) |
| { |
| if ( !_pEntry ) |
| return false; |
| |
| DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() ); |
| switch (pEntryData->eType) |
| { |
| case etTableOrView: |
| case etQuery: |
| break; |
| default: |
| // nothing to do |
| return false; |
| } |
| |
| OSL_ENSURE(m_pTreeModel->HasParent(_pEntry), "SbaTableQueryBrowser::implSelect: invalid entry (1)!"); |
| OSL_ENSURE(m_pTreeModel->HasParent(m_pTreeModel->GetParent(_pEntry)), "SbaTableQueryBrowser::implSelect: invalid entry (2)!"); |
| |
| // get the entry for the tables or queries |
| SvLBoxEntry* pContainer = m_pTreeModel->GetParent(_pEntry); |
| DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pContainer->GetUserData()); |
| |
| // get the entry for the datasource |
| SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer); |
| DBTreeListUserData* pConData = static_cast<DBTreeListUserData*>(pConnection->GetUserData()); |
| |
| // reinitialize the rowset |
| // but first check if it is necessary |
| // get all old properties |
| Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY); |
| ::rtl::OUString aOldName; |
| xRowSetProps->getPropertyValue(PROPERTY_COMMAND) >>= aOldName; |
| sal_Int32 nOldType = 0; |
| xRowSetProps->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nOldType; |
| Reference<XConnection> xOldConnection(xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY); |
| |
| // the name of the table or query |
| SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING); |
| OSL_ENSURE(pString,"There must be a string item!"); |
| const ::rtl::OUString sSimpleName = pString->GetText(); |
| ::rtl::OUStringBuffer sNameBuffer(sSimpleName); |
| if ( etQueryContainer == pContainerData->eType ) |
| { |
| SvLBoxEntry* pTemp = pContainer; |
| while( m_pTreeModel->GetParent(pTemp) != pConnection ) |
| { |
| sNameBuffer.insert(0,sal_Unicode('/')); |
| pString = (SvLBoxString*)pTemp->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING); |
| OSL_ENSURE(pString,"There must be a string item!"); |
| sNameBuffer.insert(0,pString->GetText()); |
| pTemp = m_pTreeModel->GetParent(pTemp); |
| } |
| } |
| ::rtl::OUString aName = sNameBuffer.makeStringAndClear(); |
| |
| sal_Int32 nCommandType = ( etTableContainer == pContainerData->eType) |
| ? CommandType::TABLE |
| : CommandType::QUERY; |
| |
| // check if need to rebuild the rowset |
| sal_Bool bRebuild = ( xOldConnection != pConData->xConnection ) |
| || ( nOldType != nCommandType ) |
| || ( aName != aOldName ); |
| |
| Reference< ::com::sun::star::form::XLoadable > xLoadable = getLoadable(); |
| bRebuild |= !xLoadable->isLoaded(); |
| bool bSuccess = true; |
| if ( bRebuild ) |
| { |
| try |
| { |
| WaitObject aWaitCursor(getBrowserView()); |
| |
| // tell the old entry it has been deselected |
| selectPath(m_pCurrentlyDisplayed, sal_False); |
| m_pCurrentlyDisplayed = NULL; |
| |
| // not really loaded |
| m_pCurrentlyDisplayed = _pEntry; |
| // tell the new entry it has been selected |
| selectPath(m_pCurrentlyDisplayed, sal_True); |
| |
| // get the name of the data source currently selected |
| ensureConnection( m_pCurrentlyDisplayed, pConData->xConnection ); |
| |
| if ( !pConData->xConnection.is() ) |
| { |
| unloadAndCleanup( sal_False ); |
| return false; |
| } |
| |
| Reference<XNameAccess> xNameAccess; |
| switch(nCommandType) |
| { |
| case CommandType::TABLE: |
| { |
| // only for tables |
| if ( !pContainerData->xContainer.is() ) |
| { |
| Reference<XTablesSupplier> xSup( pConData->xConnection, UNO_QUERY ); |
| if(xSup.is()) |
| xNameAccess = xSup->getTables(); |
| |
| pContainerData->xContainer = xNameAccess; |
| } |
| else |
| xNameAccess.set( pContainerData->xContainer, UNO_QUERY ); |
| } |
| break; |
| case CommandType::QUERY: |
| { |
| if ( pContainerData->xContainer.is() ) |
| xNameAccess.set( pContainerData->xContainer, UNO_QUERY ); |
| else |
| { |
| Reference<XQueriesSupplier> xSup( pConData->xConnection, UNO_QUERY ); |
| if(xSup.is()) |
| xNameAccess = xSup->getQueries(); |
| } |
| } |
| break; |
| } |
| String sStatus(ModuleRes( CommandType::TABLE == nCommandType ? STR_LOADING_TABLE : STR_LOADING_QUERY )); |
| sStatus.SearchAndReplaceAscii("$name$", aName); |
| BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sStatus); |
| |
| |
| sal_Bool bEscapeProcessing = sal_True; |
| if(xNameAccess.is() && xNameAccess->hasByName(sSimpleName)) |
| { |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData()); |
| if ( !pData->xObjectProperties.is() ) |
| { |
| Reference<XInterface> xObject; |
| if(xNameAccess->getByName(sSimpleName) >>= xObject) // remember the table or query object |
| { |
| pData->xObjectProperties = pData->xObjectProperties.query( xObject ); |
| // if the query contains a parameterized statement and preview is enabled we won't get any data. |
| if ( nCommandType == CommandType::QUERY && xObject.is() ) |
| { |
| Reference<XPropertySet> xObjectProps(xObject,UNO_QUERY); |
| xObjectProps->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bEscapeProcessing; |
| if ( m_bPreview ) |
| { |
| ::rtl::OUString sSql; |
| xObjectProps->getPropertyValue(PROPERTY_COMMAND) >>= sSql; |
| Reference< XMultiServiceFactory > xFactory( pConData->xConnection, UNO_QUERY ); |
| if (xFactory.is()) |
| { |
| try |
| { |
| Reference<XSingleSelectQueryAnalyzer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY); |
| if ( xAnalyzer.is() ) |
| { |
| xAnalyzer->setQuery(sSql); |
| Reference<XParametersSupplier> xParSup(xAnalyzer,UNO_QUERY); |
| if ( xParSup->getParameters()->getCount() > 0 ) |
| { |
| String sFilter = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE ")); |
| sFilter = sFilter + xAnalyzer->getFilter(); |
| String sReplace(sSql); |
| sReplace.SearchAndReplace(sFilter,String()); |
| xAnalyzer->setQuery(sReplace); |
| Reference<XSingleSelectQueryComposer> xComposer(xAnalyzer,UNO_QUERY); |
| xComposer->setFilter(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0=1"))); |
| aName = xAnalyzer->getQuery(); |
| nCommandType = CommandType::COMMAND; |
| } |
| } |
| } |
| catch (Exception&) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| String sDataSourceName( getDataSourceAcessor( pConnection ) ); |
| bSuccess = implLoadAnything( sDataSourceName, aName, nCommandType, bEscapeProcessing, pConData->xConnection ); |
| if ( !bSuccess ) |
| { // clean up |
| criticalFail(); |
| } |
| } |
| catch(const SQLException& e) |
| { |
| showError(SQLExceptionInfo(e)); |
| // reset the values |
| xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any()); |
| xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any()); |
| } |
| catch(WrappedTargetException& e) |
| { |
| SQLException aSql; |
| if(e.TargetException >>= aSql) |
| showError(SQLExceptionInfo(aSql)); |
| else |
| OSL_ENSURE(sal_False, "SbaTableQueryBrowser::implSelect: something strange happended!"); |
| // reset the values |
| xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any()); |
| xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any()); |
| } |
| catch(Exception&) |
| { |
| // reset the values |
| xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any()); |
| xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any()); |
| } |
| } |
| return bSuccess; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| SvLBoxEntry* SbaTableQueryBrowser::getEntryFromContainer(const Reference<XNameAccess>& _rxNameAccess) |
| { |
| DBTreeListBox& rListBox = m_pTreeView->getListBox(); |
| SvLBoxEntry* pContainer = NULL; |
| SvLBoxEntry* pDSLoop = rListBox.FirstChild(NULL); |
| while (pDSLoop) |
| { |
| pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_QUERIES); |
| DBTreeListUserData* pQueriesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData()); |
| if ( pQueriesData && pQueriesData->xContainer == _rxNameAccess ) |
| break; |
| |
| pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_TABLES); |
| DBTreeListUserData* pTablesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData()); |
| if ( pTablesData && pTablesData->xContainer == _rxNameAccess ) |
| break; |
| |
| pDSLoop = rListBox.NextSibling(pDSLoop); |
| pContainer = NULL; |
| } |
| return pContainer; |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SAL_CALL SbaTableQueryBrowser::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException) |
| { |
| vos::OGuard aSolarGuard( Application::GetSolarMutex() ); |
| |
| Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY); |
| // first search for a definition container where we can insert this element |
| |
| SvLBoxEntry* pEntry = getEntryFromContainer(xNames); |
| if(pEntry) // found one |
| { |
| // insert the new entry into the tree |
| DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pEntry->GetUserData()); |
| OSL_ENSURE(pContainerData, "elementInserted: There must be user data for this type!"); |
| |
| DBTreeListUserData* pNewData = new DBTreeListUserData; |
| sal_Bool bIsTable = etTableContainer == pContainerData->eType; |
| if ( bIsTable ) |
| { |
| _rEvent.Element >>= pNewData->xObjectProperties;// remember the new element |
| pNewData->eType = etTableOrView; |
| } |
| else |
| { |
| if ((sal_Int32)m_pTreeView->getListBox().GetChildCount(pEntry) < ( xNames->getElementNames().getLength() - 1 ) ) |
| { |
| // the item inserts its children on demand, but it has not been expanded yet. So ensure here and |
| // now that it has all items |
| populateTree(xNames, pEntry, etQuery ); |
| } |
| pNewData->eType = etQuery; |
| } |
| implAppendEntry( pEntry, ::comphelper::getString( _rEvent.Accessor ), pNewData, pNewData->eType ); |
| } |
| else |
| SbaXDataBrowserController::elementInserted(_rEvent); |
| } |
| // ------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::isCurrentlyDisplayedChanged(const String& _sName,SvLBoxEntry* _pContainer) |
| { |
| return m_pCurrentlyDisplayed |
| && getEntryType(m_pCurrentlyDisplayed) == getChildType(_pContainer) |
| && m_pTreeView->getListBox().GetParent(m_pCurrentlyDisplayed) == _pContainer |
| && m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed) == _sName; |
| } |
| // ------------------------------------------------------------------------- |
| void SAL_CALL SbaTableQueryBrowser::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException) |
| { |
| ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); |
| |
| Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY); |
| // get the top-level representing the removed data source |
| // and search for the queries and tables |
| SvLBoxEntry* pContainer = getEntryFromContainer(xNames); |
| if ( pContainer ) |
| { // a query or table has been removed |
| String aName = ::comphelper::getString(_rEvent.Accessor).getStr(); |
| |
| if ( isCurrentlyDisplayedChanged( aName, pContainer) ) |
| { // the element displayed currently has been replaced |
| |
| // we need to remember the old value |
| SvLBoxEntry* pTemp = m_pCurrentlyDisplayed; |
| |
| // unload |
| unloadAndCleanup( sal_False ); // don't dispose the connection |
| |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData()); |
| pTemp->SetUserData(NULL); |
| delete pData; |
| // the data could be null because we have a table which isn't correct |
| m_pTreeModel->Remove(pTemp); |
| } |
| else |
| { |
| // remove the entry from the model |
| SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer); |
| while(pChild) |
| { |
| if (m_pTreeView->getListBox().GetEntryText(pChild) == aName) |
| { |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData()); |
| pChild->SetUserData(NULL); |
| delete pData; |
| m_pTreeModel->Remove(pChild); |
| break; |
| } |
| pChild = m_pTreeModel->NextSibling(pChild); |
| } |
| } |
| |
| // maybe the object which is part of the document data source has been removed |
| checkDocumentDataSource(); |
| } |
| else |
| SbaXDataBrowserController::elementRemoved(_rEvent); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SAL_CALL SbaTableQueryBrowser::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException) |
| { |
| ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); |
| |
| Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY); |
| SvLBoxEntry* pContainer = getEntryFromContainer(xNames); |
| if ( pContainer ) |
| { // a table or query as been replaced |
| String aName = ::comphelper::getString(_rEvent.Accessor).getStr(); |
| |
| if ( isCurrentlyDisplayedChanged( aName, pContainer) ) |
| { // the element displayed currently has been replaced |
| |
| // we need to remember the old value |
| SvLBoxEntry* pTemp = m_pCurrentlyDisplayed; |
| unloadAndCleanup( sal_False ); // don't dispose the connection |
| |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData()); |
| if (pData) |
| { |
| if ( etTableOrView == pData->eType ) |
| { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query |
| _rEvent.Element >>= pData->xObjectProperties; // remember the new element |
| } |
| else |
| { |
| pTemp->SetUserData(NULL); |
| delete pData; |
| } |
| } |
| } |
| else |
| { |
| // find the entry for this name |
| SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer); |
| while(pChild) |
| { |
| if (m_pTreeView->getListBox().GetEntryText(pChild) == aName) |
| { |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData()); |
| if (pData) |
| { |
| if ( etTableOrView == pData->eType ) |
| { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query |
| _rEvent.Element >>= pData->xObjectProperties; // remember the new element |
| } |
| else |
| { |
| pChild->SetUserData(NULL); |
| delete pData; |
| } |
| } |
| break; |
| } |
| pChild = m_pTreeModel->NextSibling(pChild); |
| } |
| } |
| |
| // maybe the object which is part of the document data source has been removed |
| checkDocumentDataSource(); |
| } |
| else if (xNames.get() == m_xDatabaseContext.get()) |
| { // a datasource has been replaced in the context |
| DBG_ERROR("SbaTableQueryBrowser::elementReplaced: no support for replaced data sources!"); |
| // very suspicious: the database context should not allow to replace data source, only to register |
| // and revoke them |
| } |
| else |
| SbaXDataBrowserController::elementReplaced(_rEvent); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::impl_releaseConnection( SharedConnection& _rxConnection ) |
| { |
| // remove as event listener |
| Reference< XComponent > xComponent( _rxConnection, UNO_QUERY ); |
| if ( xComponent.is() ) |
| { |
| Reference< XEventListener > xListener( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY ); |
| xComponent->removeEventListener( xListener ); |
| } |
| |
| try |
| { |
| // temporary (hopefully!) hack for #i55274# |
| Reference< XFlushable > xFlush( _rxConnection, UNO_QUERY ); |
| if ( xFlush.is() ) |
| xFlush->flush(); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| // clear |
| _rxConnection.clear(); |
| // will implicitly dispose if we have the ownership, since xConnection is a SharedConnection |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::disposeConnection( SvLBoxEntry* _pDSEntry ) |
| { |
| DBG_ASSERT( _pDSEntry, "SbaTableQueryBrowser::disposeConnection: invalid entry (NULL)!" ); |
| DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::disposeConnection: invalid entry (not top-level)!" ); |
| |
| if ( _pDSEntry ) |
| { |
| DBTreeListUserData* pTreeListData = static_cast< DBTreeListUserData* >( _pDSEntry->GetUserData() ); |
| if ( pTreeListData ) |
| impl_releaseConnection( pTreeListData->xConnection ); |
| } |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::closeConnection(SvLBoxEntry* _pDSEntry,sal_Bool _bDisposeConnection) |
| { |
| DBG_ASSERT(_pDSEntry, "SbaTableQueryBrowser::closeConnection: invalid entry (NULL)!"); |
| DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::closeConnection: invalid entry (not top-level)!"); |
| |
| // if one of the entries of the given DS is displayed currently, unload the form |
| if (m_pCurrentlyDisplayed && (m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed) == _pDSEntry)) |
| unloadAndCleanup(_bDisposeConnection); |
| |
| // collapse the query/table container |
| for (SvLBoxEntry* pContainers = m_pTreeModel->FirstChild(_pDSEntry); pContainers; pContainers= m_pTreeModel->NextSibling(pContainers)) |
| { |
| SvLBoxEntry* pElements = m_pTreeModel->FirstChild(pContainers); |
| if ( pElements ) |
| m_pTreeView->getListBox().Collapse(pContainers); |
| m_pTreeView->getListBox().EnableExpandHandler(pContainers); |
| // and delete their children (they are connection-relative) |
| for (; pElements; ) |
| { |
| SvLBoxEntry* pRemove = pElements; |
| pElements= m_pTreeModel->NextSibling(pElements); |
| DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pRemove->GetUserData()); |
| pRemove->SetUserData(NULL); |
| delete pData; |
| m_pTreeModel->Remove(pRemove); |
| } |
| } |
| // collapse the entry itself |
| m_pTreeView->getListBox().Collapse(_pDSEntry); |
| |
| // dispose/reset the connection |
| if ( _bDisposeConnection ) |
| disposeConnection( _pDSEntry ); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::unloadAndCleanup( sal_Bool _bDisposeConnection ) |
| { |
| if (!m_pCurrentlyDisplayed) |
| // nothing to do |
| return; |
| |
| SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed); |
| |
| // de-select the path for the currently displayed table/query |
| if (m_pCurrentlyDisplayed) |
| { |
| selectPath(m_pCurrentlyDisplayed, sal_False); |
| } |
| m_pCurrentlyDisplayed = NULL; |
| |
| try |
| { |
| // get the active connection. We need to dispose it. |
| Reference< XPropertySet > xRowSetProps(getRowSet(),UNO_QUERY); |
| Reference< XConnection > xConn; |
| xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION) >>= xConn; |
| #if OSL_DEBUG_LEVEL > 1 |
| { |
| Reference< XComponent > xComp; |
| ::cppu::extractInterface(xComp, xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION)); |
| } |
| #endif |
| |
| // unload the form |
| Reference< XLoadable > xLoadable = getLoadable(); |
| if (xLoadable->isLoaded()) |
| xLoadable->unload(); |
| |
| // clear the grid control |
| Reference< XNameContainer > xConta(getControlModel(),UNO_QUERY); |
| clearGridColumns(xConta); |
| |
| // dispose the connection |
| if(_bDisposeConnection) |
| disposeConnection( pDSEntry ); |
| } |
| catch(SQLException& e) |
| { |
| showError(SQLExceptionInfo(e)); |
| } |
| catch(WrappedTargetException& e) |
| { |
| SQLException aSql; |
| if(e.TargetException >>= aSql) |
| showError(SQLExceptionInfo(aSql)); |
| else |
| OSL_ENSURE(sal_False, "SbaTableQueryBrowser::unloadAndCleanup: something strange happended!"); |
| } |
| catch(Exception&) |
| { |
| OSL_ENSURE(sal_False, "SbaTableQueryBrowser::unloadAndCleanup: could not reset the form"); |
| } |
| } |
| |
| // ------------------------------------------------------------------------- |
| namespace |
| { |
| Reference< XInterface > lcl_getDataSource( const Reference< XNameAccess >& _rxDatabaseContext, |
| const ::rtl::OUString& _rDataSourceName, const Reference< XConnection >& _rxConnection ) |
| { |
| Reference< XDataSource > xDataSource; |
| try |
| { |
| if ( _rDataSourceName.getLength() && _rxDatabaseContext->hasByName( _rDataSourceName ) ) |
| xDataSource.set( _rxDatabaseContext->getByName( _rDataSourceName ), UNO_QUERY_THROW ); |
| |
| if ( !xDataSource.is() ) |
| { |
| Reference< XChild > xConnAsChild( _rxConnection, UNO_QUERY ); |
| if ( xConnAsChild.is() ) |
| xDataSource.set( xConnAsChild->getParent(), UNO_QUERY_THROW ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| return xDataSource.get(); |
| } |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::impl_initialize() |
| { |
| ::vos::OGuard aGuard(Application::GetSolarMutex()); |
| // doin' a lot of VCL stuff here -> lock the SolarMutex |
| |
| // first initialize the parent |
| SbaXDataBrowserController::impl_initialize(); |
| |
| Reference<XConnection> xForeignConnection; |
| Reference< XFrame > xFrame; |
| |
| ::rtl::OUString aTableName, aCatalogName, aSchemaName; |
| |
| sal_Bool bEsacpeProcessing = sal_True; |
| sal_Int32 nInitialDisplayCommandType = CommandType::COMMAND; |
| ::rtl::OUString sInitialDataSourceName; |
| ::rtl::OUString sInitialCommand; |
| |
| const NamedValueCollection& rArguments( getInitParams() ); |
| |
| rArguments.get_ensureType( (::rtl::OUString)PROPERTY_DATASOURCENAME, sInitialDataSourceName ); |
| rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND_TYPE, nInitialDisplayCommandType ); |
| rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND, sInitialCommand ); |
| rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, xForeignConnection ); |
| rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_CATALOGNAME, aCatalogName ); |
| rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_SCHEMANAME, aSchemaName ); |
| rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_TABLENAME, aTableName ); |
| rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, bEsacpeProcessing ); |
| rArguments.get_ensureType( "Frame", xFrame ); |
| rArguments.get_ensureType( (::rtl::OUString)PROPERTY_SHOWMENU, m_bShowMenu ); |
| |
| // disable the browser if either of ShowTreeViewButton (compatibility name) or EnableBrowser |
| // is present and set to FALSE |
| sal_Bool bDisableBrowser = ( sal_False == rArguments.getOrDefault( "ShowTreeViewButton", sal_True ) ) // compatibility name |
| || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_True ) ); |
| OSL_ENSURE( !rArguments.has( "ShowTreeViewButton" ), |
| "SbaTableQueryBrowser::impl_initialize: ShowTreeViewButton is superseded by EnableBrowser!" ); |
| m_bEnableBrowser = !bDisableBrowser; |
| |
| // hide the tree view it is disabled in general, or if the settings tell to hide it initially |
| sal_Bool bHideTreeView = ( !m_bEnableBrowser ) |
| || ( sal_False == rArguments.getOrDefault( "ShowTreeView", sal_True ) ) // compatibility name |
| || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_SHOW_BROWSER, sal_True ) ); |
| OSL_ENSURE( !rArguments.has( "ShowTreeView" ), |
| "SbaTableQueryBrowser::impl_initialize: ShowTreeView is superseded by ShowBrowser!" ); |
| |
| if ( bHideTreeView ) |
| hideExplorer(); |
| else |
| showExplorer(); |
| |
| if ( m_bPreview ) |
| { |
| try |
| { |
| Sequence< ::rtl::OUString> aProperties(5); |
| Sequence< Any> aValues(5); |
| |
| ::rtl::OUString* pStringIter = aProperties.getArray(); |
| Any* pValueIter = aValues.getArray(); |
| *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlwaysShowCursor")); |
| *pValueIter++ <<= sal_False; |
| *pStringIter++ = PROPERTY_BORDER; |
| *pValueIter++ <<= sal_Int16(0); |
| |
| *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasNavigationBar")); |
| *pValueIter++ <<= sal_False; |
| *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasRecordMarker")); |
| *pValueIter++ <<= sal_False; |
| |
| *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tabstop")); |
| *pValueIter++ <<= sal_False; |
| |
| Reference< XMultiPropertySet > xFormMultiSet(getFormComponent(), UNO_QUERY); |
| if ( xFormMultiSet.is() ) |
| xFormMultiSet->setPropertyValues(aProperties, aValues); |
| } |
| catch(Exception) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| // are we loaded into a (sub)frame of an embedded document (i.e. a form belonging to a database |
| // document)? |
| sal_Bool bSubFrameOfEmbeddedDocument = sal_False; |
| if ( xFrame.is() ) |
| { |
| Reference<XFramesSupplier> xSup = xFrame->getCreator(); |
| Reference<XController> xCont = xSup.is() ? xSup->getController() : Reference<XController>(); |
| |
| bSubFrameOfEmbeddedDocument = xCont.is() && ::dbtools::isEmbeddedInDatabase( xCont->getModel(), xForeignConnection ); |
| } |
| |
| // if we have a connection at this point, it was either passed from outside, our |
| // determined from a outer DB document. In both cases, do not dispose it later on. |
| SharedConnection xConnection( xForeignConnection, SharedConnection::NoTakeOwnership ); |
| |
| // should we display all registered databases in the left hand side tree? |
| // or only *one* special? |
| sal_Bool bLimitedTreeEntries = sal_False; |
| // if we're part of a frame which is a secondary frame of a database document, then only |
| // display the database for this document, not all registered ones |
| bLimitedTreeEntries |= bSubFrameOfEmbeddedDocument; |
| // if the tree view is not to be displayed at all, then only display the data source |
| // which was given as initial selection |
| bLimitedTreeEntries |= ( m_bEnableBrowser != sal_True ); |
| |
| if ( bLimitedTreeEntries ) |
| { |
| if ( xConnection.is() ) |
| { |
| startConnectionListening( xConnection ); |
| |
| // if no initial name was given, try to obtain one from the data source |
| if ( !sInitialDataSourceName.getLength() ) |
| { |
| Reference< XChild > xChild( xConnection, UNO_QUERY ); |
| Reference< XPropertySet > xDataSourceProperties; |
| if ( xChild.is() ) |
| xDataSourceProperties = xDataSourceProperties.query( xChild->getParent() ); |
| if ( xDataSourceProperties.is() ) |
| { |
| try |
| { |
| OSL_VERIFY( xDataSourceProperties->getPropertyValue( PROPERTY_NAME ) >>= sInitialDataSourceName ); |
| } |
| catch( const Exception& ) |
| { |
| OSL_ENSURE( sal_False, "SbaTableQueryBrowser::impl_initialize: a connection parent which does not have a 'Name'!??" ); |
| } |
| } |
| } |
| } |
| |
| implAddDatasource( sInitialDataSourceName, xConnection ); |
| m_pTreeView->getListBox().Expand( m_pTreeView->getListBox().First() ); |
| } |
| else |
| initializeTreeModel(); |
| |
| if ( m_bEnableBrowser ) |
| { |
| m_aDocScriptSupport = ::boost::optional< bool >( false ); |
| } |
| else |
| { |
| // we are not used as "browser", but as mere view for a single table/query/command. In particular, |
| // there is a specific database document which we belong to. |
| Reference< XOfficeDatabaseDocument > xDocument( getDataSourceOrModel( |
| lcl_getDataSource( m_xDatabaseContext, sInitialDataSourceName, xConnection ) ), UNO_QUERY ); |
| m_aDocScriptSupport = ::boost::optional< bool >( Reference< XEmbeddedScripts >( xDocument, UNO_QUERY ).is() ); |
| } |
| |
| if ( implSelect( sInitialDataSourceName, sInitialCommand, nInitialDisplayCommandType, bEsacpeProcessing, xConnection, sal_True ) ) |
| { |
| try |
| { |
| Reference< XPropertySet > xRowSetProps(getRowSet(), UNO_QUERY); |
| xRowSetProps->setPropertyValue(PROPERTY_UPDATE_CATALOGNAME,makeAny(aCatalogName)); |
| xRowSetProps->setPropertyValue(PROPERTY_UPDATE_SCHEMANAME,makeAny(aSchemaName)); |
| xRowSetProps->setPropertyValue(PROPERTY_UPDATE_TABLENAME,makeAny(aTableName)); |
| |
| } |
| catch(const Exception&) |
| { |
| OSL_ENSURE(sal_False, "SbaTableQueryBrowser::impl_initialize: could not set the update related names!"); |
| } |
| } |
| |
| InvalidateAll(); |
| } |
| |
| // ------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::haveExplorer() const |
| { |
| return m_pTreeView && m_pTreeView->IsVisible(); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::hideExplorer() |
| { |
| if (!haveExplorer()) |
| return; |
| if (!getBrowserView()) |
| return; |
| |
| m_pTreeView->Hide(); |
| m_pSplitter->Hide(); |
| getBrowserView()->Resize(); |
| |
| InvalidateFeature(ID_BROWSER_EXPLORER); |
| } |
| |
| // ------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::showExplorer() |
| { |
| if (haveExplorer()) |
| return; |
| |
| if (!getBrowserView()) |
| return; |
| |
| m_pTreeView->Show(); |
| m_pSplitter->Show(); |
| getBrowserView()->Resize(); |
| |
| InvalidateFeature(ID_BROWSER_EXPLORER); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::ensureConnection(SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection) |
| { |
| SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(_pAnyEntry); |
| DBTreeListUserData* pDSData = |
| pDSEntry |
| ? static_cast<DBTreeListUserData*>(pDSEntry->GetUserData()) |
| : NULL; |
| |
| return ensureConnection( pDSEntry, pDSData, _rConnection ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| ::std::auto_ptr< ImageProvider > SbaTableQueryBrowser::getImageProviderFor( SvLBoxEntry* _pAnyEntry ) |
| { |
| ::std::auto_ptr< ImageProvider > pImageProvider( new ImageProvider ); |
| SharedConnection xConnection; |
| if ( getExistentConnectionFor( _pAnyEntry, xConnection ) ) |
| pImageProvider.reset( new ImageProvider( xConnection ) ); |
| return pImageProvider; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::getExistentConnectionFor( SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection ) |
| { |
| SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent( _pAnyEntry ); |
| DBTreeListUserData* pDSData = |
| pDSEntry |
| ? static_cast< DBTreeListUserData* >( pDSEntry->GetUserData() ) |
| : NULL; |
| if ( pDSData ) |
| _rConnection = pDSData->xConnection; |
| return _rConnection.is(); |
| } |
| |
| #ifdef DBG_UTIL |
| // ----------------------------------------------------------------------------- |
| bool SbaTableQueryBrowser::impl_isDataSourceEntry( SvLBoxEntry* _pEntry ) const |
| { |
| return m_pTreeModel->GetRootLevelParent( _pEntry ) == _pEntry; |
| } |
| #endif |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::ensureConnection( SvLBoxEntry* _pDSEntry, void* pDSData, SharedConnection& _rConnection ) |
| { |
| DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::ensureConnection: this entry does not denote a data source!" ); |
| if(_pDSEntry) |
| { |
| DBTreeListUserData* pTreeListData = static_cast<DBTreeListUserData*>(pDSData); |
| ::rtl::OUString aDSName = GetEntryText(_pDSEntry); |
| |
| if ( pTreeListData ) |
| _rConnection = pTreeListData->xConnection; |
| |
| if ( !_rConnection.is() && pTreeListData ) |
| { |
| // show the "connecting to ..." status |
| String sConnecting(ModuleRes(STR_CONNECTING_DATASOURCE)); |
| sConnecting.SearchAndReplaceAscii("$name$", aDSName); |
| BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sConnecting); |
| |
| // build a string showing context information in case of error |
| String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) ); |
| sConnectingContext.SearchAndReplaceAscii("$name$", aDSName); |
| |
| // connect |
| _rConnection.reset( |
| connect( getDataSourceAcessor( _pDSEntry ), sConnectingContext, NULL ), |
| SharedConnection::TakeOwnership |
| ); |
| |
| // remember the connection |
| pTreeListData->xConnection = _rConnection; |
| } |
| } |
| |
| return _rConnection.is(); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| IMPL_LINK( SbaTableQueryBrowser, OnTreeEntryCompare, const SvSortData*, _pSortData ) |
| { |
| SvLBoxEntry* pLHS = static_cast<SvLBoxEntry*>(_pSortData->pLeft); |
| SvLBoxEntry* pRHS = static_cast<SvLBoxEntry*>(_pSortData->pRight); |
| DBG_ASSERT(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!"); |
| // we want the table entry and the end so we have to do a check |
| |
| if (isContainer(pRHS)) |
| { |
| // don't use getEntryType (directly or indirecly) for the LHS: |
| // LHS is currently beeing inserted, so it is not "completely valid" at the moment |
| |
| const EntryType eRight = getEntryType(pRHS); |
| if (etTableContainer == eRight) |
| // every other container should be placed _before_ the bookmark container |
| return -1; |
| |
| const String sLeft = m_pTreeView->getListBox().GetEntryText(pLHS); |
| |
| EntryType eLeft = etTableContainer; |
| if (String(ModuleRes(RID_STR_TABLES_CONTAINER)) == sLeft) |
| eLeft = etTableContainer; |
| else if (String(ModuleRes(RID_STR_QUERIES_CONTAINER)) == sLeft) |
| eLeft = etQueryContainer; |
| |
| if ( eLeft == eRight ) |
| return COMPARE_EQUAL; |
| |
| if ( ( eLeft == etTableContainer ) && ( eRight == etQueryContainer ) ) |
| return COMPARE_GREATER; |
| |
| if ( ( eLeft == etQueryContainer ) && ( eRight == etTableContainer ) ) |
| return COMPARE_LESS; |
| |
| OSL_ENSURE( false, "SbaTableQueryBrowser::OnTreeEntryCompare: unexpected case!" ); |
| return COMPARE_EQUAL; |
| } |
| |
| SvLBoxString* pLeftTextItem = static_cast<SvLBoxString*>(pLHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); |
| SvLBoxString* pRightTextItem = static_cast<SvLBoxString*>(pRHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); |
| DBG_ASSERT(pLeftTextItem && pRightTextItem, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid text items!"); |
| |
| String sLeftText = pLeftTextItem->GetText(); |
| String sRightText = pRightTextItem->GetText(); |
| |
| sal_Int32 nCompareResult = 0; // equal by default |
| |
| if (m_xCollator.is()) |
| { |
| try |
| { |
| nCompareResult = m_xCollator->compareString(sLeftText, sRightText); |
| } |
| catch(Exception&) |
| { |
| } |
| } |
| else |
| // default behaviour if we do not have a collator -> do the simple string compare |
| nCompareResult = sLeftText.CompareTo(sRightText); |
| |
| return nCompareResult; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::implAdministrate( SvLBoxEntry* _pApplyTo ) |
| { |
| OSL_PRECOND( _pApplyTo, "SbaTableQueryBrowser::implAdministrate: illegal entry!" ); |
| if ( !_pApplyTo ) |
| return; |
| |
| try |
| { |
| // get the desktop object |
| sal_Int32 nFrameSearchFlag = FrameSearchFlag::ALL | FrameSearchFlag::GLOBAL ; |
| Reference< XComponentLoader > xFrameLoader(getORB()->createInstance(SERVICE_FRAME_DESKTOP),UNO_QUERY); |
| |
| if ( xFrameLoader.is() ) |
| { |
| // the initial selection |
| SvLBoxEntry* pTopLevelSelected = _pApplyTo; |
| while (pTopLevelSelected && m_pTreeView->getListBox().GetParent(pTopLevelSelected)) |
| pTopLevelSelected = m_pTreeView->getListBox().GetParent(pTopLevelSelected); |
| ::rtl::OUString sInitialSelection; |
| if (pTopLevelSelected) |
| sInitialSelection = getDataSourceAcessor( pTopLevelSelected ); |
| |
| Reference< XDataSource > xDataSource( getDataSourceByName( sInitialSelection, getView(), getORB(), NULL ) ); |
| Reference< XModel > xDocumentModel( getDataSourceOrModel( xDataSource ), UNO_QUERY ); |
| |
| if ( xDocumentModel.is() ) |
| { |
| Reference< XInteractionHandler > xInteractionHandler( |
| getORB()->createInstance( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), |
| UNO_QUERY ); |
| OSL_ENSURE( xInteractionHandler.is(), "SbaTableQueryBrowser::implAdministrate: no interaction handler available!" ); |
| |
| ::comphelper::NamedValueCollection aLoadArgs; |
| aLoadArgs.put( "Model", xDocumentModel ); |
| aLoadArgs.put( "InteractionHandler", xInteractionHandler ); |
| aLoadArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG ); |
| |
| Sequence< PropertyValue > aLoadArgPV; |
| aLoadArgs >>= aLoadArgPV; |
| |
| xFrameLoader->loadComponentFromURL( |
| xDocumentModel->getURL(), |
| ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_default")), |
| nFrameSearchFlag, |
| aLoadArgPV |
| ); |
| } |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::requestQuickHelp( const SvLBoxEntry* _pEntry, String& _rText ) const |
| { |
| const DBTreeListUserData* pData = static_cast< const DBTreeListUserData* >( _pEntry->GetUserData() ); |
| if ( ( pData->eType == etDatasource ) && pData->sAccessor.Len() ) |
| { |
| _rText = ::svt::OFileNotation( pData->sAccessor ).get( ::svt::OFileNotation::N_SYSTEM ); |
| return sal_True; |
| } |
| return sal_False; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| PopupMenu* SbaTableQueryBrowser::getContextMenu( Control& _rControl ) const |
| { |
| OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl, |
| "SbaTableQueryBrowser::getContextMenu: where does this come from?" ); |
| if ( &m_pTreeView->getListBox() != &_rControl ) |
| return NULL; |
| |
| return new PopupMenu( ModuleRes( MENU_BROWSER_DEFAULTCONTEXT ) ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| IController& SbaTableQueryBrowser::getCommandController() |
| { |
| return *this; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| ::cppu::OInterfaceContainerHelper* SbaTableQueryBrowser::getContextMenuInterceptors() |
| { |
| return &m_aContextMenuInterceptors; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| Any SbaTableQueryBrowser::getCurrentSelection( Control& _rControl ) const |
| { |
| OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl, |
| "SbaTableQueryBrowser::getCurrentSelection: where does this come from?" ); |
| |
| if ( &m_pTreeView->getListBox() != &_rControl ) |
| return Any(); |
| |
| SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected(); |
| if ( !pSelected ) |
| return Any(); |
| |
| OSL_ENSURE( m_pTreeView->getListBox().NextSelected( pSelected ) == NULL, |
| "SbaTableQueryBrowser::getCurrentSelection: single-selection is expected here!" ); |
| |
| NamedDatabaseObject aSelectedObject; |
| DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pSelected->GetUserData() ); |
| aSelectedObject.Type = static_cast< sal_Int32 >( pData->eType ); |
| |
| switch ( aSelectedObject.Type ) |
| { |
| case DatabaseObject::QUERY: |
| case DatabaseObject::TABLE: |
| aSelectedObject.Name = m_pTreeView->getListBox().GetEntryText( pSelected ); |
| break; |
| |
| case DatabaseObjectContainer::DATA_SOURCE: |
| case DatabaseObjectContainer::QUERIES: |
| case DatabaseObjectContainer::TABLES: |
| aSelectedObject.Name = getDataSourceAcessor( pSelected ); |
| break; |
| |
| default: |
| OSL_ENSURE( false, "SbaTableQueryBrowser::getCurrentSelection: invalid (unexpected) object type!" ); |
| break; |
| } |
| |
| return makeAny( aSelectedObject ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::implGetQuerySignature( ::rtl::OUString& _rCommand, sal_Bool& _bEscapeProcessing ) |
| { |
| _rCommand = ::rtl::OUString(); |
| _bEscapeProcessing = sal_False; |
| |
| try |
| { |
| // ontain the dss (data source signature) of the form |
| ::rtl::OUString sDataSourceName; |
| ::rtl::OUString sCommand; |
| sal_Int32 nCommandType = CommandType::COMMAND; |
| Reference< XPropertySet > xRowsetProps( getRowSet(), UNO_QUERY ); |
| ODataAccessDescriptor aDesc( xRowsetProps ); |
| sDataSourceName = aDesc.getDataSource(); |
| aDesc[ daCommand ] >>= sCommand; |
| aDesc[ daCommandType ] >>= nCommandType; |
| |
| // do we need to do anything? |
| if ( CommandType::QUERY != nCommandType ) |
| return sal_False; |
| |
| // get the query object |
| Reference< XQueryDefinitionsSupplier > xSuppQueries; |
| Reference< XNameAccess > xQueries; |
| Reference< XPropertySet > xQuery; |
| m_xDatabaseContext->getByName( sDataSourceName ) >>= xSuppQueries; |
| if ( xSuppQueries.is() ) |
| xQueries = xSuppQueries->getQueryDefinitions(); |
| if ( xQueries.is() ) |
| xQueries->getByName( sCommand ) >>= xQuery; |
| OSL_ENSURE( xQuery.is(), "SbaTableQueryBrowser::implGetQuerySignature: could not retrieve the query object!" ); |
| |
| // get the two properties we need |
| if ( xQuery.is() ) |
| { |
| xQuery->getPropertyValue( PROPERTY_COMMAND ) >>= _rCommand; |
| _bEscapeProcessing = ::cppu::any2bool( xQuery->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) ); |
| return sal_True; |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| return sal_False; |
| } |
| //------------------------------------------------------------------------------ |
| void SbaTableQueryBrowser::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException ) |
| { |
| if (aEvent.Frame == m_xCurrentFrameParent) |
| { |
| if(aEvent.Action == FrameAction_COMPONENT_DETACHING) |
| implRemoveStatusListeners(); |
| else if (aEvent.Action == FrameAction_COMPONENT_REATTACHED) |
| connectExternalDispatches(); |
| } |
| else |
| SbaXDataBrowserController::frameAction(aEvent); |
| |
| } |
| // ----------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::clearGridColumns(const Reference< XNameContainer >& _xColContainer) |
| { |
| // first we have to clear the grid |
| Sequence< ::rtl::OUString > aNames = _xColContainer->getElementNames(); |
| const ::rtl::OUString* pIter = aNames.getConstArray(); |
| const ::rtl::OUString* pEnd = pIter + aNames.getLength(); |
| Reference< XInterface > xColumn; |
| for (; pIter != pEnd;++pIter) |
| { |
| _xColContainer->getByName(*pIter) >>= xColumn; |
| _xColContainer->removeByName(*pIter); |
| ::comphelper::disposeComponent(xColumn); |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::isHiContrast() const |
| { |
| sal_Bool bRet = sal_False; |
| if ( m_pTreeView ) |
| bRet = m_pTreeView->getListBox().GetSettings().GetStyleSettings().GetHighContrastMode(); |
| return bRet; |
| } |
| // ----------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::loadMenu(const Reference< XFrame >& _xFrame) |
| { |
| if ( m_bShowMenu ) |
| { |
| OGenericUnoController::loadMenu(_xFrame); |
| } |
| else if ( !m_bPreview ) |
| { |
| Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager = getLayoutManager(_xFrame); |
| |
| if ( xLayoutManager.is() ) |
| { |
| xLayoutManager->lock(); |
| xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ))); |
| xLayoutManager->unlock(); |
| xLayoutManager->doLayout(); |
| } |
| onLoadedMenu( xLayoutManager ); |
| } |
| } |
| // ----------------------------------------------------------------------------- |
| ::rtl::OUString SbaTableQueryBrowser::getPrivateTitle() const |
| { |
| ::rtl::OUString sTitle; |
| if ( m_pCurrentlyDisplayed ) |
| { |
| SvLBoxEntry* pContainer = m_pTreeModel->GetParent(m_pCurrentlyDisplayed); |
| // get the entry for the datasource |
| SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer); |
| ::rtl::OUString sName = m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed); |
| sTitle = GetEntryText( pConnection ); |
| INetURLObject aURL(sTitle); |
| if ( aURL.GetProtocol() != INET_PROT_NOT_VALID ) |
| sTitle = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET); |
| if ( sName.getLength() ) |
| { |
| sName += ::rtl::OUString::createFromAscii(" - "); |
| sName += sTitle; |
| sTitle = sName; |
| } |
| } |
| |
| return sTitle; |
| } |
| // ----------------------------------------------------------------------------- |
| sal_Bool SbaTableQueryBrowser::preReloadForm() |
| { |
| sal_Bool bIni = sal_False; |
| if ( !m_pCurrentlyDisplayed ) |
| { |
| // switch the grid to design mode while loading |
| getBrowserView()->getGridControl()->setDesignMode(sal_True); |
| // we had an invalid statement so we need to connect the column models |
| Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY); |
| ::svx::ODataAccessDescriptor aDesc(xRowSetProps); |
| // extract the props |
| ::rtl::OUString sDataSource; |
| ::rtl::OUString sCommand; |
| sal_Int32 nCommandType = CommandType::COMMAND; |
| sal_Bool bEscapeProcessing = sal_True; |
| extractDescriptorProps(aDesc, sDataSource, sCommand, nCommandType, bEscapeProcessing); |
| if ( sDataSource.getLength() && sCommand.getLength() && (-1 != nCommandType) ) |
| { |
| SvLBoxEntry* pDataSource = NULL; |
| SvLBoxEntry* pCommandType = NULL; |
| m_pCurrentlyDisplayed = getObjectEntry( sDataSource, sCommand, nCommandType, &pDataSource, &pCommandType, sal_True, SharedConnection() ); |
| bIni = sal_True; |
| } |
| } |
| return bIni; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| void SbaTableQueryBrowser::postReloadForm() |
| { |
| InitializeGridModel(getFormComponent()); |
| LoadFinished(sal_True); |
| //updateTitle(); |
| } |
| |
| //------------------------------------------------------------------------------ |
| Reference< XEmbeddedScripts > SAL_CALL SbaTableQueryBrowser::getScriptContainer() throw (RuntimeException) |
| { |
| // update our database document |
| Reference< XModel > xDocument; |
| try |
| { |
| Reference< XPropertySet > xCursorProps( getRowSet(), UNO_QUERY_THROW ); |
| Reference< XConnection > xConnection( xCursorProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY ); |
| if ( xConnection.is() ) |
| { |
| Reference< XChild > xChild( xConnection, UNO_QUERY_THROW ); |
| Reference< XDocumentDataSource > xDataSource( xChild->getParent(), UNO_QUERY_THROW ); |
| xDocument.set( xDataSource->getDatabaseDocument(), UNO_QUERY_THROW ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| Reference< XEmbeddedScripts > xScripts( xDocument, UNO_QUERY ); |
| OSL_ENSURE( xScripts.is() || !xDocument.is(), |
| "SbaTableQueryBrowser::getScriptContainer: invalid database document!" ); |
| return xScripts; |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL SbaTableQueryBrowser::registerContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException) |
| { |
| if ( _Interceptor.is() ) |
| m_aContextMenuInterceptors.addInterface( _Interceptor ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL SbaTableQueryBrowser::releaseContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException) |
| { |
| if ( _Interceptor.is() ) |
| m_aContextMenuInterceptors.removeInterface( _Interceptor ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL SbaTableQueryBrowser::registeredDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| implAddDatasource( _Event.Name, SharedConnection() ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SbaTableQueryBrowser::impl_cleanupDataSourceEntry( const String& _rDataSourceName ) |
| { |
| // get the top-level representing the removed data source |
| SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().FirstChild( NULL ); |
| while ( pDataSourceEntry ) |
| { |
| if ( m_pTreeView->getListBox().GetEntryText( pDataSourceEntry ) == _rDataSourceName ) |
| break; |
| |
| pDataSourceEntry = m_pTreeView->getListBox().NextSibling( pDataSourceEntry ); |
| } |
| |
| OSL_ENSURE( pDataSourceEntry, "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: do not know this data source!" ); |
| if ( !pDataSourceEntry ) |
| return; |
| |
| if ( isSelected( pDataSourceEntry ) ) |
| { // a table or query belonging to the deleted data source is currently beeing displayed. |
| OSL_ENSURE( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) == pDataSourceEntry, |
| "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (1)!" ); |
| unloadAndCleanup( sal_True ); |
| } |
| else |
| OSL_ENSURE( |
| ( NULL == m_pCurrentlyDisplayed ) |
| || ( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) != pDataSourceEntry ), |
| "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (2)!"); |
| |
| // delete any user data of the child entries of the to-be-removed entry |
| SvTreeEntryList* pList = m_pTreeModel->GetChildList( pDataSourceEntry ); |
| if ( pList ) |
| { |
| SvLBoxEntry* pEntryLoop = static_cast<SvLBoxEntry*>( pList->First() ); |
| while ( pEntryLoop ) |
| { |
| DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pEntryLoop->GetUserData() ); |
| pEntryLoop->SetUserData( NULL ); |
| delete pData; |
| pEntryLoop = static_cast< SvLBoxEntry* >( pList->Next() ); |
| } |
| } |
| |
| // remove the entry |
| DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() ); |
| pDataSourceEntry->SetUserData( NULL ); |
| delete pData; |
| m_pTreeModel->Remove( pDataSourceEntry ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL SbaTableQueryBrowser::revokedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| impl_cleanupDataSourceEntry( _Event.Name ); |
| |
| // maybe the object which is part of the document data source has been removed |
| checkDocumentDataSource(); |
| } |
| |
| //------------------------------------------------------------------------------ |
| void SAL_CALL SbaTableQueryBrowser::changedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| // in case the data source was expanded, and connected, we need to clean it up |
| // for simplicity, just do as if the data source were completely removed and re-added |
| impl_cleanupDataSourceEntry( _Event.Name ); |
| implAddDatasource( _Event.Name, SharedConnection() ); |
| } |
| |
| |
| // ......................................................................... |
| } // namespace dbaui |
| // ......................................................................... |
| |
| |