tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / forms / source / component / EditBase.cxx
blob41c256e9c120f998dc2b429278da22225affcd2c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "EditBase.hxx"
21 #include <property.hxx>
22 #include <tools/debug.hxx>
23 #include <comphelper/basicio.hxx>
24 #include <comphelper/property.hxx>
25 #include <comphelper/types.hxx>
26 #include <tools/time.hxx>
27 #include <tools/date.hxx>
28 #include <com/sun/star/io/XMarkableStream.hpp>
29 #include <com/sun/star/util/Time.hpp>
30 #include <com/sun/star/util/Date.hpp>
33 namespace frm
35 using namespace ::com::sun::star;
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::sdb;
38 using namespace ::com::sun::star::sdbc;
39 using namespace ::com::sun::star::io;
40 using namespace ::com::sun::star::util;
42 namespace
44 const sal_uInt16 DEFAULT_LONG = 0x0001;
45 const sal_uInt16 DEFAULT_DOUBLE = 0x0002;
46 const sal_uInt16 FILTERPROPOSAL = 0x0004;
47 const sal_uInt16 DEFAULT_TIME = 0x0008;
48 const sal_uInt16 DEFAULT_DATE = 0x0010;
52 OEditBaseModel::OEditBaseModel( const Reference< XComponentContext >& _rxFactory, const OUString& rUnoControlModelName,
53 const OUString& rDefault, const bool _bSupportExternalBinding, const bool _bSupportsValidation )
54 :OBoundControlModel( _rxFactory, rUnoControlModelName, rDefault, true, _bSupportExternalBinding, _bSupportsValidation )
55 ,m_nLastReadVersion(0)
56 ,m_bEmptyIsNull(true)
57 ,m_bFilterProposal(false)
62 OEditBaseModel::OEditBaseModel( const OEditBaseModel* _pOriginal, const Reference< XComponentContext >& _rxFactory )
63 :OBoundControlModel( _pOriginal, _rxFactory )
64 ,m_nLastReadVersion(0)
67 m_bFilterProposal = _pOriginal->m_bFilterProposal;
68 m_bEmptyIsNull = _pOriginal->m_bEmptyIsNull;
69 m_aDefault = _pOriginal->m_aDefault;
70 m_aDefaultText = _pOriginal->m_aDefaultText;
74 OEditBaseModel::~OEditBaseModel( )
78 // XPersist
80 void OEditBaseModel::write(const Reference<XObjectOutputStream>& _rxOutStream)
82 OBoundControlModel::write(_rxOutStream);
84 // Version
85 sal_uInt16 nVersionId = 0x0006;
86 DBG_ASSERT((getPersistenceFlags() & ~PF_SPECIAL_FLAGS) == 0,
87 "OEditBaseModel::write : invalid special version flags !");
88 // please don't use other flags, older versions can't interpret them !
90 nVersionId |= getPersistenceFlags();
91 _rxOutStream->writeShort(nVersionId);
93 // Name
94 _rxOutStream->writeShort(0); // obsolete
95 _rxOutStream << m_aDefaultText;
97 // Masking for any
98 sal_uInt16 nAnyMask = 0;
99 if (m_aDefault.getValueTypeClass() == TypeClass_LONG)
100 nAnyMask |= DEFAULT_LONG;
101 else if (m_aDefault.getValueTypeClass() == TypeClass_DOUBLE)
102 nAnyMask |= DEFAULT_DOUBLE;
103 else if (m_aDefault.getValueType() == cppu::UnoType<util::Time>::get())
104 nAnyMask |= DEFAULT_TIME;
105 else if (m_aDefault.getValueType() == cppu::UnoType<util::Date>::get())
106 nAnyMask |= DEFAULT_DATE;
108 if (m_bFilterProposal) // Don't save a value, because it's boolean
109 nAnyMask |= FILTERPROPOSAL;
111 _rxOutStream->writeBoolean(m_bEmptyIsNull);
112 _rxOutStream->writeShort(nAnyMask);
114 if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
115 _rxOutStream->writeLong(getINT32(m_aDefault));
116 else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
117 _rxOutStream->writeDouble(getDouble(m_aDefault));
118 else if ((nAnyMask & DEFAULT_TIME) == DEFAULT_TIME)
120 util::Time aTime;
121 OSL_VERIFY(m_aDefault >>= aTime);
122 _rxOutStream->writeHyper(::tools::Time(aTime).GetTime());
124 else if ((nAnyMask & DEFAULT_DATE) == DEFAULT_DATE)
126 util::Date aDate;
127 OSL_VERIFY(m_aDefault >>= aDate);
128 _rxOutStream->writeLong(::Date(aDate).GetDate());
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 its 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 its members to defaults).
141 if ((nVersionId & PF_HANDLE_COMMON_PROPS) != 0)
142 writeCommonEditProperties(_rxOutStream);
144 // !!! properties common to all OEditBaseModel derived classes should be written in writeCommonEditProperties !!!
148 sal_uInt16 OEditBaseModel::getPersistenceFlags() const
150 return PF_HANDLE_COMMON_PROPS;
154 void OEditBaseModel::read(const Reference<XObjectInputStream>& _rxInStream)
156 OBoundControlModel::read(_rxInStream);
157 ::osl::MutexGuard aGuard(m_aMutex);
159 // Version's own version number
160 sal_uInt16 nVersion = _rxInStream->readShort();
161 m_nLastReadVersion = nVersion;
163 bool bHandleCommonProps = (nVersion & PF_HANDLE_COMMON_PROPS) != 0;
164 nVersion = nVersion & ~PF_SPECIAL_FLAGS;
166 // obsolete
167 _rxInStream->readShort();
169 _rxInStream >> m_aDefaultText;
171 if (nVersion >= 0x0003)
173 m_bEmptyIsNull = _rxInStream->readBoolean();
175 sal_uInt16 nAnyMask = _rxInStream->readShort();
176 if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
178 sal_Int32 nValue = _rxInStream->readLong();
179 m_aDefault <<= nValue;
181 else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
183 double fValue = _rxInStream->readDouble();
184 m_aDefault <<= fValue;
186 else if ((nAnyMask & DEFAULT_TIME) == DEFAULT_TIME)
188 m_aDefault <<= ::tools::Time::fromEncodedTime(_rxInStream->readHyper()).GetUNOTime();
190 else if ((nAnyMask & DEFAULT_DATE) == DEFAULT_DATE)
192 m_aDefault <<= ::Date(_rxInStream->readLong()).GetUNODate();
195 if ((nAnyMask & FILTERPROPOSAL) == FILTERPROPOSAL)
196 m_bFilterProposal = true;
199 if (nVersion > 4)
200 readHelpTextCompatibly(_rxInStream);
202 if (bHandleCommonProps)
203 readCommonEditProperties(_rxInStream);
205 // After reading, display default values
206 if ( !getControlSource().isEmpty() )
207 // (not if we don't have a control source - the "State" property acts like it is persistent, then)
208 resetNoBroadcast();
212 void OEditBaseModel::defaultCommonEditProperties()
214 OBoundControlModel::defaultCommonProperties();
215 // no own common properties at the moment
219 void OEditBaseModel::readCommonEditProperties(const Reference<XObjectInputStream>& _rxInStream)
221 sal_Int32 nLen = _rxInStream->readLong();
223 Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
224 DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
225 sal_Int32 nMark = xMark->createMark();
227 // read properties common to all OBoundControlModels
228 OBoundControlModel::readCommonProperties(_rxInStream);
230 // read properties common to all OEditBaseModels
232 // skip the remaining bytes
233 xMark->jumpToMark(nMark);
234 _rxInStream->skipBytes(nLen);
235 xMark->deleteMark(nMark);
239 void OEditBaseModel::writeCommonEditProperties(const Reference<XObjectOutputStream>& _rxOutStream)
241 Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
242 DBG_ASSERT(xMark.is(), "OEditBaseModel::writeCommonProperties : can only work with markable streams !");
243 sal_Int32 nMark = xMark->createMark();
245 // a placeholder where we will write the overall length (later in this method)
246 sal_Int32 nLen = 0;
247 _rxOutStream->writeLong(nLen);
249 // write properties common to all OBoundControlModels
250 OBoundControlModel::writeCommonProperties(_rxOutStream);
252 // write properties common to all OEditBaseModels
254 // close the block - write the correct length at the beginning
255 nLen = xMark->offsetToMark(nMark) - sizeof(nLen);
256 xMark->jumpToMark(nMark);
257 _rxOutStream->writeLong(nLen);
258 xMark->jumpToFurthest();
259 xMark->deleteMark(nMark);
263 void OEditBaseModel::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
265 switch (nHandle)
267 case PROPERTY_ID_EMPTY_IS_NULL:
268 rValue <<= m_bEmptyIsNull;
269 break;
270 case PROPERTY_ID_FILTERPROPOSAL:
271 rValue <<= m_bFilterProposal;
272 break;
273 case PROPERTY_ID_DEFAULT_TEXT:
274 rValue <<= m_aDefaultText;
275 break;
276 case PROPERTY_ID_DEFAULT_VALUE:
277 case PROPERTY_ID_DEFAULT_DATE:
278 case PROPERTY_ID_DEFAULT_TIME:
279 rValue = m_aDefault;
280 break;
281 default:
282 OBoundControlModel::getFastPropertyValue(rValue, nHandle);
286 sal_Bool OEditBaseModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
287 sal_Int32 nHandle, const Any& rValue )
289 bool bModified(false);
290 switch (nHandle)
292 case PROPERTY_ID_EMPTY_IS_NULL:
293 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEmptyIsNull);
294 break;
295 case PROPERTY_ID_FILTERPROPOSAL:
296 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bFilterProposal);
297 break;
298 case PROPERTY_ID_DEFAULT_TEXT:
299 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultText);
300 break;
301 case PROPERTY_ID_DEFAULT_VALUE:
302 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, cppu::UnoType<double>::get());
303 break;
304 case PROPERTY_ID_DEFAULT_DATE:
305 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, cppu::UnoType<util::Date>::get());
306 break;
307 case PROPERTY_ID_DEFAULT_TIME:
308 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, cppu::UnoType<util::Time>::get());
309 break;
310 default:
311 bModified = OBoundControlModel::convertFastPropertyValue(
312 rConvertedValue,
313 rOldValue,
314 nHandle,
315 rValue);
317 return bModified;
320 void OEditBaseModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue )
322 switch (nHandle)
324 case PROPERTY_ID_EMPTY_IS_NULL:
325 DBG_ASSERT(rValue.getValueTypeClass() == TypeClass_BOOLEAN, "invalid type" );
326 m_bEmptyIsNull = getBOOL(rValue);
327 break;
328 case PROPERTY_ID_FILTERPROPOSAL:
329 DBG_ASSERT(rValue.getValueTypeClass() == TypeClass_BOOLEAN, "invalid type" );
330 m_bFilterProposal = getBOOL(rValue);
331 break;
332 // Changing the default values causes a reset
333 case PROPERTY_ID_DEFAULT_TEXT:
334 DBG_ASSERT(rValue.getValueTypeClass() == TypeClass_STRING, "invalid type" );
335 rValue >>= m_aDefaultText;
336 resetNoBroadcast();
337 break;
338 case PROPERTY_ID_DEFAULT_VALUE:
339 case PROPERTY_ID_DEFAULT_DATE:
340 case PROPERTY_ID_DEFAULT_TIME:
341 m_aDefault = rValue;
342 resetNoBroadcast();
343 break;
344 default:
345 OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue );
349 // XPropertyState
351 Any OEditBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
353 switch (nHandle)
355 case PROPERTY_ID_DEFAULT_TEXT:
356 return Any(OUString());
357 case PROPERTY_ID_FILTERPROPOSAL:
358 return Any(false);
359 case PROPERTY_ID_DEFAULT_VALUE:
360 case PROPERTY_ID_DEFAULT_DATE:
361 case PROPERTY_ID_DEFAULT_TIME:
362 return Any();
363 default:
364 return OBoundControlModel::getPropertyDefaultByHandle(nHandle);
372 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */