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_svx.hxx" 30 31 #include "fmprop.hrc" 32 #include "fmservs.hxx" 33 #include "svx/fmtools.hxx" 34 #include "svx/dbtoolsclient.hxx" 35 #include "svx/fmglob.hxx" 36 37 /** === begin UNO includes === **/ 38 #include <com/sun/star/awt/LineEndFormat.hpp> 39 #include <com/sun/star/beans/PropertyAttribute.hpp> 40 #include <com/sun/star/beans/XIntrospection.hpp> 41 #include <com/sun/star/container/XChild.hpp> 42 #include <com/sun/star/form/XForm.hpp> 43 #include <com/sun/star/form/XFormComponent.hpp> 44 #include <com/sun/star/form/XGridColumnFactory.hpp> 45 #include <com/sun/star/io/XActiveDataSink.hpp> 46 #include <com/sun/star/io/XActiveDataSource.hpp> 47 #include <com/sun/star/io/XObjectInputStream.hpp> 48 #include <com/sun/star/io/XObjectOutputStream.hpp> 49 #include <com/sun/star/io/XPersistObject.hpp> 50 #include <com/sun/star/lang/Locale.hpp> 51 #include <com/sun/star/lang/XServiceInfo.hpp> 52 #include <com/sun/star/sdb/CommandType.hpp> 53 #include <com/sun/star/sdb/ErrorCondition.hpp> 54 #include <com/sun/star/sdb/SQLContext.hpp> 55 #include <com/sun/star/sdb/XCompletedConnection.hpp> 56 #include <com/sun/star/sdb/XQueriesSupplier.hpp> 57 #include <com/sun/star/sdb/XResultSetAccess.hpp> 58 #include <com/sun/star/sdbc/DataType.hpp> 59 #include <com/sun/star/sdbc/XDataSource.hpp> 60 #include <com/sun/star/sdbcx/Privilege.hpp> 61 #include <com/sun/star/sdbcx/XTablesSupplier.hpp> 62 #include <com/sun/star/task/XInteractionHandler.hpp> 63 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> 64 #include <com/sun/star/uno/XNamingService.hpp> 65 #include <com/sun/star/util/Language.hpp> 66 #include <com/sun/star/util/NumberFormat.hpp> 67 #include <com/sun/star/util/XCloneable.hpp> 68 #include <com/sun/star/util/XNumberFormatTypes.hpp> 69 #include <com/sun/star/util/XNumberFormats.hpp> 70 #include <com/sun/star/util/XNumberFormatsSupplier.hpp> 71 #include <com/sun/star/util/XNumberFormatter.hpp> 72 /** === end UNO includes === **/ 73 74 #include <basic/sbxvar.hxx> 75 #include <svl/eitem.hxx> 76 #include <svl/stritem.hxx> 77 #include <comphelper/container.hxx> 78 #include <comphelper/extract.hxx> 79 #include <comphelper/processfactory.hxx> 80 #include <comphelper/property.hxx> 81 #include <comphelper/sequence.hxx> 82 #include <comphelper/types.hxx> 83 #include <comphelper/uno3.hxx> 84 #include <connectivity/dbexception.hxx> 85 #include <connectivity/dbtools.hxx> 86 #include <cppuhelper/servicefactory.hxx> 87 #include <cppuhelper/typeprovider.hxx> 88 #include <rtl/logfile.hxx> 89 #include <rtl/math.hxx> 90 #include <sfx2/bindings.hxx> 91 #include <svl/eitem.hxx> 92 #include <svl/stritem.hxx> 93 #include <toolkit/unohlp.hxx> 94 #include <tools/debug.hxx> 95 #include <tools/string.hxx> 96 #include <vcl/stdtext.hxx> 97 #include <vcl/svapp.hxx> 98 99 #include <algorithm> 100 101 using namespace ::com::sun::star::uno; 102 using namespace ::com::sun::star::util; 103 using namespace ::com::sun::star::lang; 104 using namespace ::com::sun::star::frame; 105 using namespace ::com::sun::star::awt; 106 using namespace ::com::sun::star::beans; 107 using namespace ::com::sun::star::container; 108 using namespace ::com::sun::star::ui::dialogs; 109 using namespace ::com::sun::star::sdbc; 110 using namespace ::com::sun::star::sdbcx; 111 using namespace ::com::sun::star::sdb; 112 using namespace ::com::sun::star::task; 113 using namespace ::com::sun::star::form; 114 using namespace ::svxform; 115 using namespace ::connectivity::simple; 116 117 // ------------------------------------------------------------------------------ 118 namespace 119 { 120 static bool lcl_shouldDisplayError( const Any& _rError ) 121 { 122 SQLException aError; 123 if ( !( _rError >>= aError ) ) 124 return true; 125 126 if ( aError.Message.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "[OOoBase]" ) ) != 0 ) 127 // it is an exception *not* thrown by an OOo Base core component 128 return true; 129 130 // the only exception we do not display ATM is a RowSetVetoException, which 131 // has been raised because an XRowSetApprovalListener vetoed a change 132 if ( aError.ErrorCode + ErrorCondition::ROW_SET_OPERATION_VETOED == 0 ) 133 return false; 134 135 // everything else is to be displayed 136 return true; 137 } 138 } 139 140 // ------------------------------------------------------------------------------ 141 void displayException(const Any& _rExcept, Window* _pParent) 142 { 143 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "fmtools::displayException" ); 144 // check whether we need to display it 145 if ( !lcl_shouldDisplayError( _rExcept ) ) 146 return; 147 148 try 149 { 150 // the parent window 151 Window* pParentWindow = _pParent ? _pParent : GetpApp()->GetDefDialogParent(); 152 Reference< XWindow > xParentWindow = VCLUnoHelper::GetInterface(pParentWindow); 153 154 Sequence< Any > aArgs(2); 155 aArgs[0] <<= PropertyValue(::rtl::OUString::createFromAscii("SQLException"), 0, _rExcept, PropertyState_DIRECT_VALUE); 156 aArgs[1] <<= PropertyValue(::rtl::OUString::createFromAscii("ParentWindow"), 0, makeAny(xParentWindow), PropertyState_DIRECT_VALUE); 157 158 static ::rtl::OUString s_sDialogServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sdb.ErrorMessageDialog"); 159 Reference< XExecutableDialog > xErrorDialog( 160 ::comphelper::getProcessServiceFactory()->createInstanceWithArguments(s_sDialogServiceName, aArgs), UNO_QUERY); 161 if (xErrorDialog.is()) 162 xErrorDialog->execute(); 163 else 164 ShowServiceNotAvailableError(pParentWindow, s_sDialogServiceName, sal_True); 165 } 166 catch(Exception&) 167 { 168 OSL_ENSURE(sal_False, "displayException: could not display the error message!"); 169 } 170 } 171 172 // ------------------------------------------------------------------------------ 173 void displayException(const ::com::sun::star::sdbc::SQLException& _rExcept, Window* _pParent) 174 { 175 displayException(makeAny(_rExcept), _pParent); 176 } 177 178 // ------------------------------------------------------------------------------ 179 void displayException(const ::com::sun::star::sdbc::SQLWarning& _rExcept, Window* _pParent) 180 { 181 displayException(makeAny(_rExcept), _pParent); 182 } 183 184 // ------------------------------------------------------------------------------ 185 void displayException(const ::com::sun::star::sdb::SQLContext& _rExcept, Window* _pParent) 186 { 187 displayException(makeAny(_rExcept), _pParent); 188 } 189 190 // ------------------------------------------------------------------------------ 191 void displayException(const ::com::sun::star::sdb::SQLErrorEvent& _rEvent, Window* _pParent) 192 { 193 displayException(_rEvent.Reason, _pParent); 194 } 195 196 //------------------------------------------------------------------------------ 197 sal_Int32 getElementPos(const Reference< ::com::sun::star::container::XIndexAccess>& xCont, const Reference< XInterface >& xElement) 198 { 199 sal_Int32 nIndex = -1; 200 if (!xCont.is()) 201 return nIndex; 202 203 204 Reference< XInterface > xNormalized( xElement, UNO_QUERY ); 205 DBG_ASSERT( xNormalized.is(), "getElementPos: invalid element!" ); 206 if ( xNormalized.is() ) 207 { 208 // Feststellen an welcher Position sich das Kind befindet 209 nIndex = xCont->getCount(); 210 while (nIndex--) 211 { 212 try 213 { 214 Reference< XInterface > xCurrent(xCont->getByIndex( nIndex ),UNO_QUERY); 215 DBG_ASSERT( xCurrent.get() == Reference< XInterface >( xCurrent, UNO_QUERY ).get(), 216 "getElementPos: container element not normalized!" ); 217 if ( xNormalized.get() == xCurrent.get() ) 218 break; 219 } 220 catch(Exception&) 221 { 222 DBG_ERROR( "getElementPos: caught an exception!" ); 223 } 224 225 } 226 } 227 return nIndex; 228 } 229 230 //------------------------------------------------------------------ 231 ::rtl::OUString getLabelName(const Reference< ::com::sun::star::beans::XPropertySet>& xControlModel) 232 { 233 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "fmtools::getLabelName" ); 234 if (!xControlModel.is()) 235 return ::rtl::OUString(); 236 237 if (::comphelper::hasProperty(FM_PROP_CONTROLLABEL, xControlModel)) 238 { 239 Reference< ::com::sun::star::beans::XPropertySet> xLabelSet; 240 xControlModel->getPropertyValue(FM_PROP_CONTROLLABEL) >>= xLabelSet; 241 if (xLabelSet.is() && ::comphelper::hasProperty(FM_PROP_LABEL, xLabelSet)) 242 { 243 Any aLabel( xLabelSet->getPropertyValue(FM_PROP_LABEL) ); 244 if ((aLabel.getValueTypeClass() == TypeClass_STRING) && ::comphelper::getString(aLabel).getLength()) 245 return ::comphelper::getString(aLabel); 246 } 247 } 248 249 return ::comphelper::getString(xControlModel->getPropertyValue(FM_PROP_CONTROLSOURCE)); 250 } 251 252 //======================================================================== 253 // = CursorWrapper 254 //------------------------------------------------------------------------ 255 CursorWrapper::CursorWrapper(const Reference< ::com::sun::star::sdbc::XRowSet>& _rxCursor, sal_Bool bUseCloned) 256 { 257 ImplConstruct(Reference< ::com::sun::star::sdbc::XResultSet>(_rxCursor, UNO_QUERY), bUseCloned); 258 } 259 260 //------------------------------------------------------------------------ 261 CursorWrapper::CursorWrapper(const Reference< ::com::sun::star::sdbc::XResultSet>& _rxCursor, sal_Bool bUseCloned) 262 { 263 ImplConstruct(_rxCursor, bUseCloned); 264 } 265 266 //------------------------------------------------------------------------ 267 void CursorWrapper::ImplConstruct(const Reference< ::com::sun::star::sdbc::XResultSet>& _rxCursor, sal_Bool bUseCloned) 268 { 269 if (bUseCloned) 270 { 271 Reference< ::com::sun::star::sdb::XResultSetAccess> xAccess(_rxCursor, UNO_QUERY); 272 try 273 { 274 m_xMoveOperations = xAccess.is() ? xAccess->createResultSet() : Reference< ::com::sun::star::sdbc::XResultSet>(); 275 } 276 catch(Exception&) 277 { 278 } 279 } 280 else 281 m_xMoveOperations = _rxCursor; 282 283 m_xBookmarkOperations = m_xBookmarkOperations.query( m_xMoveOperations ); 284 m_xColumnsSupplier = m_xColumnsSupplier.query( m_xMoveOperations ); 285 m_xPropertyAccess = m_xPropertyAccess.query( m_xMoveOperations ); 286 287 if ( !m_xMoveOperations.is() || !m_xBookmarkOperations.is() || !m_xColumnsSupplier.is() || !m_xPropertyAccess.is() ) 288 { // all or nothing !! 289 m_xMoveOperations = NULL; 290 m_xBookmarkOperations = NULL; 291 m_xColumnsSupplier = NULL; 292 } 293 else 294 m_xGeneric = m_xMoveOperations.get(); 295 } 296 297 //------------------------------------------------------------------------ 298 const CursorWrapper& CursorWrapper::operator=(const Reference< ::com::sun::star::sdbc::XRowSet>& _rxCursor) 299 { 300 m_xMoveOperations = Reference< ::com::sun::star::sdbc::XResultSet>(_rxCursor, UNO_QUERY); 301 m_xBookmarkOperations = Reference< ::com::sun::star::sdbcx::XRowLocate>(_rxCursor, UNO_QUERY); 302 m_xColumnsSupplier = Reference< ::com::sun::star::sdbcx::XColumnsSupplier>(_rxCursor, UNO_QUERY); 303 if (!m_xMoveOperations.is() || !m_xBookmarkOperations.is() || !m_xColumnsSupplier.is()) 304 { // all or nothing !! 305 m_xMoveOperations = NULL; 306 m_xBookmarkOperations = NULL; 307 m_xColumnsSupplier = NULL; 308 } 309 return *this; 310 } 311 312 //------------------------------------------------------------------------------ 313 FmXDisposeListener::~FmXDisposeListener() 314 { 315 setAdapter(NULL); 316 } 317 318 //------------------------------------------------------------------------------ 319 void FmXDisposeListener::setAdapter(FmXDisposeMultiplexer* pAdapter) 320 { 321 if (m_pAdapter) 322 { 323 ::osl::MutexGuard aGuard(m_rMutex); 324 m_pAdapter->release(); 325 m_pAdapter = NULL; 326 } 327 328 if (pAdapter) 329 { 330 ::osl::MutexGuard aGuard(m_rMutex); 331 m_pAdapter = pAdapter; 332 m_pAdapter->acquire(); 333 } 334 } 335 336 //============================================================================== 337 DBG_NAME(FmXDisposeMultiplexer); 338 //------------------------------------------------------------------------------ 339 FmXDisposeMultiplexer::FmXDisposeMultiplexer(FmXDisposeListener* _pListener, const Reference< ::com::sun::star::lang::XComponent>& _rxObject, sal_Int16 _nId) 340 :m_xObject(_rxObject) 341 ,m_pListener(_pListener) 342 ,m_nId(_nId) 343 { 344 DBG_CTOR(FmXDisposeMultiplexer, NULL); 345 m_pListener->setAdapter(this); 346 347 if (m_xObject.is()) 348 m_xObject->addEventListener(this); 349 } 350 351 //------------------------------------------------------------------------------ 352 FmXDisposeMultiplexer::~FmXDisposeMultiplexer() 353 { 354 DBG_DTOR(FmXDisposeMultiplexer, NULL); 355 } 356 357 // ::com::sun::star::lang::XEventListener 358 //------------------------------------------------------------------ 359 void FmXDisposeMultiplexer::disposing(const ::com::sun::star::lang::EventObject& _Source) throw( RuntimeException ) 360 { 361 Reference< ::com::sun::star::lang::XEventListener> xPreventDelete(this); 362 363 if (m_pListener) 364 { 365 m_pListener->disposing(_Source, m_nId); 366 m_pListener->setAdapter(NULL); 367 m_pListener = NULL; 368 } 369 m_xObject = NULL; 370 } 371 372 //------------------------------------------------------------------ 373 void FmXDisposeMultiplexer::dispose() 374 { 375 if (m_xObject.is()) 376 { 377 Reference< ::com::sun::star::lang::XEventListener> xPreventDelete(this); 378 379 m_xObject->removeEventListener(this); 380 m_xObject = NULL; 381 382 m_pListener->setAdapter(NULL); 383 m_pListener = NULL; 384 } 385 } 386 387 //============================================================================== 388 //------------------------------------------------------------------------------ 389 sal_Int16 getControlTypeByObject(const Reference< ::com::sun::star::lang::XServiceInfo>& _rxObject) 390 { 391 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "fmtools::getControlTypeByObject" ); 392 // ask for the persistent service name 393 Reference< ::com::sun::star::io::XPersistObject> xPersistence(_rxObject, UNO_QUERY); 394 DBG_ASSERT(xPersistence.is(), "::getControlTypeByObject : argument shold be an ::com::sun::star::io::XPersistObject !"); 395 if (!xPersistence.is()) 396 return OBJ_FM_CONTROL; 397 398 ::rtl::OUString sPersistentServiceName = xPersistence->getServiceName(); 399 if (sPersistentServiceName.equals(FM_COMPONENT_EDIT)) // 5.0-Name 400 { 401 // may be a simple edit field or a formatted field, dependent of the supported services 402 if (_rxObject->supportsService(FM_SUN_COMPONENT_FORMATTEDFIELD)) 403 return OBJ_FM_FORMATTEDFIELD; 404 return OBJ_FM_EDIT; 405 } 406 if (sPersistentServiceName.equals(FM_COMPONENT_TEXTFIELD)) 407 return OBJ_FM_EDIT; 408 if (sPersistentServiceName.equals(FM_COMPONENT_COMMANDBUTTON)) 409 return OBJ_FM_BUTTON; 410 if (sPersistentServiceName.equals(FM_COMPONENT_FIXEDTEXT)) 411 return OBJ_FM_FIXEDTEXT; 412 if (sPersistentServiceName.equals(FM_COMPONENT_LISTBOX)) 413 return OBJ_FM_LISTBOX; 414 if (sPersistentServiceName.equals(FM_COMPONENT_CHECKBOX)) 415 return OBJ_FM_CHECKBOX; 416 if (sPersistentServiceName.equals(FM_COMPONENT_RADIOBUTTON)) 417 return OBJ_FM_RADIOBUTTON; 418 if (sPersistentServiceName.equals(FM_COMPONENT_GROUPBOX)) 419 return OBJ_FM_GROUPBOX; 420 if (sPersistentServiceName.equals(FM_COMPONENT_COMBOBOX)) 421 return OBJ_FM_COMBOBOX; 422 if (sPersistentServiceName.equals(FM_COMPONENT_GRID)) // 5.0-Name 423 return OBJ_FM_GRID; 424 if (sPersistentServiceName.equals(FM_COMPONENT_GRIDCONTROL)) 425 return OBJ_FM_GRID; 426 if (sPersistentServiceName.equals(FM_COMPONENT_IMAGEBUTTON)) 427 return OBJ_FM_IMAGEBUTTON; 428 if (sPersistentServiceName.equals(FM_COMPONENT_FILECONTROL)) 429 return OBJ_FM_FILECONTROL; 430 if (sPersistentServiceName.equals(FM_COMPONENT_DATEFIELD)) 431 return OBJ_FM_DATEFIELD; 432 if (sPersistentServiceName.equals(FM_COMPONENT_TIMEFIELD)) 433 return OBJ_FM_TIMEFIELD; 434 if (sPersistentServiceName.equals(FM_COMPONENT_NUMERICFIELD)) 435 return OBJ_FM_NUMERICFIELD; 436 if (sPersistentServiceName.equals(FM_COMPONENT_CURRENCYFIELD)) 437 return OBJ_FM_CURRENCYFIELD; 438 if (sPersistentServiceName.equals(FM_COMPONENT_PATTERNFIELD)) 439 return OBJ_FM_PATTERNFIELD; 440 if (sPersistentServiceName.equals(FM_COMPONENT_HIDDEN)) // 5.0-Name 441 return OBJ_FM_HIDDEN; 442 if (sPersistentServiceName.equals(FM_COMPONENT_HIDDENCONTROL)) 443 return OBJ_FM_HIDDEN; 444 if (sPersistentServiceName.equals(FM_COMPONENT_IMAGECONTROL)) 445 return OBJ_FM_IMAGECONTROL; 446 if (sPersistentServiceName.equals(FM_COMPONENT_FORMATTEDFIELD)) 447 { 448 DBG_ERROR("::getControlTypeByObject : suspicious persistent service name (formatted field) !"); 449 // objects with that service name should exist as they aren't compatible with older versions 450 return OBJ_FM_FORMATTEDFIELD; 451 } 452 if ( sPersistentServiceName.equals( FM_SUN_COMPONENT_SCROLLBAR ) ) 453 return OBJ_FM_SCROLLBAR; 454 if ( sPersistentServiceName.equals( FM_SUN_COMPONENT_SPINBUTTON) ) 455 return OBJ_FM_SPINBUTTON; 456 if (sPersistentServiceName.equals(FM_SUN_COMPONENT_NAVIGATIONBAR)) 457 return OBJ_FM_NAVIGATIONBAR; 458 459 DBG_ERROR("::getControlTypeByObject : unknown object type !"); 460 return OBJ_FM_CONTROL; 461 } 462 463 //------------------------------------------------------------------------------ 464 void setConnection(const Reference< ::com::sun::star::sdbc::XRowSet>& _rxRowSet, const Reference< ::com::sun::star::sdbc::XConnection>& _rxConn) 465 { 466 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "fmtools::setConnection" ); 467 Reference< ::com::sun::star::beans::XPropertySet> xRowSetProps(_rxRowSet, UNO_QUERY); 468 if (xRowSetProps.is()) 469 { 470 try 471 { 472 Any aConn(makeAny(_rxConn)); 473 xRowSetProps->setPropertyValue(FM_PROP_ACTIVE_CONNECTION, aConn); 474 } 475 catch(Exception&) 476 { 477 DBG_ERROR("::setConnection : could not set the connection !"); 478 } 479 480 } 481 } 482 //------------------------------------------------------------------------------ 483 sal_Bool isRowSetAlive(const Reference< XInterface >& _rxRowSet) 484 { 485 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "fmtools::isRowSetAlive" ); 486 sal_Bool bIsAlive = sal_False; 487 Reference< ::com::sun::star::sdbcx::XColumnsSupplier> xSupplyCols(_rxRowSet, UNO_QUERY); 488 Reference< ::com::sun::star::container::XIndexAccess> xCols; 489 if (xSupplyCols.is()) 490 xCols = Reference< ::com::sun::star::container::XIndexAccess>(xSupplyCols->getColumns(), UNO_QUERY); 491 if (xCols.is() && (xCols->getCount() > 0)) 492 bIsAlive = sal_True; 493 494 return bIsAlive; 495 } 496 497