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