/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _SFX_DOCFILT_HACK_HXX
#include <sfx2/docfilt.hxx>
#endif
#ifndef _DBACCESS_UI_CALLBACKS_HXX_
#include "callbacks.hxx"
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _DBU_RESOURCE_HRC_
#include "dbu_resource.hrc"
#endif
#ifndef DBAUI_DLGSAVE_HXX
#include "dlgsave.hxx"
#endif
#ifndef DBAUI_DBTREELISTBOX_HXX
#include "dbtreelistbox.hxx"
#endif
#ifndef DBACCESS_SOURCE_UI_INC_DEFAULTOBJECTNAMECHECK_HXX
#include "defaultobjectnamecheck.hxx"
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _COM_SUN_STAR_SDB_XSINGLESELECTQUERYANALYZER_HPP_
#include <com/sun/star/sdb/XSingleSelectQueryAnalyzer.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XCOMPLETEDCONNECTION_HPP_
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
#include <com/sun/star/sdbc/XDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
#include <com/sun/star/sdb/SQLContext.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XVIEWSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XDATADESCRIPTORFACTORY_HPP_
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XAPPEND_HPP_
#include <com/sun/star/sdbcx/XAppend.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATA_HPP_
#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
#endif
#include <com/sun/star/sdbc/ColumnValue.hpp>
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
#include <com/sun/star/task/XInteractionHandler.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENT_HPP_
#include <com/sun/star/ucb/XContent.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_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIOEXCEPTION_HPP_
#include <com/sun/star/ucb/InteractiveIOException.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XDOCUMENTDATASOURCE_HPP_
#include <com/sun/star/sdb/XDocumentDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_IOERRORCODE_HPP_
#include <com/sun/star/ucb/IOErrorCode.hpp>
#endif
#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif
#ifndef _TOOLKIT_AWT_VCLXWINDOW_HXX_
#include <toolkit/awt/vclxwindow.hxx>
#endif
#ifndef _VCL_STDTEXT_HXX
#include <vcl/stdtext.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HPP_
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XCONTAINER_HPP_
#include <com/sun/star/container/XContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMECONTAINER_HPP_
#include <com/sun/star/container/XHierarchicalNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_TEXTALIGN_HPP_
#include <com/sun/star/awt/TextAlign.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_FONTDESCRIPTOR_HPP_
#include <com/sun/star/awt/FontDescriptor.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_FONTWEIGHT_HPP_
#include <com/sun/star/awt/FontWeight.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_FONTRELIEF_HPP_
#include <com/sun/star/awt/FontRelief.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_FONTWIDTH_HPP_
#include <com/sun/star/awt/FontWidth.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef DBAUI_SBATTRDLG_HRC
#include "dlgattr.hrc"
#endif
#ifndef DBAUI_TYPEINFO_HXX
#include "TypeInfo.hxx"
#endif
#ifndef DBAUI_FIELDDESCRIPTIONS_HXX
#include "FieldDescriptions.hxx"
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef COMPHELPER_COMPONENTCONTEXT_HXX
#include <comphelper/componentcontext.hxx>
#endif

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif

#define ITEMID_HORJUSTIFY		SID_ATTR_ALIGN_HOR_JUSTIFY
#define ITEMID_VERJUSTIFY		SID_ATTR_ALIGN_VER_JUSTIFY
//#define ITEMID_ORIENTATION     SID_ATTR_ALIGN_ORIENTATION
#define ITEMID_LINEBREAK		SID_ATTR_ALIGN_LINEBREAK
#define ITEMID_MARGIN			SID_ATTR_ALIGN_MARGIN
#define ITEMID_NUMBERINFO		SID_ATTR_NUMBERFORMAT_INFO

#ifndef _SFXITEMPOOL_HXX
#include <svl/itempool.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _DBA_DBACCESS_HELPID_HRC_
#include "dbaccess_helpid.hrc"
#endif
#ifndef _SFXITEMSET_HXX //autogen wg. SfxItemSet
#include <svl/itemset.hxx>
#endif
#ifndef DBACCESS_SBA_GRID_HRC
#include "sbagrid.hrc"
#endif
#ifndef _SFXRNGITEM_HXX
#include <svl/rngitem.hxx>
#endif
#ifndef _SFXINTITEM_HXX
#include <svl/intitem.hxx>
#endif
#ifndef _SVX_ALGITEM_HXX
#include <svx/algitem.hxx>
#endif
#ifndef _SVX_NUMINF_HXX
#include <svx/numinf.hxx>
#endif
#define _ZFORLIST_DECLARE_TABLE
#ifndef _SVX_NUMINF_HXX
#include <svx/numinf.hxx>
#endif
#ifndef _ZFORLIST_HXX
#include <svl/zforlist.hxx>
#endif
#ifndef DBAUI_SBATTRDLG_HXX
#include "dlgattr.hxx"
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_
#include <com/sun/star/container/XChild.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATSSUPPLIER_HPP_
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
#include <com/sun/star/util/XNumberFormatter.hpp>
#endif
#ifndef _DBU_MISC_HRC_
#include "dbu_misc.hrc"
#endif
#ifndef _DBAUI_SQLMESSAGE_HXX_
#include "sqlmessage.hxx"
#endif
#ifndef _COM_SUN_STAR_UTIL_NUMBERFORMAT_HPP_
#include <com/sun/star/util/NumberFormat.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_URL_HPP_
#include <com/sun/star/util/URL.hpp>
#endif
#ifndef _SV_TOOLBOX_HXX
#include <vcl/toolbox.hxx>
#endif
#ifndef _DBAUI_DLGSIZE_HXX
#include "dlgsize.hxx"
#endif
#ifndef _SVTOOLS_EDITBROWSEBOX_HXX_
#include <svtools/editbrowsebox.hxx>
#endif
#ifndef _UTL_CONFIGMGR_HXX_
#include <unotools/configmgr.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_HELPOPT_HXX
#include <svtools/helpopt.hxx>
#endif
#ifndef _UCBHELPER_CONTENT_HXX
#include <ucbhelper/content.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef TOOLS_DIAGNOSE_EX_H
#include <tools/diagnose_ex.h>
#endif
#ifndef _NUMUNO_HXX
#include <svl/numuno.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <unotools/pathoptions.hxx>
#endif
#ifndef SVTOOLS_FILENOTATION_HXX_
#include <svl/filenotation.hxx>
#endif
#ifndef _SVT_FILEVIEW_HXX
#include <svtools/fileview.hxx>
#endif
#ifndef _CONNECTIVITY_FILE_VALUE_HXX_
#include <connectivity/FValue.hxx>
#endif

// .........................................................................
namespace dbaui
{
// .........................................................................
using namespace ::dbtools;
using namespace ::comphelper;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::ui::dialogs;
using namespace ::svt;
using ::com::sun::star::ucb::InteractiveIOException;
using ::com::sun::star::ucb::IOErrorCode_NO_FILE;
using ::com::sun::star::ucb::IOErrorCode_NOT_EXISTING;
using ::com::sun::star::frame::XModel;

// -----------------------------------------------------------------------------
SQLExceptionInfo createConnection(	const ::rtl::OUString& _rsDataSourceName,
	 								const Reference< ::com::sun::star::container::XNameAccess >& _xDatabaseContext,
									const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rMF,
									Reference< ::com::sun::star::lang::XEventListener>& _rEvtLst,
									Reference< ::com::sun::star::sdbc::XConnection>& _rOUTConnection )
{
	Reference<XPropertySet> xProp;
	try
	{
		xProp.set(_xDatabaseContext->getByName(_rsDataSourceName),UNO_QUERY);
	}
	catch(Exception&)
	{
	}
	SQLExceptionInfo aInfo;

	return createConnection(xProp,_rMF,_rEvtLst,_rOUTConnection);
}
// -----------------------------------------------------------------------------
SQLExceptionInfo createConnection(	const Reference< ::com::sun::star::beans::XPropertySet>& _xDataSource,
									const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rMF,
									Reference< ::com::sun::star::lang::XEventListener>& _rEvtLst,
									Reference< ::com::sun::star::sdbc::XConnection>& _rOUTConnection )
{
	SQLExceptionInfo aInfo;
	if ( !_xDataSource.is() )
	{
		OSL_ENSURE(0,"createConnection: coult not retrieve the data source!");
		return aInfo;
	}

	::rtl::OUString sPwd, sUser;
	sal_Bool bPwdReq = sal_False;
	try
	{
		_xDataSource->getPropertyValue(PROPERTY_PASSWORD) >>= sPwd;
		bPwdReq = ::cppu::any2bool(_xDataSource->getPropertyValue(PROPERTY_ISPASSWORDREQUIRED));
		_xDataSource->getPropertyValue(PROPERTY_USER) >>= sUser;
	}
	catch(Exception&)
	{
		OSL_ENSURE(0,"createConnection: error while retrieving data source properties!");
	}


	try
	{
		if(bPwdReq && !sPwd.getLength())
		{	// password required, but empty -> connect using an interaction handler
			Reference<XCompletedConnection> xConnectionCompletion(_xDataSource, UNO_QUERY);
			if (!xConnectionCompletion.is())
			{
				OSL_ENSURE(0,"createConnection: missing an interface ... need an error message here!");
			}
			else
			{	// instantiate the default SDB interaction handler
				Reference< XInteractionHandler > xHandler(_rMF->createInstance(SERVICE_TASK_INTERACTION_HANDLER), UNO_QUERY);
				if (!xHandler.is())
				{
					OSL_ENSURE(sal_False, "createConnection: could not instantiate an interaction handler!");
					// ShowServiceNotAvailableError(NULL, String(SERVICE_TASK_INTERACTION_HANDLER), sal_True);
						// TODO: a real parent!
				}
				else
					_rOUTConnection = xConnectionCompletion->connectWithCompletion(xHandler);
			}
		}
		else
		{
			Reference<XDataSource> xDataSource(_xDataSource,UNO_QUERY);
			_rOUTConnection = xDataSource->getConnection(sUser, sPwd);
		}
		// be notified when connection is in disposing
		Reference< XComponent >  xComponent(_rOUTConnection, UNO_QUERY);
		if (xComponent.is() && _rEvtLst.is())
			xComponent->addEventListener(_rEvtLst);
	}
	catch(SQLContext& e) { aInfo = SQLExceptionInfo(e); }
	catch(SQLWarning& e) { aInfo = SQLExceptionInfo(e); }
	catch(SQLException& e) { aInfo = SQLExceptionInfo(e); }
	catch(Exception&) { OSL_ENSURE(0,"SbaTableQueryBrowser::OnExpandEntry: could not connect - unknown exception!"); }

	//	showError(aInfo);

	return aInfo;
}
// -----------------------------------------------------------------------------
Reference< XDataSource > getDataSourceByName( const ::rtl::OUString& _rDataSourceName,
    Window* _pErrorMessageParent, Reference< XMultiServiceFactory > _rxORB, ::dbtools::SQLExceptionInfo* _pErrorInfo )
{
    ::comphelper::ComponentContext aContext( _rxORB );
    Reference< XNameAccess > xDatabaseContext( aContext.createComponent( "com.sun.star.sdb.DatabaseContext" ), UNO_QUERY_THROW );

    Reference< XDataSource > xDatasource;
    Any aError;
    SQLExceptionInfo aSQLError;
	try
	{
		xDatabaseContext->getByName( _rDataSourceName ) >>= xDatasource;
	}
	catch(const WrappedTargetException& e)
	{
        InteractiveIOException aIOException;
        if  (   ( e.TargetException >>= aIOException )
            &&  (   ( aIOException.Code == IOErrorCode_NO_FILE )
                ||  ( aIOException.Code == IOErrorCode_NOT_EXISTING )
                )
            )
        {
            String sErrorMessage = String( ModuleRes( STR_FILE_DOES_NOT_EXIST ) );
		    OFileNotation aTransformer( e.Message );
		    sErrorMessage.SearchAndReplaceAscii( "$file$", aTransformer.get( OFileNotation::N_SYSTEM ) );
            aSQLError = SQLExceptionInfo( sErrorMessage ).get();
        }
        else
        {
            aSQLError = SQLExceptionInfo( e.TargetException );
            if ( !aSQLError.isValid() )
                aError = e.TargetException;
        }
	}
    catch( const Exception& )
    {
        DBG_UNHANDLED_EXCEPTION();
    }

	if ( xDatasource.is() )
		return xDatasource;

    if ( aSQLError.isValid() )
    {
        if ( _pErrorInfo )
        {
            *_pErrorInfo = aSQLError;
        }
        else
        {
            showError( aSQLError, _pErrorMessageParent, _rxORB );
        }
    }

    return Reference<XDataSource>();
}
// -----------------------------------------------------------------------------
Reference< XInterface > getDataSourceOrModel(const Reference< XInterface >& _xObject)
{
	Reference< XInterface > xRet;
	Reference<XDocumentDataSource> xDocumentDataSource(_xObject,UNO_QUERY);
    if ( xDocumentDataSource.is() )
        xRet = xDocumentDataSource->getDatabaseDocument();

	if ( !xRet.is() )
	{
		Reference<XOfficeDatabaseDocument> xOfficeDoc(_xObject,UNO_QUERY);
		if ( xOfficeDoc.is() )
			xRet = xOfficeDoc->getDataSource();
	}

	return xRet;
}
// -----------------------------------------------------------------------------
void showError(const SQLExceptionInfo& _rInfo,Window* _pParent,const Reference< XMultiServiceFactory >& _xFactory)
{
	OSL_ENSURE(_pParent,"showError: Parent window must be NOT NULL!");
	::dbtools::showError(_rInfo,VCLUnoHelper::GetInterface(_pParent),_xFactory);
}

// -----------------------------------------------------------------------------
::std::vector< Reference<XNameAccess> > getKeyColumns(const Reference<XIndexAccess >& _rxKeys,
													  sal_Int32 _nKeyType)
{
	// use keys and indexes for excat postioning
	// first the keys
	::std::vector< Reference<XNameAccess> > vRet;
	if(_rxKeys.is())
	{
		Reference<XPropertySet> xProp;
		for(sal_Int32 i=0;i< _rxKeys->getCount();++i)
		{
			_rxKeys->getByIndex(i) >>= xProp;
			sal_Int32 nKeyType = 0;
			xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType;
			if(_nKeyType == nKeyType)
			{
				Reference<XColumnsSupplier> xKeyColsSup(xProp,UNO_QUERY);
				OSL_ENSURE(xKeyColsSup.is(),"Columnsupplier is null!");
				vRet.push_back(xKeyColsSup->getColumns());
			}
		}
	}

	return vRet;
}
// -----------------------------------------------------------------------------

TOTypeInfoSP getTypeInfoFromType(const OTypeInfoMap& _rTypeInfo,
							   sal_Int32 _nType,
							   const ::rtl::OUString& _sTypeName,
							   const ::rtl::OUString& _sCreateParams,
							   sal_Int32 _nPrecision,
							   sal_Int32 _nScale,
							   sal_Bool _bAutoIncrement,
							   sal_Bool& _brForceToType)
{
	TOTypeInfoSP pTypeInfo;
	_brForceToType = sal_False;
	// search for type
	::std::pair<OTypeInfoMap::const_iterator, OTypeInfoMap::const_iterator> aPair = _rTypeInfo.equal_range(_nType);
	OTypeInfoMap::const_iterator aIter = aPair.first;
	if(aIter != _rTypeInfo.end()) // compare with end is correct here
	{
		for(;aIter != aPair.second;++aIter)
		{
			// search the best matching type
	#ifdef DBG_UTIL
			::rtl::OUString sDBTypeName			= aIter->second->aTypeName;         (void)sDBTypeName;
			sal_Int32		nDBTypePrecision	= aIter->second->nPrecision;        (void)nDBTypePrecision;
			sal_Int32		nDBTypeScale		= aIter->second->nMaximumScale;     (void)nDBTypeScale;
			sal_Bool		bDBAutoIncrement	= aIter->second->bAutoIncrement;    (void)bDBAutoIncrement;
	#endif
			if	(	(
						!_sTypeName.getLength()
					||	(aIter->second->aTypeName.equalsIgnoreAsciiCase(_sTypeName))
					)
				&&	(
						(
								!aIter->second->aCreateParams.getLength()
							&&	!_sCreateParams.getLength()
						)
					||	(
								(aIter->second->nPrecision		>= _nPrecision)
							&&	(aIter->second->nMaximumScale	>= _nScale)
							&&	( (_bAutoIncrement && aIter->second->bAutoIncrement) || !_bAutoIncrement )
						)
					)
				)
				break;
		}

		if (aIter == aPair.second)
		{
			for(aIter = aPair.first; aIter != aPair.second; ++aIter)
			{
				sal_Int32 nPrec = aIter->second->nPrecision;
				sal_Int32 nScale = aIter->second->nMaximumScale;
				// search the best matching type (now comparing the local names)
				if	(	(aIter->second->aLocalTypeName.equalsIgnoreAsciiCase(_sTypeName))
					&&	(nPrec	>= _nPrecision)
					&&	(nScale	>= _nScale)
					&&	( (_bAutoIncrement && aIter->second->bAutoIncrement) || !_bAutoIncrement )
					)
				{
					OSL_ENSURE(sal_False,
						(	::rtl::OString("getTypeInfoFromType: assuming column type ")
						+=	::rtl::OString(aIter->second->aTypeName.getStr(), aIter->second->aTypeName.getLength(), gsl_getSystemTextEncoding())
						+=	::rtl::OString("\" (expected type name ")
						+=	::rtl::OString(_sTypeName.getStr(), _sTypeName.getLength(), gsl_getSystemTextEncoding())
						+=	::rtl::OString(" matches the type's local name).")).getStr());
					break;
				}
			}
		}

		if (aIter == aPair.second)
		{	// no match for the names, no match for the local names
			// -> drop the precision and the scale restriction, accept any type with the property
			// type id (nType)

			//OSL_ENSURE(sal_False,
			//	(	::rtl::OString("getTypeInfoFromType: did not find a matching type")
			//	+=	::rtl::OString(" (expected type name: ")
			//	+=	::rtl::OString(_sTypeName.getStr(), _sTypeName.getLength(), gsl_getSystemTextEncoding())
			//	+=	::rtl::OString(")! Defaulting to the first matching type.")).getStr());
			for(aIter = aPair.first; aIter != aPair.second; ++aIter)
			{
				// search the best matching type (now comparing the local names)
#ifdef DBG_UTIL
				::rtl::OUString sDBTypeName = aIter->second->aTypeName;
#endif
				sal_Int32 nPrec = aIter->second->nPrecision;
				sal_Int32 nScale = aIter->second->nMaximumScale;
				if	(	(nPrec	>= _nPrecision)
					&&	(nScale	>= _nScale)
					&&	( (_bAutoIncrement && aIter->second->bAutoIncrement) || !_bAutoIncrement )
					)
					break;
			}
		}
		if (aIter == aPair.second)
		{
			if ( _bAutoIncrement )
			{
				for(aIter = aPair.first; aIter != aPair.second; ++aIter)
				{
					// search the best matching type (now comparing the local names)
#ifdef DBG_UTIL
					::rtl::OUString sDBTypeName = aIter->second->aTypeName;
#endif
					sal_Int32 nScale = aIter->second->nMaximumScale;
					if	(	(nScale	>= _nScale)
						&&	(aIter->second->bAutoIncrement	== _bAutoIncrement)
						)
						break;
				}
				if ( aIter == aPair.second )
				{
					// try it without the auto increment flag
					pTypeInfo = getTypeInfoFromType(_rTypeInfo,
								   _nType,
								   _sTypeName,
								   _sCreateParams,
								   _nPrecision,
								   _nScale,
								   sal_False,
								   _brForceToType);
				}
				else
					pTypeInfo = aIter->second;
			}
			else
			{
				pTypeInfo = aPair.first->second;
				_brForceToType = sal_True;
			}
		}
		else
			pTypeInfo = aIter->second;
	}
	else
	{
		::comphelper::TStringMixEqualFunctor aCase(sal_False);
		// search for typeinfo where the typename is equal _sTypeName
		OTypeInfoMap::const_iterator typeInfoLoop = _rTypeInfo.begin();
		OTypeInfoMap::const_iterator typeInfoEnd  = _rTypeInfo.end();
		for (; typeInfoLoop != typeInfoEnd; ++typeInfoLoop)
		{
			if ( aCase( typeInfoLoop->second->getDBName() , _sTypeName ) )
            {
			    pTypeInfo = typeInfoLoop->second;
				break;
            }
		}
	}

	OSL_ENSURE(pTypeInfo, "getTypeInfoFromType: no type info found for this type!");
	return pTypeInfo;
}
// -----------------------------------------------------------------------------
void fillTypeInfo(	const Reference< ::com::sun::star::sdbc::XConnection>& _rxConnection,
					const String& _rsTypeNames,
					OTypeInfoMap& _rTypeInfoMap,
					::std::vector<OTypeInfoMap::iterator>& _rTypeInfoIters)
{
	if(!_rxConnection.is())
		return;
	Reference< XResultSet> xRs = _rxConnection->getMetaData ()->getTypeInfo ();
	Reference< XRow> xRow(xRs,UNO_QUERY);
	// Information for a single SQL type
	if(xRs.is())
	{
		static const ::rtl::OUString aB1 = ::rtl::OUString::createFromAscii(" [ ");
		static const ::rtl::OUString aB2 = ::rtl::OUString::createFromAscii(" ]");
        Reference<XResultSetMetaData> xResultSetMetaData = Reference<XResultSetMetaDataSupplier>(xRs,UNO_QUERY)->getMetaData();
        ::connectivity::ORowSetValue aValue;
        ::std::vector<sal_Int32> aTypes;
        ::std::vector<sal_Bool> aNullable;
		// Loop on the result set until we reach end of file
		while (xRs->next())
		{
			TOTypeInfoSP pInfo(new OTypeInfo());
            sal_Int32 nPos = 1;
            if ( aTypes.empty() )
            {
                sal_Int32 nCount = xResultSetMetaData->getColumnCount();
                if ( nCount < 1 )
                    nCount = 18;
                aTypes.reserve(nCount+1);
                aTypes.push_back(-1);
                aNullable.push_back(sal_False);
                for (sal_Int32 j = 1; j <= nCount ; ++j)
                {
                    aTypes.push_back(xResultSetMetaData->getColumnType(j));
                    aNullable.push_back(xResultSetMetaData->isNullable(j) != ColumnValue::NO_NULLS);
                }
            }

            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->aTypeName		= aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->nType			= aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->nPrecision		= aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->aLiteralPrefix	= aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->aLiteralSuffix	= aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->aCreateParams	= aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->bNullable		= (sal_Int32)aValue == ColumnValue::NULLABLE;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->bCaseSensitive	= (sal_Bool)aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->nSearchType		= aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->bUnsigned		= (sal_Bool)aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->bCurrency		= (sal_Bool)aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->bAutoIncrement	= (sal_Bool)aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->aLocalTypeName	= aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->nMinimumScale	= aValue;
			++nPos;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);
			pInfo->nMaximumScale	= aValue;
            nPos = 18;
            aValue.fill(nPos,aTypes[nPos],aNullable[nPos],xRow);

			// check if values are less than zero like it happens in a oracle jdbc driver
			if( pInfo->nPrecision < 0)
				pInfo->nPrecision = 0;
			if( pInfo->nMinimumScale < 0)
				pInfo->nMinimumScale = 0;
			if( pInfo->nMaximumScale < 0)
				pInfo->nMaximumScale = 0;

			String aName;
			switch(pInfo->nType)
			{
				case DataType::CHAR:
					aName = _rsTypeNames.GetToken(TYPE_CHAR);
					break;
				case DataType::VARCHAR:
					aName = _rsTypeNames.GetToken(TYPE_TEXT);
					break;
				case DataType::DECIMAL:
					aName = _rsTypeNames.GetToken(TYPE_DECIMAL);
					break;
				case DataType::NUMERIC:
					aName = _rsTypeNames.GetToken(TYPE_NUMERIC);
					break;
				case DataType::BIGINT:
					aName = _rsTypeNames.GetToken(TYPE_BIGINT);
					break;
				case DataType::FLOAT:
					aName = _rsTypeNames.GetToken(TYPE_FLOAT);
					break;
				case DataType::DOUBLE:
					aName = _rsTypeNames.GetToken(TYPE_DOUBLE);
					break;
				case DataType::LONGVARCHAR:
					aName = _rsTypeNames.GetToken(TYPE_MEMO);
					break;
				case DataType::LONGVARBINARY:
					aName = _rsTypeNames.GetToken(TYPE_IMAGE);
					break;
				case DataType::DATE:
					aName = _rsTypeNames.GetToken(TYPE_DATE);
					break;
				case DataType::TIME:
					aName = _rsTypeNames.GetToken(TYPE_TIME);
					break;
				case DataType::TIMESTAMP:
					aName = _rsTypeNames.GetToken(TYPE_DATETIME);
					break;
				case DataType::BIT:
					if ( pInfo->aCreateParams.getLength() )
					{
						aName = _rsTypeNames.GetToken(TYPE_BIT);
						break;
					}
					// run through
				case DataType::BOOLEAN:
					aName = _rsTypeNames.GetToken(TYPE_BOOL);
					break;
				case DataType::TINYINT:
					aName = _rsTypeNames.GetToken(TYPE_TINYINT);
					break;
				case DataType::SMALLINT:
					aName = _rsTypeNames.GetToken(TYPE_SMALLINT);
					break;
				case DataType::INTEGER:
					aName = _rsTypeNames.GetToken(TYPE_INTEGER);
					break;
				case DataType::REAL:
					aName = _rsTypeNames.GetToken(TYPE_REAL);
					break;
				case DataType::BINARY:
					aName = _rsTypeNames.GetToken(TYPE_BINARY);
					break;
				case DataType::VARBINARY:
					aName = _rsTypeNames.GetToken(TYPE_VARBINARY);
					break;
				case DataType::SQLNULL:
					aName = _rsTypeNames.GetToken(TYPE_SQLNULL);
					break;
				case DataType::OBJECT:
					aName = _rsTypeNames.GetToken(TYPE_OBJECT);
					break;
				case DataType::DISTINCT:
					aName = _rsTypeNames.GetToken(TYPE_DISTINCT);
					break;
				case DataType::STRUCT:
					aName = _rsTypeNames.GetToken(TYPE_STRUCT);
					break;
				case DataType::ARRAY:
					aName = _rsTypeNames.GetToken(TYPE_ARRAY);
					break;
				case DataType::BLOB:
					aName = _rsTypeNames.GetToken(TYPE_BLOB);
					break;
				case DataType::CLOB:
					aName = _rsTypeNames.GetToken(TYPE_CLOB);
					break;
				case DataType::REF:
					aName = _rsTypeNames.GetToken(TYPE_REF);
					break;
				case DataType::OTHER:
					aName = _rsTypeNames.GetToken(TYPE_OTHER);
					break;
			}
			if ( aName.Len() )
			{
				pInfo->aUIName = aName.GetBuffer();
				pInfo->aUIName += aB1;
			}
			pInfo->aUIName += pInfo->aTypeName;
			if ( aName.Len() )
				pInfo->aUIName += aB2;
			// Now that we have the type info, save it in the multimap
			_rTypeInfoMap.insert(OTypeInfoMap::value_type(pInfo->nType,pInfo));
		}
		// for a faster index access
		_rTypeInfoIters.reserve(_rTypeInfoMap.size());

		OTypeInfoMap::iterator aIter = _rTypeInfoMap.begin();
        OTypeInfoMap::iterator aEnd = _rTypeInfoMap.end();
		for(;aIter != aEnd;++aIter)
			_rTypeInfoIters.push_back(aIter);

		// Close the result set/statement.

		::comphelper::disposeComponent(xRs);
	}
}
// -----------------------------------------------------------------------------
void setColumnProperties(const Reference<XPropertySet>& _rxColumn,const OFieldDescription* _pFieldDesc)
{
	_rxColumn->setPropertyValue(PROPERTY_NAME,makeAny(_pFieldDesc->GetName()));
	_rxColumn->setPropertyValue(PROPERTY_TYPENAME,makeAny(_pFieldDesc->getTypeInfo()->aTypeName));
	_rxColumn->setPropertyValue(PROPERTY_TYPE,makeAny(_pFieldDesc->GetType()));
	_rxColumn->setPropertyValue(PROPERTY_PRECISION,makeAny(_pFieldDesc->GetPrecision()));
	_rxColumn->setPropertyValue(PROPERTY_SCALE,makeAny(_pFieldDesc->GetScale()));
	_rxColumn->setPropertyValue(PROPERTY_ISNULLABLE, makeAny(_pFieldDesc->GetIsNullable()));
	_rxColumn->setPropertyValue(PROPERTY_ISAUTOINCREMENT,::cppu::bool2any(_pFieldDesc->IsAutoIncrement()));
    _rxColumn->setPropertyValue(PROPERTY_DESCRIPTION,makeAny(_pFieldDesc->GetDescription()));
	if ( _rxColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_ISCURRENCY) && _pFieldDesc->IsCurrency() )
		_rxColumn->setPropertyValue(PROPERTY_ISCURRENCY,::cppu::bool2any(_pFieldDesc->IsCurrency()));
	// set autoincrement value when available
	// and only set when the entry is not empty, that lets the value in the column untouched
	if ( _pFieldDesc->IsAutoIncrement() && _pFieldDesc->GetAutoIncrementValue().getLength() && _rxColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_AUTOINCREMENTCREATION) )
		_rxColumn->setPropertyValue(PROPERTY_AUTOINCREMENTCREATION,makeAny(_pFieldDesc->GetAutoIncrementValue()));
}
// -----------------------------------------------------------------------------
::rtl::OUString createDefaultName(const Reference< XDatabaseMetaData>& _xMetaData,const Reference<XNameAccess>& _xTables,const ::rtl::OUString& _sName)
{
	OSL_ENSURE(_xMetaData.is(),"No MetaData!");
	::rtl::OUString sDefaultName = _sName;
	try
	{
		::rtl::OUString sCatalog,sSchema,sCompsedName;
		if(_xMetaData->supportsCatalogsInTableDefinitions())
		{
			try
			{
				Reference< XConnection> xCon = _xMetaData->getConnection();
				if ( xCon.is() )
					sCatalog = xCon->getCatalog();
				if ( !sCatalog.getLength() )
				{
					Reference<XResultSet> xRes = _xMetaData->getCatalogs();
					Reference<XRow> xRow(xRes,UNO_QUERY);
					while(xRes.is() && xRes->next())
					{
						sCatalog = xRow->getString(1);
						if(!xRow->wasNull())
							break;
					}
				}
			}
			catch(const SQLException&)
			{
			}
		}
		if(_xMetaData->supportsSchemasInTableDefinitions())
		{
			sSchema = _xMetaData->getUserName();
		}
		sCompsedName = ::dbtools::composeTableName( _xMetaData, sCatalog, sSchema, _sName, sal_False, ::dbtools::eInDataManipulation );
		sDefaultName = ::dbtools::createUniqueName(_xTables,sCompsedName);
	}
	catch(const SQLException&)
	{
	}
	return sDefaultName;
}
// -----------------------------------------------------------------------------
sal_Bool checkDataSourceAvailable(const ::rtl::OUString& _sDataSourceName,const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB)
{
	sal_Bool bRet = sal_False;
	Reference< XNameAccess > xDataBaseContext(_xORB->createInstance(SERVICE_SDB_DATABASECONTEXT), UNO_QUERY);
	if ( xDataBaseContext.is() )
	{
		bRet = xDataBaseContext->hasByName(_sDataSourceName);
		if ( !bRet )
		{ // try if this one is a URL
			try
			{
				bRet = xDataBaseContext->getByName(_sDataSourceName).hasValue();
			}
			catch(Exception)
			{
			}
		}
	}
	return bRet;
}
// -----------------------------------------------------------------------------
sal_Int32 mapTextAllign(const SvxCellHorJustify& _eAlignment)
{
	sal_Int32 nAlignment = com::sun::star::awt::TextAlign::LEFT;
	switch (_eAlignment)
	{
		case SVX_HOR_JUSTIFY_STANDARD:
		case SVX_HOR_JUSTIFY_LEFT:		nAlignment = ::com::sun::star::awt::TextAlign::LEFT;	break;
		case SVX_HOR_JUSTIFY_CENTER:	nAlignment = ::com::sun::star::awt::TextAlign::CENTER;	break;
		case SVX_HOR_JUSTIFY_RIGHT:		nAlignment = ::com::sun::star::awt::TextAlign::RIGHT;	break;
		default:
			OSL_ENSURE(0,"Invalid TextAlign!");
	}
	return nAlignment;
}
// -----------------------------------------------------------------------------
SvxCellHorJustify mapTextJustify(const sal_Int32& _nAlignment)
{
	SvxCellHorJustify eJustify = SVX_HOR_JUSTIFY_LEFT;
	switch (_nAlignment)
	{
		case ::com::sun::star::awt::TextAlign::LEFT		: eJustify = SVX_HOR_JUSTIFY_LEFT; break;
		case ::com::sun::star::awt::TextAlign::CENTER	: eJustify = SVX_HOR_JUSTIFY_CENTER; break;
		case ::com::sun::star::awt::TextAlign::RIGHT	: eJustify = SVX_HOR_JUSTIFY_RIGHT; break;
		default:
			OSL_ENSURE(0,"Invalid TextAlign!");
	}
	return eJustify;
}
// -----------------------------------------------------------------------------
float ConvertFontWeight( ::FontWeight eWeight )
{
	if( eWeight == WEIGHT_DONTKNOW )
		return ::com::sun::star::awt::FontWeight::DONTKNOW;
	else if( eWeight == WEIGHT_THIN )
		return ::com::sun::star::awt::FontWeight::THIN;
	else if( eWeight == WEIGHT_ULTRALIGHT )
		return ::com::sun::star::awt::FontWeight::ULTRALIGHT;
	else if( eWeight == WEIGHT_LIGHT )
		return ::com::sun::star::awt::FontWeight::LIGHT;
	else if( eWeight == WEIGHT_SEMILIGHT )
		return ::com::sun::star::awt::FontWeight::SEMILIGHT;
	else if( ( eWeight == WEIGHT_NORMAL ) || ( eWeight == WEIGHT_MEDIUM ) )
		return ::com::sun::star::awt::FontWeight::NORMAL;
	else if( eWeight == WEIGHT_SEMIBOLD )
		return ::com::sun::star::awt::FontWeight::SEMIBOLD;
	else if( eWeight == WEIGHT_BOLD )
		return ::com::sun::star::awt::FontWeight::BOLD;
	else if( eWeight == WEIGHT_ULTRABOLD )
		return ::com::sun::star::awt::FontWeight::ULTRABOLD;
	else if( eWeight == WEIGHT_BLACK )
		return ::com::sun::star::awt::FontWeight::BLACK;

	OSL_ENSURE(0, "Unknown FontWeigth" );
	return ::com::sun::star::awt::FontWeight::DONTKNOW;
}
// -----------------------------------------------------------------------------
float ConvertFontWidth( ::FontWidth eWidth )
{
	if( eWidth == WIDTH_DONTKNOW )
		return ::com::sun::star::awt::FontWidth::DONTKNOW;
	else if( eWidth == WIDTH_ULTRA_CONDENSED )
		return ::com::sun::star::awt::FontWidth::ULTRACONDENSED;
	else if( eWidth == WIDTH_EXTRA_CONDENSED )
		return ::com::sun::star::awt::FontWidth::EXTRACONDENSED;
	else if( eWidth == WIDTH_CONDENSED )
		return ::com::sun::star::awt::FontWidth::CONDENSED;
	else if( eWidth == WIDTH_SEMI_CONDENSED )
		return ::com::sun::star::awt::FontWidth::SEMICONDENSED;
	else if( eWidth == WIDTH_NORMAL )
		return ::com::sun::star::awt::FontWidth::NORMAL;
	else if( eWidth == WIDTH_SEMI_EXPANDED )
		return ::com::sun::star::awt::FontWidth::SEMIEXPANDED;
	else if( eWidth == WIDTH_EXPANDED )
		return ::com::sun::star::awt::FontWidth::EXPANDED;
	else if( eWidth == WIDTH_EXTRA_EXPANDED )
		return ::com::sun::star::awt::FontWidth::EXTRAEXPANDED;
	else if( eWidth == WIDTH_ULTRA_EXPANDED )
		return ::com::sun::star::awt::FontWidth::ULTRAEXPANDED;

	OSL_ENSURE(0, "Unknown FontWidth" );
	return ::com::sun::star::awt::FontWidth::DONTKNOW;
}
// -----------------------------------------------------------------------------
::com::sun::star::awt::FontDescriptor CreateFontDescriptor( const Font& rFont )
{
	::com::sun::star::awt::FontDescriptor aFD;
	aFD.Name			= rFont.GetName();
	aFD.StyleName		= rFont.GetStyleName();
	aFD.Height			= (sal_Int16)rFont.GetSize().Height();
	aFD.Width			= (sal_Int16)rFont.GetSize().Width();
	aFD.Family			= sal::static_int_cast< sal_Int16 >(rFont.GetFamily());
	aFD.CharSet			= rFont.GetCharSet();
	aFD.Pitch			= sal::static_int_cast< sal_Int16 >(rFont.GetPitch());
	aFD.CharacterWidth	= ConvertFontWidth( rFont.GetWidthType() );
	aFD.Weight			= ConvertFontWeight( rFont.GetWeight() );
	aFD.Slant			= (::com::sun::star::awt::FontSlant)rFont.GetItalic();
	aFD.Underline		= sal::static_int_cast< sal_Int16 >(
        rFont.GetUnderline());
	aFD.Strikeout		= sal::static_int_cast< sal_Int16 >(
        rFont.GetStrikeout());
	aFD.Orientation		= rFont.GetOrientation();
	aFD.Kerning			= rFont.IsKerning();
	aFD.WordLineMode	= rFont.IsWordLineMode();
	aFD.Type			= 0;   // ??? => Nur an Metric...
	return aFD;
}
// -----------------------------------------------------------------------------
void callColumnFormatDialog(const Reference<XPropertySet>& xAffectedCol,
							const Reference<XPropertySet>& xField,
							SvNumberFormatter* _pFormatter,
							Window* _pParent)
{
	if (xAffectedCol.is() && xField.is())
	{
		try
		{
			Reference< XPropertySetInfo >  xInfo = xAffectedCol->getPropertySetInfo();
			sal_Bool bHasFormat = xInfo->hasPropertyByName(PROPERTY_FORMATKEY);
			sal_Int32 nDataType = ::comphelper::getINT32(xField->getPropertyValue(PROPERTY_TYPE));

			SvxCellHorJustify eJustify(SVX_HOR_JUSTIFY_STANDARD);
			Any aAlignment = xAffectedCol->getPropertyValue(PROPERTY_ALIGN);
			if (aAlignment.hasValue())
				eJustify = dbaui::mapTextJustify(::comphelper::getINT16(aAlignment));
			sal_Int32  nFormatKey = 0;
			if ( bHasFormat )
				nFormatKey = ::comphelper::getINT32(xAffectedCol->getPropertyValue(PROPERTY_FORMATKEY));

			sal_uInt16 nFlags = 0;
			if(callColumnFormatDialog(_pParent,_pFormatter,nDataType,nFormatKey,eJustify,nFlags,bHasFormat))
			{
				xAffectedCol->setPropertyValue(PROPERTY_ALIGN, makeAny((sal_Int16)dbaui::mapTextAllign(eJustify)));
				if (nFlags & TP_ATTR_NUMBER)
					xAffectedCol->setPropertyValue(PROPERTY_FORMATKEY, makeAny(nFormatKey));

			}
		}
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
	}
}
// -----------------------------------------------------------------------------
sal_Bool callColumnFormatDialog(Window* _pParent,
								SvNumberFormatter* _pFormatter,
								sal_Int32 _nDataType,
								sal_Int32& _nFormatKey,
								SvxCellHorJustify& _eJustify,
								sal_uInt16&	_nFlags,
								sal_Bool  _bHasFormat)
{
	sal_Bool bRet = sal_False;
	// the allowed format changes depend of the type of the field ...
	_nFlags = TP_ATTR_ALIGN;

	if (_bHasFormat)
		_nFlags |= TP_ATTR_NUMBER;

	// ------------
	// UNO->ItemSet
	static SfxItemInfo aItemInfos[] =
	{
		{ 0, 0 },
		{ SID_ATTR_NUMBERFORMAT_VALUE,		SFX_ITEM_POOLABLE },
		{ SID_ATTR_ALIGN_HOR_JUSTIFY,		SFX_ITEM_POOLABLE },
		{ SID_ATTR_NUMBERFORMAT_ONE_AREA,	SFX_ITEM_POOLABLE },
		{ SID_ATTR_NUMBERFORMAT_INFO,		SFX_ITEM_POOLABLE }
	};
	static sal_uInt16 aAttrMap[] =
	{
		SBA_DEF_RANGEFORMAT, SBA_ATTR_ALIGN_HOR_JUSTIFY,
		SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA,
		SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO,
		0
	};

	SfxPoolItem* pDefaults[] =
	{
		new SfxRangeItem(SBA_DEF_RANGEFORMAT, SBA_DEF_FMTVALUE, SBA_ATTR_ALIGN_HOR_JUSTIFY),
		new SfxUInt32Item(SBA_DEF_FMTVALUE),
		new SvxHorJustifyItem(SVX_HOR_JUSTIFY_STANDARD, SBA_ATTR_ALIGN_HOR_JUSTIFY),
		new SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, sal_False),
		new SvxNumberInfoItem(SID_ATTR_NUMBERFORMAT_INFO)
	};

	SfxItemPool* pPool = new SfxItemPool(String::CreateFromAscii("GridBrowserProperties"), SBA_DEF_RANGEFORMAT, SBA_ATTR_ALIGN_HOR_JUSTIFY, aItemInfos, pDefaults);
	pPool->SetDefaultMetric( SFX_MAPUNIT_TWIP );	// ripped, don't understand why
	pPool->FreezeIdRanges();						// the same

	SfxItemSet* pFormatDescriptor = new SfxItemSet(*pPool, aAttrMap);
	// fill it
	pFormatDescriptor->Put(SvxHorJustifyItem(_eJustify, SBA_ATTR_ALIGN_HOR_JUSTIFY));
	sal_Bool bText = sal_False;
	if (_bHasFormat)
	{
		// if the col is bound to a text field we have to disallow all non-text formats
		if ((DataType::CHAR == _nDataType) || (DataType::VARCHAR == _nDataType) || (DataType::LONGVARCHAR == _nDataType) || (DataType::CLOB == _nDataType))
		{
			bText = sal_True;
			pFormatDescriptor->Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, sal_True));
			if (!_pFormatter->IsTextFormat(_nFormatKey))
				// text fields can only have text formats
				_nFormatKey = _pFormatter->GetStandardFormat(NUMBERFORMAT_TEXT,_pParent->GetSettings().GetLanguage());
		}

		pFormatDescriptor->Put(SfxUInt32Item(SBA_DEF_FMTVALUE, _nFormatKey));
	}

	if (!bText)
	{
		double dPreviewVal = 1234.56789;
		SvxNumberInfoItem aFormatter(_pFormatter, dPreviewVal, SID_ATTR_NUMBERFORMAT_INFO);
		pFormatDescriptor->Put(aFormatter);
	}

	{	// want the dialog to be destroyed before our set
		SbaSbAttrDlg aDlg(_pParent, pFormatDescriptor, _pFormatter, _nFlags);
		if (RET_OK == aDlg.Execute())
		{
			// ------------
			// ItemSet->UNO
			// UNO-properties
			const SfxItemSet* pSet = aDlg.GetExampleSet();
			// (of course we could put the modified items directly into the column, but then the UNO-model
			// won't reflect these changes, and why do we have a model, then ?)

			// horizontal justify
			SFX_ITEMSET_GET(*pSet, pHorJustify, SvxHorJustifyItem, SBA_ATTR_ALIGN_HOR_JUSTIFY, sal_True);

			_eJustify = (SvxCellHorJustify)pHorJustify->GetValue();

			// format key
			if (_nFlags & TP_ATTR_NUMBER)
			{
				SFX_ITEMSET_GET(*pSet, pFormat, SfxUInt32Item, SBA_DEF_FMTVALUE, sal_True);
				_nFormatKey = (sal_Int32)pFormat->GetValue();
			}
			bRet = sal_True;
		}
			// deleted formats
		const SfxItemSet* pResult = aDlg.GetOutputItemSet();
		if (pResult)
		{
			const SfxPoolItem* pItem = pResult->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
			const SvxNumberInfoItem* pInfoItem = static_cast<const SvxNumberInfoItem*>(pItem);
			if (pInfoItem && pInfoItem->GetDelCount())
			{
				const sal_uInt32* pDeletedKeys = pInfoItem->GetDelArray();

				for (sal_uInt16 i=0; i< pInfoItem->GetDelCount(); ++i, ++pDeletedKeys)
					_pFormatter->DeleteEntry(*pDeletedKeys);
			}
		}
	}

	delete pFormatDescriptor;
    SfxItemPool::Free(pPool);
	for (sal_uInt16 i=0; i<sizeof(pDefaults)/sizeof(pDefaults[0]); ++i)
		delete pDefaults[i];

	return bRet;
}

//------------------------------------------------------------------------------
const SfxFilter* getStandardDatabaseFilter()
{
	static const String s_sDatabaseType = String::CreateFromAscii("StarOffice XML (Base)");
	const SfxFilter* pFilter = SfxFilter::GetFilterByName( s_sDatabaseType);
	OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
	return pFilter;
}


// -----------------------------------------------------------------------------
sal_Bool appendToFilter(const Reference<XConnection>& _xConnection,
						const ::rtl::OUString& _sName,
						const Reference< XMultiServiceFactory >& _xFactory,
						Window* _pParent)
{
	sal_Bool bRet = sal_False;
	Reference< XChild> xChild(_xConnection,UNO_QUERY);
	if(xChild.is())
	{
		Reference< XPropertySet> xProp(xChild->getParent(),UNO_QUERY);
		if(xProp.is())
		{
			Sequence< ::rtl::OUString > aFilter;
			xProp->getPropertyValue(PROPERTY_TABLEFILTER) >>= aFilter;
			// first check if we have something like SCHEMA.%
			sal_Bool bHasToInsert = sal_True;
			static ::rtl::OUString sPattern = ::rtl::OUString::createFromAscii("%");
			const ::rtl::OUString* pBegin = aFilter.getConstArray();
			const ::rtl::OUString* pEnd = pBegin + aFilter.getLength();
			for (;pBegin != pEnd; ++pBegin)
			{
				if(pBegin->indexOf('%') != -1)
				{
					sal_Int32 nLen;
					if((nLen = pBegin->lastIndexOf('.')) != -1 && !pBegin->compareTo(_sName,nLen))
						bHasToInsert = sal_False;
					else if(pBegin->getLength() == 1)
						bHasToInsert = sal_False;
				}
			}

			bRet = sal_True;
			if(bHasToInsert)
			{
				if(! ::dbaui::checkDataSourceAvailable(::comphelper::getString(xProp->getPropertyValue(PROPERTY_NAME)),_xFactory))
				{
					String aMessage(ModuleRes(STR_TABLEDESIGN_DATASOURCE_DELETED));
					OSQLWarningBox( _pParent, aMessage ).Execute();
					bRet = sal_False;
				}
				else
				{
					aFilter.realloc(aFilter.getLength()+1);
					aFilter.getArray()[aFilter.getLength()-1] = _sName;
					xProp->setPropertyValue(PROPERTY_TABLEFILTER,makeAny(aFilter));
				}
			}
		}
	}
	return bRet;
}
// -----------------------------------------------------------------------------
void notifySystemWindow(Window* _pWindow,Window* _pToRegister, ::comphelper::mem_fun1_t<TaskPaneList,Window*> _rMemFunc)
{
	OSL_ENSURE(_pWindow,"Window can not be null!");
    SystemWindow* pSystemWindow = _pWindow ? _pWindow->GetSystemWindow() : NULL;
	if ( pSystemWindow )
	{
		_rMemFunc( pSystemWindow->GetTaskPaneList(), _pToRegister );
	}
}
// -----------------------------------------------------------------------------
void adjustToolBoxSize(ToolBox* _pToolBox)
{
	// adjust the toolbox size, otherwise large bitmaps don't fit into
	Size aOldSize = _pToolBox->GetSizePixel();
	Size aSize = _pToolBox->CalcWindowSizePixel();
	if ( !aSize.Width() )
		aSize.Width() = aOldSize.Width();
	else if ( !aSize.Height() )
		aSize.Height() = aOldSize.Height();

	Size aTbSize = _pToolBox->GetSizePixel();
	if ( (aSize.Width() && aSize.Width() != aTbSize.Width()) ||
			(aSize.Height() && aSize.Height() != aTbSize.Height()) )
	{
		_pToolBox->SetPosSizePixel( _pToolBox->GetPosPixel(), aSize );
		_pToolBox->Invalidate();
	}
}
// -----------------------------------------------------------------------------
sal_Bool isHiContrast(Window* _pWindow)
{
	OSL_ENSURE(_pWindow,"Window must be not null!");
	Window* pIter = _pWindow;
	//	while( pIter &&  pIter->GetBackground().GetColor().GetColor() == COL_TRANSPARENT )
	while( pIter )
	{
		if ( pIter->GetBackground().GetColor().GetColor() == COL_TRANSPARENT )
			pIter = pIter->GetParent();
		else
			break;
	}
	return pIter && pIter->GetSettings().GetStyleSettings().GetHighContrastMode();
}

// -----------------------------------------------------------------------------
void adjustBrowseBoxColumnWidth( ::svt::EditBrowseBox* _pBox, sal_uInt16 _nColId )
{
	sal_Int32 nColSize = -1;
	sal_uInt32 nDefaultWidth = _pBox->GetDefaultColumnWidth( _pBox->GetColumnTitle( _nColId ) );
	if ( nDefaultWidth != _pBox->GetColumnWidth( _nColId ) )
	{
		Size aSizeMM = _pBox->PixelToLogic( Size( _pBox->GetColumnWidth( _nColId ), 0 ), MapMode( MAP_MM ) );
		nColSize = aSizeMM.Width() * 10;
	}

	Size aDefaultMM = _pBox->PixelToLogic( Size( nDefaultWidth, 0 ), MapMode( MAP_MM ) );

	DlgSize aColumnSizeDlg( _pBox, nColSize, sal_False, aDefaultMM.Width() * 10 );
	if ( aColumnSizeDlg.Execute() )
	{
		sal_Int32 nValue = aColumnSizeDlg.GetValue();
		if ( -1 == nValue )
		{	// default width
			nValue = _pBox->GetDefaultColumnWidth( _pBox->GetColumnTitle( _nColId ) );
		}
		else
		{
			Size aSizeMM( nValue / 10, 0 );
			nValue = _pBox->LogicToPixel( aSizeMM, MapMode( MAP_MM ) ).Width();
		}
		_pBox->SetColumnWidth( _nColId, nValue );
	}
}
// -----------------------------------------------------------------------------
// check if SQL92 name checking is enabled
sal_Bool isSQL92CheckEnabled(const Reference<XConnection>& _xConnection)
{
	return ::dbtools::getBooleanDataSourceSetting( _xConnection, PROPERTY_ENABLESQL92CHECK );
}
// -----------------------------------------------------------------------------
sal_Bool isAppendTableAliasEnabled(const Reference<XConnection>& _xConnection)
{
	return ::dbtools::getBooleanDataSourceSetting( _xConnection, INFO_APPEND_TABLE_ALIAS );
}

// -----------------------------------------------------------------------------
sal_Bool generateAsBeforeTableAlias(const Reference<XConnection>& _xConnection)
{
	return ::dbtools::getBooleanDataSourceSetting( _xConnection, INFO_AS_BEFORE_CORRELATION_NAME );
}

// -----------------------------------------------------------------------------
void fillAutoIncrementValue(const Reference<XPropertySet>& _xDatasource,
							sal_Bool& _rAutoIncrementValueEnabled,
							::rtl::OUString& _rsAutoIncrementValue)
{
	if ( _xDatasource.is() )
	{
		OSL_ENSURE(_xDatasource->getPropertySetInfo()->hasPropertyByName(PROPERTY_INFO),"NO datasource supplied!");
		Sequence<PropertyValue> aInfo;
		_xDatasource->getPropertyValue(PROPERTY_INFO) >>= aInfo;

		// search the right propertyvalue
		const PropertyValue* pValue =::std::find_if(aInfo.getConstArray(),
													aInfo.getConstArray() + aInfo.getLength(),
													::std::bind2nd(TPropertyValueEqualFunctor(),PROPERTY_AUTOINCREMENTCREATION));
		if ( pValue && pValue != (aInfo.getConstArray() + aInfo.getLength()) )
			pValue->Value >>= _rsAutoIncrementValue;
		pValue =::std::find_if(aInfo.getConstArray(),
													aInfo.getConstArray() + aInfo.getLength(),
													::std::bind2nd(TPropertyValueEqualFunctor(),::rtl::OUString::createFromAscii("IsAutoRetrievingEnabled") ));
		if ( pValue && pValue != (aInfo.getConstArray() + aInfo.getLength()) )
			pValue->Value >>= _rAutoIncrementValueEnabled;
	}
}
// -----------------------------------------------------------------------------
void fillAutoIncrementValue(const Reference<XConnection>& _xConnection,
							sal_Bool& _rAutoIncrementValueEnabled,
							::rtl::OUString& _rsAutoIncrementValue)
{
	Reference< XChild> xChild(_xConnection,UNO_QUERY);
	if(xChild.is())
	{
		Reference< XPropertySet> xProp(xChild->getParent(),UNO_QUERY);
		fillAutoIncrementValue(xProp,_rAutoIncrementValueEnabled,_rsAutoIncrementValue);
	}
}
// -----------------------------------------------------------------------------
::rtl::OUString getStrippedDatabaseName(const Reference<XPropertySet>& _xDataSource,::rtl::OUString& _rsDatabaseName)
{
	if ( !_rsDatabaseName.getLength() && _xDataSource.is() )
	{
		try
		{
			_xDataSource->getPropertyValue(PROPERTY_NAME) >>= _rsDatabaseName;
		}
		catch(const Exception& )
		{
            DBG_UNHANDLED_EXCEPTION();
		}
	}
	::rtl::OUString sName = _rsDatabaseName;
	INetURLObject aURL(sName);
	if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )
		sName = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_UNAMBIGUOUS);
	return sName;
}
// -----------------------------------------------------------------------------
	void AppendConfigToken( ::rtl::OUString& _rURL, sal_Bool _bQuestionMark )
	{
		Any aLocale =
			::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
		::rtl::OUString sLocaleStr;
		if ( !( aLocale >>= sLocaleStr ) )
			// fallback is english
			sLocaleStr = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en"));

		// query part exists?
		if ( _bQuestionMark )
			// no, so start with '?'
			_rURL += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("?"));
		else
			// yes, so only append with '&'
			_rURL += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("&"));

		// set parameters
		_rURL += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Language="));
		_rURL += sLocaleStr;
		_rURL += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("&System="));
		_rURL += SvtHelpOptions().GetSystem();
	}

namespace
{
	// -----------------------------------------------------------------------

	sal_Bool GetHelpAnchor_Impl( const ::rtl::OUString& _rURL, ::rtl::OUString& _rAnchor )
	{
		sal_Bool bRet = sal_False;
		::rtl::OUString sAnchor;

		try
		{
			::ucbhelper::Content aCnt( INetURLObject( _rURL ).GetMainURL( INetURLObject::NO_DECODE ),
								 Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
			if ( ( aCnt.getPropertyValue( ::rtl::OUString::createFromAscii( "AnchorName" ) ) >>= sAnchor ) )
			{

				if ( sAnchor.getLength() > 0 )
				{
					_rAnchor = sAnchor;
					bRet = sal_True;
				}
			}
			else
			{
				DBG_ERRORFILE( "Property 'AnchorName' is missing" );
			}
		}
		catch( Exception& )
		{
		}

		return bRet;
	}
// .........................................................................
} // annonymous
// .........................................................................
// -----------------------------------------------------------------------------
::com::sun::star::util::URL	createHelpAgentURL(const ::rtl::OUString& _sModuleName, const rtl::OString& sHelpId)
{
	::com::sun::star::util::URL aURL;
	aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.help://" ) );
	aURL.Complete += _sModuleName;
	aURL.Complete += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
	aURL.Complete += ::rtl::OStringToOUString( sHelpId, RTL_TEXTENCODING_UTF8);

	::rtl::OUString sAnchor;
	::rtl::OUString sTempURL = aURL.Complete;
	AppendConfigToken( sTempURL, sal_True );
	sal_Bool bHasAnchor = GetHelpAnchor_Impl( sTempURL, sAnchor );
	AppendConfigToken(aURL.Complete,sal_True);
	if ( bHasAnchor )
	{
		aURL.Complete += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("#"));
		aURL.Complete += sAnchor;
	}
	return aURL;
}
// -----------------------------------------------------------------------------
void setEvalDateFormatForFormatter(Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter)
{
	OSL_ENSURE( _rxFormatter.is(),"setEvalDateFormatForFormatter: Formatter is NULL!");
	if ( _rxFormatter.is() )
	{
		Reference< ::com::sun::star::util::XNumberFormatsSupplier >  xSupplier = _rxFormatter->getNumberFormatsSupplier();

		Reference< XUnoTunnel > xTunnel(xSupplier,UNO_QUERY);
		SvNumberFormatsSupplierObj* pSupplierImpl = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
		OSL_ENSURE(pSupplierImpl,"No Supplier!");

		if ( pSupplierImpl )
		{
			SvNumberFormatter* pFormatter = pSupplierImpl->GetNumberFormatter();
			pFormatter->SetEvalDateFormat(NF_EVALDATEFORMAT_FORMAT);
		}
	}
}
// -----------------------------------------------------------------------------
TOTypeInfoSP queryPrimaryKeyType(const OTypeInfoMap& _rTypeInfo)
{
	TOTypeInfoSP pTypeInfo;
	// first we search for a type which supports autoIncrement
	OTypeInfoMap::const_iterator aIter = _rTypeInfo.begin();
	OTypeInfoMap::const_iterator aEnd  = _rTypeInfo.end();
	for(;aIter != aEnd;++aIter)
	{
		// OJ: we don't want to set an autoincrement column to be key
		// because we don't have the possiblity to know how to create
		// such auto increment column later on
		// so until we know how to do it, we create a column without autoincrement
		//	if ( !aIter->second->bAutoIncrement )
		{	// therefor we have searched
			if ( aIter->second->nType == DataType::INTEGER )
			{
				pTypeInfo = aIter->second; // alternative
				break;
			}
			else if ( !pTypeInfo.get() && aIter->second->nType == DataType::DOUBLE )
				pTypeInfo = aIter->second; // alternative
			else if ( !pTypeInfo.get() && aIter->second->nType == DataType::REAL )
				pTypeInfo = aIter->second; // alternative
		}
	}
	if ( !pTypeInfo.get() ) // just a fallback
		pTypeInfo = queryTypeInfoByType(DataType::VARCHAR,_rTypeInfo);

	OSL_ENSURE(pTypeInfo.get(),"checkColumns: cann't find a type which is useable as a key!");
	return pTypeInfo;
}
// -----------------------------------------------------------------------------
TOTypeInfoSP queryTypeInfoByType(sal_Int32 _nDataType,const OTypeInfoMap& _rTypeInfo)
{
	OTypeInfoMap::const_iterator aIter = _rTypeInfo.find(_nDataType);
	if(aIter != _rTypeInfo.end())
		return aIter->second;
	// fall back if the type is unknown
	TOTypeInfoSP pTypeInfo;
	switch(_nDataType)
	{
		case DataType::TINYINT:
			pTypeInfo = queryTypeInfoByType(DataType::SMALLINT,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			// run through
		case DataType::SMALLINT:
			pTypeInfo = queryTypeInfoByType(DataType::INTEGER,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			// run through
		case DataType::INTEGER:
			pTypeInfo = queryTypeInfoByType(DataType::FLOAT,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			// run through
		case DataType::FLOAT:
			pTypeInfo = queryTypeInfoByType(DataType::REAL,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			// run through
		case DataType::DATE:
		case DataType::TIME:
			if( DataType::DATE == _nDataType || DataType::TIME == _nDataType )
			{
				pTypeInfo = queryTypeInfoByType(DataType::TIMESTAMP,_rTypeInfo);
				if( bool(pTypeInfo))
					break;
			}
			// run through
		case DataType::TIMESTAMP:
		case DataType::REAL:
		case DataType::BIGINT:
			pTypeInfo = queryTypeInfoByType(DataType::DOUBLE,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			// run through
		case DataType::DOUBLE:
			pTypeInfo = queryTypeInfoByType(DataType::NUMERIC,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			// run through
		case DataType::NUMERIC:
			pTypeInfo = queryTypeInfoByType(DataType::DECIMAL,_rTypeInfo);
			break;
		case DataType::DECIMAL:
			pTypeInfo = queryTypeInfoByType(DataType::NUMERIC,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			pTypeInfo = queryTypeInfoByType(DataType::DOUBLE,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			break;
		case DataType::VARCHAR:
			pTypeInfo = queryTypeInfoByType(DataType::LONGVARCHAR,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			break;
		case DataType::LONGVARCHAR:
			pTypeInfo = queryTypeInfoByType(DataType::CLOB,_rTypeInfo);
			if( bool(pTypeInfo))
				break;
			break;
		default:
			;
	} // switch(_nDataType)
	if ( !pTypeInfo )
	{
		::rtl::OUString sCreate(RTL_CONSTASCII_USTRINGPARAM("x")),sTypeName;
		sal_Bool bForce = sal_True;
		pTypeInfo = ::dbaui::getTypeInfoFromType(_rTypeInfo,DataType::VARCHAR,sTypeName,sCreate,50,0,sal_False,bForce);
	} // if ( !pTypeInfo )
	OSL_ENSURE(pTypeInfo,"Wrong DataType supplied!");
	return pTypeInfo;
}
// -----------------------------------------------------------------------------
sal_Int32 askForUserAction(Window* _pParent,sal_uInt16 _nTitle,sal_uInt16 _nText,sal_Bool _bAll,const ::rtl::OUString& _sName)
{
	vos::OGuard aGuard( Application::GetSolarMutex() );
	String aMsg = String(ModuleRes(_nText));
	aMsg.SearchAndReplace(String::CreateFromAscii("%1"),String(_sName));
	OSQLMessageBox aAsk(_pParent,String(ModuleRes(_nTitle )),aMsg,WB_YES_NO | WB_DEF_YES,OSQLMessageBox::Query);
	if ( _bAll )
	{
		aAsk.AddButton(String(ModuleRes(STR_BUTTON_TEXT_ALL)), RET_ALL, 0);
		aAsk.GetPushButton(RET_ALL)->SetHelpId(HID_CONFIRM_DROP_BUTTON_ALL);
	}
	return aAsk.Execute();
}

// -----------------------------------------------------------------------------
namespace
{
    static ::rtl::OUString lcl_createSDBCLevelStatement( const ::rtl::OUString& _rStatement, const Reference< XConnection >& _rxConnection )
    {
        ::rtl::OUString sSDBCLevelStatement( _rStatement );
        try
        {
            Reference< XMultiServiceFactory > xAnalyzerFactory( _rxConnection, UNO_QUERY_THROW );
            Reference< XSingleSelectQueryAnalyzer > xAnalyzer( xAnalyzerFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY_THROW );
            xAnalyzer->setQuery( _rStatement );
            sSDBCLevelStatement = xAnalyzer->getQueryWithSubstitution();
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return sSDBCLevelStatement;
    }
}

// -----------------------------------------------------------------------------
Reference< XPropertySet > createView( const ::rtl::OUString& _rName, const Reference< XConnection >& _rxConnection,
                                    const ::rtl::OUString& _rCommand )
{
	Reference<XViewsSupplier> xSup(_rxConnection,UNO_QUERY);
	Reference< XNameAccess > xViews;
	if(xSup.is())
		xViews = xSup->getViews();
	Reference<XDataDescriptorFactory> xFact(xViews,UNO_QUERY);
	OSL_ENSURE(xFact.is(),"No XDataDescriptorFactory available!");
	if(!xFact.is())
		return NULL;

	Reference<XPropertySet> xView = xFact->createDataDescriptor();
	if ( !xView.is() )
		return NULL;

	::rtl::OUString sCatalog,sSchema,sTable;
	::dbtools::qualifiedNameComponents(_rxConnection->getMetaData(),
										_rName,
										sCatalog,
										sSchema,
										sTable,
										::dbtools::eInDataManipulation);

	xView->setPropertyValue(PROPERTY_CATALOGNAME,makeAny(sCatalog));
	xView->setPropertyValue(PROPERTY_SCHEMANAME,makeAny(sSchema));
	xView->setPropertyValue(PROPERTY_NAME,makeAny(sTable));

	xView->setPropertyValue( PROPERTY_COMMAND, makeAny( _rCommand ) );

	Reference<XAppend> xAppend(xViews,UNO_QUERY);
	if(xAppend.is())
		xAppend->appendByDescriptor(xView);

	xView = NULL;
	// we need to reget the view because after appending it it is no longer valid
	// but this time it isn't a view object it is a table object with type "VIEW"
	Reference<XTablesSupplier> xTabSup(_rxConnection,UNO_QUERY);
	Reference< XNameAccess > xTables;
	if ( xTabSup.is() )
	{
		xTables = xTabSup->getTables();
		if ( xTables.is() && xTables->hasByName( _rName ) )
			xTables->getByName( _rName ) >>= xView;
	}

	return xView;
}

// -----------------------------------------------------------------------------
Reference<XPropertySet> createView( const ::rtl::OUString& _rName, const Reference< XConnection >& _rxConnection
								   ,const Reference<XPropertySet>& _rxSourceObject)
{
	::rtl::OUString sCommand;
    Reference< XPropertySetInfo > xPSI( _rxSourceObject->getPropertySetInfo(), UNO_SET_THROW );
	if ( xPSI->hasPropertyByName( PROPERTY_COMMAND ) )
	{
		_rxSourceObject->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand;

        sal_Bool bEscapeProcessing( sal_False );
        OSL_VERIFY( _rxSourceObject->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
        if ( bEscapeProcessing )
            sCommand = lcl_createSDBCLevelStatement( sCommand, _rxConnection );
	}
	else
	{
		sCommand = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SELECT * FROM " ) );
		sCommand += composeTableNameForSelect( _rxConnection, _rxSourceObject );
	}
    return createView( _rName, _rxConnection, sCommand );
}

// -----------------------------------------------------------------------------
sal_Bool insertHierachyElement( Window* _pParent, const Reference< XMultiServiceFactory >& _rxORB,
						   const Reference<XHierarchicalNameContainer>& _xNames,
						   const String& _sParentFolder,
						   sal_Bool _bForm,
						   sal_Bool _bCollection,
						   const Reference<XContent>& _xContent,
						   sal_Bool _bMove)
{
    OSL_ENSURE( _xNames.is(), "insertHierachyElement: illegal name container!" );
	if ( !_xNames.is() )
        return sal_False;

    Reference<XNameAccess> xNameAccess( _xNames, UNO_QUERY );
	::rtl::OUString sName = _sParentFolder;
	if ( _xNames->hasByHierarchicalName(sName) )
	{
		Reference<XChild> xChild(_xNames->getByHierarchicalName(sName),UNO_QUERY);
		xNameAccess.set(xChild,UNO_QUERY);
		if ( !xNameAccess.is() && xChild.is() )
			xNameAccess.set(xChild->getParent(),UNO_QUERY);
	}

    OSL_ENSURE( xNameAccess.is(), "insertHierachyElement: could not find the proper name container!" );
	if ( !xNameAccess.is() )
        return sal_False;

    ::rtl::OUString sNewName;
	Reference<XPropertySet> xProp(_xContent,UNO_QUERY);
	if ( xProp.is() )
		xProp->getPropertyValue(PROPERTY_NAME) >>= sNewName;

	if ( !_bMove || !sNewName.getLength() )
	{
		String sTargetName,sLabel;
		if ( !sNewName.getLength() || xNameAccess->hasByName(sNewName) )
		{
			if ( sNewName.getLength() )
				sTargetName = sNewName;
			else
				sTargetName = String(ModuleRes( _bCollection ? STR_NEW_FOLDER : ((_bForm) ? RID_STR_FORM : RID_STR_REPORT)));
			sLabel = String(ModuleRes( _bCollection ? STR_FOLDER_LABEL  : ((_bForm) ? STR_FRM_LABEL : STR_RPT_LABEL)));
			sTargetName = ::dbtools::createUniqueName(xNameAccess,sTargetName);


			// here we have everything needed to create a new query object ...
            HierarchicalNameCheck aNameChecker( _xNames.get(), sName );
			// ... ehm, except a new name
			OSaveAsDlg aAskForName(	_pParent,
                                    _rxORB,
									sTargetName,
									sLabel,
									aNameChecker,
									SAD_ADDITIONAL_DESCRIPTION | SAD_TITLE_PASTE_AS);
			if ( RET_OK != aAskForName.Execute() )
				// cancelled by the user
				return sal_False;

			sNewName = aAskForName.getName();
		}
	}
	else if ( xNameAccess->hasByName(sNewName) )
	{
		String sError(ModuleRes(STR_NAME_ALREADY_EXISTS));
		sError.SearchAndReplaceAscii("#",sNewName);
		throw SQLException(sError,NULL,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")) ,0,Any());
	}

    try
	{
		Reference<XMultiServiceFactory> xORB( xNameAccess, UNO_QUERY_THROW );
		Sequence< Any > aArguments(3);
		PropertyValue aValue;
		// set as folder
		aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name"));
		aValue.Value <<= sNewName;
		aArguments[0] <<= aValue;
		//parent
		aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Parent"));
		aValue.Value <<= xNameAccess;
		aArguments[1] <<= aValue;

		aValue.Name = PROPERTY_EMBEDDEDOBJECT;
		aValue.Value <<= _xContent;
		aArguments[2] <<= aValue;

		::rtl::OUString sServiceName(_bCollection ? ((_bForm) ? SERVICE_NAME_FORM_COLLECTION : SERVICE_NAME_REPORT_COLLECTION) : SERVICE_SDB_DOCUMENTDEFINITION);

		Reference<XContent > xNew( xORB->createInstanceWithArguments( sServiceName, aArguments ), UNO_QUERY_THROW );
		Reference< XNameContainer > xNameContainer( xNameAccess, UNO_QUERY_THROW );
		xNameContainer->insertByName( sNewName, makeAny( xNew ) );
	}
    catch( const IllegalArgumentException& e )
    {
        ::dbtools::throwGenericSQLException( e.Message, e.Context );
    }
	catch( const Exception& )
	{
        DBG_UNHANDLED_EXCEPTION();
        return sal_False;
	}

    return sal_True;
}
// -----------------------------------------------------------------------------
Reference< XNumberFormatter > getNumberFormatter(const Reference< XConnection >& _rxConnection,const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rMF )
{
	// ---------------------------------------------------------------
	// create a formatter working with the connections format supplier
	Reference< XNumberFormatter > xFormatter;

	try
	{
		Reference< ::com::sun::star::util::XNumberFormatsSupplier >  xSupplier(::dbtools::getNumberFormats(_rxConnection, sal_True,_rMF));

		if ( xSupplier.is() )
		{
			// create a new formatter
			xFormatter = Reference< ::com::sun::star::util::XNumberFormatter > (
				_rMF->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.NumberFormatter"))), UNO_QUERY);
			if ( xFormatter.is() )
				xFormatter->attachNumberFormatsSupplier(xSupplier);
		}
	}
	catch(const Exception&)
	{
        DBG_UNHANDLED_EXCEPTION();
	}
	return xFormatter;
}


// .........................................................................
} // dbaui
// .........................................................................
