Files
libreoffice/dbaccess/source/ui/browser/unodatbr.cxx
Rüdiger Timm 4e24b7b64c INTEGRATION: CWS dba22a (1.182.2); FILE MERGED
2006/11/15 08:49:49 fs 1.182.2.1: #142997#
modified the double-click handling in the DBTreeListBox
various stack trace reports suggest there are scenarios where a double click
handler somehow destroys/corrupts the list box and/or its entries, but the
subsequent default handling in the SvListBox class accesses those corrupted
entities.
Since we're not able to reproduce any of those crashs, the handling in the
DBTreeListBox and its clients now is as follows:
If a double click is handled, then the DBTreeListBox::DoubleClickHdl will
return 0, this way causing the SvListBox to *not* process the double
click event further.
2006-12-01 16:30:23 +00:00

3793 lines
153 KiB
C++

/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: unodatbr.cxx,v $
*
* $Revision: 1.184 $
*
* last change: $Author: rt $ $Date: 2006-12-01 17:30:23 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#ifndef _SVX_GRIDCTRL_HXX
#include <svx/gridctrl.hxx>
#endif
#ifndef SVX_DATABASE_REGISTRATION_UI_HXX
#include <svx/databaseregistrationui.hxx>
#endif
#ifndef _SBA_UNODATBR_HXX_
#include "unodatbr.hxx"
#endif
#ifndef _SBA_GRID_HXX
#include "sbagrid.hxx"
#endif
#ifndef DBACCESS_IMAGEPROVIDER_HXX
#include "imageprovider.hxx"
#endif
#ifndef _SVTREEBOX_HXX
#include <svtools/svtreebx.hxx>
#endif
#ifndef _SVX_DATACCESSDESCRIPTOR_HXX_
#include <svx/dataaccessdescriptor.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_FETCHDIRECTION_HPP_
#include <com/sun/star/sdbc/FetchDirection.hpp>
#endif
#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif
#ifndef _COM_SUN_STAR_FORM_XLOADABLE_HPP_
#include <com/sun/star/form/XLoadable.hpp>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _COM_SUN_STAR_SDB_XPARAMETERSSUPPLIER_HPP_
#include <com/sun/star/sdb/XParametersSupplier.hpp>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYANALYZER_HPP_
#include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYCOMPOSER_HPP_
#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
#endif
#ifndef _SV_MULTISEL_HXX //autogen
#include <tools/multisel.hxx>
#endif
#ifndef TOOLS_DIAGNOSE_EX_H
#include <tools/diagnose_ex.h>
#endif
#ifndef _COM_SUN_STAR_SDB_XQUERIESSUPPLIER_HPP_
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XWARNINGSSUPPLIER_HPP_
#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XRENAME_HPP_
#include <com/sun/star/sdbcx/XRename.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XDOCUMENTDATASOURCE_HPP_
#include <com/sun/star/sdb/XDocumentDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XLAYOUTMANAGER_HPP_
#include <com/sun/star/frame/XLayoutManager.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XFLUSHABLE_HPP_
#include <com/sun/star/util/XFlushable.hpp>
#endif
#ifndef _URLOBJ_HXX //autogen
#include <tools/urlobj.hxx>
#endif
#ifndef TOOLS_DIAGNOSE_EX_H
#include <tools/diagnose_ex.h>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif
#ifndef _SV_WAITOBJ_HXX
#include <vcl/waitobj.hxx>
#endif
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX
#include <vcl/toolbox.hxx>
#endif
#ifndef _SFXAPP_HXX //autogen
#include <sfx2/app.hxx>
#endif
#ifndef _SV_WRKWIN_HXX //autogen
#include <vcl/wrkwin.hxx>
#endif
#ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_
#include <com/sun/star/sdb/CommandType.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
#include <com/sun/star/sdbc/DataType.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XGRIDCOLUMNFACTORY_HPP_
#include <com/sun/star/form/XGridColumnFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XFORM_HPP_
#include <com/sun/star/form/XForm.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_VISUALEFFECT_HPP_
#include <com/sun/star/awt/VisualEffect.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_LINEENDFORMAT_HPP_
#include <com/sun/star/awt/LineEndFormat.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_TEXTALIGN_HPP_
#include <com/sun/star/awt/TextAlign.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XBOOKMARKSSUPPLIER_HPP_
#include <com/sun/star/sdb/XBookmarksSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XVIEWSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XDROP_HPP_
#include <com/sun/star/sdbcx/XDrop.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XCOMPLETEDCONNECTION_HPP_
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
#include <com/sun/star/sdbc/XDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XQUERYDEFINITIONSSUPPLIER_HPP_
#include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_UI_DIALOGS_XEXECUTABLEDIALOG_HPP_
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_NAMEDVALUE_HPP_
#include <com/sun/star/beans/NamedValue.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XDATADESCRIPTORFACTORY_HPP_
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#endif
#ifndef _SVX_ALGITEM_HXX //autogen
#include <svx/algitem.hxx>
#endif
#ifndef _COM_SUN_STAR_SDB_XRESULTSETACCESS_HPP_
#include <com/sun/star/sdb/XResultSetAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_SQLWARNING_HPP_
#include <com/sun/star/sdbc/SQLWarning.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
#include <com/sun/star/sdb/SQLContext.hpp>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef DBAUI_DBTREEMODEL_HXX
#include "dbtreemodel.hxx"
#endif
#ifndef DBACCESS_UI_DBTREEVIEW_HXX
#include "dbtreeview.hxx"
#endif
#ifndef SVTOOLS_FILENOTATION_HXX
#include <svtools/filenotation.hxx>
#endif
#ifndef _SVLBOXITM_HXX
#include <svtools/svlbitm.hxx>
#endif
#ifndef _SV_SPLIT_HXX
#include <vcl/split.hxx>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _DBU_BRW_HRC_
#include "dbu_brw.hrc"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef DBACCESS_SBA_GRID_HRC
#include "sbagrid.hrc"
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _DBU_REGHELPER_HXX_
#include "dbu_reghelper.hxx"
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include <connectivity/dbexception.hxx>
#endif
#ifndef _VCL_STDTEXT_HXX
#include <vcl/stdtext.hxx>
#endif
#ifndef DBAUI_DBTREELISTBOX_HXX
#include "dbtreelistbox.hxx"
#endif
#ifndef _DBA_DBACCESS_HELPID_HRC_
#include "dbaccess_helpid.hrc"
#endif
#ifndef _DBAUI_LISTVIEWITEMS_HXX_
#include "listviewitems.hxx"
#endif
#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef DBAUI_TOKENWRITER_HXX
#include "TokenWriter.hxx"
#endif
#ifndef DBAUI_DBEXCHANGE_HXX
#include "dbexchange.hxx"
#endif
#ifndef DBAUI_WIZ_COPYTABLEDIALOG_HXX
#include "WCopyTable.hxx"
#endif
#ifndef DBAUI_WIZ_EXTENDPAGES_HXX
#include "WExtendPages.hxx"
#endif
#ifndef DBAUI_WIZ_NAMEMATCHING_HXX
#include "WNameMatch.hxx"
#endif
#ifndef DBAUI_WIZ_COLUMNSELECT_HXX
#include "WColumnSelect.hxx"
#endif
#ifndef DBAUI_ENUMTYPES_HXX
#include "QEnumTypes.hxx"
#endif
#ifndef DBAUI_WIZARD_CPAGE_HXX
#include "WCPage.hxx"
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef DBAUI_RTFREADER_HXX
#include "RtfReader.hxx"
#endif
#ifndef DBAUI_HTMLREADER_HXX
#include "HtmlReader.hxx"
#endif
#ifndef _DBAUI_SQLMESSAGE_HXX_
#include "sqlmessage.hxx"
#endif
#ifndef DBAUI_DLGSAVE_HXX
#include "dlgsave.hxx"
#endif
#ifndef _SOT_STORAGE_HXX
#include <sot/storage.hxx>
#endif
#ifndef _DBAUI_LINKEDDOCUMENTS_HXX_
#include "linkeddocuments.hxx"
#endif
#ifndef _DBACCESS_UI_DIRECTSQL_HXX_
#include "directsql.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_
#include <com/sun/star/sdbcx/Privilege.hpp>
#endif
#ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
#include <svtools/moduleoptions.hxx>
#endif
#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::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 ::dbtools;
using namespace ::comphelper;
using namespace ::svx;
using ::com::sun::star::frame::XLayoutManager; // obsolete of interface is moved outside drafts
using ::com::sun::star::ui::XUIElement; // dito
// .........................................................................
namespace dbaui
{
// .........................................................................
//==================================================================
//= 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(m_aMutex)
,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)
{
Any aReturn = SbaXDataBrowserController::queryInterface(_rType);
if (!aReturn.hasValue())
aReturn = SbaTableQueryBrowser_Base::queryInterface(_rType);
return aReturn;
}
//------------------------------------------------------------------------------
Sequence< Type > SAL_CALL SbaTableQueryBrowser::getTypes( ) throw (RuntimeException)
{
return ::comphelper::concatSequences(
SbaXDataBrowserController::getTypes(),
SbaTableQueryBrowser_Base::getTypes()
);
}
//------------------------------------------------------------------------------
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);
// 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<DBTreeListModel> aTemp(m_pTreeModel);
m_pTreeModel = NULL;
}
// remove ourself as status listener
implRemoveStatusListeners();
// remove the container listener from the database context
Reference< XContainer > xDatasourceContainer(m_xDatabaseContext, UNO_QUERY);
if (xDatasourceContainer.is())
xDatasourceContainer->removeContainerListener(this);
// 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< XContainer > xDatasourceContainer(m_xDatabaseContext, UNO_QUERY);
if (xDatasourceContainer.is())
xDatasourceContainer->addContainerListener(this);
else
DBG_ERROR("SbaTableQueryBrowser::Construct: the DatabaseContext should allow us to be a listener!");
// the collator for the string compares
m_xCollator = Reference< XCollator >(getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.i18n.Collator")), UNO_QUERY);
if (m_xCollator.is())
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(),m_xMultiServiceFacatory, WB_TABSTOP | WB_BORDER);
m_pTreeView->SetPreExpandHandler(LINK(this, SbaTableQueryBrowser, OnExpandEntry));
m_pTreeView->setCopyHandler(LINK(this, SbaTableQueryBrowser, OnCopyEntry));
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 DBTreeListModel;
m_pTreeModel->SetSortMode(SortAscending);
m_pTreeModel->SetCompareHdl(LINK(this, SbaTableQueryBrowser, OnTreeEntryCompare));
m_pTreeView->setModel(m_pTreeModel);
m_pTreeView->setSelectHdl(LINK(this, SbaTableQueryBrowser, OnSelectEntry));
// 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;
}
// -------------------------------------------------------------------------
sal_Bool SbaTableQueryBrowser::InitializeForm(const Reference< ::com::sun::star::sdbc::XRowSet > & _rxForm)
{
if(!m_pCurrentlyDisplayed)
return sal_True;
// this method set all format settings from the orignal table or query
try
{
// we send all properties at once, maybe the implementation is clever enough to handle one big PropertiesChanged
// more effective than many small PropertyChanged ;)
Sequence< ::rtl::OUString> aProperties(3);
Sequence< Any> aValues(3);
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
OSL_ENSURE( pData, "SbaTableQueryBrowser::InitializeForm: No user data set at the currently displayed entry!" );
OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeForm: No table available!" );
if ( pData->xObjectProperties.is() )
{
sal_Int32 nPos = 0;
// is the filter intially applied ?
aProperties.getArray()[nPos] = PROPERTY_APPLYFILTER;
aValues.getArray()[nPos++] = pData->xObjectProperties->getPropertyValue(PROPERTY_APPLYFILTER);
// the initial filter
aProperties.getArray()[nPos] = PROPERTY_FILTER;
aValues.getArray()[nPos++] = pData->xObjectProperties->getPropertyValue(PROPERTY_FILTER);
if ( pData->xObjectProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_HAVING_CLAUSE) )
{
aProperties.realloc(aProperties.getLength()+1);
aValues.realloc(aValues.getLength()+1);
// the initial having clause
aProperties.getArray()[nPos] = PROPERTY_HAVING_CLAUSE;
aValues.getArray()[nPos++] = pData->xObjectProperties->getPropertyValue(PROPERTY_HAVING_CLAUSE);
}
// the initial ordering
aProperties.getArray()[nPos] = PROPERTY_ORDER;
aValues.getArray()[nPos++] = pData->xObjectProperties->getPropertyValue(PROPERTY_ORDER);
Reference< XMultiPropertySet > xFormMultiSet(_rxForm, UNO_QUERY);
xFormMultiSet->setPropertyValues(aProperties, aValues);
}
}
catch(Exception&)
{
DBG_ERROR("SbaTableQueryBrowser::InitializeForm : something went wrong !");
return sal_False;
}
return sal_True;
}
//------------------------------------------------------------------------------
void SbaTableQueryBrowser::initializePreviewMode()
{
if ( getBrowserView() && getBrowserView()->getVclControl() )
{
getBrowserView()->getVclControl()->AlwaysEnableInput( FALSE );
getBrowserView()->getVclControl()->EnableInput( 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 ));
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeGridModel: No table available!" );
::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_ACTIVECONNECTION ) >>= 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 bSupress = ::cppu::any2bool(xDataSourceProp->getPropertyValue(PROPERTY_SUPPRESSVERSIONCL));
// 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 sPropertyName;
Reference<XPropertySet> xColumn;
for (sal_uInt16 i=0; pIter != pEnd; ++i,++pIter)
{
// Typ
// first get type to determine wich control we need
::cppu::extractInterface(xColumn,xColumns->getByName(*pIter));
// ignore the column when it is a rowversion one
if(bSupress && xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_ISROWVERSION)
&& ::cppu::any2bool(xColumn->getPropertyValue(PROPERTY_ISROWVERSION)))
continue;
sal_Bool bFormattedIsNumeric = sal_True;
sal_Int32 nType = comphelper::getINT32(xColumn->getPropertyValue(PROPERTY_TYPE));
::std::vector< NamedValue > aInitialValues;
::std::vector< ::rtl::OUString > aCopyProperties;
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 ) ) );
sPropertyName = PROPERTY_DEFAULTSTATE;
break;
case DataType::LONGVARCHAR:
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");
sPropertyName = PROPERTY_DEFAULTTEXT;
break;
case DataType::VARCHAR:
case DataType::CHAR:
bFormattedIsNumeric = sal_False;
// NO break!
default:
aCurrentModelType = ::rtl::OUString::createFromAscii("FormattedField");
sPropertyName = 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 ) ) );
aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( *pIter ) ) );
Reference< XPropertySet > xCurrentCol = xColFactory->createColumn(aCurrentModelType);
Reference< XPropertySetInfo > xColumnPropertyInfo = xCurrentCol->getPropertySetInfo();
// calculate the default
Any aDefault;
sal_Bool bDefault = xColumnPropertyInfo->hasPropertyByName(PROPERTY_CONTROLDEFAULT);
if ( bDefault )
aDefault = xColumn->getPropertyValue(PROPERTY_CONTROLDEFAULT);
// default value
if ( nType == DataType::BIT || nType == DataType::BOOLEAN )
{
if(bDefault && 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( sPropertyName, aDefault ) );
// transfer properties from the definition to the UNO-model :
aCopyProperties.push_back( PROPERTY_HIDDEN );
aCopyProperties.push_back( PROPERTY_WIDTH );
Any aDescription; aDescription <<= ::rtl::OUString();
if ( xColumn->getPropertySetInfo()->hasPropertyByName( PROPERTY_HELPTEXT ) )
aDescription <<= ::comphelper::getString( xColumn->getPropertyValue( PROPERTY_HELPTEXT ) );
aInitialValues.push_back( NamedValue( PROPERTY_HELPTEXT, aDescription ) );
// ... horizontal justify
aInitialValues.push_back( NamedValue( PROPERTY_ALIGN, makeAny( sal_Int16( ::comphelper::getINT32( xColumn->getPropertyValue( PROPERTY_ALIGN ) ) ) ) ) );
// now set all those values
for ( ::std::vector< NamedValue >::const_iterator property = aInitialValues.begin();
property != aInitialValues.end();
++property
)
{
xCurrentCol->setPropertyValue( property->Name, property->Value );
}
for ( ::std::vector< ::rtl::OUString >::const_iterator copyPropertyName = aCopyProperties.begin();
copyPropertyName != aCopyProperties.end();
++copyPropertyName
)
xCurrentCol->setPropertyValue( *copyPropertyName, xColumn->getPropertyValue( *copyPropertyName ) );
xColContainer->insertByName(*pIter, makeAny(xCurrentCol));
}
}
}
catch(Exception&)
{
DBG_ERROR("SbaTableQueryBrowser::InitializeGridModel : something went wrong !");
return sal_False;
}
return sal_True;
}
// -----------------------------------------------------------------------------
Reference<XPropertySet> getColumnHelper(SvLBoxEntry* _pCurrentlyDisplayed,const Reference<XPropertySet>& _rxSource)
{
Reference<XPropertySet> xRet;
if(_pCurrentlyDisplayed)
{
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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))
::cppu::extractInterface(xRet,xNames->getByName(aName));
}
return xRet;
}
// -----------------------------------------------------------------------
void SbaTableQueryBrowser::transferChangedControlProperty(const ::rtl::OUString& _rProperty, const Any& _rNewValue)
{
if(m_pCurrentlyDisplayed)
{
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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(Exception&)
{
OSL_ENSURE(sal_False, "SbaTableQueryBrowser::propertyChange: caught an 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)
{
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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(Exception&)
{
DBG_ERROR("SbaTableQueryBrowser::propertyChange: caught an exception!");
}
}
// -----------------------------------------------------------------------
sal_Bool SbaTableQueryBrowser::suspend(sal_Bool bSuspend) throw( RuntimeException )
{
vos::OGuard aSolarGuard( Application::GetSolarMutex() );
::osl::MutexGuard aGuard(m_aMutex);
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);
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
{
DBTreeListModel::DBTreeListUserData* pData = static_cast< DBTreeListModel::DBTreeListUserData* >( _pEntry->GetUserData() );
return ( !pData || ( pData->sAccessor == sId ) );
}
}
// -------------------------------------------------------------------------
String SbaTableQueryBrowser::getDataSourceAcessor( SvLBoxEntry* _pDataSourceEntry ) const
{
DBG_ASSERT( _pDataSourceEntry, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry!" );
DBTreeListModel::DBTreeListUserData* pData = static_cast< DBTreeListModel::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 && m_pTreeView->getListBox())
{
// 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
Image a, b, c; // not interested in reusing them
String e, f;
implAddDatasource( _rDataSource, a, e, b, f, c, _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
pObject = m_pTreeView->getListBox()->GetEntryPosByName(_rCommand, pCommandType);
}
}
}
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(m_xCurrentFrame, 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(Exception&)
{
OSL_ENSURE( 0, "SbaTableQueryBrowser::connectExternalDispatches: caught an exception while attaching a status listener!!" );
}
}
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();
++aLoop
)
{
if ( aLoop->second.xDispatcher.get() == xSource.get() )
{
ExternalFeaturesMap::iterator aPrevious = aLoop;
--aPrevious;
// remove it
m_aExternalFeatures.erase( aLoop );
// maybe update the UI
implCheckExternalSlot(aLoop->first);
// continue, the same XDispatch may be resposible for more than one URL
aLoop = aPrevious;
}
}
}
else
{
Reference<XConnection> xCon(_rSource.Source, UNO_QUERY);
if ( xCon.is() && m_pTreeView && m_pTreeView->getListBox() )
{ // 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)
{
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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&)
{
OSL_ENSURE(sal_False, "SbaTableQueryBrowser::getSelection: caught an exception while retrieving the selection!");
}
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);
if(m_xCurrentFrame.is())
{
m_xCurrentFrameParent = m_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< XLayoutManager > xLayouter;
Reference< XPropertySet > xFrameProps( m_xCurrentFrame, UNO_QUERY );
if ( xFrameProps.is() )
xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ) >>= xLayouter;
if ( xLayouter.is() )
{
Reference< XUIElement > xUI;
try
{
xUI = xLayouter->getElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ) ) );
if ( !xUI.is() )
xUI = xLayouter->getElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/browserobjectbar" ) ) );
}
catch( const Exception& )
{ // nii
if ( !xUI.is() )
xUI = xLayouter->getElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/browserobjectbar" ) ) );
}
if ( xUI.is() )
{
m_xMainToolbar = m_xMainToolbar.query( xUI->getRealInterface() );
OSL_ENSURE( m_xMainToolbar.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" );
}
}
}
catch( const Exception& )
{
OSL_ENSURE( sal_False, "SbaTableQueryBrowser::attachFrame: caught an 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
::com::sun::star::lang::EventObject aEvt(*this);
::cppu::OInterfaceIteratorHelper aIter(m_aSelectionListeners);
while (aIter.hasMoreElements())
static_cast< XSelectionChangeListener* >(aIter.next())->selectionChanged(aEvt);
}
//------------------------------------------------------------------------------
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_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:
{ // this slot is available even if no form is loaded
aReturn.bEnabled = m_bEnableBrowser;
aReturn.bChecked = haveExplorer();
return aReturn;
}
case ID_BROWSER_REMOVEFILTER:
aReturn = SbaXDataBrowserController::GetState(nId);
return aReturn;
}
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;
// no chance while loading the form
if (PendingLoad())
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_COMMANDTYPE));
aReturn.bEnabled = aReturn.bEnabled && ((::comphelper::getBOOL(xDataSource->getPropertyValue(PROPERTY_USE_ESCAPE_PROCESSING)) || (nType == ::com::sun::star::sdb::CommandType::QUERY)));
}
}
catch(DisposedException&)
{
OSL_ENSURE(sal_False, "SbaTableQueryBrowser::GetState: object already disposed!");
}
catch(Exception&)
{
OSL_ENSURE(sal_False, "SbaTableQueryBrowser::GetState: caught a strange exception!!");
}
}
break;
case ID_BROWSER_TITLE:
{
Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
sal_Int32 nCommandType = CommandType::TABLE;
xProp->getPropertyValue(PROPERTY_COMMANDTYPE) >>= 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:
if(m_pTreeView->HasChildPathFocus())
aReturn.bEnabled = isEntryCopyAllowed(m_pTreeView->getListBox()->GetCurEntry());
else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing())
{
SbaGridControl* pControl = getBrowserView()->getVclControl();
aReturn.bEnabled = pControl->canCopyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
}
else
return SbaXDataBrowserController::GetState(nId);
break;
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)
{
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)
OnSelectEntry( 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_COMMANDTYPE);
aDescriptor[daConnection] = xProp->getPropertyValue(PROPERTY_ACTIVECONNECTION);
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(Exception&)
{
DBG_ERROR("SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not dispatch the slot (caught an 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())
{
SbaGridControl* pControl = getBrowserView()->getVclControl();
pControl->copyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
}
else
SbaXDataBrowserController::Execute(nId,aArgs);
break;
default:
SbaXDataBrowserController::Execute(nId,aArgs);
break;
}
}
// -------------------------------------------------------------------------
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 );
DBTreeListModel::DBTreeListUserData* pDSData = new DBTreeListModel::DBTreeListUserData;
pDSData->eType = etDatasource;
pDSData->sAccessor = sDataSourceId;
pDSData->xConnection = _rxConnection;
if ( _rxConnection.is() )
pDSData->aController = ModelControllerConnector( impl_nf_getDBDocumentForConnection( _rxConnection ), this );
pDatasourceEntry->SetUserData(pDSData);
// the child for the queries container
{
SvLBoxEntry* pQueries = m_pTreeView->getListBox()->InsertEntry(_rQueryName, _rQueryImage, _rQueryImage, pDatasourceEntry, sal_True);
DBTreeListModel::DBTreeListUserData* pQueriesData = new DBTreeListModel::DBTreeListUserData;
pQueriesData->eType = etQueryContainer;
pQueries->SetUserData(pQueriesData);
}
// the child for the tables container
{
SvLBoxEntry* pTables = m_pTreeView->getListBox()->InsertEntry(_rTableName, _rTableImage, _rTableImage, pDatasourceEntry, sal_True);
DBTreeListModel::DBTreeListUserData* pTablesData = new DBTreeListModel::DBTreeListUserData;
pTablesData->eType = etTableContainer;
pTables->SetUserData(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() );
}
}
// -------------------------------------------------------------------------
sal_Bool SbaTableQueryBrowser::populateTree(const Reference<XNameAccess>& _xNameAccess,
SvLBoxEntry* _pParent,
EntryType _eEntryType)
{
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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))
{
DBTreeListModel::DBTreeListUserData* pEntryData = new DBTreeListModel::DBTreeListUserData;
pEntryData->eType = _eEntryType;
implAppendEntry( _pParent, *pIter, pEntryData, _eEntryType );
}
}
}
catch(Exception&)
{
DBG_ERROR("SbaTableQueryBrowser::populateTree: could not fill the tree");
return sal_False;
}
return sal_True;
}
//------------------------------------------------------------------------------
void SbaTableQueryBrowser::implAppendEntry( SvLBoxEntry* _pParent, const String& _rName, void* _pUserData, EntryType _eEntryType )
{
::std::auto_ptr< ImageProvider > pImageProvider( getImageProviderFor( _pParent ) );
Image aImage( pImageProvider->getImage( _rName, getDatabaseObjectType( _eEntryType ), false ) );
Image aImageHC( pImageProvider->getImage( _rName, getDatabaseObjectType( _eEntryType ), true ) );
SvLBoxEntry* pNewEntry = m_pTreeView->getListBox()->InsertEntry( _rName, _pParent, sal_False, 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 );
}
//------------------------------------------------------------------------------
IMPL_LINK(SbaTableQueryBrowser, OnExpandEntry, SvLBoxEntry*, _pParent)
{
if (_pParent->HasChilds())
// nothing to to ...
return 1L;
::osl::MutexGuard aGuard(m_aEntryMutex);
SvLBoxEntry* pFirstParent = m_pTreeView->getListBox()->GetRootLevelParent(_pParent);
OSL_ENSURE(pFirstParent,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!");
DBTreeListModel::DBTreeListUserData* pData = static_cast< DBTreeListModel::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&)
{
OSL_ENSURE(sal_False, "SbaTableQueryBrowser, OnExpandEntry: caught an unknown exception while populating the tables!");
}
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))
{
DBTreeListModel::DBTreeListUserData* pParentData = static_cast< DBTreeListModel::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
DBTreeListModel::DBTreeListUserData* pEntryData = static_cast<DBTreeListModel::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;
}
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(Exception&)
{
DBG_ERROR("SbaTableQueryBrowser::ensureEntryObject: caught an exception while retrieving the queries container!");
}
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)
{
Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
if(xProp.is())
{
Reference< ::com::sun::star::form::XLoadable > xLoadable(xProp,UNO_QUERY);
try
{
// the values allowing the RowSet to re-execute
xProp->setPropertyValue(PROPERTY_DATASOURCENAME, makeAny(_rDataSourceName));
if(_rxConnection.is())
xProp->setPropertyValue( PROPERTY_ACTIVECONNECTION, makeAny( _rxConnection.getTyped() ) );
// set this _before_ setting the connection, else the rowset would rebuild it ...
xProp->setPropertyValue(PROPERTY_COMMANDTYPE, makeAny(_nCommandType));
xProp->setPropertyValue(PROPERTY_COMMAND, makeAny(_rCommand));
xProp->setPropertyValue(PROPERTY_USE_ESCAPE_PROCESSING, ::cppu::bool2any(_bEscapeProcessing));
if ( m_bPreview )
{
// this be undone by the grid control in DbGridControl::RecalcRows
// xProp->setPropertyValue(PROPERTY_FETCHSIZE, makeAny(sal_Int32(20)));
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(getRowSet());
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());
if ( m_bPreview )
initializePreviewMode();
LoadFinished(sal_True);
}
InvalidateAll();
return bSuccess;
}
catch(SQLException& e)
{
showError(SQLExceptionInfo(e));
}
catch(WrappedTargetException& e)
{
SQLException aSql;
if(e.TargetException >>= aSql)
showError(SQLExceptionInfo(aSql));
else
OSL_ENSURE(sal_False, "SbaTableQueryBrowser::implLoadAnything: something strange happended!");
}
catch(Exception&)
{
OSL_ENSURE(sal_False, "SbaTableQueryBrowser::implLoadAnything: something strange happended!");
}
}
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 (pDataSource) // OJ change for the new app
{
if (pCommand)
{
if ( _bSelectDirect )
{
OnSelectEntry(pCommand);
}
else
m_pTreeView->getListBox()->Select(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, OnSelectEntry, SvLBoxEntry*, _pEntry)
{
::osl::MutexGuard aGuard(m_aEntryMutex);
DBTreeListModel::DBTreeListUserData* pEntryData = static_cast<DBTreeListModel::DBTreeListUserData*>(_pEntry->GetUserData());
switch (pEntryData->eType)
{
case etTableOrView:
case etQuery:
break;
default:
// nothing to do
return 0L;
}
OSL_ENSURE(m_pTreeModel->HasParent(_pEntry), "SbaTableQueryBrowser::OnSelectEntry: invalid entry (1)!");
OSL_ENSURE(m_pTreeModel->HasParent(m_pTreeModel->GetParent(_pEntry)), "SbaTableQueryBrowser::OnSelectEntry: invalid entry (2)!");
// get the entry for the tables or queries
SvLBoxEntry* pContainer = m_pTreeModel->GetParent(_pEntry);
DBTreeListModel::DBTreeListUserData* pContainerData = static_cast<DBTreeListModel::DBTreeListUserData*>(pContainer->GetUserData());
// get the entry for the datasource
SvLBoxEntry* pConnection = m_pTreeModel->GetParent(pContainer);
DBTreeListModel::DBTreeListUserData* pConData = static_cast<DBTreeListModel::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_COMMANDTYPE) >>= nOldType;
Reference<XConnection> xOldConnection;
::cppu::extractInterface(xOldConnection,xRowSetProps->getPropertyValue(PROPERTY_ACTIVECONNECTION));
// 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!");
::rtl::OUString aName(pString->GetText().GetBuffer());
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();
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 0L;
}
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:
{
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);
if(xNameAccess.is() && xNameAccess->hasByName(aName))
{
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::DBTreeListUserData*>(_pEntry->GetUserData());
if ( !pData->xObjectProperties.is() )
{
Reference<XInterface> xObject;
if(xNameAccess->getByName(aName) >>= 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 ( m_bPreview && nCommandType == CommandType::QUERY && xObject.is() )
{
::rtl::OUString sSql;
Reference<XPropertySet> xObjectProps(xObject,UNO_QUERY);
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&)
{
}
}
}
}
}
}
String sDataSourceName( getDataSourceAcessor( pConnection ) );
if ( implLoadAnything( sDataSourceName, aName, nCommandType, sal_True, pConData->xConnection ) )
// set the title of the beamer
updateTitle();
else
{ // clean up
criticalFail();
}
}
catch(const SQLException& e)
{
showError(SQLExceptionInfo(e));
// reset the values
xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
xRowSetProps->setPropertyValue(PROPERTY_ACTIVECONNECTION,Any());
}
catch(WrappedTargetException& e)
{
SQLException aSql;
if(e.TargetException >>= aSql)
showError(SQLExceptionInfo(aSql));
else
OSL_ENSURE(sal_False, "SbaTableQueryBrowser::OnSelectEntry: something strange happended!");
// reset the values
xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
xRowSetProps->setPropertyValue(PROPERTY_ACTIVECONNECTION,Any());
}
catch(Exception&)
{
// reset the values
xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
xRowSetProps->setPropertyValue(PROPERTY_ACTIVECONNECTION,Any());
}
}
return 0L;
}
// -----------------------------------------------------------------------------
SvLBoxEntry* SbaTableQueryBrowser::getEntryFromContainer(const Reference<XNameAccess>& _rxNameAccess)
{
DBTreeListBox* pListBox = m_pTreeView->getListBox();
SvLBoxEntry* pContainer = NULL;
if ( pListBox )
{
SvLBoxEntry* pDSLoop = pListBox->FirstChild(NULL);
while (pDSLoop)
{
pContainer = pListBox->GetEntry(pDSLoop, CONTAINER_QUERIES);
DBTreeListModel::DBTreeListUserData* pQueriesData = static_cast<DBTreeListModel::DBTreeListUserData*>(pContainer->GetUserData());
if ( pQueriesData && pQueriesData->xContainer == _rxNameAccess )
break;
pContainer = pListBox->GetEntry(pDSLoop, CONTAINER_TABLES);
DBTreeListModel::DBTreeListUserData* pTablesData = static_cast<DBTreeListModel::DBTreeListUserData*>(pContainer->GetUserData());
if ( pTablesData && pTablesData->xContainer == _rxNameAccess )
break;
pDSLoop = pListBox->NextSibling(pDSLoop);
pContainer = NULL;
}
}
return pContainer;
}
// -------------------------------------------------------------------------
void SAL_CALL SbaTableQueryBrowser::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException)
{
vos::OGuard aSolarGuard( Application::GetSolarMutex() );
::osl::MutexGuard aGuard(m_aEntryMutex);
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
DBTreeListModel::DBTreeListUserData* pContainerData = static_cast<DBTreeListModel::DBTreeListUserData*>(pEntry->GetUserData());
OSL_ENSURE(pContainerData, "elementInserted: There must be user data for this type!");
DBTreeListModel::DBTreeListUserData* pNewData = new DBTreeListModel::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 if (xNames.get() == m_xDatabaseContext.get())
{ // a new datasource has been added to the context
// the name of the new ds
::rtl::OUString sNewDS;
_rEvent.Accessor >>= sNewDS;
// add new entries to the list box model
Image a, b, c; // not interested in reusing them
String e, f;
implAddDatasource( sNewDS, a, e, b, f, c, SharedConnection() );
}
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());
::osl::MutexGuard aGuard(m_aEntryMutex);
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
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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)
{
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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 if (xNames.get() == m_xDatabaseContext.get())
{ // a datasource has been removed from the context
// the name
::rtl::OUString sNewDS;
_rEvent.Accessor >>= sNewDS;
String sNewDatasource = sNewDS;
// get the top-level representing the removed data source
SvLBoxEntry* pDSLoop = m_pTreeView->getListBox()->FirstChild(NULL);
while (pDSLoop)
{
if (m_pTreeView->getListBox()->GetEntryText(pDSLoop) == sNewDatasource)
break;
pDSLoop = m_pTreeView->getListBox()->NextSibling(pDSLoop);
}
if (pDSLoop)
{
if (isSelected(pDSLoop))
{ // a table or query belonging to the deleted data source is currently beeing displayed.
OSL_ENSURE(m_pTreeView->getListBox()->GetRootLevelParent(m_pCurrentlyDisplayed) == pDSLoop, "SbaTableQueryBrowser::elementRemoved: inconsistence (1)!");
unloadAndCleanup( sal_True );
}
else
OSL_ENSURE(
(NULL == m_pCurrentlyDisplayed)
|| (m_pTreeView->getListBox()->GetRootLevelParent(m_pCurrentlyDisplayed) != pDSLoop), "SbaTableQueryBrowser::elementRemoved: inconsistence (2)!");
// look for user data to delete
SvTreeEntryList* pList = m_pTreeModel->GetChildList(pDSLoop);
if(pList)
{
SvLBoxEntry* pEntryLoop = static_cast<SvLBoxEntry*>(pList->First());
while (pEntryLoop)
{
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::DBTreeListUserData*>(pEntryLoop->GetUserData());
pEntryLoop->SetUserData(NULL);
delete pData;
pEntryLoop = static_cast<SvLBoxEntry*>(pList->Next());
}
}
// remove the entry. This should remove all children, too.
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::DBTreeListUserData*>(pDSLoop->GetUserData());
pDSLoop->SetUserData(NULL);
delete pData;
m_pTreeModel->Remove(pDSLoop);
}
else
DBG_ERROR("SbaTableQueryBrowser::elementRemoved: unknown datasource name!");
// 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)
{
::osl::MutexGuard aGuard(m_aEntryMutex);
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
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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)
{
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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 )
{
DBTreeListModel::DBTreeListUserData* pTreeListData = static_cast< DBTreeListModel::DBTreeListUserData* >( _pDSEntry->GetUserData() );
if ( pTreeListData )
{
DBG_ASSERT( !pTreeListData->xConnection.is() == !!pTreeListData->aController.empty(),
"SbaTableQueryBrowser::disposeConnection: inconsistency: there should either be a connection and a controller, or none of both!" );
impl_releaseConnection( pTreeListData->xConnection );
pTreeListData->aController.clear();
}
}
}
// -------------------------------------------------------------------------
void SbaTableQueryBrowser::closeConnection(SvLBoxEntry* _pDSEntry,sal_Bool _bDisposeConnection)
{
DBG_ASSERT(_pDSEntry, "SbaTableQueryBrowser::closeConnection: invalid entry (NULL)!");
OSL_ENSURE( 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);
DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::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_ACTIVECONNECTION) >>= xConn;
#if OSL_DEBUG_LEVEL > 1
{
Reference< XComponent > xComp;
::cppu::extractInterface(xComp, xRowSetProps->getPropertyValue(PROPERTY_ACTIVECONNECTION));
}
#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");
}
// set a default title
setDefaultTitle();
}
// -------------------------------------------------------------------------
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() );
if ( !rArguments.getIfExists_ensureType( (::rtl::OUString)PROPERTY_DATASOURCENAME, sInitialDataSourceName ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for DataSourceName.")),*this);
if ( !rArguments.getIfExists_ensureType( (::rtl::OUString)PROPERTY_COMMANDTYPE, nInitialDisplayCommandType ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for CommandType.")),*this);
if ( !rArguments.getIfExists_ensureType( (::rtl::OUString)PROPERTY_COMMAND, sInitialCommand ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for Command.")),*this);
if ( !rArguments.getIfExists_ensureType( (::rtl::OUString)PROPERTY_ACTIVECONNECTION, xForeignConnection ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for ActiveConnection.")),*this);
if ( !rArguments.getIfExists_ensureType( (::rtl::OUString)PROPERTY_UPDATE_CATALOGNAME, aCatalogName ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for UpdateCatalogName.")),*this);
if ( !rArguments.getIfExists_ensureType( (::rtl::OUString)PROPERTY_UPDATE_SCHEMANAME, aSchemaName ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for UpdateSchemaName.")),*this);
if ( !rArguments.getIfExists_ensureType( (::rtl::OUString)PROPERTY_UPDATE_TABLENAME, aTableName ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for UpdateTableName.")),*this);
if ( !rArguments.getIfExists_ensureType( (::rtl::OUString)PROPERTY_USE_ESCAPE_PROCESSING, bEsacpeProcessing ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for EscapeProcessing.")),*this);
if ( !rArguments.getIfExists_ensureType( "Frame", xFrame ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for Frame.")),*this);
if ( !rArguments.getIfExists_ensureType( (::rtl::OUString)PROPERTY_SHOWMENU, m_bShowMenu ) )
throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid argument type for ShowMenu.")),*this);
sal_Bool bShowTreeView = rArguments.getOrDefault( (::rtl::OUString)PROPERTY_SHOWTREEVIEW, sal_True );
m_bEnableBrowser = rArguments.getOrDefault( (::rtl::OUString)PROPERTY_SHOWTREEVIEWBUTTON, sal_True );
if ( bShowTreeView )
showExplorer();
else
hideExplorer();
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'!??" );
}
}
}
}
Image aDBImage, aQueriesImage, aTablesImage;
String sQueriesName, sTablesName;
implAddDatasource( sInitialDataSourceName,
aDBImage, sQueriesName, aQueriesImage, sTablesName, aTablesImage, xConnection
);
m_pTreeView->getListBox()->Expand( m_pTreeView->getListBox()->First() );
}
else
initializeTreeModel();
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::initialize: could not set the update related names!");
}
}
else
{
// set a default title
setDefaultTitle();
}
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);
DBTreeListModel::DBTreeListUserData* pDSData =
pDSEntry
? static_cast<DBTreeListModel::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 );
DBTreeListModel::DBTreeListUserData* pDSData =
pDSEntry
? static_cast< DBTreeListModel::DBTreeListUserData* >( pDSEntry->GetUserData() )
: NULL;
if ( pDSData )
_rConnection = pDSData->xConnection;
return _rConnection.is();
}
// -----------------------------------------------------------------------------
bool SbaTableQueryBrowser::impl_isDataSourceEntry( SvLBoxEntry* _pEntry ) const
{
return m_pTreeModel->GetRootLevelParent( _pEntry ) == _pEntry;
}
// -------------------------------------------------------------------------
Reference< XModel > SbaTableQueryBrowser::impl_nf_getDBDocumentForConnection( const Reference< XConnection >& _rxConnection )
{
Reference< XModel > xModel;
try
{
Reference< XChild > xChild( _rxConnection, UNO_QUERY_THROW );
Reference< XDocumentDataSource > xDS( xChild->getParent(), UNO_QUERY_THROW );
xModel = Reference< XModel >( xDS->getDatabaseDocument(), UNO_QUERY_THROW );
}
catch( const Exception& )
{
OSL_ENSURE( sal_False, "SbaTableQueryBrowser::impl_nf_getDBDocumentForConnection: caught an exception!" );
}
return xModel;
}
// -----------------------------------------------------------------------------
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)
{
DBTreeListModel::DBTreeListUserData* pTreeListData = static_cast<DBTreeListModel::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, rtl::OUString(), sal_True ),
SharedConnection::TakeOwnership
);
if ( _rConnection.is() )
{
DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::ensureConnection: this is no data source entry!" );
// if this fails, we can't expect pTreeListData->aController to point to a valid
// instance, since those instances are only filled for data source entries
pTreeListData->aController = ModelControllerConnector( impl_nf_getDBDocumentForConnection( _rConnection ), this );
}
// 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;
return eLeft < eRight
? COMPARE_LESS
: eLeft == eRight
? COMPARE_EQUAL
: COMPARE_GREATER;
}
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::implDirectSQL( SvLBoxEntry* _pApplyTo )
{
try
{
SharedConnection xConnection;
if(!ensureConnection(_pApplyTo, xConnection))
return;
DirectSQLDialog aDlg(getView(), xConnection);
aDlg.Execute();
}
catch(const SQLException& e)
{
showError(SQLExceptionInfo(e));
}
catch(const WrappedTargetException& e)
{
SQLException aSql;
if(e.TargetException >>= aSql)
showError(SQLExceptionInfo(aSql));
else
OSL_ENSURE(sal_False, "SbaTableQueryBrowser::implDirectSQL: something strange happended!");
}
catch(const Exception&)
{
DBG_ERROR("SbaTableQueryBrowser::implDirectSQL: caught an (unknown) exception!");
}
}
// -----------------------------------------------------------------------------
void SbaTableQueryBrowser::implAdministrate( SvLBoxEntry* _pApplyTo )
{
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< XModel > xDocumentModel(
getDataSourceOrModel(getDataSourceByName_displayError( m_xDatabaseContext, sInitialSelection, getView(), getORB(), true )),UNO_QUERY);
if ( xDocumentModel.is() )
{
Sequence<PropertyValue > aArgs(1);
aArgs[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Model"));
aArgs[0].Value <<= xDocumentModel;
xFrameLoader->loadComponentFromURL(
xDocumentModel->getURL(),
::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_default")),
nFrameSearchFlag,
aArgs
);
}
}
}
catch(::com::sun::star::uno::Exception&)
{
DBG_ERROR("SbaTableQueryBrowser::implAdministrate: caught an exception while creating/executing the dialog!");
}
}
// -----------------------------------------------------------------------------
sal_Bool SbaTableQueryBrowser::requestQuickHelp( const SvLBoxEntry* _pEntry, String& _rText ) const
{
const DBTreeListModel::DBTreeListUserData* pData = static_cast< const DBTreeListModel::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;
}
// -----------------------------------------------------------------------------
sal_Bool SbaTableQueryBrowser::requestContextMenu( const CommandEvent& _rEvent )
{
::Point aPosition;
SvLBoxEntry* pEntry = NULL;
SvLBoxEntry* pOldSelection = NULL;
if (_rEvent.IsMouseEvent())
{
aPosition = _rEvent.GetMousePosPixel();
// ensure that the entry which the user clicked at is selected
pEntry = m_pTreeView->getListBox()->GetEntry(aPosition);
if (pEntry && !m_pTreeView->getListBox()->IsSelected(pEntry))
{
pOldSelection = m_pTreeView->getListBox()->FirstSelected();
m_pTreeView->getListBox()->lockAutoSelect();
m_pTreeView->getListBox()->Select(pEntry);
m_pTreeView->getListBox()->unlockAutoSelect();
}
}
else
{
// use the center of the current entry
pEntry = m_pTreeView->getListBox()->GetCurEntry();
OSL_ENSURE(pEntry,"No current entry!");
aPosition = m_pTreeView->getListBox()->GetEntryPosition(pEntry);
aPosition.X() += m_pTreeView->getListBox()->GetOutputSizePixel().Width() / 2;
aPosition.Y() += m_pTreeView->getListBox()->GetEntryHeight() / 2;
}
// disable entries according to the currently selected entry
// does the datasource which the selected entry belongs to has an open connection ?
SvLBoxEntry* pDSEntry = NULL;
DBTreeListModel::DBTreeListUserData* pDSData = NULL;
DBTreeListModel::DBTreeListUserData* pEntryData = NULL;
if(pEntry)
{
pDSEntry = m_pTreeView->getListBox()->GetRootLevelParent(pEntry);
pDSData = pDSEntry
? static_cast<DBTreeListModel::DBTreeListUserData*>(pDSEntry->GetUserData())
: NULL;
pEntryData = static_cast<DBTreeListModel::DBTreeListUserData*>(pEntry->GetUserData());
}
EntryType eType = pEntryData ? pEntryData->eType : etUnknown;
ModuleRes nMenuRes( MENU_BROWSER_DEFAULTCONTEXT );
PopupMenu aContextMenu( nMenuRes );
PopupMenu* pDynamicSubMenu = NULL;
// enable menu entries
if (!pDSData || !pDSData->xConnection.is())
{ // no -> disable the connection-related menu entries
aContextMenu.EnableItem(ID_TREE_CLOSE_CONN, sal_False);
aContextMenu.EnableItem(ID_TREE_REBUILD_CONN, sal_False);
}
aContextMenu.EnableItem(SID_COPY, sal_False);
if ( pEntry )
{
switch (eType)
{
// 1. for tables/views
case etTableContainer:
case etTableOrView:
{
aContextMenu.EnableItem( SID_COPY, etTableOrView == eType );
}
break;
// 3. for queries
case etQueryContainer:
case etQuery:
{
// 3.2 actions on existing queries
aContextMenu.EnableItem(SID_COPY, etQuery == eType);
}
break;
case etDatasource:
case etUnknown:
break;
}
}
// rebuild conn not implemented yet
aContextMenu.EnableItem(ID_TREE_REBUILD_CONN, sal_False);
if (!m_xMultiServiceFacatory.is())
// no ORB -> no administration dialog
aContextMenu.EnableItem(ID_TREE_EDIT_DATABASE, sal_False);
// no disabled entries
aContextMenu.RemoveDisabledEntries();
sal_Bool bReopenConn = sal_False;
USHORT nPos = aContextMenu.Execute(m_pTreeView->getListBox(), aPosition);
delete pDynamicSubMenu;
pDynamicSubMenu = NULL;
// restore the old selection
if (pOldSelection)
{
m_pTreeView->getListBox()->lockAutoSelect();
m_pTreeView->getListBox()->Select(pOldSelection);
m_pTreeView->getListBox()->unlockAutoSelect();
}
switch (nPos)
{
case ID_TREE_EDIT_DATABASE:
implAdministrate(pEntry);
break;
case ID_DIRECT_SQL:
implDirectSQL(pEntry);
break;
case ID_TREE_REBUILD_CONN:
bReopenConn = sal_True;
case ID_TREE_CLOSE_CONN:
openHelpAgent(HID_DSBROWSER_DISCONNECTING);
closeConnection(pDSEntry);
break;
case SID_COPY:
{
TransferableHelper* pTransfer = implCopyObject( pEntry, (etQuery == eType) ? CommandType::QUERY : CommandType::TABLE );
Reference< XTransferable> aEnsureDelete = pTransfer;
if (pTransfer)
pTransfer->CopyToClipboard(getView());
}
break;
case ID_TREE_ADMINISTRATE:
::svx::administrateDatabaseRegistration( getView() );
break;
}
return sal_True; // handled
}
// -----------------------------------------------------------------------------
void SbaTableQueryBrowser::setDefaultTitle()
{
::rtl::OUString sTitle = String(ModuleRes(STR_DSBROWSER_TITLE));
setTitle(sTitle);
}
// -----------------------------------------------------------------------------
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_USE_ESCAPE_PROCESSING ) );
return sal_True;
}
}
catch( const Exception& )
{
OSL_ENSURE( sal_False, "SbaTableQueryBrowser::implGetQuerySignature: caught an 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()->GetBackground().GetColor().IsDark();
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/browserobjectbar" )));
xLayoutManager->unlock();
xLayoutManager->doLayout();
}
onLoadedMenu( xLayoutManager );
}
}
// -----------------------------------------------------------------------------
void SbaTableQueryBrowser::updateTitle()
{
if ( m_pCurrentlyDisplayed )
{
SvLBoxEntry* pContainer = m_pTreeModel->GetParent(m_pCurrentlyDisplayed);
// get the entry for the datasource
SvLBoxEntry* pConnection = m_pTreeModel->GetParent(pContainer);
::rtl::OUString sName = m_pTreeView->getListBox()->GetEntryText(m_pCurrentlyDisplayed);
::rtl::OUString 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())
{
sTitle += ::rtl::OUString::createFromAscii(": ");
sTitle += sName;
}
setTitle(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();
}
// .........................................................................
} // namespace dbaui
// .........................................................................