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