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_forms.hxx" 30 #include "EditBase.hxx" 31 #include "property.hxx" 32 #ifndef _FRM_PROPERTY_HRC_ 33 #include "property.hrc" 34 #endif 35 #include "services.hxx" 36 #include <tools/debug.hxx> 37 #include <comphelper/basicio.hxx> 38 #include <cppuhelper/queryinterface.hxx> 39 #include "frm_resource.hxx" 40 #ifndef _FRM_RESOURCE_HRC_ 41 #include "frm_resource.hrc" 42 #endif 43 44 //......................................................................... 45 namespace frm 46 { 47 using namespace ::com::sun::star::uno; 48 using namespace ::com::sun::star::sdb; 49 using namespace ::com::sun::star::sdbc; 50 using namespace ::com::sun::star::sdbcx; 51 using namespace ::com::sun::star::beans; 52 using namespace ::com::sun::star::container; 53 using namespace ::com::sun::star::form; 54 using namespace ::com::sun::star::awt; 55 using namespace ::com::sun::star::io; 56 using namespace ::com::sun::star::lang; 57 using namespace ::com::sun::star::util; 58 59 const sal_uInt16 DEFAULT_LONG = 0x0001; 60 const sal_uInt16 DEFAULT_DOUBLE = 0x0002; 61 const sal_uInt16 FILTERPROPOSAL = 0x0004; 62 63 DBG_NAME( OEditBaseModel ) 64 //------------------------------------------------------------------ 65 OEditBaseModel::OEditBaseModel( const Reference< XMultiServiceFactory >& _rxFactory, const ::rtl::OUString& rUnoControlModelName, 66 const ::rtl::OUString& rDefault, const sal_Bool _bSupportExternalBinding, const sal_Bool _bSupportsValidation ) 67 :OBoundControlModel( _rxFactory, rUnoControlModelName, rDefault, sal_True, _bSupportExternalBinding, _bSupportsValidation ) 68 ,m_nLastReadVersion(0) 69 ,m_bEmptyIsNull(sal_True) 70 ,m_bFilterProposal(sal_False) 71 { 72 DBG_CTOR( OEditBaseModel, NULL ); 73 } 74 75 //------------------------------------------------------------------ 76 OEditBaseModel::OEditBaseModel( const OEditBaseModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory ) 77 :OBoundControlModel( _pOriginal, _rxFactory ) 78 ,m_nLastReadVersion(0) 79 { 80 DBG_CTOR( OEditBaseModel, NULL ); 81 82 m_bFilterProposal = _pOriginal->m_bFilterProposal; 83 m_bEmptyIsNull = _pOriginal->m_bEmptyIsNull; 84 m_aDefault = _pOriginal->m_aDefault; 85 m_aDefaultText = _pOriginal->m_aDefaultText; 86 } 87 88 //------------------------------------------------------------------ 89 OEditBaseModel::~OEditBaseModel( ) 90 { 91 DBG_DTOR( OEditBaseModel, NULL ); 92 } 93 94 // XPersist 95 //------------------------------------------------------------------------------ 96 void OEditBaseModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 97 { 98 OBoundControlModel::write(_rxOutStream); 99 100 // Version 101 sal_uInt16 nVersionId = 0x0005; 102 DBG_ASSERT((getPersistenceFlags() & ~PF_SPECIAL_FLAGS) == 0, 103 "OEditBaseModel::write : invalid special version flags !"); 104 // please don't use other flags, older versions can't interpret them ! 105 106 nVersionId |= getPersistenceFlags(); 107 _rxOutStream->writeShort(nVersionId); 108 109 // Name 110 _rxOutStream->writeShort(0); // obsolete 111 _rxOutStream << m_aDefaultText; 112 113 // Maskierung fuer any 114 sal_uInt16 nAnyMask = 0; 115 if (m_aDefault.getValueType().getTypeClass() == TypeClass_LONG) 116 nAnyMask |= DEFAULT_LONG; 117 else if (m_aDefault.getValueType().getTypeClass() == TypeClass_DOUBLE) 118 nAnyMask |= DEFAULT_DOUBLE; 119 120 if (m_bFilterProposal) // da boolean, kein Wert speichern 121 nAnyMask |= FILTERPROPOSAL; 122 123 _rxOutStream->writeBoolean(m_bEmptyIsNull); 124 _rxOutStream->writeShort(nAnyMask); 125 126 if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG) 127 _rxOutStream->writeLong(getINT32(m_aDefault)); 128 else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE) 129 _rxOutStream->writeDouble(getDouble(m_aDefault)); 130 131 // since version 5 we write the help text 132 writeHelpTextCompatibly(_rxOutStream); 133 // (that's potentially bad : at the time I added the above line we had two derived classes : OEditModel and 134 // OFormattedModel. The first one does not have an own version handling, so it can't write the help text itself, 135 // the second one does it's own writing (reading) after calling our method, so normally we shouldn't write any 136 // additional members as this is not compatible to older office versions. 137 // We decided to place the writing of the help text here as it seems the less worse alternative. There is no delivered 138 // office version including formatted controls (and thus the OFormattedModel), and the OFormattedModel::read seems 139 // robust against this change (as it will read a wrong and unknown file version and thus set it's members to defaults). 140 141 if ((nVersionId & PF_HANDLE_COMMON_PROPS) != 0) 142 writeCommonEditProperties(_rxOutStream); 143 144 // !!! properties common to all OEditBaseModel derived classes should be written in writeCommonEditProperties !!! 145 } 146 147 //------------------------------------------------------------------------------ 148 sal_uInt16 OEditBaseModel::getPersistenceFlags() const 149 { 150 return PF_HANDLE_COMMON_PROPS; 151 } 152 153 //------------------------------------------------------------------------------ 154 void OEditBaseModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 155 { 156 OBoundControlModel::read(_rxInStream); 157 ::osl::MutexGuard aGuard(m_aMutex); 158 159 // Version eigene Versionsnummer 160 sal_uInt16 nVersion = _rxInStream->readShort(); 161 m_nLastReadVersion = nVersion; 162 163 sal_Bool bHandleCommonProps = (nVersion & PF_HANDLE_COMMON_PROPS) != 0; 164 nVersion = nVersion & ~PF_SPECIAL_FLAGS; 165 166 // obsolete 167 _rxInStream->readShort(); 168 169 _rxInStream >> m_aDefaultText; 170 171 if (nVersion >= 0x0003) 172 { 173 m_bEmptyIsNull = _rxInStream->readBoolean(); 174 175 sal_uInt16 nAnyMask = _rxInStream->readShort(); 176 if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG) 177 { 178 sal_Int32 nValue = _rxInStream->readLong(); 179 m_aDefault <<= (sal_Int32)nValue; 180 } 181 else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE) 182 { 183 double fValue = _rxInStream->readDouble(); 184 m_aDefault <<= (double)fValue; 185 } 186 187 if ((nAnyMask & FILTERPROPOSAL) == FILTERPROPOSAL) 188 m_bFilterProposal = sal_True; 189 } 190 191 if (nVersion > 4) 192 readHelpTextCompatibly(_rxInStream); 193 194 if (bHandleCommonProps) 195 readCommonEditProperties(_rxInStream); 196 197 // Nach dem Lesen die Defaultwerte anzeigen 198 if ( getControlSource().getLength() ) 199 // (not if we don't have a control source - the "State" property acts like it is persistent, then) 200 resetNoBroadcast(); 201 }; 202 203 //------------------------------------------------------------------------------ 204 void OEditBaseModel::defaultCommonEditProperties() 205 { 206 OBoundControlModel::defaultCommonProperties(); 207 // no own common properties at the moment 208 } 209 210 //------------------------------------------------------------------------------ 211 void OEditBaseModel::readCommonEditProperties(const Reference<XObjectInputStream>& _rxInStream) 212 { 213 sal_Int32 nLen = _rxInStream->readLong(); 214 215 Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY); 216 DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !"); 217 sal_Int32 nMark = xMark->createMark(); 218 219 // read properties common to all OBoundControlModels 220 OBoundControlModel::readCommonProperties(_rxInStream); 221 222 // read properties common to all OEditBaseModels 223 224 // skip the remaining bytes 225 xMark->jumpToMark(nMark); 226 _rxInStream->skipBytes(nLen); 227 xMark->deleteMark(nMark); 228 } 229 230 //------------------------------------------------------------------------------ 231 void OEditBaseModel::writeCommonEditProperties(const Reference<XObjectOutputStream>& _rxOutStream) 232 { 233 Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY); 234 DBG_ASSERT(xMark.is(), "OEditBaseModel::writeCommonProperties : can only work with markable streams !"); 235 sal_Int32 nMark = xMark->createMark(); 236 237 // a placeholder where we will write the overall length (later in this method) 238 sal_Int32 nLen = 0; 239 _rxOutStream->writeLong(nLen); 240 241 // write properties common to all OBoundControlModels 242 OBoundControlModel::writeCommonProperties(_rxOutStream); 243 244 // write properties common to all OEditBaseModels 245 246 // close the block - write the correct length at the beginning 247 nLen = xMark->offsetToMark(nMark) - sizeof(nLen); 248 xMark->jumpToMark(nMark); 249 _rxOutStream->writeLong(nLen); 250 xMark->jumpToFurthest(); 251 xMark->deleteMark(nMark); 252 } 253 254 //------------------------------------------------------------------------------ 255 void OEditBaseModel::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const 256 { 257 switch (nHandle) 258 { 259 case PROPERTY_ID_EMPTY_IS_NULL: 260 rValue <<= (sal_Bool)m_bEmptyIsNull; 261 break; 262 case PROPERTY_ID_FILTERPROPOSAL: 263 rValue <<= (sal_Bool)m_bFilterProposal; 264 break; 265 case PROPERTY_ID_DEFAULT_TEXT: 266 rValue <<= m_aDefaultText; 267 break; 268 case PROPERTY_ID_DEFAULT_VALUE: 269 case PROPERTY_ID_DEFAULT_DATE: 270 case PROPERTY_ID_DEFAULT_TIME: 271 rValue = m_aDefault; 272 break; 273 default: 274 OBoundControlModel::getFastPropertyValue(rValue, nHandle); 275 } 276 } 277 278 //------------------------------------------------------------------------------ 279 sal_Bool OEditBaseModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue, 280 sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException ) 281 { 282 sal_Bool bModified(sal_False); 283 switch (nHandle) 284 { 285 case PROPERTY_ID_EMPTY_IS_NULL: 286 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEmptyIsNull); 287 break; 288 case PROPERTY_ID_FILTERPROPOSAL: 289 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bFilterProposal); 290 break; 291 case PROPERTY_ID_DEFAULT_TEXT: 292 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultText); 293 break; 294 case PROPERTY_ID_DEFAULT_VALUE: 295 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, ::getCppuType((const double*)0)); 296 break; 297 case PROPERTY_ID_DEFAULT_DATE: 298 case PROPERTY_ID_DEFAULT_TIME: 299 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, ::getCppuType((const sal_Int32*)0)); 300 break; 301 default: 302 bModified = OBoundControlModel::convertFastPropertyValue( 303 rConvertedValue, 304 rOldValue, 305 nHandle, 306 rValue); 307 } 308 return bModified; 309 } 310 311 //------------------------------------------------------------------------------ 312 void OEditBaseModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw ( ::com::sun::star::uno::Exception) 313 { 314 switch (nHandle) 315 { 316 case PROPERTY_ID_EMPTY_IS_NULL: 317 DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" ); 318 m_bEmptyIsNull = getBOOL(rValue); 319 break; 320 case PROPERTY_ID_FILTERPROPOSAL: 321 DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" ); 322 m_bFilterProposal = getBOOL(rValue); 323 break; 324 // Aenderung der defaultwerte fuehrt zu reset 325 case PROPERTY_ID_DEFAULT_TEXT: 326 DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "invalid type" ); 327 rValue >>= m_aDefaultText; 328 resetNoBroadcast(); 329 break; 330 case PROPERTY_ID_DEFAULT_VALUE: 331 case PROPERTY_ID_DEFAULT_DATE: 332 case PROPERTY_ID_DEFAULT_TIME: 333 m_aDefault = rValue; 334 resetNoBroadcast(); 335 break; 336 default: 337 OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue ); 338 } 339 } 340 341 //XPropertyState 342 //------------------------------------------------------------------------------ 343 Any OEditBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const 344 { 345 switch (nHandle) 346 { 347 case PROPERTY_ID_DEFAULT_TEXT: 348 return makeAny(::rtl::OUString()); 349 case PROPERTY_ID_FILTERPROPOSAL: 350 return Any(makeAny((sal_Bool)sal_False)); 351 case PROPERTY_ID_DEFAULT_VALUE: 352 case PROPERTY_ID_DEFAULT_DATE: 353 case PROPERTY_ID_DEFAULT_TIME: 354 return Any(); 355 default: 356 return OBoundControlModel::getPropertyDefaultByHandle(nHandle); 357 } 358 } 359 360 //......................................................................... 361 } 362 //......................................................................... 363 364