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