1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 
31 #include "AppController.hxx"
32 #include "dbustrings.hrc"
33 #include "advancedsettingsdlg.hxx"
34 #include "subcomponentmanager.hxx"
35 #include "closeveto.hxx"
36 
37 /** === begin UNO includes === **/
38 #include <com/sun/star/beans/NamedValue.hpp>
39 #include <com/sun/star/container/XChild.hpp>
40 #include <com/sun/star/container/XContainer.hpp>
41 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
42 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
43 #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
44 #include <com/sun/star/container/XNameContainer.hpp>
45 #include <com/sun/star/frame/FrameSearchFlag.hpp>
46 #include <com/sun/star/frame/XStorable.hpp>
47 #include <com/sun/star/sdb/CommandType.hpp>
48 #include <com/sun/star/sdb/SQLContext.hpp>
49 #include <com/sun/star/sdb/XBookmarksSupplier.hpp>
50 #include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
51 #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
52 #include <com/sun/star/sdbc/XDataSource.hpp>
53 #include <com/sun/star/sdbcx/XAlterView.hpp>
54 #include <com/sun/star/sdbcx/XAppend.hpp>
55 #include <com/sun/star/sdbcx/XRename.hpp>
56 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
57 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
58 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
59 #include <com/sun/star/uno/XNamingService.hpp>
60 #include <com/sun/star/util/XFlushable.hpp>
61 #include <com/sun/star/util/XModifiable.hpp>
62 #include <com/sun/star/util/XModifyBroadcaster.hpp>
63 #include <com/sun/star/util/XNumberFormatter.hpp>
64 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
65 #include <com/sun/star/document/XEmbeddedScripts.hpp>
66 #include <com/sun/star/frame/XModel2.hpp>
67 #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
68 #include <com/sun/star/util/XModifyBroadcaster.hpp>
69 #include <com/sun/star/util/XModifiable.hpp>
70 #include <com/sun/star/frame/FrameSearchFlag.hpp>
71 #include <com/sun/star/util/XFlushable.hpp>
72 #include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
73 #include "com/sun/star/beans/NamedValue.hpp"
74 #include <com/sun/star/awt/XTopWindow.hpp>
75 #include <com/sun/star/task/XInteractionHandler.hpp>
76 #include <com/sun/star/sdb/application/DatabaseObject.hpp>
77 #include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp>
78 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
79 #include <com/sun/star/container/XHierarchicalName.hpp>
80 /** === end UNO includes === **/
81 #include <tools/debug.hxx>
82 #include <tools/diagnose_ex.h>
83 #include <tools/string.hxx>
84 
85 #include <svl/urihelper.hxx>
86 #include <svl/filenotation.hxx>
87 #include <svtools/svtreebx.hxx>
88 #include <svtools/transfer.hxx>
89 #include <svtools/cliplistener.hxx>
90 #include <svtools/svlbitm.hxx>
91 #include <svtools/insdlg.hxx>
92 
93 #include <comphelper/sequence.hxx>
94 #include <comphelper/uno3.hxx>
95 #include <comphelper/string.hxx>
96 #include <comphelper/types.hxx>
97 #include <comphelper/interaction.hxx>
98 #include <comphelper/componentcontext.hxx>
99 
100 #include <vcl/msgbox.hxx>
101 #include <vcl/stdtext.hxx>
102 #include <vcl/svapp.hxx>
103 #include <vcl/menu.hxx>
104 #include <vcl/lstbox.hxx>
105 
106 #include <unotools/pathoptions.hxx>
107 #include <unotools/tempfile.hxx>
108 #include <unotools/internaloptions.hxx>
109 #include <unotools/moduleoptions.hxx>
110 #include <unotools/historyoptions.hxx>
111 
112 #include <sfx2/mailmodelapi.hxx>
113 #include <sfx2/filedlghelper.hxx>
114 #include <sfx2/docfilt.hxx>
115 #include <sfx2/QuerySaveDocument.hxx>
116 
117 #include <cppuhelper/typeprovider.hxx>
118 #include <cppuhelper/exc_hlp.hxx>
119 
120 #include <connectivity/dbtools.hxx>
121 #include <connectivity/dbexception.hxx>
122 
123 #include <svx/dbaexchange.hxx>
124 #include <svx/dbaobjectex.hxx>
125 #include <svx/svxdlg.hxx>
126 
127 #include <vos/mutex.hxx>
128 #include "AppView.hxx"
129 #include "browserids.hxx"
130 #include "dbu_reghelper.hxx"
131 #include "dbu_app.hrc"
132 #include "defaultobjectnamecheck.hxx"
133 #include "databaseobjectview.hxx"
134 #include "listviewitems.hxx"
135 #include "AppDetailView.hxx"
136 #include "linkeddocuments.hxx"
137 #include "sqlmessage.hxx"
138 #include "UITools.hxx"
139 #include "dsntypes.hxx"
140 #include "dbaccess_helpid.hrc"
141 #include "dlgsave.hxx"
142 #include "dbaccess_slotid.hrc"
143 
144 #include <algorithm>
145 #include <functional>
146 
147 #include <boost/noncopyable.hpp>
148 
149 extern "C" void SAL_CALL createRegistryInfo_ODBApplication()
150 {
151 	static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::OApplicationController > aAutoRegistration;
152 }
153 //........................................................................
154 namespace dbaui
155 {
156 //........................................................................
157 using namespace ::dbtools;
158 using namespace ::svx;
159 using namespace ::com::sun::star;
160 using namespace ::com::sun::star::uno;
161 using namespace ::com::sun::star::ucb;
162 using namespace ::com::sun::star::view;
163 using namespace ::com::sun::star::util;
164 using namespace ::com::sun::star::beans;
165 using namespace ::com::sun::star::lang;
166 using namespace ::com::sun::star::frame;
167 using namespace ::com::sun::star::container;
168 using namespace ::com::sun::star::sdb;
169 using namespace ::com::sun::star::sdbc;
170 using namespace ::com::sun::star::sdbcx;
171 using namespace ::com::sun::star::datatransfer;
172 using namespace ::com::sun::star::ui::dialogs;
173 using namespace ::com::sun::star::task;
174 using ::com::sun::star::document::XEmbeddedScripts;
175 using ::com::sun::star::document::XDocumentEventBroadcaster;
176 using ::com::sun::star::document::DocumentEvent;
177 using ::com::sun::star::sdb::application::NamedDatabaseObject;
178 
179 namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
180 namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer;
181 
182 //------------------------------------------------------------------------------
183 ::rtl::OUString SAL_CALL OApplicationController::getImplementationName() throw( RuntimeException )
184 {
185 	return getImplementationName_Static();
186 }
187 
188 //------------------------------------------------------------------------------
189 ::rtl::OUString OApplicationController::getImplementationName_Static() throw( RuntimeException )
190 {
191 	return ::rtl::OUString(SERVICE_SDB_APPLICATIONCONTROLLER);
192 }
193 //------------------------------------------------------------------------------
194 Sequence< ::rtl::OUString> OApplicationController::getSupportedServiceNames_Static(void) throw( RuntimeException )
195 {
196 	Sequence< ::rtl::OUString> aSupported(1);
197 	aSupported.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.application.DefaultViewController");
198 	return aSupported;
199 }
200 //-------------------------------------------------------------------------
201 Sequence< ::rtl::OUString> SAL_CALL OApplicationController::getSupportedServiceNames() throw(RuntimeException)
202 {
203 	return getSupportedServiceNames_Static();
204 }
205 // -------------------------------------------------------------------------
206 Reference< XInterface > SAL_CALL OApplicationController::Create(const Reference<XMultiServiceFactory >& _rxFactory)
207 {
208 	return *(new OApplicationController(_rxFactory));
209 }
210 // -----------------------------------------------------------------------------
211 
212 struct XContainerFunctor : public ::std::unary_function< OApplicationController::TContainerVector::value_type , bool>
213 {
214 	Reference<XContainerListener> m_xContainerListener;
215 	XContainerFunctor( const Reference<XContainerListener>& _xContainerListener)
216 		: m_xContainerListener(_xContainerListener){}
217 
218 	bool operator() (const OApplicationController::TContainerVector::value_type& lhs) const
219 	{
220 		if ( lhs.is() )
221 			lhs->removeContainerListener(m_xContainerListener);
222 		return true;
223 	}
224 };
225 
226 //====================================================================
227 //= OApplicationController
228 //====================================================================
229 class SelectionNotifier : public ::boost::noncopyable
230 {
231 private:
232     ::cppu::OInterfaceContainerHelper   m_aSelectionListeners;
233     ::cppu::OWeakObject&                m_rContext;
234     sal_Int32                           m_nSelectionNestingLevel;
235 
236 public:
237     SelectionNotifier( ::osl::Mutex& _rMutex, ::cppu::OWeakObject& _rContext )
238         :m_aSelectionListeners( _rMutex )
239         ,m_rContext( _rContext )
240         ,m_nSelectionNestingLevel( 0 )
241     {
242     }
243 
244     void addListener( const Reference< XSelectionChangeListener >& _Listener )
245     {
246         m_aSelectionListeners.addInterface( _Listener );
247     }
248 
249     void removeListener( const Reference< XSelectionChangeListener >& _Listener )
250     {
251         m_aSelectionListeners.removeInterface( _Listener );
252     }
253 
254     void disposing()
255     {
256         EventObject aEvent( m_rContext );
257         m_aSelectionListeners.disposeAndClear( aEvent );
258     }
259 
260     ~SelectionNotifier()
261     {
262     }
263 
264     struct SelectionGuardAccess { friend class SelectionGuard; private: SelectionGuardAccess() { }  };
265 
266     /** enters a block which modifies the selection of our owner.
267 
268         Can be called multiple times, the only important thing is to call leaveSelection
269         equally often.
270     */
271     void    enterSelection( SelectionGuardAccess )
272     {
273         ++m_nSelectionNestingLevel;
274     }
275 
276     /** leaves a block which modifies the selection of our owner
277 
278         Must be paired with enterSelection calls.
279 
280         When the last block is left, i.e. the last leaveSelection call is made on the current stack,
281         then our SelectionChangeListeners are notified
282     */
283     void    leaveSelection( SelectionGuardAccess )
284     {
285         if ( --m_nSelectionNestingLevel == 0 )
286         {
287             EventObject aEvent( m_rContext );
288             m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent );
289         }
290     }
291 };
292 
293 class SelectionGuard : public ::boost::noncopyable
294 {
295 public:
296     SelectionGuard( SelectionNotifier& _rNotifier )
297         :m_rNotifier( _rNotifier )
298     {
299         m_rNotifier.enterSelection( SelectionNotifier::SelectionGuardAccess() );
300     }
301 
302     ~SelectionGuard()
303     {
304         m_rNotifier.leaveSelection( SelectionNotifier::SelectionGuardAccess() );
305     }
306 
307 private:
308     SelectionNotifier&  m_rNotifier;
309 };
310 
311 //====================================================================
312 //= OApplicationController
313 //====================================================================
314 DBG_NAME(OApplicationController)
315 //--------------------------------------------------------------------
316 OApplicationController::OApplicationController(const Reference< XMultiServiceFactory >& _rxORB)
317 	:OApplicationController_CBASE( _rxORB )
318     ,m_aContextMenuInterceptors( getMutex() )
319     ,m_pSubComponentManager( new SubComponentManager( *this, getSharedMutex() ) )
320     ,m_aTypeCollection(_rxORB)
321     ,m_aTableCopyHelper(this)
322 	,m_pClipbordNotifier(NULL)
323 	,m_nAsyncDrop(0)
324     ,m_aControllerConnectedEvent( LINK( this, OApplicationController, OnFirstControllerConnected ) )
325     ,m_aSelectContainerEvent( LINK( this, OApplicationController, OnSelectContainer ) )
326 	,m_ePreviewMode(E_PREVIEWNONE)
327 	,m_eCurrentType(E_NONE)
328 	,m_bNeedToReconnect(sal_False)
329     ,m_bSuspended( sal_False )
330     ,m_pSelectionNotifier( new SelectionNotifier( getMutex(), *this ) )
331 {
332     DBG_CTOR(OApplicationController,NULL);
333 }
334 //------------------------------------------------------------------------------
335 OApplicationController::~OApplicationController()
336 {
337 	if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
338 	{
339 		OSL_ENSURE(0,"Please check who doesn't dispose this component!");
340         // increment ref count to prevent double call of Dtor
341         osl_incrementInterlockedCount( &m_refCount );
342         dispose();
343 	}
344 	::std::auto_ptr< Window> aTemp( getView() );
345     clearView();
346 
347     DBG_DTOR(OApplicationController,NULL);
348 }
349 //--------------------------------------------------------------------
350 IMPLEMENT_FORWARD_XTYPEPROVIDER2(OApplicationController,OApplicationController_CBASE,OApplicationController_Base)
351 IMPLEMENT_FORWARD_XINTERFACE2(OApplicationController,OApplicationController_CBASE,OApplicationController_Base)
352 // -----------------------------------------------------------------------------
353 void OApplicationController::disconnect()
354 {
355     if ( m_xDataSourceConnection.is() )
356 	    stopConnectionListening( m_xDataSourceConnection );
357 
358     try
359     {
360         // temporary (hopefully!) hack for #i55274#
361         Reference< XFlushable > xFlush( m_xDataSourceConnection, UNO_QUERY );
362         if ( xFlush.is() && m_xMetaData.is() && !m_xMetaData->isReadOnly() )
363             xFlush->flush();
364     }
365     catch( const Exception& )
366     {
367         DBG_UNHANDLED_EXCEPTION();
368     }
369 
370     m_xDataSourceConnection.clear();
371     m_xMetaData.clear();
372 
373 	InvalidateAll();
374 }
375 
376 //--------------------------------------------------------------------
377 void SAL_CALL OApplicationController::disposing()
378 {
379     m_aControllerConnectedEvent.CancelCall();
380 
381 	::std::for_each(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),XContainerFunctor(this));
382 	m_aCurrentContainers.clear();
383     m_pSubComponentManager->disposing();
384     m_pSelectionNotifier->disposing();
385 
386 	if ( getView() )
387 	{
388 		getContainer()->showPreview(NULL);
389 		m_pClipbordNotifier->ClearCallbackLink();
390 		m_pClipbordNotifier->AddRemoveListener( getView(), sal_False );
391 		m_pClipbordNotifier->release();
392 		m_pClipbordNotifier = NULL;
393 	}
394 
395 	disconnect();
396 	try
397 	{
398 		Reference < XFrame > xFrame;
399 		attachFrame( xFrame );
400 
401         if ( m_xDataSource.is() )
402 		{
403 		    m_xDataSource->removePropertyChangeListener(::rtl::OUString(), this);
404             m_xDataSource->removePropertyChangeListener(PROPERTY_INFO, this);
405 			m_xDataSource->removePropertyChangeListener(PROPERTY_URL, this);
406 			m_xDataSource->removePropertyChangeListener(PROPERTY_ISPASSWORDREQUIRED, this);
407 			m_xDataSource->removePropertyChangeListener(PROPERTY_LAYOUTINFORMATION, this);
408 			m_xDataSource->removePropertyChangeListener(PROPERTY_SUPPRESSVERSIONCL, this);
409 			m_xDataSource->removePropertyChangeListener(PROPERTY_TABLEFILTER, this);
410 			m_xDataSource->removePropertyChangeListener(PROPERTY_TABLETYPEFILTER, this);
411 			m_xDataSource->removePropertyChangeListener(PROPERTY_USER, this);
412 			// otherwise we may delete our datasource twice
413 			Reference<XPropertySet> xProp = m_xDataSource;
414 			m_xDataSource = NULL;
415 		}
416 
417 		Reference< XModifyBroadcaster > xBroadcaster( m_xModel, UNO_QUERY );
418 		if ( xBroadcaster.is() )
419 			xBroadcaster->removeModifyListener(static_cast<XModifyListener*>(this));
420 
421 		if ( m_xModel.is() )
422 		{
423 			::rtl::OUString sUrl = m_xModel->getURL();
424 			if ( sUrl.getLength() )
425 	    	{
426                 ::comphelper::NamedValueCollection aArgs( m_xModel->getArgs() );
427                 if ( true == aArgs.getOrDefault( "PickListEntry", true ) )
428                 {
429     				::rtl::OUString		aFilter;
430     				INetURLObject		aURL( m_xModel->getURL() );
431     				const SfxFilter* pFilter = getStandardDatabaseFilter();
432     				if ( pFilter )
433     					aFilter = pFilter->GetFilterName();
434 
435     				// add to svtool history options
436     				SvtHistoryOptions().AppendItem( ePICKLIST,
437     						aURL.GetURLNoPass( INetURLObject::NO_DECODE ),
438     						aFilter,
439     						getStrippedDatabaseName(),
440     						::rtl::OUString() );
441                 }
442             }
443 
444             m_xModel->disconnectController( this );
445 
446             m_xModel.clear();
447 		}
448 	}
449 	catch(Exception)
450 	{
451         DBG_UNHANDLED_EXCEPTION();
452 	}
453 
454     clearView();
455 	OApplicationController_CBASE::disposing(); // here the m_refCount must be equal 5
456 }
457 
458 //--------------------------------------------------------------------
459 sal_Bool OApplicationController::Construct(Window* _pParent)
460 {
461 	setView( * new OApplicationView( _pParent, getORB(), *this, m_ePreviewMode ) );
462 	getView()->SetUniqueId(UID_APP_VIEW);
463 
464 	// late construction
465 	sal_Bool bSuccess = sal_False;
466 	try
467 	{
468 		getContainer()->Construct();
469 		bSuccess = sal_True;
470 	}
471 	catch(SQLException&)
472 	{
473 	}
474 	catch(Exception&)
475 	{
476 		DBG_ERROR("OApplicationController::Construct : the construction of UnoDataBrowserView failed !");
477 	}
478 
479 	if ( !bSuccess )
480 	{
481 		::std::auto_ptr< Window> aTemp( getView() );
482         clearView();
483 		return sal_False;
484 	}
485 
486 	// now that we have a view we can create the clipboard listener
487 	m_aSystemClipboard = TransferableDataHelper::CreateFromSystemClipboard( getView() );
488 	m_aSystemClipboard.StartClipboardListening( );
489 
490 	m_pClipbordNotifier = new TransferableClipboardListener( LINK( this, OApplicationController, OnClipboardChanged ) );
491 	m_pClipbordNotifier->acquire();
492 	m_pClipbordNotifier->AddRemoveListener( getView(), sal_True );
493 
494 	OApplicationController_CBASE::Construct( _pParent );
495 	getView()->Show();
496 
497 	return sal_True;
498 }
499 
500 //--------------------------------------------------------------------
501 void SAL_CALL OApplicationController::disposing(const EventObject& _rSource) throw( RuntimeException )
502 {
503     ::osl::MutexGuard aGuard( getMutex() );
504 	Reference<XConnection> xCon(_rSource.Source, UNO_QUERY);
505 	if ( xCon.is() )
506 	{
507         DBG_ASSERT( m_xDataSourceConnection == xCon,
508             "OApplicationController::disposing: which connection does this come from?" );
509 
510         if ( getContainer() && getContainer()->getElementType() == E_TABLE )
511             getContainer()->clearPages();
512         if ( m_xDataSourceConnection == xCon )
513         {
514 			m_xMetaData.clear();
515             m_xDataSourceConnection.clear();
516 		}
517 	}
518 	else if ( _rSource.Source == m_xModel )
519 	{
520 		m_xModel.clear();
521 	}
522 	else if ( _rSource.Source == m_xDataSource )
523 	{
524 		m_xDataSource = NULL;
525 	}
526 	else
527 	{
528 		Reference<XContainer> xContainer( _rSource.Source, UNO_QUERY );
529 		if ( xContainer.is() )
530 		{
531 			TContainerVector::iterator aFind = ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer);
532 			if ( aFind != m_aCurrentContainers.end() )
533 				m_aCurrentContainers.erase(aFind);
534 		}
535 		OApplicationController_CBASE::disposing( _rSource );
536 	}
537 }
538 //--------------------------------------------------------------------
539 sal_Bool SAL_CALL OApplicationController::suspend(sal_Bool bSuspend) throw( RuntimeException )
540 {
541     // notify the OnPrepareViewClosing event (before locking any mutex)
542     Reference< XDocumentEventBroadcaster > xBroadcaster( m_xModel, UNO_QUERY );
543     if ( xBroadcaster.is() )
544     {
545         xBroadcaster->notifyDocumentEvent(
546             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnPrepareViewClosing" ) ),
547             this,
548             Any()
549         );
550     }
551 
552     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
553     ::osl::MutexGuard aGuard( getMutex() );
554 
555     if ( getView() && getView()->IsInModalMode() )
556         return sal_False;
557 
558     sal_Bool bCanSuspend = sal_True;
559 
560     if ( m_bSuspended != bSuspend )
561     {
562 	    if ( bSuspend && !closeSubComponents() )
563 		    return sal_False;
564 
565 	    Reference<XModifiable> xModi(m_xModel,UNO_QUERY);
566         Reference<XStorable> xStor(getModel(),UNO_QUERY);
567 
568 	    if  (   bSuspend
569             &&  xStor.is()
570             &&  !xStor->isReadonly()
571             &&  (   xModi.is()
572                 &&  xModi->isModified()
573                 )
574             )
575 	    {
576 		    switch (ExecuteQuerySaveDocument(getView(),getStrippedDatabaseName()))
577 		    {
578 			    case RET_YES:
579 				    Execute(ID_BROWSER_SAVEDOC,Sequence<PropertyValue>());
580 				    bCanSuspend = !xModi->isModified();
581                     // when we save the document this must be false else some press cancel
582 				    break;
583 			    case RET_CANCEL:
584 				    bCanSuspend = sal_False;
585 			    default:
586 				    break;
587 		    }
588 	    }
589     }
590 
591     if ( bCanSuspend )
592 	    m_bSuspended = bSuspend;
593 
594 	return bCanSuspend;
595 }
596 // -----------------------------------------------------------------------------
597 FeatureState OApplicationController::GetState(sal_uInt16 _nId) const
598 {
599 	FeatureState aReturn;
600 	aReturn.bEnabled = sal_False;
601 	// check this first
602 	if ( !getContainer() || m_bReadOnly )
603 		return aReturn;
604 
605 	try
606 	{
607 		switch (_nId)
608 		{
609             case SID_OPENURL:
610                 aReturn.bEnabled = sal_True;
611                 if ( m_xModel.is() )
612 				    aReturn.sTitle = m_xModel->getURL();
613                 break;
614 			case ID_BROWSER_COPY:
615 				{
616 					sal_Int32 nCount = getContainer()->getSelectionCount();
617 					aReturn.bEnabled = nCount >= 1;
618 					if ( aReturn.bEnabled && nCount == 1 && getContainer()->getElementType() == E_TABLE )
619 						aReturn.bEnabled = getContainer()->isALeafSelected();
620 				}
621 				break;
622 			case ID_BROWSER_CUT:
623 				aReturn.bEnabled = !isDataSourceReadOnly() && getContainer()->getSelectionCount() >= 1;
624 				aReturn.bEnabled = aReturn.bEnabled && ( (ID_BROWSER_CUT == _nId && getContainer()->getElementType() == E_TABLE) ? getContainer()->isCutAllowed() : sal_True);
625 				break;
626 			case ID_BROWSER_PASTE:
627 				switch( getContainer()->getElementType() )
628 				{
629 					case E_TABLE:
630 						aReturn.bEnabled = !isDataSourceReadOnly() && !isConnectionReadOnly() && isTableFormat();
631 						break;
632 					case E_QUERY:
633 						aReturn.bEnabled = !isDataSourceReadOnly() && getViewClipboard().HasFormat(SOT_FORMATSTR_ID_DBACCESS_QUERY);
634 						break;
635 					default:
636 						aReturn.bEnabled = !isDataSourceReadOnly() && OComponentTransferable::canExtractComponentDescriptor(getViewClipboard().GetDataFlavorExVector(),getContainer()->getElementType() == E_FORM);
637 				}
638 				break;
639 			case SID_DB_APP_PASTE_SPECIAL:
640 				aReturn.bEnabled = getContainer()->getElementType() == E_TABLE && !isDataSourceReadOnly() && !isConnectionReadOnly() && isTableFormat();
641 				break;
642 			case SID_OPENDOC:
643 			case SID_HELP_INDEX:
644 				aReturn.bEnabled = sal_True;
645 				break;
646 			case ID_BROWSER_SAVEDOC:
647 				aReturn.bEnabled = !isDataSourceReadOnly() && m_xDocumentModify.is() && m_xDocumentModify->isModified();
648 				break;
649 			case ID_BROWSER_SAVEASDOC:
650 				aReturn.bEnabled = sal_True;
651 				break;
652 			case ID_BROWSER_SORTUP:
653 				aReturn.bEnabled = getContainer()->isFilled() && getContainer()->getElementCount();
654 				aReturn.bChecked = aReturn.bEnabled && getContainer()->isSortUp();
655 				break;
656 			case ID_BROWSER_SORTDOWN:
657 				aReturn.bEnabled = getContainer()->isFilled() && getContainer()->getElementCount();
658 				aReturn.bChecked = aReturn.bEnabled && !getContainer()->isSortUp();
659 				break;
660 
661 			case SID_NEWDOC:
662 			case SID_APP_NEW_FORM:
663 			case ID_DOCUMENT_CREATE_REPWIZ:
664                 aReturn.bEnabled = !isDataSourceReadOnly() && SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SWRITER);
665 				break;
666 			case SID_APP_NEW_REPORT:
667 				aReturn.bEnabled = !isDataSourceReadOnly()
668                                     && SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SWRITER);
669                 if ( aReturn.bEnabled )
670                 {
671                     Reference< XContentEnumerationAccess > xEnumAccess(m_xServiceFactory, UNO_QUERY);
672 					aReturn.bEnabled = xEnumAccess.is();
673 	                if ( aReturn.bEnabled )
674                     {
675                         const ::rtl::OUString sReportEngineServiceName = ::dbtools::getDefaultReportEngineServiceName(m_xServiceFactory);
676                         aReturn.bEnabled = sReportEngineServiceName.getLength() != 0;
677                         if ( aReturn.bEnabled )
678                         {
679                     	    const Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(sReportEngineServiceName);
680                             aReturn.bEnabled = xEnumDrivers.is() && xEnumDrivers->hasMoreElements();
681                         }
682                     }
683                 }
684 				break;
685 			case SID_DB_APP_VIEW_TABLES:
686 				aReturn.bEnabled = sal_True;
687 				aReturn.bChecked = getContainer()->getElementType() == E_TABLE;
688 				break;
689 			case SID_DB_APP_VIEW_QUERIES:
690 				aReturn.bEnabled = sal_True;
691 				aReturn.bChecked = getContainer()->getElementType() == E_QUERY;
692 				break;
693 			case SID_DB_APP_VIEW_FORMS:
694 				aReturn.bEnabled = sal_True;
695 				aReturn.bChecked = getContainer()->getElementType() == E_FORM;
696 				break;
697 			case SID_DB_APP_VIEW_REPORTS:
698 				aReturn.bEnabled = sal_True;
699 				aReturn.bChecked = getContainer()->getElementType() == E_REPORT;
700 				break;
701 			case ID_NEW_QUERY_DESIGN:
702 			case ID_NEW_QUERY_SQL:
703 			case ID_APP_NEW_QUERY_AUTO_PILOT:
704 			case SID_DB_FORM_NEW_PILOT:
705 				aReturn.bEnabled = !isDataSourceReadOnly();
706 				break;
707 			case ID_NEW_VIEW_DESIGN:
708 			case SID_DB_NEW_VIEW_SQL:
709 			case ID_NEW_VIEW_DESIGN_AUTO_PILOT:
710 				aReturn.bEnabled = !isDataSourceReadOnly() && !isConnectionReadOnly();
711 				if ( aReturn.bEnabled )
712 				{
713 					Reference<XViewsSupplier> xViewsSup( getConnection(), UNO_QUERY );
714 					aReturn.bEnabled = xViewsSup.is();
715 				}
716 				break;
717 			case ID_NEW_TABLE_DESIGN:
718 			case ID_NEW_TABLE_DESIGN_AUTO_PILOT:
719 				aReturn.bEnabled = !isDataSourceReadOnly() && !isConnectionReadOnly();
720 				break;
721 			case ID_DIRECT_SQL:
722 				aReturn.bEnabled = sal_True;
723 				break;
724             case ID_MIGRATE_SCRIPTS:
725             {
726                 // Our document supports embedding scripts into it, if and only if there are no
727                 // forms/reports with macros/scripts into them. So, we need to enable migration
728                 // if and only if the database document does *not* support embedding scripts.
729                 bool bAvailable =
730                         !Reference< XEmbeddedScripts >( m_xModel, UNO_QUERY ).is()
731                     &&  !Reference< XStorable >( m_xModel, UNO_QUERY_THROW )->isReadonly();
732                 aReturn.bEnabled = bAvailable;
733                 if ( !bAvailable )
734                     aReturn.bInvisible = true;
735             }
736             break;
737 			case SID_APP_NEW_FOLDER:
738 				aReturn.bEnabled = !isDataSourceReadOnly() && getContainer()->getSelectionCount() <= 1;
739 				if ( aReturn.bEnabled )
740 				{
741 					const ElementType eType = getContainer()->getElementType();
742 					aReturn.bEnabled = eType == E_REPORT || eType == E_FORM;
743 				}
744 				break;
745 			case SID_FORM_CREATE_REPWIZ_PRE_SEL:
746 			case SID_REPORT_CREATE_REPWIZ_PRE_SEL:
747             case SID_APP_NEW_REPORT_PRE_SEL:
748 				aReturn.bEnabled = !isDataSourceReadOnly()
749 									&& SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SWRITER)
750 									&& getContainer()->isALeafSelected();
751 				if ( aReturn.bEnabled )
752 				{
753 					ElementType eType = getContainer()->getElementType();
754 					aReturn.bEnabled = eType == E_QUERY || eType == E_TABLE;
755                     if ( aReturn.bEnabled && SID_APP_NEW_REPORT_PRE_SEL == _nId )
756                     {
757                         Reference< XContentEnumerationAccess > xEnumAccess(m_xServiceFactory, UNO_QUERY);
758 					    aReturn.bEnabled = xEnumAccess.is();
759 	                    if ( aReturn.bEnabled )
760                         {
761                             static ::rtl::OUString s_sReportDesign(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.pentaho.SOReportJobFactory"));
762                     	    Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(s_sReportDesign);
763                             aReturn.bEnabled = xEnumDrivers.is() && xEnumDrivers->hasMoreElements();
764                         }
765                     }
766 				}
767 				break;
768 			case SID_DB_APP_DELETE:
769 			case SID_DB_APP_RENAME:
770 				aReturn.bEnabled = isRenameDeleteAllowed(getContainer()->getElementType(), _nId == SID_DB_APP_DELETE);
771 				break;
772 			case SID_DB_APP_TABLE_DELETE:
773 			case SID_DB_APP_TABLE_RENAME:
774 				aReturn.bEnabled = isRenameDeleteAllowed(E_TABLE, _nId == SID_DB_APP_TABLE_DELETE);
775 				break;
776 			case SID_DB_APP_QUERY_DELETE:
777 			case SID_DB_APP_QUERY_RENAME:
778 				aReturn.bEnabled = isRenameDeleteAllowed(E_QUERY, _nId == SID_DB_APP_QUERY_DELETE);
779 				break;
780 			case SID_DB_APP_FORM_DELETE:
781 			case SID_DB_APP_FORM_RENAME:
782 				aReturn.bEnabled = isRenameDeleteAllowed(E_FORM, _nId == SID_DB_APP_FORM_DELETE);
783 				break;
784 			case SID_DB_APP_REPORT_DELETE:
785 			case SID_DB_APP_REPORT_RENAME:
786 				aReturn.bEnabled = isRenameDeleteAllowed(E_REPORT, _nId == SID_DB_APP_REPORT_DELETE);
787 				break;
788 
789 			case SID_SELECTALL:
790 				aReturn.bEnabled = getContainer()->getElementCount() > 0 && getContainer()->getSelectionCount() != getContainer()->getElementCount();
791 				break;
792 			case SID_DB_APP_EDIT:
793 			case SID_DB_APP_TABLE_EDIT:
794 			case SID_DB_APP_QUERY_EDIT:
795 			case SID_DB_APP_FORM_EDIT:
796 			case SID_DB_APP_REPORT_EDIT:
797 				aReturn.bEnabled = !isDataSourceReadOnly() && getContainer()->getSelectionCount() > 0
798 									&& getContainer()->isALeafSelected();
799 				break;
800 			case SID_DB_APP_EDIT_SQL_VIEW:
801                 if ( isDataSourceReadOnly() )
802 				    aReturn.bEnabled = sal_False;
803                 else
804                 {
805                     switch ( getContainer()->getElementType() )
806                     {
807                     case E_QUERY:
808                         aReturn.bEnabled =  ( getContainer()->getSelectionCount() > 0 )
809                                         &&  ( getContainer()->isALeafSelected() );
810                         break;
811                     case E_TABLE:
812                         aReturn.bEnabled = sal_False;
813                         // there's one exception: views which support altering their underlying
814                         // command can be edited in SQL view, too
815                         if  (   ( getContainer()->getSelectionCount() > 0 )
816                             &&  ( getContainer()->isALeafSelected() )
817                             )
818                         {
819 						    ::std::vector< ::rtl::OUString > aSelected;
820 						    getSelectionElementNames( aSelected );
821                             bool bAlterableViews = true;
822                             for (   ::std::vector< ::rtl::OUString >::const_iterator selectedName = aSelected.begin();
823                                     bAlterableViews && ( selectedName != aSelected.end() ) ;
824                                     ++selectedName
825                                 )
826                             {
827                                 bAlterableViews &= impl_isAlterableView_nothrow( *selectedName );
828                             }
829                             aReturn.bEnabled = bAlterableViews;
830                         }
831                         break;
832                     default:
833                         break;
834                     }
835                 }
836                 break;
837 			case SID_DB_APP_OPEN:
838 			case SID_DB_APP_TABLE_OPEN:
839 			case SID_DB_APP_QUERY_OPEN:
840 			case SID_DB_APP_FORM_OPEN:
841 			case SID_DB_APP_REPORT_OPEN:
842 				aReturn.bEnabled = getContainer()->getSelectionCount() > 0 && getContainer()->isALeafSelected();
843 				break;
844 			case SID_DB_APP_DSUSERADMIN:
845 				aReturn.bEnabled = !m_aTypeCollection.isEmbeddedDatabase(::comphelper::getString(m_xDataSource->getPropertyValue(PROPERTY_URL)));
846 			    break;
847 			case SID_DB_APP_DSRELDESIGN:
848 				aReturn.bEnabled = sal_True;
849 				break;
850 			case SID_DB_APP_TABLEFILTER:
851 				aReturn.bEnabled = !isDataSourceReadOnly();
852 				break;
853 			case SID_DB_APP_REFRESH_TABLES:
854 				aReturn.bEnabled = getContainer()->getElementType() == E_TABLE && isConnected();
855 				break;
856 			case SID_DB_APP_DSPROPS:
857                 aReturn.bEnabled = m_xDataSource.is() && m_aTypeCollection.isShowPropertiesEnabled(::comphelper::getString(m_xDataSource->getPropertyValue(PROPERTY_URL)));
858 				break;
859 			case SID_DB_APP_DSCONNECTION_TYPE:
860                 aReturn.bEnabled = !isDataSourceReadOnly() && m_xDataSource.is() && !m_aTypeCollection.isEmbeddedDatabase(::comphelper::getString(m_xDataSource->getPropertyValue(PROPERTY_URL)));
861 				break;
862 			case SID_DB_APP_DSADVANCED_SETTINGS:
863                 aReturn.bEnabled = m_xDataSource.is() && AdvancedSettingsDialog::doesHaveAnyAdvancedSettings( m_aTypeCollection.getType(::comphelper::getString( m_xDataSource->getPropertyValue( PROPERTY_URL ) )) );
864 				break;
865 			case SID_DB_APP_CONVERTTOVIEW:
866 				aReturn.bEnabled = !isDataSourceReadOnly();
867 				if ( aReturn.bEnabled )
868 				{
869 					ElementType eType = getContainer()->getElementType();
870 					aReturn.bEnabled = eType == E_QUERY && getContainer()->getSelectionCount() > 0;
871 					if ( aReturn.bEnabled )
872 					{
873 						Reference<XViewsSupplier> xViewSup( getConnection(), UNO_QUERY );
874 						aReturn.bEnabled = xViewSup.is() && Reference<XAppend>(xViewSup->getViews(),UNO_QUERY).is();
875 					}
876 				}
877 				break;
878 			case SID_DB_APP_DISABLE_PREVIEW:
879 				aReturn.bEnabled = sal_True;
880 				aReturn.bChecked = getContainer()->getPreviewMode() == E_PREVIEWNONE;
881 				break;
882 			case SID_DB_APP_VIEW_DOCINFO_PREVIEW:
883 				{
884 					ElementType eType = getContainer()->getElementType();
885 					aReturn.bEnabled = (E_REPORT == eType || E_FORM == eType);
886 					aReturn.bChecked = getContainer()->getPreviewMode() == E_DOCUMENTINFO;
887 				}
888 				break;
889 			case SID_DB_APP_VIEW_DOC_PREVIEW:
890 				aReturn.bEnabled = sal_True;
891 				aReturn.bChecked = getContainer()->getPreviewMode() == E_DOCUMENT;
892 				break;
893             case ID_BROWSER_UNDO:
894                 aReturn.bEnabled = sal_False;
895                 break;
896 			case SID_MAIL_SENDDOC:
897 				aReturn.bEnabled = sal_True;
898 				break;
899 			case SID_DB_APP_SENDREPORTASMAIL:
900 				{
901 					ElementType eType = getContainer()->getElementType();
902 					aReturn.bEnabled = E_REPORT == eType && getContainer()->getSelectionCount() > 0 && getContainer()->isALeafSelected();
903 				}
904 				break;
905 			case SID_DB_APP_SENDREPORTTOWRITER:
906 			case SID_DB_APP_DBADMIN:
907 				aReturn.bEnabled = sal_False;
908 				break;
909 			case SID_DB_APP_STATUS_TYPE:
910                 aReturn.bEnabled = m_xDataSource.is();
911 				if ( aReturn.bEnabled )
912 				{
913                     ::rtl::OUString sURL;
914                     m_xDataSource->getPropertyValue(PROPERTY_URL) >>= sURL;
915                     ::rtl::OUString sDSTypeName;
916                     if ( m_aTypeCollection.isEmbeddedDatabase( sURL ) )
917                     {
918                         sDSTypeName = String( ModuleRes( RID_STR_EMBEDDED_DATABASE ) );
919                     }
920                     else
921                     {
922 					    sDSTypeName = m_aTypeCollection.getTypeDisplayName(sURL);
923                     }
924 				    aReturn.sTitle = sDSTypeName;
925 				}
926 				break;
927 			case SID_DB_APP_STATUS_DBNAME:
928 				aReturn.bEnabled = m_xDataSource.is();
929 				if ( aReturn.bEnabled )
930 				{
931 					::rtl::OUString sURL;
932 					m_xDataSource->getPropertyValue(PROPERTY_URL) >>= sURL;
933                     String sDatabaseName;
934 					String sHostName;
935 					sal_Int32 nPortNumber( -1 );
936 
937 					m_aTypeCollection.extractHostNamePort( sURL, sDatabaseName, sHostName, nPortNumber );
938 
939                     if ( !sDatabaseName.Len() )
940 						sDatabaseName = m_aTypeCollection.cutPrefix( sURL );
941 					if ( m_aTypeCollection.isFileSystemBased(sURL) )
942 					{
943 						sDatabaseName = SvtPathOptions().SubstituteVariable( sDatabaseName );
944 						if ( sDatabaseName.Len() )
945 						{
946 							::svt::OFileNotation aFileNotation(sDatabaseName);
947 							// set this decoded URL as text
948 							sDatabaseName = aFileNotation.get(::svt::OFileNotation::N_SYSTEM);
949 						}
950 					}
951 
952                     if ( sDatabaseName.Len() == 0 )
953                         sDatabaseName = m_aTypeCollection.getTypeDisplayName( sURL );
954 
955                     aReturn.sTitle = sDatabaseName;
956 				}
957 				break;
958 			case SID_DB_APP_STATUS_USERNAME:
959 				aReturn.bEnabled = m_xDataSource.is();
960 				if ( aReturn.bEnabled )
961                     m_xDataSource->getPropertyValue( PROPERTY_USER ) >>= aReturn.sTitle;
962 				break;
963 			case SID_DB_APP_STATUS_HOSTNAME:
964 				aReturn.bEnabled = m_xDataSource.is();
965 				if ( aReturn.bEnabled )
966 				{
967 					::rtl::OUString sURL;
968 					m_xDataSource->getPropertyValue( PROPERTY_URL ) >>= sURL;
969 
970 					String sHostName, sDatabaseName;
971 					sal_Int32 nPortNumber = -1;
972 					m_aTypeCollection.extractHostNamePort( sURL, sDatabaseName, sHostName, nPortNumber );
973 					aReturn.sTitle = sHostName;
974 				}
975 				break;
976 			default:
977 				aReturn = OApplicationController_CBASE::GetState(_nId);
978 		}
979 	}
980 	catch(const Exception& )
981 	{
982         DBG_UNHANDLED_EXCEPTION();
983 	}
984 	return aReturn;
985 }
986 
987 // -----------------------------------------------------------------------------
988 namespace
989 {
990     bool lcl_handleException_nothrow( const Reference< XModel >& _rxDocument, const Any& _rException )
991     {
992         bool bHandled = false;
993 
994         // try handling the error with an interaction handler
995         ::comphelper::NamedValueCollection aArgs( _rxDocument->getArgs() );
996         Reference< XInteractionHandler > xHandler( aArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
997         if ( xHandler.is() )
998         {
999             ::rtl::Reference< ::comphelper::OInteractionRequest > pRequest( new ::comphelper::OInteractionRequest( _rException ) );
1000             ::rtl::Reference< ::comphelper::OInteractionApprove > pApprove( new ::comphelper::OInteractionApprove );
1001             pRequest->addContinuation( pApprove.get() );
1002 
1003             try
1004             {
1005                 xHandler->handle( pRequest.get() );
1006             }
1007             catch( const Exception& )
1008             {
1009                 DBG_UNHANDLED_EXCEPTION();
1010             }
1011 
1012             bHandled = pApprove->wasSelected();
1013         }
1014         return bHandled;
1015     }
1016 }
1017 
1018 // -----------------------------------------------------------------------------
1019 void OApplicationController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs)
1020 {
1021 	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1022 	::osl::MutexGuard aGuard( getMutex() );
1023 
1024     if ( isUserDefinedFeature( _nId ) )
1025     {
1026         OApplicationController_CBASE::Execute( _nId, aArgs );
1027         return;
1028     }
1029 
1030 	if ( !getContainer() || m_bReadOnly )
1031 		return; // return without execution
1032 
1033 	try
1034 	{
1035 		switch(_nId)
1036 		{
1037 			case ID_BROWSER_CUT:
1038 				getContainer()->cut();
1039 				break;
1040 			case ID_BROWSER_COPY:
1041 				{
1042 					TransferableHelper* pTransfer = copyObject( );
1043 					Reference< XTransferable> aEnsureDelete = pTransfer;
1044 
1045 					if ( pTransfer )
1046 						pTransfer->CopyToClipboard(getView());
1047 				}
1048 				break;
1049 			case ID_BROWSER_PASTE:
1050 				{
1051 					const TransferableDataHelper& rTransferData( getViewClipboard() );
1052 					ElementType eType = getContainer()->getElementType();
1053 
1054 					switch( eType )
1055 					{
1056 						case E_TABLE:
1057 							{
1058 								// get the selected tablename
1059 								::std::vector< ::rtl::OUString > aList;
1060 								getSelectionElementNames( aList );
1061 								if ( !aList.empty() )
1062 									m_aTableCopyHelper.SetTableNameForAppend( *aList.begin() );
1063                                 else
1064                                     m_aTableCopyHelper.ResetTableNameForAppend();
1065 
1066 								m_aTableCopyHelper.pasteTable( rTransferData , getDatabaseName(), ensureConnection() );
1067 							}
1068 							break;
1069 
1070 						case E_QUERY:
1071                             if ( rTransferData.HasFormat(SOT_FORMATSTR_ID_DBACCESS_QUERY) )
1072 							    paste( E_QUERY, ODataAccessObjectTransferable::extractObjectDescriptor( rTransferData ) );
1073 							break;
1074 						default:
1075 							{
1076 								::std::vector< ::rtl::OUString> aList;
1077 								getSelectionElementNames(aList);
1078 								::rtl::OUString sFolderNameToInsertInto;
1079 								if ( !aList.empty() )
1080 								{
1081 									Reference< XHierarchicalNameAccess > xContainer(getElements(eType),UNO_QUERY);
1082 									if ( xContainer.is()
1083 										&& xContainer->hasByHierarchicalName(*aList.begin())
1084 										&& (xContainer->getByHierarchicalName(*aList.begin()) >>= xContainer)
1085 										&& xContainer.is()
1086 										)
1087 										sFolderNameToInsertInto = *aList.begin();
1088 								}
1089 								paste( eType, OComponentTransferable::extractComponentDescriptor( rTransferData ),
1090                                     sFolderNameToInsertInto );
1091 							}
1092 							break;
1093 					}
1094 				}
1095 				break;
1096 			case SID_DB_APP_PASTE_SPECIAL:
1097 				{
1098 					if ( !aArgs.getLength() )
1099 					{
1100                         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1101                         ::std::auto_ptr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog( getView() ));
1102 						::std::vector<SotFormatStringId> aFormatIds;
1103 						getSupportedFormats(getContainer()->getElementType(),aFormatIds);
1104 						const ::std::vector<SotFormatStringId>::iterator aEnd = aFormatIds.end();
1105                         ::rtl::OUString sEmpty;
1106 						for (::std::vector<SotFormatStringId>::iterator aIter = aFormatIds.begin();aIter != aEnd; ++aIter)
1107 							pDlg->Insert(*aIter,sEmpty);
1108 
1109 						const TransferableDataHelper& rClipboard = getViewClipboard();
1110 						pasteFormat(pDlg->GetFormat(rClipboard.GetTransferable()));
1111 					}
1112 					else
1113 					{
1114 						const PropertyValue* pIter = aArgs.getConstArray();
1115 						const PropertyValue* pEnd  = pIter + aArgs.getLength();
1116 						for( ; pIter != pEnd ; ++pIter)
1117 						{
1118 							if ( pIter->Name.equalsAscii("FormatStringId") )
1119 							{
1120 								SotFormatStringId nFormatId = 0;
1121 								if ( pIter->Value >>= nFormatId )
1122 									pasteFormat(nFormatId);
1123 								break;
1124 							}
1125 						}
1126 					}
1127 				}
1128 				break;
1129 			case SID_OPENDOC:
1130 			case SID_HELP_INDEX:
1131 				{
1132 					Reference < XDispatchProvider > xProv( getFrame(), UNO_QUERY );
1133 					if ( xProv.is() )
1134 					{
1135 						URL aURL;
1136 						switch(_nId)
1137 						{
1138 							case SID_HELP_INDEX:
1139 								aURL.Complete = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:HelpIndex"));
1140 								break;
1141 							case SID_OPENDOC:
1142 								aURL.Complete = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Open"));
1143 								break;
1144 						}
1145 
1146 						if ( m_xUrlTransformer.is() )
1147 							m_xUrlTransformer->parseStrict( aURL );
1148 						Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, String(), 0 );
1149             			if ( xDisp.is() )
1150                 			xDisp->dispatch( aURL, Sequence < PropertyValue >() );
1151 					}
1152 				}
1153 				break;
1154 			case ID_BROWSER_SAVEDOC:
1155 				{
1156 					Reference< XStorable > xStore( m_xModel, UNO_QUERY_THROW );
1157                     try
1158                     {
1159                         xStore->store();
1160                     }
1161                     catch( const Exception& )
1162                     {
1163                         lcl_handleException_nothrow( m_xModel, ::cppu::getCaughtException() );
1164                     }
1165 				}
1166 				break;
1167 
1168             case ID_BROWSER_SAVEASDOC:
1169 				{
1170 					WinBits nBits(WB_STDMODAL|WB_SAVEAS);
1171                     ::rtl::OUString sUrl;
1172 			        if ( m_xModel.is() )
1173 				        sUrl = m_xModel->getURL();
1174 			        if ( !sUrl.getLength() )
1175                         sUrl = SvtPathOptions().GetWorkPath();
1176 
1177 					::sfx2::FileDialogHelper aFileDlg( com::sun::star::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,static_cast<sal_uInt32>(nBits) ,getView());
1178 					aFileDlg.SetDisplayDirectory( sUrl );
1179 
1180 					const SfxFilter* pFilter = getStandardDatabaseFilter();
1181 					if ( pFilter )
1182 					{
1183 						aFileDlg.AddFilter(pFilter->GetUIName(),pFilter->GetDefaultExtension());
1184 						aFileDlg.SetCurrentFilter(pFilter->GetUIName());
1185 					}
1186 
1187 					if ( aFileDlg.Execute() != ERRCODE_NONE )
1188                         break;
1189 
1190                     Reference<XStorable> xStore( m_xModel, UNO_QUERY_THROW );
1191 					INetURLObject aURL( aFileDlg.GetPath() );
1192                     try
1193                     {
1194                         xStore->storeAsURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), Sequence< PropertyValue >() );
1195                     }
1196                     catch( const Exception& )
1197                     {
1198                         lcl_handleException_nothrow( m_xModel, ::cppu::getCaughtException() );
1199                     }
1200 
1201 					/*updateTitle();*/
1202 					m_bCurrentlyModified = sal_False;
1203 					InvalidateFeature(ID_BROWSER_SAVEDOC);
1204                     if ( getContainer()->getElementType() == E_NONE )
1205                     {
1206                         getContainer()->selectContainer(E_NONE);
1207                         getContainer()->selectContainer(E_TABLE);
1208                         // #i95524#
1209                         getContainer()->Invalidate();
1210                         refreshTables();
1211                     }
1212 
1213 				}
1214 				break;
1215 			case ID_BROWSER_SORTUP:
1216 				getContainer()->sortUp();
1217 				InvalidateFeature(ID_BROWSER_SORTDOWN);
1218 				break;
1219 			case ID_BROWSER_SORTDOWN:
1220 				getContainer()->sortDown();
1221 				InvalidateFeature(ID_BROWSER_SORTUP);
1222 				break;
1223 
1224 			case ID_NEW_TABLE_DESIGN_AUTO_PILOT:
1225 			case ID_NEW_VIEW_DESIGN_AUTO_PILOT:
1226 			case ID_APP_NEW_QUERY_AUTO_PILOT:
1227 			case SID_DB_FORM_NEW_PILOT:
1228 			case SID_REPORT_CREATE_REPWIZ_PRE_SEL:
1229             case SID_APP_NEW_REPORT_PRE_SEL:
1230 			case SID_FORM_CREATE_REPWIZ_PRE_SEL:
1231 			case ID_DOCUMENT_CREATE_REPWIZ:
1232 			case SID_APP_NEW_FORM:
1233 			case SID_APP_NEW_REPORT:
1234 			case ID_NEW_QUERY_SQL:
1235 			case ID_NEW_QUERY_DESIGN:
1236 			case ID_NEW_TABLE_DESIGN:
1237 				{
1238 					ElementType eType = E_TABLE;
1239 					sal_Bool bAutoPilot = sal_False;
1240                     ::comphelper::NamedValueCollection aCreationArgs;
1241 
1242 					switch( _nId )
1243 					{
1244 						case SID_DB_FORM_NEW_PILOT:
1245 						case SID_FORM_CREATE_REPWIZ_PRE_SEL:
1246 							bAutoPilot = sal_True;
1247 							// run through
1248 						case SID_APP_NEW_FORM:
1249 							eType = E_FORM;
1250 							break;
1251 						case ID_DOCUMENT_CREATE_REPWIZ:
1252 						case SID_REPORT_CREATE_REPWIZ_PRE_SEL:
1253 							bAutoPilot = sal_True;
1254 							// run through
1255 						case SID_APP_NEW_REPORT:
1256                         case SID_APP_NEW_REPORT_PRE_SEL:
1257 							eType = E_REPORT;
1258 							break;
1259 						case ID_APP_NEW_QUERY_AUTO_PILOT:
1260 							bAutoPilot = sal_True;
1261 							eType = E_QUERY;
1262 							break;
1263 						case ID_NEW_QUERY_DESIGN:
1264                             aCreationArgs.put( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN, sal_True );
1265 							// run through
1266 						case ID_NEW_QUERY_SQL:
1267 							eType = E_QUERY;
1268 							break;
1269  						case ID_NEW_TABLE_DESIGN_AUTO_PILOT:
1270  							bAutoPilot = sal_True;
1271  							// run through
1272 						case ID_NEW_TABLE_DESIGN:
1273 							break;
1274 						default:
1275 							OSL_ENSURE(0,"illegal switch call!");
1276 					}
1277                     if ( bAutoPilot )
1278                         getContainer()->PostUserEvent( LINK( this, OApplicationController, OnCreateWithPilot ), reinterpret_cast< void* >( eType ) );
1279                     else
1280                     {
1281                         Reference< XComponent > xDocDefinition;
1282 					    newElement( eType, aCreationArgs, xDocDefinition );
1283                     }
1284 				}
1285 				break;
1286 			case SID_APP_NEW_FOLDER:
1287 				{
1288 					ElementType eType = getContainer()->getElementType();
1289 					::rtl::OUString sName = getContainer()->getQualifiedName( NULL );
1290 					insertHierachyElement(eType,sName);
1291 				}
1292 				break;
1293 			case ID_NEW_VIEW_DESIGN:
1294 			case SID_DB_NEW_VIEW_SQL:
1295 				{
1296                     SharedConnection xConnection( ensureConnection() );
1297 					if ( xConnection.is() )
1298 					{
1299 						QueryDesigner aDesigner( getORB(), this, getFrame(), true );
1300 
1301                         ::comphelper::NamedValueCollection aCreationArgs;
1302                         aCreationArgs.put( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN, ID_NEW_VIEW_DESIGN == _nId );
1303 
1304                         const Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
1305 						const Reference< XComponent > xComponent( aDesigner.createNew( xDataSource, aCreationArgs ), UNO_QUERY );
1306                         onDocumentOpened( ::rtl::OUString(), E_QUERY, E_OPEN_DESIGN, xComponent, NULL );
1307 					}
1308 				}
1309 				break;
1310 			case SID_DB_APP_DELETE:
1311 			case SID_DB_APP_TABLE_DELETE:
1312 			case SID_DB_APP_QUERY_DELETE:
1313 			case SID_DB_APP_FORM_DELETE:
1314 			case SID_DB_APP_REPORT_DELETE:
1315 				deleteEntries();
1316 				break;
1317 			case SID_DB_APP_RENAME:
1318 			case SID_DB_APP_TABLE_RENAME:
1319 			case SID_DB_APP_QUERY_RENAME:
1320 			case SID_DB_APP_FORM_RENAME:
1321 			case SID_DB_APP_REPORT_RENAME:
1322 				renameEntry();
1323 				break;
1324 			case SID_DB_APP_EDIT:
1325 			case SID_DB_APP_EDIT_SQL_VIEW:
1326 			case SID_DB_APP_TABLE_EDIT:
1327 			case SID_DB_APP_QUERY_EDIT:
1328 			case SID_DB_APP_FORM_EDIT:
1329 			case SID_DB_APP_REPORT_EDIT:
1330 				doAction( _nId, E_OPEN_DESIGN );
1331                 break;
1332 			case SID_DB_APP_OPEN:
1333 			case SID_DB_APP_TABLE_OPEN:
1334 			case SID_DB_APP_QUERY_OPEN:
1335 			case SID_DB_APP_FORM_OPEN:
1336 			case SID_DB_APP_REPORT_OPEN:
1337 				doAction( _nId, E_OPEN_NORMAL );
1338 				break;
1339 			case SID_DB_APP_CONVERTTOVIEW:
1340 				doAction( _nId, E_OPEN_NORMAL );
1341 				break;
1342 			case SID_SELECTALL:
1343 				getContainer()->selectAll();
1344 				InvalidateAll();
1345 				break;
1346 			case SID_DB_APP_DSRELDESIGN:
1347             {
1348                 Reference< XComponent > xRelationDesigner;
1349                 if ( !m_pSubComponentManager->activateSubFrame( ::rtl::OUString(), SID_DB_APP_DSRELDESIGN, E_OPEN_DESIGN, xRelationDesigner ) )
1350                 {
1351 				    SharedConnection xConnection( ensureConnection() );
1352 				    if ( xConnection.is() )
1353 				    {
1354 					    RelationDesigner aDesigner( getORB(), this, m_aCurrentFrame.getFrame() );
1355 
1356                         const Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
1357 					    const Reference< XComponent > xComponent( aDesigner.createNew( xDataSource ), UNO_QUERY );
1358                         onDocumentOpened( ::rtl::OUString(), SID_DB_APP_DSRELDESIGN, E_OPEN_DESIGN, xComponent, NULL );
1359 				    }
1360                 }
1361             }
1362 			break;
1363 			case SID_DB_APP_DSUSERADMIN:
1364 				{
1365 					SharedConnection xConnection( ensureConnection() );
1366 					if ( xConnection.is() )
1367 						openDialog(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.UserAdministrationDialog")));
1368 				}
1369 				break;
1370 			case SID_DB_APP_TABLEFILTER:
1371 				openTableFilterDialog();
1372 				askToReconnect();
1373 				break;
1374 			case SID_DB_APP_REFRESH_TABLES:
1375 				refreshTables();
1376 				break;
1377 			case SID_DB_APP_DSPROPS:
1378 				openDataSourceAdminDialog();
1379 				askToReconnect();
1380 				break;
1381 			case SID_DB_APP_DSADVANCED_SETTINGS:
1382 				openDialog(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.AdvancedDatabaseSettingsDialog")));
1383 				askToReconnect();
1384 				break;
1385 			case SID_DB_APP_DSCONNECTION_TYPE:
1386 				openDialog(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.DataSourceTypeChangeDialog")));
1387 				askToReconnect();
1388 				break;
1389 			case ID_DIRECT_SQL:
1390 				{
1391 					SharedConnection xConnection( ensureConnection() );
1392 					if ( xConnection.is() )
1393 						openDirectSQLDialog();
1394 				}
1395 				break;
1396             case ID_MIGRATE_SCRIPTS:
1397                 impl_migrateScripts_nothrow();
1398                 break;
1399 			case SID_DB_APP_VIEW_TABLES:
1400                 m_aSelectContainerEvent.Call( reinterpret_cast< void* >( E_TABLE ) );
1401 				break;
1402 			case SID_DB_APP_VIEW_QUERIES:
1403                 m_aSelectContainerEvent.Call( reinterpret_cast< void* >( E_QUERY ) );
1404 				break;
1405 			case SID_DB_APP_VIEW_FORMS:
1406                 m_aSelectContainerEvent.Call( reinterpret_cast< void* >( E_FORM ) );
1407 				break;
1408 			case SID_DB_APP_VIEW_REPORTS:
1409                 m_aSelectContainerEvent.Call( reinterpret_cast< void* >( E_REPORT ) );
1410 				break;
1411 			case SID_DB_APP_DISABLE_PREVIEW:
1412 				m_ePreviewMode = E_PREVIEWNONE;
1413 				getContainer()->switchPreview(m_ePreviewMode);
1414 				break;
1415 			case SID_DB_APP_VIEW_DOCINFO_PREVIEW:
1416 				m_ePreviewMode = E_DOCUMENTINFO;
1417 				getContainer()->switchPreview(m_ePreviewMode);
1418 				break;
1419 			case SID_DB_APP_VIEW_DOC_PREVIEW:
1420 				m_ePreviewMode = E_DOCUMENT;
1421 				getContainer()->switchPreview(m_ePreviewMode);
1422 				break;
1423 			case SID_MAIL_SENDDOC:
1424 				{
1425 					SfxMailModel aSendMail;
1426                     if ( aSendMail.AttachDocument(rtl::OUString(),getModel(), rtl::OUString()) == SfxMailModel::SEND_MAIL_OK )
1427 						aSendMail.Send( getFrame() );
1428 				}
1429 				break;
1430 			case SID_DB_APP_SENDREPORTASMAIL:
1431 				doAction( _nId, E_OPEN_FOR_MAIL );
1432 				break;
1433 		}
1434 	}
1435 	catch( const Exception& )
1436 	{
1437         DBG_UNHANDLED_EXCEPTION();
1438 	}
1439 	InvalidateFeature(_nId);
1440 }
1441 // -----------------------------------------------------------------------------
1442 void OApplicationController::describeSupportedFeatures()
1443 {
1444 	OApplicationController_CBASE::describeSupportedFeatures();
1445 
1446     implDescribeSupportedFeature( ".uno:Save",               ID_BROWSER_SAVEDOC,        CommandGroup::DOCUMENT );
1447     implDescribeSupportedFeature( ".uno:SaveAs",             ID_BROWSER_SAVEASDOC,      CommandGroup::DOCUMENT );
1448 	implDescribeSupportedFeature( ".uno:SendMail",			 SID_MAIL_SENDDOC,			CommandGroup::DOCUMENT );
1449 	implDescribeSupportedFeature( ".uno:DBSendReportAsMail",SID_DB_APP_SENDREPORTASMAIL,
1450 																						CommandGroup::DOCUMENT );
1451 	implDescribeSupportedFeature( ".uno:DBSendReportToWriter",SID_DB_APP_SENDREPORTTOWRITER,
1452 																						CommandGroup::DOCUMENT );
1453     implDescribeSupportedFeature( ".uno:DBNewForm",          SID_APP_NEW_FORM,          CommandGroup::INSERT );
1454     implDescribeSupportedFeature( ".uno:DBNewFolder",        SID_APP_NEW_FOLDER,        CommandGroup::INSERT );
1455     implDescribeSupportedFeature( ".uno:DBNewFormAutoPilot", SID_DB_FORM_NEW_PILOT,     CommandGroup::INSERT );
1456     implDescribeSupportedFeature( ".uno:DBNewFormAutoPilotWithPreSelection",
1457                                                              SID_FORM_CREATE_REPWIZ_PRE_SEL,
1458                                                                                         CommandGroup::APPLICATION );
1459 
1460 	implDescribeSupportedFeature( ".uno:DBNewReport",		 SID_APP_NEW_REPORT,		CommandGroup::INSERT );
1461     implDescribeSupportedFeature( ".uno:DBNewReportAutoPilot",
1462                                                              ID_DOCUMENT_CREATE_REPWIZ, CommandGroup::INSERT );
1463     implDescribeSupportedFeature( ".uno:DBNewReportAutoPilotWithPreSelection",
1464                                                              SID_REPORT_CREATE_REPWIZ_PRE_SEL,
1465                                                                                         CommandGroup::APPLICATION );
1466     implDescribeSupportedFeature( ".uno:DBNewQuery",         ID_NEW_QUERY_DESIGN,       CommandGroup::INSERT );
1467     implDescribeSupportedFeature( ".uno:DBNewQuerySql",      ID_NEW_QUERY_SQL,          CommandGroup::INSERT );
1468     implDescribeSupportedFeature( ".uno:DBNewQueryAutoPilot",ID_APP_NEW_QUERY_AUTO_PILOT,
1469                                                                                         CommandGroup::INSERT );
1470     implDescribeSupportedFeature( ".uno:DBNewTable",         ID_NEW_TABLE_DESIGN,       CommandGroup::INSERT );
1471     implDescribeSupportedFeature( ".uno:DBNewTableAutoPilot",ID_NEW_TABLE_DESIGN_AUTO_PILOT,
1472                                                                                         CommandGroup::INSERT );
1473     implDescribeSupportedFeature( ".uno:DBNewView",          ID_NEW_VIEW_DESIGN,        CommandGroup::INSERT );
1474     implDescribeSupportedFeature( ".uno:DBNewViewSQL",       SID_DB_NEW_VIEW_SQL,       CommandGroup::INSERT );
1475 
1476     implDescribeSupportedFeature( ".uno:DBDelete",           SID_DB_APP_DELETE,         CommandGroup::EDIT );
1477 	implDescribeSupportedFeature( ".uno:Delete",			 SID_DB_APP_DELETE,         CommandGroup::EDIT );
1478     implDescribeSupportedFeature( ".uno:DBRename",           SID_DB_APP_RENAME,         CommandGroup::EDIT );
1479     implDescribeSupportedFeature( ".uno:DBEdit",             SID_DB_APP_EDIT,           CommandGroup::EDIT );
1480     implDescribeSupportedFeature( ".uno:DBEditSqlView",      SID_DB_APP_EDIT_SQL_VIEW,  CommandGroup::EDIT );
1481     implDescribeSupportedFeature( ".uno:DBOpen",             SID_DB_APP_OPEN,           CommandGroup::EDIT );
1482 
1483     implDescribeSupportedFeature( ".uno:DBTableDelete",      SID_DB_APP_TABLE_DELETE,   CommandGroup::EDIT );
1484     implDescribeSupportedFeature( ".uno:DBTableRename",      SID_DB_APP_TABLE_RENAME,   CommandGroup::EDIT );
1485     implDescribeSupportedFeature( ".uno:DBTableEdit",        SID_DB_APP_TABLE_EDIT,     CommandGroup::EDIT );
1486     implDescribeSupportedFeature( ".uno:DBTableOpen",        SID_DB_APP_TABLE_OPEN,     CommandGroup::EDIT );
1487 
1488     implDescribeSupportedFeature( ".uno:DBQueryDelete",      SID_DB_APP_QUERY_DELETE,   CommandGroup::EDIT );
1489     implDescribeSupportedFeature( ".uno:DBQueryRename",      SID_DB_APP_QUERY_RENAME,   CommandGroup::EDIT );
1490     implDescribeSupportedFeature( ".uno:DBQueryEdit",        SID_DB_APP_QUERY_EDIT,     CommandGroup::EDIT );
1491     implDescribeSupportedFeature( ".uno:DBQueryOpen",        SID_DB_APP_QUERY_OPEN,     CommandGroup::EDIT );
1492 
1493     implDescribeSupportedFeature( ".uno:DBFormDelete",       SID_DB_APP_FORM_DELETE,    CommandGroup::EDIT );
1494     implDescribeSupportedFeature( ".uno:DBFormRename",       SID_DB_APP_FORM_RENAME,    CommandGroup::EDIT );
1495     implDescribeSupportedFeature( ".uno:DBFormEdit",         SID_DB_APP_FORM_EDIT,      CommandGroup::EDIT );
1496     implDescribeSupportedFeature( ".uno:DBFormOpen",         SID_DB_APP_FORM_OPEN,      CommandGroup::EDIT );
1497 
1498     implDescribeSupportedFeature( ".uno:DBReportDelete",     SID_DB_APP_REPORT_DELETE,  CommandGroup::EDIT );
1499     implDescribeSupportedFeature( ".uno:DBReportRename",     SID_DB_APP_REPORT_RENAME,  CommandGroup::EDIT );
1500     implDescribeSupportedFeature( ".uno:DBReportEdit",       SID_DB_APP_REPORT_EDIT,    CommandGroup::EDIT );
1501     implDescribeSupportedFeature( ".uno:DBReportOpen",       SID_DB_APP_REPORT_OPEN,    CommandGroup::EDIT );
1502 
1503     implDescribeSupportedFeature( ".uno:SelectAll",          SID_SELECTALL,             CommandGroup::EDIT );
1504     implDescribeSupportedFeature( ".uno:Undo",               ID_BROWSER_UNDO,           CommandGroup::EDIT );
1505 
1506     implDescribeSupportedFeature( ".uno:Sortup",             ID_BROWSER_SORTUP,         CommandGroup::VIEW );
1507     implDescribeSupportedFeature( ".uno:SortDown",           ID_BROWSER_SORTDOWN,       CommandGroup::VIEW );
1508     implDescribeSupportedFeature( ".uno:DBRelationDesign",   SID_DB_APP_DSRELDESIGN,    CommandGroup::APPLICATION );
1509     implDescribeSupportedFeature( ".uno:DBUserAdmin",        SID_DB_APP_DSUSERADMIN,    CommandGroup::APPLICATION );
1510     implDescribeSupportedFeature( ".uno:DBTableFilter",      SID_DB_APP_TABLEFILTER,    CommandGroup::APPLICATION );
1511     implDescribeSupportedFeature( ".uno:DBDSProperties",     SID_DB_APP_DSPROPS,        CommandGroup::EDIT );
1512     implDescribeSupportedFeature( ".uno:DBDSConnectionType", SID_DB_APP_DSCONNECTION_TYPE,
1513                                                                                         CommandGroup::EDIT );
1514     implDescribeSupportedFeature( ".uno:DBDSAdvancedSettings",
1515                                                              SID_DB_APP_DSADVANCED_SETTINGS,
1516                                                                                         CommandGroup::EDIT );
1517     implDescribeSupportedFeature( ".uno:PasteSpecial",       SID_DB_APP_PASTE_SPECIAL,  CommandGroup::EDIT );
1518     implDescribeSupportedFeature( ".uno:DBConvertToView",    SID_DB_APP_CONVERTTOVIEW,  CommandGroup::EDIT );
1519     implDescribeSupportedFeature( ".uno:DBRefreshTables",    SID_DB_APP_REFRESH_TABLES, CommandGroup::APPLICATION );
1520     implDescribeSupportedFeature( ".uno:DBDirectSQL",        ID_DIRECT_SQL,             CommandGroup::APPLICATION );
1521     implDescribeSupportedFeature( ".uno:DBMigrateScripts",   ID_MIGRATE_SCRIPTS,        CommandGroup::APPLICATION );
1522     implDescribeSupportedFeature( ".uno:DBViewTables",       SID_DB_APP_VIEW_TABLES,    CommandGroup::VIEW );
1523     implDescribeSupportedFeature( ".uno:DBViewQueries",      SID_DB_APP_VIEW_QUERIES,   CommandGroup::VIEW );
1524     implDescribeSupportedFeature( ".uno:DBViewForms",        SID_DB_APP_VIEW_FORMS,     CommandGroup::VIEW );
1525     implDescribeSupportedFeature( ".uno:DBViewReports",      SID_DB_APP_VIEW_REPORTS,   CommandGroup::VIEW );
1526     implDescribeSupportedFeature( ".uno:DBDisablePreview",   SID_DB_APP_DISABLE_PREVIEW,CommandGroup::VIEW );
1527     implDescribeSupportedFeature( ".uno:DBShowDocInfoPreview",
1528                                                              SID_DB_APP_VIEW_DOCINFO_PREVIEW,
1529                                                                                         CommandGroup::VIEW );
1530     implDescribeSupportedFeature( ".uno:DBShowDocPreview",   SID_DB_APP_VIEW_DOC_PREVIEW,
1531                                                                                         CommandGroup::VIEW );
1532 
1533     implDescribeSupportedFeature( ".uno:OpenUrl",            SID_OPENURL,               CommandGroup::APPLICATION );
1534 
1535     // this one should not appear under Tools->Customize->Keyboard
1536     implDescribeSupportedFeature( ".uno:DBNewReportWithPreSelection",
1537                                                              SID_APP_NEW_REPORT_PRE_SEL,CommandGroup::INTERNAL );
1538 	implDescribeSupportedFeature( ".uno:DBDSImport",		SID_DB_APP_DSIMPORT, CommandGroup::INTERNAL);
1539 	implDescribeSupportedFeature( ".uno:DBDSExport",		SID_DB_APP_DSEXPORT, CommandGroup::INTERNAL);
1540 	implDescribeSupportedFeature( ".uno:DBDBAdmin",			SID_DB_APP_DBADMIN, CommandGroup::INTERNAL);
1541 
1542 	// status info
1543 	implDescribeSupportedFeature( ".uno:DBStatusType",		SID_DB_APP_STATUS_TYPE, CommandGroup::INTERNAL);
1544 	implDescribeSupportedFeature( ".uno:DBStatusDBName",	SID_DB_APP_STATUS_DBNAME, CommandGroup::INTERNAL);
1545 	implDescribeSupportedFeature( ".uno:DBStatusUserName",	SID_DB_APP_STATUS_USERNAME, CommandGroup::INTERNAL);
1546 	implDescribeSupportedFeature( ".uno:DBStatusHostName",	SID_DB_APP_STATUS_HOSTNAME, CommandGroup::INTERNAL);
1547 }
1548 // -----------------------------------------------------------------------------
1549 OApplicationView*	OApplicationController::getContainer() const
1550 {
1551 	return static_cast< OApplicationView* >( getView() );
1552 }
1553 
1554 // -----------------------------------------------------------------------------
1555 // ::com::sun::star::container::XContainerListener
1556 void SAL_CALL OApplicationController::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException)
1557 {
1558 	::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1559 	::osl::MutexGuard aGuard( getMutex() );
1560 
1561 	Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY);
1562 	if ( ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) != m_aCurrentContainers.end() )
1563 	{
1564 		OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
1565 		if ( getContainer() )
1566 		{
1567 			::rtl::OUString sName;
1568 			_rEvent.Accessor >>= sName;
1569 			ElementType eType = getElementType(xContainer);
1570 
1571 			switch( eType )
1572 			{
1573 				case E_TABLE:
1574 					ensureConnection();
1575 					break;
1576 				case E_FORM:
1577 				case E_REPORT:
1578 					{
1579 						Reference< XContainer > xSubContainer(_rEvent.Element,UNO_QUERY);
1580 						if ( xSubContainer.is() )
1581 							containerFound(xSubContainer);
1582 					}
1583 					break;
1584                 default:
1585                     break;
1586 			}
1587 			getContainer()->elementAdded(eType,sName,_rEvent.Element);
1588 		}
1589 	}
1590 }
1591 // -----------------------------------------------------------------------------
1592 void SAL_CALL OApplicationController::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException)
1593 {
1594 	::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1595 	::osl::MutexGuard aGuard( getMutex() );
1596 
1597 	Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY);
1598 	if ( ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) != m_aCurrentContainers.end() )
1599 	{
1600 		OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
1601 		::rtl::OUString sName;
1602 		_rEvent.Accessor >>= sName;
1603 		ElementType eType = getElementType(xContainer);
1604 		switch( eType )
1605 		{
1606 			case E_TABLE:
1607 				ensureConnection();
1608 				break;
1609 			case E_FORM:
1610 			case E_REPORT:
1611 				{
1612 					Reference<XContent> xContent(xContainer,UNO_QUERY);
1613 					if ( xContent.is() )
1614 					{
1615 						sName = xContent->getIdentifier()->getContentIdentifier() + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) + sName;
1616 					}
1617 				}
1618 				break;
1619             default:
1620                 break;
1621 		}
1622 		getContainer()->elementRemoved(eType,sName);
1623 	}
1624 }
1625 // -----------------------------------------------------------------------------
1626 void SAL_CALL OApplicationController::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException)
1627 {
1628 	::vos::OGuard aSolarGuard(Application::GetSolarMutex());
1629 	::osl::MutexGuard aGuard( getMutex() );
1630 
1631 	Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY);
1632 	if ( ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) != m_aCurrentContainers.end() )
1633 	{
1634 		OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
1635 		::rtl::OUString sName;
1636 		try
1637 		{
1638 			_rEvent.Accessor >>= sName;
1639 			Reference<XConnection> xConnection;
1640 			Reference<XPropertySet> xProp(_rEvent.Element,UNO_QUERY);
1641 			::rtl::OUString sNewName;
1642 
1643 			ElementType eType = getElementType(xContainer);
1644 			switch( eType )
1645 			{
1646 				case E_TABLE:
1647                 {
1648 					ensureConnection();
1649 					if ( xProp.is() && m_xMetaData.is() )
1650 						sNewName = ::dbaui::composeTableName( m_xMetaData, xProp, ::dbtools::eInDataManipulation, false, false, false );
1651                 }
1652 				break;
1653 				case E_FORM:
1654 				case E_REPORT:
1655 					{
1656 						Reference<XContent> xContent(xContainer,UNO_QUERY);
1657 						if ( xContent.is() )
1658 						{
1659 							sName = xContent->getIdentifier()->getContentIdentifier() + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) + sName;
1660 						}
1661 					}
1662 					break;
1663                 default:
1664                     break;
1665 			}
1666 			//	getContainer()->elementReplaced(getContainer()->getElementType(),sName,sNewName);
1667 		}
1668 		catch( Exception& )
1669 		{
1670             DBG_UNHANDLED_EXCEPTION();
1671 		}
1672 	}
1673 }
1674 namespace
1675 {
1676 	::rtl::OUString lcl_getToolBarResource(ElementType _eType)
1677 	{
1678 		::rtl::OUString sToolbar;
1679 		switch(_eType)
1680 		{
1681 			case E_TABLE:
1682 				sToolbar = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/tableobjectbar" ));
1683 				break;
1684 			case E_QUERY:
1685 				sToolbar = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/queryobjectbar" ));
1686 				break;
1687 			case E_FORM:
1688 				sToolbar = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/formobjectbar" ));
1689 				break;
1690 			case E_REPORT:
1691 				sToolbar = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/reportobjectbar" ));
1692 				break;
1693 			case E_NONE:
1694 				break;
1695 			default:
1696 				OSL_ENSURE(0,"Invalid ElementType!");
1697 				break;
1698 		}
1699 		return sToolbar;
1700 	}
1701 }
1702 // -----------------------------------------------------------------------------
1703 sal_Bool OApplicationController::onContainerSelect(ElementType _eType)
1704 {
1705 	OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
1706 
1707     if ( m_eCurrentType != _eType && _eType != E_NONE )
1708 	{
1709         SelectionGuard aSelGuard( *m_pSelectionNotifier );
1710 
1711         if ( _eType == E_TABLE )
1712 		{
1713 			try
1714 			{
1715 				SharedConnection xConnection( ensureConnection() );
1716 				if ( xConnection.is() && getContainer()->getDetailView() )
1717 				{
1718 					getContainer()->getDetailView()->createTablesPage(xConnection);
1719 					Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY);
1720 					if ( xTabSup.is() )
1721 						addContainerListener(xTabSup->getTables());
1722 				}
1723 				else
1724 				{
1725 					return sal_False;
1726 				}
1727 			}
1728 			catch( const Exception& )
1729 			{
1730 				return sal_False;
1731 			}
1732 		}
1733         Reference< XLayoutManager > xLayoutManager = getLayoutManager( getFrame() );
1734         if ( xLayoutManager.is() )
1735         {
1736 		    ::rtl::OUString sToolbar = lcl_getToolBarResource(_eType);
1737 		    ::rtl::OUString sDestroyToolbar = lcl_getToolBarResource(m_eCurrentType);
1738 
1739 		    xLayoutManager->lock();
1740 		    xLayoutManager->destroyElement( sDestroyToolbar );
1741 		    if ( sToolbar.getLength() )
1742 		    {
1743 			    xLayoutManager->createElement( sToolbar );
1744 			    xLayoutManager->requestElement( sToolbar );
1745 		    }
1746 		    xLayoutManager->unlock();
1747 		    xLayoutManager->doLayout();
1748         }
1749 
1750 		if ( _eType != E_TABLE && getContainer()->getDetailView() )
1751 		{
1752 			Reference< XNameAccess > xContainer = getElements(_eType);
1753 			addContainerListener(xContainer);
1754 			getContainer()->getDetailView()->createPage(_eType,xContainer);
1755 		}
1756 
1757         SelectionByElementType::iterator pendingSelection = m_aPendingSelection.find( _eType );
1758         if ( pendingSelection != m_aPendingSelection.end() )
1759         {
1760             Sequence< ::rtl::OUString > aSelected( pendingSelection->second.size() );
1761             ::std::copy( pendingSelection->second.begin(), pendingSelection->second.end(), aSelected.getArray() );
1762             getContainer()->selectElements( aSelected );
1763 
1764             m_aPendingSelection.erase( pendingSelection );
1765         }
1766 
1767 		InvalidateAll();
1768 	}
1769 	m_eCurrentType = _eType;
1770 
1771 	return sal_True;
1772 }
1773 // -----------------------------------------------------------------------------
1774 bool OApplicationController::onEntryDoubleClick( SvTreeListBox& _rTree )
1775 {
1776 	if ( getContainer() && getContainer()->isLeaf( _rTree.GetHdlEntry() ) )
1777 	{
1778 		try
1779 		{
1780 			openElement(
1781                 getContainer()->getQualifiedName( _rTree.GetHdlEntry() ),
1782                 getContainer()->getElementType(),
1783                 E_OPEN_NORMAL
1784             );
1785             return true;    // handled
1786 		}
1787 		catch(const Exception&)
1788 		{
1789 			DBG_UNHANDLED_EXCEPTION();
1790 		}
1791 	}
1792     return false;   // not handled
1793 }
1794 // -----------------------------------------------------------------------------
1795 bool OApplicationController::impl_isAlterableView_nothrow( const ::rtl::OUString& _rTableOrViewName ) const
1796 {
1797     OSL_PRECOND( m_xDataSourceConnection.is(), "OApplicationController::impl_isAlterableView_nothrow: no connection!" );
1798 
1799     bool bIsAlterableView( false );
1800     try
1801     {
1802         Reference< XViewsSupplier > xViewsSupp( m_xDataSourceConnection, UNO_QUERY );
1803         Reference< XNameAccess > xViews;
1804         if ( xViewsSupp.is() )
1805             xViews = xViewsSupp->getViews();
1806 
1807         Reference< XAlterView > xAsAlterableView;
1808         if ( xViews.is() && xViews->hasByName( _rTableOrViewName ) )
1809             xAsAlterableView.set( xViews->getByName( _rTableOrViewName ), UNO_QUERY );
1810 
1811         bIsAlterableView = xAsAlterableView.is();
1812     }
1813     catch( const Exception& )
1814     {
1815         DBG_UNHANDLED_EXCEPTION();
1816     }
1817     return bIsAlterableView;
1818 }
1819 
1820 // -----------------------------------------------------------------------------
1821 Reference< XComponent > OApplicationController::openElement(const ::rtl::OUString& _sName, ElementType _eType,
1822     ElementOpenMode _eOpenMode, sal_uInt16 _nInstigatorCommand )
1823 {
1824     return openElementWithArguments( _sName, _eType, _eOpenMode, _nInstigatorCommand, ::comphelper::NamedValueCollection() );
1825 }
1826 
1827 // -----------------------------------------------------------------------------
1828 Reference< XComponent > OApplicationController::openElementWithArguments( const ::rtl::OUString& _sName, ElementType _eType,
1829     ElementOpenMode _eOpenMode, sal_uInt16 _nInstigatorCommand, const ::comphelper::NamedValueCollection& _rAdditionalArguments )
1830 {
1831     OSL_PRECOND( getContainer(), "OApplicationController::openElementWithArguments: no view!" );
1832     if ( !getContainer() )
1833         return NULL;
1834 
1835 	Reference< XComponent > xRet;
1836 	if ( _eOpenMode == E_OPEN_DESIGN )
1837 	{
1838 		// OJ: http://www.openoffice.org/issues/show_bug.cgi?id=30382
1839 		getContainer()->showPreview(NULL);
1840 	}
1841 
1842     bool isStandaloneDocument = false;
1843     switch ( _eType )
1844 	{
1845 	case E_REPORT:
1846         if ( _eOpenMode != E_OPEN_DESIGN )
1847         {
1848             // reports which are opened in a mode other than design are no sub components of our application
1849             // component, but standalone documents.
1850             isStandaloneDocument = true;
1851         }
1852         // NO break!
1853 	case E_FORM:
1854 	{
1855         if ( isStandaloneDocument || !m_pSubComponentManager->activateSubFrame( _sName, _eType, _eOpenMode, xRet ) )
1856         {
1857 		    ::std::auto_ptr< OLinkedDocumentsAccess > aHelper = getDocumentsAccess( _eType );
1858             if ( !aHelper->isConnected() )
1859                 break;
1860 
1861 		    Reference< XComponent > xDefinition;
1862 		    xRet = aHelper->open( _sName, xDefinition, _eOpenMode, _rAdditionalArguments );
1863 
1864             if ( !isStandaloneDocument )
1865 		        onDocumentOpened( _sName, _eType, _eOpenMode, xRet, xDefinition );
1866         }
1867 	}
1868 	break;
1869 
1870 	case E_QUERY:
1871 	case E_TABLE:
1872 	{
1873         if ( !m_pSubComponentManager->activateSubFrame( _sName, _eType, _eOpenMode, xRet ) )
1874         {
1875 		    SharedConnection xConnection( ensureConnection() );
1876 		    if ( !xConnection.is() )
1877                 break;
1878 
1879             ::std::auto_ptr< DatabaseObjectView > pDesigner;
1880             ::comphelper::NamedValueCollection aArguments( _rAdditionalArguments );
1881 
1882             Any aDataSource;
1883 		    if ( _eOpenMode == E_OPEN_DESIGN )
1884 		    {
1885                 bool bAddViewTypeArg = false;
1886 
1887 			    if ( _eType == E_TABLE )
1888 			    {
1889                     if ( impl_isAlterableView_nothrow( _sName ) )
1890                     {
1891                         pDesigner.reset( new QueryDesigner( getORB(), this, m_aCurrentFrame.getFrame(), true ) );
1892                         bAddViewTypeArg = true;
1893                     }
1894                     else
1895                     {
1896                         pDesigner.reset( new TableDesigner( getORB(), this, m_aCurrentFrame.getFrame() ) );
1897                     }
1898 			    }
1899 			    else if ( _eType == E_QUERY )
1900 			    {
1901                     pDesigner.reset( new QueryDesigner( getORB(), this, m_aCurrentFrame.getFrame(), false ) );
1902                     bAddViewTypeArg = true;
1903 			    }
1904 			    aDataSource <<= m_xDataSource;
1905 
1906                 if ( bAddViewTypeArg )
1907                 {
1908                     const bool bQueryGraphicalMode =( _nInstigatorCommand != SID_DB_APP_EDIT_SQL_VIEW );
1909                     aArguments.put( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN, bQueryGraphicalMode );
1910                 }
1911 
1912 		    }
1913 		    else
1914 		    {
1915 			    pDesigner.reset( new ResultSetBrowser( getORB(), this, m_aCurrentFrame.getFrame(), _eType == E_TABLE ) );
1916 
1917                 if ( !aArguments.has( (::rtl::OUString)PROPERTY_SHOWMENU ) )
1918                     aArguments.put( (::rtl::OUString)PROPERTY_SHOWMENU, makeAny( (sal_Bool)sal_True ) );
1919 
1920 		        aDataSource <<= getDatabaseName();
1921 		    }
1922 
1923 		    xRet.set( pDesigner->openExisting( aDataSource, _sName, aArguments ) );
1924 	        onDocumentOpened( _sName, _eType, _eOpenMode, xRet, NULL );
1925         }
1926 	}
1927 	break;
1928 
1929     default:
1930         OSL_ENSURE( false, "OApplicationController::openElement: illegal object type!" );
1931         break;
1932 	}
1933 	return xRet;
1934 }
1935 // -----------------------------------------------------------------------------
1936 IMPL_LINK( OApplicationController, OnSelectContainer, void*, _pType )
1937 {
1938     ElementType eType = (ElementType)reinterpret_cast< sal_IntPtr >( _pType );
1939     getContainer()->selectContainer(eType);
1940     return 0L;
1941 }
1942 // -----------------------------------------------------------------------------
1943 IMPL_LINK( OApplicationController, OnCreateWithPilot, void*, _pType )
1944 {
1945     ElementType eType = (ElementType)reinterpret_cast< sal_IntPtr >( _pType );
1946     newElementWithPilot( eType );
1947     return 0L;
1948 }
1949 
1950 // -----------------------------------------------------------------------------
1951 void OApplicationController::newElementWithPilot( ElementType _eType )
1952 {
1953     CloseVeto aKeepDoc( getFrame() );
1954         // prevent the document being closed while the wizard is open
1955 
1956     OSL_ENSURE( getContainer(), "OApplicationController::newElementWithPilot: without a view?" );
1957 
1958 	switch ( _eType )
1959 	{
1960 		case E_REPORT:
1961 		case E_FORM:
1962 		{
1963 			::std::auto_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess(_eType);
1964             if ( aHelper->isConnected() )
1965 			{
1966                 sal_Int32 nCommandType = -1;
1967                 const ::rtl::OUString sCurrentSelected( getCurrentlySelectedName( nCommandType ) );
1968 				if ( E_REPORT == _eType )
1969 					aHelper->newReportWithPilot( nCommandType, sCurrentSelected );
1970 				else
1971 					aHelper->newFormWithPilot( nCommandType, sCurrentSelected );
1972 			}
1973         }
1974         break;
1975         case E_QUERY:
1976         case E_TABLE:
1977  		{
1978 		    ::std::auto_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess(_eType);
1979             if ( aHelper->isConnected() )
1980             {
1981 		        if ( E_QUERY == _eType )
1982 			        aHelper->newQueryWithPilot();
1983 		        else
1984 			        aHelper->newTableWithPilot();
1985 		    }
1986  		}
1987  		break;
1988         case E_NONE:
1989             break;
1990     }
1991 
1992     // no need for onDocumentOpened, the table wizard opens the created table by using
1993     // XDatabaseDocumentUI::loadComponent method.
1994 }
1995 
1996 // -----------------------------------------------------------------------------
1997 Reference< XComponent > OApplicationController::newElement( ElementType _eType, const ::comphelper::NamedValueCollection& i_rAdditionalArguments,
1998                                                            Reference< XComponent >& o_rDocumentDefinition )
1999 {
2000 	OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
2001 
2002     Reference< XComponent > xComponent;
2003     o_rDocumentDefinition.clear();
2004 
2005 	switch ( _eType )
2006 	{
2007         case E_FORM:
2008 		case E_REPORT:
2009 		{
2010 			::std::auto_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess( _eType );
2011             if ( !aHelper->isConnected() )
2012                 break;
2013 
2014             xComponent = aHelper->newDocument( _eType == E_FORM ? ID_FORM_NEW_TEXT : ID_REPORT_NEW_TEXT, i_rAdditionalArguments, o_rDocumentDefinition );
2015 		}
2016 		break;
2017 
2018 		case E_QUERY:
2019 		case E_TABLE:
2020 		{
2021 			::std::auto_ptr< DatabaseObjectView > pDesigner;
2022 			SharedConnection xConnection( ensureConnection() );
2023 			if ( !xConnection.is() )
2024                 break;
2025 
2026             if ( _eType == E_TABLE )
2027 			{
2028 				pDesigner.reset( new TableDesigner( getORB(), this, getFrame() ) );
2029 			}
2030 			else if ( _eType == E_QUERY )
2031 			{
2032 				pDesigner.reset( new QueryDesigner( getORB(), this, getFrame(), false ) );
2033 			}
2034 
2035             Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
2036 			xComponent.set( pDesigner->createNew( xDataSource, i_rAdditionalArguments ), UNO_QUERY );
2037 		}
2038 		break;
2039 
2040         default:
2041             OSL_ENSURE( false, "OApplicationController::newElement: illegal type!" );
2042             break;
2043 	}
2044 
2045     if ( xComponent.is() )
2046         onDocumentOpened( ::rtl::OUString(), _eType, E_OPEN_DESIGN, xComponent, o_rDocumentDefinition );
2047 
2048     return xComponent;
2049 }
2050 
2051 // -----------------------------------------------------------------------------
2052 void OApplicationController::addContainerListener(const Reference<XNameAccess>& _xCollection)
2053 {
2054 	try
2055 	{
2056 		Reference< XContainer > xCont(_xCollection, UNO_QUERY);
2057 		if ( xCont.is() )
2058 		{
2059 			// add as listener to get notified if elements are inserted or removed
2060 			TContainerVector::iterator aFind = ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xCont);
2061 			if ( aFind == m_aCurrentContainers.end() )
2062 			{
2063 				xCont->addContainerListener(this);
2064 				m_aCurrentContainers.push_back(xCont);
2065 			}
2066 		}
2067 	}
2068 	catch( const Exception& )
2069 	{
2070         DBG_UNHANDLED_EXCEPTION();
2071 	}
2072 }
2073 // -----------------------------------------------------------------------------
2074 void OApplicationController::renameEntry()
2075 {
2076 	::vos::OGuard aSolarGuard(Application::GetSolarMutex());
2077 	::osl::MutexGuard aGuard( getMutex() );
2078 
2079 	OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
2080 	::std::vector< ::rtl::OUString> aList;
2081 	getSelectionElementNames(aList);
2082 
2083 	Reference< XNameAccess > xContainer = getElements(getContainer()->getElementType());
2084 	OSL_ENSURE(aList.size() == 1,"Invalid rename call here. More than one element!");
2085     if ( aList.empty() )
2086         return;
2087 
2088 	try
2089 	{
2090 		if ( xContainer.is() )
2091 		{
2092             ::std::auto_ptr< IObjectNameCheck > pNameChecker;
2093             ::std::auto_ptr< OSaveAsDlg > aDialog;
2094 
2095 			Reference<XRename> xRename;
2096 			const ElementType eType = getContainer()->getElementType();
2097 			switch( eType )
2098 			{
2099 				case E_FORM:
2100 				case E_REPORT:
2101 					{
2102 						Reference<XHierarchicalNameContainer> xHNames(xContainer, UNO_QUERY);
2103 						if ( xHNames.is() )
2104 						{
2105 							String sLabel;
2106 							if ( eType == E_FORM )
2107 								sLabel = String(ModuleRes( STR_FRM_LABEL ));
2108 							else
2109 								sLabel = String(ModuleRes( STR_RPT_LABEL ));
2110 
2111 							::rtl::OUString sName = *aList.begin();
2112 							if ( xHNames->hasByHierarchicalName(sName) )
2113 							{
2114 								xRename.set(xHNames->getByHierarchicalName(sName),UNO_QUERY);
2115 								Reference<XChild> xChild(xRename,UNO_QUERY);
2116 								if ( xChild.is() )
2117 								{
2118 									Reference<XHierarchicalNameContainer> xParent(xChild->getParent(),UNO_QUERY);
2119 									if ( xParent.is() )
2120 									{
2121 										xHNames = xParent;
2122 										Reference<XPropertySet>(xRename,UNO_QUERY)->getPropertyValue(PROPERTY_NAME) >>= sName;
2123 									}
2124 								}
2125                                 pNameChecker.reset( new HierarchicalNameCheck( xHNames.get(), String() ) );
2126 								aDialog.reset( new OSaveAsDlg(
2127                                     getView(), getORB(), sName, sLabel, *pNameChecker, SAD_TITLE_RENAME ) );
2128 							}
2129 						}
2130 					}
2131 					break;
2132 				case E_TABLE:
2133                     ensureConnection();
2134                     if ( !getConnection().is() )
2135                         break;
2136                     // NO break
2137 				case E_QUERY:
2138 					if ( xContainer->hasByName(*aList.begin()) )
2139 					{
2140 						xRename.set(xContainer->getByName(*aList.begin()),UNO_QUERY);
2141                         sal_Int32 nCommandType = eType == E_QUERY ? CommandType::QUERY : CommandType::TABLE;
2142 
2143                         ensureConnection();
2144                         pNameChecker.reset( new DynamicTableOrQueryNameCheck( getConnection(), nCommandType ) );
2145 					    aDialog.reset( new OSaveAsDlg(
2146                             getView(), nCommandType, getORB(), getConnection(),
2147                                 *aList.begin(), *pNameChecker, SAD_TITLE_RENAME ) );
2148 					}
2149 					break;
2150                 default:
2151                     break;
2152 			}
2153 
2154 			if ( xRename.is() && aDialog.get() )
2155 			{
2156 
2157 				sal_Bool bTryAgain = sal_True;
2158 				while( bTryAgain )
2159 				{
2160 					if ( aDialog->Execute() == RET_OK )
2161 					{
2162 						try
2163 						{
2164 							::rtl::OUString sNewName;
2165 							if ( eType == E_TABLE )
2166 							{
2167 								::rtl::OUString sName = aDialog->getName();
2168 								::rtl::OUString sCatalog = aDialog->getCatalog();
2169 								::rtl::OUString sSchema	 = aDialog->getSchema();
2170 
2171 								sNewName = ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sName, sal_False, ::dbtools::eInDataManipulation );
2172 							}
2173 							else
2174 								sNewName = aDialog->getName();
2175 
2176 							::rtl::OUString sOldName = *aList.begin();
2177 							if ( eType == E_FORM || eType == E_REPORT )
2178 							{
2179 								Reference<XContent> xContent(xRename,UNO_QUERY);
2180 								if ( xContent.is() )
2181 								{
2182 									sOldName = xContent->getIdentifier()->getContentIdentifier();
2183 								}
2184 							}
2185 
2186 							xRename->rename(sNewName);
2187 
2188                             if ( eType == E_TABLE )
2189                             {
2190                                 Reference<XPropertySet> xProp(xRename,UNO_QUERY);
2191                                 sNewName = ::dbaui::composeTableName( m_xMetaData, xProp, ::dbtools::eInDataManipulation, false, false, false );
2192                             }
2193 							getContainer()->elementReplaced( eType , sOldName, sNewName );
2194 
2195 							bTryAgain = sal_False;
2196 						}
2197 						catch(const SQLException& )
2198                         {
2199                             showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
2200 
2201 						}
2202 						catch(const ElementExistException& e)
2203 						{
2204 							static ::rtl::OUString sStatus = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000"));
2205 							String sMsg = String( ModuleRes( STR_NAME_ALREADY_EXISTS ) );
2206 							sMsg.SearchAndReplace('#',e.Message);
2207 							showError(SQLExceptionInfo(SQLException(sMsg, e.Context, sStatus, 0, Any())));
2208 						}
2209 						catch(const Exception& )
2210 						{
2211                             DBG_UNHANDLED_EXCEPTION();
2212 						}
2213 					}
2214 					else
2215 						bTryAgain = sal_False;
2216 				}
2217 			}
2218 		}
2219 	}
2220 	catch(const Exception& )
2221 	{
2222         DBG_UNHANDLED_EXCEPTION();
2223 	}
2224 }
2225 
2226 // -----------------------------------------------------------------------------
2227 void OApplicationController::onSelectionChanged()
2228 {
2229 	InvalidateAll();
2230 
2231     SelectionGuard aSelGuard( *m_pSelectionNotifier );
2232 
2233 	OApplicationView* pView = getContainer();
2234     if ( !pView )
2235         return;
2236 
2237     if ( pView->getSelectionCount() == 1 )
2238     {
2239         const ElementType eType = pView->getElementType();
2240   	    if ( pView->isALeafSelected() )
2241         {
2242             const ::rtl::OUString sName = pView->getQualifiedName( NULL /* means 'first selected' */ );
2243             showPreviewFor( eType, sName );
2244         }
2245     }
2246 }
2247 // -----------------------------------------------------------------------------
2248 void OApplicationController::showPreviewFor(const ElementType _eType,const ::rtl::OUString& _sName)
2249 {
2250     if ( m_ePreviewMode == E_PREVIEWNONE )
2251         return;
2252 
2253     OApplicationView* pView = getContainer();
2254     if ( !pView )
2255         return;
2256 
2257 	try
2258 	{
2259 		switch( _eType )
2260 		{
2261 			case E_FORM:
2262 			case E_REPORT:
2263             {
2264 				Reference< XHierarchicalNameAccess > xContainer( getElements( _eType ), UNO_QUERY_THROW );
2265                 Reference< XContent> xContent( xContainer->getByHierarchicalName( _sName ), UNO_QUERY_THROW );
2266 	            pView->showPreview( xContent );
2267             }
2268 			break;
2269 
2270             case E_TABLE:
2271 			case E_QUERY:
2272                 {
2273                     SharedConnection xConnection( ensureConnection() );
2274 					if ( xConnection.is() )
2275 						pView->showPreview( getDatabaseName(), xConnection, _sName, _eType == E_TABLE );
2276                 }
2277 				return;
2278 
2279             default:
2280                 OSL_ENSURE( false, "OApplicationController::showPreviewFor: unexpected element type!" );
2281                 break;
2282 		}
2283 	}
2284 	catch( const SQLException& )
2285 	{
2286         showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
2287 	}
2288 	catch(const Exception& )
2289 	{
2290         DBG_UNHANDLED_EXCEPTION();
2291 	}
2292 }
2293 
2294 //------------------------------------------------------------------------------
2295 IMPL_LINK( OApplicationController, OnClipboardChanged, void*, EMPTYARG )
2296 {
2297 	return OnInvalidateClipboard( NULL );
2298 }
2299 //------------------------------------------------------------------------------
2300 IMPL_LINK(OApplicationController, OnInvalidateClipboard, void*, EMPTYARG)
2301 {
2302 	InvalidateFeature(ID_BROWSER_CUT);
2303 	InvalidateFeature(ID_BROWSER_COPY);
2304 	InvalidateFeature(ID_BROWSER_PASTE);
2305 	InvalidateFeature(SID_DB_APP_PASTE_SPECIAL);
2306 	return 0L;
2307 }
2308 // -----------------------------------------------------------------------------
2309 void OApplicationController::onCutEntry()
2310 {
2311 }
2312 // -----------------------------------------------------------------------------
2313 void OApplicationController::onCopyEntry()
2314 {
2315 	Execute(ID_BROWSER_COPY,Sequence<PropertyValue>());
2316 }
2317 // -----------------------------------------------------------------------------
2318 void OApplicationController::onPasteEntry()
2319 {
2320 	Execute(ID_BROWSER_PASTE,Sequence<PropertyValue>());
2321 }
2322 // -----------------------------------------------------------------------------
2323 void OApplicationController::onDeleteEntry()
2324 {
2325 	ElementType eType = getContainer()->getElementType();
2326 	sal_uInt16 nId = 0;
2327 	switch(eType)
2328 	{
2329 		case E_TABLE:
2330 			nId = SID_DB_APP_TABLE_DELETE;
2331 			break;
2332 		case E_QUERY:
2333 			nId = SID_DB_APP_QUERY_DELETE;
2334 			break;
2335 		case E_FORM:
2336 			nId = SID_DB_APP_FORM_DELETE;
2337 			break;
2338 		case E_REPORT:
2339 			nId = SID_DB_APP_REPORT_DELETE;
2340 			break;
2341 		default:
2342 			OSL_ENSURE(0,"Invalid ElementType!");
2343 			break;
2344 	}
2345 	executeChecked(nId,Sequence<PropertyValue>());
2346 }
2347 
2348 // -----------------------------------------------------------------------------
2349 void OApplicationController::executeUnChecked(const URL& _rCommand, const Sequence< PropertyValue>& aArgs)
2350 {
2351     OApplicationController_CBASE::executeUnChecked( _rCommand, aArgs );
2352 }
2353 
2354 // -----------------------------------------------------------------------------
2355 void OApplicationController::executeChecked(const URL& _rCommand, const Sequence< PropertyValue>& aArgs)
2356 {
2357     OApplicationController_CBASE::executeChecked( _rCommand, aArgs );
2358 }
2359 
2360 // -----------------------------------------------------------------------------
2361 void OApplicationController::executeUnChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue>& aArgs)
2362 {
2363     OApplicationController_CBASE::executeUnChecked( _nCommandId, aArgs );
2364 }
2365 
2366 // -----------------------------------------------------------------------------
2367 void OApplicationController::executeChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue>& aArgs)
2368 {
2369     OApplicationController_CBASE::executeChecked( _nCommandId, aArgs );
2370 }
2371 
2372 // -----------------------------------------------------------------------------
2373 sal_Bool OApplicationController::isCommandEnabled(sal_uInt16 _nCommandId) const
2374 {
2375     return OApplicationController_CBASE::isCommandEnabled( _nCommandId );
2376 }
2377 
2378 // -----------------------------------------------------------------------------
2379 sal_Bool OApplicationController::isCommandEnabled( const ::rtl::OUString& _rCompleteCommandURL ) const
2380 {
2381     return OApplicationController_CBASE::isCommandEnabled( _rCompleteCommandURL );
2382 }
2383 
2384 // -----------------------------------------------------------------------------
2385 sal_uInt16 OApplicationController::registerCommandURL( const ::rtl::OUString& _rCompleteCommandURL )
2386 {
2387     return OApplicationController_CBASE::registerCommandURL( _rCompleteCommandURL );
2388 }
2389 
2390 // -----------------------------------------------------------------------------
2391 void OApplicationController::notifyHiContrastChanged()
2392 {
2393     OApplicationController_CBASE::notifyHiContrastChanged();
2394 }
2395 
2396 // -----------------------------------------------------------------------------
2397 Reference< XController > OApplicationController::getXController() throw( RuntimeException )
2398 {
2399     return OApplicationController_CBASE::getXController();
2400 }
2401 
2402 // -----------------------------------------------------------------------------
2403 bool OApplicationController::interceptUserInput( const NotifyEvent& _rEvent )
2404 {
2405     return OApplicationController_CBASE::interceptUserInput( _rEvent );
2406 }
2407 
2408 // -----------------------------------------------------------------------------
2409 PopupMenu* OApplicationController::getContextMenu( Control& /*_rControl*/ ) const
2410 {
2411     return new PopupMenu( ModuleRes( RID_MENU_APP_EDIT ) );
2412 }
2413 
2414 // -----------------------------------------------------------------------------
2415 IController& OApplicationController::getCommandController()
2416 {
2417     return *static_cast< IApplicationController* >( this );
2418 }
2419 
2420 // -----------------------------------------------------------------------------
2421 ::cppu::OInterfaceContainerHelper* OApplicationController::getContextMenuInterceptors()
2422 {
2423     return &m_aContextMenuInterceptors;
2424 }
2425 
2426 // -----------------------------------------------------------------------------
2427 Any OApplicationController::getCurrentSelection( Control& _rControl ) const
2428 {
2429     Sequence< NamedDatabaseObject > aSelection;
2430 	getContainer()->describeCurrentSelectionForControl( _rControl, aSelection );
2431     return makeAny( aSelection );
2432 }
2433 
2434 // -----------------------------------------------------------------------------
2435 sal_Bool OApplicationController::requestQuickHelp( const SvLBoxEntry* /*_pEntry*/, String& /*_rText*/ ) const
2436 {
2437     return sal_False;
2438 }
2439 
2440 // -----------------------------------------------------------------------------
2441 sal_Bool OApplicationController::requestDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ )
2442 {
2443 	TransferableHelper* pTransfer = NULL;
2444 	if ( getContainer() && getContainer()->getSelectionCount() )
2445 	{
2446 		try
2447 		{
2448 			pTransfer = copyObject( );
2449 			Reference< XTransferable> xEnsureDelete = pTransfer;
2450 
2451 			if ( pTransfer && getContainer()->getDetailView() )
2452 			{
2453 				ElementType eType = getContainer()->getElementType();
2454 				pTransfer->StartDrag( getContainer()->getDetailView()->getTreeWindow(), ((eType == E_FORM || eType == E_REPORT) ? DND_ACTION_COPYMOVE : DND_ACTION_COPY) );
2455 			}
2456 		}
2457 		catch(const Exception& )
2458 		{
2459             DBG_UNHANDLED_EXCEPTION();
2460 		}
2461 	}
2462 
2463 	return NULL != pTransfer;
2464 }
2465 // -----------------------------------------------------------------------------
2466 sal_Int8 OApplicationController::queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors )
2467 {
2468 	sal_Int8 nActionAskedFor = _rEvt.mnAction;
2469 	// check if we're a table or query container
2470 	OApplicationView* pView = getContainer();
2471 	if ( pView && !isDataSourceReadOnly() )
2472 	{
2473 		ElementType eType = pView->getElementType();
2474 		if ( eType != E_NONE && (eType != E_TABLE || !isConnectionReadOnly()) )
2475 		{
2476 			// check for the concrete type
2477 			if(::std::find_if(_rFlavors.begin(),_rFlavors.end(),TAppSupportedSotFunctor(eType,sal_True)) != _rFlavors.end())
2478 				return DND_ACTION_COPY;
2479 			if ( eType == E_FORM || eType == E_REPORT )
2480 			{
2481 				sal_Int8 nAction = OComponentTransferable::canExtractComponentDescriptor(_rFlavors,eType == E_FORM) ? DND_ACTION_COPY : DND_ACTION_NONE;
2482 				if ( nAction != DND_ACTION_NONE )
2483 				{
2484 					SvLBoxEntry* pHitEntry = pView->getEntry(_rEvt.maPosPixel);
2485 					::rtl::OUString sName;
2486 					if ( pHitEntry )
2487 					{
2488 						sName = pView->getQualifiedName( pHitEntry );
2489 						if ( sName.getLength() )
2490 						{
2491 							Reference< XHierarchicalNameAccess > xContainer(getElements(pView->getElementType()),UNO_QUERY);
2492 							if ( xContainer.is() && xContainer->hasByHierarchicalName(sName) )
2493 							{
2494 								Reference< XHierarchicalNameAccess > xHitObject(xContainer->getByHierarchicalName(sName),UNO_QUERY);
2495 								if ( xHitObject.is() )
2496 									nAction = nActionAskedFor & DND_ACTION_COPYMOVE;
2497 							}
2498 							else
2499 								nAction = DND_ACTION_NONE;
2500 						}
2501 					}
2502 					/*else
2503 						nAction = nActionAskedFor & DND_ACTION_COPYMOVE;
2504                     */
2505 				}
2506 				return nAction;
2507 			}
2508 		}
2509 	}
2510 
2511 	return DND_ACTION_NONE;
2512 }
2513 // -----------------------------------------------------------------------------
2514 sal_Int8 OApplicationController::executeDrop( const ExecuteDropEvent& _rEvt )
2515 {
2516 	OApplicationView* pView = getContainer();
2517 	if ( !pView || pView->getElementType() == E_NONE )
2518 	{
2519 		DBG_ERROR("OApplicationController::executeDrop: what the hell did queryDrop do?");
2520 			// queryDrop shoud not have allowed us to reach this situation ....
2521 		return DND_ACTION_NONE;
2522 	}
2523 
2524 	// a TransferableDataHelper for accessing the dropped data
2525 	TransferableDataHelper aDroppedData(_rEvt.maDropEvent.Transferable);
2526 
2527 
2528 	// reset the data of the previous async drop (if any)
2529 	if ( m_nAsyncDrop )
2530 		Application::RemoveUserEvent(m_nAsyncDrop);
2531 
2532 
2533 	m_nAsyncDrop = 0;
2534 	m_aAsyncDrop.aDroppedData.clear();
2535 	m_aAsyncDrop.nType			= pView->getElementType();
2536 	m_aAsyncDrop.nAction		= _rEvt.mnAction;
2537 	m_aAsyncDrop.bError			= sal_False;
2538 	m_aAsyncDrop.bHtml			= sal_False;
2539 	m_aAsyncDrop.aUrl			= ::rtl::OUString();
2540 
2541 
2542 	// loop through the available formats and see what we can do ...
2543 	// first we have to check if it is our own format, if not we have to copy the stream :-(
2544 	if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(aDroppedData.GetDataFlavorExVector()) )
2545 	{
2546 		m_aAsyncDrop.aDroppedData	= ODataAccessObjectTransferable::extractObjectDescriptor(aDroppedData);
2547 
2548 		// asyncron because we some dialogs and we aren't allowed to show them while in D&D
2549 		m_nAsyncDrop = Application::PostUserEvent(LINK(this, OApplicationController, OnAsyncDrop));
2550 		return DND_ACTION_COPY;
2551 	}
2552 	else if ( OComponentTransferable::canExtractComponentDescriptor(aDroppedData.GetDataFlavorExVector(),m_aAsyncDrop.nType == E_FORM) )
2553 	{
2554 		m_aAsyncDrop.aDroppedData = OComponentTransferable::extractComponentDescriptor(aDroppedData);
2555 		SvLBoxEntry* pHitEntry = pView->getEntry(_rEvt.maPosPixel);
2556 		if ( pHitEntry )
2557 			m_aAsyncDrop.aUrl = pView->getQualifiedName( pHitEntry );
2558 
2559 		sal_Int8 nAction = _rEvt.mnAction;
2560 		Reference<XContent> xContent;
2561 		m_aAsyncDrop.aDroppedData[daComponent] >>= xContent;
2562 		if ( xContent.is() )
2563 		{
2564 			::rtl::OUString sName = xContent->getIdentifier()->getContentIdentifier();
2565 			sal_Int32 nIndex = 0;
2566 			sName = sName.copy(sName.getToken(0,'/',nIndex).getLength() + 1);
2567 			if ( m_aAsyncDrop.aUrl.Len() >= sName.getLength() && 0 == sName.compareTo(m_aAsyncDrop.aUrl,sName.getLength()) )
2568 			{
2569 				m_aAsyncDrop.aDroppedData.clear();
2570 				return DND_ACTION_NONE;
2571 			}
2572 
2573 			// check if move is allowed, if another object with the same name exists only copy is allowed
2574 			Reference< XHierarchicalNameAccess > xContainer(getElements(m_aAsyncDrop.nType),UNO_QUERY);
2575 			Reference<XNameAccess> xNameAccess(xContainer,UNO_QUERY);
2576 
2577 			if ( m_aAsyncDrop.aUrl.Len() && xContainer.is() && xContainer->hasByHierarchicalName(m_aAsyncDrop.aUrl) )
2578 				xNameAccess.set(xContainer->getByHierarchicalName(m_aAsyncDrop.aUrl),UNO_QUERY);
2579 
2580 			if ( xNameAccess.is() )
2581 			{
2582 				Reference<XPropertySet> xProp(xContent,UNO_QUERY);
2583 				if ( xProp.is() )
2584 				{
2585 					xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
2586 					if ( xNameAccess.is() && xNameAccess->hasByName(sName) )
2587 						nAction &= ~DND_ACTION_MOVE;
2588 				}
2589 				else
2590 					nAction &= ~DND_ACTION_MOVE;
2591 			}
2592 		}
2593 		if ( nAction != DND_ACTION_NONE )
2594 		{
2595 			m_aAsyncDrop.nAction = nAction;
2596 			// asyncron because we some dialogs and we aren't allowed to show them while in D&D
2597 			m_nAsyncDrop = Application::PostUserEvent(LINK(this, OApplicationController, OnAsyncDrop));
2598 		}
2599 		else
2600 			m_aAsyncDrop.aDroppedData.clear();
2601 		return nAction;
2602 	}
2603 	else
2604 	{
2605         SharedConnection xConnection( ensureConnection() );
2606         if ( xConnection.is() && m_aTableCopyHelper.copyTagTable( aDroppedData, m_aAsyncDrop, xConnection ) )
2607         {
2608 			// asyncron because we some dialogs and we aren't allowed to show them while in D&D
2609 			m_nAsyncDrop = Application::PostUserEvent(LINK(this, OApplicationController, OnAsyncDrop));
2610 			return DND_ACTION_COPY;
2611 		}
2612 	}
2613 
2614 	return DND_ACTION_NONE;
2615 }
2616 // -----------------------------------------------------------------------------
2617 Reference< XModel >  SAL_CALL OApplicationController::getModel(void) throw( RuntimeException )
2618 {
2619 	return m_xModel;
2620 }
2621 
2622 // -----------------------------------------------------------------------------
2623 void OApplicationController::onAttachedFrame()
2624 {
2625     sal_Int32 nConnectedControllers( 0 );
2626     try
2627     {
2628         Reference< XModel2 > xModel( m_xModel, UNO_QUERY_THROW );
2629         Reference< XEnumeration > xEnumControllers( xModel->getControllers(), UNO_SET_THROW );
2630         while ( xEnumControllers->hasMoreElements() )
2631         {
2632             Reference< XController > xController( xEnumControllers->nextElement(), UNO_QUERY_THROW );
2633             ++nConnectedControllers;
2634         }
2635     }
2636     catch( const Exception& )
2637     {
2638     	DBG_UNHANDLED_EXCEPTION();
2639     }
2640 
2641     if ( nConnectedControllers > 1 )
2642     {   // we are not the first connected controller, there were already others
2643         return;
2644     }
2645 
2646     m_aControllerConnectedEvent.Call();
2647 }
2648 
2649 // -----------------------------------------------------------------------------
2650 IMPL_LINK( OApplicationController, OnFirstControllerConnected, void*, /**/ )
2651 {
2652 	::osl::MutexGuard aGuard( getMutex() );
2653 
2654     if ( !m_xModel.is() )
2655     {
2656         OSL_ENSURE( false, "OApplicationController::OnFirstControllerConnected: too late!" );
2657     }
2658 
2659     // if we have forms or reports which contain macros/scripts, then show a warning
2660     // which suggests the user to migrate them to the database document
2661     Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
2662     if ( xDocumentScripts.is() )
2663     {
2664         // no need to show this warning, obviously the document supports embedding scripts
2665         // into itself, so there are no "old-style" forms/reports which have macros/scripts
2666         // themselves
2667         return 0L;
2668     }
2669 
2670     try
2671     {
2672         // If the migration just happened, but was not successful, the document is reloaded.
2673         // In this case, we should not show the warning, again.
2674         ::comphelper::NamedValueCollection aModelArgs( m_xModel->getArgs() );
2675         if ( aModelArgs.getOrDefault( "SuppressMigrationWarning", sal_False ) )
2676             return 0L;
2677 
2678         // also, if the document is read-only, then no migration is possible, and the
2679         // respective menu entry is hidden. So, don't show the warning in this case, too.
2680         if ( Reference< XStorable >( m_xModel, UNO_QUERY_THROW )->isReadonly() )
2681             return 0L;
2682 
2683         SQLWarning aWarning;
2684         aWarning.Message = String( ModuleRes( STR_SUB_DOCS_WITH_SCRIPTS ) );
2685         SQLException aDetail;
2686         aDetail.Message = String( ModuleRes( STR_SUB_DOCS_WITH_SCRIPTS_DETAIL ) );
2687         aWarning.NextException <<= aDetail;
2688 
2689         ::comphelper::ComponentContext aContext( getORB() );
2690         Sequence< Any > aArgs(1);
2691         aArgs[0] <<= NamedValue( PROPERTY_SQLEXCEPTION, makeAny( aWarning ) );
2692         Reference< XExecutableDialog > xDialog(
2693             aContext.createComponentWithArguments( "com.sun.star.sdb.ErrorMessageDialog", aArgs ),
2694             UNO_QUERY_THROW );
2695         xDialog->execute();
2696     }
2697     catch( const Exception& )
2698     {
2699     	DBG_UNHANDLED_EXCEPTION();
2700     }
2701 
2702     return 1L;
2703 }
2704 
2705 // -----------------------------------------------------------------------------
2706 void SAL_CALL OApplicationController::attachFrame( const Reference< XFrame > & i_rxFrame ) throw( RuntimeException )
2707 {
2708     OApplicationController_CBASE::attachFrame( i_rxFrame );
2709     if ( getFrame().is() )
2710         onAttachedFrame();
2711 }
2712 
2713 // -----------------------------------------------------------------------------
2714 sal_Bool SAL_CALL OApplicationController::attachModel(const Reference< XModel > & _rxModel) throw( RuntimeException )
2715 {
2716 	::osl::MutexGuard aGuard( getMutex() );
2717     const Reference< XOfficeDatabaseDocument > xOfficeDoc( _rxModel, UNO_QUERY );
2718     const Reference< XModifiable > xDocModify( _rxModel, UNO_QUERY );
2719     if ( ( !xOfficeDoc.is() || !xDocModify.is() ) && _rxModel.is() )
2720     {
2721         DBG_ERROR( "OApplicationController::attachModel: invalid model!" );
2722         return sal_False;
2723     }
2724 
2725     if ( m_xModel.is() && ( m_xModel != _rxModel ) && ( _rxModel.is() ) )
2726     {
2727         OSL_ENSURE( false, "OApplicationController::attachModel: missing implementation: setting a new model while we have another one!" );
2728         // we'd need to completely update our view here, close sub components, and the like
2729         return sal_False;
2730     }
2731 
2732     const ::rtl::OUString aPropertyNames[] =
2733     {
2734         PROPERTY_URL, PROPERTY_USER
2735     };
2736 
2737     // disconnect from old model
2738     try
2739     {
2740         if ( m_xDataSource.is() )
2741         {
2742             for ( size_t i=0; i < sizeof( aPropertyNames ) / sizeof( aPropertyNames[0] ); ++i )
2743             {
2744                 m_xDataSource->removePropertyChangeListener( aPropertyNames[i], this );
2745             }
2746         }
2747 
2748 		Reference< XModifyBroadcaster >  xBroadcaster( m_xModel, UNO_QUERY );
2749         if ( xBroadcaster.is() )
2750 		    xBroadcaster->removeModifyListener( this );
2751     }
2752     catch( const Exception& )
2753     {
2754     	DBG_UNHANDLED_EXCEPTION();
2755     }
2756 
2757     m_xModel = _rxModel;
2758     m_xDocumentModify = xDocModify;
2759     m_xDataSource.set( xOfficeDoc.is() ? xOfficeDoc->getDataSource() : Reference< XDataSource >(), UNO_QUERY );
2760 
2761     // connect to new model
2762     try
2763     {
2764         if ( m_xDataSource.is() )
2765         {
2766             for ( size_t i=0; i < sizeof( aPropertyNames ) / sizeof( aPropertyNames[0] ); ++i )
2767             {
2768                 m_xDataSource->addPropertyChangeListener( aPropertyNames[i], this );
2769             }
2770         }
2771 
2772 		Reference< XModifyBroadcaster >  xBroadcaster( m_xModel, UNO_QUERY_THROW );
2773 		xBroadcaster->addModifyListener( this );
2774 
2775     }
2776     catch( const Exception& )
2777     {
2778     	DBG_UNHANDLED_EXCEPTION();
2779     }
2780 
2781     // initial preview mode
2782 	if ( m_xDataSource.is() )
2783 	{
2784 		try
2785 		{
2786 			// to get the 'modified' for the data source
2787             ::comphelper::NamedValueCollection aLayoutInfo( m_xDataSource->getPropertyValue( PROPERTY_LAYOUTINFORMATION ) );
2788             if ( aLayoutInfo.has( (rtl::OUString)INFO_PREVIEW ) )
2789             {
2790                 const sal_Int32 nPreviewMode( aLayoutInfo.getOrDefault( (rtl::OUString)INFO_PREVIEW, (sal_Int32)0 ) );
2791 				m_ePreviewMode = static_cast< PreviewMode >( nPreviewMode );
2792                 if ( getView() )
2793                     getContainer()->switchPreview( m_ePreviewMode );
2794 			}
2795 		}
2796 		catch( const Exception& )
2797 		{
2798             DBG_UNHANDLED_EXCEPTION();
2799 		}
2800 	}
2801 
2802 	return sal_True;
2803 }
2804 // -----------------------------------------------------------------------------
2805 void OApplicationController::containerFound( const Reference< XContainer >& _xContainer)
2806 {
2807 	try
2808 	{
2809 		if ( _xContainer.is() )
2810 		{
2811 			m_aCurrentContainers.push_back(_xContainer);
2812 			_xContainer->addContainerListener(this);
2813 		}
2814 	}
2815 	catch(const Exception&)
2816 	{
2817 		DBG_UNHANDLED_EXCEPTION();
2818 	}
2819 }
2820 // -----------------------------------------------------------------------------
2821 ::rtl::OUString OApplicationController::getCurrentlySelectedName(sal_Int32& _rnCommandType) const
2822 {
2823     _rnCommandType = ( (getContainer()->getElementType() == E_QUERY)
2824 								? CommandType::QUERY : ( (getContainer()->getElementType() == E_TABLE) ? CommandType::TABLE : -1 ));
2825 
2826 
2827 	::rtl::OUString sName;
2828 	if ( _rnCommandType != -1 )
2829 	{
2830 		try
2831 		{
2832 			sName = getContainer()->getQualifiedName( NULL );
2833             OSL_ENSURE( sName.getLength(), "OApplicationController::getCurrentlySelectedName: no name given!" );
2834 		}
2835 		catch( const Exception& )
2836 		{
2837             DBG_UNHANDLED_EXCEPTION();
2838 		}
2839 	}
2840     return sName;
2841 }
2842 
2843 // -----------------------------------------------------------------------------
2844 void SAL_CALL OApplicationController::addSelectionChangeListener( const Reference< view::XSelectionChangeListener >& _Listener ) throw (RuntimeException)
2845 {
2846     m_pSelectionNotifier->addListener( _Listener );
2847 }
2848 
2849 // -----------------------------------------------------------------------------
2850 void SAL_CALL OApplicationController::removeSelectionChangeListener( const Reference< view::XSelectionChangeListener >& _Listener ) throw (RuntimeException)
2851 {
2852     m_pSelectionNotifier->removeListener( _Listener );
2853 }
2854 
2855 // -----------------------------------------------------------------------------
2856 ::sal_Bool SAL_CALL OApplicationController::select( const Any& _aSelection ) throw (IllegalArgumentException, RuntimeException)
2857 {
2858     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2859 	::osl::MutexGuard aGuard( getMutex() );
2860     Sequence< ::rtl::OUString> aSelection;
2861     if ( !_aSelection.hasValue() || !getView() )
2862     {
2863         getContainer()->selectElements(aSelection);
2864         return sal_True;
2865     }
2866 
2867     // --------------------------------------------------------------
2868     // BEGIN compatibility
2869     Sequence< NamedValue > aCurrentSelection;
2870     if ( (_aSelection >>= aCurrentSelection) && aCurrentSelection.getLength() )
2871     {
2872         ElementType eType = E_NONE;
2873         const NamedValue* pIter = aCurrentSelection.getConstArray();
2874         const NamedValue* pEnd	= pIter + aCurrentSelection.getLength();
2875         for(;pIter != pEnd;++pIter)
2876         {
2877             if ( pIter->Name.equalsAscii("Type") )
2878             {
2879                 sal_Int32 nType = 0;
2880                 pIter->Value >>= nType;
2881                 if ( nType < DatabaseObject::TABLE || nType > DatabaseObject::REPORT )
2882                     throw IllegalArgumentException();
2883                 eType = static_cast< ElementType >( nType );
2884             }
2885             else if ( pIter->Name.equalsAscii("Selection") )
2886                 pIter->Value >>= aSelection;
2887         }
2888 
2889         m_aSelectContainerEvent.CancelCall();   // just in case the async select request was running
2890         getContainer()->selectContainer(eType);
2891         getContainer()->selectElements(aSelection);
2892         return sal_True;
2893     }
2894     // END compatibility
2895     // --------------------------------------------------------------
2896 
2897     Sequence< NamedDatabaseObject > aSelectedObjects;
2898     if ( !( _aSelection >>= aSelectedObjects ) )
2899     {
2900         aSelectedObjects.realloc( 1 );
2901         if ( !( _aSelection >>= aSelectedObjects[0] ) )
2902             throw IllegalArgumentException();
2903     }
2904 
2905     SelectionByElementType aSelectedElements;
2906     ElementType eSelectedCategory = E_NONE;
2907     for (   const NamedDatabaseObject* pObject = aSelectedObjects.getConstArray();
2908             pObject != aSelectedObjects.getConstArray() + aSelectedObjects.getLength();
2909             ++pObject
2910         )
2911     {
2912         switch ( pObject->Type )
2913         {
2914             case DatabaseObject::TABLE:
2915             case DatabaseObjectContainer::SCHEMA:
2916             case DatabaseObjectContainer::CATALOG:
2917                 aSelectedElements[ E_TABLE ].push_back( pObject->Name );
2918                 break;
2919             case DatabaseObject::QUERY:
2920                 aSelectedElements[ E_QUERY ].push_back( pObject->Name );
2921                 break;
2922             case DatabaseObject::FORM:
2923             case DatabaseObjectContainer::FORMS_FOLDER:
2924                 aSelectedElements[ E_FORM ].push_back( pObject->Name );
2925                 break;
2926             case DatabaseObject::REPORT:
2927             case DatabaseObjectContainer::REPORTS_FOLDER:
2928                 aSelectedElements[ E_REPORT ].push_back( pObject->Name );
2929                 break;
2930             case DatabaseObjectContainer::TABLES:
2931             case DatabaseObjectContainer::QUERIES:
2932             case DatabaseObjectContainer::FORMS:
2933             case DatabaseObjectContainer::REPORTS:
2934                 if ( eSelectedCategory != E_NONE )
2935                     throw IllegalArgumentException(
2936                         String(ModuleRes(RID_STR_NO_DIFF_CAT)),
2937                         *this, sal_Int16( pObject - aSelectedObjects.getConstArray() ) );
2938                 eSelectedCategory =
2939                         ( pObject->Type == DatabaseObjectContainer::TABLES )  ? E_TABLE
2940                     :   ( pObject->Type == DatabaseObjectContainer::QUERIES ) ? E_QUERY
2941                     :   ( pObject->Type == DatabaseObjectContainer::FORMS )   ? E_FORM
2942                     :   ( pObject->Type == DatabaseObjectContainer::REPORTS ) ? E_REPORT
2943                     :   E_NONE;
2944                 break;
2945 
2946             default:
2947             case DatabaseObjectContainer::DATA_SOURCE:
2948             {
2949                 ::rtl::OUString sMessage = String(ModuleRes( RID_STR_UNSUPPORTED_OBJECT_TYPE ));
2950                 ::comphelper::string::searchAndReplaceAsciiI( sMessage, "$type$", ::rtl::OUString::valueOf(sal_Int32( pObject->Type )) );
2951                 throw IllegalArgumentException(sMessage, *this, sal_Int16( pObject - aSelectedObjects.getConstArray() ));
2952             }
2953         }
2954     }
2955 
2956     for (   SelectionByElementType::const_iterator sel = aSelectedElements.begin();
2957             sel != aSelectedElements.end();
2958             ++sel
2959         )
2960     {
2961         if ( sel->first == m_eCurrentType )
2962         {
2963             Sequence< ::rtl::OUString > aSelected( sel->second.size() );
2964             ::std::copy( sel->second.begin(), sel->second.end(), aSelected.getArray() );
2965             getContainer()->selectElements( aSelected );
2966         }
2967         else
2968         {
2969             m_aPendingSelection[ sel->first ] = sel->second;
2970         }
2971     }
2972 
2973     m_aSelectContainerEvent.CancelCall();   // just in case the async select request was running
2974     getContainer()->selectContainer( eSelectedCategory );
2975 
2976     return sal_True;
2977 }
2978 // -----------------------------------------------------------------------------
2979 Any SAL_CALL OApplicationController::getSelection(  ) throw (RuntimeException)
2980 {
2981     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2982     ::osl::MutexGuard aGuard( getMutex() );
2983 
2984     Sequence< NamedDatabaseObject > aCurrentSelection;
2985     const ElementType eType( getContainer()->getElementType() );
2986     if ( eType != E_NONE )
2987     {
2988         getContainer()->describeCurrentSelectionForType( eType, aCurrentSelection );
2989         if ( aCurrentSelection.getLength() == 0 )
2990         {   // if no objects are selected, add an entry to the sequence which describes the overall category
2991             // which is selected currently
2992             aCurrentSelection.realloc(1);
2993             aCurrentSelection[0].Name = getDatabaseName();
2994             switch ( eType )
2995             {
2996             case E_TABLE:   aCurrentSelection[0].Type = DatabaseObjectContainer::TABLES;   break;
2997             case E_QUERY:   aCurrentSelection[0].Type = DatabaseObjectContainer::QUERIES;  break;
2998             case E_FORM:    aCurrentSelection[0].Type = DatabaseObjectContainer::FORMS;    break;
2999             case E_REPORT:  aCurrentSelection[0].Type = DatabaseObjectContainer::REPORTS;  break;
3000             default:
3001                 OSL_ENSURE( false, "OApplicationController::getSelection: unexpected current element type!" );
3002                 break;
3003             }
3004         }
3005     }
3006     return makeAny( aCurrentSelection );
3007 }
3008 // -----------------------------------------------------------------------------
3009 void OApplicationController::impl_migrateScripts_nothrow()
3010 {
3011     try
3012     {
3013         ::rtl::OUString sDialogService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.application.MacroMigrationWizard" ) );
3014         ::comphelper::ComponentContext aContext( getORB() );
3015         Sequence< Any > aDialogArgs(1);
3016         aDialogArgs[0] <<= Reference< XOfficeDatabaseDocument >( m_xModel, UNO_QUERY_THROW );
3017         Reference< XExecutableDialog > xDialog(
3018             aContext.createComponentWithArguments( sDialogService, aDialogArgs ),
3019             UNO_QUERY );
3020 
3021         if ( !xDialog.is() )
3022         {
3023             ShowServiceNotAvailableError( getView(), sDialogService, true );
3024             return;
3025         }
3026 
3027         xDialog->execute();
3028     }
3029     catch( const Exception& )
3030     {
3031     	DBG_UNHANDLED_EXCEPTION();
3032     }
3033 }
3034 
3035 //........................................................................
3036 }	// namespace dbaui
3037 //........................................................................
3038 
3039