/**************************************************************
 * 
 * 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_dbui.hxx"
#ifndef DBAUI_GENERICCONTROLLER_HXX
#include "genericcontroller.hxx"
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif
#ifndef _TOOLKIT_AWT_VCLXWINDOW_HXX_
#include <toolkit/awt/vclxwindow.hxx>
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif
#ifndef DBAUI_DATAVIEW_HXX
#include "dataview.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef TOOLS_DIAGNOSE_EX_H
#include <tools/diagnose_ex.h>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _VCL_STDTEXT_HXX
#include <vcl/stdtext.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#include <framework/titlehelper.hxx>
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#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_SDB_XCOMPLETEDCONNECTION_HPP_
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
#include <com/sun/star/task/XInteractionHandler.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_
#include <com/sun/star/util/XCloseable.hpp>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _DBAUI_COMMON_TYPES_HXX_
#include "commontypes.hxx"
#endif

#ifndef _SV_WAITOBJ_HXX
#include <vcl/waitobj.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef SVTOOLS_URIHELPER_HXX
#include <svl/urihelper.hxx>
#endif
#ifndef _DBAUI_DATASOURCECONNECTOR_HXX_
#include "datasourceconnector.hxx"
#endif
#ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
#include <unotools/moduleoptions.hxx>
#endif
#ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_STATUS_VISIBILITY_HPP_
#include <com/sun/star/frame/status/Visibility.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFIABLE_HPP_
#include <com/sun/star/util/XModifiable.hpp>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _RTL_LOGFILE_HXX_
#include <rtl/logfile.hxx>
#endif
#include <algorithm>
#include <hash_map>
#include <cppuhelper/implbase1.hxx>
#include <limits>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::frame::status;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star;
using namespace ::dbtools;
using namespace ::comphelper;

// -------------------------------------------------------------------------
#define ALL_FEATURES	            -1
#define FIRST_USER_DEFINED_FEATURE  ( ::std::numeric_limits< sal_uInt16 >::max() - 1000 )
#define LAST_USER_DEFINED_FEATURE   ( ::std::numeric_limits< sal_uInt16 >::max()        )

// -------------------------------------------------------------------------
typedef ::std::hash_map< sal_Int16, sal_Int16 > CommandHashMap;
typedef ::std::list< DispatchInformation > DispatchInfoList;


// -------------------------------------------------------------------------
const ::rtl::OUString& getConfirmDeletionURL()
{
	static const ::rtl::OUString sConfirmDeletionURL( RTL_CONSTASCII_USTRINGPARAM( ".uno:FormSlots/ConfirmDeletion" ) );
	return sConfirmDeletionURL;
}

namespace dbaui
{

//==========================================================================
//= UserDefinedFeatures
//==========================================================================
class UserDefinedFeatures
{
public:
    UserDefinedFeatures( const Reference< XController >& _rxController );

    FeatureState    getState( const URL& _rFeatureURL );
    void            execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs );

private:
    ::com::sun::star::uno::WeakReference< XController > m_aController;
};

//--------------------------------------------------------------------------
UserDefinedFeatures::UserDefinedFeatures( const Reference< XController >& _rxController )
    :m_aController( _rxController )
{
}

//--------------------------------------------------------------------------
FeatureState UserDefinedFeatures::getState( const URL& /*_rFeatureURL*/ )
{
    // for now, enable all the time
    // TODO: we should ask the dispatcher. However, this is laborious, since you cannot ask a dispatcher
    // directly, but need to add a status listener.
    FeatureState aState;
    aState.bEnabled = sal_True;
    return aState;
}

//--------------------------------------------------------------------------
void UserDefinedFeatures::execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs )
{
    try
    {
        Reference< XController > xController( (Reference< XController >)m_aController, UNO_SET_THROW );
        Reference< XDispatchProvider > xDispatchProvider( xController->getFrame(), UNO_QUERY_THROW );
        Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch(
            _rFeatureURL,
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
            FrameSearchFlag::AUTO
        ) );

        if ( xDispatch == xController )
        {
            OSL_ENSURE( false, "UserDefinedFeatures::execute: the controller shouldn't be the dispatcher here!" );
            xDispatch.clear();
        }

        if ( xDispatch.is() )
            xDispatch->dispatch( _rFeatureURL, _rArgs );
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//==========================================================================
//= OGenericUnoController_Data
//==========================================================================
struct OGenericUnoController_Data
{
    ::sfx2::UserInputInterception   m_aUserInputInterception;
    UserDefinedFeatures             m_aUserDefinedFeatures;

    OGenericUnoController_Data( OGenericUnoController& _rController, ::osl::Mutex& _rMutex )
        :m_aUserInputInterception( _rController, _rMutex )
        ,m_aUserDefinedFeatures( _rController.getXController() )
    {
    }
};

//==========================================================================
//= OGenericUnoController
//==========================================================================
DBG_NAME(OGenericUnoController)
// -------------------------------------------------------------------------
OGenericUnoController::OGenericUnoController(const Reference< XMultiServiceFactory >& _rM)
	:OGenericUnoController_Base( getMutex() )
	,m_pView(NULL)
#ifdef DBG_UTIL
    ,m_bDescribingSupportedFeatures( false )
#endif
	,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll))
	,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask))
	,m_xServiceFactory(_rM)
    ,m_aCurrentFrame( *this )
	,m_bPreview(sal_False)
	,m_bReadOnly(sal_False)
	,m_bCurrentlyModified(sal_False)
    ,m_bExternalTitle(sal_False)
{
    osl_incrementInterlockedCount( &m_refCount );
    {
        m_pData.reset( new OGenericUnoController_Data( *this, getMutex() ) );
    }
    osl_decrementInterlockedCount( &m_refCount );

    DBG_CTOR(OGenericUnoController,NULL);

	try
	{
		m_xUrlTransformer = Reference< XURLTransformer > (_rM->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")), UNO_QUERY);
	}
	catch(Exception&)
	{
        DBG_UNHANDLED_EXCEPTION();
	}
}

#ifdef WNT
// -----------------------------------------------------------------------------
OGenericUnoController::OGenericUnoController()
	:OGenericUnoController_Base( getMutex() )
	,m_pView(NULL)
#ifdef DBG_UTIL
    ,m_bDescribingSupportedFeatures( false )
#endif
	,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll))
	,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask))
    ,m_aCurrentFrame( *this )
	,m_bPreview(sal_False)
	,m_bReadOnly(sal_False)
	,m_bCurrentlyModified(sal_False)
{
    OSL_ENSURE( false, "OGenericUnoController::OGenericUnoController: illegal call!" );
    // This ctor only exists because the MSVC compiler complained about an unresolved external
    // symbol. It should not be used at all. Since using it yields strange runtime problems,
    // we simply abort here.
    abort();
}
#endif

// -----------------------------------------------------------------------------
OGenericUnoController::~OGenericUnoController()
{

    DBG_DTOR(OGenericUnoController,NULL);
}

// -----------------------------------------------------------------------------
sal_Bool OGenericUnoController::Construct(Window* /*pParent*/)
{
	OSL_ENSURE( getView(), "the view is NULL!" );

	if ( getView() )
	{
		getView()->Construct();
		getView()->Show();
	}

    m_aSupportedFeatures.clear();
	fillSupportedFeatures();

	// create the database context
	DBG_ASSERT(getORB().is(), "OGenericUnoController::Construct need a service factory!");
	try
	{
		m_xDatabaseContext = Reference< XNameAccess >(getORB()->createInstance(SERVICE_SDB_DATABASECONTEXT), UNO_QUERY);
	}
	catch(Exception&)
	{
		DBG_ERROR("OGenericUnoController::Construct: could not create (or start listening at) the database context!");
	}

	if (!m_xDatabaseContext.is())
	{		// at least notify the user. Though the whole component does not make any sense without the database context ...
		ShowServiceNotAvailableError(getView(), String(SERVICE_SDB_DATABASECONTEXT), sal_True);
	}
	return sal_True;
}
//------------------------------------------------------------------------------
IMPL_LINK(OGenericUnoController, OnAsyncInvalidateAll, void*, EMPTYARG)
{
	if ( !OGenericUnoController_Base::rBHelper.bInDispose && !OGenericUnoController_Base::rBHelper.bDisposed )
		InvalidateFeature_Impl();
	return 0L;
}
// -----------------------------------------------------------------------------
void OGenericUnoController::impl_initialize()
{
}
// -------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	::osl::MutexGuard aGuard( getMutex() );

	Reference< XWindow >		xParent;
	Reference< XFrame > xFrame;

	PropertyValue aValue;
	const Any* pIter	= aArguments.getConstArray();
	const Any* pEnd 	= pIter + aArguments.getLength();

	for ( ; pIter != pEnd; ++pIter )
	{
		if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "Frame" ) ) )
		{
            xFrame.set(aValue.Value,UNO_QUERY_THROW);
		}
        /* #i42316#
		else if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "ReadOnly" ) ) )
		{
			aValue.Value >>= m_bReadOnly;
		}
        */
		else if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "Preview" ) ) )
		{
			aValue.Value >>= m_bPreview;
            m_bReadOnly = sal_True;
		}
	}
	try
	{
		if ( !xFrame.is() )
            throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "need a frame" ) ), *this, 1 );

        xParent = xFrame->getContainerWindow();
		VCLXWindow* pParentComponent = VCLXWindow::GetImplementation(xParent);
		Window* pParentWin = pParentComponent ? pParentComponent->GetWindow() : NULL;
		if (!pParentWin)
		{
			throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "Parent window is null" ), *this, 1 );
		}

        m_aInitParameters.assign( aArguments );
		Construct( pParentWin );

        ODataView* pView = getView();
        if ( !pView )
            throw RuntimeException( ::rtl::OUString::createFromAscii( "unable to create a view" ), *this );

		if ( m_bReadOnly || m_bPreview )
			pView->EnableInput( sal_False );

        impl_initialize();
	}
	catch(Exception& e)
	{
		// no one clears my view if I won't
		::std::auto_ptr<Window> aTemp(m_pView);
		m_pView = NULL;
		throw;
	}
}

//------------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::acquire(  ) throw ()
{
	OGenericUnoController_Base::acquire();
}

//------------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::release(  ) throw ()
{
	OGenericUnoController_Base::release();
}

// -------------------------------------------------------------------------
void OGenericUnoController::startFrameListening( const Reference< XFrame >& _rxFrame )
{
    if ( _rxFrame.is() )
	    _rxFrame->addFrameActionListener( this );
}

// -------------------------------------------------------------------------
void OGenericUnoController::stopFrameListening( const Reference< XFrame >& _rxFrame )
{
	if ( _rxFrame.is() )
		_rxFrame->removeFrameActionListener( this );
}

// -------------------------------------------------------------------------
void OGenericUnoController::disposing(const EventObject& Source) throw( RuntimeException )
{
	// our frame ?
	if ( Source.Source == getFrame() )
		stopFrameListening( getFrame() );
}
//------------------------------------------------------------------------
void OGenericUnoController::modified(const EventObject& aEvent) throw( RuntimeException )
{
	::osl::MutexGuard aGuard( getMutex() );
	if ( !isDataSourceReadOnly() )
	{
		Reference<XModifiable> xModi(aEvent.Source,UNO_QUERY);
		if ( xModi.is() )
			m_bCurrentlyModified = xModi->isModified(); // can only be reset by save
		else
			m_bCurrentlyModified = sal_True;
	}
	InvalidateFeature(ID_BROWSER_SAVEDOC);
	InvalidateFeature(ID_BROWSER_UNDO);
}
// -----------------------------------------------------------------------
Reference< XWindow > SAL_CALL OGenericUnoController::getComponentWindow() throw (RuntimeException)
{
	return VCLUnoHelper::GetInterface( getView() );
}

// -----------------------------------------------------------------------
::rtl::OUString SAL_CALL OGenericUnoController::getViewControllerName() throw (::com::sun::star::uno::RuntimeException)
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) );
}

// -----------------------------------------------------------------------
Sequence< PropertyValue > SAL_CALL OGenericUnoController::getCreationArguments() throw (RuntimeException)
{
    // currently we do not support any creation args, so anything passed to XModel2::createViewController would be
    // lost, so we can equally return an empty sequence here
    return Sequence< PropertyValue >();
}

// -----------------------------------------------------------------------
void OGenericUnoController::attachFrame( const Reference< XFrame >& _rxFrame ) throw( RuntimeException )
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	::osl::MutexGuard aGuard( getMutex() );

    stopFrameListening( m_aCurrentFrame.getFrame() );
	Reference< XFrame > xFrame = m_aCurrentFrame.attachFrame( _rxFrame );
	startFrameListening( xFrame );

	loadMenu( xFrame );

	if ( getView() )
		getView()->attachFrame( xFrame );
}

// -----------------------------------------------------------------------------
struct CommandCollector : public ::std::unary_function< SupportedFeatures::value_type, void>
{
	sal_uInt16  m_nFeature;
	StringBag&  m_rFeatureCommands;
	CommandCollector( sal_uInt16 _nFeature, StringBag& _rFeatureCommands )
        :m_nFeature        ( _nFeature         )
        ,m_rFeatureCommands( _rFeatureCommands )
    {
    }

	void operator() ( const SupportedFeatures::value_type& lhs )
	{
		if ( lhs.second.nFeatureId == m_nFeature )
			m_rFeatureCommands.insert( lhs.first );
	}
};

// -----------------------------------------------------------------------
namespace
{
    typedef ::std::vector< Any >    States;

    // ...................................................................
    void    lcl_notifyMultipleStates( XStatusListener& _rListener, FeatureStateEvent& _rEvent, const States& _rStates )
    {
        for (   States::const_iterator state = _rStates.begin();
                state != _rStates.end();
                ++state
            )
        {
            _rEvent.State = *state;
            _rListener.statusChanged( _rEvent );
        }
    }

    // ...................................................................
    void    lcl_collectStates( const FeatureState& _rFeatureState, States& _out_rStates )
    {
        // order matters, due to a bug in framework which resets the check state when any non-boolean event
        // arrives
        // #i68215# is the bug to (re-)introduce this "ordered" notification here
        // #i67882# is the bug which was caused by the real fix which we did in framework
        // #i68216# is the bug which requests to fix the code in Draw which relies on
        //          framework's implementation details
        // 2006-08-07 / frank.schoenheit@sun.com
        if ( !!_rFeatureState.sTitle )
            _out_rStates.push_back( makeAny( *_rFeatureState.sTitle ) );
        if ( !!_rFeatureState.bChecked )
            _out_rStates.push_back( makeAny( (sal_Bool)*_rFeatureState.bChecked ) );
        if ( !!_rFeatureState.bInvisible )
            _out_rStates.push_back( makeAny( Visibility( !*_rFeatureState.bInvisible ) ) );
        if ( _rFeatureState.aValue.hasValue() )
            _out_rStates.push_back( _rFeatureState.aValue );
        if ( _out_rStates.empty() )
            _out_rStates.push_back( Any() );
    }
}

// -----------------------------------------------------------------------
void OGenericUnoController::ImplBroadcastFeatureState(const ::rtl::OUString& _rFeature, const Reference< XStatusListener > & xListener, sal_Bool _bIgnoreCache)
{
	sal_uInt16 nFeat = m_aSupportedFeatures[ _rFeature ].nFeatureId;
	FeatureState aFeatState( GetState( nFeat ) );

	FeatureState& rCachedState = m_aStateCache[nFeat];	// creates if neccessary
	if ( !_bIgnoreCache )
	{
		// check if we really need to notify the listeners : this method may be called much more often than needed, so check
		// the cached state of the feature
		sal_Bool bAlreadyCached = ( m_aStateCache.find(nFeat) != m_aStateCache.end() );
		if ( bAlreadyCached )
            if  (   ( rCachedState.bEnabled == aFeatState.bEnabled )
                &&  ( rCachedState.bChecked == aFeatState.bChecked )
                &&  ( rCachedState.bInvisible == aFeatState.bInvisible )
                &&  ( rCachedState.sTitle == aFeatState.sTitle )
                )
            return;
	}
	rCachedState = aFeatState;

	FeatureStateEvent aEvent;
	aEvent.FeatureURL.Complete = _rFeature;
	if (m_xUrlTransformer.is())
		m_xUrlTransformer->parseStrict(aEvent.FeatureURL);
	aEvent.Source		= (XDispatch*)this;
	aEvent.IsEnabled	= aFeatState.bEnabled;

    // collect all states to be notified
    States aStates;
    lcl_collectStates( aFeatState, aStates );

	// a special listener ?
	if ( xListener.is() )
        lcl_notifyMultipleStates( *xListener.get(), aEvent, aStates );
	else
	{	// no -> iterate through all listeners responsible for the URL
        StringBag aFeatureCommands;
		::std::for_each(
            m_aSupportedFeatures.begin(),
            m_aSupportedFeatures.end(),
            CommandCollector( nFeat, aFeatureCommands )
        );

		// it is possible that listeners are registered or revoked while
		// we are notifying them, so we must use a copy of m_arrStatusListener, not
		// m_arrStatusListener itself
		// #121276# / 2005-05-19 / frank.schoenheit@sun.com
		Dispatch aNotifyLoop( m_arrStatusListener );
		DispatchIterator iterSearch = aNotifyLoop.begin();
		DispatchIterator iterEnd = aNotifyLoop.end();

		while (iterSearch != iterEnd)
		{
			DispatchTarget& rCurrent = *iterSearch;
			if ( aFeatureCommands.find( rCurrent.aURL.Complete ) != aFeatureCommands.end() )
			{
				aEvent.FeatureURL = rCurrent.aURL;
                lcl_notifyMultipleStates( *rCurrent.xListener.get(), aEvent, aStates );
			}
			++iterSearch;
		}
	}

}

//------------------------------------------------------------------------------
sal_Bool OGenericUnoController::isFeatureSupported( sal_Int32 _nId )
{
	SupportedFeatures::iterator aFeaturePos = ::std::find_if(
		m_aSupportedFeatures.begin(),
		m_aSupportedFeatures.end(),
		::std::bind2nd( CompareFeatureById(), _nId )
	);

    return ( m_aSupportedFeatures.end() != aFeaturePos && aFeaturePos->first.getLength());
}

// -----------------------------------------------------------------------
void OGenericUnoController::InvalidateFeature(const ::rtl::OUString& _rURLPath, const Reference< XStatusListener > & _xListener, sal_Bool _bForceBroadcast)
{
	ImplInvalidateFeature( m_aSupportedFeatures[ _rURLPath ].nFeatureId, _xListener, _bForceBroadcast );
}

// -----------------------------------------------------------------------------
void OGenericUnoController::InvalidateFeature_Impl()
{
#ifdef DBG_UTIL
	static sal_Int32 s_nRecursions = 0;
	++s_nRecursions;
#endif

	sal_Bool bEmpty = sal_True;
	FeatureListener aNextFeature;
	{
		::osl::MutexGuard aGuard( m_aFeatureMutex);
		bEmpty = m_aFeaturesToInvalidate.empty();
		if (!bEmpty)
			aNextFeature = m_aFeaturesToInvalidate.front();
	}
	while(!bEmpty)
	{
		if ( ALL_FEATURES == aNextFeature.nId )
		{
			InvalidateAll_Impl();
			break;
		}
		else
		{
			SupportedFeatures::iterator aFeaturePos = ::std::find_if(
				m_aSupportedFeatures.begin(),
				m_aSupportedFeatures.end(),
				::std::bind2nd( CompareFeatureById(), aNextFeature.nId )
			);

#if OSL_DEBUG_LEVEL > 0
            if ( m_aSupportedFeatures.end() == aFeaturePos )
            {
                ::rtl::OString sMessage( "OGenericUnoController::InvalidateFeature_Impl: feature id " );
                sMessage += ::rtl::OString::valueOf( aNextFeature.nId );
                sMessage += ::rtl::OString( " has been invalidated, but is not supported!" );
                OSL_ENSURE( false, sMessage.getStr() );
            }
#endif
			if ( m_aSupportedFeatures.end() != aFeaturePos )
				// we really know this feature
				ImplBroadcastFeatureState( aFeaturePos->first, aNextFeature.xListener, aNextFeature.bForceBroadcast );
		}

		::osl::MutexGuard aGuard( m_aFeatureMutex);
		m_aFeaturesToInvalidate.pop_front();
		bEmpty = m_aFeaturesToInvalidate.empty();
		if (!bEmpty)
			aNextFeature = m_aFeaturesToInvalidate.front();
	}

#ifdef DBG_UTIL
	--s_nRecursions;
#endif
}

// -----------------------------------------------------------------------
void OGenericUnoController::ImplInvalidateFeature( sal_Int32 _nId, const Reference< XStatusListener >& _xListener, sal_Bool _bForceBroadcast )
{
#if OSL_DEBUG_LEVEL > 0
    if ( _nId != -1 )
    {
	    SupportedFeatures::iterator aFeaturePos = ::std::find_if(
		    m_aSupportedFeatures.begin(),
		    m_aSupportedFeatures.end(),
		    ::std::bind2nd( CompareFeatureById(), _nId )
	    );
        OSL_ENSURE( aFeaturePos != m_aSupportedFeatures.end(), "OGenericUnoController::ImplInvalidateFeature: invalidating an unsupported feature is suspicious, at least!" );
    }
#endif

	FeatureListener aListener;
	aListener.nId               = _nId;
	aListener.xListener         = _xListener;
	aListener.bForceBroadcast   = _bForceBroadcast;

	sal_Bool bWasEmpty;
	{
		::osl::MutexGuard aGuard( m_aFeatureMutex );
		bWasEmpty = m_aFeaturesToInvalidate.empty();
		m_aFeaturesToInvalidate.push_back( aListener );
	}

	if ( bWasEmpty )
		m_aAsyncInvalidateAll.Call();
}

// -----------------------------------------------------------------------
void OGenericUnoController::InvalidateFeature(sal_uInt16 _nId, const Reference< XStatusListener > & _xListener, sal_Bool _bForceBroadcast)
{
	ImplInvalidateFeature( _nId, _xListener, _bForceBroadcast );
}

// -----------------------------------------------------------------------
void OGenericUnoController::InvalidateAll()
{
	ImplInvalidateFeature( ALL_FEATURES, NULL, sal_True );
}

// -----------------------------------------------------------------------------
void OGenericUnoController::InvalidateAll_Impl()
{
	// ---------------------------------
	// invalidate all aupported features

	for (   SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin();
            aIter != m_aSupportedFeatures.end();
            ++aIter
        )
		ImplBroadcastFeatureState( aIter->first, NULL, sal_True );

	{
		::osl::MutexGuard aGuard( m_aFeatureMutex);
		DBG_ASSERT(m_aFeaturesToInvalidate.size(), "OGenericUnoController::InvalidateAll_Impl: to be called from within InvalidateFeature_Impl only!");
		m_aFeaturesToInvalidate.pop_front();
		if(!m_aFeaturesToInvalidate.empty())
			m_aAsyncInvalidateAll.Call();
	}
}

// -----------------------------------------------------------------------
Reference< XDispatch >	OGenericUnoController::queryDispatch(const URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException )
{
	Reference< XDispatch > xReturn;

    OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::queryDispatch: shouldn't this be filled at construction time?" );
    if ( m_aSupportedFeatures.empty() )
        fillSupportedFeatures();

	// URL's we can handle ourself?
	if  (   aURL.Complete.equals( getConfirmDeletionURL() )
        ||  (   ( m_aSupportedFeatures.find( aURL.Complete ) != m_aSupportedFeatures.end() )
            &&  !isUserDefinedFeature( aURL.Complete )
            )
        )
	{
		xReturn = this;
	}
	// no? -> ask the slave dispatcher
	else if ( m_xSlaveDispatcher.is() )
	{
		xReturn = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
	}

	// outta here
	return xReturn;
}

// -----------------------------------------------------------------------
Sequence< Reference< XDispatch > > OGenericUnoController::queryDispatches(const Sequence< DispatchDescriptor >& aDescripts) throw( RuntimeException )
{
	Sequence< Reference< XDispatch > > aReturn;
	sal_Int32 nLen = aDescripts.getLength();
	if ( nLen )
	{
		aReturn.realloc( nLen );
				Reference< XDispatch >* pReturn 	= aReturn.getArray();
		const	Reference< XDispatch >* pReturnEnd	= aReturn.getArray() + nLen;
		const	DispatchDescriptor* 	pDescripts	= aDescripts.getConstArray();

		for ( ; pReturn != pReturnEnd; ++ pReturn, ++pDescripts )
		{
			*pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags );
		}
	}

	return aReturn;
}

// -----------------------------------------------------------------------
Reference< XDispatchProvider >	OGenericUnoController::getSlaveDispatchProvider(void) throw( RuntimeException )
{
	return m_xSlaveDispatcher;
}

// -----------------------------------------------------------------------
void OGenericUnoController::setSlaveDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException )
{
	m_xSlaveDispatcher = _xNewProvider;
}

// -----------------------------------------------------------------------
Reference< XDispatchProvider >	OGenericUnoController::getMasterDispatchProvider(void) throw( RuntimeException )
{
	return m_xMasterDispatcher;
}

// -----------------------------------------------------------------------
void OGenericUnoController::setMasterDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException )
{
	m_xMasterDispatcher = _xNewProvider;
}

// -----------------------------------------------------------------------
void OGenericUnoController::dispatch(const URL& _aURL, const Sequence< PropertyValue >& aArgs) throw(RuntimeException)
{
    ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
    // Since the fix for #123967#, the SolarMutex is not locked anymore when the framework calls into
    // here. So, lock it ourself. The real solution would be to lock it only in the places
    // where it's needed, but a) this might turn out difficult, since we then also need to care
    // for locking in the proper order (SolarMutex and m_aMutex), and b) this would be too many places
    // for the time frame of the fix.
    // #i52602# / frank.schoenheit@sun.com / 2005-07-29

#ifdef TIMELOG
    ::rtl::OString sLog( "OGenericUnoController::dispatch( '" );
    sLog += ::rtl::OString( _aURL.Main.getStr(), _aURL.Main.getLength(), osl_getThreadTextEncoding() );
    sLog += ::rtl::OString( "' )" );
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", sLog.getStr() );
#endif

    executeChecked(_aURL,aArgs);
}

// -----------------------------------------------------------------------
void OGenericUnoController::addStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException)
{
    // parse the ULR now and here, this saves later parsing in each notification round
    URL aParsedURL( _rURL );
	if ( m_xUrlTransformer.is() )
		m_xUrlTransformer->parseStrict( aParsedURL );

    // remeber the listener together with the URL
	m_arrStatusListener.insert( m_arrStatusListener.end(), DispatchTarget( aParsedURL, aListener ) );

    // initially broadcast the state
	ImplBroadcastFeatureState( aParsedURL.Complete, aListener, sal_True );
		// force the new state to be broadcasted to the new listener
}

// -----------------------------------------------------------------------
void OGenericUnoController::removeStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException)
{
	DispatchIterator iterSearch = m_arrStatusListener.begin();

	sal_Bool bRemoveForAll = (_rURL.Complete.getLength() == 0);
	while ( iterSearch != m_arrStatusListener.end() )
	{
		DispatchTarget& rCurrent = *iterSearch;
		if	(	(rCurrent.xListener == aListener)
			&&	(	bRemoveForAll
				||	(rCurrent.aURL.Complete.equals(_rURL.Complete))
				)
			)
		{
			m_arrStatusListener.erase( iterSearch );
			if (!bRemoveForAll)
				// remove the listener only for the given URL, so we can exit the loop after deletion
				break;
		}
		else
			++iterSearch;
	}

    OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::removeStatusListener: shouldn't this be filled at construction time?" );
    if ( m_aSupportedFeatures.empty() )
        fillSupportedFeatures();

	SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find(_rURL.Complete);
	if (aIter != m_aSupportedFeatures.end())
	{	// clear the cache for that feature
		StateCacheIterator aCachePos = m_aStateCache.find( aIter->second.nFeatureId );
		if ( aCachePos != m_aStateCache.end() )
			m_aStateCache.erase( aCachePos );
	}

	// now remove the listener from the deque
	::osl::MutexGuard aGuard( m_aFeatureMutex );
	m_aFeaturesToInvalidate.erase(
		::std::remove_if(	m_aFeaturesToInvalidate.begin(),
							m_aFeaturesToInvalidate.end(),
							::std::bind2nd(FindFeatureListener(),aListener))
		,m_aFeaturesToInvalidate.end());
}
// -----------------------------------------------------------------------------
void OGenericUnoController::releaseNumberForComponent()
{
    try
    {
        Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY      );
        if ( xUntitledProvider.is() )
            xUntitledProvider->releaseNumberForComponent(static_cast<XWeak*>(this));
    }
    catch( const Exception& )
	{
        // NII
	}
}
// -----------------------------------------------------------------------
void OGenericUnoController::disposing()
{
	{
		EventObject aDisposeEvent;
		aDisposeEvent.Source = static_cast<XWeak*>(this);
		Dispatch aStatusListener = m_arrStatusListener;
		Dispatch::iterator aEnd = aStatusListener.end();
		for (Dispatch::iterator aIter = aStatusListener.begin(); aIter != aEnd; ++aIter)
		{
			aIter->xListener->disposing(aDisposeEvent);
		}
		m_arrStatusListener.clear();
	}

	m_xDatabaseContext = NULL;
	{
		::osl::MutexGuard aGuard( m_aFeatureMutex);
		m_aAsyncInvalidateAll.CancelCall();
		m_aFeaturesToInvalidate.clear();
	}

    releaseNumberForComponent();

	// check out from all the objects we are listening
	// the frame
	stopFrameListening( m_aCurrentFrame.getFrame() );
    m_aCurrentFrame.attachFrame( NULL );

    m_xMasterDispatcher = NULL;
    m_xSlaveDispatcher = NULL;
    m_xServiceFactory = NULL;
	m_xTitleHelper.clear();
    m_xUrlTransformer.clear();
    m_aInitParameters.clear();
}

// -----------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
{
    // disambiguate
    OGenericUnoController_Base::WeakComponentImplHelperBase::addEventListener( xListener );
}

// -----------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
{
    // disambiguate
    OGenericUnoController_Base::WeakComponentImplHelperBase::removeEventListener( xListener );
}

//------------------------------------------------------------------------------
void OGenericUnoController::frameAction(const FrameActionEvent& aEvent) throw( RuntimeException )
{
    ::osl::MutexGuard aGuard( getMutex() );
    if ( aEvent.Frame == m_aCurrentFrame.getFrame() )
        m_aCurrentFrame.frameAction( aEvent.Action );
}

//------------------------------------------------------------------------------
void OGenericUnoController::implDescribeSupportedFeature( const sal_Char* _pAsciiCommandURL,
        sal_uInt16 _nFeatureId, sal_Int16 _nCommandGroup )
{
#ifdef DBG_UTIL
    DBG_ASSERT( m_bDescribingSupportedFeatures, "OGenericUnoController::implDescribeSupportedFeature: bad timing for this call!" );
#endif
    OSL_PRECOND( _nFeatureId < FIRST_USER_DEFINED_FEATURE, "OGenericUnoController::implDescribeSupportedFeature: invalid feature id!" );

    ControllerFeature aFeature;
    aFeature.Command = ::rtl::OUString::createFromAscii( _pAsciiCommandURL );
    aFeature.nFeatureId = _nFeatureId;
    aFeature.GroupId = _nCommandGroup;

#if OSL_DEBUG_LEVEL > 0
    OSL_ENSURE( m_aSupportedFeatures.find( aFeature.Command ) == m_aSupportedFeatures.end(),
        "OGenericUnoController::implDescribeSupportedFeature: this feature is already there!" );
#endif
    m_aSupportedFeatures[ aFeature.Command ] = aFeature;
}

//------------------------------------------------------------------------------
void OGenericUnoController::describeSupportedFeatures()
{
    // add all supported features
    implDescribeSupportedFeature( ".uno:Copy", ID_BROWSER_COPY, CommandGroup::EDIT );
	implDescribeSupportedFeature( ".uno:Cut", ID_BROWSER_CUT, CommandGroup::EDIT );
	implDescribeSupportedFeature( ".uno:Paste", ID_BROWSER_PASTE, CommandGroup::EDIT );
	implDescribeSupportedFeature( ".uno:ClipboardFormatItems", ID_BROWSER_CLIPBOARD_FORMAT_ITEMS );
	implDescribeSupportedFeature( ".uno:DSBEditDoc", ID_BROWSER_EDITDOC, CommandGroup::DOCUMENT );
}

//------------------------------------------------------------------------------
FeatureState OGenericUnoController::GetState( sal_uInt16 _nId ) const
{
	FeatureState aReturn;
		// (disabled automatically)

	switch ( _nId )
	{
		case ID_BROWSER_UNDO:
		case ID_BROWSER_SAVEDOC:
			aReturn.bEnabled = sal_True;
			break;
        default:
            aReturn = m_pData->m_aUserDefinedFeatures.getState( getURLForId( _nId ) );
            break;
	}

	return aReturn;
}

//------------------------------------------------------------------------------
void OGenericUnoController::Execute( sal_uInt16 _nId, const Sequence< PropertyValue>& _rArgs )
{
    OSL_ENSURE( isUserDefinedFeature( _nId ),
        "OGenericUnoController::Execute: responsible for user defined features only!" );

    // user defined features can be handled by dispatch interceptors resp. protocol handlers only.
    // So, we need to do a queryDispatch, and dispatch the URL
    m_pData->m_aUserDefinedFeatures.execute( getURLForId( _nId ), _rArgs );
}

//------------------------------------------------------------------------------
URL OGenericUnoController::getURLForId(sal_Int32 _nId) const
{
	URL aReturn;
	if ( m_xUrlTransformer.is() )
	{
		SupportedFeatures::const_iterator aIter = ::std::find_if(
			m_aSupportedFeatures.begin(),
			m_aSupportedFeatures.end(),
			::std::bind2nd( CompareFeatureById(), _nId )
		);

		if ( m_aSupportedFeatures.end() != aIter && aIter->first.getLength() )
		{
			aReturn.Complete = aIter->first;
			m_xUrlTransformer->parseStrict( aReturn );
		}
	}
	return aReturn;
}

//-------------------------------------------------------------------------
bool OGenericUnoController::isUserDefinedFeature( const sal_uInt16 _nFeatureId ) const
{
    return ( _nFeatureId >= FIRST_USER_DEFINED_FEATURE ) && ( _nFeatureId < LAST_USER_DEFINED_FEATURE );
}

//-------------------------------------------------------------------------
bool OGenericUnoController::isUserDefinedFeature( const ::rtl::OUString& _rFeatureURL ) const
{
    SupportedFeatures::const_iterator pos = m_aSupportedFeatures.find( _rFeatureURL );
    OSL_PRECOND( pos != m_aSupportedFeatures.end(),
        "OGenericUnoController::isUserDefinedFeature: this is no supported feature at all!" );

    return ( pos != m_aSupportedFeatures.end() ) ? isUserDefinedFeature( pos->second.nFeatureId ) : false;
}

//-------------------------------------------------------------------------
sal_Bool SAL_CALL OGenericUnoController::supportsService(const ::rtl::OUString& ServiceName) throw(RuntimeException)
{
	Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());

	const ::rtl::OUString* pArray = aSupported.getConstArray();
	const ::rtl::OUString* pArrayEnd = aSupported.getConstArray() + aSupported.getLength();

	for ( ;( pArray != pArrayEnd ) && !pArray->equals( ServiceName ); ++pArray )
		;
	return pArray != pArrayEnd;
}

// -----------------------------------------------------------------------------
void OGenericUnoController::startConnectionListening(const Reference< XConnection >& _rxConnection)
{
	// we have to remove ourself before dispoing the connection
	Reference< XComponent >  xComponent(_rxConnection, UNO_QUERY);
	if (xComponent.is())
		xComponent->addEventListener(static_cast<XFrameActionListener*>(this));
}

// -----------------------------------------------------------------------------
void OGenericUnoController::stopConnectionListening(const Reference< XConnection >& _rxConnection)
{
	// we have to remove ourself before dispoing the connection
	Reference< XComponent >  xComponent(_rxConnection, UNO_QUERY);
	if (xComponent.is())
		xComponent->removeEventListener(static_cast<XFrameActionListener*>(this));
}
// -----------------------------------------------------------------------------
Reference< XConnection > OGenericUnoController::connect( const Reference< XDataSource>& _xDataSource,
    ::dbtools::SQLExceptionInfo* _pErrorInfo )
{
	WaitObject aWaitCursor( getView() );

	ODatasourceConnector aConnector( getORB(), getView(), ::rtl::OUString() );
	Reference< XConnection > xConnection = aConnector.connect( _xDataSource, _pErrorInfo );
	startConnectionListening( xConnection );

	return xConnection;
}
// -----------------------------------------------------------------------------
Reference< XConnection > OGenericUnoController::connect( const ::rtl::OUString& _rDataSourceName,
    const ::rtl::OUString& _rContextInformation, ::dbtools::SQLExceptionInfo* _pErrorInfo )
{
	WaitObject aWaitCursor( getView() );

	ODatasourceConnector aConnector( getORB(), getView(), _rContextInformation );
	Reference<XConnection> xConnection = aConnector.connect( _rDataSourceName, _pErrorInfo );
	startConnectionListening( xConnection );

	return xConnection;
}

// -----------------------------------------------------------------------------
void OGenericUnoController::showError(const SQLExceptionInfo& _rInfo)
{
	::dbaui::showError(_rInfo,getView(),getORB());
}
// -----------------------------------------------------------------------------
Reference< XLayoutManager > OGenericUnoController::getLayoutManager(const Reference< XFrame >& _xFrame) const
{
	Reference< XPropertySet > xPropSet( _xFrame, UNO_QUERY );
    Reference< XLayoutManager > xLayoutManager;
	if ( xPropSet.is() )
    {
        try
        {
			xLayoutManager.set(xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY);
        }
        catch ( Exception& )
        {
        }
    }
	return xLayoutManager;
}
// -----------------------------------------------------------------------------
void OGenericUnoController::loadMenu(const Reference< XFrame >& _xFrame)
{
    Reference< XLayoutManager > xLayoutManager = getLayoutManager(_xFrame);
    if ( xLayoutManager.is() )
	{
		xLayoutManager->lock();
        xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" )));
		xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" )));
		xLayoutManager->unlock();
		xLayoutManager->doLayout();
	}

    onLoadedMenu( xLayoutManager );
}

// -----------------------------------------------------------------------------
void OGenericUnoController::onLoadedMenu(const Reference< XLayoutManager >& /*_xLayoutManager*/)
{
    // not interested in
}

// -----------------------------------------------------------------------------
void OGenericUnoController::closeTask()
{
	m_aAsyncCloseTask.Call();
}
// -----------------------------------------------------------------------------
IMPL_LINK(OGenericUnoController, OnAsyncCloseTask, void*, EMPTYARG)
{
	if ( !OGenericUnoController_Base::rBHelper.bInDispose )
	{
        try
        {
            Reference< util::XCloseable > xCloseable( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW );
            xCloseable->close( sal_False ); // false - holds the owner ship for this frame inside this object!
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
	}
	return 0L;
}
// -----------------------------------------------------------------------------
Any SAL_CALL OGenericUnoController::getViewData(void) throw( RuntimeException )
{
	return Any();
}
// -----------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::restoreViewData(const Any& /*Data*/) throw( RuntimeException )
{
}

// -----------------------------------------------------------------------------
Reference< XModel > SAL_CALL OGenericUnoController::getModel(void) throw( RuntimeException )
{
    return Reference< XModel >();
}

// -----------------------------------------------------------------------------
Reference< XFrame > SAL_CALL OGenericUnoController::getFrame(void) throw( RuntimeException )
{
    ::osl::MutexGuard aGuard( getMutex() );
    return m_aCurrentFrame.getFrame();
}

// -----------------------------------------------------------------------------
sal_Bool SAL_CALL OGenericUnoController::attachModel(const Reference< XModel > & /*xModel*/) throw( RuntimeException )
{
    OSL_ENSURE( false, "OGenericUnoController::attachModel: not supported!" );
    return sal_False;
}

// -----------------------------------------------------------------------------
void OGenericUnoController::executeUnChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs)
{
	Execute(_nCommandId, aArgs);
}
// -----------------------------------------------------------------------------
void OGenericUnoController::executeUnChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs)
{
    OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeUnChecked: shouldn't this be filled at construction time?" );
    if ( m_aSupportedFeatures.empty() )
        fillSupportedFeatures();

    SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete );
	if (aIter != m_aSupportedFeatures.end())
		Execute( aIter->second.nFeatureId, aArgs );
}
// -----------------------------------------------------------------------------
void OGenericUnoController::executeChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs)
{
    OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeChecked: shouldn't this be filled at construction time?" );
    if ( m_aSupportedFeatures.empty() )
        fillSupportedFeatures();

    SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete );
	if ( aIter != m_aSupportedFeatures.end() )
	{
		sal_uInt16 nFeatureId = aIter->second.nFeatureId;
		if ( GetState( nFeatureId ).bEnabled )
			Execute( nFeatureId, aArgs );
	}
}
// -----------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace
{
	::rtl::OUString lcl_getModuleHelpModuleName( const Reference< XFrame >& _rxFrame )
	{
		const sal_Char* pReturn = NULL;

		try
		{
			// get the model of the document in the given frame
			Reference< XController > xController;
			if ( _rxFrame.is() )
				xController = _rxFrame->getController();
			Reference< XModel > xModel;
			if ( xController.is() )
				xModel = xController->getModel();
			Reference< XServiceInfo > xSI( xModel, UNO_QUERY );

			if ( !xSI.is() )
			{	// try to go up the frame hierarchy

				Reference< XFrame > xParentFrame;
				if ( _rxFrame.is() )
					xParentFrame = xParentFrame.query( _rxFrame->getCreator() );
				// did we find a parent frame? Which is no top-level frame?
				if ( xParentFrame.is() && !_rxFrame->isTop() )
					// TODO: to prevent framework assertions, re-insert this "isTop" once 98303 is fixed
					return lcl_getModuleHelpModuleName( xParentFrame );
			}
			else
			{
#if OSL_DEBUG_LEVEL > 0
				Sequence< ::rtl::OUString > sServiceNames = xSI->getSupportedServiceNames();
				const ::rtl::OUString* pLoop = sServiceNames.getConstArray();
				for ( sal_Int32 i=0; i<sServiceNames.getLength(); ++i, ++pLoop )
				{
					sal_Int32 nDummy = 0;
                    (void)nDummy;
				}
#endif

				// check which service we know ....
				static const sal_Char* pTransTable[] = {
					"com.sun.star.sdb.OfficeDatabaseDocument","sdatabase",
                    "com.sun.star.report.ReportDefinition","sdatabase",
					"com.sun.star.text.TextDocument",	"swriter",
					"com.sun.star.sheet.SpreadsheetDocument", "scalc",
					"com.sun.star.presentation.PresentationDocument", "simpress",
					"com.sun.star.drawing.DrawingDocument", "sdraw",
					"com.sun.star.formula.FormularProperties", "smath",
					"com.sun.star.chart.ChartDocument", "schart"
				};
				OSL_ENSURE( ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) % 2 == 0,
					"lcl_getModuleHelpModuleName: odd size of translation table!" );

				// loop through the table
				sal_Int32 nTableEntries = ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) / 2;
				const sal_Char** pDocumentService = pTransTable;
				const sal_Char** pHelpModuleName = pTransTable + 1;
				for ( sal_Int32 j=0; j<nTableEntries; ++j )
				{
					if ( xSI->supportsService( ::rtl::OUString::createFromAscii( *pDocumentService ) ) )
					{	// found a table entry which matches the model's services
						pReturn = *pHelpModuleName;
						break;
					}

					++pDocumentService; ++pDocumentService;
					++pHelpModuleName; ++pHelpModuleName;
				}
			}

			if ( !pReturn )
			{
				// could not determine the document type we're living in
				// ->fallback
				SvtModuleOptions aModOpt;
				if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
					pReturn = "swriter";
				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
					pReturn = "sdatabase";
				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
					pReturn = "scalc";
				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
					pReturn = "simpress";
				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
					pReturn = "sdraw";
				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
					pReturn = "smath";
				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCHART ) )
					pReturn = "schart";
				else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SBASIC ) )
					pReturn = "sbasic";
				else
				{
					OSL_ENSURE( sal_False, "lcl_getModuleHelpModuleName: no installed module found" );
				}
			}
		}
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

		if ( !pReturn )
			pReturn = "swriter";

		return ::rtl::OUString::createFromAscii( pReturn );
	}
}

// -----------------------------------------------------------------------------

void OGenericUnoController::openHelpAgent(rtl::OUString const& _suHelpStringURL )
{
    rtl::OUString suURL(_suHelpStringURL);
    rtl::OUString sLanguage = rtl::OUString::createFromAscii("Language=");
    if (suURL.indexOf(sLanguage) == -1)
    {
        AppendConfigToken(suURL, sal_False /* sal_False := add '&' */ );
    }
    URL aURL;
    aURL.Complete = suURL;

    openHelpAgent( aURL );
}

void OGenericUnoController::openHelpAgent(const rtl::OString& _sHelpId)
{
	openHelpAgent( createHelpAgentURL( lcl_getModuleHelpModuleName( getFrame() ), _sHelpId ) );
}

void OGenericUnoController::openHelpAgent( const URL& _rURL )
{
	try
	{
        URL aURL( _rURL );

        if ( m_xUrlTransformer.is() )
            m_xUrlTransformer->parseStrict(aURL);

		Reference< XDispatchProvider > xDispProv( m_aCurrentFrame.getFrame(), UNO_QUERY );
		Reference< XDispatch > xHelpDispatch;
		if ( xDispProv.is() )
			xHelpDispatch = xDispProv->queryDispatch(aURL, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_helpagent")), FrameSearchFlag::PARENT | FrameSearchFlag::SELF);
		OSL_ENSURE(xHelpDispatch.is(), "SbaTableQueryBrowser::openHelpAgent: could not get a dispatcher!");
		if (xHelpDispatch.is())
		{
			xHelpDispatch->dispatch(aURL, Sequence< PropertyValue >());
		}
	}
    catch( const Exception& )
    {
        DBG_UNHANDLED_EXCEPTION();
    }
}
// -----------------------------------------------------------------------------
Reference< awt::XWindow> OGenericUnoController::getTopMostContainerWindow() const
{
	Reference< ::com::sun::star::awt::XWindow> xWindow;

    // get the top most window
    Reference< XFrame > xFrame( m_aCurrentFrame.getFrame() );
	if ( xFrame.is() )
	{
		xWindow = xFrame->getContainerWindow();

        while ( xFrame.is() && !xFrame->isTop() )
		{
			xFrame.set( xFrame->getCreator(), UNO_QUERY );
		}
		if ( xFrame.is() )
			xWindow = xFrame->getContainerWindow();
	}
	return xWindow;
}
// -----------------------------------------------------------------------------
Reference< XTitle > OGenericUnoController::impl_getTitleHelper_throw()
{
    ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
    ::osl::MutexGuard aGuard( getMutex() );

    if ( ! m_xTitleHelper.is ())
    {
        Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY      );
        Reference< XController >      xThis(static_cast< XController* >(this), UNO_QUERY_THROW);

        ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(m_xServiceFactory);
        m_xTitleHelper.set( static_cast< ::cppu::OWeakObject* >(pHelper), UNO_QUERY_THROW);

        pHelper->setOwner                   (xThis            );
        pHelper->connectWithUntitledNumbers (xUntitledProvider);
    }

    return m_xTitleHelper;
}

//=============================================================================
// XTitle
::rtl::OUString SAL_CALL OGenericUnoController::getTitle()
    throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
    if ( m_bExternalTitle )
        return impl_getTitleHelper_throw()->getTitle ();
    return getPrivateTitle() + impl_getTitleHelper_throw()->getTitle ();
}

//=============================================================================
// XTitle
void SAL_CALL OGenericUnoController::setTitle(const ::rtl::OUString& sTitle)
    throw (RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	::osl::MutexGuard aGuard( getMutex() );
    m_bExternalTitle = sal_True;
    impl_getTitleHelper_throw()->setTitle (sTitle);
}

//=============================================================================
// XTitleChangeBroadcaster
void SAL_CALL OGenericUnoController::addTitleChangeListener(const Reference< XTitleChangeListener >& xListener)
    throw (RuntimeException)
{
    Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY);
    if (xBroadcaster.is ())
        xBroadcaster->addTitleChangeListener (xListener);
}

// -----------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::removeTitleChangeListener(const Reference< XTitleChangeListener >& xListener)
    throw (RuntimeException)
{
    Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY);
    if (xBroadcaster.is ())
        xBroadcaster->removeTitleChangeListener (xListener);
}

// =============================================================================
// XUserInputInterception
// -----------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::addKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException)
{
    if ( _rxHandler.is() )
        m_pData->m_aUserInputInterception.addKeyHandler( _rxHandler );
}

// -----------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::removeKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException)
{
    m_pData->m_aUserInputInterception.removeKeyHandler( _rxHandler );
}

// -----------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::addMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException)
{
    if ( _rxHandler.is() )
        m_pData->m_aUserInputInterception.addMouseClickHandler( _rxHandler );
}

// -----------------------------------------------------------------------------
void SAL_CALL OGenericUnoController::removeMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException)
{
    m_pData->m_aUserInputInterception.removeMouseClickHandler( _rxHandler );
}

// =============================================================================
// -----------------------------------------------------------------------------
void OGenericUnoController::executeChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs)
{
	if ( isCommandEnabled(_nCommandId) )
		Execute(_nCommandId, aArgs);
}

// -----------------------------------------------------------------------------
sal_Bool OGenericUnoController::isCommandEnabled(sal_uInt16 _nCommandId) const
{
	return GetState( _nCommandId ).bEnabled;
}

// -----------------------------------------------------------------------------
sal_uInt16 OGenericUnoController::registerCommandURL( const ::rtl::OUString& _rCompleteCommandURL )
{
    if ( !_rCompleteCommandURL.getLength() )
        return 0;

    SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL );
	if ( aIter != m_aSupportedFeatures.end() )
		return aIter->second.nFeatureId;

    // this is a previously unkwnon command
    sal_uInt16 nFeatureId = FIRST_USER_DEFINED_FEATURE;
    while ( isFeatureSupported( nFeatureId ) && ( nFeatureId < LAST_USER_DEFINED_FEATURE ) )
        ++nFeatureId;
    if ( nFeatureId == LAST_USER_DEFINED_FEATURE )
    {
        OSL_ENSURE( false, "OGenericUnoController::registerCommandURL: no more space for user defined features!" );
        return 0L;
    }

    ControllerFeature aFeature;
    aFeature.Command = _rCompleteCommandURL;
    aFeature.nFeatureId = nFeatureId;
    aFeature.GroupId = CommandGroup::INTERNAL;
    m_aSupportedFeatures[ aFeature.Command ] = aFeature;

    return nFeatureId;
}

// -----------------------------------------------------------------------------
void OGenericUnoController::notifyHiContrastChanged()
{
}

// -----------------------------------------------------------------------------
sal_Bool OGenericUnoController::isDataSourceReadOnly() const
{
    return sal_False;
}

// -----------------------------------------------------------------------------
Reference< XController > OGenericUnoController::getXController() throw( RuntimeException )
{
    return this;
}

// -----------------------------------------------------------------------------
bool OGenericUnoController::interceptUserInput( const NotifyEvent& _rEvent )
{
    return m_pData->m_aUserInputInterception.handleNotifyEvent( _rEvent );
}

// -----------------------------------------------------------------------------
sal_Bool OGenericUnoController::isCommandChecked(sal_uInt16 _nCommandId) const
{
    FeatureState aState = GetState( _nCommandId );

	return aState.bChecked && (sal_Bool)*aState.bChecked;
}
// -----------------------------------------------------------------------------
sal_Bool OGenericUnoController::isCommandEnabled( const ::rtl::OUString& _rCompleteCommandURL ) const
{
    OSL_ENSURE( _rCompleteCommandURL.getLength(), "OGenericUnoController::isCommandEnabled: Empty command url!" );

	sal_Bool bIsEnabled = sal_False;
    SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL );
	if ( aIter != m_aSupportedFeatures.end() )
		bIsEnabled = isCommandEnabled( aIter->second.nFeatureId );

	return bIsEnabled;
}

// -----------------------------------------------------------------------------
Sequence< ::sal_Int16 > SAL_CALL OGenericUnoController::getSupportedCommandGroups() throw (RuntimeException)
{
    CommandHashMap aCmdHashMap;
	for (   SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin();
            aIter != m_aSupportedFeatures.end();
            ++aIter
        )
        if ( aIter->second.GroupId != CommandGroup::INTERNAL )
            aCmdHashMap.insert( CommandHashMap::value_type( aIter->second.GroupId, 0 ));

    Sequence< sal_Int16 > aCommandGroups( aCmdHashMap.size() );
    ::std::transform( aCmdHashMap.begin(),
        aCmdHashMap.end(),
        aCommandGroups.getArray(),
        ::std::select1st< CommandHashMap::value_type >()
    );

    return aCommandGroups;
}

// -----------------------------------------------------------------------------
Sequence< DispatchInformation > SAL_CALL OGenericUnoController::getConfigurableDispatchInformation( ::sal_Int16 CommandGroup ) throw (RuntimeException)
{
    DispatchInfoList    aInformationList;
    DispatchInformation aDispatchInfo;
    for (   SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin();
            aIter != m_aSupportedFeatures.end();
            ++aIter
        )
    {
        if ( sal_Int16( aIter->second.GroupId ) == CommandGroup )
        {
            aDispatchInfo = aIter->second;
            aInformationList.push_back( aDispatchInfo );
        }
    }

    Sequence< DispatchInformation > aInformation( aInformationList.size() );
    ::std::transform( aInformationList.begin(),
        aInformationList.end(),
        aInformation.getArray(),
        ::std::identity< DispatchInformation >()
    );

    return aInformation;
}
// -----------------------------------------------------------------------------
void OGenericUnoController::fillSupportedFeatures()
{
#ifdef DBG_UTIL
    m_bDescribingSupportedFeatures = true;
#endif
	describeSupportedFeatures();
// -----------------------------------------------------------------------------
#ifdef DBG_UTIL
    m_bDescribingSupportedFeatures = false;
#endif
}


void SAL_CALL OGenericUnoController::dispose() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aSolarGuard(Application::GetSolarMutex());
	OGenericUnoController_Base::dispose();
}
}   // namespace dbaui

