Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "EditBase.hxx"
21 : #include "property.hxx"
22 : #include "property.hrc"
23 : #include "services.hxx"
24 : #include <tools/debug.hxx>
25 : #include <comphelper/basicio.hxx>
26 : #include <cppuhelper/queryinterface.hxx>
27 : #include "frm_resource.hxx"
28 : #include "frm_resource.hrc"
29 : #include <tools/time.hxx>
30 : #include <tools/date.hxx>
31 : #include <com/sun/star/util/Time.hpp>
32 : #include <com/sun/star/util/Date.hpp>
33 :
34 :
35 : namespace frm
36 : {
37 : using namespace ::com::sun::star;
38 : using namespace ::com::sun::star::uno;
39 : using namespace ::com::sun::star::sdb;
40 : using namespace ::com::sun::star::sdbc;
41 : using namespace ::com::sun::star::sdbcx;
42 : using namespace ::com::sun::star::beans;
43 : using namespace ::com::sun::star::container;
44 : using namespace ::com::sun::star::form;
45 : using namespace ::com::sun::star::awt;
46 : using namespace ::com::sun::star::io;
47 : using namespace ::com::sun::star::lang;
48 : using namespace ::com::sun::star::util;
49 :
50 : namespace
51 : {
52 : const sal_uInt16 DEFAULT_LONG = 0x0001;
53 : const sal_uInt16 DEFAULT_DOUBLE = 0x0002;
54 : const sal_uInt16 FILTERPROPOSAL = 0x0004;
55 : const sal_uInt16 DEFAULT_TIME = 0x0008;
56 : const sal_uInt16 DEFAULT_DATE = 0x0010;
57 : }
58 :
59 :
60 0 : OEditBaseModel::OEditBaseModel( const Reference< XComponentContext >& _rxFactory, const OUString& rUnoControlModelName,
61 : const OUString& rDefault, const sal_Bool _bSupportExternalBinding, const sal_Bool _bSupportsValidation )
62 : :OBoundControlModel( _rxFactory, rUnoControlModelName, rDefault, sal_True, _bSupportExternalBinding, _bSupportsValidation )
63 : ,m_nLastReadVersion(0)
64 : ,m_bEmptyIsNull(sal_True)
65 0 : ,m_bFilterProposal(sal_False)
66 : {
67 0 : }
68 :
69 :
70 0 : OEditBaseModel::OEditBaseModel( const OEditBaseModel* _pOriginal, const Reference< XComponentContext >& _rxFactory )
71 : :OBoundControlModel( _pOriginal, _rxFactory )
72 0 : ,m_nLastReadVersion(0)
73 : {
74 :
75 0 : m_bFilterProposal = _pOriginal->m_bFilterProposal;
76 0 : m_bEmptyIsNull = _pOriginal->m_bEmptyIsNull;
77 0 : m_aDefault = _pOriginal->m_aDefault;
78 0 : m_aDefaultText = _pOriginal->m_aDefaultText;
79 0 : }
80 :
81 :
82 0 : OEditBaseModel::~OEditBaseModel( )
83 : {
84 0 : }
85 :
86 : // XPersist
87 :
88 0 : void OEditBaseModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
89 : {
90 0 : OBoundControlModel::write(_rxOutStream);
91 :
92 : // Version
93 0 : sal_uInt16 nVersionId = 0x0006;
94 : DBG_ASSERT((getPersistenceFlags() & ~PF_SPECIAL_FLAGS) == 0,
95 : "OEditBaseModel::write : invalid special version flags !");
96 : // please don't use other flags, older versions can't interpret them !
97 :
98 0 : nVersionId |= getPersistenceFlags();
99 0 : _rxOutStream->writeShort(nVersionId);
100 :
101 : // Name
102 0 : _rxOutStream->writeShort(0); // obsolete
103 0 : _rxOutStream << m_aDefaultText;
104 :
105 : // Masking for any
106 0 : sal_uInt16 nAnyMask = 0;
107 0 : if (m_aDefault.getValueType().getTypeClass() == TypeClass_LONG)
108 0 : nAnyMask |= DEFAULT_LONG;
109 0 : else if (m_aDefault.getValueType().getTypeClass() == TypeClass_DOUBLE)
110 0 : nAnyMask |= DEFAULT_DOUBLE;
111 0 : else if (m_aDefault.getValueType() == ::getCppuType((const util::Time*)0))
112 0 : nAnyMask |= DEFAULT_TIME;
113 0 : else if (m_aDefault.getValueType() == ::getCppuType((const util::Date*)0))
114 0 : nAnyMask |= DEFAULT_DATE;
115 :
116 0 : if (m_bFilterProposal) // Don't save a value, because it's boolean
117 0 : nAnyMask |= FILTERPROPOSAL;
118 :
119 0 : _rxOutStream->writeBoolean(m_bEmptyIsNull);
120 0 : _rxOutStream->writeShort(nAnyMask);
121 :
122 0 : if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
123 0 : _rxOutStream->writeLong(getINT32(m_aDefault));
124 0 : else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
125 0 : _rxOutStream->writeDouble(getDouble(m_aDefault));
126 0 : else if ((nAnyMask & DEFAULT_TIME) == DEFAULT_TIME)
127 : {
128 0 : util::Time aTime;
129 0 : OSL_VERIFY(m_aDefault >>= aTime);
130 0 : _rxOutStream->writeHyper(::Time(aTime).GetTime());
131 : }
132 0 : else if ((nAnyMask & DEFAULT_DATE) == DEFAULT_DATE)
133 : {
134 0 : util::Date aDate;
135 0 : OSL_VERIFY(m_aDefault >>= aDate);
136 0 : _rxOutStream->writeLong(::Date(aDate).GetDate());
137 : }
138 :
139 : // since version 5 we write the help text
140 0 : writeHelpTextCompatibly(_rxOutStream);
141 : // (that's potentially bad : at the time I added the above line we had two derived classes : OEditModel and
142 : // OFormattedModel. The first one does not have an own version handling, so it can't write the help text itself,
143 : // the second one does it's own writing (reading) after calling our method, so normally we shouldn't write any
144 : // additional members as this is not compatible to older office versions.
145 : // We decided to place the writing of the help text here as it seems the less worse alternative. There is no delivered
146 : // office version including formatted controls (and thus the OFormattedModel), and the OFormattedModel::read seems
147 : // robust against this change (as it will read a wrong and unknown file version and thus set it's members to defaults).
148 :
149 0 : if ((nVersionId & PF_HANDLE_COMMON_PROPS) != 0)
150 0 : writeCommonEditProperties(_rxOutStream);
151 :
152 : // !!! properties common to all OEditBaseModel derived classes should be written in writeCommonEditProperties !!!
153 0 : }
154 :
155 :
156 0 : sal_uInt16 OEditBaseModel::getPersistenceFlags() const
157 : {
158 0 : return PF_HANDLE_COMMON_PROPS;
159 : }
160 :
161 :
162 0 : void OEditBaseModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
163 : {
164 0 : OBoundControlModel::read(_rxInStream);
165 0 : ::osl::MutexGuard aGuard(m_aMutex);
166 :
167 : // Version's own version number
168 0 : sal_uInt16 nVersion = _rxInStream->readShort();
169 0 : m_nLastReadVersion = nVersion;
170 :
171 0 : sal_Bool bHandleCommonProps = (nVersion & PF_HANDLE_COMMON_PROPS) != 0;
172 0 : nVersion = nVersion & ~PF_SPECIAL_FLAGS;
173 :
174 : // obsolete
175 0 : _rxInStream->readShort();
176 :
177 0 : _rxInStream >> m_aDefaultText;
178 :
179 0 : if (nVersion >= 0x0003)
180 : {
181 0 : m_bEmptyIsNull = _rxInStream->readBoolean();
182 :
183 0 : sal_uInt16 nAnyMask = _rxInStream->readShort();
184 0 : if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
185 : {
186 0 : sal_Int32 nValue = _rxInStream->readLong();
187 0 : m_aDefault <<= (sal_Int32)nValue;
188 : }
189 0 : else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
190 : {
191 0 : double fValue = _rxInStream->readDouble();
192 0 : m_aDefault <<= (double)fValue;
193 : }
194 0 : else if ((nAnyMask & DEFAULT_TIME) == DEFAULT_TIME)
195 : {
196 0 : m_aDefault <<= ::Time(_rxInStream->readHyper()).GetUNOTime();
197 : }
198 0 : else if ((nAnyMask & DEFAULT_DATE) == DEFAULT_DATE)
199 : {
200 0 : m_aDefault <<= ::Date(_rxInStream->readLong()).GetUNODate();
201 : }
202 :
203 0 : if ((nAnyMask & FILTERPROPOSAL) == FILTERPROPOSAL)
204 0 : m_bFilterProposal = sal_True;
205 : }
206 :
207 0 : if (nVersion > 4)
208 0 : readHelpTextCompatibly(_rxInStream);
209 :
210 0 : if (bHandleCommonProps)
211 0 : readCommonEditProperties(_rxInStream);
212 :
213 : // After reading, display default values
214 0 : if ( !getControlSource().isEmpty() )
215 : // (not if we don't have a control source - the "State" property acts like it is persistent, then)
216 0 : resetNoBroadcast();
217 0 : };
218 :
219 :
220 0 : void OEditBaseModel::defaultCommonEditProperties()
221 : {
222 0 : OBoundControlModel::defaultCommonProperties();
223 : // no own common properties at the moment
224 0 : }
225 :
226 :
227 0 : void OEditBaseModel::readCommonEditProperties(const Reference<XObjectInputStream>& _rxInStream)
228 : {
229 0 : sal_Int32 nLen = _rxInStream->readLong();
230 :
231 0 : Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
232 : DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
233 0 : sal_Int32 nMark = xMark->createMark();
234 :
235 : // read properties common to all OBoundControlModels
236 0 : OBoundControlModel::readCommonProperties(_rxInStream);
237 :
238 : // read properties common to all OEditBaseModels
239 :
240 : // skip the remaining bytes
241 0 : xMark->jumpToMark(nMark);
242 0 : _rxInStream->skipBytes(nLen);
243 0 : xMark->deleteMark(nMark);
244 0 : }
245 :
246 :
247 0 : void OEditBaseModel::writeCommonEditProperties(const Reference<XObjectOutputStream>& _rxOutStream)
248 : {
249 0 : Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
250 : DBG_ASSERT(xMark.is(), "OEditBaseModel::writeCommonProperties : can only work with markable streams !");
251 0 : sal_Int32 nMark = xMark->createMark();
252 :
253 : // a placeholder where we will write the overall length (later in this method)
254 0 : sal_Int32 nLen = 0;
255 0 : _rxOutStream->writeLong(nLen);
256 :
257 : // write properties common to all OBoundControlModels
258 0 : OBoundControlModel::writeCommonProperties(_rxOutStream);
259 :
260 : // write properties common to all OEditBaseModels
261 :
262 : // close the block - write the correct length at the beginning
263 0 : nLen = xMark->offsetToMark(nMark) - sizeof(nLen);
264 0 : xMark->jumpToMark(nMark);
265 0 : _rxOutStream->writeLong(nLen);
266 0 : xMark->jumpToFurthest();
267 0 : xMark->deleteMark(nMark);
268 0 : }
269 :
270 :
271 0 : void OEditBaseModel::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
272 : {
273 0 : switch (nHandle)
274 : {
275 : case PROPERTY_ID_EMPTY_IS_NULL:
276 0 : rValue <<= (sal_Bool)m_bEmptyIsNull;
277 0 : break;
278 : case PROPERTY_ID_FILTERPROPOSAL:
279 0 : rValue <<= (sal_Bool)m_bFilterProposal;
280 0 : break;
281 : case PROPERTY_ID_DEFAULT_TEXT:
282 0 : rValue <<= m_aDefaultText;
283 0 : break;
284 : case PROPERTY_ID_DEFAULT_VALUE:
285 : case PROPERTY_ID_DEFAULT_DATE:
286 : case PROPERTY_ID_DEFAULT_TIME:
287 0 : rValue = m_aDefault;
288 0 : break;
289 : default:
290 0 : OBoundControlModel::getFastPropertyValue(rValue, nHandle);
291 : }
292 0 : }
293 :
294 :
295 0 : sal_Bool OEditBaseModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
296 : sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException )
297 : {
298 0 : sal_Bool bModified(sal_False);
299 0 : switch (nHandle)
300 : {
301 : case PROPERTY_ID_EMPTY_IS_NULL:
302 0 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEmptyIsNull);
303 0 : break;
304 : case PROPERTY_ID_FILTERPROPOSAL:
305 0 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bFilterProposal);
306 0 : break;
307 : case PROPERTY_ID_DEFAULT_TEXT:
308 0 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultText);
309 0 : break;
310 : case PROPERTY_ID_DEFAULT_VALUE:
311 0 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, ::getCppuType((const double*)0));
312 0 : break;
313 : case PROPERTY_ID_DEFAULT_DATE:
314 0 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, ::getCppuType((const util::Date*)0));
315 0 : break;
316 : case PROPERTY_ID_DEFAULT_TIME:
317 0 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, ::getCppuType((const util::Time*)0));
318 0 : break;
319 : default:
320 : bModified = OBoundControlModel::convertFastPropertyValue(
321 : rConvertedValue,
322 : rOldValue,
323 : nHandle,
324 0 : rValue);
325 : }
326 0 : return bModified;
327 : }
328 :
329 :
330 0 : void OEditBaseModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw ( ::com::sun::star::uno::Exception, std::exception)
331 : {
332 0 : switch (nHandle)
333 : {
334 : case PROPERTY_ID_EMPTY_IS_NULL:
335 : DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" );
336 0 : m_bEmptyIsNull = getBOOL(rValue);
337 0 : break;
338 : case PROPERTY_ID_FILTERPROPOSAL:
339 : DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" );
340 0 : m_bFilterProposal = getBOOL(rValue);
341 0 : break;
342 : // Changing the default values causes a reset
343 : case PROPERTY_ID_DEFAULT_TEXT:
344 : DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "invalid type" );
345 0 : rValue >>= m_aDefaultText;
346 0 : resetNoBroadcast();
347 0 : break;
348 : case PROPERTY_ID_DEFAULT_VALUE:
349 : case PROPERTY_ID_DEFAULT_DATE:
350 : case PROPERTY_ID_DEFAULT_TIME:
351 0 : m_aDefault = rValue;
352 0 : resetNoBroadcast();
353 0 : break;
354 : default:
355 0 : OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue );
356 : }
357 0 : }
358 :
359 : // XPropertyState
360 :
361 0 : Any OEditBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
362 : {
363 0 : switch (nHandle)
364 : {
365 : case PROPERTY_ID_DEFAULT_TEXT:
366 0 : return makeAny(OUString());
367 : case PROPERTY_ID_FILTERPROPOSAL:
368 0 : return Any(makeAny((sal_Bool)sal_False));
369 : case PROPERTY_ID_DEFAULT_VALUE:
370 : case PROPERTY_ID_DEFAULT_DATE:
371 : case PROPERTY_ID_DEFAULT_TIME:
372 0 : return Any();
373 : default:
374 0 : return OBoundControlModel::getPropertyDefaultByHandle(nHandle);
375 : }
376 : }
377 :
378 :
379 : }
380 :
381 :
382 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|