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