xref: /trunk/main/forms/source/component/EditBase.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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