Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "AppController.hxx"
22 : #include "AppDetailView.hxx"
23 : #include "AppView.hxx"
24 : #include "dbaccess_slotid.hrc"
25 : #include "dbu_app.hrc"
26 : #include "dbustrings.hrc"
27 : #include "defaultobjectnamecheck.hxx"
28 : #include "dlgsave.hxx"
29 : #include "UITools.hxx"
30 : #include "subcomponentmanager.hxx"
31 :
32 : #include <com/sun/star/container/XChild.hpp>
33 : #include <com/sun/star/container/XContainer.hpp>
34 : #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
35 : #include <com/sun/star/container/XNameAccess.hpp>
36 : #include <com/sun/star/container/XNameContainer.hpp>
37 : #include <com/sun/star/lang/XEventListener.hpp>
38 : #include <com/sun/star/sdb/CommandType.hpp>
39 : #include <com/sun/star/sdb/SQLContext.hpp>
40 : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
41 : #include <com/sun/star/sdbcx/XRename.hpp>
42 : #include <com/sun/star/sdb/ErrorCondition.hpp>
43 : #include <com/sun/star/sdb/application/DatabaseObject.hpp>
44 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
45 : #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
46 : #include <com/sun/star/ucb/Command.hpp>
47 : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
48 : #include <com/sun/star/ucb/XCommandProcessor.hpp>
49 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
50 : #include <com/sun/star/uno/XNamingService.hpp>
51 : #include <com/sun/star/util/XCloseable.hpp>
52 : #include <com/sun/star/util/XRefreshable.hpp>
53 :
54 : #include <cppuhelper/exc_hlp.hxx>
55 : #include <comphelper/processfactory.hxx>
56 : #include <connectivity/dbexception.hxx>
57 : #include <connectivity/dbtools.hxx>
58 : #include <connectivity/sqlerror.hxx>
59 : #include <sfx2/mailmodelapi.hxx>
60 : #include <svx/dbaexchange.hxx>
61 : #include <toolkit/unohlp.hxx>
62 : #include <tools/diagnose_ex.h>
63 : #include <osl/diagnose.h>
64 : #include <unotools/bootstrap.hxx>
65 : #include <vcl/mnemonic.hxx>
66 : #include <vcl/svapp.hxx>
67 : #include <vcl/waitobj.hxx>
68 : #include <osl/mutex.hxx>
69 :
70 : //........................................................................
71 : namespace dbaui
72 : {
73 : using namespace ::dbtools;
74 : using namespace ::connectivity;
75 : using namespace ::svx;
76 : using namespace ::com::sun::star;
77 : using namespace ::com::sun::star::uno;
78 : using namespace ::com::sun::star::awt;
79 : using namespace ::com::sun::star::util;
80 : using namespace ::com::sun::star::frame;
81 : using namespace ::com::sun::star::lang;
82 : using namespace ::com::sun::star::ui::dialogs;
83 : using namespace ::com::sun::star::sdb;
84 : using namespace ::com::sun::star::sdbc;
85 : using namespace ::com::sun::star::sdbcx;
86 : using namespace ::com::sun::star::beans;
87 : using namespace ::com::sun::star::container;
88 : using namespace ::com::sun::star::ucb;
89 :
90 : /** === begin UNO using === **/
91 : using ::com::sun::star::util::XCloseable;
92 : using ::com::sun::star::ui::XContextMenuInterceptor;
93 : /** === end UNO using === **/
94 :
95 : namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
96 : namespace ErrorCondition = ::com::sun::star::sdb::ErrorCondition;
97 :
98 : //........................................................................
99 : // -----------------------------------------------------------------------------
100 :
101 : class CloseChecker : public ::cppu::WeakImplHelper1< com::sun::star::lang::XEventListener >
102 : {
103 : bool m_bClosed;
104 :
105 : public:
106 : CloseChecker()
107 : :m_bClosed( false )
108 : {
109 : }
110 :
111 0 : virtual ~CloseChecker()
112 0 : {
113 0 : }
114 :
115 : bool isClosed()
116 : {
117 : return true;
118 : }
119 :
120 : // interface XEventListener
121 0 : virtual void SAL_CALL disposing( const EventObject& /*Source*/ ) throw( RuntimeException )
122 : {
123 0 : m_bClosed = true;
124 0 : }
125 :
126 : };
127 : // -----------------------------------------------------------------------------
128 0 : void OApplicationController::convertToView(const ::rtl::OUString& _sName)
129 : {
130 : try
131 : {
132 0 : SharedConnection xConnection( getConnection() );
133 0 : Reference< XQueriesSupplier > xSup( xConnection, UNO_QUERY_THROW );
134 0 : Reference< XNameAccess > xQueries( xSup->getQueries(), UNO_QUERY_THROW );
135 0 : Reference< XPropertySet > xSourceObject( xQueries->getByName( _sName ), UNO_QUERY_THROW );
136 :
137 0 : Reference< XTablesSupplier > xTablesSup( xConnection, UNO_QUERY_THROW );
138 0 : Reference< XNameAccess > xTables( xTablesSup->getTables(), UNO_QUERY_THROW );
139 :
140 0 : Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
141 :
142 0 : String aName = String(ModuleRes(STR_TBL_TITLE));
143 0 : aName = aName.GetToken(0,' ');
144 0 : String aDefaultName = ::dbaui::createDefaultName(xMeta,xTables,aName);
145 :
146 0 : DynamicTableOrQueryNameCheck aNameChecker( xConnection, CommandType::TABLE );
147 0 : OSaveAsDlg aDlg( getView(), CommandType::TABLE, comphelper::getComponentContext(getORB()), xConnection, aDefaultName, aNameChecker );
148 0 : if ( aDlg.Execute() == RET_OK )
149 : {
150 0 : ::rtl::OUString sName = aDlg.getName();
151 0 : ::rtl::OUString sCatalog = aDlg.getCatalog();
152 0 : ::rtl::OUString sSchema = aDlg.getSchema();
153 : ::rtl::OUString sNewName(
154 0 : ::dbtools::composeTableName( xMeta, sCatalog, sSchema, sName, sal_False, ::dbtools::eInTableDefinitions ) );
155 0 : Reference<XPropertySet> xView = ::dbaui::createView(sNewName,xConnection,xSourceObject);
156 0 : if ( !xView.is() )
157 0 : throw SQLException(String(ModuleRes(STR_NO_TABLE_FORMAT_INSIDE)),*this,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")) ,0,Any());
158 0 : getContainer()->elementAdded(E_TABLE,sNewName,makeAny(xView));
159 0 : }
160 : }
161 0 : catch(const SQLException& )
162 : {
163 0 : showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
164 : }
165 0 : catch( const Exception& )
166 : {
167 : DBG_UNHANDLED_EXCEPTION();
168 : }
169 0 : }
170 : // -----------------------------------------------------------------------------
171 0 : void OApplicationController::pasteFormat(sal_uInt32 _nFormatId)
172 : {
173 0 : if ( _nFormatId )
174 : {
175 : try
176 : {
177 0 : const TransferableDataHelper& rClipboard = getViewClipboard();
178 0 : ElementType eType = getContainer()->getElementType();
179 0 : if ( eType == E_TABLE )
180 : {
181 0 : m_aTableCopyHelper.pasteTable( _nFormatId, rClipboard, getDatabaseName(), ensureConnection() );
182 : }
183 : else
184 0 : paste( eType, ODataAccessObjectTransferable::extractObjectDescriptor( rClipboard ) );
185 :
186 : }
187 0 : catch( const Exception& )
188 : {
189 : DBG_UNHANDLED_EXCEPTION();
190 : }
191 : }
192 0 : }
193 : // -----------------------------------------------------------------------------
194 0 : void OApplicationController::openDataSourceAdminDialog()
195 : {
196 0 : openDialog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DatasourceAdministrationDialog" ) ) );
197 0 : }
198 :
199 : // -----------------------------------------------------------------------------
200 0 : void OApplicationController::openDialog( const ::rtl::OUString& _sServiceName )
201 : {
202 : try
203 : {
204 0 : SolarMutexGuard aSolarGuard;
205 0 : ::osl::MutexGuard aGuard( getMutex() );
206 0 : WaitObject aWO(getView());
207 :
208 0 : Sequence< Any > aArgs(3);
209 0 : sal_Int32 nArgPos = 0;
210 :
211 0 : Reference< ::com::sun::star::awt::XWindow> xWindow = getTopMostContainerWindow();
212 0 : if ( !xWindow.is() )
213 : {
214 : OSL_ENSURE( getContainer(), "OApplicationController::Construct: have no view!" );
215 0 : if ( getContainer() )
216 0 : xWindow = VCLUnoHelper::GetInterface(getView()->Window::GetParent());
217 : }
218 : // the parent window
219 0 : aArgs[nArgPos++] <<= PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow")),
220 : 0,
221 : makeAny(xWindow),
222 0 : PropertyState_DIRECT_VALUE);
223 :
224 : // the initial selection
225 0 : ::rtl::OUString sInitialSelection;
226 0 : if ( getContainer() )
227 0 : sInitialSelection = getDatabaseName();
228 0 : if ( !sInitialSelection.isEmpty() )
229 : {
230 0 : aArgs[ nArgPos++ ] <<= PropertyValue(
231 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialSelection" ) ), 0,
232 0 : makeAny( sInitialSelection ), PropertyState_DIRECT_VALUE );
233 : }
234 :
235 0 : SharedConnection xConnection( getConnection() );
236 0 : if ( xConnection.is() )
237 : {
238 0 : aArgs[ nArgPos++ ] <<= PropertyValue(
239 : PROPERTY_ACTIVE_CONNECTION, 0,
240 0 : makeAny( xConnection ), PropertyState_DIRECT_VALUE );
241 : }
242 0 : aArgs.realloc( nArgPos );
243 :
244 : // create the dialog
245 0 : Reference< XExecutableDialog > xAdminDialog;
246 : xAdminDialog = Reference< XExecutableDialog >(
247 0 : getORB()->createInstanceWithArguments(_sServiceName,aArgs), UNO_QUERY);
248 :
249 : // execute it
250 0 : if (xAdminDialog.is())
251 0 : xAdminDialog->execute();
252 : }
253 0 : catch( const Exception& )
254 : {
255 : DBG_UNHANDLED_EXCEPTION();
256 : }
257 0 : }
258 : // -----------------------------------------------------------------------------
259 0 : void OApplicationController::openTableFilterDialog()
260 : {
261 0 : openDialog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TableFilterDialog" ) ) );
262 0 : }
263 :
264 : // -----------------------------------------------------------------------------
265 0 : void OApplicationController::refreshTables()
266 : {
267 0 : if ( getContainer() && getContainer()->getDetailView() )
268 : {
269 0 : WaitObject aWO(getView());
270 : OSL_ENSURE(getContainer()->getElementType() == E_TABLE,"Only allowed when the tables container is selected!");
271 : try
272 : {
273 0 : Reference<XRefreshable> xRefresh(getElements(E_TABLE),UNO_QUERY);
274 0 : if ( xRefresh.is() )
275 0 : xRefresh->refresh();
276 : }
277 0 : catch(const Exception&)
278 : {
279 : OSL_FAIL("Could not refresh tables!");
280 : }
281 :
282 0 : getContainer()->getDetailView()->clearPages(sal_False);
283 0 : getContainer()->getDetailView()->createTablesPage( ensureConnection() );
284 : }
285 0 : }
286 : // -----------------------------------------------------------------------------
287 0 : void OApplicationController::openDirectSQLDialog()
288 : {
289 0 : openDialog( SERVICE_SDB_DIRECTSQLDIALOG );
290 0 : }
291 : // -----------------------------------------------------------------------------
292 0 : void SAL_CALL OApplicationController::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException)
293 : {
294 0 : SolarMutexGuard aSolarGuard;
295 0 : ::osl::MutexGuard aGuard( getMutex() );
296 0 : if ( evt.PropertyName == PROPERTY_USER )
297 : {
298 0 : m_bNeedToReconnect = sal_True;
299 0 : InvalidateFeature(SID_DB_APP_STATUS_USERNAME);
300 : }
301 0 : else if ( evt.PropertyName == PROPERTY_URL )
302 : {
303 0 : m_bNeedToReconnect = sal_True;
304 0 : InvalidateFeature(SID_DB_APP_STATUS_DBNAME);
305 0 : InvalidateFeature(SID_DB_APP_STATUS_TYPE);
306 0 : InvalidateFeature(SID_DB_APP_STATUS_HOSTNAME);
307 : }
308 0 : else if ( PROPERTY_NAME == evt.PropertyName )
309 : {
310 0 : const ElementType eType = getContainer()->getElementType();
311 0 : if ( eType == E_FORM || eType == E_REPORT )
312 : {
313 0 : ::rtl::OUString sOldName,sNewName;
314 0 : evt.OldValue >>= sOldName;
315 0 : evt.NewValue >>= sNewName;
316 :
317 : // if the old name is empty, then this is a newly inserted content. We're notified of it via the
318 : // elementInserted method, so there's no need to handle it here.
319 :
320 0 : if ( !sOldName.isEmpty() )
321 : {
322 0 : Reference<XChild> xChild(evt.Source,UNO_QUERY);
323 0 : if ( xChild.is() )
324 : {
325 0 : Reference<XContent> xContent(xChild->getParent(),UNO_QUERY);
326 0 : if ( xContent.is() )
327 0 : sOldName = xContent->getIdentifier()->getContentIdentifier() + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) + sOldName;
328 : }
329 :
330 0 : getContainer()->elementReplaced( eType , sOldName, sNewName );
331 0 : }
332 : }
333 : }
334 :
335 0 : EventObject aEvt;
336 0 : aEvt.Source = m_xModel;
337 0 : modified(aEvt);
338 0 : }
339 :
340 : // -----------------------------------------------------------------------------
341 0 : Reference< XDataSource > SAL_CALL OApplicationController::getDataSource() throw (RuntimeException)
342 : {
343 0 : ::osl::MutexGuard aGuard( getMutex() );
344 0 : Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
345 0 : return xDataSource;
346 : }
347 :
348 : // -----------------------------------------------------------------------------
349 0 : Reference< XWindow > SAL_CALL OApplicationController::getApplicationMainWindow() throw (RuntimeException)
350 : {
351 0 : ::osl::MutexGuard aGuard( getMutex() );
352 0 : Reference< XFrame > xFrame( getFrame(), UNO_QUERY_THROW );
353 0 : Reference< XWindow > xWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW );
354 0 : return xWindow;
355 : }
356 :
357 : // -----------------------------------------------------------------------------
358 0 : Sequence< Reference< XComponent > > SAL_CALL OApplicationController::getSubComponents() throw (RuntimeException)
359 : {
360 0 : ::osl::MutexGuard aGuard( getMutex() );
361 0 : return m_pSubComponentManager->getSubComponents();
362 : }
363 :
364 : // -----------------------------------------------------------------------------
365 0 : Reference< XConnection > SAL_CALL OApplicationController::getActiveConnection() throw (RuntimeException)
366 : {
367 0 : ::osl::MutexGuard aGuard( getMutex() );
368 0 : return m_xDataSourceConnection.getTyped();
369 : }
370 :
371 : // -----------------------------------------------------------------------------
372 0 : ::sal_Bool SAL_CALL OApplicationController::isConnected( ) throw (RuntimeException)
373 : {
374 0 : ::osl::MutexGuard aGuard( getMutex() );
375 0 : return m_xDataSourceConnection.is();
376 : }
377 :
378 : // -----------------------------------------------------------------------------
379 0 : void SAL_CALL OApplicationController::connect( ) throw (SQLException, RuntimeException)
380 : {
381 0 : SolarMutexGuard aSolarGuard;
382 0 : ::osl::MutexGuard aGuard( getMutex() );
383 :
384 0 : SQLExceptionInfo aError;
385 0 : SharedConnection xConnection = ensureConnection( &aError );
386 0 : if ( !xConnection.is() )
387 : {
388 0 : if ( aError.isValid() )
389 0 : aError.doThrow();
390 :
391 : // no particular error, but nonetheless could not connect -> throw a generic exception
392 0 : String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) );
393 0 : sConnectingContext.SearchAndReplaceAscii( "$name$", getStrippedDatabaseName() );
394 0 : ::dbtools::throwGenericSQLException( sConnectingContext, *this );
395 0 : }
396 0 : }
397 :
398 : // -----------------------------------------------------------------------------
399 0 : beans::Pair< ::sal_Int32, ::rtl::OUString > SAL_CALL OApplicationController::identifySubComponent( const Reference< XComponent >& i_rSubComponent ) throw (IllegalArgumentException, RuntimeException)
400 : {
401 0 : ::osl::MutexGuard aGuard( getMutex() );
402 :
403 0 : sal_Int32 nType = -1;
404 0 : ::rtl::OUString sName;
405 :
406 0 : if ( !m_pSubComponentManager->lookupSubComponent( i_rSubComponent, sName, nType ) )
407 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
408 :
409 0 : if ( nType == SID_DB_APP_DSRELDESIGN )
410 : // this is somewhat hacky ... we're expected to return a DatabaseObject value. However, there is no such
411 : // value for the relation design. /me thinks we should change the API definition here ...
412 0 : nType = -1;
413 :
414 0 : return beans::Pair< ::sal_Int32, ::rtl::OUString >( nType, sName );
415 : }
416 :
417 : // -----------------------------------------------------------------------------
418 0 : ::sal_Bool SAL_CALL OApplicationController::closeSubComponents( ) throw (RuntimeException)
419 : {
420 0 : SolarMutexGuard aSolarGuard;
421 0 : ::osl::MutexGuard aGuard( getMutex() );
422 0 : return m_pSubComponentManager->closeSubComponents();
423 : }
424 :
425 :
426 : // -----------------------------------------------------------------------------
427 : namespace
428 : {
429 0 : ElementType lcl_objectType2ElementType( const sal_Int32 _nObjectType )
430 : {
431 0 : ElementType eType( E_NONE );
432 0 : switch ( _nObjectType )
433 : {
434 0 : case DatabaseObject::TABLE: eType = E_TABLE; break;
435 0 : case DatabaseObject::QUERY: eType = E_QUERY; break;
436 0 : case DatabaseObject::FORM: eType = E_FORM; break;
437 0 : case DatabaseObject::REPORT: eType = E_REPORT; break;
438 : default:
439 : OSL_FAIL( "lcl_objectType2ElementType: unsupported object type!" );
440 : // this should have been caught earlier
441 : }
442 0 : return eType;
443 : }
444 : }
445 :
446 : // -----------------------------------------------------------------------------
447 0 : void OApplicationController::impl_validateObjectTypeAndName_throw( const sal_Int32 _nObjectType, const ::boost::optional< ::rtl::OUString >& i_rObjectName )
448 : {
449 : // ensure we're connected
450 0 : if ( !isConnected() )
451 : {
452 0 : SQLError aError( comphelper::getComponentContext(getORB()) );
453 0 : aError.raiseException( ErrorCondition::DB_NOT_CONNECTED, *this );
454 : }
455 :
456 : // ensure a proper object type
457 0 : if ( ( _nObjectType != DatabaseObject::TABLE )
458 : && ( _nObjectType != DatabaseObject::QUERY )
459 : && ( _nObjectType != DatabaseObject::FORM )
460 : && ( _nObjectType != DatabaseObject::REPORT )
461 : )
462 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
463 :
464 0 : if ( !i_rObjectName )
465 0 : return;
466 :
467 : // ensure an existing object
468 0 : Reference< XNameAccess > xContainer( getElements( lcl_objectType2ElementType( _nObjectType ) ) );
469 0 : if ( !xContainer.is() )
470 : // all possible reasons for this (e.g. not being connected currently) should
471 : // have been handled before
472 0 : throw RuntimeException( ::rtl::OUString(), *this );
473 :
474 0 : bool bExistentObject = false;
475 0 : switch ( _nObjectType )
476 : {
477 : case DatabaseObject::TABLE:
478 : case DatabaseObject::QUERY:
479 0 : bExistentObject = xContainer->hasByName( *i_rObjectName );
480 0 : break;
481 : case DatabaseObject::FORM:
482 : case DatabaseObject::REPORT:
483 : {
484 0 : Reference< XHierarchicalNameAccess > xHierarchy( xContainer, UNO_QUERY_THROW );
485 0 : bExistentObject = xHierarchy->hasByHierarchicalName( *i_rObjectName );
486 : }
487 0 : break;
488 : }
489 :
490 0 : if ( !bExistentObject )
491 0 : throw NoSuchElementException( *i_rObjectName, *this );
492 : }
493 :
494 : // -----------------------------------------------------------------------------
495 0 : Reference< XComponent > SAL_CALL OApplicationController::loadComponent( ::sal_Int32 _ObjectType,
496 : const ::rtl::OUString& _ObjectName, ::sal_Bool _ForEditing ) throw (IllegalArgumentException, NoSuchElementException, SQLException, RuntimeException)
497 : {
498 0 : return loadComponentWithArguments( _ObjectType, _ObjectName, _ForEditing, Sequence< PropertyValue >() );
499 : }
500 :
501 : // -----------------------------------------------------------------------------
502 0 : Reference< XComponent > SAL_CALL OApplicationController::loadComponentWithArguments( ::sal_Int32 _ObjectType,
503 : const ::rtl::OUString& _ObjectName, ::sal_Bool _ForEditing, const Sequence< PropertyValue >& _Arguments ) throw (IllegalArgumentException, NoSuchElementException, SQLException, RuntimeException)
504 : {
505 0 : SolarMutexGuard aSolarGuard;
506 0 : ::osl::MutexGuard aGuard( getMutex() );
507 :
508 0 : impl_validateObjectTypeAndName_throw( _ObjectType, _ObjectName );
509 :
510 : Reference< XComponent > xComponent( openElementWithArguments(
511 : _ObjectName,
512 : lcl_objectType2ElementType( _ObjectType ),
513 : _ForEditing ? E_OPEN_DESIGN : E_OPEN_NORMAL,
514 : _ForEditing ? SID_DB_APP_EDIT : SID_DB_APP_OPEN,
515 : ::comphelper::NamedValueCollection( _Arguments )
516 0 : ) );
517 :
518 0 : return xComponent;
519 : }
520 :
521 : // -----------------------------------------------------------------------------
522 0 : Reference< XComponent > SAL_CALL OApplicationController::createComponent( ::sal_Int32 i_nObjectType, Reference< XComponent >& o_DocumentDefinition ) throw (IllegalArgumentException, SQLException, RuntimeException)
523 : {
524 0 : return createComponentWithArguments( i_nObjectType, Sequence< PropertyValue >(), o_DocumentDefinition );
525 : }
526 :
527 : // -----------------------------------------------------------------------------
528 0 : Reference< XComponent > SAL_CALL OApplicationController::createComponentWithArguments( ::sal_Int32 i_nObjectType, const Sequence< PropertyValue >& i_rArguments, Reference< XComponent >& o_DocumentDefinition ) throw (IllegalArgumentException, SQLException, RuntimeException)
529 : {
530 0 : SolarMutexGuard aSolarGuard;
531 0 : ::osl::MutexGuard aGuard( getMutex() );
532 :
533 0 : impl_validateObjectTypeAndName_throw( i_nObjectType, ::boost::optional< ::rtl::OUString >() );
534 :
535 : Reference< XComponent > xComponent( newElement(
536 : lcl_objectType2ElementType( i_nObjectType ),
537 : ::comphelper::NamedValueCollection( i_rArguments ),
538 : o_DocumentDefinition
539 0 : ) );
540 :
541 0 : return xComponent;
542 : }
543 :
544 : // -----------------------------------------------------------------------------
545 0 : void SAL_CALL OApplicationController::registerContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException)
546 : {
547 0 : if ( _Interceptor.is() )
548 0 : m_aContextMenuInterceptors.addInterface( _Interceptor );
549 0 : }
550 :
551 : // -----------------------------------------------------------------------------
552 0 : void SAL_CALL OApplicationController::releaseContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException)
553 : {
554 0 : m_aContextMenuInterceptors.removeInterface( _Interceptor );
555 0 : }
556 :
557 : // -----------------------------------------------------------------------------
558 0 : void OApplicationController::previewChanged( sal_Int32 _nMode )
559 : {
560 0 : SolarMutexGuard aSolarGuard;
561 0 : ::osl::MutexGuard aGuard( getMutex() );
562 :
563 0 : if ( m_xDataSource.is() && !isDataSourceReadOnly() )
564 : {
565 : try
566 : {
567 0 : ::comphelper::NamedValueCollection aLayoutInfo( m_xDataSource->getPropertyValue( PROPERTY_LAYOUTINFORMATION ) );
568 0 : sal_Int32 nOldMode = aLayoutInfo.getOrDefault( "Preview", _nMode );
569 0 : if ( nOldMode != _nMode )
570 : {
571 0 : aLayoutInfo.put( "Preview", _nMode );
572 0 : m_xDataSource->setPropertyValue( PROPERTY_LAYOUTINFORMATION, makeAny( aLayoutInfo.getPropertyValues() ) );
573 0 : }
574 : }
575 0 : catch ( const Exception& )
576 : {
577 : DBG_UNHANDLED_EXCEPTION();
578 : }
579 : }
580 0 : InvalidateFeature(SID_DB_APP_DISABLE_PREVIEW);
581 0 : InvalidateFeature(SID_DB_APP_VIEW_DOCINFO_PREVIEW);
582 0 : InvalidateFeature(SID_DB_APP_VIEW_DOC_PREVIEW);
583 0 : }
584 : // -----------------------------------------------------------------------------
585 0 : void OApplicationController::askToReconnect()
586 : {
587 0 : if ( m_bNeedToReconnect )
588 : {
589 0 : m_bNeedToReconnect = sal_False;
590 0 : sal_Bool bClear = sal_True;
591 0 : if ( !m_pSubComponentManager->empty() )
592 : {
593 0 : QueryBox aQry(getView(), ModuleRes(APP_CLOSEDOCUMENTS));
594 0 : switch (aQry.Execute())
595 : {
596 : case RET_YES:
597 0 : closeSubComponents();
598 0 : break;
599 : default:
600 0 : bClear = sal_False;
601 0 : break;
602 0 : }
603 : }
604 0 : if ( bClear )
605 : {
606 0 : ElementType eType = getContainer()->getElementType();
607 0 : disconnect();
608 0 : getContainer()->getDetailView()->clearPages(sal_False);
609 0 : getContainer()->selectContainer(E_NONE); // invalidate the old selection
610 0 : m_eCurrentType = E_NONE;
611 0 : getContainer()->selectContainer(eType); // reselect the current one again
612 : }
613 : }
614 0 : }
615 :
616 : // -----------------------------------------------------------------------------
617 0 : ::rtl::OUString OApplicationController::getDatabaseName() const
618 : {
619 0 : ::rtl::OUString sDatabaseName;
620 : try
621 : {
622 0 : if ( m_xDataSource.is() )
623 : {
624 0 : OSL_VERIFY( m_xDataSource->getPropertyValue( PROPERTY_NAME ) >>= sDatabaseName );
625 : }
626 : }
627 0 : catch ( const Exception& )
628 : {
629 : DBG_UNHANDLED_EXCEPTION();
630 : }
631 0 : return sDatabaseName;
632 : }
633 :
634 : // -----------------------------------------------------------------------------
635 0 : ::rtl::OUString OApplicationController::getStrippedDatabaseName() const
636 : {
637 0 : ::rtl::OUString sDatabaseName;
638 0 : return ::dbaui::getStrippedDatabaseName( m_xDataSource, sDatabaseName );
639 : }
640 :
641 : // -----------------------------------------------------------------------------
642 0 : void OApplicationController::onDocumentOpened( const ::rtl::OUString& _rName, const sal_Int32 _nType,
643 : const ElementOpenMode _eMode, const Reference< XComponent >& _xDocument, const Reference< XComponent >& _rxDefinition )
644 : {
645 0 : if ( !_xDocument.is() )
646 0 : return;
647 :
648 : try
649 : {
650 : OSL_ENSURE( _xDocument.is(), "OApplicationController::onDocumentOpened: is there any *valid* scenario where this fails?" );
651 0 : m_pSubComponentManager->onSubComponentOpened( _rName, _nType, _eMode, _xDocument.is() ? _xDocument : _rxDefinition );
652 :
653 0 : if ( _rxDefinition.is() )
654 : {
655 0 : Reference< XPropertySet > xProp( _rxDefinition, UNO_QUERY_THROW );
656 0 : Reference< XPropertySetInfo > xPSI( xProp->getPropertySetInfo(), UNO_SET_THROW );
657 0 : xProp->addPropertyChangeListener( PROPERTY_NAME, static_cast< XPropertyChangeListener* >( this ) );
658 : }
659 : }
660 0 : catch( const Exception& )
661 : {
662 : DBG_UNHANDLED_EXCEPTION();
663 : }
664 : }
665 : // -----------------------------------------------------------------------------
666 0 : sal_Bool OApplicationController::insertHierachyElement(ElementType _eType,const String& _sParentFolder,sal_Bool _bCollection,const Reference<XContent>& _xContent,sal_Bool _bMove)
667 : {
668 0 : Reference<XHierarchicalNameContainer> xNames(getElements(_eType), UNO_QUERY);
669 0 : return dbaui::insertHierachyElement(getView()
670 : ,comphelper::getComponentContext(getORB())
671 : ,xNames
672 : ,_sParentFolder
673 : ,_eType == E_FORM
674 : ,_bCollection
675 : ,_xContent
676 0 : ,_bMove);
677 : }
678 : // -----------------------------------------------------------------------------
679 0 : sal_Bool OApplicationController::isRenameDeleteAllowed(ElementType _eType,sal_Bool _bDelete) const
680 : {
681 0 : ElementType eType = getContainer()->getElementType();
682 0 : sal_Bool bEnabled = !isDataSourceReadOnly() && eType == _eType;
683 0 : if ( bEnabled )
684 : {
685 :
686 0 : if ( E_TABLE == eType )
687 0 : bEnabled = !isConnectionReadOnly() && getContainer()->isALeafSelected();
688 :
689 0 : sal_Bool bCompareRes = sal_False;
690 0 : if ( _bDelete )
691 0 : bCompareRes = getContainer()->getSelectionCount() > 0;
692 : else
693 : {
694 0 : bCompareRes = getContainer()->getSelectionCount() == 1;
695 0 : if ( bEnabled && bCompareRes && E_TABLE == eType )
696 : {
697 0 : ::std::vector< ::rtl::OUString> aList;
698 0 : getSelectionElementNames(aList);
699 :
700 : try
701 : {
702 0 : Reference< XNameAccess > xContainer = const_cast<OApplicationController*>(this)->getElements(eType);
703 0 : bEnabled = (xContainer.is() && xContainer->hasByName(*aList.begin()));
704 0 : if ( bEnabled )
705 0 : bEnabled = Reference<XRename>(xContainer->getByName(*aList.begin()),UNO_QUERY).is();
706 : }
707 0 : catch(Exception&)
708 : {
709 0 : bEnabled = sal_False;
710 0 : }
711 : }
712 : }
713 :
714 0 : bEnabled = bEnabled && bCompareRes;
715 : }
716 0 : return bEnabled;
717 : }
718 : // -----------------------------------------------------------------------------
719 0 : void OApplicationController::onLoadedMenu(const Reference< ::com::sun::star::frame::XLayoutManager >& _xLayoutManager)
720 : {
721 :
722 0 : if ( _xLayoutManager.is() )
723 : {
724 0 : static ::rtl::OUString s_sStatusbar(RTL_CONSTASCII_USTRINGPARAM("private:resource/statusbar/statusbar"));
725 0 : _xLayoutManager->createElement( s_sStatusbar );
726 0 : _xLayoutManager->requestElement( s_sStatusbar );
727 :
728 0 : if ( getContainer() )
729 : {
730 : // we need to share the "mnemonic space":
731 0 : MnemonicGenerator aMnemonicGenerator;
732 : // - the menu already has mnemonics
733 0 : SystemWindow* pSystemWindow = getContainer()->GetSystemWindow();
734 0 : MenuBar* pMenu = pSystemWindow ? pSystemWindow->GetMenuBar() : NULL;
735 0 : if ( pMenu )
736 : {
737 0 : sal_uInt16 nMenuItems = pMenu->GetItemCount();
738 0 : for ( sal_uInt16 i = 0; i < nMenuItems; ++i )
739 0 : aMnemonicGenerator.RegisterMnemonic( pMenu->GetItemText( pMenu->GetItemId( i ) ) );
740 : }
741 : // - the icons should use automatic ones
742 0 : getContainer()->createIconAutoMnemonics( aMnemonicGenerator );
743 : // - as well as the entries in the task pane
744 0 : getContainer()->setTaskExternalMnemonics( aMnemonicGenerator );
745 : }
746 :
747 0 : Execute( SID_DB_APP_VIEW_FORMS, Sequence< PropertyValue >() );
748 0 : InvalidateAll();
749 : }
750 0 : }
751 : // -----------------------------------------------------------------------------
752 0 : void OApplicationController::doAction(sal_uInt16 _nId ,ElementOpenMode _eOpenMode)
753 : {
754 0 : ::std::vector< ::rtl::OUString> aList;
755 0 : getSelectionElementNames(aList);
756 0 : ElementType eType = getContainer()->getElementType();
757 0 : ::comphelper::NamedValueCollection aArguments;
758 0 : ElementOpenMode eOpenMode = _eOpenMode;
759 0 : if ( eType == E_REPORT && E_OPEN_FOR_MAIL == _eOpenMode )
760 : {
761 0 : aArguments.put("Hidden",true);
762 0 : eOpenMode = E_OPEN_NORMAL;
763 : }
764 :
765 0 : ::std::vector< ::std::pair< ::rtl::OUString ,Reference< XModel > > > aCompoments;
766 0 : ::std::vector< ::rtl::OUString>::iterator aEnd = aList.end();
767 0 : for (::std::vector< ::rtl::OUString>::iterator aIter = aList.begin(); aIter != aEnd; ++aIter)
768 : {
769 0 : if ( SID_DB_APP_CONVERTTOVIEW == _nId )
770 0 : convertToView(*aIter);
771 : else
772 : {
773 0 : Reference< XModel > xModel( openElementWithArguments( *aIter, eType, eOpenMode, _nId,aArguments ), UNO_QUERY );
774 0 : aCompoments.push_back( ::std::pair< ::rtl::OUString, Reference< XModel > >( *aIter, xModel ) );
775 : }
776 : }
777 :
778 : // special handling for mail, if more than one document is selected attach them all
779 0 : if ( _eOpenMode == E_OPEN_FOR_MAIL )
780 : {
781 :
782 0 : ::std::vector< ::std::pair< ::rtl::OUString ,Reference< XModel > > >::iterator componentIter = aCompoments.begin();
783 0 : ::std::vector< ::std::pair< ::rtl::OUString ,Reference< XModel > > >::iterator componentEnd = aCompoments.end();
784 0 : ::rtl::OUString aDocTypeString;
785 0 : SfxMailModel aSendMail;
786 0 : SfxMailModel::SendMailResult eResult = SfxMailModel::SEND_MAIL_OK;
787 0 : for (; componentIter != componentEnd && SfxMailModel::SEND_MAIL_OK == eResult; ++componentIter)
788 : {
789 : try
790 : {
791 0 : Reference< XModel > xModel(componentIter->second,UNO_QUERY);
792 :
793 : // Send document as e-Mail using stored/default type
794 0 : eResult = aSendMail.AttachDocument(aDocTypeString,xModel,componentIter->first);
795 0 : ::comphelper::disposeComponent(xModel);
796 : }
797 0 : catch(const Exception&)
798 : {
799 : DBG_UNHANDLED_EXCEPTION();
800 : }
801 : }
802 0 : if ( !aSendMail.IsEmpty() )
803 0 : aSendMail.Send( getFrame() );
804 0 : }
805 0 : }
806 : // -----------------------------------------------------------------------------
807 0 : ElementType OApplicationController::getElementType(const Reference< XContainer >& _xContainer) const
808 : {
809 0 : ElementType eRet = E_NONE;
810 0 : Reference<XServiceInfo> xServiceInfo(_xContainer,UNO_QUERY);
811 0 : if ( xServiceInfo.is() )
812 : {
813 0 : if ( xServiceInfo->supportsService(SERVICE_SDBCX_TABLES) )
814 0 : eRet = E_TABLE;
815 0 : else if ( xServiceInfo->supportsService(SERVICE_NAME_FORM_COLLECTION) )
816 0 : eRet = E_FORM;
817 0 : else if ( xServiceInfo->supportsService(SERVICE_NAME_REPORT_COLLECTION) )
818 0 : eRet = E_REPORT;
819 : else
820 0 : eRet = E_QUERY;
821 : }
822 0 : return eRet;
823 : }
824 :
825 : //........................................................................
826 : } // namespace dbaui
827 : //........................................................................
828 :
829 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|