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