1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svtools.hxx" 30 31 #include "svtools/genericunodialog.hxx" 32 33 #include <com/sun/star/beans/NamedValue.hpp> 34 #include <com/sun/star/ucb/AlreadyInitializedException.hpp> 35 36 #include <toolkit/awt/vclxwindow.hxx> 37 #include <comphelper/extract.hxx> 38 #include <cppuhelper/typeprovider.hxx> 39 #include <comphelper/property.hxx> 40 #include <osl/diagnose.h> 41 #include <tools/diagnose_ex.h> 42 #include <vcl/msgbox.hxx> 43 #include <vos/mutex.hxx> 44 #include <vcl/svapp.hxx> 45 46 using namespace ::comphelper; 47 using namespace ::com::sun::star::uno; 48 using namespace ::com::sun::star::lang; 49 using namespace ::com::sun::star::beans; 50 using namespace ::com::sun::star::ucb; 51 52 //......................................................................... 53 namespace svt 54 { 55 //......................................................................... 56 57 //========================================================================= 58 //------------------------------------------------------------------------- 59 OGenericUnoDialog::OGenericUnoDialog(const Reference< XMultiServiceFactory >& _rxORB) 60 :OPropertyContainer(GetBroadcastHelper()) 61 ,m_pDialog(NULL) 62 ,m_bExecuting(sal_False) 63 ,m_bCanceled(sal_False) 64 ,m_bTitleAmbiguous(sal_True) 65 ,m_bInitialized( false ) 66 ,m_bNeedInitialization( false ) 67 ,m_aContext( _rxORB ) 68 { 69 registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_TITLE), UNODIALOG_PROPERTY_ID_TITLE, PropertyAttribute::TRANSIENT, 70 &m_sTitle, getCppuType(&m_sTitle)); 71 registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_PARENT), UNODIALOG_PROPERTY_ID_PARENT, PropertyAttribute::TRANSIENT, 72 &m_xParent, getCppuType(&m_xParent)); 73 } 74 75 //------------------------------------------------------------------------- 76 OGenericUnoDialog::OGenericUnoDialog(const Reference< XComponentContext >& _rxContext) 77 :OPropertyContainer(GetBroadcastHelper()) 78 ,m_pDialog(NULL) 79 ,m_bExecuting(sal_False) 80 ,m_bCanceled(sal_False) 81 ,m_bTitleAmbiguous(sal_True) 82 ,m_bInitialized( false ) 83 ,m_bNeedInitialization( false ) 84 ,m_aContext(_rxContext) 85 { 86 registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_TITLE), UNODIALOG_PROPERTY_ID_TITLE, PropertyAttribute::TRANSIENT, 87 &m_sTitle, getCppuType(&m_sTitle)); 88 registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_PARENT), UNODIALOG_PROPERTY_ID_PARENT, PropertyAttribute::TRANSIENT, 89 &m_xParent, getCppuType(&m_xParent)); 90 } 91 92 //------------------------------------------------------------------------- 93 OGenericUnoDialog::~OGenericUnoDialog() 94 { 95 if ( m_pDialog ) 96 { 97 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 98 ::osl::MutexGuard aGuard( m_aMutex ); 99 if ( m_pDialog ) 100 destroyDialog(); 101 } 102 } 103 104 //------------------------------------------------------------------------- 105 Any SAL_CALL OGenericUnoDialog::queryInterface(const Type& _rType) throw (RuntimeException) 106 { 107 Any aReturn = OGenericUnoDialogBase::queryInterface(_rType); 108 109 if (!aReturn.hasValue()) 110 aReturn = ::cppu::queryInterface(_rType 111 ,static_cast<XPropertySet*>(this) 112 ,static_cast<XMultiPropertySet*>(this) 113 ,static_cast<XFastPropertySet*>(this) 114 ); 115 116 return aReturn; 117 } 118 119 //------------------------------------------------------------------------- 120 Sequence<Type> SAL_CALL OGenericUnoDialog::getTypes( ) throw(RuntimeException) 121 { 122 return ::comphelper::concatSequences( 123 OGenericUnoDialogBase::getTypes(), 124 ::comphelper::OPropertyContainer::getTypes() 125 ); 126 } 127 128 //------------------------------------------------------------------------- 129 Sequence<sal_Int8> SAL_CALL OGenericUnoDialog::getImplementationId( ) throw(RuntimeException) 130 { 131 static ::cppu::OImplementationId aId; 132 return aId.getImplementationId(); 133 } 134 135 //------------------------------------------------------------------------- 136 sal_Bool SAL_CALL OGenericUnoDialog::supportsService(const ::rtl::OUString& ServiceName) throw(RuntimeException) 137 { 138 Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames()); 139 const ::rtl::OUString* pArray = aSupported.getConstArray(); 140 for (sal_Int32 i = 0; i < aSupported.getLength(); ++i, ++pArray) 141 if (pArray->equals(ServiceName)) 142 return sal_True; 143 return sal_False; 144 } 145 146 //------------------------------------------------------------------------- 147 void OGenericUnoDialog::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw(Exception) 148 { 149 // TODO : need some handling if we're currently executing ... 150 151 OPropertyContainer::setFastPropertyValue_NoBroadcast(nHandle, rValue); 152 153 if (UNODIALOG_PROPERTY_ID_TITLE == nHandle) 154 { 155 // from now on m_sTitle is valid 156 m_bTitleAmbiguous = sal_False; 157 158 if (m_pDialog) 159 m_pDialog->SetText(String(m_sTitle)); 160 } 161 } 162 163 //------------------------------------------------------------------------- 164 sal_Bool OGenericUnoDialog::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) throw(IllegalArgumentException) 165 { 166 switch (nHandle) 167 { 168 case UNODIALOG_PROPERTY_ID_PARENT: 169 { 170 Reference<starawt::XWindow> xNew; 171 ::cppu::extractInterface(xNew, rValue); 172 if (xNew != m_xParent) 173 { 174 rConvertedValue <<= xNew; 175 rOldValue <<= m_xParent; 176 return sal_True; 177 } 178 return sal_False; 179 } 180 } 181 return OPropertyContainer::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue); 182 } 183 184 //------------------------------------------------------------------------- 185 void SAL_CALL OGenericUnoDialog::setTitle( const ::rtl::OUString& _rTitle ) throw(RuntimeException) 186 { 187 UnoDialogEntryGuard aGuard( *this ); 188 189 try 190 { 191 setPropertyValue(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_TITLE), makeAny(_rTitle)); 192 } 193 catch(RuntimeException&) 194 { 195 // allowed to pass 196 throw; 197 } 198 catch( const Exception& ) 199 { 200 DBG_UNHANDLED_EXCEPTION(); 201 // not allowed to pass 202 } 203 } 204 205 //------------------------------------------------------------------------- 206 bool OGenericUnoDialog::impl_ensureDialog_lck() 207 { 208 if ( m_pDialog ) 209 return true; 210 211 // get the parameters for the dialog from the current settings 212 213 // the parent window 214 Window* pParent = NULL; 215 VCLXWindow* pImplementation = VCLXWindow::GetImplementation(m_xParent); 216 if (pImplementation) 217 pParent = pImplementation->GetWindow(); 218 219 // the title 220 String sTitle = m_sTitle; 221 222 Dialog* pDialog = createDialog( pParent ); 223 OSL_ENSURE( pDialog, "OGenericUnoDialog::impl_ensureDialog_lck: createDialog returned nonsense!" ); 224 if ( !pDialog ) 225 return false; 226 227 // do some initialisations 228 if ( !m_bTitleAmbiguous ) 229 pDialog->SetText( sTitle ); 230 231 // be notified when the dialog is killed by somebody else 232 // #i65958# / 2006-07-07 / frank.schoenheit@sun.com 233 pDialog->AddEventListener( LINK( this, OGenericUnoDialog, OnDialogDying ) ); 234 235 m_pDialog = pDialog; 236 237 return true; 238 } 239 240 //------------------------------------------------------------------------- 241 sal_Int16 SAL_CALL OGenericUnoDialog::execute( ) throw(RuntimeException) 242 { 243 // both creation and execution of the dialog must be guarded with the SolarMutex, so be generous here 244 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 245 246 Dialog* pDialogToExecute = NULL; 247 // create the dialog, if neccessary 248 { 249 UnoDialogEntryGuard aGuard( *this ); 250 251 if (m_bExecuting) 252 throw RuntimeException( 253 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "already executing the dialog (recursive call)" ) ), 254 *this 255 ); 256 257 m_bCanceled = sal_False; 258 m_bExecuting = sal_True; 259 260 if ( !impl_ensureDialog_lck() ) 261 return 0; 262 263 pDialogToExecute = m_pDialog; 264 } 265 266 // start execution 267 sal_Int16 nReturn(0); 268 if ( pDialogToExecute ) 269 nReturn = pDialogToExecute->Execute(); 270 271 { 272 ::osl::MutexGuard aExecutionGuard(m_aExecutionMutex); 273 if (m_bCanceled) 274 nReturn = RET_CANCEL; 275 } 276 277 { 278 ::osl::MutexGuard aGuard(m_aMutex); 279 280 // get the settings of the dialog 281 executedDialog( nReturn ); 282 283 m_bExecuting = sal_False; 284 } 285 286 // outta here 287 return nReturn; 288 } 289 290 #ifdef AWT_DIALOG 291 //------------------------------------------------------------------------- 292 void SAL_CALL OGenericUnoDialog::endExecute( ) throw(RuntimeException) 293 { 294 UnoDialogEntryGuard aGuard( *this ); 295 if (!m_bExecuting) 296 throw RuntimeException(); 297 298 { 299 ::osl::MutexGuard aExecutionGuard(m_aExecutionMutex); 300 OSL_ENSURE(m_pDialog, "OGenericUnoDialog::endExecute : executing which dialog ?"); 301 // m_bExecuting is true but we have no dialog ? 302 if (!m_pDialog) 303 throw RuntimeException(); 304 305 if (!m_pDialog->IsInExecute()) 306 // we tighly missed it ... another thread finished the execution of the dialog, 307 // but did not manage it to reset m_bExecuting, it currently tries to acquire 308 // m_aMutex or m_aExecutionMutex 309 // => nothing to do 310 return; 311 312 m_pDialog->EndDialog(RET_CANCEL); 313 m_bCanceled = sal_True; 314 } 315 } 316 #endif 317 318 //------------------------------------------------------------------------- 319 void OGenericUnoDialog::implInitialize(const Any& _rValue) 320 { 321 try 322 { 323 PropertyValue aProperty; 324 NamedValue aValue; 325 if ( _rValue >>= aProperty ) 326 { 327 setPropertyValue( aProperty.Name, aProperty.Value ); 328 } 329 else if ( _rValue >>= aValue ) 330 { 331 setPropertyValue( aValue.Name, aValue.Value ); 332 } 333 } 334 catch(const Exception&) 335 { 336 DBG_UNHANDLED_EXCEPTION(); 337 } 338 } 339 340 //------------------------------------------------------------------------- 341 void SAL_CALL OGenericUnoDialog::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException) 342 { 343 ::osl::MutexGuard aGuard( m_aMutex ); 344 if ( m_bInitialized ) 345 throw AlreadyInitializedException( ::rtl::OUString(), *this ); 346 347 const Any* pArguments = aArguments.getConstArray(); 348 for (sal_Int32 i=0; i<aArguments.getLength(); ++i, ++pArguments) 349 implInitialize(*pArguments); 350 351 m_bInitialized = true; 352 } 353 354 //------------------------------------------------------------------------- 355 void OGenericUnoDialog::destroyDialog() 356 { 357 delete m_pDialog; 358 m_pDialog = NULL; 359 } 360 361 //------------------------------------------------------------------------- 362 IMPL_LINK( OGenericUnoDialog, OnDialogDying, VclWindowEvent*, _pEvent ) 363 { 364 OSL_ENSURE( _pEvent->GetWindow() == m_pDialog, "OGenericUnoDialog::OnDialogDying: where does this come from?" ); 365 if ( _pEvent->GetId() == VCLEVENT_OBJECT_DYING ) 366 m_pDialog = NULL; 367 return 0L; 368 } 369 370 //......................................................................... 371 } // namespace svt 372 //......................................................................... 373 374