1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "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>
34 //.........................................................................
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
;
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;
59 DBG_NAME( OEditBaseModel
)
60 //------------------------------------------------------------------
61 OEditBaseModel::OEditBaseModel( const Reference
< XMultiServiceFactory
>& _rxFactory
, const OUString
& rUnoControlModelName
,
62 const OUString
& rDefault
, const sal_Bool _bSupportExternalBinding
, const sal_Bool _bSupportsValidation
)
63 :OBoundControlModel( _rxFactory
, rUnoControlModelName
, rDefault
, sal_True
, _bSupportExternalBinding
, _bSupportsValidation
)
64 ,m_nLastReadVersion(0)
65 ,m_bEmptyIsNull(sal_True
)
66 ,m_bFilterProposal(sal_False
)
68 DBG_CTOR( OEditBaseModel
, NULL
);
71 //------------------------------------------------------------------
72 OEditBaseModel::OEditBaseModel( const OEditBaseModel
* _pOriginal
, const Reference
< XMultiServiceFactory
>& _rxFactory
)
73 :OBoundControlModel( _pOriginal
, _rxFactory
)
74 ,m_nLastReadVersion(0)
76 DBG_CTOR( OEditBaseModel
, NULL
);
78 m_bFilterProposal
= _pOriginal
->m_bFilterProposal
;
79 m_bEmptyIsNull
= _pOriginal
->m_bEmptyIsNull
;
80 m_aDefault
= _pOriginal
->m_aDefault
;
81 m_aDefaultText
= _pOriginal
->m_aDefaultText
;
84 //------------------------------------------------------------------
85 OEditBaseModel::~OEditBaseModel( )
87 DBG_DTOR( OEditBaseModel
, NULL
);
91 //------------------------------------------------------------------------------
92 void OEditBaseModel::write(const Reference
<XObjectOutputStream
>& _rxOutStream
) throw ( ::com::sun::star::io::IOException
, ::com::sun::star::uno::RuntimeException
)
94 OBoundControlModel::write(_rxOutStream
);
97 sal_uInt16 nVersionId
= 0x0006;
98 DBG_ASSERT((getPersistenceFlags() & ~PF_SPECIAL_FLAGS
) == 0,
99 "OEditBaseModel::write : invalid special version flags !");
100 // please don't use other flags, older versions can't interpret them !
102 nVersionId
|= getPersistenceFlags();
103 _rxOutStream
->writeShort(nVersionId
);
106 _rxOutStream
->writeShort(0); // obsolete
107 _rxOutStream
<< m_aDefaultText
;
110 sal_uInt16 nAnyMask
= 0;
111 if (m_aDefault
.getValueType().getTypeClass() == TypeClass_LONG
)
112 nAnyMask
|= DEFAULT_LONG
;
113 else if (m_aDefault
.getValueType().getTypeClass() == TypeClass_DOUBLE
)
114 nAnyMask
|= DEFAULT_DOUBLE
;
115 else if (m_aDefault
.getValueType() == ::getCppuType((const util::Time
*)0))
116 nAnyMask
|= DEFAULT_TIME
;
117 else if (m_aDefault
.getValueType() == ::getCppuType((const util::Date
*)0))
118 nAnyMask
|= DEFAULT_DATE
;
120 if (m_bFilterProposal
) // Don't save a value, because it's boolean
121 nAnyMask
|= FILTERPROPOSAL
;
123 _rxOutStream
->writeBoolean(m_bEmptyIsNull
);
124 _rxOutStream
->writeShort(nAnyMask
);
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 else if ((nAnyMask
& DEFAULT_TIME
) == DEFAULT_TIME
)
133 OSL_VERIFY(m_aDefault
>>= aTime
);
134 _rxOutStream
->writeHyper(::Time(aTime
).GetTime());
136 else if ((nAnyMask
& DEFAULT_DATE
) == DEFAULT_DATE
)
139 OSL_VERIFY(m_aDefault
>>= aDate
);
140 _rxOutStream
->writeLong(::Date(aDate
).GetDate());
143 // since version 5 we write the help text
144 writeHelpTextCompatibly(_rxOutStream
);
145 // (that's potentially bad : at the time I added the above line we had two derived classes : OEditModel and
146 // OFormattedModel. The first one does not have an own version handling, so it can't write the help text itself,
147 // the second one does it's own writing (reading) after calling our method, so normally we shouldn't write any
148 // additional members as this is not compatible to older office versions.
149 // We decided to place the writing of the help text here as it seems the less worse alternative. There is no delivered
150 // office version including formatted controls (and thus the OFormattedModel), and the OFormattedModel::read seems
151 // robust against this change (as it will read a wrong and unknown file version and thus set it's members to defaults).
153 if ((nVersionId
& PF_HANDLE_COMMON_PROPS
) != 0)
154 writeCommonEditProperties(_rxOutStream
);
156 // !!! properties common to all OEditBaseModel derived classes should be written in writeCommonEditProperties !!!
159 //------------------------------------------------------------------------------
160 sal_uInt16
OEditBaseModel::getPersistenceFlags() const
162 return PF_HANDLE_COMMON_PROPS
;
165 //------------------------------------------------------------------------------
166 void OEditBaseModel::read(const Reference
<XObjectInputStream
>& _rxInStream
) throw ( ::com::sun::star::io::IOException
, ::com::sun::star::uno::RuntimeException
)
168 OBoundControlModel::read(_rxInStream
);
169 ::osl::MutexGuard
aGuard(m_aMutex
);
171 // Version's own version number
172 sal_uInt16 nVersion
= _rxInStream
->readShort();
173 m_nLastReadVersion
= nVersion
;
175 sal_Bool bHandleCommonProps
= (nVersion
& PF_HANDLE_COMMON_PROPS
) != 0;
176 nVersion
= nVersion
& ~PF_SPECIAL_FLAGS
;
179 _rxInStream
->readShort();
181 _rxInStream
>> m_aDefaultText
;
183 if (nVersion
>= 0x0003)
185 m_bEmptyIsNull
= _rxInStream
->readBoolean();
187 sal_uInt16 nAnyMask
= _rxInStream
->readShort();
188 if ((nAnyMask
& DEFAULT_LONG
) == DEFAULT_LONG
)
190 sal_Int32 nValue
= _rxInStream
->readLong();
191 m_aDefault
<<= (sal_Int32
)nValue
;
193 else if ((nAnyMask
& DEFAULT_DOUBLE
) == DEFAULT_DOUBLE
)
195 double fValue
= _rxInStream
->readDouble();
196 m_aDefault
<<= (double)fValue
;
198 else if ((nAnyMask
& DEFAULT_TIME
) == DEFAULT_TIME
)
200 m_aDefault
<<= ::Time(_rxInStream
->readHyper()).GetUNOTime();
202 else if ((nAnyMask
& DEFAULT_DATE
) == DEFAULT_DATE
)
204 m_aDefault
<<= ::Date(_rxInStream
->readLong()).GetUNODate();
207 if ((nAnyMask
& FILTERPROPOSAL
) == FILTERPROPOSAL
)
208 m_bFilterProposal
= sal_True
;
212 readHelpTextCompatibly(_rxInStream
);
214 if (bHandleCommonProps
)
215 readCommonEditProperties(_rxInStream
);
217 // After reading, display default values
218 if ( !getControlSource().isEmpty() )
219 // (not if we don't have a control source - the "State" property acts like it is persistent, then)
223 //------------------------------------------------------------------------------
224 void OEditBaseModel::defaultCommonEditProperties()
226 OBoundControlModel::defaultCommonProperties();
227 // no own common properties at the moment
230 //------------------------------------------------------------------------------
231 void OEditBaseModel::readCommonEditProperties(const Reference
<XObjectInputStream
>& _rxInStream
)
233 sal_Int32 nLen
= _rxInStream
->readLong();
235 Reference
<XMarkableStream
> xMark(_rxInStream
, UNO_QUERY
);
236 DBG_ASSERT(xMark
.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
237 sal_Int32 nMark
= xMark
->createMark();
239 // read properties common to all OBoundControlModels
240 OBoundControlModel::readCommonProperties(_rxInStream
);
242 // read properties common to all OEditBaseModels
244 // skip the remaining bytes
245 xMark
->jumpToMark(nMark
);
246 _rxInStream
->skipBytes(nLen
);
247 xMark
->deleteMark(nMark
);
250 //------------------------------------------------------------------------------
251 void OEditBaseModel::writeCommonEditProperties(const Reference
<XObjectOutputStream
>& _rxOutStream
)
253 Reference
<XMarkableStream
> xMark(_rxOutStream
, UNO_QUERY
);
254 DBG_ASSERT(xMark
.is(), "OEditBaseModel::writeCommonProperties : can only work with markable streams !");
255 sal_Int32 nMark
= xMark
->createMark();
257 // a placeholder where we will write the overall length (later in this method)
259 _rxOutStream
->writeLong(nLen
);
261 // write properties common to all OBoundControlModels
262 OBoundControlModel::writeCommonProperties(_rxOutStream
);
264 // write properties common to all OEditBaseModels
266 // close the block - write the correct length at the beginning
267 nLen
= xMark
->offsetToMark(nMark
) - sizeof(nLen
);
268 xMark
->jumpToMark(nMark
);
269 _rxOutStream
->writeLong(nLen
);
270 xMark
->jumpToFurthest();
271 xMark
->deleteMark(nMark
);
274 //------------------------------------------------------------------------------
275 void OEditBaseModel::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
279 case PROPERTY_ID_EMPTY_IS_NULL
:
280 rValue
<<= (sal_Bool
)m_bEmptyIsNull
;
282 case PROPERTY_ID_FILTERPROPOSAL
:
283 rValue
<<= (sal_Bool
)m_bFilterProposal
;
285 case PROPERTY_ID_DEFAULT_TEXT
:
286 rValue
<<= m_aDefaultText
;
288 case PROPERTY_ID_DEFAULT_VALUE
:
289 case PROPERTY_ID_DEFAULT_DATE
:
290 case PROPERTY_ID_DEFAULT_TIME
:
294 OBoundControlModel::getFastPropertyValue(rValue
, nHandle
);
298 //------------------------------------------------------------------------------
299 sal_Bool
OEditBaseModel::convertFastPropertyValue( Any
& rConvertedValue
, Any
& rOldValue
,
300 sal_Int32 nHandle
, const Any
& rValue
) throw( IllegalArgumentException
)
302 sal_Bool
bModified(sal_False
);
305 case PROPERTY_ID_EMPTY_IS_NULL
:
306 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_bEmptyIsNull
);
308 case PROPERTY_ID_FILTERPROPOSAL
:
309 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_bFilterProposal
);
311 case PROPERTY_ID_DEFAULT_TEXT
:
312 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aDefaultText
);
314 case PROPERTY_ID_DEFAULT_VALUE
:
315 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aDefault
, ::getCppuType((const double*)0));
317 case PROPERTY_ID_DEFAULT_DATE
:
318 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aDefault
, ::getCppuType((const util::Date
*)0));
320 case PROPERTY_ID_DEFAULT_TIME
:
321 bModified
= tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_aDefault
, ::getCppuType((const util::Time
*)0));
324 bModified
= OBoundControlModel::convertFastPropertyValue(
333 //------------------------------------------------------------------------------
334 void OEditBaseModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
) throw ( ::com::sun::star::uno::Exception
)
338 case PROPERTY_ID_EMPTY_IS_NULL
:
339 DBG_ASSERT(rValue
.getValueType().getTypeClass() == TypeClass_BOOLEAN
, "invalid type" );
340 m_bEmptyIsNull
= getBOOL(rValue
);
342 case PROPERTY_ID_FILTERPROPOSAL
:
343 DBG_ASSERT(rValue
.getValueType().getTypeClass() == TypeClass_BOOLEAN
, "invalid type" );
344 m_bFilterProposal
= getBOOL(rValue
);
346 // Changing the default values causes a reset
347 case PROPERTY_ID_DEFAULT_TEXT
:
348 DBG_ASSERT(rValue
.getValueType().getTypeClass() == TypeClass_STRING
, "invalid type" );
349 rValue
>>= m_aDefaultText
;
352 case PROPERTY_ID_DEFAULT_VALUE
:
353 case PROPERTY_ID_DEFAULT_DATE
:
354 case PROPERTY_ID_DEFAULT_TIME
:
359 OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle
, rValue
);
364 //------------------------------------------------------------------------------
365 Any
OEditBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle
) const
369 case PROPERTY_ID_DEFAULT_TEXT
:
370 return makeAny(OUString());
371 case PROPERTY_ID_FILTERPROPOSAL
:
372 return Any(makeAny((sal_Bool
)sal_False
));
373 case PROPERTY_ID_DEFAULT_VALUE
:
374 case PROPERTY_ID_DEFAULT_DATE
:
375 case PROPERTY_ID_DEFAULT_TIME
:
378 return OBoundControlModel::getPropertyDefaultByHandle(nHandle
);
382 //.........................................................................
384 //.........................................................................
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */