xref: /AOO41X/main/dbaccess/source/ui/app/AppController.cxx (revision 96de54900b79e13b861fbc62cbf36018b54e21b7)
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_dbaccess.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