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 197 : OEditBaseModel::OEditBaseModel( const Reference< XComponentContext >& _rxFactory, const OUString& rUnoControlModelName,
61 : const OUString& rDefault, const bool _bSupportExternalBinding, const bool _bSupportsValidation )
62 : :OBoundControlModel( _rxFactory, rUnoControlModelName, rDefault, true, _bSupportExternalBinding, _bSupportsValidation )
63 : ,m_nLastReadVersion(0)
64 : ,m_bEmptyIsNull(true)
65 197 : ,m_bFilterProposal(false)
66 : {
67 197 : }
68 :
69 :
70 8 : OEditBaseModel::OEditBaseModel( const OEditBaseModel* _pOriginal, const Reference< XComponentContext >& _rxFactory )
71 : :OBoundControlModel( _pOriginal, _rxFactory )
72 8 : ,m_nLastReadVersion(0)
73 : {
74 :
75 8 : m_bFilterProposal = _pOriginal->m_bFilterProposal;
76 8 : m_bEmptyIsNull = _pOriginal->m_bEmptyIsNull;
77 8 : m_aDefault = _pOriginal->m_aDefault;
78 8 : m_aDefaultText = _pOriginal->m_aDefaultText;
79 8 : }
80 :
81 :
82 195 : OEditBaseModel::~OEditBaseModel( )
83 : {
84 195 : }
85 :
86 : // XPersist
87 :
88 8 : void OEditBaseModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
89 : {
90 8 : OBoundControlModel::write(_rxOutStream);
91 :
92 : // Version
93 8 : 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 8 : nVersionId |= getPersistenceFlags();
99 8 : _rxOutStream->writeShort(nVersionId);
100 :
101 : // Name
102 8 : _rxOutStream->writeShort(0); // obsolete
103 8 : _rxOutStream << m_aDefaultText;
104 :
105 : // Masking for any
106 8 : sal_uInt16 nAnyMask = 0;
107 8 : if (m_aDefault.getValueType().getTypeClass() == TypeClass_LONG)
108 0 : nAnyMask |= DEFAULT_LONG;
109 8 : else if (m_aDefault.getValueType().getTypeClass() == TypeClass_DOUBLE)
110 0 : nAnyMask |= DEFAULT_DOUBLE;
111 8 : else if (m_aDefault.getValueType() == cppu::UnoType<util::Time>::get())
112 0 : nAnyMask |= DEFAULT_TIME;
113 8 : else if (m_aDefault.getValueType() == cppu::UnoType<util::Date>::get())
114 0 : nAnyMask |= DEFAULT_DATE;
115 :
116 8 : if (m_bFilterProposal) // Don't save a value, because it's boolean
117 0 : nAnyMask |= FILTERPROPOSAL;
118 :
119 8 : _rxOutStream->writeBoolean(m_bEmptyIsNull);
120 8 : _rxOutStream->writeShort(nAnyMask);
121 :
122 8 : if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
123 0 : _rxOutStream->writeLong(getINT32(m_aDefault));
124 8 : else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
125 0 : _rxOutStream->writeDouble(getDouble(m_aDefault));
126 8 : else if ((nAnyMask & DEFAULT_TIME) == DEFAULT_TIME)
127 : {
128 0 : util::Time aTime;
129 0 : OSL_VERIFY(m_aDefault >>= aTime);
130 0 : _rxOutStream->writeHyper(::tools::Time(aTime).GetTime());
131 : }
132 8 : 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 8 : 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 8 : if ((nVersionId & PF_HANDLE_COMMON_PROPS) != 0)
150 8 : writeCommonEditProperties(_rxOutStream);
151 :
152 : // !!! properties common to all OEditBaseModel derived classes should be written in writeCommonEditProperties !!!
153 8 : }
154 :
155 :
156 8 : sal_uInt16 OEditBaseModel::getPersistenceFlags() const
157 : {
158 8 : return PF_HANDLE_COMMON_PROPS;
159 : }
160 :
161 :
162 8 : void OEditBaseModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
163 : {
164 8 : OBoundControlModel::read(_rxInStream);
165 8 : ::osl::MutexGuard aGuard(m_aMutex);
166 :
167 : // Version's own version number
168 8 : sal_uInt16 nVersion = _rxInStream->readShort();
169 8 : m_nLastReadVersion = nVersion;
170 :
171 8 : bool bHandleCommonProps = (nVersion & PF_HANDLE_COMMON_PROPS) != 0;
172 8 : nVersion = nVersion & ~PF_SPECIAL_FLAGS;
173 :
174 : // obsolete
175 8 : _rxInStream->readShort();
176 :
177 8 : _rxInStream >> m_aDefaultText;
178 :
179 8 : if (nVersion >= 0x0003)
180 : {
181 8 : m_bEmptyIsNull = _rxInStream->readBoolean();
182 :
183 8 : sal_uInt16 nAnyMask = _rxInStream->readShort();
184 8 : if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
185 : {
186 0 : sal_Int32 nValue = _rxInStream->readLong();
187 0 : m_aDefault <<= (sal_Int32)nValue;
188 : }
189 8 : else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
190 : {
191 0 : double fValue = _rxInStream->readDouble();
192 0 : m_aDefault <<= (double)fValue;
193 : }
194 8 : else if ((nAnyMask & DEFAULT_TIME) == DEFAULT_TIME)
195 : {
196 0 : m_aDefault <<= ::tools::Time(_rxInStream->readHyper()).GetUNOTime();
197 : }
198 8 : else if ((nAnyMask & DEFAULT_DATE) == DEFAULT_DATE)
199 : {
200 0 : m_aDefault <<= ::Date(_rxInStream->readLong()).GetUNODate();
201 : }
202 :
203 8 : if ((nAnyMask & FILTERPROPOSAL) == FILTERPROPOSAL)
204 0 : m_bFilterProposal = true;
205 : }
206 :
207 8 : if (nVersion > 4)
208 8 : readHelpTextCompatibly(_rxInStream);
209 :
210 8 : if (bHandleCommonProps)
211 8 : readCommonEditProperties(_rxInStream);
212 :
213 : // After reading, display default values
214 8 : if ( !getControlSource().isEmpty() )
215 : // (not if we don't have a control source - the "State" property acts like it is persistent, then)
216 6 : resetNoBroadcast();
217 8 : };
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 8 : void OEditBaseModel::readCommonEditProperties(const Reference<XObjectInputStream>& _rxInStream)
228 : {
229 8 : sal_Int32 nLen = _rxInStream->readLong();
230 :
231 8 : Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
232 : DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
233 8 : sal_Int32 nMark = xMark->createMark();
234 :
235 : // read properties common to all OBoundControlModels
236 8 : OBoundControlModel::readCommonProperties(_rxInStream);
237 :
238 : // read properties common to all OEditBaseModels
239 :
240 : // skip the remaining bytes
241 8 : xMark->jumpToMark(nMark);
242 8 : _rxInStream->skipBytes(nLen);
243 8 : xMark->deleteMark(nMark);
244 8 : }
245 :
246 :
247 8 : void OEditBaseModel::writeCommonEditProperties(const Reference<XObjectOutputStream>& _rxOutStream)
248 : {
249 8 : Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
250 : DBG_ASSERT(xMark.is(), "OEditBaseModel::writeCommonProperties : can only work with markable streams !");
251 8 : sal_Int32 nMark = xMark->createMark();
252 :
253 : // a placeholder where we will write the overall length (later in this method)
254 8 : sal_Int32 nLen = 0;
255 8 : _rxOutStream->writeLong(nLen);
256 :
257 : // write properties common to all OBoundControlModels
258 8 : OBoundControlModel::writeCommonProperties(_rxOutStream);
259 :
260 : // write properties common to all OEditBaseModels
261 :
262 : // close the block - write the correct length at the beginning
263 8 : nLen = xMark->offsetToMark(nMark) - sizeof(nLen);
264 8 : xMark->jumpToMark(nMark);
265 8 : _rxOutStream->writeLong(nLen);
266 8 : xMark->jumpToFurthest();
267 8 : xMark->deleteMark(nMark);
268 8 : }
269 :
270 :
271 35786 : void OEditBaseModel::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
272 : {
273 35786 : switch (nHandle)
274 : {
275 : case PROPERTY_ID_EMPTY_IS_NULL:
276 215 : rValue <<= m_bEmptyIsNull;
277 215 : break;
278 : case PROPERTY_ID_FILTERPROPOSAL:
279 211 : rValue <<= m_bFilterProposal;
280 211 : break;
281 : case PROPERTY_ID_DEFAULT_TEXT:
282 217 : rValue <<= m_aDefaultText;
283 217 : break;
284 : case PROPERTY_ID_DEFAULT_VALUE:
285 : case PROPERTY_ID_DEFAULT_DATE:
286 : case PROPERTY_ID_DEFAULT_TIME:
287 110 : rValue = m_aDefault;
288 110 : break;
289 : default:
290 35033 : OBoundControlModel::getFastPropertyValue(rValue, nHandle);
291 : }
292 35786 : }
293 :
294 :
295 3124 : sal_Bool OEditBaseModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
296 : sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException )
297 : {
298 3124 : bool bModified(false);
299 3124 : switch (nHandle)
300 : {
301 : case PROPERTY_ID_EMPTY_IS_NULL:
302 102 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEmptyIsNull);
303 102 : break;
304 : case PROPERTY_ID_FILTERPROPOSAL:
305 94 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bFilterProposal);
306 94 : break;
307 : case PROPERTY_ID_DEFAULT_TEXT:
308 101 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultText);
309 101 : break;
310 : case PROPERTY_ID_DEFAULT_VALUE:
311 0 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, cppu::UnoType<double>::get());
312 0 : break;
313 : case PROPERTY_ID_DEFAULT_DATE:
314 0 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, cppu::UnoType<util::Date>::get());
315 0 : break;
316 : case PROPERTY_ID_DEFAULT_TIME:
317 0 : bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, cppu::UnoType<util::Time>::get());
318 0 : break;
319 : default:
320 : bModified = OBoundControlModel::convertFastPropertyValue(
321 : rConvertedValue,
322 : rOldValue,
323 : nHandle,
324 2827 : rValue);
325 : }
326 3124 : return bModified;
327 : }
328 :
329 :
330 731 : void OEditBaseModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw ( ::com::sun::star::uno::Exception, std::exception)
331 : {
332 731 : switch (nHandle)
333 : {
334 : case PROPERTY_ID_EMPTY_IS_NULL:
335 : DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" );
336 18 : m_bEmptyIsNull = getBOOL(rValue);
337 18 : break;
338 : case PROPERTY_ID_FILTERPROPOSAL:
339 : DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" );
340 16 : m_bFilterProposal = getBOOL(rValue);
341 16 : 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 20 : rValue >>= m_aDefaultText;
346 20 : resetNoBroadcast();
347 20 : 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 677 : OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue );
356 : }
357 731 : }
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 makeAny(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: */
|